Files
calibration/tests/README.md
T

131 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 测试说明
**用途:** 说明合成 pytest 与旧车 S2 线下试验的边界(避免误读)。日常跑通请先看根目录 [README](../README.md)。
| 试验 | 是否默认 pytest | 在证明什么 | 不在证明什么 |
|---|---|---|---|
| **合成数据** | 是 | 算法链路正确、能收回已知 yaw / δt | 实车安装精度、平移可交付 |
| **旧车 S2** | 否(线下手工) | 主机时间旧数据上流水线能跑完;质量门会拒绝坏结果 | 外参真值;新车可用性 |
---
## 1. 自动化测试(合成数据 / `pytest`)
入口:`tests/test_v1_pipeline.py`
命令:
```powershell
cd <仓库根目录>
python -m pytest -q
```
| 测试 | 输入 | 在测什么 | 期望结果 |
| ------------------------------------------------------------- | ------------ | ------------------- | ------------------------------------------ |
| `test_rotation_handeye_recovers_yaw` | 合成运动对(无点云) | 旋转手眼能否收回已知 yaw | 旋转误差 < 1° |
| `test_time_offset_on_synthetic` | 合成会话(故意加 δt) | 模长相关粗估时间偏置 | |δt 误差| < 0.05 s |
| `test_signed_time_offset_refine_improves_or_keeps` | 同上 + 真值 R | 有符号三轴 δt 精修 | 不比粗估明显更差 |
| `test_preintegration_bias_jacobian_matches_finite_difference` | 随机陀螺序列 | 旋转预积分 `J_bg` | 与有限差分一致(松阈值) |
| `test_imu_preintegration_recovers_constant_accel_translation` | 常值加速度 | 完整预积分 Δv/Δp | 接近解析值 |
| `test_imu_preintegration_bias_jacobian_finite_difference` | 随机 IMU | `J_bg`/`J_ba` 一阶修正 | 与重积分接近 |
| `test_synthetic_pipeline_rejects_noisy_icp_but_keeps_time_audit` | synthetic end-to-end | strict rotation quality gate + time audit | noisy ICP is blocked; delta-t remains accurate |
| `test_synthetic_pipeline_full_se3_smoke` | synthetic end-to-end | full-SE(3) smoke test | returns an explicit accepted/rejected/blocked status |
| `test_planar_yaw_is_not_full_rotation_or_translation_observable` | pure-yaw motion pairs | degeneracy detection | full rotation/translation observability is rejected |
| `test_multi_axis_motion_is_rotation_and_translation_observable` | multi-axis motion pairs | positive observability case | rotation and translation pass |
| `test_translation_prior_is_reported_but_not_accepted_when_unobservable` | planar motion + CAD prior | prior semantics | prior is reported but not accepted as calibration |
| `test_handeye_rejects_a_small_fraction_of_gross_rotation_outliers` | motion pairs with a gross outlier | residual-distribution gate | solve is rejected |
| `test_motion_pairs_reject_low_fitness` | low-fitness registration | fitness gate | no motion pair is emitted |
| `test_motion_pairs_reject_imu_and_lidar_discontinuities` | timestamp gaps | continuity gates | cross-gap pairs are rejected |
合成数据由 `tools/generate_synthetic_session.py` 生成(墙面点云 + 已知外参 yaw 与 δt)。
一键复现见根目录 README`tools/reproduce_synthetic.py`
---
## 2. 旧车 S2 线下试验(不在默认 pytest 里)
### 用了什么数据
| 项 | 内容 |
| ------- | -------------------------------------------------------------------------- |
| 车辆 / 批次 | 旧 **S2** 验证集(`S2_scheme1_validation`)数据在网盘的“室外车数据\IMU-雷达标定数据” |
| 典型路径 | `D:\IMU_calibration\work\S2_scheme1_validation\`(历史目录名;含 `imu.csv` + 雷达会话) |
| IMU 时间 | **主机 UTC 接收时间**(串口块到达时刻),不是 IMU 设备时间 |
| 雷达时间 | dlog 导出的主机侧 `unix_time_ns`,不是 MSOP 设备时间 |
| 帧率特征 | 雷达约 **1 Hz** 量级,关键帧间隔偏长 |
| 配置烟测 | `config/s2_old_smoke.yaml`(仅声明为旧数据烟测,不当交付) |
这些数据**只能用来验证流水线能否跑通**,不能当作新车外参真值来源。
`blocked` 是质量门的**预期结果**,不是「算法突然坏了」。
### 做了什么测试
对同一批 S2 中间格式多次跑 `cli run`,例如:
- 预积分加强后的输出目录(本机历史名如 `out_scheme2_preint`
- 有符号 δt / 联合精修后的输出(本机历史名如 `out_scheme2_phaseA`
-`tools/compare_s2_runs.py` 对比两次 `summary.json`
命令形态(路径按本机实际修改;雷达会话目录若仍叫 `scheme2_session` 为历史命名):
```powershell
python -m imu_lidar.cli run `
--vehicle-config config\s2_old_smoke.yaml `
--imu D:\IMU_calibration\work\S2_scheme1_validation\imu.csv `
--lidar D:\IMU_calibration\work\S2_scheme1_validation\scheme2_session `
--output path\to\out_s2 `
--mode rotation_only `
--time-offset-search-s 2.0
python tools\compare_s2_runs.py path\to\out_old\summary.json path\to\out_new\summary.json
```
### 得到什么结果(记录摘要)
| 指标 | 预积分加强一轮 | 有符号 δt / 精修一轮 |
| -------- | ------------- | ------------------ |
| `status` | `blocked`(预期) | `blocked`(预期) |
| 手眼 RMS | 约 **15.0°** | 约 **14.5°** |
| 手眼中位数 | — | 约 **6.8°** |
| δt | 约 **2.0 s** | 约 **1.75 s**(有修正) |
| 相关峰 | 很弱(约 0.18) | 仍弱(约 0.13 |
| 结论 | 链路可跑 | 残差略降,但 **不当交付外参** |
原因归纳:
1. 时间戳是**主机时间**,相关峰弱,δt / yaw / 零偏互相耦合;
2. 雷达约 1 Hz,运动对间隔长,IMU 侧更易漂;
3. 质量门主动 `blocked`,避免把坏结果当成安装参数。
**正式标定**必须改用设备时间(IMU `device_timestamp`、雷达 MSOP 设备时)重新采集后再跑。
---
## 3. 配准结果怎么目视检查
标定跑完后(合成或实车):
```powershell
python tools\visualize_pair_3d.py `
--lidar examples\synthetic_session\lidar `
--imu examples\synthetic_session\imu.csv `
--summary examples\synthetic_session\out\summary.json `
--pair-index 0 `
--save-png examples\synthetic_session\out\pair0_overlay.png
```
交互窗口快捷键:`1``4` 切换叠点模式;`N`/`]` 下一运动对,`P`/`[` 上一运动对。
无显示器时加 `--no-gui --save-png ...` 只出俯视图 PNG。