4. 常用延迟分析工具:ros2 topic delay、ros2 topic hz、ros2 bag info

做自动驾驶系统,说白了就是跟时间赛跑。你想想看,传感器数据晚到 10 毫秒,可能就错过了一个障碍物。所以,怎么快速定位延迟问题?我个人的习惯是,先拿命令行工具摸个底。

今天咱们就聊聊三个最趁手的工具:ros2 topic delay、ros2 topic hz 和 ros2 bag info。它们就像医生的听诊器,不用开刀就能知道系统哪里「堵车」了。

4.1 ros2 topic hz:先看频率稳不稳

这个命令是我用得最频繁的。它统计一个话题的发布频率,单位是 Hz。

用法很简单:

ros2 topic hz /sensing/lidar/points_raw

输出大概长这样:

average rate: 10.002
    min: 9.987s max: 10.015s std dev: 0.00423s window: 100

嗯,这里要注意:平均频率 10 Hz 不代表没问题。你得看标准差(std dev)。如果标准差很大,比如超过 0.1 秒,说明数据在「一卡一卡」地来。我在项目中遇到过,某个激光雷达驱动偶尔丢帧,平均频率看着是 10 Hz,但实际最大间隔到了 200 毫秒——这在地图构建时直接导致定位漂移。

核心指标:

  • 平均频率:是否接近预期值(比如 10 Hz、20 Hz)
  • 标准差:越小越好,超过 0.05 秒就要警惕
  • 最小/最大间隔:最大间隔如果超过 2 倍周期,说明有严重抖动

我的小技巧: 用 -w 200 参数扩大窗口,比如 ros2 topic hz /topic -w 200。这样统计 200 个样本,更能反映长期稳定性。别只看前 10 个数据,那都是「幸存者偏差」。

4.2 ros2 topic delay:直接测端到端延迟

这个工具更狠——它直接告诉你「从发布到接收花了多久」。前提是话题消息里带了时间戳。

用法:

ros2 topic delay /perception/objects

输出示例:

average delay: 0.032
    min: 0.021s max: 0.045s std dev: 0.005s window: 100

说白了,这个命令比较的是消息头里的 stamp 和当前接收时间。如果延迟突然飙升到 100 毫秒以上,那大概率是某个处理节点在「拖后腿」。

我曾经排查过一个诡异的问题:感知模块的延迟偶尔跳到 200 毫秒,但 CPU 和内存看起来都正常。后来用 ros2 topic delay 配合 ros2 topic hz 一对比,发现延迟飙升时,话题频率反而没变。这说明问题不在发布端,而在接收端的回调函数里——有个第三方库在特定场景下触发了垃圾回收。

避坑指南: 我曾经被这个工具坑过一次。如果发布者忘记给消息打时间戳(stamp 为默认值 0),ros2 topic delay 会算出一个巨大的假延迟。所以,先确认消息里真的有时间戳。用 ros2 topic echo /topic --once 看一眼 header 字段。

4.3 ros2 bag info:离线分析的好帮手

有时候问题不是实时发生的,而是跑完一趟路测才发现。这时候就得翻 rosbag 了。

ros2 bag info 能告诉你 bag 文件里每个话题的详细信息:

ros2 bag info my_route_bag/

输出:

Files:             my_route_bag_0.db3
Bag size:          2.4 GiB
Storage id:        sqlite3
Duration:          187.3s
Start:             Jan 20 2025 14:32:10.123 (1705744330.123)
End:               Jan 20 2025 14:35:17.423 (1705744517.423)
Messages:          45231
Topic information:
  Topic: /sensing/lidar/points_raw | Type: sensor_msgs/msg/PointCloud2 | Count: 1873 | Serialization Format: cdr
  Topic: /vehicle/steering_status   | Type: std_msgs/msg/Float32       | Count: 18730 | Serialization Format: cdr
  Topic: /vehicle/speed_status      | Type: std_msgs/msg/Float32       | Count: 18730 | Serialization Format: cdr

你想想看,这里最有价值的信息是什么?Count 和 Duration 的比值。比如激光雷达话题 1873 条消息,时长 187.3 秒,算下来正好 10 Hz。但如果某个话题的 Count 明显偏少,比如本该 10 Hz 的只有 5 Hz 的数据量,那说明采集过程中就有丢帧。

进阶用法: 结合 ros2 bag info 和 ros2 topic delay 做离线分析。先把 bag 播放出来:

ros2 bag play my_route_bag/ --clock 200
# 另开终端
ros2 topic delay /perception/objects -w 500

这样就能复现路测时的延迟情况,而且可以反复测,直到找到根因。

4.4 三个工具怎么配合?一张图说清楚

我画了张流程图,帮你理清排查思路:

延迟分析工具配合流程 ros2 topic hz 检查发布频率是否稳定 频率正常? 是 ros2 topic delay 测量端到端延迟 否 检查发布端:驱动、CPU负载 或使用 ros2 bag 录制后离线分析 延迟超标? 是 排查 接收端 否 系统延迟正常,继续监控 或使用 ros2 bag info 做历史对比

这张图的核心逻辑是:先用 ros2 topic hz 筛掉发布端问题,再用 ros2 topic delay 定位接收端延迟,最后用 ros2 bag info 做离线复盘。三步走,基本能覆盖 90% 的延迟场景。

4.5 实战经验总结

工具 适用场景 我踩过的坑
ros2 topic hz 检查发布频率是否稳定 只看平均频率,忽略了最大间隔
ros2 topic delay 测量端到端延迟 消息没时间戳时,会算出假延迟
ros2 bag info 离线分析历史数据 忘记看 Count 和 Duration 的比值

我的建议: 把这几个命令写成别名,加到 .bashrc 里。比如:

alias hz='ros2 topic hz -w 200'
alias delay='ros2 topic delay -w 200'
alias baginfo='ros2 bag info'

这样排查问题时能省不少打字时间。嗯,效率就是一点点抠出来的。

好了,这三个工具够你应付大部分延迟问题了。记住一个原则:先看频率,再看延迟,最后翻历史数据。别一上来就翻代码,命令行能告诉你的,远比你想的多。

可可精品资料库