Creating a custom subscriber to a topic in ROS 2
Last update: 05-19-2024
In the world of ROS2 (Robot Operating System 2), communication between different parts of a robotic system is facilitated by publishers and subscribers using a messaging system. In this blog post, we'll focus on implementing the subscriber side of a communication system in ROS2. We will use an existing publisher example, the 'talker' node from the 'demo_nodes_cpp' package, to provide the messages that our subscriber will receive.
I'm going to assume that you already have a ROS2 workspace. If you need a refresher on that, please refer to my previous blog post which covers the basics of creating a workspace and a package.
Introduction to Subscriber Nodes
A subscriber node in ROS2 is responsible for receiving messages from a topic to which it is subscribed. Topics are named buses over which nodes exchange messages. Subscribers and publishers communicate asynchronously through these topics.
Setting Up the Publisher
Let's start the publisher:
ros2 run demo_nodes_cpp talker
This command runs the 'talker' node, which publishes messages to a topic.
Identifying the Topic
Next, we need to identify the topic to which our subscriber should listen. To list all active topics, use:
ros2 topic list
Among the listed topics, you should find /chatter, which is the topic used by the 'talker' node.
Finding the Message Type
To subscribe correctly, we need to know the type of messages sent to /chatter. Run:
ros2 topic info /chatter
Investigating the result of this command, we learn that the type of the topic is std_msgs/msg/String (the class String
in the std_msgs/msg
module).
Analyzing the Message Type
Understanding the message structure is crucial. To see the details of the String type, execute:
ros2 interface show std_msgs/msg/String
This command shows the structure of the String message type. You will see a field named data
of type string. This data
field is the payload of the message and the main part of interest for our subscriber.
Creating the Package
Equipped with the insights about our topic and its messages, let's move on to creating our subscriber.
First, we'll create a new package:
cd ~/ros2_ws/src
ros2 pkg create pub_sub_pkg --build-type ament_python --dependencies rclpy
And in this package, let's create the Python file for our new node:
touch ~/ros2_ws/src/pub_sub_pkg/pub_sub_pkg/sub_node.py
Subscriber Node Implementation
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class ExampleSubNode(Node):
def __init__(self):
super().__init__("sub1_node")
self.get_logger().info("Subscribing...")
self.create_subscription(
String,
'/chatter',
self.msg_callback,
10)
def msg_callback(self, msg):
self.get_logger().info(msg.data)
def main(args=None):
rclpy.init(args=args)
node = ExampleSubNode()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == '__main__':
main()
Explanation of the code
- from std_msgs.msg import String: We include this specific import because our analysis of the message type (
std_msgs/msg/String
) revealed that the messages published to /chatter are of type String. - In our constructor, we initialize the node with the name sub1_node.
- We then call the
create_subscription
method. We pass four parameters: the type (String
, as we saw before), the topic to subscribe to ('/chatter'), the callback function to handle incoming messages, and the message queue size. - The callback function extracts the 'data' field from the message (that's the field of actual data in the message, as we saw before).
Adding the node to the package
Let's add our node to the console_scripts array in the package's setup.py:
'console_scripts': [
'sub_node = pub_sub_pkg.sub_node:main'
],
Building and Sourcing the Workspace
Before running the subscriber node, we need to build the workspace and source it:
cd ~/ros2_ws
colcon build
source ~/.bashrc
Running the Subscriber Node
To run your subscriber and start listening to messages, open a new terminal window and run:
ros2 run pub_sub_pkg sub_node
Once started, our subscriber node will begin listening continuously to the /chatter
topic. You should immediately start seeing logs of incoming messages, indicating that your node is actively receiving data from the publisher.
To sum up
We just created our first subscriber node in ROS2. Creating a subscriber node is a fundamental skill for anyone looking to build robust and interactive robotic applications. By subscribing to topics, nodes can communicate and coordinate actions within a larger system, making them an integral part of the ROS2 ecosystem.