第3章:随机误差建模——Allan方差分析法
各位同学,欢迎来到随机误差建模这一章。
说实话,IMU的误差分两类:一类是确定性误差,比如零偏、尺度因子,这些我们能用标定手段干掉;另一类是随机误差,说白了就是噪声——它没有固定规律,但又有统计特征。今天我们要聊的Allan方差分析法,就是用来“解剖”这些随机噪声的利器。
3.1 为什么需要Allan方差?
我在做低成本MEMS IMU项目时,遇到过一个问题:陀螺仪的输出数据看起来“挺干净”,但积分后姿态漂移得厉害。后来才发现,噪声的“颜色”不一样,光看时域波形根本看不出来。
Allan方差最早是用于原子钟频率稳定度分析的,后来被引入IMU领域。它的核心思想很简单:通过不同时间尺度上的方差变化,来识别噪声的类型和强度。
核心价值:Allan方差能帮我们从一堆随机数据中,分离出5种典型噪声成分——量化噪声、角度随机游走、零偏不稳定性、速率随机游走、速率斜坡。
3.2 Allan方差分析法的步骤
嗯,这里我直接说步骤,你跟着做就行。我在项目里至少跑了上百次Allan方差分析,流程早就烂熟于心了。
- 采集静态数据:IMU静止放置,采样率固定(比如100Hz),采集时长至少2小时。我建议至少4小时,数据越长,低频段分析越准。
- 计算角增量/速度增量:对于陀螺仪,计算每个采样间隔内的角增量;对于加速度计,计算速度增量。
- 分组平均:将数据按不同时间长度τ分组,每组内取平均。τ从最小采样间隔开始,逐步增大。
- 计算方差:对每个τ,计算相邻两组平均值的差值的方差,再除以2。
- 绘制双对数曲线:横轴为τ(对数坐标),纵轴为Allan方差σ²(τ)(对数坐标)。
你想想看,这个过程其实就是在问:如果我把数据按不同时长做平均,噪声的波动程度会怎么变化?
3.3 Allan方差曲线解读
曲线画出来后,怎么读?我刚开始看的时候也是一头雾水,后来总结了一个口诀:看斜率,辨噪声。
下面这张SVG图,是我自己画的Allan方差典型曲线,包含了5种噪声成分的斜率特征:
这张图怎么看?我带你走一遍:
- 量化噪声:斜率 -1,出现在短时间尺度(τ很小)。说白了就是ADC量化带来的误差,低成本IMU里比较明显。
- 角度随机游走:斜率 -1/2,这是最常见的噪声成分。我在做行人导航时,这个参数直接决定了零速修正的频率。
- 零偏不稳定性:斜率 0,曲线的最低点。这个值就是IMU的“零偏稳定性”,是选型时最关键的指标之一。
- 速率随机游走:斜率 +1/2,出现在长时间尺度。说明零偏在缓慢漂移,温度变化或老化效应会导致这个。
- 速率斜坡:斜率 +1,这是确定性趋势项,不是随机噪声。如果出现这个,说明你的数据里有线性趋势,需要先做去趋势处理。
我的经验:实际IMU的Allan曲线往往是这5种噪声的叠加。你看到的曲线可能只有2-3个明显的斜率段,这很正常。别硬套5段,能识别出主要成分就够了。
3.4 基于Allan方差的噪声参数提取
曲线看懂了,接下来就是提取参数。说白了,就是从曲线上读出每个噪声成分的系数。
我常用的方法是:最小二乘拟合。在双对数坐标下,对每个斜率段做线性拟合,然后反算出噪声系数。
下面给出一段Python代码,这是我项目里一直在用的,你直接拿去用:
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)
allan_var = np.zeros(max_m)
for m in range(1, max_m + 1):
# 分组平均
n = 2**m
tau[m-1] = n / fs
# 计算相邻组差值的方差
num_groups = N // n
if num_groups < 2:
break
# 取每个组的平均值
groups = data[:num_groups * n].reshape(num_groups, n)
means = np.mean(groups, axis=1)
# 计算Allan方差
diff = means[1:] - means[:-1]
allan_var[m-1] = 0.5 * np.mean(diff**2)
return tau, allan_var
# 使用示例
fs = 100.0 # 100Hz采样
# 假设gyro_data是你的陀螺仪数据(单位:rad/s)
# tau, avar = allan_variance(gyro_data, fs)
# 绘制双对数曲线
# plt.loglog(tau, np.sqrt(avar))
# plt.xlabel('τ (s)')
# plt.ylabel('Allan Deviation (rad/s)')
# plt.grid(True, which='both', ls='--')
# plt.show()
注意:数据长度直接影响低频段的可靠性。我吃过亏——有一次只采集了30分钟数据,结果速率随机游走那段曲线完全是假的。后来我养成了习惯:至少采集2小时,最好4小时以上。
3.5 参数提取的具体方法
从Allan曲线上提取噪声参数,我总结了下面这张表,你直接对照着用:
| 噪声类型 | 斜率 | 提取方法 | 单位 |
|---|---|---|---|
| 量化噪声 | -1 | 在τ=√3处读取σ值,Q = σ / √3 | rad 或 m/s |
| 角度随机游走 | -1/2 | 在τ=1处读取σ值,ARW = σ | °/√h 或 m/s/√h |
| 零偏不稳定性 | 0 | 读取曲线最低点的σ值 | °/h 或 m/s² |
| 速率随机游走 | +1/2 | 在τ=3处读取σ值,RRW = σ / √3 | °/h/√h 或 m/s²/√h |
| 速率斜坡 | +1 | 在τ=√2处读取σ值,斜率系数 = σ / (τ/√2) | °/h² 或 m/s²/h |
嗯,这里要特别说一下角度随机游走(ARW)。这个参数在导航里太重要了——它决定了你的姿态在无修正情况下能保持多久。我做过一个无人机项目,ARW是0.5°/√h的IMU,纯惯性飞行30秒后姿态误差就超过5度了。
3.6 避坑指南
最后,分享几个我踩过的坑:
- 数据预处理不能省:先去掉明显的异常值(比如IMU刚上电时的数据),再做去趋势处理。我曾经因为没去趋势,把速率斜坡当成了随机噪声,结果参数全错了。
- 采样率要匹配:低成本IMU的采样率通常不高(100-200Hz),这时候量化噪声段可能只有几个点,别强行拟合。
- 温度影响:Allan方差分析要在恒温环境下做。我试过在空调时开时关的房间里采集数据,结果零偏不稳定性那段曲线抖得跟心电图似的。
- 多次测量取平均:单次Allan曲线有随机性,我建议至少做3次,取平均曲线再提取参数。
总结一下:Allan方差分析法,说白了就是给IMU的随机噪声“拍X光片”。通过一张双对数曲线图,你就能看清5种噪声的分布情况,然后提取出关键参数。这些参数会直接用在后面的卡尔曼滤波器设计里——比如设置过程噪声协方差矩阵Q。
好了,这一章的内容就到这里。记住,Allan方差分析不是一次性工作——随着IMU老化或温度变化,噪声参数会变。我建议每半年重新做一次分析,更新滤波器参数。
公众号:蓝海资料掘金营,微信deep3321