Welcome to the next installment in my series on the ROS transform system (ROS tf). In my previous article I explained how BLUEsat’s Rovers all run on the Robotics Operating System (ROS), and what the ROS tf system was all about. In this article I will introduce a number of useful tools and packages that allow us to take advantage of ROS transforms, with very little code involved.
First we’ll look at the Robot State Publisher – a simple tool for publishing basic transforms of robots joints using a model of your robot. Then I will demonstrate visualising TF trees in RQT, a useful way to identify problems with your transform system. Finally I will explain how to visualise the movement of your robot using RViz.
Using Robot State Publisher
The standard ROS packages include a number of ways to to publish transforms with little or no code. One of the most useful of these is the robot state publisher, which takes in a URDF file modelling your robot, and outputs static transforms for fixed joints. It also listens for joint messages to publish the position of other joints. Creating a URDF file is outside the scope of this article, but I recommend the SolidWorks to URDF converter, although it is no longer maintained.
The robot state publisher package is effective because it abstracts away a lot of the work you would otherwise need to do. Developers only need to publish message describing an angular rotation, velocity or extension of a joint (depending on the type – more later). There’s even a UI you can use for testing provided by the joint state publisher ROS package.
Starting the publisher is reasonably simple. First you need to define the location of your urdf file. If you are using a ROS launch file then you can simply add the following line to your launch file.
<param name="robot_description" command="$(find xacro)/xacro '$(find owr_bluetounge2_tf)/robots/owr_bluetounge2_tf.URDF'" />
owr_bluetounge2_tf with the the name of the ROS package your urdf file is in and
/robots/owr_bluetounge2_tf.URDF with the path to your urdf file within the the package folder. If you want, you can also get rid of the
$(find ... ) section completely and just use an absolute path.
Then to run the node itself, add the following line to the file and then run it using the
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
A complete file can be found on our GitHub.
By itself this will only publish the “static transforms.” These are the ones not associated with moving joints. To get ROS to publish transforms for joints that move we need to provide it with either an “extension”, “rotation” or “velocity” for the joint. The type of value depends on what type of joint you defined in your urdf. In terms of units ROS standardises measurements in meters, radians, and m/s for distance, rotation and speed respectively.
Now that you have your robot model set up, you probably want to test it. The easiest way to do this is with the “joint_state_publisher”. This provides a simple GUI to publish those topics.
To run the “joint_state_publisher” simply type:
rosrun joint_state_publisher joint_state_publisher _use_gui:=true
This is useful for testing, but for the actual operation of your robot you probably want to automate this. To do this you need to publish one or more “sensor_msgs/joint_states” message on the
/joint_states topic describing the states of your joints.
As well as a standard ROS header describing time information, the message contains four arrays. The first is “names” and corresponds to the names of your joints in the urdf file. This defines the order for the values in the other three arrays; “position”, “velocity”, “effort”. To preserve ordering, you need to define each named joint in all three other arrays, but the joint state publisher will only consider position or velocity depending on the type of joint.
Visualising TF Trees in RQT
Once you have your transform tree up and running, you probably want to check that it is working as expected – this is where RQT comes in. If you haven’t encountered RQT before, I recommend you take a look at our previous tutorial on debugging ROS systems. As I mentioned in that article, RQT is basically a Swiss army knife full of handy ROS tools. You start it by typing
rqt in the terminal, with roscore running.
In this case the plugin we are looking for is simply called the “TF Tree” tool. You can find it in the “Plugins” menu under “Visualisation”. It allows you to see the connections in your TF tree, when they last updated, and most importantly, any gaps in the tree.
The image below is a great example of this. We can see that there are several disjoint trees. This is a good indication that something is wrong with our ROS system. In order for us to be able to transform between all of the robot’s co-ordinate systems we need to be able to transform freely.
In the case above this is because the robot state publisher has not received states for all of the joints it is expecting. But other causes may include a node not running or a localisation system that hasn’t collected sufficient sensor data yet.
3D Representations of your Robot in RViz
Finally let’s visualise the transforms we have been working. This is where RViz comes in.
RViz contains method for visualising a range of different transformed data. First let’s see our robot in its transformed state.
The RViz window is split into three columns. From left to right. The first displays information about the data you are visualising, the second displays a 3D scene that will contain the data and the third contains information about the camera.
To add your robot, make sure you have joint state publisher running as described above. Then click “Add” in the left hand column. A list of data types should appear in a new window. Select “Robot Model.” You should get something like the below image.
Now try moving some of the joints using the joint state publisher. The corresponding part of your robot should move!
Have a play around in RViz and see what else you can visualise.
Thanks for reading this installation of my series on the ROS transform (TF) system. Please, stay tuned for the next instalment where I will cover using these transforms to process data in code!