2. ROS2话题通信基础
任务目标
在ROS2中创建两个Python节点:talker发布字符串消息到话题chatter,listener订阅该话题并打印接收到的内容。通过运行这两个节点,验证话题通信链路是否打通。
环境准备
本案例基于ROS2 Humble版本,需要预先安装rclpy库(ROS2 Python客户端库,随ROS2默认安装)。创建一个ROS2工作空间并构建功能包:
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python py_topic_demo
关键完整代码
在py_topic_demo/py_topic_demo/目录下创建两个节点文件。先创建发布者节点talker.py:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class Talker(Node):
def __init__(self):
super().__init__('talker')
self.publisher = self.create_publisher(String, 'chatter', 10)
self.timer = self.create_timer(1.0, self.timer_callback)
self.count = 0
def timer_callback(self):
msg = String()
msg.data = f'Hello ROS2: {self.count}'
self.publisher.publish(msg)
self.get_logger().info(f'Publishing: "{msg.data}"')
self.count += 1
def main(args=None):
rclpy.init(args=args)
node = Talker()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
接着创建订阅者节点listener.py:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class Listener(Node):
def __init__(self):
super().__init__('listener')
self.subscription = self.create_subscription(
String, 'chatter', self.listener_callback, 10)
def listener_callback(self, msg):
self.get_logger().info(f'I heard: "{msg.data}"')
def main(args=None):
rclpy.init(args=args)
node = Listener()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
配置与构建
编辑setup.py,在entry_points中添加节点入口:
entry_points={
'console_scripts': [
'talker = py_topic_demo.talker:main',
'listener = py_topic_demo.listener:main',
],
},
构建并配置环境:
cd ~/ros2_ws
colcon build --packages-select py_topic_demo
source install/setup.bash
运行与验证
打开两个终端,分别执行以下命令:
# 终端1:运行发布者
ros2 run py_topic_demo talker
# 终端2:运行订阅者
ros2 run py_topic_demo listener
验证方法:观察终端2的listener是否持续打印I heard: "Hello ROS2: N"(N为递增数字),同时终端1的talker打印对应的发布日志。若两个终端输出内容一致且数字同步递增,说明话题通信正常。也可在第三个终端执行ros2 topic echo /chatter查看话题数据流,或使用ros2 topic list确认/chatter话题存在。
预期输出示例
终端2(listener)应显示类似内容:
[INFO] [listener]: I heard: "Hello ROS2: 0"
[INFO] [listener]: I heard: "Hello ROS2: 1"
[INFO] [listener]: I heard: "Hello ROS2: 2"
以上输出由代码逻辑直接推出:发布者每秒递增计数并发布消息,订阅者收到后打印。实际运行时应观察到持续递增的输出流。