Files
calibration/README_RTK_IMU.md
T

178 lines
10 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.
# RTK-IMU 标定:流程、结果与复现
本文是本次 G90 双天线 RTK 与 HI13 IMU 标定的工程入口。算法代码在 `rtk_imu/`,命令入口在 `tools/`,正式审核结果在 `artifacts/rtk_imu_calibration_v3/`。原始 `.rscap`、统一导出数据、状态快照与 checkpoint 均只保留本地,不提交仓库。
## 一句话结论
RTK-IMU 旋转外参由双天线基线方向与水平静止重力约束获得;平移外参以机械测量为绝对基准,再通过 RTK+IMU 联合状态图、高动态转弯/坡道数据、独立 held-out 数据和旋转扰动测试进行一致性验证。
当前动态数据不足以独立高精度求出完整 XYZ 杆臂,因此它不是 data-only translation calibration。机械测量给出了杆臂的绝对值;在未参与标定的数据、转弯等杆臂敏感运动以及旋转外参扰动测试中,均未发现该机械外参存在明显矛盾或不稳定性。当前结果的正确表述是:**机械杆臂锚定,并经动态数据一致性验证的工程候选**。
## 当前工程候选与状态
坐标约定:`l_I = p_ANT1^I`,即 ANT1(主天线、左侧)相位中心在 IMU 坐标系中的位置。车体/RTK 安装坐标为:+X 为 ANT1(左)到 ANT2(右),+Y 为车辆前进方向且与 IMU +Y 同向,+Z 向上;GGA 参考点为 ANT1 相位中心,离地 `1.916499878 m`
- 固定旋转来源:`R2G_gravity_level_prior`
- 固定旋转近似 RPYX/Y/Z):`[0.454°, -0.003°, 0.012°]`
- 当前工程候选杆臂:`l_I = [-0.4518015159, -0.2644749820, 0.7314656115] m`
- 变换约定:`p_RTK = R_RTK_IMU * p_IMU + t_RTK_IMU`
- 对应候选 `T_RTK_IMU`(四舍五入到 6 位小数):
```text
[[ 1.000000, -0.000214, -0.000044, 0.451777],
[ 0.000214, 0.999969, -0.007929, 0.270363],
[ 0.000046, 0.007929, 0.999969, -0.729325],
[ 0.000000, 0.000000, 0.000000, 1.000000]]
```
当前门禁状态必须同时保留:
- `data_only_translation_accepted=false`:数据本身没有提供足够稳定的完整平移可观性。
- `engineering_translation_accepted=false`:独立传播验证仍存在公共加速度偏差,不能声称正式工程放行。
- `independent_extrinsic_sensitive_validation_passed=true`:杆臂敏感的高动态验证未发现机械杆臂冲突。
- `heldout_physical_validation_passed=true``rotation_sensitivity_passed=true`:固定候选在 held-out 物理残差和旋转扰动中保持一致。
因此不得描述为“data-only 标定平移”或“动态数据已精确细化机械杆臂”。完整、机器可读的结论见 [engineering_release_decision.json](artifacts/rtk_imu_calibration_v3/engineering_release_decision.json)。
## 求解流程
1. **统一原始数据导出。** 使用 G90/HI13 设备时间作为主时间轴;host receive time 仅用于诊断。G90 保留 GGA 质量、GNHPR 基线及质量、BESTNAVA Doppler velocity,必要时 PVTSLNAHI13 保留 system time、gyro、accel、姿态/四元数和 host receive time。
2. **R0 连续性与质量控制。** 校验 checksum、RTK Fixed、设备时间单调性、IMU 覆盖、baseline jump 与测量间隔。轨迹连续性由 IMU 设备时间和预积分覆盖决定;孤立 HPR 缺失/Q5 只禁用或降权 HPR factor,不切断 IMU 轨迹。
3. **旋转外参。** R1b 从基线与 IMU 动态估计 ANT1→ANT2 在 IMU 中的 2DoF 方向;R2V 用基线与高质量 Doppler 速度作独立诊断;R2G 使用水平静止场地中的基线+重力+地面水平先验补齐完整旋转。R2G 是本次正式固定旋转来源,旧 GNHPR 三轴手眼只作诊断。
4. **节点状态图。** 每个 GNSS node 包含 `R,p,v,bg,ba` 的 15DoF 状态;相邻 node 由 covariance-whitened IMU preintegration 和 bias random walk 连接。BEST 约束 XYZGGA 仅在 BEST 缺失时约束 XYDoppler 约束速度,HPR 是可选姿态/基线因子。
5. **机械锚定的平移验证。** 杆臂以机械值为基准,分别比较无先验 free、固定机械杆臂和软先验解。free 解只用于观测性诊断,不能因为数值收敛就替代机械值。
6. **独立验证。** 使用 circle、left-right、slope 的高动态非重叠窗口;再使用剩余 held-out 窗口、旋转 ±扰动敏感性、独立 innovation 和 propagation-bias root-cause audit 复核。
## 证据与限制
47 个非重叠标定窗口上的 free/fixed/prior 对比表明机械先验与数据拟合相容,但 posterior/prior 方差比没有显示足够的数据驱动细化,因此 `translation_refined_by_data=false`。剩余 267 个 frozen held-out 窗口的物理验证通过;然而独立传播创新在低速、低角速度区间同时出现位置和 Doppler 的同向偏差,等效为约 `0.20 m/s²` 的公共传播加速度误差。
该误差在 `|omega|` 很小时不能优先归因于杆臂速度项 `R*(omega × l)`,因此它不单独否决高动态杆臂敏感验证;但在传播模型根因关闭前,也不能把候选杆臂标为正式工程已放行。
主要审核证据:
- [47 窗口机械分支](artifacts/rtk_imu_calibration_v3/mechanical_prior_engineering_47_window.json)
- [held-out 验证](artifacts/rtk_imu_calibration_v3/mechanical_prior_engineering_heldout.json)
- [独立创新审计](artifacts/rtk_imu_calibration_v3/heldout_independent_innovation.json)
- [传播偏差根因审计](artifacts/rtk_imu_calibration_v3/propagation_bias_root_cause_audit.json)
- [旋转敏感性](artifacts/rtk_imu_calibration_v3/mechanical_prior_rotation_sensitivity.json)
## 如何复现
### 1. 准备环境和原始数据
```powershell
cd <repository-root>
python -m pip install -e ".[dev]"
```
将三批 G90/HI13 原始 `.rscap` 会话放到本机的数据位置。数据位置不写入仓库;`tools/export_rtk_imu_unified.py` 中的会话配对清单必须与实际采集文件一致。
```powershell
$OUT = "artifacts\rtk_imu_calibration_v3\reproduce"
python tools\export_rtk_imu_unified.py --output-root "$OUT\unified" --overwrite
$MANIFEST = "$OUT\unified\manifest.json"
```
导出后应检查每个会话目录中的 `export_summary.json`,并确认 `manifest.json` 中记录的传感器时间轴没有被 host receive time 替换。
### 2. 复现固定旋转
`<flat-static-session-id>` 必须是已确认地面水平、车辆静止的会话;可多次传入 `--level-static`。R2V 只作独立诊断,不替代 R2G。
```powershell
python tools\run_rtk_imu_multisource.py `
--manifest $MANIFEST `
--level-static <flat-static-session-id> `
--output "$OUT\r2g_multisource.json"
```
检查输出的 R2G 旋转与本 README 的近似 RPY 一致后,将该旋转固定为后续 node graph 的 `--rotation-rpy-deg 0.454 -0.003 0.012`。若 R2G 不一致,应停止,先复核天线方向、场地水平和时间/轴定义,不应继续求杆臂。
### 3. 复现窗口选择与无先验诊断
从 circle、left-right、slope 三类会话中选择高质量窗口;窗口不可共享 IMU/GNSS/HPR 样本。仓库提交的 `lever_information_window_selection*.json` 是本次审核所用选择结果,可用于对照。
```powershell
python tools\select_rtk_imu_windows_by_lever_information.py `
--manifest $MANIFEST `
--circle-session <circle-session-id> `
--left-right-session <left-right-session-id> `
--slope-session <slope-session-id> `
--output "$OUT\selection.json" `
--rotation-rpy-deg 0.454 -0.003 0.012
python tools\run_rtk_imu_node_graph_free_selected.py `
--manifest $MANIFEST `
--selection "$OUT\selection.json" `
--output "$OUT\free_baseline.json" `
--start-name all `
--rotation-rpy-deg 0.454 -0.003 0.012
```
free solve 的作用是输出边缘化杆臂信息、协方差、最弱方向和多初值稳定性;本次数据若仍未达到完整 XYZ 可观性,不得扩大无先验求解规模来强行放行。
### 4. 复现机械杆臂分支和 held-out 验证
固定工程候选杆臂并使用同一批非重叠标定窗口。`states.npz` 和 checkpoint-dir 是本地过程产物,应保持被 `.gitignore` 排除。
```powershell
python tools\run_rtk_imu_mechanical_prior_branch.py `
--manifest $MANIFEST `
--selection "$OUT\selection.json" `
--free-baseline "$OUT\free_baseline.json" `
--output "$OUT\mechanical_47_window.json" `
--state-output "$OUT\states.npz" `
--rotation-rpy-deg 0.454 -0.003 0.012
python tools\run_rtk_imu_mechanical_prior_heldout.py `
--manifest $MANIFEST `
--calibration-selection "$OUT\selection.json" `
--all-selection <all-nonoverlapping-selection.json> `
--engineering-result "$OUT\mechanical_47_window.json" `
--output "$OUT\heldout.json" `
--checkpoint-dir "$OUT\heldout_checkpoints" `
--rotation-rpy-deg 0.454 -0.003 0.012
```
随后运行独立 innovation、传播根因审计和旋转敏感性。它们不重新优化杆臂,不应被用于调 covariance、R2G 或机械先验。
```powershell
python tools\audit_rtk_imu_heldout_innovation.py `
--manifest $MANIFEST `
--calibration-selection "$OUT\selection.json" `
--all-selection <all-nonoverlapping-selection.json> `
--engineering-result "$OUT\mechanical_47_window.json" `
--output "$OUT\heldout_innovation.json" `
--rotation-rpy-deg 0.454 -0.003 0.012
python tools\audit_rtk_imu_propagation_bias_root_cause.py `
--manifest $MANIFEST `
--calibration-selection "$OUT\selection.json" `
--all-selection <all-nonoverlapping-selection.json> `
--engineering-result "$OUT\mechanical_47_window.json" `
--output "$OUT\propagation_bias_root_cause.json" `
--rotation-rpy-deg 0.454 -0.003 0.012
```
最终仅汇总已生成的结果,不在 release 阶段重新拟合:
```powershell
python tools\finalize_rtk_imu_engineering_release.py `
--calibration "$OUT\mechanical_47_window.json" `
--heldout-postfit "$OUT\heldout.json" `
--innovation "$OUT\heldout_innovation.json" `
--sensitivity <rotation_sensitivity.json> `
--convergence-retry <heldout_retry.json> `
--propagation-root-cause "$OUT\propagation_bias_root_cause.json" `
--output "$OUT\engineering_release_decision.json"
```
## 相关文件
- [RTK-IMU 代码包](rtk_imu/README.md)
- [多源导出与旋转 V3 说明](docs/rtk_imu_multisource_v3.md)
- [engineering 6DoF 说明](docs/rtk_imu_engineering_6dof.md)
- [历史链路审计](docs/rtk_imu_calibration.md)
- [正式结果索引](artifacts/rtk_imu_calibration_v3/README.md)