VIO 深度笔记:预积分、可观性与标定误差传播
推导 IMU 预积分与 bias 一阶修正,分析视觉惯性可观性条件,并给出外参/时延误差如何污染尺度与姿态的工程诊断方法。

VIO 论文读起来像「视觉 + IMU 一起优化」,真机失败却几乎总是:时间不同步、外参错、噪声数量级错、初始化在不可观激励下强行成功。本文按「模型 → 可观性 → 误差传播 → 诊断」展开。
状态与观测模型
常用状态(IMU body 系):
x = [ R, p, v, b_g, b_a ] (+ 可选: 外参 T_bc, 时延 t_d, 尺度 s)运动方程(连续时间,忽略地球自转):
Ṙ = R [ω_m - b_g - n_g]_×
ṗ = v
v̇ = R (a_m - b_a - n_a) + g
ḃ_g = n_{bg}, ḃ_a = n_{ba}视觉因子提供路标重投影;IMU 因子连接相邻关键帧的相对运动。紧耦合把两者放进同一个 MAP。
IMU 预积分:为什么必须做
若每次优化迭代都从原始 IMU 序列重新积分,代价不可接受,且线性化点变化会毁掉一致性。Forster 等提出的预积分:在局部坐标系把 [t_i, t_j] 的 IMU 测量压缩为:
ΔR_ij, Δv_ij, Δp_ij及其对 bias 的一阶雅可比 J_bg, J_ba,以及协方差 Σ_ij。
2.1 离散递推(概念形式)
以中值积分为例(实现细节随代码库而异):
ΔR ← ΔR · Exp( (ω - b_g) Δt )
Δv ← Δv + ΔR · (a - b_a) Δt
Δp ← Δp + Δv Δt + ½ ΔR · (a - b_a) Δt²同时递推协方差:把状态转移线性化,做离散 Lyapunov / 离散 RK 更新。
2.2 Bias 更新时的一阶修正
优化中 bias 从线性化点 b̄ 变为 b̄ + δb 时,不必重积全段:
ΔR(b) ≈ ΔR(b̄) · Exp( J_bg^R · δb_g )
Δv(b) ≈ Δv(b̄) + J_bg^v δb_g + J_ba^v δb_a
Δp(b) ≈ Δp(b̄) + J_bg^p δb_g + J_ba^p δb_a这就是预积分「可重复线性化」的关键。若你的实现每次 bias 一变就整段重积却忘记更新 Σ,滤波器会过度自信。
2.3 残差(右乘扰动)
r_R = Log( (ΔR Exp(J δb))ᵀ R_iᵀ R_j )
r_v = R_iᵀ (v_j - v_i - g Δt) - (Δv + J δb)
r_p = R_iᵀ (p_j - p_i - v_i Δt - ½ g Δt²) - (Δp + J δb)把 r = [r_R; r_v; r_p] 用 Σ_ij 加权,即 IMU 因子。
可观性:初始化成功 ≠ 状态可观
3.1 理想条件下可观的量
静态偏置、已知重力模长、充分激励时,可观:
- 姿态(相对重力)
- 速度
- 陀螺 bias
- 加计 bias(与重力耦合,需运动分离)
- 单目尺度
- (弱)外参旋转/平移的部分分量
3.2 不可观 / 弱可观陷阱
| 激励不足 | 后果 |
|---|---|
| 近似匀速直线 | 尺度与加计 bias 耦合难分 |
| 几乎静止 | 陀螺 bias 可估,尺度不可观 |
| 纯旋转 | 位置/速度可观性差 |
| 重力方向激励不足 | 姿态绕重力轴 yaw 弱可观(视传感器) |
OpenVINS / VINS 初始化失败时,先画轨迹激励:是否覆盖三轴角速度与加速度变化,而不是先降特征阈值。
3.3 初始化的信息论视角
初始化本质是:用短窗口视觉结构(SfM)+ IMU 约束解一个非线性系统。若视觉基线不足,SfM 尺度本身噪声极大,IMU 再准也只能「拟合噪声」。
实用判据(可写进代码):
- 视差角中位数 > 阈值
- IMU 激励:
∫||ω||、∫||a - g||超过下限 - 重力对齐后重投影误差 / 预积分残差 Chi2 通过
- bias 落在物理合理区间(例如陀螺 bias 不是 1 rad/s)
失败就重置,不要「带着错误尺度继续跑」。
标定误差如何传播
4.1 外参旋转误差 δθ
相机光线方向被错误旋转,等价于系统性地把视觉约束扭到错误的 body 系。表现:
- 水平运动时高度漂移
- 转弯时尺度呼吸(忽大忽小)
- 静止时视觉与重力方向打架 → 姿态抖动
经验:δθ 到 1° 量级,对高速平台往往不可接受;手持慢速有时仍能「看着还行」。
4.2 外参平移误差 δt
对立体/深度影响直接;对单目 VIO,主要污染尺度与杠杆臂补偿。高速旋转时,ω × δt 会被误解释为线运动。
4.3 时间偏移 t_d
相机时间戳比 IMU 慢 t_d 时,运动越快误差越大。近似:
Δp_error ~ v · t_d + ½ a · t_d²
ΔR_error ~ ω · t_d诊断:把同一段 bag 用 t_d ∈ [-30ms, 30ms] 扫一遍,看轨迹 ATE / 重投影;真机软同步常落在数毫秒到数十毫秒。
4.4 噪声参数数量级
Allan Variance 得到的连续时间密度要和离散预积分实现一致(是否含 √dt)。常见错误:把 datasheet 的 °/h、µg/√Hz 单位换算错两个数量级。
- Σ 过小:过度信任 IMU → 轨迹「刚硬」但撞视觉时撕裂
- Σ 过大:VIO 退化成 VO,失去尺度刚性
边缘化与一致性
滑窗 VIO 必须边缘化老状态。错误边缘化会引入「虚假信息」:
- 线性化点远离当前估计却不重新线性化(First Estimate Jacobian 策略需统一)
- 丢弃与视觉残差相关的交叉项
- 先验重复使用同一批测量(double counting)
症状:长时间运行后协方差异常缩小,一遇回环或强视觉变化就发散。
工程诊断手册
6.1 日志里应持久化的量
每帧 / 每关键帧记录:
- 特征数、匹配内点数、重投影 RMSE
- IMU 因子 Chi2、视觉因子 Chi2
b_g, b_a曲线- 滑窗尺度(若显式参数化)或中位深度
- 优化迭代次数 / 耗时
6.2 场景化排障
A. 一开始就飞
- 检查加速度单位(g vs m/s²)
- 检查轴方向与右手系
- 检查重力符号
B. 前 20 秒正常后尺度崩
- 初始化阈值过松
- 外参平移/时延
- 曝光变化导致视觉权重失真
C. 转弯掉高程
- 外参滚转/俯仰
- 加计轴交叉耦合
- 轮速(若融合)半径错误
D. 振动环境(机载)
- 加计饱和 / 高频噪声未滤波
- 需要更好的减振与噪声建模,而不是只加特征点
标定流水线(可复现)
- 相机内参:全视场、多距离、含边缘
- IMU Allan:静止 2–4 小时(视传感器)
- Kalibr
cam + imu:充分激励,检查重投影与加速度残差报告 - 用 EuRoC 同类配置跑通基线,再上自有硬件
- 真机:固定外参初值,短时在线精修(若系统支持),收敛后锁定
把标定文件、固件版本、安装扭矩/结构件版本纳入版本管理——结构形变会导致「昨天还准今天飘」。
算法选型要点(深层)
| 系统 | 后端 | 适合 |
|---|---|---|
| VINS-Fusion | 优化 + 边缘化 | 研究/无人机,生态成熟 |
| OpenVINS | MSCKF 系滤波 | 高效、工程清晰 |
| ORB-SLAM3 VI | 特征 + 局部 BA + Atlas | 多地图、重定位强 |
| OKVIS / Kimera | 关键帧优化 | 学术基线 |
选择标准不是 GitHub star,而是:你能否改它的噪声模型、外参与时间偏移,并导出残差日志。
小结
VIO 的深度不在「又换一个前端网络」,而在:
- 预积分与 Σ 是否自洽
- 激励是否满足可观性
- 外参/时延误差是否被量化
- 边缘化是否保持一致性
- 失败是否可检测、可重置
把这五件事做成仪表盘,你才能从「能 Demo」走到「能部署」。
参考
IMU 相关的问题,时间对齐没确认前,我不会先去拧偏置噪声参数。
- Forster et al., On-Manifold Preintegration for Real-Time Visual-Inertial Odometry
- Qin et al., VINS-Mono
- Geneva et al., OpenVINS
- Mirzaei & Roumeliotis, observability of IMU-camera calibration
- Kalibr (ETH)
相关
也可以看看
johan's blog