ROS2 核心概念:节点、话题、服务、动作、参数与图
ROS2 的软件架构建立在一组清晰的核心抽象之上。如果把机器人系统比作一个团队,节点就是每个成员,话题是公开的白板,服务是点对点的问答,动作是长期任务的下达与反馈,参数则是成员的可调配置。理解这些概念之间的区别与协作方式,是掌握 ROS2 开发的第一步。
核心原理:六类基本概念
| 概念 | 通信模式 | 关键特征 | 典型用途 |
|---|---|---|---|
| 节点 (Node) | — | 可执行的最小单元,拥有唯一名称 | 封装传感器驱动、算法、控制逻辑 |
| 话题 (Topic) | 发布/订阅 (异步) | 一对多、多对多,数据流持续单向 | 图像流、激光扫描、里程计、状态发布 |
| 服务 (Service) | 请求/响应 (同步) | 一次性调用,有超时机制 | 开关灯、获取地图、设置参数快照 |
| 动作 (Action) | 目标/反馈/结果 (长时) | 可取消、可反馈进度、可预empt | 导航到目标点、机械臂抓取、路径跟踪 |
| 参数 (Parameter) | 键值存储 | 运行时动态读写,可持久化 | PID 系数、最大速度、传感器频率 |
| 图 (Graph) | 全局拓扑 | 描述所有节点与通信关系的网络 | 系统监控、调试、运行时发现 |
核心要点:话题是“持续广播”,服务是“一问一答”,动作是“带反馈的长任务”。节点通过图(Graph)机制自动发现彼此,无需手动配置 IP 地址。
方法流程:节点间通信的三种模式
在 ROS2 中,节点之间的交互方式决定了系统的实时性、可靠性和复杂度。选择正确的通信模式是架构设计的关键。
- 话题通信(异步、持续):发布者将消息放入 DDS 中间件,订阅者异步接收。适用于高频数据流,如激光雷达扫描、摄像头图像、IMU 数据。多个订阅者可以同时接收同一话题,实现一对多解耦。
- 服务通信(同步、一次性):客户端发送请求后阻塞等待服务端响应。适用于低频、需要确认结果的交互,如“打开机械臂夹爪”“查询当前地图”。服务不适合高频调用,因为同步等待会阻塞调用方。
- 动作通信(长时、可反馈):动作客户端发送目标,服务端返回“已接收”后开始执行,期间持续发送反馈(如进度百分比),最终返回结果。动作支持取消和抢占(新目标替换旧目标),适合导航、机械臂规划等耗时操作。
选择建议:如果数据是“持续产生且不需要回复”,用话题;如果“需要立即得到结果且频率低”,用服务;如果“任务耗时数秒以上且需要进度反馈”,用动作。
案例场景:机器人导航中的概念协作
以移动机器人执行“从 A 点导航到 B 点”为例,观察各概念如何协同工作:
- 传感器节点(/lidar_driver)通过话题
/scan持续发布激光数据。 - 定位节点(/amcl)订阅
/scan和/odom,通过话题/amcl_pose发布机器人当前位姿。 - 导航节点(/nav2_controller)订阅
/amcl_pose和/map,计算路径后通过话题/cmd_vel发布速度指令。 - 底盘驱动节点(/motor_controller)订阅
/cmd_vel,将速度指令转换为电机 PWM 信号。 - 用户通过动作客户端向导航节点发送
/navigate_to_pose目标,导航节点反馈“已到达 50%”等进度。 - 若需要临时打开机器人上的指示灯,用户调用服务
/set_led_state,同步等待“成功/失败”响应。 - 所有节点的 PID 参数、最大速度等通过参数动态调整,无需重新编译。
# 查看当前图结构
ros2 node list
ros2 topic list
ros2 service list
ros2 action list
# 查看话题数据流
ros2 topic echo /scan --once
# 调用服务
ros2 service call /set_led_state std_srvs/srv/SetBool "{data: true}"
# 发送动作目标
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: {pose: {position: {x: 2.0, y: 1.0}}}}"
误区与复盘:常见理解偏差
误区一:把服务当话题用。 有开发者试图用服务高频传输传感器数据,导致调用方阻塞、系统卡顿。正确做法:高频数据一律走话题,服务只用于低频控制指令。
误区二:忽略动作的反馈机制。 动作的反馈通道是设计亮点,但很多初学者只关心最终结果,不处理 feedback,导致无法监控任务进度。应始终订阅反馈以更新状态显示或做异常判断。
误区三:混淆参数与话题。 参数适合低频配置(如 PID 系数),不适合传输高频状态(如当前速度)。参数变化不会产生消息流,需要主动读取或监听参数事件。
复盘要点:ROS2 的图(Graph)机制让所有节点在运行时动态发现彼此,无需静态配置。使用 rqt_graph 可以可视化当前通信拓扑,是排查“节点间为何没有数据”的首选工具。若话题没有数据,先检查发布者是否在运行、话题名称是否拼写一致、消息类型是否匹配。