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 通信架构

下面这张图展示了节点、话题、服务、动作之间的关系。我建议你多看几遍,理解它们各自的定位。

ROS2 核心通信架构 激光雷达节点 里程计节点 建图节点 导航节点 底盘控制节点 /scan (话题) /odom (话题) /get_map (服务) /follow_path (动作) 图例: 话题(单向广播) 服务(请求-响应) 动作(目标-反馈-结果)

3.7 实战小练习:用命令行观察 turtlesim

光看不练假把式。打开终端,跟我做一遍:

  1. 启动 turtlesim 模拟器:ros2 run turtlesim turtlesim_node
  2. 新开一个终端,查看节点列表:ros2 node list,你应该能看到 /turtlesim
  3. 查看话题列表:ros2 topic list,注意看 /turtle1/cmd_vel 和 /turtle1/pose
  4. 监听乌龟位姿:ros2 topic echo /turtle1/pose,你会看到实时更新的坐标数据
  5. 再开一个终端,让乌龟动起来:ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {z: 1.0}}"
  6. 观察位姿数据的变化,是不是很直观?

注意:发布话题时,消息类型和格式必须完全正确。少一个字段或者类型写错,命令就会报错。我刚开始经常因为少写一个花括号而抓狂。

好了,这一章的内容就到这里。节点、话题、服务、动作这四个概念,是 ROS2 的基石。你不需要一次全部记住,但一定要理解它们各自适合什么场景。后面几章我们会反复用到这些概念,到时候你会越来越熟悉的。