相机话题明明存在,订阅节点却一条消息也收不到;把 reliable 改成 best_effort 后突然正常。ROS 2 的 QoS 不是“网络优化参数”,它是发布者与订阅者之间的数据契约。策略不兼容时,双方甚至不会建立有效通信。
先看实际 QoS
1 | ros2 topic info /camera/image_raw --verbose |
--verbose 会显示端点和 QoS。排查“话题有但没数据”时,先比较发布者与订阅者的 reliability、durability 和其他策略,不要只重启节点。
兼容性要从“发布者提供什么、订阅者要求什么”这个方向看。下面这张表只列最容易踩到的两组策略:
| 发布者提供 | 订阅者请求 | 能否匹配 | 原因 |
|---|---|---|---|
| Reliable | Reliable | 可以 | 发布端满足可靠传输请求 |
| Reliable | Best Effort | 可以 | 订阅端接受较弱保证 |
| Best Effort | Best Effort | 可以 | 双方都允许丢失 |
| Best Effort | Reliable | 不可以 | 发布端无法满足可靠请求 |
| Transient Local | Volatile | 可以 | 发布端能力高于订阅要求 |
| Volatile | Transient Local | 不可以 | 发布端没有历史样本可交付 |
depth 并不按较大值自动协商。发布者和订阅者各自维护队列,较大的订阅队列也补不回网络上已经丢掉的样本。
用两个进程复现 QoS 不兼容
下面的脚本既能当发布者,也能当订阅者。它只依赖 rclpy 和 std_msgs,保存为 qos_probe.py 后即可运行。
1 | import sys |
先在终端 A 启动一个只提供 Best Effort 的发布者:
1 | source /opt/ros/jazzy/setup.bash |
终端 B 请求 Reliable,正常结果是发现端点但收不到样本;改成 Best Effort 后应该持续看到计数。
1 | source /opt/ros/jazzy/setup.bash |
同时运行 ros2 topic info /qos_probe --verbose,把“不出数据”对应到两端的实际策略。这个实验只验证端点兼容性,不模拟 Wi-Fi 丢包,也不能比较 Reliable 和 Best Effort 的尾延迟。
Reliable 不是所有数据的默认答案
相机和激光雷达是连续更新的数据,旧帧价值很低。网络拥塞时等待重传可能让队列越来越旧,因此传感器常用 Best Effort。配置命令、地图或低频状态可能更需要 Reliable。
1 | 高频、可由新值替代旧值 -> Best Effort + 小队列 |
Reliable 只提高 DDS 传输层的交付保证,不证明执行器已经完成动作。机器人命令仍需要序号、状态反馈和 watchdog。
如果当前问题还是“这里究竟该用 Topic 还是 Action”,先回到ROS 2 通信方式的选择。接口语义定错以后,调 QoS 只能改变消息怎么送,补不出任务反馈和取消能力。
队列深度决定新鲜度和抗突发能力
Depth 为 10 表示 Keep Last 时最多保留 10 条样本。消费者比生产者慢时,较大的队列会让它继续处理旧消息;较小队列会较早覆盖旧消息。控制系统通常更关心最新值,日志或审计系统更关心完整性,两者不应共用同一策略。
可以同时观察频率和时间戳:
1 | ros2 topic hz /camera/image_raw |
频率正常但 header.stamp 很旧,说明问题可能在排队,不在相机帧率。
订阅回调本身处理太慢时,还要继续检查Executor 与回调组。DDS 队列和 Executor 等待是两段不同的时间,最好分别记录。
Durability 决定晚加入者能看到什么
Volatile 只接收建立连接后的新样本。Transient Local 允许发布者缓存样本,新订阅者加入后可以收到最近状态。静态地图、配置状态或一次性发布的描述信息可能需要后者;高速图像通常不需要。
发布者使用 Volatile、订阅者强求 Transient Local 时可能不兼容。策略要从数据生命周期出发,不要单独改订阅端。
Deadline 和 Liveliness 需要业务动作
Deadline 可以检测数据没有按期到达,Liveliness 可以检测端点是否仍活跃。事件回调只告诉你契约被破坏,机器人要不要降速、停车或重连,仍由业务状态机决定。
| 数据 | 常见关注点 | 失败动作示例 |
|---|---|---|
| 相机图像 | 新鲜度、丢帧 | 丢旧帧、降低速度 |
| 速度命令 | deadline、watchdog | 安全减速或停车 |
| 静态地图 | durability、完整性 | 等待地图后再启动 |
| 诊断事件 | reliable、队列 | 限流并保留错误原因 |
参考资料
证据边界:本文给出 QoS 的基础选择方法,具体默认值和兼容行为受 ROS 2 发行版、RMW 和网络环境影响。策略修改必须在目标节点和故障场景下验证。