241 lines
14 KiB
Markdown
241 lines
14 KiB
Markdown
# 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) |