搜索
bottom↓
回复: 1

[求助]Matlab仿真的卡尔曼滤波器工作不正常。

[复制链接]

出0入0汤圆

发表于 2014-11-18 22:05:50 | 显示全部楼层 |阅读模式
下面是我用Matlab写的加速度计和陀螺仪融合的卡尔曼滤波器仿真代码,是根据这篇论文写的,但是出来的曲线跟陀螺仪的计算角度曲线是重合,请问一下是什么问题?

  1. close all;
  2. clear all;
  3. fid = fopen('./2014-11-11_03_13_25.dat', 'rb');
  4. fseek(fid,0,'eof');
  5. fsize = ftell(fid);
  6. fseek(fid,0,'bof');
  7. [CONFIG, CONFIG_SIZE] = fread(fid, 29, 'uchar');
  8. %卡尔曼滤波相关变量初始化
  9. T = 0.001;
  10. Q = [0.01 0;0 0.005];
  11. delta = 0;
  12. % r_k = 0.05;
  13. X_0 = [0;0];
  14. A = [1 -T;0 1];
  15. B = [(1-delta)*T;delta];
  16. C = [1 0];  %系统输出方程中的输出矩阵
  17. % P_k_1 = 0;
  18. R_k = [0.056];
  19. X_k_k = X_0;
  20. I = eye(2);
  21. P_k_k = [0.005 0.005;0.005 0.005];
  22. %获取文件数据
  23. data_size = int32((fsize -29)/12);
  24. Accel_factor = 4096.0;
  25. Gyro_factor = 65.5;
  26. accel_x = zeros(1,data_size);
  27. accel_y = zeros(1,data_size);
  28. accel_z = zeros(1,data_size);
  29. gyro_x = zeros(1,data_size);
  30. gyro_y = zeros(1,data_size);
  31. gyro_z = zeros(1,data_size);
  32. Aax = zeros(1,data_size);
  33. Aay = zeros(1,data_size);
  34. Aaz = zeros(1,data_size);
  35. Agx = zeros(1,data_size);
  36. Agy = zeros(1,data_size);
  37. Agz = zeros(1,data_size);
  38. Af_k_1 = zeros(1,data_size);
  39. Af_k_2 = zeros(1,data_size);
  40. for i = 1:1:data_size
  41.         [Accel_X, Accel_X_Size] = fread(fid, 2, 'uchar');
  42.         [Accel_Y, Accel_Y_Size] = fread(fid, 2, 'uchar');
  43.         [Accel_Z, Accel_Z_Size] = fread(fid, 2, 'uchar');
  44.         [Gyro_X, Gyro_X_Size] = fread(fid, 2, 'uchar');
  45.         [Gyro_Y, Gyro_Y_Size] = fread(fid, 2, 'uchar');
  46.         [Gyro_Z, Gyro_Z_Size] = fread(fid, 2, 'uchar');
  47.         accel_x(i) = uint16Toint16(Accel_X(1) * 256 + Accel_X(2)) / Accel_factor;
  48.         accel_y(i) = uint16Toint16(Accel_Y(1) * 256 + Accel_Y(2)) / Accel_factor;
  49.         accel_z(i) = uint16Toint16(Accel_Z(1) * 256 + Accel_Z(2)) / Accel_factor;
  50.         gyro_x(i)  =  uint16Toint16(Gyro_X(1)  * 256 + Gyro_X(2) ) / Gyro_factor ;
  51.         gyro_y(i)  =  uint16Toint16(Gyro_Y(1)  * 256 + Gyro_Y(2) ) / Gyro_factor ;
  52.         gyro_z(i)  =  uint16Toint16(Gyro_Z(1)  * 256 + Gyro_Z(2) ) / Gyro_factor ;
  53. end
  54. %平滑滤波
  55. % accel_x=smooth(accel_x,50, 'moving');
  56. % accel_y=smooth(accel_y,50, 'moving');
  57. % accel_z=smooth(accel_z,50, 'moving');
  58. % gyro_x =smooth(gyro_x, 50, 'moving');
  59. % gyro_y =smooth(gyro_y, 50, 'moving');
  60. % gyro_z =smooth(gyro_z, 50, 'moving');

  61. for i=1:1:data_size
  62.         if(i==1)
  63.                 %加速度计得到的角度
  64.                 Aax(i) = -atan2(accel_x(i), accel_z(i));
  65.                 Aay(i) = atan2(accel_y(i), accel_z(i));
  66.                 Aaz(i) = atan2(accel_x(i), accel_y(i));
  67.                 %陀螺仪得到的角度
  68.                 Agx(i) = Aay(1);
  69.                 Agy(i) = Aax(1);
  70.                 Agz(i) = Aaz(1);
  71.         else
  72.                 %加速度计得到的角度
  73.                 Aax(i) = -atan2(accel_x(i), accel_z(i));
  74.                 Aay(i) = atan2(accel_y(i), accel_z(i));
  75.                 Aaz(i) = atan2(accel_x(i), accel_y(i));
  76.                 %陀螺仪得到的角度
  77.                 Agx(i) = Agx(i-1) + gyro_x(i) * T * pi / 180.0;
  78.                 Agy(i) = Agy(i-1) + gyro_y(i) * T * pi / 180.0;
  79.                 Agz(i) = Agz(i-1) + gyro_z(i) * T * pi / 180.0;
  80.                
  81.         end
  82.         Ag_k = Aax(i);%k时刻加速度计输出的姿态角
  83.         Aw_k = Agy(i);%k时刻陀螺仪输出的姿态角
  84.         error_k = Aw_k - Ag_k; %姿态角在k时刻的偏差
  85.        
  86.         if(i==1)
  87.                 u_k = 0;
  88.         else
  89.                 u_k = gyro_y(i-1) * T * pi / 180.0;
  90.         end
  91.         X_k_1_k_1 = X_k_k;
  92.         X_k_k_1 = A * X_k_1_k_1  + B * u_k;
  93.        
  94.         P_k_1_k_1 = P_k_k;
  95.         P_k_k_1 = A * P_k_1_k_1 * (A') + Q;
  96.         %计算卡尔曼增益
  97.         %P_k_1是k-1时刻的滤波协方差
  98.         K_k = P_k_k_1 * (C') / (C * P_k_k_1 * (C') + R_k);
  99.        
  100.         X_k = [Aw_k;0];
  101.         Y_k = C * X_k;
  102.         X_k_k = X_k_k_1 + K_k * (Y_k - C * X_k_k_1);
  103.         P_k_k = (I - K_k * C) * P_k_k_1;
  104.         Af_k_1(i) = X_k_k(1);
  105.         Af_k_2(i) = X_k_k(2);
  106.         % 系统输出方程
  107.         % Y_k = C * X_k;
  108.         % 对姿态角预测值进行修正,Af_k为k时刻姿势角的最终输出值
  109.         % Af_k(i) = Aw_k + K_k * error_k;
  110.         % 计算下一步滤波算法中的滤波协方差
  111.         % P_k_1 = P_k_1 - K_k * C * P_k_1;
  112. end
  113. plot(Aax, 'r');
  114. hold on;
  115. plot(Agy, 'g');
  116. hold on;
  117. plot(Af_k_1, 'b');
  118. hold on;
  119. plot(Af_k_2, 'c');
  120. hold on;
  121. fclose(fid);
复制代码


accel_x,accel_y和accel_z是加速度计的三轴数据。
gyro_x,gyro_y和gyro_z是陀螺仪的输出角速度数据。
仿真曲线如下:


其中红线是加速度计计算得到的角度,蓝线是卡尔曼滤波器输出的角度,绿色是陀螺仪积分计算得到的角度数据(绿线与蓝线重合了,所以是看到蓝线)

本帖子中包含更多资源

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

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2014-11-18 22:07:56 | 显示全部楼层
补充一下,浅蓝色线是状态矩阵X_k_k中的error_k曲线
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表