
目录
[1. 什么是卡尔曼滤波](#1. 什么是卡尔曼滤波)
[2. 解决的核心痛点](#2. 解决的核心痛点)
[3. 典型落地场景](#3. 典型落地场景)
前言:
在电机转速、姿态传感器、动态压力等快速变化且带噪声 的采集场景中,传统滤波要么滞后严重,要么平滑不足。卡尔曼滤波通过预测 + 更新闭环迭代,在不牺牲响应速度的前提下实现最优降噪,是无人机、机器人、伺服控制、高端仪表的核心算法。
本篇实现轻量化定点卡尔曼,无矩阵、无浮点、可直接在低端 MCU 运行。
一、核心本质与应用场景
1. 什么是卡尔曼滤波
卡尔曼滤波是最优递归滤波:
- 先根据上一状态预测当前值
- 再用实际采样修正预测值
- 自动计算卡尔曼增益,动态平衡 "信模型" 还是 "信测量"
核心特性
- 动态响应极快,几乎无滞后
- 平滑效果强,抑制高斯噪声
- 单帧运算,无需缓存窗口
- 可自适应噪声环境
- 极小 RAM 占用
2. 解决的核心痛点
- 传统滤波滞后大,跟不上动态变化
- 平均 / 中值滤波无法处理高速变化信号
- 传感器噪声随机,固定算法效果差
- 需要兼顾实时性与平滑度的高端场景
3. 典型落地场景
- 陀螺仪 / 加速度计姿态融合 电机转速
- 电流动态采集 无人机
- 平衡车姿态估计 动态压力
- 流量实时监测 高精度伺服闭环反馈滤波
二、核心实现原理
-
预测阶段 根据上一时刻结果推算当前值
-
卡尔曼增益计算 动态决定信任预测还是信任测量
-
更新阶段 融合预测值与采样值,得到最优输出
-
误差协方差迭代 持续估计噪声水平,自适应调整滤波强度
全部使用定点整数运算,无浮点、无除法瓶颈。
三、工业级设计规范
- 结构体封装状态、协方差、噪声参数
- 多实例独立,多路传感器互不干扰
- 完整空指针、参数校验
- 纯静态内存,无堆分配
- 可在线动态调整噪声参数
四、完整可复用源码
filter_kalman.h
#ifndef FILTER_KALMAN_H
#define FILTER_KALMAN_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int32_t x; // 估计值
int32_t p; // 估计误差协方差
int32_t q; // 过程噪声
int32_t r; // 测量噪声
} filter_kalman_t;
void filter_kalman_init(filter_kalman_t *k, int32_t init_val, int32_t q, int32_t r);
int32_t filter_kalman_calc(filter_kalman_t *k, int32_t meas);
#ifdef __cplusplus
}
#endif
#endif
filter_kalman.c
#include "filter_kalman.h"
#define KALMAN_SCALE 1024
void filter_kalman_init(filter_kalman_t *k, int32_t init_val, int32_t q, int32_t r) {
if (!k) return;
k->x = init_val * KALMAN_SCALE;
k->p = 32 * KALMAN_SCALE;
k->q = q;
k->r = r * KALMAN_SCALE;
}
int32_t filter_kalman_calc(filter_kalman_t *k, int32_t meas) {
if (!k) return meas;
int32_t m = meas * KALMAN_SCALE;
// 预测
k->p += k->q;
// 卡尔曼增益
int32_t gain = (k->p * KALMAN_SCALE) / (k->p + k->r);
// 更新
k->x += gain * (m - k->x) / KALMAN_SCALE;
k->p = (KALMAN_SCALE - gain) * k->p / KALMAN_SCALE;
return k->x / KALMAN_SCALE;
}
五、实战演示
#include <stdio.h>
#include "filter_kalman.h"
int main(void) {
filter_kalman_t k;
filter_kalman_init(&k, 1000, 5, 100);
int32_t data[] = {1000, 1002, 998, 1050, 999, 1001, 997, 1003, 1100, 1000};
for (int i = 0; i < 10; i++) {
int32_t res = filter_kalman_calc(&k, data[i]);
printf("raw:%5d kalman:%5d\n", data[i], res);
}
return 0;
}
六、进阶优化方向
- 带加速度 / 变速度模型的自适应卡尔曼
- 互补滤波 + 卡尔曼级联
- 动态调整 Q/R 噪声参数
- 多传感器融合扩展(加速度 + 陀螺仪)
七、面试考点与易错坑点
面试问答
Q1:卡尔曼滤波为什么适合动态信号?
答:它是预测 + 修正闭环,不需要窗口缓存,响应极快,同时能最优降噪。
Q2:Q 和 R 分别代表什么?
答:Q 是过程噪声,Q 越大越信任测量;R 是测量噪声,R 越大越信任预测。
Q3:卡尔曼和一阶滞后滤波区别?
答:一阶滞后系数固定;卡尔曼增益动态自适应,效果更智能。
Q4:为什么要用定点运算?
答:低端 MCU 无 FPU,浮点慢且精度差,定点运算更快更稳定。
Q5:卡尔曼滤波缺点是什么?
答:对非高斯噪声效果一般;强尖峰干扰前需加限幅。
Q6:工程上如何调 Q、R?
答:噪声大则 R 调大;变化快则 Q 调大。
常见坑点
- Q/R 设置极端导致滤波失效
- 未做定点缩放,数值溢出
- 多通道共用实例导致状态错乱
- 初始值设置不合理导致启动漂移
- 直接用浮点版本导致 MCU 卡顿
总结
卡尔曼滤波是嵌入式高端动态降噪天花板算法,完美兼顾响应速度与平滑度,是传感器融合、电机控制、姿态检测的必备组件。本篇轻量化定点实现无门槛移植,工业级鲁棒稳定,可直接用于量产项目。
创作不易,如果对你有帮助,欢迎点赞、收藏、转发。