3. 数据预处理:传感器数据滤波算法(卡尔曼滤波、互补滤波)的硬件化思路
做智能穿戴芯片,最头疼的是什么?
我个人的经验是——传感器数据太「脏」了。加速度计随便一晃,输出值能跳得像心电图。陀螺仪温漂起来,角度能自己跑偏十几度。你想想看,如果原始数据直接喂给轨迹算法,那算出来的运动轨迹,基本就是布朗运动。
所以,数据预处理这步,绕不开。今天咱们就聊聊两种最常用的滤波算法——卡尔曼滤波和互补滤波,以及它们怎么在硬件里落地。
3.1 为什么需要硬件化滤波?
很多同学觉得,滤波嘛,MCU里跑个软件就完了。嗯,这话在低采样率场景下没错。但智能穿戴不一样——
- IMU采样率通常要200Hz以上,甚至1kHz
- 运动轨迹算法本身就要吃大量算力
- MCU主频就那么点,还要跑RTOS、蓝牙协议栈
我在做第一代运动手表芯片时,就踩过这个坑。软件卡尔曼滤波跑在Cortex-M4上,200Hz采样就把CPU占到了40%。剩下的活儿根本干不动。后来老老实实把滤波逻辑搬到了硬件加速器里,CPU占用直接降到5%以下。
3.2 互补滤波的硬件化
互补滤波,说白了就是「信谁多一点」。加速度计低频准但高频抖,陀螺仪高频准但低频漂。互补滤波就是把两者的优势拼起来。
软件里写起来很简单:
// 互补滤波伪代码
angle = 0.98 * (angle + gyro * dt) + 0.02 * accel_angle;
但硬件里怎么做?我建议这样拆:
- 乘法器 + 加法器:两个系数0.98和0.02,用定点数表示(比如Q15格式)。乘法器用组合逻辑实现,一拍搞定。
- 累加器:角度值需要不断累加陀螺仪的角速度积分。这里用寄存器+加法器构成累加器,每个时钟周期更新一次。
- 流水线结构:把计算拆成三级——第一级算gyro*dt,第二级算加权和,第三级输出。这样吞吐率能到每周期一个结果。
3.3 卡尔曼滤波的硬件化
卡尔曼滤波,很多教材讲得玄乎。其实核心就五个公式:预测、更新、算增益。我当年啃了三天才搞明白,后来发现硬件实现反而比软件更直观——因为硬件天然就是「状态机 + 矩阵运算」的架构。
硬件化卡尔曼滤波,我建议分三步走:
3.3.1 简化模型
别一上来就搞6轴9轴的全状态卡尔曼。对于运动轨迹,我们通常只需要3轴角度+3轴角速度偏置,共6个状态量。状态转移矩阵F和观测矩阵H都是稀疏的,很多元素是0或1。
举个例子,角度预测公式:
θ(k|k-1) = θ(k-1|k-1) + (ω - bias) * dt
这其实就是个加法器+乘法器的事。
3.3.2 矩阵运算硬件化
卡尔曼滤波里最耗时的就是矩阵乘法和求逆。但6x6矩阵的乘法,用硬件做其实很快:
- 乘法器阵列:6x6矩阵乘法需要36个乘法器,每个乘法器配一个累加器。全部并行计算,一个时钟周期就能出结果。
- 矩阵求逆:6x6矩阵求逆用高斯消元法,硬件里用状态机控制,大约需要几十个周期。但注意,卡尔曼增益更新不需要每个采样点都做,可以隔几个点更新一次。
3.3.3 定点化与位宽选择
卡尔曼滤波对数值精度敏感。我建议:
| 变量 | 位宽 | 小数位 | 说明 |
|---|---|---|---|
| 状态量(角度、偏置) | 24位 | Q12 | 角度范围±180°,精度0.04° |
| 协方差矩阵 | 32位 | Q16 | 数值范围大,需要更多整数位 |
| 卡尔曼增益 | 16位 | Q8 | 增益范围0~1,8位小数够用 |
3.4 两种滤波的硬件对比
互补滤波和卡尔曼滤波,各有各的适用场景。我画了张图,帮你快速理解:
3.5 我的选择建议
说了这么多,到底用哪个?我个人的经验是:
- 手环、计步器:互补滤波就够了。硬件面积小,功耗低,精度够用。
- 运动手表、专业轨迹记录:上卡尔曼滤波。虽然面积大,但精度和鲁棒性更好。
- 混合方案:我最近在做的一个项目里,用了「互补滤波做粗估计 + 卡尔曼滤波做细校正」的两级架构。互补滤波跑在200Hz,卡尔曼滤波每10个点跑一次。效果不错,面积也控制住了。
好了,滤波算法的硬件化思路就聊到这儿。下一节咱们会讲特征提取的硬件加速,到时候会用到今天讲的滤波输出作为输入。嗯,先把基础打牢,后面才能跑得快。