Communication Pipeline

In this unit we will gain understanding and practice on how information is passed between different components of the drone such as the onboard computer (Aero Compute Board) and the flight controller (AeroFC).

You should have already been exposed to the basic concepts of the Robot Operating System (ROS) during the online portion of this class. These concepts including things like nodes, topics, messages, services, etc. If you are unsure/uncomfortable with what these concepts imply, there are great tutorials online for walking you through the basics of ROS. Please see:

Talker - Listener

We are going to put some of basic tools of ROS into practice on the Intel RTF Drone. We are going to start by creating and sending a simple message in one ROS node (i.e. talker) and receiving it in another. This portion relates to this ROS tutorial, but adapted to our needs.

First make sure you have the most recent codebase on the drone.

On drone:

cd ~/bwsi-uav/catkin_ws/src/aero_control
git pull upstream master
cd ~/bwsi-uav/catkin_ws/src/aero_control/communication_pipeline

If you try to run simple_talker.py and or simple_listener.py you will receive an error stating

Exception: CODE INCOMPLETE! Delete this exception and replace with your own code

Step 1: Complete Talker

In your preferred text editor, open simple_talker.py and replace/fill in the following code block with your own code:

'''TODO-START: FILL IN CODE HERE
* create a string message that contains "Hello World" and the iteration number i
'''
raise Exception("CODE INCOMPLETE! Delete this exception and replace with your own code")
'''TODO-END '''

Once complete, you can run the talker node

Terminal 1:

roscore

Terminal 2:

python simple_talker.py

After answering the following questions, you can kill the processes by hitting Ctrl-c in each terminal

Questions Set 1:

  1. List all rosnodes that exist after running talker.py

  2. List all rostopics that are being present after running talker.py

  3. What command do I run to see what is being published to the /chatter topic?

  4. What would I change in simple_talker.py to make it publish messages more frequently?

Step 2: Complete Listener

Now we will incorporate a second rosnode to subscribe to the topic created by simple_talker.py and listen to the messages passed. Open simple_listener.py and replace/fill in the appropriate code block.

Once complete, you can run the talker and listener nodes

Terminal 1:

roscore

Terminal 2:

python simple_talker.py

Terminal 3:

python simple_listener.py

After answering the following questions, you can kill these processes by hitting Ctrl-C in each terminal. You will also want to commit the progress you have made so you can later push it to your team’s MIT GitHub repositories:

cd ~/bwsi-uav/catkin_ws/src/aero_control/communication_pipeline/src
git add -u
git commit -m "filling in code for talker and listener"

Questions Set 2:

  1. List all rosnodes that exist after running simple_talker.py and simple_listener.py

  2. List all rostopics that are being present after running simple_talker.py and simple_listener.py

  3. In terminal I ran simple_listener.py I see information being printed. Does this mean simple_listner.py is publishing to a topic?

Step 3: Launch Talker and Listener

It’s a cumbersome to be opening a different terminal for every different rosnode you want to start. Instead of doing this, we can use launch files.

Create Package

Before we make a launch file, we need to more properly set up our catkin workspace by turning aero_control into a ROS Package and indicate it’s dependencies on std_msgs and rospy

cd ~/bwsi-uav/catkin_ws/src
catkin_create_pkg aero_control std_msgs rospy

Note:

Your Intel drone may already have aero_control as a package. If you receive the error: catkin_create_pkg: error: File exists: ~/bwsi-uav/catkin_ws/src/aero_control/package.xml, then you can skip ahead to Make Executables

This will create files ~/bwsi-uav/catkin_ws/src/aero_control/CMakeLists.txt and ~/bwsi-uav/catkin_ws/src/aero_control/package.xml. You’ll want to track these new files on github, so add and commit them so you can later push them to your team’s MIT GitHub:

cd ~/bwsi-uav/catkin_ws/src/aero_control
git add CMakeLists.txt package.xml
git commit -m "starting aero_control as a package"

Make Executables

Next you need to make sure that simple_talker.py and simple_listener.py are executable in order for the launch file to properly access them. This can be done as follows:

cd ~/bwsi-uav/catkin_ws/src/aero_control/communication_pipeline/src/
chmod +x simple_talker.py
chmod +x simple_listener.py

Launch File

Now you are almost ready to run the launch file that starts roscore, simple_talker.py, and simple_listener.py simultaneously. We’ve given you part of the launch file in aero_control/communication_pipeline/launch/simnple_talk_listen.launch, but it’s incomplete. Can you figure out what is missing and add it yourself?

Once you’ve filled in the missing part of the launch file, follow these steps to run it

cd ~/bwsi-uav/catkin_ws/
catkin_make
source devel/setup.bash
roslaunch aero_control simple_talk_listen.launch

You should see the print statement from simple_listener.py in your terminal.

A useful tool for visualizing how information is being passed by ROS is rqt_graph (see references here and here for more information. With simple_talk_listen.launch still running, open a new terminal and run:

rosrun rqt_graph rqt_graph

Question Set 3:

  1. What needed to be added the launch file?

  2. With rqt_graph open, use the button in upper right corner to save an image of the graph and include it in this report. Which components in the graph indicates rosnodes and which indicate rostopics?

  3. Why do we need to run the command source devel/setup.bash before running roslaunch?

  4. Were there any steps that didn’t work or were particularly confusing? How did you work around them?

Step 4: Document and Push

Congratulations! You have implemented one of the basic building blocks of ROS! Now that you have this demo complete, you will want to push your code changes to your team’s MIT GitHub.

First double check that the repository you are working with on your drone or laptop points to the correct remote repository.

cd ~/bwsi-uav/catkin_ws/src/aero_control
git remote -v

should return 4 lines of information, the two lines that start with origin and end with (fetch) and (push) should contain the URL of your team’s MIT GitHub repository for aero_control. If not, let one of the instructors know so we can sort it out.

If that’s all set and you ran the commit commands in the previous steps, you should now be able to push those changes to to your team’s remote repositories with:

git push origin master

Finally, document the answers to question sets 1-3 and push those to your teams documents repository. You can write up the answers any way you want, but the easiest is probably to create a file called communication_pipeline_answers.md, and write a bullet point or paragraph for each question.

MAVROS

In the last section we passed basic messages between two nodes in ROS. This was done entirely in Ubuntu on the Aero Compute Board (or perhaps your laptop); it had no direct communication with the NuttX operating system that was running PX4 firmware on the Aero Flight Controller hardware. It we want our drones to fly autonomously, we need to be able to send commands to and receive sensor information from the flight controller.

Communication with the PX4 Firmware running on the AeroFC board is managed with a service called MAVLink. Similar to how ROS messages pass information between nodes on Ubuntu, MAVLink messages pass information between ROS/Ubuntu/Aero Compute Board and PX4/NuttX/AeroFC.

The MAVLink protocol is low-level, which makes it powerful, extensible, but also complicated to use. To simplify our lives we will make use of MAVROS. MAVROS can be thought of as a “wrapper” for MAVLink that simplifies the communication with ROS.

Step 1: Running MAVROS

Let’s start by getting MAVROS running. On the drone, use multiple terminals to run the following commands:

Terminal 1:

roscore

Terminal 2:

rosrun mavros mavros_node _fcu_url:=tcp://127.0.0.1:5760 _system_id:=2

After answering the following questions you can kill these processes with Ctrl-C

Question Set 1:

  1. What rosnodes are running?

  2. In a separate terminal run rosnode info mavros. Look through the list of mavros Subscriptions and Publications. Can you guess which topics could be used to send commands that control the drone? Which ones?

  3. Some of the topics that mavros subscribes and publishes to have similar sounding names because they serve related, but distinct, purpose. For example, can you guess what is the functional difference between Publication: /mavros/local_position/velocity and Subscription /mavros/setpoint_velocity/cmd_vel_unstamped?

  4. Inspect the messages being sent on the topic mavros/extended_state. Roughly how often do you get a new message? Do you think these messages originate from the Aero Compute Board or the AeroFC?

Step 2. Sending Commands

Next we are going to use the mavros node to send commands to PX4 and receive information about the state of the quadrotor. Since we are only learning the communication structure of the drone, we won’t actually be flying it with these commands, just observing that they get passed correctly.

In aero_control/communication_pipeline/src you should find two other files dispatcher.py and command_generator.py. As with the previous section, these files are missing a block of code that you need to fill in; see the code for instructions on what needs to be completed.

Once you have completed writing your code, let’s test it out. On the drone in multiple terminals run:

Terminal 1:

roscore

Terminal 2:

rosrun mavros mavros_node _fcu_url:=tcp://127.0.0.1:5760 _system_id:=2

Terminal 3:

cd ~/bwsi-uav/catkin_ws/src/aero_control/communication_pipeline/src
python dispatcher.py

Terminal 4:

cd ~/bwsi-uav/catkin_ws/src/aero_control/communication_pipeline/src
python command_generator.py

Assuming you got no errors, answer the following questions (if you did get errors, are you able to debug them?)

Question Set 2:

  1. What new nodes and topics were created by running dispatcher.py and command_generator.py that weren’t present when just running mavros?

  2. Inspect the messages being sent on /velocity_command and /mavros/setpoint_velocity/cmd_vel_unstamped. Do they appear to be the same? Are the being passed at roughly the same rate? Which one is actually being sent to the PX4/AeroFC?

  3. Why would we want to impose a limit on the velocity command sent to the flight controller?

  4. As with the previous section, it is cumbersome to run each command in a separate terminal. To this end we have included a partial launch file in aero_control/communication_pipeline/launch/mavros.launch. Can you complete the launch file and run it in order to kick off mavros, dispatcher, and command_generator simultaneously?

  5. When all nodes are running, use rqt_graph to generate an image of the nodes and topics.

Step 3: Document and Push

As before, document the answers to the preceeding question sets and push them to your team’s documents repository

Advanced Topics: uORB

So far we have only seen communication on the Aero Compute Board and how to pass messages to the Aero Flight Controller. We haven’t actually looked at message passing that occurs onboard the Aero Flight Controller in the PX4 firmware. The Aero Flight Controller uses a different system known as “uORB”. We will cover this in a later lecture but you can learn more uORB in the link below:

[ ]: