# RTK–IMU 标定 本文是本仓库 RTK–IMU 标定的唯一规范说明,覆盖数据、方法、当前结果、限制和复现。它不使用项目内部阶段代号作为前提。 ## 结论与适用范围 本次标定的正确表述是:**双天线方向和水平静止时的重力约束给出了固定旋转;天线相位中心到 IMU 的平移以机械测量为绝对基准,RTK 与 IMU 动态数据对该安装关系完成了独立一致性与稳定性验证。** 动态数据未能独立、精确地估计完整三维杆臂,但没有发现机械测量值与真实运动矛盾。 | 项目 | 当前值或状态 | | --- | --- | | 天线相位中心相对 IMU 的杆臂 `l_I` | `[-0.4518015159, -0.2644749820, 0.7314656115] m` | | 固定旋转来源 | 水平静止时的双天线基线与重力约束 | | 固定旋转近似 RPY(X/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)