2. 发布订阅基础通信
任务目标
编写两个ROS 2节点:一个发布者周期性发送字符串消息,一个订阅者接收并打印日志,验证ROS 2基础通信机制。
环境依赖
- Ubuntu 22.04 + ROS 2 Humble(或其他已安装的ROS 2发行版)
- 已创建ROS 2工作空间(如
~/ros2_ws/src) - Python 3 +
rclpy库
完整实现
在~/ros2_ws/src/下创建包talker_listener,包含以下两个节点文件:
# 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 ROS 2: {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'Received: "{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()
编译与运行
- 创建包并添加依赖:
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python talker_listener
# 将上述两个.py文件放入 talker_listener/talker_listener/ 目录
# 编辑 setup.py,在 entry_points 中添加:
# 'talker = talker_listener.talker:main',
# 'listener = talker_listener.listener:main',
- 编译并source:
cd ~/ros2_ws
colcon build --packages-select talker_listener
source install/setup.bash
- 运行(两个终端):
# 终端1
ros2 run talker_listener talker
# 终端2
ros2 run talker_listener listener
验证方法
观察终端2的listener节点是否持续打印Received: "Hello ROS 2: N"(N为递增数字),且与终端1发布者打印的Publishing内容一致。若两个终端均正常输出且消息编号同步递增,则通信验证通过。
也可用命令行工具验证:
ros2 topic list # 应看到 /chatter
ros2 topic echo /chatter # 应看到 String 消息内容
常见问题
- 找不到包:确认已执行
source install/setup.bash且包名拼写正确。 - 消息不匹配:检查发布者与订阅者是否使用相同话题名
chatter和消息类型std_msgs/String。 - 编译报错:确认
setup.py中entry_points格式正确,且package.xml已声明对std_msgs和rclpy的依赖。