第1章:IMU测量模型与误差分析

大家好,我是你们这门课的主讲。做惯导这么多年,我最大的体会就是:搞懂IMU的误差模型,比学会融合算法更重要。为什么?因为你的算法再牛,输入的数据是垃圾,输出也一定是垃圾。今天我们就来把IMU的底裤扒干净。

1.1 加速度计测量模型

先看加速度计。理想情况下,加速度计输出的是比力——也就是物体受到的惯性力与重力的合力。但现实嘛,总是不完美的。

我习惯把加速度计的测量模型写成这样:

a_m = S_a * (a_true + b_a + n_a) + 其他误差

其中:

  • a_m:测量值,你从芯片读到的那个数
  • a_true:真实比力,我们想要的东西
  • S_a:尺度因子矩阵,包含尺度误差和交轴耦合
  • b_a:零偏,随时间缓慢变化
  • n_a:白噪声,高频随机波动

说白了,你读到的加速度 = 真实值经过缩放、旋转、加偏置、再加噪声。每一步都是坑。

核心要点:加速度计的误差主要分两类——确定性误差(可以标定补偿的)和随机误差(只能建模的)。零偏和尺度因子属于前者,白噪声属于后者。

1.2 陀螺仪测量模型

陀螺仪的原理类似,但更敏感。我做过一个项目,陀螺仪零偏漂移了0.1°/s,积分10分钟,姿态就偏了60度。你说可怕不可怕?

陀螺仪的模型:

ω_m = S_g * (ω_true + b_g + n_g) + 其他

参数含义和加速度计基本一致:

  • ω_m:角速度测量值
  • ω_true:真实角速度
  • S_g:尺度因子矩阵
  • b_g:陀螺零偏
  • n_g:陀螺白噪声

个人经验:陀螺仪的零偏稳定性比加速度计差一个数量级。我建议你在选型时,重点关注陀螺仪的零偏稳定性指标,而不是只看量程。

1.3 误差来源深度解析

好,我们来逐个拆解这些误差。你想想看,一个IMU芯片内部,微米级的结构,温度一变、电压一抖,输出就变了。

1.3.1 零偏(Bias)

零偏就是IMU静止时,输出不为0的那个值。比如加速度计平放着,理论上应该输出[0, 0, g],但实际可能是[0.02, -0.01, 9.81]。这0.02就是零偏。

零偏又分两种:

  • 常值零偏:上电后基本固定,可以通过标定去掉
  • 零偏稳定性:随时间缓慢变化,是VIO系统最大的敌人

避坑指南:我曾经在一个项目中,忽略了零偏的温度效应。结果IMU在阳光下晒了10分钟,零偏漂了3倍,整个定位系统直接崩了。后来我学乖了,每次做实验前先让IMU预热5分钟。

1.3.2 尺度因子(Scale Factor)

尺度因子说白了就是增益误差。你输入1g,它输出0.98g,那尺度因子就是0.98。这个误差通常是非线性的,跟输入大小有关。

1.3.3 交轴耦合(Cross-axis Coupling)

这个比较隐蔽。理想情况下,IMU的三个轴应该是完全正交的。但制造工艺嘛,总有偏差。X轴感受到的加速度,可能会串到Y轴上去。这就是交轴耦合。

我习惯用矩阵来表示:

S = [s_xx, s_xy, s_xz;
     s_yx, s_yy, s_yz;
     s_zx, s_zy, s_zz]

对角线是尺度因子,非对角线是交轴耦合系数。好的IMU,非对角线系数一般在1%以内。便宜的MEMS,可能到5%。

1.4 Allan方差分析实战

好了,理论说完了,我们来点实际的。Allan方差是分析IMU随机误差的利器。我当年第一次用Allan方差时,觉得这东西太神奇了——它能从一段静态数据里,把各种噪声成分分离出来。

1.4.1 基本原理

Allan方差的思路很简单:对一段静态数据,取不同时间长度的子段,计算每个子段的均值,再求这些均值的方差。随着子段长度变化,方差曲线会呈现不同的斜率,对应不同的噪声源。

1.4.2 代码实战

下面是我常用的Allan方差计算代码,你们可以直接拿去用:

import numpy as np
import matplotlib.pyplot as plt

def allan_variance(data, fs):
    """
    计算Allan方差
    data: 输入数据(一维)
    fs: 采样频率(Hz)
    """
    N = len(data)
    max_m = int(np.log2(N)) - 1
    tau = np.zeros(max_m)
    adev = np.zeros(max_m)
    
    for m in range(1, max_m + 1):
        # 计算子段长度
        L = 2**m
        tau[m-1] = L / fs
        
        # 计算每个子段的均值
        num_clusters = N // L
        cluster_means = np.zeros(num_clusters)
        for i in range(num_clusters):
            cluster_means[i] = np.mean(data[i*L:(i+1)*L])
        
        # 计算Allan方差
        if num_clusters > 1:
            adev[m-1] = np.sqrt(0.5 * np.mean(
                (cluster_means[1:] - cluster_means[:-1])**2
            ))
    
    return tau, adev

# 使用示例
# 假设你有一段静态IMU数据
# tau, adev = allan_variance(gyro_data, 100)
# plt.loglog(tau, adev)
# plt.xlabel('时间 (s)')
# plt.ylabel('Allan标准差')
# plt.grid(True)
# plt.show()

我的习惯:Allan方差分析至少需要1小时以上的静态数据。数据太短,长周期噪声看不出来。我一般会采集2-3小时,然后取中间最稳定的一段。

1.4.3 结果解读

Allan方差曲线通常呈现这样的特征:

  • 斜率-1/2段:对应白噪声,也就是角度随机游走(ARW)或速度随机游走(VRW)
  • 斜率0段(平坦区):对应零偏稳定性
  • 斜率+1/2段:对应速率斜坡(Rate Ramp),通常是温度漂移

从曲线上,我们可以提取三个关键指标:

指标 含义 单位
角度随机游走 白噪声强度 °/√h
零偏稳定性 曲线最低点 °/h
速率斜坡 长周期漂移 °/h²

实战经验:我见过很多同学拿到Allan方差曲线后,不知道怎么看。记住一句话:曲线的最低点就是你的零偏稳定性。这个值决定了你的VIO系统能维持多久不飘。

1.5 本章知识体系

为了让大家更直观地理解本章的知识结构,我画了一张图:

IMU测量模型与误差分析知识体系 IMU 加速度计 陀螺仪 测量模型:a_m = S·(a_true + b + n) 测量模型:ω_m = S·(ω_true + b + n) 零偏 尺度因子 交轴耦合 白噪声 Allan方差分析 角度随机游走 | 零偏稳定性 | 速率斜坡

这张图把本章的知识脉络串起来了。从上到下,从IMU到具体传感器,再到测量模型、误差来源,最后用Allan方差做分析,提取关键指标。你把这个图记在脑子里,后面学融合算法时就会清晰很多。

最后说一句:IMU误差分析是VIO系统的基石。我见过太多人一上来就调融合参数,结果定位精度上不去,最后发现是IMU标定没做好。所以,先把IMU的脾气摸透,再谈算法优化

专注资料整理