ROS 2 Nodes and Topics
This chapter introduces two fundamental communication concepts in ROS 2: Nodes and Topics. Nodes are processes that perform computation, and Topics are the buses over which nodes exchange messages.
What is a Node?
In ROS 2, a node is essentially an executable process that performs a specific task. For example, one node might be responsible for reading data from a sensor, another for processing that data, and yet another for sending commands to a motor. ROS 2 applications are typically built as a system of many small, purpose-specific nodes.
What is a Topic?
Topics are a crucial element of the ROS 2 communication graph. They are named buses over which nodes exchange messages asynchronously. A node can publish data to a topic, or subscribe to a topic to receive data. This publish/subscribe model allows for flexible, decoupled communication between nodes.
Python Example: Publisher and Subscriber (rclpy)
Here, we will create a simple publisher and subscriber using rclpy, the Python client library for ROS 2.
Prerequisites
Ensure you have ROS 2 Humble installed and sourced.
# Source your ROS 2 environment (if not already done)
source /opt/ros/humble/setup.bash
Publisher Node
This node will publish string messages to a topic named chatter.
examples/module1/nodes_topics/publisher.py:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MinimalPublisher(Node):
def __init__(self):
super().__init__('minimal_publisher')
self.publisher_ = self.create_publisher(String, 'chatter', 10)
timer_period = 0.5 # seconds
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 0
def timer_callback(self):
msg = String()
msg.data = f'Hello ROS 2! {self.i}'
self.publisher_.publish(msg)
self.get_logger().info(f'Publishing: "{msg.data}"')
self.i += 1
def main(args=None):
rclpy.init(args=args)
minimal_publisher = MinimalPublisher()
rclpy.spin(minimal_publisher)
minimal_publisher.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Subscriber Node
This node will subscribe to the chatter topic and print the received messages.
examples/module1/nodes_topics/subscriber.py:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MinimalSubscriber(Node):
def __init__(self):
super().__init__('minimal_subscriber')
self.subscription = self.create_subscription(
String,
'chatter',
self.listener_callback,
10)
self.subscription # prevent unused variable warning
def listener_callback(self, msg):
self.get_logger().info(f'I heard: "{msg.data}"')
def main(args=None):
rclpy.init(args=args)
minimal_subscriber = MinimalSubscriber()
rclpy.spin(minimal_subscriber)
minimal_subscriber.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
How to Run
- Open two separate terminal windows.
- In each terminal, source your ROS 2 environment.
- In the first terminal, run the publisher:
python3 <path_to_your_repo>/examples/module1/nodes_topics/publisher.py - In the second terminal, run the subscriber:
python3 <path_to_your_repo>/examples/module1/nodes_topics/subscriber.py
You should see the publisher sending messages and the subscriber receiving them.
Assignment
- Modify the publisher node to publish messages to a different topic name (e.g.,
my_custom_chatter). - Update the subscriber node to listen to
my_custom_chatterinstead ofchatter. - Run both nodes and confirm they are communicating on the new topic.