# 测试说明 **用途:** 说明合成 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。