Understanding ROS2 Topics: The Lifeline of Robot Communication


Concept and Functionality

Welcome back! Today, we’re diving into one of the most fascinating aspects of ROS2: Topics. If you’ve ever wondered how different parts of a robot share information seamlessly, you’re in for a treat. Let’s unpack the magic behind ROS2 Topics and discover how they keep robotic systems ticking.

What are ROS2 Topics?

Imagine you’re in a bustling city, and you want to send a message to a friend across town. Instead of calling or texting directly, you drop a letter into a mailbox. Your friend, who checks that mailbox, will eventually get your message. This mailbox is analogous to a topic in ROS2. It’s a shared conduit for messages between different parts of a robot.

  • Topics: In ROS2, topics are named buses over which nodes (the various components of your robot) can send and receive messages. Think of them as radio channels. If two nodes tune into the same channel (topic), they can communicate.

Messages, Publishers, and Subscribers

To understand how topics work, we need to talk about messages, publishers, and subscribers.

  • Messages: These are the data packets sent over topics. They can contain anything from sensor readings to command signals. ROS2 uses predefined message types, such as std_msgs/String for text or sensor_msgs/Image for images, to ensure compatibility.

  • Publishers: Nodes that generate and send messages are called publishers. They create a topic and push messages to it, like a radio station broadcasting its signal.

  • Subscribers: Nodes that receive messages from a topic are called subscribers. They tune into a specific topic and process incoming messages, just like a radio picks up a broadcast.

This publish-subscribe model is powerful because it decouples data producers and consumers. A publisher doesn’t need to know who (or if anyone) is subscribing, and subscribers don’t need to know who is publishing. This makes the system incredibly flexible and scalable.

A node may publish data to any number of topics and simultaneously have subscriptions to any number of topics.

Topics are one of the main ways in which data is moved between nodes and therefore between different parts of the system.


Practical Example

Let’s see these concepts in action with a simple example: a publisher-subscriber setup where one node sends greetings and another receives them.

Publisher Node (Python)

# The ROS 2 Python client library
import rclpy 
# The base class that you inherit from to create a ROS 2 node.
from rclpy.node import Node 
# The standard ROS message type used for publishing string data
from std_msgs.msg import String 

class SimplePublisher(Node):
    def __init__(self):
        super().__init__('simple_publisher')

        # Creates a publisher that will send messages of type String to 
        # the topic greetings_topic. 
        # The 10 refers to the message queue size 
        # (how many messages can be queued before dropping them)
        self.publisher_ = self.create_publisher(String, 'greetings_topic', 10)
        timer_period = 1.0  # seconds'
        
        # Sets up a timer that calls the timer_callback function every second
        self.timer = self.create_timer(timer_period, self.timer_callback)

    def timer_callback(self):
        msg = String() # Creates a new message of type String
        msg.data = 'Hello, ROS2!' # Sets the message content to 'Hello, ROS2!'
        self.publisher_.publish(msg) # Publishes the message to the greetings_topic
        self.get_logger().info(f'Publishing: {msg.data}')

def main(args=None):

    # Initializes the rclpy library, which is required to use ROS 2
    rclpy.init(args=args) 

    # Creates an instance of the SimplePublisher node.
    node = SimplePublisher() 

    # Enters a loop where the node keeps running and responds to ROS 2 events 
    rclpy.spin(node) 

    # Cleans up and shuts down the node.
    node.destroy_node() 

    # Shuts down the rclpy library when the node stops spinning.
    rclpy.shutdown() 

if __name__ == '__main__':
    main()

Subscriber Node (Python)

import rclpy 
from rclpy.node import Node 
from std_msgs.msg import String 

# SimplePublisher(Node): Inherits from Node to create 
# a ROS 2 node called simple_publisher
class SimpleSubscriber(Node):
    def __init__(self):
        super().__init__('simple_subscriber')
       

        # Creates a subscription to the topic greetings_topic 
        # where the messages are of type String. 
        # Whenever a message is received on this topic
        # the listener_callback function is called
        self.subscription = self.create_subscription(
            String,
            'greetings_topic',
            self.listener_callback,
            10) 
        self.subscription  # prevent unused variable warning
    
    # This method is called whenever a message is received on the greetings_topic.
    def listener_callback(self, msg):
        self.get_logger().info(f'Subscribed: {msg.data}') 

def main(args=None):
    rclpy.init(args=args)
    node = SimpleSubscriber()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Here, the SimplePublisher node sends a greeting message "Hello, ROS2!" every second on the greetings_topic. The SimpleSubscriber node listens to this topic and prints the message it receives. This simple interaction demonstrates how topics facilitate communication in ROS2.

Expected Output:

When you run the publisher and subscriber nodes, you should see output like this in the console:

Publisher Node Output:

[INFO] [SimplePublisher]: Publishing: Hello, ROS2!
[INFO] [SimplePublisher]: Publishing: Hello, ROS2!
[INFO] [SimplePublisher]: Publishing: Hello, ROS2!

Subscriber Node Output:

[INFO] [SimpleSubscriber]: Subscribed: Hello, ROS2!
[INFO] [SimpleSubscriber]: Subscribed: Hello, ROS2!
[INFO] [SimpleSubscriber]: Subscribed: Hello, ROS2!

ROS CLI Commands

ROS2 provides a powerful command-line interface (CLI) for interacting with topics. Here are some essential commands that will make your life easier:

  • Listing Topics

    ros2 topic list
    

    Use this command to see all active topics in your ROS2 system. It’s like scanning for all available radio stations.

  • Echoing Topic Messages

    ros2 topic echo /greetings_topic
    

    This command prints messages being published on a topic in real-time. It’s useful for debugging and monitoring the data flow.

  • Publishing Messages

    ros2 topic pub /greetings_topic std_msgs/String "data: 'Hello from CLI!'"
    

    Manually publish a message to a topic from the command line. It’s a quick way to test your subscribers.


Why Topics Matter

Understanding topics is crucial because they form the backbone of communication in ROS2. They allow you to build modular, scalable, and efficient robotic systems. Whether it’s a simple robot with a few sensors or a complex multi-robot system, mastering topics will enable you to design robust communication architectures.

In part 2 of communication overview, we’ll explore ROS2 Services and Actions, which add even more capabilities to your robotic systems. Stay tuned, and keep experimenting with topics to see how they can enhance your projects!