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 定位接收端延迟,最后用 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'
这样排查问题时能省不少打字时间。嗯,效率就是一点点抠出来的。
好了,这三个工具够你应付大部分延迟问题了。记住一个原则:先看频率,再看延迟,最后翻历史数据。别一上来就翻代码,命令行能告诉你的,远比你想的多。