2. IMU误差模型与标定:确定性误差与随机误差、Allan方差分析、六面法标定与温漂补偿

IMU这东西,说白了就是自动驾驶的「内耳前庭」。你想想看,车在隧道里、高架桥下,GPS信号一丢,全靠它撑着。但IMU有个毛病——它天生就是个「说谎精」。我做了这么多年定位,见过太多被IMU坑惨的项目。所以今天咱们就来扒一扒,怎么让这个说谎精说实话。

2.1 误差从哪来?先分个类

IMU的误差,我习惯分成两大类:确定性误差和随机误差。这俩性质完全不同,处理手段也天差地别。

2.1.1 确定性误差

这类误差是「有规律」的,说白了就是可以建模、可以补偿的。主要包括:

  • 零偏(Bias):静止时输出不为零。比如陀螺仪,你把它放桌上不动,它却告诉你「我在转」。我见过最离谱的MEMS陀螺,零偏能到每秒好几度。
  • 尺度因子(Scale Factor):输入和输出不成比例。你转10度,它告诉你转了10.5度。
  • 交轴耦合(Misalignment):三个轴没装正。X轴转动时,Y轴也有输出。嗯,这就是机械装配的锅。

核心公式:

ω_measured = S * ω_true + b + n

其中S是尺度因子矩阵,b是零偏,n是噪声。这个公式,我建议你刻在脑子里。

2.1.2 随机误差

这类误差是「没规律」的,只能用统计方法描述。我在项目中遇到过最头疼的就是它——你永远不知道下一秒的噪声长什么样。

  • 白噪声(White Noise):高频随机波动,像收音机的沙沙声。
  • 随机游走(Random Walk):零偏随时间缓慢漂移。你今天标定好的零偏,明天可能就变了。
  • 量化噪声(Quantization Noise):ADC采样精度不够导致的。

我的经验: 随机误差才是IMU标定的真正难点。确定性误差一次标定就能搞定,但随机误差需要长期观测和在线估计。

2.2 Allan方差分析——给IMU做「体检」

Allan方差,说白了就是给IMU做一次全面体检。它能告诉你:你的IMU到底有多烂,烂在哪个频段。

2.2.1 基本原理

为什么要用Allan方差?因为普通的方差会随着采样时间变化。你取1秒的数据算方差,和取100秒的数据算方差,结果完全不一样。Allan方差解决了这个问题——它把数据切成不同长度的块,分别算方差。

具体做法很简单:

  1. 采集一段长时间的静态数据(至少1小时,我建议2小时以上)
  2. 把数据按不同时间长度τ切成若干段
  3. 对每个τ,计算所有段的方差
  4. 画出log(τ) vs log(Allan方差)的曲线

2.2.2 怎么看这条曲线?

Allan方差曲线有典型的形状,不同斜率对应不同误差源:

斜率 对应误差 物理意义
-1/2 白噪声(角度/速度随机游走) 高频抖动,取平均就能抑制
0 零偏不稳定性(Bias Instability) IMU的「底噪」,这是最重要的指标
+1/2 速率随机游走 零偏的长期漂移
+1 速率斜坡 温度引起的确定性漂移

关键点: 曲线的最低点对应的τ值,就是你的IMU「最佳积分时间」。低于这个时间,白噪声主导;高于这个时间,零偏漂移主导。我选IMU时,第一件事就是看这个最低点。

2.2.3 代码实现

嗯,这里给个Python实现,我项目里一直在用:

def allan_variance(data, fs):
    """
    data: 静态IMU数据
    fs: 采样率
    """
    N = len(data)
    max_pow = int(np.log2(N)) - 1
    tau = []
    avar = []
    
    for i in range(1, max_pow):
        m = 2**i
        tau.append(m / fs)
        # 分成不重叠的段
        num_segments = N // m
        segments = data[:num_segments*m].reshape(num_segments, m)
        # 每段取平均
        means = np.mean(segments, axis=1)
        # 计算方差
        avar.append(0.5 * np.var(means[1:] - means[:-1]))
    
    return np.array(tau), np.array(avar)

避坑指南: 我曾经因为数据采集时间不够长,Allan方差曲线在长τ段全是噪声。后来养成了习惯——静态数据至少采2小时,最好过夜采集。

2.3 六面法标定——给IMU「对表」

六面法,说白了就是把IMU放在6个不同的姿态,利用重力作为参考,反算出零偏和尺度因子。这个方法简单粗暴,但非常有效。

2.3.1 标定流程

你需要一个三轴转台,或者至少一个水平台面。我早期在实验室里,就用一个精密水平仪加一个直角块,也能凑合用。

  1. 水平放置:Z轴朝上,采集30秒
  2. 翻转180°:Z轴朝下,采集30秒
  3. 侧放:X轴朝上,采集30秒
  4. 侧放翻转:X轴朝下,采集30秒
  5. 侧放:Y轴朝上,采集30秒
  6. 侧放翻转:Y轴朝下,采集30秒

2.3.2 数学模型

对于加速度计,每个轴的理论输出应该是±g(重力加速度)。实际输出和理论值的关系是:

a_measured = S * a_true + b

写成矩阵形式:

[a_x]   [s_xx  s_xy  s_xz] [a_x_true]   [b_x]
[a_y] = [s_yx  s_yy  s_yz] [a_y_true] + [b_y]
[a_z]   [s_zx  s_zy  s_zz] [a_z_true]   [b_z]

6个姿态,每个姿态提供3个方程,一共18个方程。用最小二乘法就能解出12个未知数(3个零偏 + 9个尺度因子)。

注意: 六面法假设转台或台面绝对水平。我曾经在一个不平的台面上标定,结果零偏误差大了3倍。后来我学乖了——每次标定前先用水平仪校准台面。

2.4 温漂补偿——IMU的「体温计」

温度对IMU的影响,比你想象的大得多。我记得有一次冬天做路测,早上零下10度标定的IMU,中午太阳一晒,零偏直接漂了20%。从那以后,温漂补偿就成了我的必修课。

2.4.1 温漂特性

IMU的零偏和尺度因子,随温度变化呈非线性关系。典型的温漂曲线是这样的:

  • MEMS IMU:温度每变化1°C,零偏变化约0.01~0.1°/s
  • 光纤陀螺:温漂小一些,但启动阶段变化剧烈
  • 激光陀螺:温漂最小,但价格感人

2.4.2 补偿方法

我常用的方法是多项式拟合:

b(T) = c0 + c1*T + c2*T^2 + c3*T^3

标定步骤:

  1. 把IMU放进温箱,从-40°C到85°C,每5°C一个点
  2. 每个温度点保持30分钟,让IMU充分热平衡
  3. 记录每个温度下的零偏和尺度因子
  4. 用最小二乘法拟合多项式系数

我的经验: 3阶多项式通常就够了,阶数太高反而容易过拟合。另外,温箱的升降温速率要慢,我一般控制在1°C/min,太快了热应力会影响结果。

2.5 本章小结

IMU标定这件事,说难不难,说简单也不简单。你想想看,一个没标定好的IMU,就像一块不准的表——你越依赖它,它越坑你。我见过太多项目,算法调得天花乱坠,结果IMU本身就有问题,白费功夫。

核心就三点:

  • 确定性误差用六面法搞定,一次标定管半年
  • 随机误差用Allan方差摸清底细,指导滤波器设计
  • 温漂必须补偿,尤其是车规级应用,温度范围宽

嗯,标定做好了,后面的融合定位才能站得住脚。否则,再好的算法也是空中楼阁。

可可精品资料库