3. ROS2 核心概念:节点、话题、服务、动作
说实话,刚接触 ROS2 的时候,我也被这些概念搞得有点晕。节点、话题、服务、动作——听起来都挺抽象。但别担心,我带你用最直白的方式把它们捋清楚。
你想想看,一个机器人系统就像一家公司。每个员工各司其职,互相配合。ROS2 的这几个核心概念,说白了就是让机器人里的各个模块能高效协作的机制。
一句话总结:节点是干活的人,话题是广播喇叭,服务是打电话问答案,动作是派一个长期任务并随时汇报进度。
3.1 节点(Node)—— 机器人的每个“小员工”
节点就是 ROS2 系统里的最小执行单元。每个节点负责一个具体的功能。比如激光雷达驱动是一个节点,里程计计算是一个节点,路径规划又是一个节点。
我个人习惯把节点想象成乐高积木。每个积木块功能单一,但拼在一起就能搭出复杂的机器人系统。这样做的好处是——某个节点崩了,不会拖垮整个系统。
我的经验:刚开始写 ROS2 程序时,我总喜欢把一堆功能塞进一个节点里。后来调试时发现,改一个功能就得重启整个节点,太痛苦了。现在我的原则是:一个节点只做一件事,做好它。
3.2 话题(Topic)—— 广播式的“喊话”
话题是 ROS2 里最常用的通信方式。它是异步的、一对多的。发布者只管往外发数据,订阅者只管收数据,双方不需要知道对方的存在。
举个例子:激光雷达节点不断发布扫描数据到 /scan 话题。任何需要激光数据的节点——比如建图节点、避障节点——都可以订阅这个话题。发布者不需要关心谁在听,订阅者也不需要关心谁在发。
这种模式特别适合传感器数据这种高频、实时的信息流。
注意:话题通信没有反馈机制。发布者发完就完了,它不知道订阅者有没有收到、处理得怎么样。如果你需要确认对方收到了,那就得用服务或动作。
3.3 服务(Service)—— 打电话式的“请求-应答”
服务和话题最大的区别是:服务是同步的、有反馈的。客户端发一个请求,服务端处理完返回一个响应。就像你打电话问客服:“我的订单到哪了?”客服查完告诉你结果。
服务适合那些需要即时确认的场景。比如你让机械臂移动到某个位置,你得知道它到底到没到。
| 通信方式 | 方向 | 是否同步 | 典型场景 |
|---|---|---|---|
| 话题 | 单向流 | 异步 | 传感器数据、状态发布 |
| 服务 | 请求-响应 | 同步 | 查询参数、触发动作 |
| 动作 | 目标-反馈-结果 | 异步+反馈 | 导航、机械臂控制 |
3.4 动作(Action)—— 派一个“长期任务”
动作是 ROS2 里最复杂的通信方式,但也是最强大的。它专门用于那些需要长时间执行、并且需要中途反馈的任务。
比如你让机器人从 A 点导航到 B 点。这个过程可能持续几十秒甚至几分钟。你不仅想知道最终结果(到了没),还想知道中途的状态(走到哪了、还剩多少距离)。
动作的机制是:客户端发送一个目标,服务端开始执行,同时不断发送反馈。执行完毕后,再发送最终结果。
我记得第一次用动作写导航程序时,被它的三个回调函数搞得有点懵。但用顺了之后,你会发现它真的比手动写话题+服务组合要优雅得多。
核心区别:
- 话题:单向广播,适合高频数据流
- 服务:一问一答,适合即时查询
- 动作:长期任务+中途反馈,适合复杂流程
3.5 用命令行工具做通信测试
理论说完了,咱们来点实际的。ROS2 提供了一套命令行工具,可以让你在不写一行代码的情况下,观察节点之间的通信。
3.5.1 查看节点列表
ros2 node list
这个命令会列出当前系统中所有活跃的节点。如果你刚启动一个激光雷达驱动,应该能看到类似 /lidar_driver 这样的节点名。
3.5.2 查看话题列表
ros2 topic list
列出所有活跃的话题。加上 -t 参数还能看到话题的类型。
3.5.3 监听话题数据
ros2 topic echo /scan
这是我最常用的调试命令之一。它会实时打印话题上的数据流。比如监听 /scan 话题,你就能看到激光雷达每一帧的扫描数据。
避坑指南:我曾经在调试时发现 topic echo 没有输出,折腾了半天才发现是话题名拼错了。ROS2 的话题名是大小写敏感的,/Scan 和 /scan 是两个完全不同的话题。
3.5.4 调用服务
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.0, name: 'turtle2'}"
这个命令会调用一个服务,并等待返回结果。上面这个例子是在 turtlesim 模拟器中生成一只新乌龟。
3.5.5 查看动作列表
ros2 action list
列出所有可用的动作。加上 -t 可以查看动作的类型。
3.6 一张图看懂 ROS2 通信架构
下面这张图展示了节点、话题、服务、动作之间的关系。我建议你多看几遍,理解它们各自的定位。
3.7 实战小练习:用命令行观察 turtlesim
光看不练假把式。打开终端,跟我做一遍:
- 启动 turtlesim 模拟器:
ros2 run turtlesim turtlesim_node - 新开一个终端,查看节点列表:
ros2 node list,你应该能看到/turtlesim - 查看话题列表:
ros2 topic list,注意看/turtle1/cmd_vel和/turtle1/pose - 监听乌龟位姿:
ros2 topic echo /turtle1/pose,你会看到实时更新的坐标数据 - 再开一个终端,让乌龟动起来:
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {z: 1.0}}" - 观察位姿数据的变化,是不是很直观?
注意:发布话题时,消息类型和格式必须完全正确。少一个字段或者类型写错,命令就会报错。我刚开始经常因为少写一个花括号而抓狂。
好了,这一章的内容就到这里。节点、话题、服务、动作这四个概念,是 ROS2 的基石。你不需要一次全部记住,但一定要理解它们各自适合什么场景。后面几章我们会反复用到这些概念,到时候你会越来越熟悉的。