ros2 topic Command Line Tool – Debug ROS2 Topics From the Terminal

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.

Want to learn how to program with ROS2?

Don't miss this opportunity:

ROS2 For Beginners - Step by Step Course


>> Learn ROS2 in 1 Week <<