第2章:ROS2核心概念速通:节点、话题、服务、动作
好,咱们直接进入正题。ROS2里最核心的四个概念——节点、话题、服务、动作,说白了就是机器人系统里不同模块之间“说话”和“办事”的四种方式。我刚开始接触ROS时,也被这些术语绕得头晕,但后来发现,只要搞懂它们分别解决什么问题,就豁然开朗了。
2.1 节点:系统的“小工人”
节点,你可以把它想象成一个独立运行的小程序,专门干一件事。比如一个节点负责读取激光雷达数据,另一个节点负责控制电机,还有一个节点负责做路径规划。每个节点都是独立的进程,互不干扰。
我个人习惯把节点比作“小工人”。一个复杂的机器人系统,就是由几十上百个这样的小工人协作完成的。每个工人只关心自己的活儿,通过某种方式跟其他工人沟通。
核心要点:
- 每个节点有唯一的名字(比如
/camera_node) - 节点可以发布或订阅话题,也可以提供服务或调用服务
- 节点之间通过DDS(数据分发服务)通信,不直接耦合
怎么验证节点是否在运行?用命令行最直接:
# 查看所有正在运行的节点
ros2 node list
# 查看某个节点的详细信息
ros2 node info /your_node_name
我在项目中遇到过一个问题:启动了好几个节点,但 ros2 node list 却只显示一个。后来发现是节点名字重复了,后启动的节点把前面的给覆盖了。嗯,这里要注意——节点名字必须唯一,否则会出乱子。
2.2 话题:一对多的“广播”
话题是ROS2里最常用的通信方式。它是一种发布-订阅模式,说白了就是“广播”。一个节点发布消息到某个话题,其他对这个话题感兴趣的节点就能收到。
举个例子:激光雷达节点不断发布扫描数据到 /scan 话题,而导航节点订阅了这个话题,就能实时拿到数据做避障。发布者和订阅者之间完全解耦,互不知道对方的存在。
我的经验:话题适合传输持续更新的数据流,比如传感器数据、状态信息。不适合做“请求-响应”式的交互。
命令行验证话题通信:
# 列出所有话题
ros2 topic list
# 查看某个话题的详细信息(类型、发布者、订阅者)
ros2 topic info /scan
# 实时打印话题内容
ros2 topic echo /scan
# 查看话题的数据频率
ros2 topic hz /scan
我曾经调试一个机器人,发现导航总是不稳定。用 ros2 topic hz /odom 一看,里程计数据的发布频率忽高忽低,最低时只有5Hz。后来发现是CPU负载太高,导致里程计算法被卡住了。你看,命令行一查,问题就暴露了。
2.3 服务:一问一答的“请求-响应”
话题是单向的广播,服务则是双向的“请求-响应”。一个节点提供某个服务,另一个节点调用它,然后等待结果。这就像你打电话问客服:“我的订单到哪了?”客服查一下,然后告诉你结果。
服务适合那些需要立即得到结果的场景,比如“打开机械臂”、“获取当前位姿”。它不像话题那样持续发送数据,而是按需触发。
# 列出所有服务
ros2 service list
# 查看某个服务的类型和结构
ros2 service type /your_service
# 调用服务(以/spawn为例,在turtlesim中生成新乌龟)
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2.0, y: 2.0, theta: 0.0, name: 'turtle2'}"
注意:服务调用是同步的,调用方会阻塞等待结果。如果服务端处理时间很长,整个节点可能会卡住。我曾经在项目里用服务去控制一个需要5秒才能完成的动作,结果整个系统都僵住了。后来改用动作,才解决了这个问题。
2.4 动作:带反馈的“长期任务”
动作是ROS2里最强大的通信方式,专门处理那些需要较长时间才能完成的任务。它结合了话题和服务的特点:
- 调用方发送一个目标(类似服务请求)
- 执行方持续反馈进度(类似话题发布)
- 任务完成后返回最终结果(类似服务响应)
- 支持中途取消任务
你想想看,让机器人从A点走到B点,这需要好几秒甚至更久。如果用服务,调用方就得傻等。用动作就灵活多了——你可以实时查看走到哪了,随时可以喊停。
# 列出所有动作
ros2 action list
# 查看某个动作的详细信息
ros2 action info /your_action
# 发送动作目标(以/navigate_to_pose为例)
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: {header: {frame_id: 'map'}, pose: {position: {x: 1.0, y: 2.0, z: 0.0}}}}"
什么时候用哪个?一张表说清楚:
| 通信方式 | 适用场景 | 典型例子 |
|---|---|---|
| 话题 | 持续更新的数据流 | 激光雷达数据、摄像头图像 |
| 服务 | 快速、同步的请求-响应 | 获取当前位姿、设置参数 |
| 动作 | 长时间任务,需要反馈和取消 | 导航、机械臂运动 |
2.5 实战:用命令行验证通信
光说不练假把式。咱们用ROS2自带的turtlesim小乌龟模拟器,亲手验证一下这些通信方式。
第一步:启动节点
# 启动乌龟模拟器节点
ros2 run turtlesim turtlesim_node
# 启动键盘控制节点
ros2 run turtlesim turtle_teleop_key
这时候你打开另一个终端,用 ros2 node list 就能看到两个节点在运行。
第二步:验证话题通信
# 查看话题列表,你会看到 /turtle1/cmd_vel 和 /turtle1/pose
ros2 topic list
# 实时查看乌龟的位置变化
ros2 topic echo /turtle1/pose
当你用键盘控制乌龟移动时,/turtle1/pose 话题会不断输出位置数据。这就是话题通信的实时体现。
第三步:验证服务通信
# 生成一只新乌龟
ros2 service call /spawn turtlesim/srv/Spawn "{x: 5.0, y: 5.0, theta: 0.0, name: 'turtle2'}"
# 清除所有轨迹
ros2 service call /clear std_srvs/srv/Empty
调用服务后,你会立刻看到新乌龟出现在屏幕上,或者轨迹被清除。这就是服务的“一问一答”效果。
第四步:验证动作通信
turtlesim本身没有动作示例,但你可以用 ros2 action list 查看系统中是否有动作服务器在运行。在更复杂的系统中(比如Nav2导航栈),动作通信非常常见。
避坑指南:我曾经在调试时,用 ros2 topic echo 打印一个高频话题(比如IMU数据,100Hz),结果终端刷屏刷到卡死。建议加上 --once 参数只打印一次,或者用 --csv 导出到文件分析。
小结
节点、话题、服务、动作,这四个概念是ROS2的基石。节点是执行单元,话题是广播通道,服务是同步请求,动作是带反馈的长期任务。用命令行工具去验证它们,是每个ROS2开发者必须掌握的技能。
下一章,咱们会深入话题通信,手写一个发布者和订阅者,把今天学的理论变成真正的代码。到时候你会发现,理解了这些概念,写代码就是水到渠成的事。