In this tutorial I will show you how to debug your ROS2 topics using command line tools such as ros2 topic.
With a practical example, you’ll see what you can do, and what information you can find, in order to become more efficient when developing with ROS2.
>> Watch this video as an additional resource to this article:
After watching the video, subscribe to the Robotics Back-End Youtube channel so you don’t miss the next tutorials!
Code for this tutorial
Let’s write a very simple node with one publisher (in Python)
You want to learn ROS2 efficiently?
Check out ROS2 For Beginners and learn ROS2 step by step, in 1 week.
#!/usr/bin/env python3 import rclpy from rclpy.node import Node from example_interfaces.msg import String class GreetingsPublisher(Node): def __init__(self): super().__init__("greetings_publisher") self.publisher_ = self.create_publisher(String, "greetings", 10) self.timer_ = self.create_timer(1.0/5.0, self.publish_greetings) def publish_greetings(self): msg = String() msg.data = "Hello there, let's debug topics!" self.publisher_.publish(msg) def main(args=None): rclpy.init(args=args) node = GreetingsPublisher() rclpy.spin(node) rclpy.shutdown() if __name__ == "__main__": main()
Install and run the node:
- Add a line to your setup.py, inside the ‘console_scripts’ array:
"greetings_publisher = ros2_tutorials_py.greetings_publisher:main"
(use the CMakeLists.txt if you have a Cpp code). - Execute
colcon build
into your ROS2 workspace. - Source your environment (usually you’ll source your bashrc file)
- Run the node with
ros2 run your_package_name greetings_publisher
.
ros2 topic list – Find all Topics on your graph
You can find the list of all topics that some nodes are publishing or subscribing to.
$ ros2 topic list /greetings /parameter_events /rosout
As you can see here, we have 3 topics:
- /greetings: the one we’ve just created with a publisher. Note: if you create a node with a subscriber to a topic (without any publisher), you’ll also see the topic name here.
- /rosout: all nodes automatically have a publisher to this topic when started. When you print a ROS2 log, the log will be sent to that topic.
- /parameter_events: also automatically started when you start the node. Every time a change has been made to parameters for this node, the change will be published to this topic.
ros2 topic echo – Print the data going through a Topic
This is probably one of the most useful ros2 topic
command line tool, you’ll use it all the time.
Once you know the name of a topic, for example with ros2 topic list
, you can listen to it directly from the terminal.
$ ros2 topic echo /greetings data: Hello there, let's debug topics! --- data: Hello there, let's debug topics! --- data: Hello there, let's debug topics! ---
This will basically create a new subscriber to the topic, which just prints the data to the screen.
ros2 topic echo
can help you see if some messages are not going through (they will not appear), or if the data is wrong. Also, when you’ve just written a node with a publisher, you can check the result from the terminal, before you even start to write any code for a subscriber.
ros2 topic info/type – Get more details about a Topic
With ros2 topic echo
you can already see what kind of data is sent to the topic, but you don’t know exactly what is the interface.
First let’s use the ros2 topic type command. This will give you the name of the interface you need to use if you want to subscribe/publish to the topic from your code.
$ ros2 topic type /greetings example_interfaces/msg/String
Here you can see the interface is “example_interfaces/msg/String”.
From there, you can find the detail of what you should send, using ros2 interface show.
$ ros2 interface show example_interfaces/msg/String # This is an example message of using a primitive datatype, string. # If you want to test with this that's fine, but if you are deploying # it into a system you should create a semantically meaningful message type. # If you want to embed it in another message, use the primitive data type instead. string data
Quite useful. You can also use ros2 topic info
.
$ ros2 topic info /greetings Type: example_interfaces/msg/String Publisher count: 1 Subscription count: 0
Here you get 2 kinds of information:
First, the interface to use. This is the exact same result you get with ros2 topic type
.
And second, the number of publishers and subscribers for this topic. As you can see we have only one publisher here. This number will be incremented for each new publisher you start in any other node. Same for subscribers.
Note: run ros2 topic echo /greetings
in another terminal, and then run ros2 topic info /greetings
again. You’ll see the subscriber count going from 0 to 1.
That information is quite useful, for example when you see that some weird data is coming to a topic. If you expected to have 2 nodes publishing on the topic, and you see the number “3”, then maybe you forgot to kill a node somewhere which is sending some garbage data.
ros2 topic pub – Publish to a topic from the terminal
With ros2 topic echo
you can subscribe to a topic, well with ros2 topic pub
you can publish to it.
To publish to a topic you’ll need all the info you got with the previous command line tools: name of the topic, and interface type+detail.
And here, mostly 2 use cases:
1. You want to publish at a given frequency/rate. For example at 10Hz:
$ ros2 topic pub -r 10 /greetings example_interfaces/msg/String "{data: 'Hello from terminal'}" publisher: beginning loop publishing #1: example_interfaces.msg.String(data='Hello from terminal') publishing #2: example_interfaces.msg.String(data='Hello from terminal') ...
Use quotes with curly brackets “{}” to build your message. Then, inside the brackets follow the YAML syntax.
This will publish to the topic until you press CTRL+C in that terminal. If you check with ros2 topic info
, you’ll see the publisher count incremented by 1. Also you can see the data with ros2 topic echo
.
2. You want to publish one message only once:
$ ros2 topic pub -1 /greetings example_interfaces/msg/String "{data: 'Hello from terminal'}" publisher: beginning loop publishing #1: example_interfaces.msg.String(data='Hello from terminal')
Using ros2 topic pub
is quite useful when you want to test the behavior of a subscriber or network of subscribers, before you even start to write code for a publisher. Also, you may choose to send some “garbage” data to test failure cases on your subscriber side.
ros2 topic hz – Check if your publishers/subscribers manage to follow the rhythm
If you publish a very small message at 5 Hz, well, even if you’re using a 1995 computer, chances are that nothing will go wrong. But if you have to use a quite high frequency, for example 1 kHz, you may want to test if the 1 kHz is actually respected.
You can do that with ros2 topic hz
.
$ ros2 topic hz /greetings average rate: 4.977 min: 0.194s max: 0.207s std dev: 0.00428s window: 6 average rate: 5.001 min: 0.191s max: 0.209s std dev: 0.00515s window: 12 average rate: 5.001 min: 0.191s max: 0.209s std dev: 0.00447s window: 18
In the code, we defined that we want to publish at 5 Hz. Well, from the results it seems that everything is going well!
Now, in the code I will change the frequency to a much higher one, for example 2000 Hz. And let’s see what happens.
$ ros2 topic hz /greetings average rate: 1386.396 min: 0.000s max: 0.019s std dev: 0.00135s window: 1388 average rate: 1219.794 min: 0.000s max: 0.079s std dev: 0.00306s window: 2468 average rate: 1145.427 min: 0.000s max: 0.079s std dev: 0.00300s window: 3464
Uh oh, the real publishing rate is lower than the one we set. In this case it means some optimization or design revision is needed.
Of course, by running the same test, the result will depend on your computer performance. You might want to try with different frequency values.
ros2 topic bw – Check how much data is going through a Topic
This command complements ros2 topic hz
. It gives you the bandwidth used by a topic, in other words: how much bytes are transferred every second on the topic from all the publishers to all the subscribers.
$ ros2 topic bw /greetings Subscribed to [/greetings] 271 B/s from 5 messages Message size mean: 44 B min: 44 B max: 44 B 243 B/s from 10 messages Message size mean: 44 B min: 44 B max: 44 B 235 B/s from 15 messages Message size mean: 44 B min: 44 B max: 44 B
Here the bandwidth is really low, because the frequency is low (5Hz) and the message only contains one simple data field.
But let’s say you’re sending images at 10Hz, and each image is about 200 KB. So, just for this topic you’d need 2 MB/s in order to make it work correctly. If your actual available bandwidth is 1 MB/s well some messages will be late, or they won’t arrive at all.
As you can guess this command is quite useful especially for wireless networks (fleet of mobile base robots) or nodes that communicate through the Internet.
Find topic info directly from a node’s name
To complete this tutorial, know that you can also find topic information directly from nodes, without even needing to use ros2 topic list
.
Use ros2 node info on the node you want to debug.
$ ros2 node info /greetings_publisher /greetings_publisher Subscribers: Publishers: /greetings: example_interfaces/msg/String /parameter_events: rcl_interfaces/msg/ParameterEvent /rosout: rcl_interfaces/msg/Log Service Servers: /greetings_publisher/describe_parameters: rcl_interfaces/srv/DescribeParameters /greetings_publisher/get_parameter_types: rcl_interfaces/srv/GetParameterTypes /greetings_publisher/get_parameters: rcl_interfaces/srv/GetParameters /greetings_publisher/list_parameters: rcl_interfaces/srv/ListParameters /greetings_publisher/set_parameters: rcl_interfaces/srv/SetParameters /greetings_publisher/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically Service Clients: Action Servers: Action Clients:
3 important pieces of information here:
- We find the topic name “/greetings” linked to the node.
- As the topic is under “Publishers”, we know it’s a publisher (and not a subscriber).
- We also get the type of the interface, so now with
ros2 interface show
we can have all the info we need to publish/subscribe to the topic.
ros2 topic: A complete tool set to debug your Topics
ROS2 is not only about writing code. You also get a lot of tools to help you debug that code.
With the ros2 topic
command line tool you’ll be able to easily check if a publisher/subscriber is working when you develop.
From a running application, you can quickly find how to interact with nodes that already exist, without having to check their source code.
Also, it will help you diagnose problems in your graph in different situations (congested or unstable network, multi-machine setup via wireless network, etc.).
Note: if you create a custom ROS2 message, make sure to source your environment one more time in the open terminals before using ros2 topic
or ros2 interface
with it.
After topics, you can also debug services with the ros2 service command line tool.