Chapter 3. Visualization and Debugging Tools

ROS has a good number of tools which allow the user and the developer to visualize and debug their code in order to detect and solve issues with both hardware and software. This comprises a message logging system similar to log4cxx, diagnostic messages, and also visualization and inspection tools, which provide a comprehensive list of the running nodes as well as how are they interconnected.

In this chapter, we will also show you how to debug an ROS node with the GDB debugger. The message logging API will be explained, and advice will be given on how to choose the logging level. Then, we will explain the set of ROS tools that allows us to inspect which processes are running and what information is communicated between them. For instance, the following figure shows a tool that visualizes the graph of the system, where the nodes are the processes running and the edges represent the data workflow through communication topics. This tool is rqt_graph, and in this case, it shows the nodes and topics which compose the REEM robot software system running on a Gazebo simulation.

You can see multiple controllers for the arms, torso, head, MoveIt! move_group node, pick and place action servers, and the play_motion node for pre-recorded movements. Other nodes publish joint_states, spawn the robot controllers, and control the joystick to move the mobile base.

Visualization and Debugging Tools

Similarly, this chapter will show you how to plot scalar data in a time series, visualize images from a video stream, and represent different types of data in a 3D representation using (the widely known) rviz (or rqt_rviz), as shown in the following screenshot:

Visualization and Debugging Tools

The preceding screenshot shows the REEM robot, which can be run in simulation with the following command:

$ roslaunch reem_2dnav_gazebo reem_navigation.launch

Note that before you install it, you need to follow the instructions provided at http://wiki.ros.org/Robots/REEM. The following sections in this chapter will cover the following topics on visualization and debugging: debugging our code in ROS; using logging messages in our code, with different severity levels, names, conditions, and throttling options. Here, we will explain the rqt_logger_level and rqt_console interfaces, which allow you to set the severity level of a node and visualize the message, respectively. We will also inspect the state of the ROS system by listing the nodes running, the topics, services, and actions they use to transfer messages among them, and the parameters declared in the ROS master server. We will explain rqt_graph, which shows nodes and topics in a directed graph representation, and rqt_reconfigure, which allows you to change dynamic parameters. We will also take a look at visualizing diagnostics information using the runtime_monitor and robot_monitor interfaces, as well as plotting scalar data from messages using rqt_plot.

For non-scalar data, we will explain other rqt tools available in ROS, such as rqt_image_view to visualize images and rqt_rviz to show multiple data in a 3D representation. We will also show you how to visualize markers and interactive markers, and what frames are and how they are integrated into ROS messages and visualization tools. We will also explain how to use rqt_tf_tree to visualize the Transform Frame (tf) tree, along with how to save messages and replay them for simulation or evaluation purposes. We will also cover the rqt_bag interface.

Finally, other rqt_gui interfaces will be explained, as well as how to arrange them in a single GUI.

Most of the rqt tools can be run by simply inputting their name in the terminal, such as rqt_console, but in some cases this does not work and we must use rosrun rqt_reconfigure rqt_reconfigure, which always works; note that the name seems to be repeated, but it is actually the package and node names, one after the other.

Debugging ROS nodes

ROS nodes can be debugged as regular programs. They run as a process in the operating system and have a PID. Therefore, you can debug them as with any program using standard tools, such as gdb. Similarly, you can check for memory leaks with memcheck or profile the performance of your algorithm with callgrind. However, remember that in order to run a node, you must run the following command:

$ rosrun chapter3_tutorials example1

Unfortunately, you cannot simply run the command through gdb in the following way:

$ gdb rosrun chapter3_tutorials example1

In the following sections, we will explain how to call these tools for an ROS node to overcome this issue. Later, we will see how to add logging messages to our code in order to make it simple to diagnose problems; in practice, using logging messages helps to diagnose basic (and not so basic) problems without the need to debug the binaries. Similarly, we will discuss ROS introspection tools, which allow you to easily detect broken connections between nodes. Finally, even though we will provide a bottom-up overview, in practice we usually follow a top-down approach to diagnosing issues.

Using the GDB debugger with ROS nodes

In order to debug a C/C++ node with the gdb debugger, all we need to know is the location of the node executable. With the ROS Kinetic and catkin packages, the node executable is placed inside the devel/lib/<package> folder within the workspace. For example, in order to run the example1 node from the chapter3_tutorials package in gdb, we have to proceed as follows, starting from the workspace folder (/home/<user>/book_ws):

$ cd devel/lib/chapter3_tutorials

If you have run catkin_make install, you can also navigate to the install/lib/chapter3_tutorials directory using the following command:

$ cd install/lib/chapter3_tutorials

Now we can run the node executable inside gdb with the following command:

$ gdb example1

Tip

Remember that you must have roscore running before you start your node because it will need the master/server running.

Once roscore is running, you can start your node in gdb by pressing the R key (and Enter), and you can also list the associated source code with the L key as well as set breakpoints or any of the functionalities that gdb comes with. If everything is correct, you should see the following output in the gdb terminal after running the node:

Using the GDB debugger with ROS nodes

Attaching a node to GDB while launching ROS

In many cases, we might get a launch file that takes care of starting the node, as you can see in the following example:

<launch>
  <node pkg="chapter3_tutorials" type="example1" name="example1"/>
</launch>

In order to attach it to gdb, we must add launch-prefix="xterm -e gdb --args" as follows:

<launch>
  <node pkg="chapter3_tutorials" type="example1" name="example1"
  launch-prefix="xterm -e gdb --args"/>
</launch>

Similarly, you can also add output="screen" to make the node output appear on the terminal. With this launch prefix, a new xterm terminal will be created with the node attached to gdb. Set breakpoints if needed, and then press the C or R key to run the node and debug it. One of the common uses you will find of this simple workflow is to obtain a backtrace (bt) if the node crashes.

Profiling a node with valgrind while launching ROS

Additionally, we can use the same attribute to attach the node to diagnosis tools. For example, we can run our program through valgrind (see http://valgrind.org for further information) to detect memory leaks using memcheck and perform profiling analysis using callgrind. Contrary to attaching to gdb, we do not need to start xterm:

<launch>
  <node pkg="chapter3_tutorials" type="example1"
  name="example1" output="screen"
  launch-prefix="valgrind"/>
</launch>

Enabling core dumps for ROS nodes

Although ROS nodes are actually regular executables, there is a tricky point to enabling core dumps, which can later be used in a gdb session. First of all, we have to set an unlimited core size; the current value can be checked with ulimit -c. Note that this is also required for any executable and not just ROS nodes:

$ ulimit -c unlimited

Then, to allow core dumps to be created, we must set the core filename to use the pid process by default. Otherwise, they will not be created because at $ROS_HOME, there is already a core directory to prevent core dumps. Therefore, in order to create core dumps with the name and path $ROS_HOME/core.PID, we must run the following command:

$ echo 1 | sudo tee /proc/sys/kernel/core_uses_pid
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset