2、传感器建模:加速度计与陀螺仪的数学模型、Allan方差分析基础、随机游走与偏置不稳定性
好,咱们进入正题。传感器建模这事儿,说白了就是给加速度计和陀螺仪画个「像」——你得知道它怎么工作,它有哪些臭毛病,然后才能想办法治它。我当年刚入行时,总觉得建模是理论派干的事,直到有一次做无人机飞控,零漂把姿态算偏了十几度,飞机差点炸了……嗯,从那以后我再也不敢跳过建模这一步了。
2.1 加速度计的数学模型
加速度计测的是什么?不是速度,是比力。这个比力包括运动加速度和重力加速度。理想情况下,它的输出很简单:
a_meas = a_true + g + b_a + n_a
其中:
- a_true —— 真实的运动加速度
- g —— 重力加速度(9.8 m/s²)
- b_a —— 偏置(零偏),单位 m/s²
- n_a —— 测量噪声,通常建模为高斯白噪声
你想想看,如果偏置 b_a 是 0.01 m/s²,积分 100 秒后速度误差就是 1 m/s,位置误差更是平方增长。这就是为什么零漂抑制这么重要。
实际模型更复杂一些:
a_meas = S * (a_true + g) + b_a + n_a + 非线性项 + 温度漂移
其中 S 是尺度因子矩阵,包含交叉耦合。不过咱们做零漂抑制时,重点盯着 b_a 和 n_a 就行。
2.2 陀螺仪的数学模型
陀螺仪测的是角速度。模型和加速度计很像:
ω_meas = ω_true + b_g + n_g
- ω_true —— 真实角速度
- b_g —— 陀螺偏置,单位 °/s 或 rad/s
- n_g —— 角度随机游走噪声
我个人习惯把陀螺仪偏置看作「慢性毒药」。加速度计偏置影响位置,但陀螺仪偏置影响姿态,姿态一错,整个导航就全完了。我在做车载导航时遇到过,陀螺偏置只漂了 0.1°/s,10 分钟后航向偏了 60 度,车直接导航到对面车道去了……
避坑指南: 我曾经以为 MEMS 陀螺仪静态时偏置是常数,后来发现温度一变,偏置能跳一个数量级。所以建模时一定要把温度补偿考虑进去。
2.3 Allan方差分析基础
Allan 方差是什么?说白了就是一把「尺子」,用来量传感器的噪声成分。它能把白噪声、随机游走、偏置不稳定性这些成分一一拆开。
计算步骤很简单:
- 采集一段静态数据(比如 2 小时,100 Hz)
- 按不同时间长度 τ 分段
- 计算每段的均值,再求方差
- 画出 log(τ) - log(Allan 标准差) 曲线
这条曲线长什么样?我画个图给你看:
这张图怎么看?我教你个口诀:
- 左段斜率 -1/2 —— 角度随机游走(白噪声积分的结果)
- 中间平坦区 —— 偏置不稳定性(这是零漂抑制的重点!)
- 右段斜率 +1/2 —— 速率随机游走(低频噪声)
实战要点: 平坦区的最低点对应的 τ 值,就是传感器的最佳积分时间。比如 τ = 100 s 时 Allan 方差最小,说明积分 100 秒时噪声最低。我一般用这个值来设计滤波器的截止频率。
2.4 随机游走与偏置不稳定性
这两个概念容易搞混,我分开讲。
角度随机游走(ARW): 陀螺仪白噪声积分后,角度误差会像醉汉走路一样随机漂移。单位是 °/√h。数值越小越好,比如 0.01 °/√h 算高端 MEMS 了。
偏置不稳定性(BI): 这是偏置在长时间尺度上的缓慢波动。单位是 °/h。我见过一些低端传感器,BI 能到 10 °/h,静止 1 小时偏置漂了 10 度,这还怎么用?
为什么会有这些噪声?说白了就是物理限制:
- 热噪声 → 白噪声
- 1/f 噪声 → 偏置不稳定性
- 温度梯度 → 速率随机游走
注意: 很多人以为 Allan 方差分析一次就够了。我踩过这个坑——同一颗芯片,不同温度下的 Allan 曲线完全不一样。建议至少做 3 组温度点(低温、常温、高温)的测试。
2.5 实战:用 Python 做 Allan 方差分析
光说不练假把式。我给你一段代码,可以直接跑:
import numpy as np
import matplotlib.pyplot as plt
def allan_variance(data, fs):
"""
计算 Allan 方差
data: 传感器静态数据 (1D array)
fs: 采样率 (Hz)
"""
n = len(data)
max_m = int(np.log2(n)) - 1
tau = []
adev = []
for m in range(1, max_m):
# 按 2^m 个点分组
cluster_size = 2**m
num_clusters = n // cluster_size
# 计算每组的均值
clusters = data[:num_clusters * cluster_size].reshape(-1, cluster_size)
means = np.mean(clusters, axis=1)
# Allan 方差
allan_var = 0.5 * np.mean((means[1:] - means[:-1])**2)
allan_std = np.sqrt(allan_var)
tau.append(cluster_size / fs)
adev.append(allan_std)
return np.array(tau), np.array(adev)
# 模拟陀螺仪数据(含白噪声 + 偏置不稳定性)
fs = 100 # 100 Hz
t = np.arange(0, 7200, 1/fs) # 2 小时
white_noise = np.random.normal(0, 0.01, len(t)) # 白噪声
bias_drift = np.cumsum(np.random.normal(0, 1e-6, len(t))) # 偏置漂移
data = white_noise + bias_drift
# 计算 Allan 方差
tau, adev = allan_variance(data, fs)
# 画图
plt.figure(figsize=(10, 6))
plt.loglog(tau, adev, 'b-', linewidth=2)
plt.xlabel('τ (s)')
plt.ylabel('Allan 标准差 (°/s)')
plt.grid(True, which='both', alpha=0.3)
plt.title('Allan 方差分析结果')
plt.show()
我的经验: 实际数据采集时,记得先让传感器预热 10 分钟。我试过冷启动直接采,前 20 分钟的数据全是温度漂移,Allan 曲线根本没法看。
2.6 小结:建模的意义
传感器建模不是纸上谈兵。它告诉你三件事:
- 偏置有多大 —— 决定要不要做零漂抑制
- 噪声结构什么样 —— 决定用什么滤波器
- 最佳积分时间 —— 决定系统更新频率
我见过太多人上来就调滤波器参数,调了半天效果不好。其实根源在于没搞清楚传感器本身的噪声特性。先做 Allan 方差分析,再建模,最后设计滤波器——这个顺序不能乱。
嗯,这一章就到这里。建模是基础,下一章咱们聊怎么用这些模型来设计零漂抑制算法。
公众号:蓝海资料掘金营,微信deep3321