
1. 检测「很准」但总是撞——你在追旧帧
相机 30 Hz、检测 10 Hz、跟踪再叠一层,全程 Reliable + depth 10。端到端延迟堆到 800 ms,控制器以为目标在前方 0.8 m,实际已偏到侧向。图像管线必须显式选:最新帧优先(在线感知)还是无损优先(离线标定采集)——两种目标互斥,一套 QoS 假装兼顾会两头做差。RViz 订阅常用 Reliable,与在线 Best Effort 发布不兼容时,表现是「仿真有图、车上无图」,排错方向应在 QoS 而非相机驱动。
2. ROS 2 默认剖面
sensor_data 语义:BEST_EFFORT + KEEP_LAST + depth 小(常 1)。适合相机 → 检测 → 控制。
from rclpy.qos import qos_profile_sensor_data
self.create_subscription(
Image, '/camera/image_raw', self.cb, qos_profile_sensor_data)发布侧对齐:
self.create_publisher(Image, '/camera/image_raw', qos_profile_sensor_data)订阅与发布 QoS 不兼容时,无数据且无报错——先 ros2 topic info -v /camera/image_raw 看 reliability 与 depth。
3. 何时用 Reliable
标定采集、离线建图、需要每一帧进 bag 时:RELIABLE + 较大 depth,接受带宽与延迟换不丢帧。在线控制与 Reliable 大图混用是常见事故源——任务级剖面,不是全局默认。
| 场景 | Reliability | Depth |
|---|---|---|
| 在线检测/跟踪 | BEST_EFFORT | 1–5 |
| 标定/离线 bag | RELIABLE | 10+ |
| 可视化(rqt) | 常 RELIABLE | 按需 |
4. 度量:分列延迟与丢帧
ros2 topic hz /camera/image_raw
ros2 topic delay /camera/image_raw # 若可用,或用自写 stamp 差记录三项:发布 hz、端到端延迟(header.stamp → 结果 stamp)、丢帧/跳帧计数。优化前先证明延迟来自重传/排队,而不是模型 FLOPs——否则在旧帧上加速模型无意义。延迟预算应写进控制需求:若闭环 50 ms,视觉链路占用不应超过其三分之一,否则先砍分辨率而非换更大 backbone。
5. image_transport 与压缩
大图先用 image_transport 协商 raw/compressed/theora:
ros2 run image_transport list_transports订阅 compressed 而发布只有 raw,会 silent 失败。压缩降低带宽,但编解码占 CPU——在预算表里与分辨率、帧率一起算,不能单靠 QoS KeepLast(1) 变出带宽。
6. 与 Executor 的接缝
图像回调里跑重推理 + 默认 MutuallyExclusive 回调组 = 阻塞其他订阅。剖面正确后仍卡,再考虑:独立 callback group、组件化节点、NPU 推理进程。顺序反了会把 Executor 问题当成「再加 depth」。
7. 录包 vs 在线
ros2 bag record 订阅常用 RELIABLE;在线节点用 BEST_EFFORT——录包配置不要无脑复制在线 QoS。回放时配对率、延迟与现场不一致,会在 bag 上「调好」、上车又崩。
8. 端到端预算表
定规格前先算:分辨率 × 帧率 × 字节/像素 × 链路数 ≤ 带宽与 CPU 预算。超预算顺序:降分辨率 → 降帧率 → 压缩 → 换 QoS,最后才上更大模型。QoS 保最新只保证处理「尽可能新」的帧,不能凭空变出千兆网。
9. 验收
- 在线链路:
topic info显示 BEST_EFFORT + 小 depth;端到端延迟 < 控制周期 - 故意压测 CPU:应丢旧帧而非排队延迟无限增长
- 标定任务:Reliable 剖面下 bag 帧数与相机计数一致
- 设计文档并排:预算表 + QoS 剖面表,签字后再换模型
10. 案例:Reliable 导致「跟踪滞后一个身位」
叉车跟踪用 Reliable depth 20,队列在负载尖峰存 15 帧,延迟 500 ms。改为 BEST_EFFORT + KeepLast(1) 后延迟 35 ms,同模型命中率相当——瓶颈在队列语义。迁移视觉栈时先冻结分辨率/帧率/剖面,再换骨干网;否则会把队列延迟当成「模型不够准」。
11. 默认策略
在线感知保最新;采集任务另开剖面;延迟与丢帧分列度量;录包与在线 QoS 分文档。视觉栈的「准」必须含「够新」,否则准的是历史。
12. 多相机与同步
多路相机若各用 KeepLast(1),时间对齐靠 stamp 而非队列——与 message_filters 章节同一逻辑。硬件触发同步时可用 ExactTime 订阅;自由运行则 Accept Approximate slop。每路相机独立 QoS 剖面写进契约,禁止「主相机 Reliable、辅相机 Best Effort」却期望同一融合节点隐式对齐。
相关
也可以看看
johan's blog