当前位置:   article > 正文

卡尔曼滤波算法--C语言实现_卡尔曼滤波c语言实现

卡尔曼滤波c语言实现
  1. /**
  2. ******************************************************************************
  3. * @brief 卡尔曼滤波器 函数
  4. * @param inData - 输入值
  5. * @return 滤波后的值
  6. * @note r值固定,q值越大,代表越信任测量值,q值无穷大,代表只用测量值。
  7. * q值越小,代表越信任模型预测值,q值为0,代表只用模型预测值。
  8. * q:过程噪声,q增大,动态响应变快,收敛稳定性变坏;反之。控制误差
  9. * r:测量噪声,r增大,动态响应变慢,收敛稳定性变好;反之。控制响应速度
  10. ******************************************************************************
  11. */
  12. unsigned long KalmanFilter(unsigned long inData)
  13. {
  14. static float xdata kalman = 0; //上次卡尔曼值(估计出的最优值)
  15. static float xdata p = 10;
  16. float xdata q = 0.001; //q:过程噪声
  17. float xdata r = 0.001; //r:测量噪声
  18. float xdata kg = 0; //kg:卡尔曼增益
  19. p += q;
  20. kg = p / ( p + r ); //计算卡尔曼增益
  21. kalman = kalman + (kg * (inData - kalman)); //计算本次滤波估计值
  22. p = (1 - kg) * p; //更新测量方差
  23. return (unsigned long)kalman; //返回估计值
  24. }

实际应用

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "math.h"
  4. double frand()
  5. {
  6. return 2 * ((rand() / (double)RAND_MAX) - 0.5);//随机噪声
  7. }
  8. void main()
  9. {
  10. float x_last = 0;
  11. float p_last = 0.02;
  12. float Q = 0.018;
  13. float R = 0.542;
  14. float kg;
  15. float x_mid;
  16. float x_now;
  17. float p_mid;
  18. float p_now;
  19. float z_real = 0.56;
  20. float z_measure;
  21. float summerror_kalman = 0;
  22. float summerror_measure = 0;
  23. int i;
  24. x_last = z_real + frand()*0.03;
  25. x_mid = x_last;
  26. for (i = 0; i < 20; i++)
  27. {
  28. x_mid = x_last;
  29. p_mid = p_last + Q;
  30. kg = p_mid / (p_mid + R);
  31. z_measure = z_real + frand()*0.03;//测量值
  32. x_now = x_mid + kg * (z_measure - x_mid);//估计出的最有值
  33. p_now = (1 - kg)*p_mid;//最优值对应的协方差
  34. printf("Real position:%6.3f\n", z_real);
  35. printf("Measure position:%6.3f [diff:%.3f]\n", z_measure, fabs(z_real - z_measure));
  36. printf("Kalman position: %6.3f [diff:%.3f]\n", x_now, fabs(z_real - x_now));
  37. printf("\n\n");
  38. summerror_kalman += fabs(z_real - x_now);
  39. summerror_measure += fabs(z_real - z_measure);
  40. p_last = p_now;
  41. x_last = x_now;
  42. }
  43. printf("总体测量误差 :%f\n", summerror_measure);
  44. printf("总体卡尔曼滤波误差:%f\n", summerror_kalman);
  45. printf("卡尔曼误差所占比例:%d%%\n", 100 - (int)((summerror_kalman / summerror_measure) * 100));
  46. getchar();
  47. }

输出结果:

  1. Real position: 0.560
  2. Measure position: 0.564 [diff:0.004]
  3. Kalman position: 0.532 [diff:0.028]
  4. Real position: 0.560
  5. Measure position: 0.542 [diff:0.018]
  6. Kalman position: 0.533 [diff:0.027]
  7. Real position: 0.560
  8. Measure position: 0.579 [diff:0.019]
  9. Kalman position: 0.538 [diff:0.022]
  10. Real position: 0.560
  11. Measure position: 0.565 [diff:0.005]
  12. Kalman position: 0.541 [diff:0.019]
  13. Real position: 0.560
  14. Measure position: 0.559 [diff:0.001]
  15. Kalman position: 0.544 [diff:0.016]
  16. Real position: 0.560
  17. Measure position: 0.551 [diff:0.009]
  18. Kalman position: 0.545 [diff:0.015]
  19. Real position: 0.560
  20. Measure position: 0.584 [diff:0.024]
  21. Kalman position: 0.551 [diff:0.009]
  22. Real position: 0.560
  23. Measure position: 0.579 [diff:0.019]
  24. Kalman position: 0.555 [diff:0.005]
  25. Real position: 0.560
  26. Measure position: 0.575 [diff:0.015]
  27. Kalman position: 0.558 [diff:0.002]
  28. Real position: 0.560
  29. Measure position: 0.540 [diff:0.020]
  30. Kalman position: 0.555 [diff:0.005]
  31. Real position: 0.560
  32. Measure position: 0.582 [diff:0.022]
  33. Kalman position: 0.560 [diff:0.000]
  34. Real position: 0.560
  35. Measure position: 0.573 [diff:0.013]
  36. Kalman position: 0.562 [diff:0.002]
  37. Real position: 0.560
  38. Measure position: 0.561 [diff:0.001]
  39. Kalman position: 0.562 [diff:0.002]
  40. Real position: 0.560
  41. Measure position: 0.548 [diff:0.012]
  42. Kalman position: 0.559 [diff:0.001]
  43. Real position: 0.560
  44. Measure position: 0.531 [diff:0.029]
  45. Kalman position: 0.555 [diff:0.005]
  46. Real position: 0.560
  47. Measure position: 0.535 [diff:0.025]
  48. Kalman position: 0.552 [diff:0.008]
  49. Real position: 0.560
  50. Measure position: 0.552 [diff:0.008]
  51. Kalman position: 0.552 [diff:0.008]
  52. Real position: 0.560
  53. Measure position: 0.539 [diff:0.021]
  54. Kalman position: 0.549 [diff:0.011]
  55. Real position: 0.560
  56. Measure position: 0.540 [diff:0.020]
  57. Kalman position: 0.548 [diff:0.012]
  58. Real position: 0.560
  59. Measure position: 0.589 [diff:0.029]
  60. Kalman position: 0.555 [diff:0.005]
  61. 总体测量误差 :0.312517
  62. 总体卡尔曼滤波误差:0.200942
  63. 卡尔曼误差所占比例:36%
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/786312
推荐阅读
相关标签
  

闽ICP备14008679号