Tutorial 6: Tools

This session is devoted to present several tools for modelling, visualization and monitoring.

It is decomposed into the following tutorials:

Tutorial 6a: The tf tool
Tutorial 6c: The rosbag Tool
Tutorial 6d: The rqt tool

Provided packages:

This tutorial will use the following packages:

Package learning_tf2
Package urdf_tutorial
Package mastering_ros_robot_description_pkg
Package rviz_marker_demo
Package agitr_chapter6

Prepare the catkin workspace to work with them:

  1. If you have not yet done so, follow the steps in Exercise 0 to:

  • clone in your ~/git-projects folder the meta-repository containing all the required packages,

  • create the catkin workspace folders (use catkin_ws6 for the current tutorial).

  1. Follow the procedure shown in Procedure to prepare the exercises to import in the intro2ros/2023/teamXX/EXERCISE4 subgroup of your GitLab account the package:

  1. In your git-projects folder clone the urdf_tutorial and solution_exercise4 projects of your GitLab account inside an exercise4 subfolder (change XX by your team number). You can use https:

$ git clone https://gitlab.com/intro2ros/2023/teamXX/exercise4/urdf_tutorial.git exercise4/urdf_tutorial
$ git clone https://gitlab.com/intro2ros/2023/teamXX/exercise4/solution_exercise4.git exercise4/solution_exercise4

or ssh:

$ git clone git@gitlab.com:intro2ros/2023/teamXX/exercise4/urdf_tutorial.git exercise4/urdf_tutorial
$ git clone git@gitlab.com:intro2ros/2023/teamXX/exercise4/solution_exercise4.git exercise4/solution_exercise4
  1. In your catkin_ws6/src folder create a symbolic link to the packages to be used:

$ ln -s ~/git-projects/all_introduction_to_ros_packages/learning_tf2
$ ln -s ~/git-projects/exercise4/urdf_tutorial
$ ln -s ~/git-projects/all_introduction_to_ros_packages/mastering_ros_robot_description_pkg
$ ln -s ~/git-projects/all_introduction_to_ros_packages/rviz_marker_demo
$ ln -s ~/git-projects/all_introduction_to_ros_packages/agitr_chapter6
  1. Edit the build.sh file of the solution_exercise4 package to add your credencials (token_user and token_code) and push the change.

The tf tool

Objective: This tutorial session is devoted to briefly introduce to the transform library, which lets the user keep track over time of multiple coordinate frames and their relationship.

Contents

After this session you will be able to:

  • Understand and visualize the buffered-in-time ROS tree structure.

  • Know the coordinate name conventions and the TransformStamped message structure.

  • Broadcast a coordinate frame.

  • Listen to a broadcasted coordinate frame.

References:

This tutorial is partially based on the information and tutorials available at http://wiki.ros.org/tf2.

The tf library

The tf library was designed to be a core library of the ROS ecosystem. It is described in this paper.

tf2 is the second generation of the transform library, which lets the user keep track of multiple coordinate frames over time. The tf2_ros package provides roscpp bindings for tf2.

tf2 maintains the relationship between coordinate frames in a tree structure buffered in time (i.e. with transforms as edges and coordinate frames as nodes). It can be visualized using the rqt plugin rqt_tf_tree.

This tree lets the user transform points, vectors, etc between any two coordinate frames at any desired point in time. It can be used to answer questions like:

  • Where was the head frame relative to the world frame, 5 seconds ago?

  • What is the pose of the object in my gripper relative to my base?

  • What is the current pose of the base frame in the map frame?

The nodes may use this package to either listen to or broadcast transforms:

  • Listening for transforms - Receive and buffer all coordinate frames that are broadcasted in the system, and query for specific transforms between frames.

  • Broadcasting transforms - Send out the relative pose of coordinate frames to the rest of the system. A system can have many broadcasters that each provide information about a different part of the robot.

Coordinate Frame Conventions

Naming: Coordinate frames in ROS are identified by a string frame_id in the format lower case underscore separated. This string has to be unique in the system. All data produced can simply identify it’s frame_id to state where it is in the world. frame_ids do not follow namespace remapping rules

TransformStamped message

The message data type for the transforms with time information is the geometry_msgs/TransformStamped:

../_images/stampedtransform.png

Conversions

The convert function is a tf2 function that allows you to convert between data types, in particular between geometry_msgs::TransformStamped and tf2::Stamped<tf2::Transform>:

geometry_msgs::TransformStamped transformStamped;
tf2::Stamped<tf2::Transform> tfs;
tf2::convert(transformStamped, tfs);

Check the tf2::Stamped class template reference and the tf2::Transform class reference.

tf broadcasters

Static Transform broadcasters

tf2_ros provides an executable named static_transform_publisher to broadcast static transforms:

  • static_transform_publisher x y z yaw pitch roll frame_id child_frame_id

    Publishes a static coordinate transform to tf2 using an x/y/z offset in meters and yaw/pitch/roll in radians (yaw is rotation about Z, pitch is rotation about Y, and roll is rotation about X).

  • static_transform_publisher x y z qx qy qz qw frame_id child_frame_id

    Publishes a static coordinate transform to tf2 using an x/y/z offset in meters and a quaternion.

It can be used either as a command line tool or as a node that you can add to your launch files (where you set a given node name):

$ rosrun tf2_ros static_transform_publisher 1 0 0 0 0 0 1 turtle1 turtle1_ahead
<launch>
   <node pkg="tf2_ros" type="static_transform_publisher" name="tool_broadcaster" args="1 0 0 0 0 0 1 turtle1 turtle1_ahead" />
</launch>

Writing a tf2 broadcaster

The class TransformBroadcaster has been designed to send transformations over the wire.

The file turtle_tf2_broadcaster.cpp creates a node that subscribes to the pose of a turtle, whose name has been passed as a parameter, and broadcasts this pose as a transform (additionally, a static transform corresponding to a translation along the x axis w.r.t the turtle pose has been set in the launch file).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <ros/ros.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/transform_broadcaster.h>
#include <geometry_msgs/TransformStamped.h>
#include <turtlesim/Pose.h>

std::string turtle_name;

void poseCallback(const turtlesim::PoseConstPtr& msg){
 static tf2_ros::TransformBroadcaster br;
 geometry_msgs::TransformStamped transformStamped;

 transformStamped.header.stamp = ros::Time::now();
 transformStamped.header.frame_id = "world";
 transformStamped.child_frame_id = turtle_name;
 transformStamped.transform.translation.x = msg->x;
 transformStamped.transform.translation.y = msg->y;
 transformStamped.transform.translation.z = 0.0;
 tf2::Quaternion q;
 q.setRPY(0, 0, msg->theta);
 transformStamped.transform.rotation.x = q.x();
 transformStamped.transform.rotation.y = q.y();
 transformStamped.transform.rotation.z = q.z();
 transformStamped.transform.rotation.w = q.w();

 br.sendTransform(transformStamped);
}

int main(int argc, char** argv){
 ros::init(argc, argv, "my_tf2_broadcaster");

 ros::NodeHandle private_node("~");
 if (! private_node.hasParam("turtle"))
 {
   if (argc != 2){ROS_ERROR("need turtle name as argument"); return -1;};
   turtle_name = argv[1];
 }
 else
 {
   private_node.getParam("turtle", turtle_name);
 }

 ros::NodeHandle node;
 ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);

 ros::spin();
 return 0;
};

Build the learning_tf2 package and launch the nodes:

$ catkin build learning_tf2
$ source devel/setup.bash
$ roslaunch learning_tf2 start_demo.launch

You can visualize the tf tree with rqt:

$ rqt -s rqt_tf_tree

Move the turtle with the keys and verify the broadcasted transforms with the tf_echo utility:

$ rosrun tf tf_echo /world /turtle1
$ rosrun tf tf_echo /world /turtle1_ahead

Exercise

  • Add a second turtle using the /spawn service. Call it ‘turtle2’.

  • Run the node turtle_tf2_broadcaster with the name of the turtle as an argument (i.e. $ rosrun turtle_tf2 turtle_tf2_broadcaster turtle2).

  • Use tf_echo to visualize the transform that locates ‘turtle2’.

  • Update the visualization of the tree in the rqt tool.

../_images/rqtgraph_tf.png

tf listeners

The classes Buffer and TransformListener have been designed to receive the transforms information, to store it, and later use it to respond to queries about the resultant transforms between different coordinate frames using the lookupTransform function.

The file turtle_tf2_listener.cpp creates a node that spawns a second turtle and then computes a velocity to drive the second turtle towards the first one. This is done by computing the transform between the transforms broadcasted by the turtles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <ros/ros.h>
#include <tf2_ros/transform_listener.h>
#include <geometry_msgs/TransformStamped.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h>

int main(int argc, char** argv){
 ros::init(argc, argv, "my_tf2_listener");

 ros::NodeHandle node;

 ros::service::waitForService("spawn");
 ros::ServiceClient spawner =
   node.serviceClient<turtlesim::Spawn>("spawn");
 turtlesim::Spawn turtle;
 turtle.request.x = 4;
 turtle.request.y = 2;
 turtle.request.theta = 0;
 turtle.request.name = "turtle2";
 spawner.call(turtle);

 ros::Publisher turtle_vel =
   node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", 10);

 tf2_ros::Buffer tfBuffer;
 tf2_ros::TransformListener tfListener(tfBuffer);

 ros::Rate rate(10.0);
 while (node.ok()){
   geometry_msgs::TransformStamped transformStamped;
   try{
     transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1",
                              ros::Time(0));
   }
   catch (tf2::TransformException &ex) {
     ROS_WARN("%s",ex.what());
     ros::Duration(1.0).sleep();
     continue;
   }

   geometry_msgs::Twist vel_msg;

   vel_msg.angular.z = 4.0 * atan2(transformStamped.transform.translation.y,
                                   transformStamped.transform.translation.x);
   vel_msg.linear.x = 0.5 * sqrt(pow(transformStamped.transform.translation.x, 2) +
                                 pow(transformStamped.transform.translation.y, 2));
   turtle_vel.publish(vel_msg);

   rate.sleep();
 }
 return 0;
};

The launch file start_demo_2.launch runs one broadcaster node per turtle, the listener node and the turtlesim and teleope_key nodes. By launching all of them you can see how, while teleoperating turtle1, turtle2 follows turtle1.

$ roslaunch learning_tf2 start_demo_2.launch

You can visualize the tf tree with rqt, and monitorize the error using tf_echo:

$ rosrun tf tf_echo /turtle1 /turtle2

Robot Modeling and visualization tools

Objective: This tutorial session is devoted to introduce to the Unified Robot Description Format to model robots in ROS.

Contents

After this session you will be able to:

  • Understand structure of URDF files.

  • Understand the Xacro extension.

  • Use the rviz tool to visualize the robot and its environment.

Provided packages:

The package mastering_ros_robot_description_pkg contains examples of a simple pan and tilt structure and a seven degrees of freedom robot. A folder called urdf contains the urdf files and a folder called meshes contain the meshes of the 3D geometries used. Also, the launch folder contains launch files to run rviz to visualize the robots.

References:

This tutorial is partially based on the ROS wiki and on chapter 2 of the book Mastering ROS for Robotics Programming from Lentin Joseph.

Complementary resources:

The Unified Robot Description Format (URDF)

The Unified Robot Description Format (URDF) uses XML files to model robots, sensors and the working environment. The URDF package contains a C++ parser for the URDF format.

Using XML tags, the URDF can represent:

  • the kinematic description of the robot,

  • the dynamic description of the robot,

  • the visual representation of the robot, and

  • the collision model of the robot.

URDF file have the extension .urdf and are usually stored in the subfolder called urdf of the package folder.

As an extension to URDF, an XML macro language called Xacro has been designed to construct shorter and more readable XML files, as explained in Section Xacro (XML Macros). Xacro files have the extension .xacro.

Main tags

The link tag

The link tag describes the inertial properties of a single link of a robot (mass and inertia matrix), its visual model (geometry and material) and its collision model (geometry). Each of these elements has its reference frame relative to the link reference frame as shown in the figure below.

<link name="<name of the link>">
  <inertial>...........</inertial>
  <visual> ............</visual>
  <collision>..........</collision>
</link>

The complete description can be found here.

../_images/urdflink.png

The joint tag

The joint tag describes a robot joint: its type (revolute, continuous, prismatic, fixed, floating, or planar), the links it connects (parent link, child link) and the transform between them (defaulted to the identity), the joint axis (e.g. the axis of rotation for revolute joints), dynamics properties (damping, friction) and limits (joint movement, velocity and effort).

The joint is located at the origin of the child link, as shown in the figure below, and the joint axis is specified in the joint frame.

<joint name="<name of the joint>" type="<type of the joint>">
   <origin xyz="..." rpy="..."/>
   <parent link="link1"/>
   <child link="link2"/>
   <axis>"..."</axis>
   <dynamics damping="...."/>
   <limit effort="..."/>
</joint>

The complete description can be found here.

../_images/urdfjoint.png

The robot tag

The robot tag describes a complete robot: its name, the links, and the joints. Only tree structures can be represented using URDF, ruling out all parallel robots. The specification assumes the robot consists of rigid links connected by joints; flexible elements are not supported.

<robot name="<name of the robot>"/>
  <link> ..... </link>
  <link> ...... </link>
  <joint> ....... </joint>
  <joint> ...... </joint>
</robot>

A detailed description can be found here.

../_images/urdfrobot.png

Exercise

Take a look at the pan_tilt.urdf file that describes a pan-tilt structure (you will find the file in the urdf folder in the package mastering_ros_robot_description_pkg).

Additional tags

The transmission tag

The transmission tag describes the relationship between an actuator and a joint to model concepts such as gear ratios.

<transmission name="<name of the transmission>"/>
  <type> .... </type>
  <joint> ... </joint>
  <actuator>... </actuator>
</transmission>

A detailed description can be found here.

The gazebo tag

The gazebo tag is used to add extra information to the links and joints for simulation purposes in the Gazebo simulator. It will be detailed in the Simulation - basic issues tutorial.

A detailed description can be found here.

Verification tools

The command line tool check_urdf can be used to verify the correctness of a URDF file. It attempts to parse the file and either prints a description of the resulting kinematic chain, or an error message is reported.

You can test it by checking the correctness of the pan-tilt structure:

$ check_urdf pan_tilt.urdf

Also the tree structure of the robot can be graphically shown using the command tool called urdf_to_graphiz.

$ urdf_to_graphiz pan_tilt.urdf
$ evince pan_tilt.pdf
../_images/urdfpantilt.png

Xacro (XML Macros)

Xacro is an XML macro language that extends URDF by providing:

  • Modularity: It creates macros that can be reused (even in other files), which results in a modular and more readable code.

  • Programmability: It supports simple programming statements, which makes the description more efficient.

Xacro files modify the robot tag to include a namespace:

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="pan_tilt">

Properties

Constants can be declared and used as named values inside the Xacro file, thus allowing to change these values more easily.

<xacro:property name="pan_link_length" value="0.01" />
<xacro:property name="pan_link_radius" value="0.2" />
....
<cylinder length="${pan_link_length}" radius="${pan_link_radius}"/>

Math expressions

Basic operations such as + , -, * , / , unary minus, and parenthesis can be used inside ${}.

<cylinder length="${pan_link_length}" radius="${pan_link_radius+0.02}"/>

Includes

Other Xacro files can be included inside a Xacro file using the xacro:include tag, e.g.:

<xacro:include filename="$(find packageName)/urdf/anotherXacroFile.xacro"/>

Macros

Macros can be defined to allow modularity. They improve the code readability and reduce the number of lines compared to urdf, e.g.:

<xacro:macro name="inertial_matrix" params="mass">
 <inertial>
  <mass value="${mass}" />
  <inertia ixx="0.5" ixy="0.0" ixz="0.0" iyy="0.5" iyz="0.0" izz="0.5" />
 </inertial>
</xacro:macro>
...
<xacro:inertial_matrix mass="1"/>

Exercise

Take a look at the pan_tilt.xacro file that describes a pan-tilt structure.

Conversion from Xacro to urdf

Any Xacro file can be converted to URDF as follows:

$ rosrun xacro xacro pan_tilt.xacro > pan_tilt_generated.urdf

kdl_parser

The Kinematics and Dynamics Library (KDL) defines a tree structure to represent the kinematic and dynamic parameters of a robot mechanism, and provides solvers to compute anything from forward position kinematics, to inverse dynamics.

The kdl_parser provides tools to construct a KDL tree from an XML robot representation in URDF.

The seven DOF arm example

../_images/sevenDOFrobotPicture.png

Joint number

Joint name

Joint type

Limits (deg)

1

bottom_joint

Fixed

2

shoulder_pan_joint

Revolute

-150 to 114

3

shoulder_pitch_joint

Revolute

-67 to 114

4

elbow_roll_joint

Revolute

-150 to 41

5

elbow_pitch_joint

Revolute

-92 to 110

6

wrist_roll_joint

Revolute

-150 to 150

7

wrist_pitch_joint

Revolute

-92 to 113

8

gripper_roll_joint

Revolute

-150 to 150

9

finger_joint1

Prismatic

0 to 25 mm

10

finger_joint2

Prismatic

-25 to 0 mm

Exercise

Take a look at the seven_dof_arm.xacro file, to verify:

  • the use of xacro:property to define constant values,

  • the use of xacro:macro to define the inertial_matrix,

  • the use of xacro:include to include the files describing the sensors,

  • the use of prismatic joints for the fingers

The rviz visualization tool

Rviz is a 3D visualization tool for ROS (http://wiki.ros.org/rviz).

Launching rviz

We can use rviz to visualize the robots in the mastering_ros_robot_description_pkg package.

Build the package and launch the following launch file, that contains a node to run the rviz and the nodes joint_state_publisher and robot_state_publisher explained below.

<?xml version="1.0"?>
<launch>
 <arg name="model" />
 <param name="robot_description" textfile="$(find mastering_ros_robot_description_pkg)/urdf/pan_tilt.urdf" />

 <node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
 <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
 <node name="rviz" pkg="rviz" type="rviz" args="-d $(find mastering_ros_robot_description_pkg)/urdf.rviz" required="true" />
</launch>
$ catkin build mastering_ros_robot_description_pkg
$ source devel/setup.bash
$ roslaunch mastering_ros_robot_description_pkg view_demo.launch
../_images/view_demo-rviz.png

Exercise

Repeat for the 7 DOF arm using the view_arm.launch file, that loads the robot_description parameter with the robot model read from the seven_dof_arm.xacro file.

The joint_state_publisher node

The joint state publisher is one of the ROS packages that is commonly used to interact with each joint of the robot. The package contains the joint_state_publisher node, which will find the non-fixed joints from the URDF model and publish the joint state values of each joint in the sensor_msgs/JointState message format.

In order to use a GUI with a slider-based control window to control each joint, the package joint state publisher_gui should be used instead.

The robot_state_publisher node

The robot state publisher package is used to publish the state of the robot to tf. i.e. this package has the robot_state_publisher node that subscribes to joint states of the robot and publishes the 3D pose of each link using the kinematic representation from the URDF model.

Markers

Rviz provides the Marker Display to let you visualize data without rviz knowing anything about interpreting that data. Data is sent to the display by publishing visualization_msgs/Marker messages, which let you show objects (3D meshes) or basic shapes (boxes, spheres, lines, arrows,..). The set of types that can be dispayed is available here.

The visualization_msgs/MarkerArray message type describes a vector of visualization_msgs/Marker messages, which have the following fields:

../_images/visualizationmsgmarker.png

As an example, build and run the rviz_marker_demo package:

$ catkin build rviz_marker_demo
$ roslaunch rviz_marker_demo rviz_marker_demo.launch
../_images/rvizvisualizationmarker.png

Exercise

Take a look at the rviz_node.cpp file that implements a node that publishes marker messages to place objects on the scene. The following issues should be noted:

  • In this example, objects are located w.r.t a frame called assembly_frame, i.e. when they are published, the field marker.header.frame_id is set to assembly_frame. Then, the launch file runs a static_transform_publisher to broadcast a fixed transform between the global frame world and the example reference frame /assembly_frame.

  • For this demo, two Displays (the Marker and the Axes) have been added (using the Add button on the bottom left), and then the configuration has been saved (with the File->Save Config As menu) to the file rviz_marker_demo.rviz. In the launch file this file is passed as an argument to the rviz node, and therefore when rviz is launched it opens with the desired appearance.

See the rviz user guide for more details.

EXERCISE 4

To solve Exercise 4 you must modify the urdf_tutorial package that you have cloned in your git-projects folder.

Recall to keep commiting the changes when coding the solution (do small commits with good commit messages!) and write a README.md file in the solution_exercise4 package explaining your solution (Markdown Cheat Sheet).

This exercise aims to put in practice the learning of:

  • the publisher-subscriber communication

  • the client-server communication

  • the versatility of the launch utility

  • the use of joint_state_publisher and robot_state_publisher

  • the use of the tf

  • the use of rviz

Objective: To implement a ROS node that allows to teleoperate the 7-dof robot used so far, by using the arrow keys in the keyboard.

First, build and launch the urdf_tutorial example that shows the pan-tilt structure moving:

$ catkin build urdf_tutorial
$ roslaunch urdf_tutorial urdf_tutorial.launch

Starting from this example, modify it in an incremental way following the guidelines shown below (coding different versions of the node). All the partial solutions should be available and running.

Launch guidelines: Use two different launch files (called urdf_tutorial.launch and urdf_tutorial_robot.launch), according to the two types of robot (the pan-tilt structure and the robotic arm, respectively), and configure them to pass as an argument (called filename) the name of the executable file that implements a given version of the node urdf_tutorial (and do arg substitution in the type field).

Exercise 4a

  • Modify the code of the urdf_tutorial_template.cpp file to add a subscriber to a topic called teleop_values in order to teleoperate the pan and tilt degrees of freedom by using the arrow keys, which will be controlled by the turtlesim/teleop_turtle node.

  • Save the code as urdf_tutorial_a.cpp, and name the executable urdf_tutorial_a.

Tip: Do not forget to add the ros::spinOnce() inside the while loop!

Hint: Use the remap option of the launch utility to map from turtle1/cmd_vel to teleop_values.

Exercise 4b (optional)

  • Add a service to change the scale (call it urdf_tutorial/change_scale) in order to teleoperate the pan-tilt structure in a more fine or coarse way.

  • Save the code as urdf_tutorial_b.cpp, and name the executable urdf_tutorial_b.

Exercise 4c

  • Change the pan-tilt structure by the 7-dof robot. Teleoperate joints elbow_pitch_joint and wrist_pitch_joint.

  • Save the code as urdf_tutorial_arm.cpp, and name the executable urdf_tutorial_arm.

Exercise 4d (optional)

  • Add a service to choose which of the joints are to be teleoperated (you can neglect the prismatic joints of the fingers, or optionally consider them). Consider the limits of the joints given above.

  • Save the code as urdf_tutorial_arm2.cpp, and name the executable urdf_tutorial_arm2.

Exercise 4e

  • Add a TransformListener to monitorize the z value of the grasping_frame and slow down the teleoperation when its value is below 0.3 m.

  • Save the code as urdf_tutorial_arm3.cpp, and name the executable urdf_tutorial_arm3.

Exercise 4f (optional)

Change the behavior of the system in 4e as follows:

  • Add an object in front of the robot, e.g. the UpperBody part of the plane, and attach a static transform to it. To do this modify the rviz_node.cpp; call it rviz_node2.cpp. Then, monitorize the distance from the grasping_frame to the object frame and slow down the teleoperation whenever this distance is below 0.5 m.

  • You can draw a sphere to visualize the zone where the teleoperation is slowed down.

  • Save the code as urdf_tutorial_arm4.cpp, and name the executable urdf_tutorial_arm4. For this example you can create a new launch file that also has to run the rviz_node2 node.

SOLUTION EXERCISE 4

Download the zipped solution.

The rosbag Tool

Objective: This tutorial session is devoted to introduce to the rosbag tool.

Contents

After this session you will be able to:

  • Understand the mechanism to record and replay messages.

  • Use the command line utility to record and replay messages.

  • Use launch files to record and replay messages.

  • Use the rqt_tool to record and replay messages.

References:

This tutorial is partially based on the ROS wiki and on chapter 6 of A gentle introduction ROS by Jason M. O’Kane.

Complementary resources:

Recording and playing back bag files

The rosbag tool allows you to record the messages published on one or more topics to a file, and then later replay those messages.

This allows to debug our program using real data, i.e. by using rosbag we can run the real robot only a few times, recording the topics we care about, and then replay the messages on those topics many times, while debugging the code that processes those data.

The rosbag tool is available from the command line, as a package with nodes that can be run using the launch utility, and through the graphical interface rqt.

Recording bag files

To create a bag file from the command line use:

$ rosbag record -O filename.bag topic-names

You can check all the rosbag record options with the -h flag. These are some of the most used ones:

  • -O NAME record to bag with name NAME.bag

  • -o PREFIX prepend PREFIX to beginning of bag name (name will always end with date stamp)

  • -a record all topics

  • --duration=DURATION record a bag of maximum duration DURATION in seconds

  • --node=NODE record all topics subscribed to by a specific node

Playing back bag files

To replay a bag file from the command line use:

$ rosbag play -O filename.bag

You can check all the rosbag play options with the -h flag. These are some of the most used ones:

  • -r FACTOR multiply the publish rate by FACTOR

  • --topics topics to play back

Inspecting bag files

The rosbag info command can provide a number of interesting snippets of information about a bag, like the duration, message count, and topic lists.

$ rosbag info filename.bag

e.g.:

../_images/rosbaginfo.png

An example

To put in practice this utility, let’s launch the turtle teleoperation example:

$ roslaunch agitr_chapter6 teleopturtlesim.launch

and record the messages broadcasted while teleoperating the turtle (press Ctrl+C to stop recording):

$ mkdir ~/bagfiles
$ rosbag record -o ~/bagfiles/teleopturtle /turtle1/cmd_vel /turtle1/pose

The ROS graph shows a record node subscribed to topics /turtle1/cmd_vel and /turtle1/pose:

../_images/rosbagrecord_rosgraph.png

Exercise

Check the recorded file using the rosbag info option.

Now close and restart again the teleopturtlesim.launch and observe the turtle moving while the recorded bagfile is replayed (change the name accordingly):

$ rosbag play ~/bagfiles/teleopturtle_2019-03-05-10-39-28.bag --topics /turtle1/cmd_vel

Note that:

  • rosbag only replicates a sequence of messages, it does not reproduce the initial state, therefore the trajectory of the turtle would have been different from the one followed while recording, hadn’t we restarted the teleopturtlesim.launch.

  • If we had broadcasted all the messages (i.e. without specifying the --topics option), then both the turtlesim node and the rosbag would be simultaneously publishing to the same topic /turtle1/pose. This could be a problem if some node were subscribed to this topic. The same happens with the turtle1/cmd_vel topic, as shown in the ROS graph where we see the teleopkey node and the play node both publishing commanded velocities:

../_images/rosbagplay_rosgraph.png

Bags in launch files

ROS also provides executables named record and play that are members of the rosbag package. They can be called using roslaunch, e.g.:

../_images/rosbag_record_roslaunch.png ../_images/rosbag_play_roslaunch.png

The args could be passed as arguments to the launch file, as done in the following example:

<launch>
  <arg name="filename" />
  <arg name="topicname" default="-a" />
  <node
    pkg="turtlesim"
    type="turtlesim_node"
    name="turtlesim"
    respawn="true"
  />
  <node
      pkg="turtlesim"
      type="turtle_teleop_key"
      name="teleop_key"
      required="true"
      launch-prefix="xterm -e"
  />
  <node
     pkg="rosbag"
     type="record"
     name="record"
     args="-O $(arg filename) $(arg topicname)"
  />
 </launch>

Launch this roslaunch file to record all the topics in a rosbag file called file0.bag:

$ roslaunch agitr_chapter6 teleopturtlesim_record.launch filename:=file0.bag

This file will be stored in the ~/.ros folder. If you want to place elsewhere then you need to provide an absolute path.

To record some specific topics, then:

$ roslaunch agitr_chapter6 teleopturtlesim_record.launch filename:=file0.bag topicname:="/turtle1/cmd_vel /turtle1/pose"

The following launch file launches the teleoperation application with the rosbag play node:

<launch>
  <arg name="filename" />
  <node
    pkg="turtlesim"
    type="turtlesim_node"
    name="turtlesim"
    respawn="true"
  />
  <node
    pkg="rosbag"
    type="play"
    name="play"
    args="$(arg filename)"
  />
 </launch>

Launch it to replay the file0.bag file recorded previously (stored in the ~/.ros folder):

$ roslaunch agitr_chapter6 teleopturtlesim_play.launch filename:=file0.bag

If you want to replay a bag file placed elsewhere then you need to provide an absolute path.

Exercise

Add an argument to the launch file to configure the duration of the bag recording, and repeat.

The rqt_bag utility

rqt_bag is a graphical application for recording and replaying bag files. It allows to:

  • show bag message contents

  • display image messages (optionally as thumbnails on a timeline)

  • plot configurable time-series of message values

  • publish/record messages on selected topics to/from ROS

  • export messages in a time range to a new bag

Let’s use it for recording topics of the turtle teleoperation example:

$ roslaunch agitr_chapter6 teleopturtlesim.launch
$ rqt_bag

Press the red button to start recording (first you will be queried to select the topics to be recorded and the name of the bag file). If you select to record the commanded velocity then some plot like the following will be shown (note that until no messages are broadcased by teleoperating the keys, actually nothing is recorded).

../_images/rqt_capture.png

Now, let’s use it for replaying the recorded bag. Open again the rqt_bag tool and load the ros bag. Once loaded, select the Publish option (as shown in the figure below) and play:

../_images/rqt_replay.png

You will see the turtle moving as the /turtle1/cmd_vel messages are replayed.

The rqt tool

ROS provides many GUI tools, like rqt_graph, rqt_tf_tree or rqt_bag. They can be run in the traditional standalone method, or they can be run as plugins of a global GUI, called rqt, which incorporates these utilities and others.

A list of available plugins, grouped by utilities, can be found here. They belong to the following two metapackages:

If you are interested to run a single plugin you can directly open it by using the -s option, e.g.:

$ rqt -s rqt_topic

However, it is recommended to run rqt and then load any desired plugin. A layout of the selected plugins can be stored by creating a new Perspective (it can be exported as a .perspective file).

Common plugins

Some of the available common plugins are the following.

For logging:

  • Logger level (rqt_logger_level) provides a GUI plugin for configuring the logger level of ROS nodes.

  • Console (rqt_console) provides a GUI plugin for displaying and filtering ROS messages.

For introspection:

  • Node Graph (rqt_graph) provides a GUI plugin for visualizing the ROS computation graph.

For Topics:

  • Message Type Browser (rqt_msg) provides a GUI plugin for introspecting available ROS message types.

  • Message publisher (rqt_publisher) provides a GUI plugin for publishing arbitrary messages with fixed or computed field values.

  • Topic Monitor (rqt_topic) provides a GUI plugin for displaying debug information about ROS topics including publishers, subscribers, publishing rate, and ROS Messages.

For services:

  • Service Type Browser (rqt_srv) provides a GUI plugin for introspecting available ROS message types.

  • Service Caller (rqt_service_caller) provides a GUI plugin for calling arbitrary services.

For visualization:

  • Plot (rqt_plot) provides a GUI plugin visualizing numeric values in a 2D plot using different plotting backends.

Exercise

  1. Rosrun turtlesim and the turtle_teleop_key, e.g. by roslaunching agitr_chapter6/teleopturtlesim.launch.

  2. Open rqt and load the following plugins: Service Caller, Message publisher, Topic Monitor and Plot.

  3. Use those plugins to:

    1. Using the Service Caller, create a new turtle called ‘MyTurtle’ at position (3.0,3.0) by using the /spawn service.

    2. Using the Message Publisher, move turtle1 and MyTurtle with rotational motions around themselves by publishing angular velocities of 1 and -1, respectively.

    3. Using the Topic Monitor, monitor the poses of both turtles.

    4. Using the Plot, visualize the angular position of the turtles.

Robot plugins

Some of the available robot plugins are:

  • Visualization of 3D poses (rqt_pose_view) provides a GUI plugin for visualizing 3D poses.

  • Visualization of the ROS tf tree (rqt_tf_tree) provides a GUI plugin for visualizing the ROS TF frame tree.