3、IMU预积分理论(上):预积分的动机与数学推导,离散时间下的预积分公式,预积分量的更新与协方差传递
大家好,欢迎来到这一节。今天我们要聊的是IMU预积分,这是视觉惯性里程计(VIO)里非常核心的一块。说实话,我第一次接触这个概念的时候,也觉得有点绕。但别急,我们一步步来拆解。
3.1 为什么需要预积分?——动机与直觉
先问大家一个问题:在视觉SLAM里,我们通常把图像帧作为关键帧。两帧之间,IMU会输出很多很多数据。如果每次优化都要重新积分这些IMU数据,计算量会非常大。而且,一旦位姿变了,积分就得重来。
这就像你写了一份很长的报告,结果老板说“你把第一页的标题改一下”,然后你整份报告都得重写。是不是很崩溃?
预积分就是为了解决这个问题。它的核心思想是:把两帧之间的IMU测量值“打包”成一个相对运动约束。这个约束不依赖于绝对位姿,只依赖于两帧之间的相对运动。
核心动机: 预积分将IMU测量值从“绝对位姿的积分”转化为“相对位姿的约束”,从而在优化中避免重复积分,大幅提升计算效率。
我个人习惯把预积分理解成“IMU的压缩包”。你想想看,原本几百个IMU数据点,压缩成一个预积分量,优化的时候直接解压用就行了。我在项目中遇到过,如果不做预积分,后端优化一次可能要几十毫秒,用了预积分后,直接降到几毫秒。效果立竿见影。
3.2 预积分的数学推导
好,我们来看数学。IMU的测量模型是这样的:
a_m = a - g + b_a + n_a
ω_m = ω + b_g + n_g
其中a_m和ω_m是测量值,a和ω是真实值,g是重力,b_a和b_g是零偏,n_a和n_g是噪声。
传统的积分是从时刻i到时刻j,直接积分出位置、速度和姿态:
p_j = p_i + v_i * Δt + 0.5 * g * Δt² + R_i * ∫∫ (a_m - b_a - n_a) dt²
v_j = v_i + g * Δt + R_i * ∫ (a_m - b_a - n_a) dt
R_j = R_i * ∫ exp(ω_m - b_g - n_g) dt
注意看,这里每个积分都依赖于R_i(起始时刻的姿态)。一旦R_i在优化中变了,所有积分都得重算。这就是问题的根源。
预积分的做法是:把积分项从绝对坐标系转移到机体坐标系。我们定义预积分量如下:
ΔR_ij = ∫ exp(ω_m - b_g - n_g) dt
Δv_ij = ∫ R_t^T * (a_m - b_a - n_a) dt
Δp_ij = ∫∫ R_t^T * (a_m - b_a - n_a) dt²
这里R_t是从时刻i到当前时刻t的姿态变化。你会发现,这些预积分量只依赖于IMU测量值和零偏,与绝对位姿完全无关。
个人经验: 我在写代码时,喜欢把预积分量单独封装成一个类。这样在优化中,只需要更新零偏,然后对预积分量做一阶线性修正,非常方便。
3.3 离散时间下的预积分公式
实际中,IMU数据是离散的。我们假设在时间区间[t_k, t_{k+1}]内,IMU测量值保持不变。那么离散时间的预积分公式如下:
ΔR_{k+1} = ΔR_k * Exp((ω_m - b_g) * Δt)
Δv_{k+1} = Δv_k + ΔR_k * (a_m - b_a) * Δt
Δp_{k+1} = Δp_k + Δv_k * Δt + 0.5 * ΔR_k * (a_m - b_a) * Δt²
这里Exp()是李代数到李群的指数映射。说白了,就是旋转矩阵的更新。
嗯,这里要注意一点:离散化会引入误差。IMU频率越高,误差越小。我一般用200Hz的IMU,效果还不错。如果你用100Hz,可能需要考虑更高精度的积分方法,比如中值积分。
3.4 预积分量的更新与协方差传递
预积分量不是一成不变的。当零偏更新时,预积分量也需要更新。我们通常用一阶泰勒展开来做:
ΔR_ij(b_g_new) ≈ ΔR_ij(b_g) * Exp(∂ΔR/∂b_g * δb_g)
Δv_ij(b_new) ≈ Δv_ij(b) + ∂Δv/∂b_a * δb_a + ∂Δv/∂b_g * δb_g
Δp_ij(b_new) ≈ Δp_ij(b) + ∂Δp/∂b_a * δb_a + ∂Δp/∂b_g * δb_g
这些雅可比矩阵可以在预积分过程中递推计算。我建议你在代码里把这些雅可比也存下来,后面优化要用。
接下来是协方差传递。预积分量是有噪声的,我们需要知道它的不确定性。协方差传递公式如下:
Σ_{k+1} = A_k * Σ_k * A_k^T + B_k * Q * B_k^T
其中A_k是状态转移矩阵,B_k是噪声输入矩阵,Q是IMU噪声的协方差矩阵。这个公式和卡尔曼滤波里的协方差预测一模一样。
避坑指南: 我曾经在协方差传递上栽过跟头。当时忽略了零偏的雅可比,结果优化出来的轨迹飘得厉害。后来加上零偏的雅可比,问题就解决了。所以,零偏的雅可比一定不能省。
3.5 知识体系总览
为了让大家更直观地理解预积分的整体流程,我画了一张图:
3.6 总结与要点
好了,我们来回顾一下今天的内容:
- 预积分的动机:避免在优化中重复积分IMU数据,提升计算效率。
- 数学推导:将积分从绝对坐标系转移到机体坐标系,得到与绝对位姿无关的预积分量。
- 离散时间公式:用欧拉积分或中值积分递推ΔR、Δv、Δp。
- 更新与协方差:零偏变化时用一阶泰勒展开修正,协方差通过线性化传递。
核心一句话: 预积分就是把IMU数据“打包”成相对约束,让优化又快又稳。
我个人觉得,预积分是VIO里最优雅的设计之一。它把原本耦合的问题解耦了,让系统变得模块化。你在写代码的时候,也会感受到这种设计带来的清爽感。
好,今天就到这里。下一节我们会继续深入,聊预积分的具体实现和代码细节。到时候我会分享一些我踩过的坑,保证让你少走弯路。