Implementing ROS Topic Communication in Python
Overview
Establishing topic-based communication in ROS involves creating distinct nodes that act as a Publisher and a Subscriber. The Publisher handles the generation and transmission of data, while the Subscriber listens for specific messages and executes a callback function upon receipt. The connection handshake and master management are handled internally by the ROS core.
Publisher Implementation
The Publisher node is responsible for initializing the communication interface and broadcasting messages at a set frequency. Below is a Python implementation that broadcasts a status string.
#!/usr/bin/env python3
import rospy
from std_msgs.msg import String
def broadcast_status():
# Initialize the ROS node with a unique name
rospy.init_node('status_broadcaster', anonymous=True)
# Create a Publisher object for the 'network_state' topic
# Queue size is set to 10 to buffer messages
state_pub = rospy.Publisher('network_state', String, queue_size=10)
# Define a loop rate of 2 Hz
rate = rospy.Rate(2)
while not rospy.is_shutdown():
# Instantiate the message object
transmission = String()
transmission.data = "system_operational"
# Publish the data to the topic
state_pub.publish(transmission)
# Sleep to maintain the loop rate
rate.sleep()
if __name__ == '__main__':
try:
broadcast_status()
except rospy.ROSInterruptException:
pass
This script initializes a node named status_broadcaster. It defines a publisher targeting the network_state topic using the std_msgs/String message type. Inside the while loop, the script constructs a string message containing "system_operational" and publishes it. The rospy.Rate(2) call ensures the loop executes approximately twice per second.
Subscriber Implementation
The Subscriber node listens to the specific topic and processes incoming data. The primary logic resides within a callback function triggered whenever a new message arrives.
#!/usr/bin/env python3
import rospy
from std_msgs.msg import String
def data_callback(received_message):
"""Callback function to handle incoming messages."""
rospy.loginfo("Log received: %s", received_message.data)
def listener_node():
# Initialize the ROS node
rospy.init_node('state_monitor', anonymous=True)
# Subscribe to the 'network_state' topic
# 'data_callback' will be invoked when a message is received
rospy.Subscriber('network_state', String, data_callback)
# Keep the node running and listening for events
rospy.spin()
if __name__ == '__main__':
listener_node()
This code sets up a node named state_monitor. The rospy.Subscriber function links to the network_state topic. When a message is detected, the data_callback function executes automatically, logging the content of the message to the console. The rospy.spin() function blocks the program from exiting, ensuring the node remains active to process incoming traffic.
Configuration and Execution
To make the Python scripts executable, the file permissions must be modified using chmod +x. Additionally, the CMakeLists.txt file within the package requires configuration to install the Python scripts into the appropriate directory. Standard practice involves using the catkin_install_python() macro to define the executable targets.