3. 任务通信模型

在 ROS 2 中,节点之间的数据交换并不是只有一种方式。话题、服务、动作构成了最常用的三种任务通信模型,它们分别面向“持续数据流”“短时请求响应”“长时可控任务”三类典型需求。理解三者的通信机制、QoS 策略与性能特征,是进行任务通信与行为编排设计的基础。

核心判断原则:先看任务是否需要“持续反馈”和“可取消”,再看是否需要“服务端主动执行并返回结果”,最后才考虑是否只是单向广播数据。选错通信模型,往往会导致系统结构复杂、实时性下降或资源浪费。

一、三种通信模型的通信机制

话题(Topic)采用发布/订阅模型。发布者将消息写入某个话题,订阅者异步接收,双方不需要知道对方是否存在。它适合传感器数据、状态广播、图像流、里程计等高频、单向、持续的数据传输。话题通信是松耦合的,一个发布者可以对应多个订阅者,一个订阅者也可以订阅多个话题。

服务(Service)采用请求/响应模型。客户端发送一次请求,服务端处理后返回一次响应。它适合“问一次、答一次”的短时操作,例如查询参数、触发标定、读取设备状态、执行一次简单计算。服务是同步或异步等待结果的,通信双方存在明确的角色关系:客户端发起,服务端响应。

动作(Action)建立在话题和服务之上,采用“目标—反馈—结果”的长时任务模型。客户端发送目标,服务端持续反馈执行进度,最终返回结果,并支持取消目标。它适合导航到某点、机械臂抓取、旋转指定角度、执行一段轨迹等需要时间、需要监控、可能中途取消的任务。

ROS 2 三种任务通信模型对比 话题 Topic 发布者 订阅者 持续数据流 • 单向、异步、松耦合 • 高频、多对多 • 无返回结果 • 适合传感器/状态广播 QoS:可靠性/历史/深度/寿命 服务 Service 客户端 服务端 请求 / 响应 • 一问一答、短时完成 • 同步或异步等待 • 有明确返回结果 • 适合查询/触发/标定 QoS:可靠性/深度/寿命 动作 Action 客户端 服务端 目标 / 反馈 / 结果 • 长时任务、可取消 • 持续反馈进度 • 最终返回结果 • 适合导航/抓取/轨迹 QoS:目标/反馈/结果独立配置

二、适用场景与选择方法

选择通信模型时,可以按以下顺序判断:

  1. 是否需要持续、高频地传输数据?如果是,优先选话题。例如激光雷达、摄像头、IMU、关节状态。
  2. 是否只需要一次请求、一次响应?如果是,优先选服务。例如查询电池电量、设置参数、触发一次标定。
  3. 任务是否需要较长时间执行,并且需要反馈进度或允许取消?如果是,优先选动作。例如导航到目标点、机械臂抓取、旋转指定角度。
  4. 是否既需要状态广播,又需要任务控制?可以组合使用:话题负责状态流,服务负责配置,动作负责长时任务。
一个常见误区是“用话题模拟服务”:发布请求后等待另一个话题返回结果。这样虽然能跑通,但会丢失服务本身的请求/响应语义,错误处理、超时控制和接口约束都会变差。能用服务表达的一次性交互,不要用两个话题硬拼。

三、QoS 策略差异

QoS 是 ROS 2 通信质量的关键配置。话题、服务、动作都支持 QoS,但关注点不同。话题最常配置可靠性、历史策略、队列深度和寿命;服务通常关注可靠性和队列深度;动作则把目标、反馈、结果拆成多个通信通道,可以分别配置 QoS。

通信模型 典型 QoS 关注点 常见配置建议 适用场景
话题 可靠性、历史、深度、寿命 传感器用 Best Effort + Keep Last;控制指令用 Reliable 高频数据流、状态广播
服务 可靠性、深度 默认 Reliable,深度不宜过大 短时请求响应
动作 目标、反馈、结果分别配置 目标/结果 Reliable;反馈可 Best Effort 长时任务、可取消任务

例如,对于高频激光雷达话题,如果使用 Reliable 且队列过深,网络拥塞时可能造成延迟累积;对于导航动作的反馈,如果使用 Best Effort,可以降低带宽压力,但客户端可能丢失部分进度更新。QoS 配置没有绝对最优,必须结合链路质量和任务容忍度来定。

四、性能对比与工程案例

从性能角度看,话题的吞吐量最高、延迟最低,适合大数据量持续传输;服务的延迟取决于服务端处理时间,通常用于短时操作;动作因为包含目标、反馈、结果多个阶段,整体时延最长,但可控性最好。

# 查看话题 QoS 配置
ros2 topic info /scan --verbose

# 查看服务列表与类型
ros2 service list -t

# 查看动作列表与类型
ros2 action list -t

# 发送一个动作目标
ros2 action send_goal /turtle1/rotate_absolute \
  turtlesim/action/RotateAbsolute "{theta: 1.57}" --feedback

以一个移动机器人任务为例:激光雷达和里程计使用话题持续发布;电池查询、参数设置使用服务;导航到目标点使用动作。这样划分后,数据流、配置流和任务流各自独立,系统结构清晰,调试也更容易。

复盘时重点检查三件事:第一,是否把长时任务错误地做成了服务,导致客户端长时间阻塞;第二,是否把高频数据错误地做成了服务,导致请求堆积;第三,是否忽略了 QoS 兼容性,导致发布者和订阅者无法建立连接。很多“通信不上”的问题,根源不是代码错误,而是模型选型或 QoS 配置不匹配。

总结来说,话题、服务、动作不是互相替代的关系,而是面向不同任务粒度的通信工具。话题解决“持续数据流”,服务解决“短时请求响应”,动作解决“长时可控任务”。在实际工程中,先明确任务语义,再匹配通信模型,最后配置 QoS,才能构建出稳定、可维护的 ROS 2 任务通信与行为编排系统。