从 has_sync 到端到端证据:相机与 IMU 时间同步 QA
has_sync=True 很重要,但它只说明某一段同步链路建立了。它不能自动证明相机与 IMU 的消息时间戳已经落在同一时间轴,也不能证明多相机帧属于同一次触发。
要把时间同步从“看起来正常”变成可发布的工程能力,需要分层验证。
五层同步问题
| 层次 | 要回答的问题 | 典型证据 |
|---|---|---|
| 链路 | PPS / 串口消息是否持续到达 | link state、消息率、丢包 |
| 时钟 | offset 是否收敛且稳定 | raw/smoothed offset、jitter |
| 触发 | 多相机是否属于同一触发 | trigger seq、bundle complete |
| 时间域 | 相机与 IMU stamp 是否同域 | stamp domain、转换路径 |
| 运动一致性 | 两类传感器是否在物理上对齐 | 光流/角速度相关性、激励条件 |
任何一层通过,都不能替代下一层。
1. 在线与离线必须复用同一个分析器
最容易出现的维护问题是:在线节点用一套阈值,离线脚本又实现一套,最后同一份数据得到两个结论。
更好的结构是:
rosbag / JSONL ─┐
├─> shared analyzers ─> summary model
ROS subscribers ┘ ├─ summary.json
├─ report.html
└─ junit.xml在线节点只负责收集滑动窗口,离线 CLI 只负责读取数据,两者把同一种事件模型交给共享 analyzer。
2. 不要混用 receipt time 与 header stamp
ROS 消息至少存在两类常见时间:
header.stamp:消息声明的事件时间;- receipt time:本机收到回调的时间。
receipt time 会包含调度、传输和队列延迟。它可以衡量链路覆盖与消息新鲜度,但不能直接当作传感器物理 offset。
相机还可能有 driver PTS、group PTS、trigger time;IMU 可能有 PX4 sample time、同步后的 realtime 或 ROS publish time。QA 配置必须明确每个指标使用哪一个源。
3. 多相机同步看 bundle,不只看平均频率
六路相机都在 20 Hz,不等于每个 bundle 都完整。需要按 sync_seq 或 trigger_seq 聚合,统计:
- bundle complete ratio;
- 同组最大 skew;
- sequence gap;
- 重复帧与迟到帧;
- 滑动窗口边缘的半截 bundle。
窗口起止位置天然会截断部分 bundle,因此边缘桶应显式忽略或单独标记,不能把它们误算成真实丢帧。
4. 运动相关性需要足够激励
用图像光流与 gyro 估计 camera-IMU offset 时,如果设备静止,视觉变化和角速度都接近噪声底,算法即使输出一个数也不可信。
测试应包含明确的旋转或运动激励,并设置最低能量门限:激励不足就输出 INSUFFICIENT_EXCITATION,而不是给出伪精确 offset。
5. QA 输出要能进入发布门禁
建议同时输出三种形式:
summary.json:给自动化系统和后续聚合;report.html:给工程师快速阅读;junit.xml:直接进入 CI 测试结果。
一个典型 gate 可以包含:
link_up == true
offset_jitter_p99 < threshold
bundle_complete_ratio >= threshold
camera_skew_p99 < threshold
imu_rate within expected range
time_domain_consistent == true阈值应来自硬件和算法需求,而不是为了让当前数据通过。
最终验收边界
时间同步 QA 至少要区分:
- 代码单测通过;
- 离线样例通过;
- 板端在线窗口通过;
- 动态激励下物理 offset 可估;
- 正式 release/service 已部署。
把这些层次分开,才能避免用“节点 active”或“has_sync 为真”替代真正的端到端同步证据。