A publisher node sends messages to other parts of a robot system. It helps share information like sensor data or commands.
Creating a publisher node in ROS
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, 'topic', 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, world! {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()
The create_publisher method sets up the topic and message type.
The timer_callback sends messages regularly.
import rclpy from rclpy.node import Node from std_msgs.msg import String class PublisherEmptyTopic(Node): def __init__(self): super().__init__('publisher_empty_topic') # Publishing to a topic with no subscribers yet self.publisher_ = self.create_publisher(String, 'empty_topic', 10) self.get_logger().info('Publisher created for empty_topic') if __name__ == '__main__': rclpy.init() node = PublisherEmptyTopic() rclpy.spin(node) node.destroy_node() rclpy.shutdown()
import rclpy from rclpy.node import Node from std_msgs.msg import String class SingleMessagePublisher(Node): def __init__(self): super().__init__('single_message_publisher') self.publisher_ = self.create_publisher(String, 'single_msg_topic', 10) msg = String() msg.data = 'Only one message' self.publisher_.publish(msg) self.get_logger().info('Published one message') if __name__ == '__main__': rclpy.init() node = SingleMessagePublisher() rclpy.spin(node) node.destroy_node() rclpy.shutdown()
import rclpy from rclpy.node import Node from std_msgs.msg import String class PublisherEndMessage(Node): def __init__(self): super().__init__('publisher_end_message') self.publisher_ = self.create_publisher(String, 'end_topic', 10) self.i = 0 self.timer = self.create_timer(1.0, self.timer_callback) def timer_callback(self): if self.i < 3: msg = String() msg.data = f'Message {self.i}' self.publisher_.publish(msg) self.get_logger().info(f'Publishing: {msg.data}') self.i += 1 else: self.get_logger().info('No more messages to publish') if __name__ == '__main__': rclpy.init() node = PublisherEndMessage() rclpy.spin(node) node.destroy_node() rclpy.shutdown()
This program creates a publisher node that sends a message every second. It prints what it sends to the console.
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, 'topic', 10) self.i = 0 self.timer = self.create_timer(1.0, self.timer_callback) def timer_callback(self): msg = String() msg.data = f'Hello, world! {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()
Publishing messages regularly uses a timer callback to automate sending.
Time complexity is O(1) for each publish call.
Common mistake: forgetting to call rclpy.spin() so the node keeps running.
Use a publisher node when you want to send data out; use a subscriber node to receive data.
A publisher node sends messages on a topic to share information.
Use create_publisher to set up the topic and message type.
Use a timer callback to send messages regularly.
Practice
Solution
Step 1: Understand the role of a publisher node
A publisher node sends messages to other nodes by publishing on a topic.Step 2: Compare options with the role
Only To send messages on a topic to share information describes sending messages on a topic, which matches the publisher's role.Final Answer:
To send messages on a topic to share information -> Option DQuick Check:
Publisher node = sends messages [OK]
- Confusing publisher with subscriber
- Thinking publisher stores data
- Assuming publisher compiles code
Solution
Step 1: Recall ROS2 Python publisher syntax
The method is called on the node instance as self.create_publisher, with message type first, then topic name, then queue size.Step 2: Check each option's syntax
self.create_publisher(String, 'topic_name', 10) matches the correct method name and argument order. self.createPublisher(String, 'topic_name', 10) has wrong method name casing. create_publisher(String, 'topic_name', 10) misses self. self.create_publisher('topic_name', String, 10) swaps argument order.Final Answer:
self.create_publisher(String, 'topic_name', 10) -> Option BQuick Check:
Correct method and argument order = self.create_publisher(String, 'topic_name', 10) [OK]
- Wrong method name casing
- Missing self when calling method
- Swapping topic name and message type
def timer_callback(self):
msg = String()
msg.data = 'Hello ROS'
self.publisher.publish(msg)
print('Published:', msg.data)Solution
Step 1: Analyze the print statement
The print outputs the string 'Published:' followed by the value of msg.data, which is 'Hello ROS'.Step 2: Confirm msg.data value
msg.data is assigned 'Hello ROS' before publishing, so the print shows 'Published: Hello ROS'.Final Answer:
Published: Hello ROS -> Option AQuick Check:
Print shows 'Published:' plus msg.data [OK]
- Printing variable name instead of value
- Assuming print shows only msg.data
- Confusing msg.data with undefined
def __init__(self):
self.publisher = self.create_publisher(String, 'chatter', 10)
def timer_callback(self):
msg = String()
msg.data = 'Hello'
self.publisher.publish(msg)
self.timer = self.create_timer(1.0, timer_callback)Solution
Step 1: Check code structure and indentation
The self.timer = self.create_timer(1.0, timer_callback) line lacks indentation and appears outside __init__ at class level, where 'self' is undefined, causing NameError.Step 2: Verify other options
A: timer_callback includes 'self'. B: create_publisher args are correct (type, topic, qos). D: msg.data = 'Hello' is valid.Final Answer:
Timer is created outside the class constructor -> Option CQuick Check:
self assignments must be inside instance methods like __init__ [OK]
- Omitting 'self' in method parameters
- Misordering create_publisher arguments
- Creating timer outside class context
Solution
Step 1: Check timer_callback method signatures
Options A and C define timer_callback(self); B omits 'self', causing AttributeError on self.i and self.publisher.Step 2: Verify increment logic
class IntPublisher(Node): def __init__(self): super().__init__('int_publisher') self.publisher = self.create_publisher(Int32, 'numbers', 10) self.i = 0 self.timer = self.create_timer(1.0, self.timer_callback) def timer_callback(self): msg = Int32() msg.data = self.i self.publisher.publish(msg) self.i += 1 initializes self.i=0 and does self.i += 1 after publishing, yielding 0,1,2,... class IntPublisher(Node): def __init__(self): super().__init__('int_publisher') self.publisher = self.create_publisher(Int32, 'numbers', 10) self.i = 0 self.timer = self.create_timer(1.0, self.timer_callback) def timer_callback(self): msg = Int32() msg.data = 0 self.publisher.publish(msg) self.i += 1 always publishes 0. class IntPublisher(Node): def __init__(self): super().__init__('int_publisher') self.publisher = self.create_publisher(Int32, 'numbers', 10) self.i = 1 self.timer = self.create_timer(1.0, self.timer_callback) def timer_callback(self): msg = Int32() msg.data = self.i self.publisher.publish(msg) self.i = 0 publishes 1 then sets self.i=0 repeatedly.Final Answer:
self.i = 0; msg.data = self.i; self.i += 1 -> Option AQuick Check:
self.i starts 0, increment after publish [OK]
- Missing 'self' in timer_callback
- Not incrementing the counter
- Resetting counter inside callback
Ready to prove it?
Pass the test and this pattern moves unknown
