Files
calibration/docs/RTK-IMU标定.md
T

241 lines
14 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.
# RTKIMU 标定
本文是本仓库 RTK–IMU 标定的唯一规范说明,覆盖数据、方法、当前结果、限制和复现。它不使用项目内部阶段代号作为前提。
## 结论与适用范围
本次标定的正确表述是:**双天线方向和水平静止时的重力约束给出了固定旋转;天线相位中心到 IMU 的平移以机械测量为绝对基准,RTK 与 IMU 动态数据对该安装关系完成了独立一致性与稳定性验证。** 动态数据未能独立、精确地估计完整三维杆臂,但没有发现机械测量值与真实运动矛盾。
| 项目 | 当前值或状态 |
| --- | --- |
| 天线相位中心相对 IMU 的杆臂 `l_I` | `[-0.4518015159, -0.2644749820, 0.7314656115] m` |
| 固定旋转来源 | 水平静止时的双天线基线与重力约束 |
| 固定旋转近似 RPYX/Y/Z | `[0.454°, -0.003°, 0.012°]` |
| 仅由数据估计三维平移 | 未通过:`data_only_translation_accepted=false` |
| 正式工程平移验收 | 未通过:`engineering_translation_accepted=false` |
| 杆臂敏感的高动态独立验证 | 通过:未发现机械杆臂冲突 |
该候选可用于算法联调和工程验证,但不能称为“数据独立完成的完整六自由度标定”或“正式工程放行的外参”。低速、低角速度留出数据仍显示约 `0.20 m/s²` 的共同加速度传播误差;其根因未关闭前,工程放行保持为否。机器可读结论见 [工程发布决定](../artifacts/rtk_imu_calibration_v3/engineering_release_decision.json)。
## 安装与坐标定义
- 主天线为 ANT1,位于车辆前进方向左侧;从天线为 ANT2,位于右侧;两者平行安装。
- 双天线报文的 heading 是**主天线到从天线**的方向。
- IMU 的 `+Y` 指向车辆前进方向;天线基线因此指向车辆右侧。
- GGA 的参考点为 ANT1 相位中心,离地 `1.916499878 m`
- `l_I = p_ANT1^I` 表示从 IMU 原点指向 ANT1 相位中心、并在 IMU 坐标系表达的向量。
输出变换的定义为:
```text
p_RTK = R_RTK_IMU · p_IMU + t_RTK_IMU
p_IMU = R_RTK_IMUᵀ · p_RTK + l_I
t_RTK_IMU = -R_RTK_IMU · l_I
```
RTK 原点就是 ANT1,所以 `T_IMU_RTK` 的平移等于 `l_I`,两个变换必须互逆。下游实现必须按这些公式检查方向和符号。
## 原始数据与统一导出
使用三个日期的 G90 双天线 RTK 与 HI13 IMU 原始 `.rscap`。按捕获开始时间在 1.5 秒内配对,共导出 55 组会话;0815 的一组无匹配 HI13,已记录为 unmatched,不参与联合求解。
| 批次 | 配对会话 | GNHPR | BESTNAVA | PVTSLNA | Q4 双天线方向 | Fixed Doppler |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 0808 | 18 | 46,180 | 8,291 | 5,993 | 45,606 | 8,128 |
| 0815 | 28 | 96,241 | 12,660 | 9,638 | 27,045 | 3,385 |
| 0819 | 9 | 15,717 | 2,029 | 1,427 | 14,976 | 1,930 |
旧导出以 GGA 为中心,将最近的 GNHPR 合并到同一行,且没有保留 BESTNAVA/PVTSLNA;这会把异步报文伪装成同时观测,也不能独立使用 GNSS 位置和 Doppler 速度。
新导出保留每条异步报文:
| 文件 | 内容 |
| --- | --- |
| `imu.npz` | HI13 `system_time`、三轴陀螺/加速度、RPY、四元数、磁场、PPS、温度、气压和主机接收时间 |
| `rtk.csv` | 各 GGA/GNHPR/BESTNAVA/PVTSLNA 的测量时间、质量、校验和和原始字段 |
| `export_summary.json` | 报文统计、四元数检查与跨时钟诊断 |
| `manifest.json` | 会话、批次、导出目录与未配对记录 |
HI13 `system_time` 是主时间轴。G90 的 GNSS UTC 或周/TOW 时间原样保留,并映射到此主时间轴;主机接收时间只用于时钟桥接、延迟和抖动诊断,绝不能作为采样时间。
## 求解与验证流程
```text
统一导出原始报文
→ 检查校验和、固定解、时间连续性和 IMU 预积分覆盖
→ 由双天线基线和重力固定旋转
→ 以节点状态图检查无机械先验时的杆臂可观性
→ 以机械杆臂为基准进行动态一致性验证
→ 使用未参与标定的数据和高动态转弯/坡道复核
```
### 旋转
双天线基线只提供两个方向自由度,不能单独推出完整三维姿态。因此旋转经过三类检查:
1. 连续高质量基线与 IMU 相对转动,检查基线在 IMU 中的方向。
2. 基线加高速近似直线 Doppler 速度,独立检查前向;因可用高速样本不足且与 IMU 航向存在不一致,它只作诊断。
3. 明确真实水平、车辆静止的会话中,基线确定横向,HI13 重力确定竖直,叉乘得到前向。这是当前固定旋转的正式来源。
旧式“直接把 GNHPR 三轴姿态与 IMU 做手眼”仅作诊断,不再作为正式外参。
### 平移与杆臂
每个 GNSS 节点包含姿态、位置、速度、陀螺偏置和加速度偏置。相邻节点由带协方差的 IMU 预积分连接;BESTNAVA 约束三维位置,Doppler 约束速度,GGA 只在 BEST 缺失时补充水平位置,双天线方向是可选姿态观测。GGA 的 MSL 高程绝不用于 ENU 的 Z 轴。
```text
p_ANT1^W = p_IMU^W + R_WI · l_I
v_ANT1^W = v_IMU^W + R_WI · ((ω - b_g) × l_I)
```
无机械先验求解只用来检查可观性:边缘化其他状态后,检查三维杆臂的信息矩阵、协方差、最弱方向和不同初值稳定性。本批数据不能稳定约束完整 XYZ,所以不会用其点估计替代机械值。
在同一批非重叠高动态窗口中,已比较无先验诊断解、固定机械杆臂和机械软约束解。机械值没有显著恶化位置、速度或双天线残差;但数据相对机械先验的信息增益不足,不能证明数据细化了杆臂。因此绝对值仍以机械测量为准。
## 如何使用结果
可以:固定本文旋转和机械杆臂,用于定位、融合或控制算法验证;并把“机械测量 + 动态一致性验证”写入配置或报告。
不能:把它描述为数据独立的三维平移标定、完整六自由度正式放行,或仅凭优化收敛就宣称杆臂真实。
## 结果文件与本地过程文件
`artifacts/rtk_imu_calibration_v3/` 是**本次提交的审核快照**,不是原始数据目录,也不是每次运行的工作目录。阅读顺序如下:
| 类别 | 主要文件 | 用途 |
| --- | --- | --- |
| 最终结论 | `engineering_release_decision.json` | 唯一的放行状态、候选杆臂、两个互逆变换和限制说明;下游首先读取它。 |
| 旋转证据 | `multisource_result.json` | 双天线方向、重力和速度诊断的旋转结果。 |
| 杆臂一致性 | `mechanical_prior_engineering_47_window.json` | 同一 47 个标定窗口上无先验、固定机械值和机械软约束三种结果的比较。 |
| 独立验证 | `mechanical_prior_engineering_heldout.json``heldout_independent_innovation.json` | 未参与标定的 267 个窗口的物理残差和独立传播创新。 |
| 稳定性与根因 | `mechanical_prior_rotation_sensitivity.json``propagation_bias_root_cause_audit.json` | 固定旋转扰动的影响,以及低速传播公共加速度误差的诊断。 |
| 固定选窗输入 | `lever_information_window_selection.json``lever_information_window_selection_refined.json` | 分别记录 47 个标定窗口和 314 个全部非重叠窗口;后者用于从中扣除 47 个标定窗口,得到 267 个留出窗口。 |
| 辅助审计 | `bestnava_doppler_factor_yield_*.json``hpr_dropout_bridge_*.json``motion_excitation_*.json` 等 | 记录数据保留率、双天线短缺口处理和运动激励检查;它们解释流程选择,不单独决定放行。 |
目录中还保留少量历史诊断和调试快照,文件名含 `debug``fast_diagnostic``p0` 或旧 node-graph 阶段。这些不是当前发布结论,阅读时应以 `engineering_release_decision.json` 及其 `evidence` 字段指向的文件为准。`mechanical_prior_engineering_47_window_states.npz` 是一次历史状态缓存;它不是复现的必要输入,也不应在后续运行中再次提交。
原始 `.rscap`、统一导出目录、运行中的 `.npz` 状态、checkpoint 和临时 JSON 应放在仓库外或被忽略的本地工作目录。不要把它们覆盖到 `artifacts/rtk_imu_calibration_v3/`,以免把正式审核快照和个人运行过程混在一起。
## 复现
### 复现范围
| 目标 | 是否需要原始数据 | 推荐操作 |
| --- | --- | --- |
| 核验当前发布结论 | 否 | 读取 `engineering_release_decision.json`,并按其 `evidence` 字段查看证据 JSON。 |
| 重做数据导出和固定旋转 | 是 | 按下文步骤 1–2 运行;结果应与本文的会话数、时间规则和旋转量级一致。 |
| 重做机械杆臂一致性与留出验证 | 是 | 按步骤 3–5 使用冻结选窗文件;计算量较大,所有输出放到本地工作目录。 |
| 生成新的工程结论 | 是,且需新的审核决策 | 不要复用或覆盖当前发布快照;应新建工作目录和结果目录,并重新执行完整门禁。 |
以下命令用于重建本次发布所依据的流程。原始数据路径不提交仓库;导出脚本目前的三批默认来源定义在 `tools/export_rtk_imu_unified.py``DEFAULT_SOURCES`。若本机原始数据不在这些位置,应先在该常量中仅替换本地路径,保持批次和文件配对规则不变。
### 1. 导出 55 组统一数据
```powershell
python -m pip install -e ".[dev]"
$WORK = "D:\data\rtk_imu_reproduce" # 本地工作目录,不提交
$UNIFIED = "$WORK\unified"
python tools\export_rtk_imu_unified.py --output-root $UNIFIED --overwrite
$MANIFEST = "$UNIFIED\manifest.json"
```
检查 `manifest.json`:应有 55 个配对会话,0815 的一个单独 G90 记录在 `unmatched`;每个会话应包含 `imu.npz``rtk.csv``export_summary.json`。确认 HI13 `system_time` 是主时间轴,主机接收时间没有成为观测采样时间。
### 2. 重建固定旋转
本次发布使用两个明确水平、车辆静止的会话。两个 `--level-static` 参数都必须提供:
```powershell
$ROTATION = "$WORK\rotation.json"
python tools\run_rtk_imu_multisource.py `
--manifest $MANIFEST `
--level-static 0819_20260819_072130 `
--level-static 0819_20260819_073045 `
--output $ROTATION
```
检查输出中“基线 + 重力 + 水平场地约束”的旋转是否接近 `[0.454°, -0.003°, 0.012°]`。如果差异明显,应停止后续步骤,先核对天线方向、会话是否真实水平和时间/坐标定义;不要直接求杆臂。
### 3. 选择并诊断 47 个标定窗口
本次种子运动分别是持续绕圈、左右转向和坡道。脚本会在不共享 IMU/GNSS/HPR 样本的前提下,按杆臂信息增益补充窗口;当前发布的固定结果为 47 个窗口。
```powershell
$SEL47 = "$WORK\selection_47.json"
python tools\select_rtk_imu_windows_by_lever_information.py `
--manifest $MANIFEST `
--circle-session 0808_20260808_092827 `
--left-right-session 0808_20260808_082148 `
--slope-session 0815_20260812_123424 `
--rotation-rpy-deg 0.4543066225 -0.0026392019 0.0122384129 `
--output $SEL47
$FREE47 = "$WORK\free_47.json"
python tools\run_rtk_imu_node_graph_free_selected.py `
--manifest $MANIFEST `
--selection $SEL47 `
--rotation-rpy-deg 0.4543066225 -0.0026392019 0.0122384129 `
--start-name all `
--output $FREE47
```
`$FREE47` 只用于确认无机械先验时的可观性和多初值稳定性;它不是可交付杆臂,也不应因此修改机械值。
### 4. 重做机械杆臂一致性比较
```powershell
$ENGINEERING = "$WORK\mechanical_47.json"
python tools\run_rtk_imu_mechanical_prior_branch.py `
--manifest $MANIFEST `
--selection $SEL47 `
--free-baseline $FREE47 `
--rotation-rpy-deg 0.4543066225 -0.0026392019 0.0122384129 `
--state-output "$WORK\mechanical_47_states.npz" `
--output $ENGINEERING
```
结果必须同时比较无先验、固定机械杆臂和机械软约束杆臂。`mechanical_47_states.npz` 仅为本地缓存,不提交。
### 5. 重做留出验证和发布汇总
本次留出验证使用 314 个冻结的全部非重叠窗口,其中 47 个是标定窗口、267 个是留出窗口。为了精确复现本次窗口划分,直接使用仓库中的 `lever_information_window_selection_refined.json`,不要重新选择或改变窗口。
```powershell
$ALL314 = "artifacts\rtk_imu_calibration_v3\lever_information_window_selection_refined.json"
$HELDOUT = "$WORK\heldout.json"
python tools\run_rtk_imu_mechanical_prior_heldout.py `
--manifest $MANIFEST `
--calibration-selection $SEL47 `
--all-selection $ALL314 `
--engineering-result $ENGINEERING `
--checkpoint-dir "$WORK\heldout_checkpoints" `
--rotation-rpy-deg 0.4543066225 -0.0026392019 0.0122384129 `
--output $HELDOUT
python tools\audit_rtk_imu_heldout_innovation.py `
--manifest $MANIFEST `
--calibration-selection $SEL47 `
--all-selection $ALL314 `
--engineering-result $ENGINEERING `
--rotation-rpy-deg 0.4543066225 -0.0026392019 0.0122384129 `
--output "$WORK\heldout_innovation.json"
python tools\audit_rtk_imu_propagation_bias_root_cause.py `
--manifest $MANIFEST `
--calibration-selection $SEL47 `
--all-selection $ALL314 `
--engineering-result $ENGINEERING `
--rotation-rpy-deg 0.4543066225 -0.0026392019 0.0122384129 `
--output "$WORK\propagation_bias_root_cause.json"
```
旋转敏感性、未收敛窗口重试和最终汇总属于发布级验证;它们不重新拟合杆臂。若要重新生成最终发布 JSON,必须连同上述审计结果、旋转敏感性结果和重试结果一起传给 `tools/finalize_rtk_imu_engineering_release.py`。在没有完成这些验证时,不得将本地结果标为成功。
## 代码边界与审核证据
RTK 专用代码位于 `rtk_imu/`,命令行和审计工具位于 `tools/`。它只复用 `imu_lidar/` 的通用几何、地理坐标、IMU 读取、预积分和旋转初始化模块;不依赖雷达点云、配准或雷达联合优化代码。
- [多源旋转结果](../artifacts/rtk_imu_calibration_v3/multisource_result.json)
- [47 窗口机械杆臂比较](../artifacts/rtk_imu_calibration_v3/mechanical_prior_engineering_47_window.json)
- [留出数据验证](../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)