[应用方案] 卡尔曼(Kalman)滤波算法原理、C语言实现

[复制链接]
109|46
jonas222 发表于 2025-12-30 14:34 | 显示全部楼层 |阅读模式
卡尔曼滤波一、滤波效果展示
  ①. X k-1|k-1 为k-1时刻的输出。   ②. 当X为一维数据时,Fk的值是1。   ③. 一维数据下(uk=0时):系统预测值 = 系统状态变量k-1时刻的最优值。
2. 预测协方差方程(1)目的  根据 k-1时刻的系统协方差 预测 k时刻系统协方差。
(2)方程





(3)备注  ①. 当X为一维数据时,Fk的值是1。
3. 卡尔曼增益方程(1)目的  根据(k时刻) 协方差矩阵的预测值 计算 卡尔曼增益。
(2)方程





(3)备注  ①. 当 Pk|k-1 为一个一维矩阵时,Hk 是1。
4. 跟新最优值方程(卡尔曼滤波的输出)(1)目的  根据 状态变量的预测值 和 系统测量值 计算出 k时刻状态变量的最优值。
(2)方程





(3)备注  ①. 当 Pk|k-1 为一个一维矩阵时,Hk 是1。
5. 更新协方差方程(1)目的  为了求 k时刻的协方差矩阵。(为得到k+1时刻的卡尔曼输出值做准备)
(2)方程





(3)备注  ①. 当 Pk|k-1 为一个一维矩阵时,Hk 是1。
四、C 程序代码实现1. 参数列表





2. 代码实现(一维数据滤波) 实际参数是参照别人已经选好的参数,不过也可以自己改变参数,去观察波形的效果,体会每个参数对于滤波效果的影响,这里不详细介绍。





  1. //1. 结构体类型定义
  2. typedef struct
  3. {
  4.    
  5.     float LastP;//上次估算协方差 初始化值为0.02
  6.     float Now_P;//当前估算协方差 初始化值为0
  7.     float out;//卡尔曼滤波器输出 初始化值为0
  8.     float Kg;//卡尔曼增益 初始化值为0
  9.     float Q;//过程噪声协方差 初始化值为0.001
  10.     float R;//观测噪声协方差 初始化值为0.543
  11. }KFP;//Kalman Filter parameter

  12. //2. 以高度为例 定义卡尔曼结构体并初始化参数
  13. KFP KFP_height={
  14.    0.02,0,0,0,0.001,0.543};

  15. /** *卡尔曼滤波器 *@param KFP *kfp 卡尔曼结构体参数 * float input 需要滤波的参数的测量值(即传感器的采集值) *[url=/u/return]@return[/url] 滤波后的参数(最优值) */
  16. float kalmanFilter(KFP *kfp,float input)
  17. {
  18.    
  19.      //预测协方差方程:k时刻系统估算协方差 = k-1时刻的系统协方差 + 过程噪声协方差
  20.      kfp->Now_P = kfp->LastP + kfp->Q;
  21.      //卡尔曼增益方程:卡尔曼增益 = k时刻系统估算协方差 / (k时刻系统估算协方差 + 观测噪声协方差)
  22.      kfp->Kg = kfp->Now_P / (kfp->NOw_P + kfp->R);
  23.      //更新最优值方程:k时刻状态变量的最优值 = 状态变量的预测值 + 卡尔曼增益 * (测量值 - 状态变量的预测值)
  24.      kfp->out = kfp->out + kfp->Kg * (input -kfp->out);//因为这一次的预测值就是上一次的输出值
  25.      //更新协方差方程: 本次的系统协方差付给 kfp->LastP 威下一次运算准备。
  26.      kfp->LastP = (1-kfp->Kg) * kfp->Now_P;
  27.      return kfp->out;
  28. }

  29. /** *调用卡尔曼滤波器 实践 */
  30. int height;
  31. int kalman_height=0;
  32. kalman_height = kalmanFilter(&KFP_height,(float)height);








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
pixhw 发表于 2026-1-4 22:41 | 显示全部楼层
系统必须满足“线性 + 高斯白噪声”假设
cashrwood 发表于 2026-1-6 12:03 | 显示全部楼层
卡尔曼滤波计算开销远大于互补滤波
plsbackup 发表于 2026-1-6 12:48 | 显示全部楼层
标准卡尔曼滤波仅适用于线性系统。对于非线性系统,需采用扩展卡尔曼滤波或无迹卡尔曼滤波。EKF通过线性化近似非线性函数,可能引入较大误差;UKF通过采样点近似非线性分布,精度更高但计算量更大。
 楼主| jonas222 发表于 2026-1-6 15:05 | 显示全部楼层
滤波器的采样率需与系统动态和传感器采样率匹配。若采样率过低,滤波器将无法及时跟踪系统变化;若过高,可能导致计算资源浪费。
houjiakai 发表于 2026-1-7 17:02 | 显示全部楼层
卡尔曼滤波的核心在于平衡“信任模型”和“信任测量值”。
jtracy3 发表于 2026-1-7 19:26 | 显示全部楼层
如果只是简单平滑速度,且计算资源紧张,试试一阶低通滤波或者Alpha-Beta 滤波器,效果可能差不多,但代码量极小且不易发散。
暖茶轻语 发表于 2026-1-8 08:24 | 显示全部楼层
感谢分享卡尔曼滤波的实现细节
复古留声机 发表于 2026-1-8 14:46 | 显示全部楼层
代码实现部分很详细,对于初学者来说是个很好的学习材料
backlugin 发表于 2026-1-8 14:50 | 显示全部楼层
根据系统特性建立精确的数学模型,或采用自适应卡尔曼滤波动态调整模型参数。
1988020566 发表于 2026-1-8 16:28 | 显示全部楼层
对于 IMU 姿态融合,Mahony/Madgwick 互补滤波在 MCU 上更高效
everyrobin 发表于 2026-1-8 17:38 | 显示全部楼层
Q:反映模型不确定性,过大会导致跟踪滞后,过小则无法适应突发扰动;
R:体现传感器精度,过大会使滤波器过度依赖预测值,过小则放大测量误差;
updownq 发表于 2026-1-10 17:15 | 显示全部楼层
初始状态协方差 P₀ 反映你对初始状态的不确定程度。
timfordlare 发表于 2026-1-13 17:35 | 显示全部楼层
过程噪声代表系统动态的不确定性。若Q设置过小,滤波器将过度依赖模型预测,忽略实际动态变化;若设置过大,滤波器将过度依赖观测数据,导致估计波动。
lzmm 发表于 2026-1-13 17:54 | 显示全部楼层
使用MATLAB/Simulink、Python等工具搭建仿真平台,结合真实数据校准仿真模型。
bartonalfred 发表于 2026-1-13 17:55 | 显示全部楼层
强烈推荐使用 ARM CMSIS-DSP 库,它已经帮您优化了汇编级的矩阵运算,比自己写 C 语言循环快几十倍。
chenci2013 发表于 2026-1-17 12:39 | 显示全部楼层
卡尔曼滤波有时候会“发疯”,表现为滤波值与真实值越差越远。
burgessmaggie 发表于 2026-1-17 13:39 | 显示全部楼层
直接用于非线性系统→ 必须用 EKF 或 UKF
gygp 发表于 2026-1-17 15:53 | 显示全部楼层
观测模型描述了如何从系统状态生成观测值。若模型与实际传感器特性不符,滤波器将无法正确融合观测数据。
timfordlare 发表于 2026-1-17 17:55 | 显示全部楼层
过程噪声代表系统动态的不确定性。若Q设置过小,滤波器将过度依赖模型预测,忽略实际动态变化;若设置过大,滤波器将过度依赖观测数据,导致估计波动。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

51

主题

1833

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0