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;

但硬件里怎么做?我建议这样拆:

  1. 乘法器 + 加法器:两个系数0.98和0.02,用定点数表示(比如Q15格式)。乘法器用组合逻辑实现,一拍搞定。
  2. 累加器:角度值需要不断累加陀螺仪的角速度积分。这里用寄存器+加法器构成累加器,每个时钟周期更新一次。
  3. 流水线结构:把计算拆成三级——第一级算gyro*dt,第二级算加权和,第三级输出。这样吞吐率能到每周期一个结果。
避坑指南: 我曾经在互补滤波的系数选择上吃过亏。0.98和0.02看起来简单,但定点化后精度损失会导致角度漂移。建议用Q1.15格式,保留15位小数精度。另外,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矩阵求逆用高斯消元法,硬件里用状态机控制,大约需要几十个周期。但注意,卡尔曼增益更新不需要每个采样点都做,可以隔几个点更新一次。
关键优化: 我在实际项目中,把卡尔曼增益的计算周期从每采样点一次改成了每10个采样点一次。角度精度只下降了0.3度,但硬件面积省了40%。这叫「工程上的取舍」。

3.3.3 定点化与位宽选择

卡尔曼滤波对数值精度敏感。我建议:

变量 位宽 小数位 说明
状态量(角度、偏置) 24位 Q12 角度范围±180°,精度0.04°
协方差矩阵 32位 Q16 数值范围大,需要更多整数位
卡尔曼增益 16位 Q8 增益范围0~1,8位小数够用
注意: 协方差矩阵的数值会随时间增长,如果不做处理,可能溢出。我习惯在每次更新后对协方差矩阵做一次「数值归一化」,把对角线元素限制在合理范围内。这个操作在硬件里就是一个比较器+移位器的事。

3.4 两种滤波的硬件对比

互补滤波和卡尔曼滤波,各有各的适用场景。我画了张图,帮你快速理解:

互补滤波 vs 卡尔曼滤波 硬件实现对比 互补滤波 卡尔曼滤波 硬件资源: • 2个乘法器 + 2个加法器 • 3个寄存器(角度、偏置、dt) • 无状态机,纯组合逻辑 延迟: • 2~3个时钟周期 精度: • 中等,适合低动态场景 面积: • 约500~1000门 硬件资源: • 36个乘法器 + 36个累加器 • 6x6矩阵寄存器组 • 状态机控制(约20个状态) 延迟: • 50~100个时钟周期 精度: • 高,适合高动态场景 面积: • 约5000~10000门 选择建议:低功耗场景用互补滤波,高精度场景用卡尔曼滤波

3.5 我的选择建议

说了这么多,到底用哪个?我个人的经验是:

  • 手环、计步器:互补滤波就够了。硬件面积小,功耗低,精度够用。
  • 运动手表、专业轨迹记录:上卡尔曼滤波。虽然面积大,但精度和鲁棒性更好。
  • 混合方案:我最近在做的一个项目里,用了「互补滤波做粗估计 + 卡尔曼滤波做细校正」的两级架构。互补滤波跑在200Hz,卡尔曼滤波每10个点跑一次。效果不错,面积也控制住了。
一个小技巧: 不管用哪种滤波,记得在硬件里加一个「数据有效性检查」模块。我曾经遇到过传感器瞬间跳变到满量程的情况,滤波算法直接发散。加一个简单的限幅器(比较器+选择器),就能避免这种问题。

好了,滤波算法的硬件化思路就聊到这儿。下一节咱们会讲特征提取的硬件加速,到时候会用到今天讲的滤波输出作为输入。嗯,先把基础打牢,后面才能跑得快。

专注资料整理