3、IMU测量模型与运动学:加速度计与陀螺仪原理、IMU噪声模型、Allan方差分析

好,咱们进入第三章。这一章聊的是IMU——视觉惯性SLAM系统的“心脏”。说白了,没有IMU,纯视觉在快速运动或弱纹理场景下很容易“飘”。但IMU也不是完美的,它有自己的一套脾气。你得摸透它的测量模型和噪声特性,才能用好它。

核心观点:IMU的测量值 = 真实值 + 系统误差 + 随机噪声。我们的目标,就是把这堆“脏数据”洗干净,喂给后端优化器。

3.1 加速度计与陀螺仪原理

先说说加速度计。它测的是什么?不是速度,是比力(Specific Force)。你想想看,一个静止放在桌面上的加速度计,它读数是(0, 0, 9.81) m/s²。为什么?因为它感受到的是重力加速度的反作用力。这个力,就是比力。

陀螺仪呢?它测的是角速度。MEMS陀螺仪的原理其实挺巧妙的——利用科里奥利效应。一个振动的质量块,当它绕某个轴旋转时,会受到一个垂直于振动方向和旋转轴方向的力。测这个力的大小,就能反推出角速度。

我个人习惯把IMU的测量模型写成这样:

加速度计: a_m = R^T * (a_w - g) + b_a + n_a
陀螺仪:   ω_m = ω_w + b_g + n_g

这里:

  • a_mω_m 是测量值
  • a_wω_w 是世界坐标系下的真实值
  • R 是旋转矩阵,把世界系转到IMU系
  • g 是重力向量
  • b_ab_g 是零偏(Bias)
  • n_an_g 是白噪声

嗯,这里要注意:加速度计测量的是“比力”,不是“加速度”。很多新手会搞混,以为加速度计直接输出加速度。其实不是的,它输出的是“非引力加速度”。所以我们在做预积分时,要先把重力项减掉。

我的经验:有一次在无人机上做VIO,发现高度一直在漂。查了半天,原来是加速度计的零偏没标定好。0.1 m/s²的零偏,积分10秒就能产生5米的误差。所以,零偏的初始标定非常重要。

3.2 IMU噪声模型

IMU的噪声,我把它分成两大类:

  1. 确定性误差:包括零偏、尺度因子、轴间耦合等。这些可以通过标定来补偿。
  2. 随机噪声:包括白噪声、随机游走、量化噪声等。这些需要用统计模型来描述。

在SLAM里,我们最关心的是两个噪声参数:

参数 符号 单位 物理意义
陀螺仪白噪声 σ_g rad/s/√Hz 角速度测量的高频抖动
加速度计白噪声 σ_a m/s²/√Hz 加速度测量的高频抖动
陀螺仪零偏随机游走 σ_bg rad/s²/√Hz 零偏随时间缓慢漂移的速率
加速度计零偏随机游走 σ_ba m/s³/√Hz 零偏随时间缓慢漂移的速率

为什么是这些参数?因为IMU的误差模型,本质上是一个“白噪声驱动”的系统。白噪声经过积分,会变成随机游走。你想想看,陀螺仪的角速度测量有白噪声,积分后得到角度,这个角度的误差就是随机游走。同理,加速度计的白噪声积分后得到速度误差,再积分得到位置误差——这就是为什么纯惯性导航的位置误差会随时间三次方增长。

避坑指南:我曾经在标定一个低成本IMU时,发现Allan方差曲线在短时间尺度上不是-1/2斜率。后来才发现,这个IMU的量化噪声特别大,把白噪声的频谱特征给掩盖了。所以,拿到一个新IMU,先别急着用,画个Allan方差图看看。

3.3 Allan方差分析

Allan方差,说白了就是用来“拆解”IMU噪声成分的工具。它通过分析不同时间尺度上的方差变化,把白噪声、随机游走、量化噪声、零偏不稳定性等一一分离出来。

计算步骤其实不复杂:

  1. 采集一段长时间的静态IMU数据(至少1小时,我建议2小时以上)
  2. 把数据分成若干段,每段时长τ
  3. 计算每段数据的平均值
  4. 计算相邻段平均值的差的方差
  5. 改变τ,重复步骤2-4
  6. 画出log(τ) vs log(Allan方差)的曲线

下面是我用Python写的一个简单实现:

def allan_variance(data, max_tau_ratio=0.1):
    """
    计算Allan方差
    data: 一维IMU数据
    max_tau_ratio: 最大τ占数据长度的比例
    """
    n = len(data)
    max_tau = int(n * max_tau_ratio)
    tau_list = []
    avar_list = []
    
    # 用对数间隔生成τ值
    tau_values = np.unique(np.logspace(0, np.log10(max_tau), 50).astype(int))
    
    for tau in tau_values:
        # 计算每个时间段的平均值
        m = n // tau
        if m < 2:
            break
        # 分段平均
        data_avg = data[:m*tau].reshape(m, tau).mean(axis=1)
        # 计算相邻段差的方差
        diff = data_avg[1:] - data_avg[:-1]
        avar = 0.5 * np.mean(diff**2)
        
        tau_list.append(tau)
        avar_list.append(avar)
    
    return np.array(tau_list), np.array(avar_list)

画出来的Allan方差曲线,不同斜率对应不同噪声类型:

斜率 噪声类型 读取位置
-1/2 白噪声(角度随机游走) τ=1处的值
0 零偏不稳定性 曲线最低点
+1/2 零偏随机游走 大τ处的斜率
-1 量化噪声 小τ处的斜率
+1 速率斜坡 大τ处的斜率

我个人习惯,拿到一个新IMU,第一件事就是跑Allan方差。这就像医生给病人做体检,先看看各项指标是否正常。如果零偏不稳定性特别大,那这个IMU可能不太适合做高精度SLAM。

关键点:Allan方差曲线的最低点对应的τ值,就是IMU的“最佳积分时间”。在这个时间尺度上,IMU的噪声最小。如果你的SLAM系统里,IMU预积分的时间窗口接近这个值,那精度会比较好。

嗯,这里还要提一句。Allan方差分析需要静态数据,但实际应用中IMU是运动的。所以,我们通常用Allan方差来标定IMU的“本征噪声”,然后在SLAM系统里用这些参数来设置信息矩阵的权重。

IMU测量模型与噪声分析框架 IMU原始测量 测量模型 a_m = Rᵀ(a_w - g) + b_a + n_a | ω_m = ω_w + b_g + n_g 确定性误差 • 零偏 (Bias) • 尺度因子 | 轴间耦合 随机噪声 • 白噪声 (σ_g, σ_a) • 随机游走 (σ_bg, σ_ba) 标定方法 六面法 | 转台标定 | 多位置法 分析方法 Allan方差 | 功率谱密度 SLAM系统:预积分 | 信息矩阵 | 状态估计 图:IMU测量模型与噪声分析框架

这张图把整个IMU测量模型和噪声分析的脉络理清楚了。从原始测量出发,经过测量模型分解,再到确定性误差和随机噪声的分别处理,最后汇聚到SLAM系统的应用。你想想看,每一步都有对应的数学工具和工程方法。

实用建议:在实际项目中,我建议把Allan方差分析做成一个自动化脚本。每次标定完IMU,自动生成报告,包括噪声参数、曲线图、以及“IMU健康度”评分。这样团队里每个人都能快速判断IMU的状态。

好了,这一章的内容就到这里。IMU的测量模型和噪声分析,是视觉惯性SLAM的基石。把这块吃透了,后面的预积分、初始化、紧耦合优化,你才能理解为什么代码要那样写,参数要那样设。

专注资料整理