OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11014|回复: 17

MPU6050卡尔曼X轴滤波问题

[复制链接]

25

主题

281

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2504
金钱
2504
注册时间
2015-8-17
在线时间
383 小时
发表于 2016-7-19 11:49:33 | 显示全部楼层 |阅读模式
1金钱
本人最近在研究卡尔曼滤波,Y轴滤得很好,但是X轴却很不好,有遇到过的朋友的吗?
Y轴.png
这个是Y轴,我感觉滤波效果还是很不错了。
X轴.png
这个是X轴,这滤波我完全不能接受,为什么被我用红色圈住的地方会反向的?而且好像整体波形都滞后很严重。

最佳答案

查看完整内容[请看2#楼]

谢谢原子哥,原因找到了,算x和y的夹角的时候,x的公式错了,应该是Angle_x_temp = (atan2(z , y)) * 180 / Pi;我也是移植我们论坛上下的代码,他写是的Angle_x_temp = (atan2(y , z)) * 180 / Pi; 没细看。他那个代码应该是做平衡车的,只用了Y轴,所以他的Y轴是对的。
做事的原则:
1.每个问题重复三遍、研究三遍后再提问,直接得到答案的人什么都没学会。
2.做事要有始有终,感谢那些帮助自己解决问题的人,把解决的方法总结起来。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

25

主题

281

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2504
金钱
2504
注册时间
2015-8-17
在线时间
383 小时
 楼主| 发表于 2016-7-19 11:49:34 | 显示全部楼层

谢谢原子哥,原因找到了,算x和y的夹角的时候,x的公式错了,应该是Angle_x_temp = (atan2(z , y)) * 180 / Pi;我也是移植我们论坛上下的代码,他写是的Angle_x_temp = (atan2(y , z)) * 180 / Pi; 没细看。他那个代码应该是做平衡车的,只用了Y轴,所以他的Y轴是对的。

做事的原则:
1.每个问题重复三遍、研究三遍后再提问,直接得到答案的人什么都没学会。
2.做事要有始有终,感谢那些帮助自己解决问题的人,把解决的方法总结起来。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2016-7-20 22:30:52 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-7-15
在线时间
6 小时
发表于 2016-7-21 18:55:41 | 显示全部楼层
你好,可以传一下滤波的程序吗~谢谢
回复

使用道具 举报

25

主题

281

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2504
金钱
2504
注册时间
2015-8-17
在线时间
383 小时
 楼主| 发表于 2016-7-21 21:38:07 | 显示全部楼层
[mw_shl_code=c,true]#include "Kalman_filter.h"
#include "math.h"

float Accel_x;             //XÖá¼óËù¶èÖμÔY′æ
float Accel_y;             //YÖá¼óËù¶èÖμÔY′æ
float Accel_z;             //ZÖá¼óËù¶èÖμÔY′æ

float Gyro_x;                 //XÖáíóÂYòÇêy¾YÔY′æ
float Gyro_y;    //YÖáíóÂYòÇêy¾YÔY′æ
float Gyro_z;                 //ZÖáíóÂYòÇêy¾YÔY′æ

//float Angle_gy;    //óé½ÇËù¶è¼ÆËãμÄÇãD±½Ç¶è
float Angle_x_temp;  //óé¼óËù¶è¼ÆËãμÄxÇãD±½Ç¶è
float Angle_y_temp;  //óé¼óËù¶è¼ÆËãμÄyÇãD±½Ç¶è
float Angle_z_temp;

float Angle_X_Final; //X×îÖÕÇãD±½Ç¶è
float Angle_Y_Final; //Y×îÖÕÇãD±½Ç¶è
float Angle_Z_Final; //Z×îÖÕÇãD±½Ç¶è

//¿¨¶ûÂü2Îêy
char  C_0 = 1;
float Q_bias_x, Q_bias_y, Q_bias_z;
float Angle_err_x, Angle_err_y, Angle_err_z;
float PCt_0, PCt_1, E;
float K_0, K_1, t_0, t_1;
float Pdot[4] = { 0,0,0,0 };
float PP[2][2] = { { 1, 0 },{ 0, 1 } };

double KalmanFilter(const double ResrcData, double ProcessNiose_Q, double MeasureNoise_R)
{
        double R = MeasureNoise_R;
        double Q = ProcessNiose_Q;
        static double x_last;
        double x_mid = x_last;
        double x_now;
        static double p_last;
        double p_mid;
        double p_now;
        double kg;
        x_mid = x_last; //x_last=x(k-1|k-1),x_mid=x(k|k-1)
        p_mid = p_last + Q; //p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=Ôëéù
        kg = p_mid / (p_mid + R); //kg=kalman filter,R=Ôëéù
        x_now = x_mid + kg*(ResrcData - x_mid);//1à×îóÅÖμ
        p_now = (1 - kg)*p_mid;//×îóÅÖμ¶Ôó|μÄcovariance
        p_last = p_now; //¸üDÂcovarianceÖμ
        x_last = x_now; //¸üDÂÏμí3×′ì¬Öμ
        return x_now;
}

//½Ç¶è¼ÆËã
void Angle_Calcu(void)
{
        //·¶Î§Îa2gê±£¬»»Ëã1ØÏμ£o16384 LSB/g
        //deg = rad*180/3.14
        float x=0, y=0, z=0;

        Accel_x = aacx; //xÖá¼óËù¶èÖμÔY′æ
        Accel_y = aacy; //yÖá¼óËù¶èÖμÔY′æ
        Accel_z = aacz; //zÖá¼óËù¶èÖμÔY′æ
        Gyro_x = gyrox;  //xÖáíóÂYòÇÖμÔY′æ
        Gyro_y = gyroy;  //yÖáíóÂYòÇÖμÔY′æ
        Gyro_z = gyroz;  //zÖáíóÂYòÇÖμÔY′æ

        //′|àíxÖá¼óËù¶è
        if (Accel_x<32764) x = Accel_x / 16384;
        else              x = 1 - (Accel_x - 49152) / 16384;

        //′|àíy&#214;á&#188;ó&#203;ù&#182;è
        if (Accel_y<32764) y = Accel_y / 16384;
        else              y = 1 - (Accel_y - 49152) / 16384;

        //′|àíz&#214;á&#188;ó&#203;ù&#182;è
        if (Accel_z<32764) z = Accel_z / 16384;
        else              z = (Accel_z - 49152) / 16384;

        //ó&#195;&#188;ó&#203;ù&#182;è&#188;&#198;&#203;&#227;èy&#184;&#246;&#214;áoí&#203;&#174;&#198;&#189;&#195;&#230;×&#248;±ê&#207;μ&#214;&#174;&#188;&#228;μ&#196;&#188;D&#189;&#199;
        Angle_x_temp = (atan2(z , y)) * 180 / Pi;
        Angle_y_temp = (atan2(x , z)) * 180 / Pi;
        Angle_z_temp = (atan2(y , x)) * 180 / Pi;

        //&#189;&#199;&#182;èμ&#196;&#213;y&#184;oo&#197;
        if (Accel_y<32764) Angle_y_temp = +Angle_y_temp;
        if (Accel_y>32764) Angle_y_temp = -Angle_y_temp;
        if (Accel_x<32764) Angle_x_temp = +Angle_x_temp;
        if (Accel_x>32764) Angle_x_temp = -Angle_x_temp;
        if (Accel_z<32764) Angle_z_temp = +Angle_z_temp;
        if (Accel_z>32764) Angle_z_temp = -Angle_z_temp;
       
        //&#189;&#199;&#203;ù&#182;è
        //&#207;ò&#199;°&#212;&#203;&#182;ˉ
        if (Gyro_x<32768) Gyro_x = -(Gyro_x / 16.4);//·&#182;&#206;§&#206;a1000deg/sê±£&#172;&#187;&#187;&#203;&#227;1&#216;&#207;μ£o16.4 LSB/(deg/s)
        //&#207;òoó&#212;&#203;&#182;ˉ
        if (Gyro_x>32768) Gyro_x = +(65535 - Gyro_x) / 16.4;
        //&#207;ò&#199;°&#212;&#203;&#182;ˉ
        if (Gyro_y<32768) Gyro_y = -(Gyro_y / 16.4);//·&#182;&#206;§&#206;a1000deg/sê±£&#172;&#187;&#187;&#203;&#227;1&#216;&#207;μ£o16.4 LSB/(deg/s)
        //&#207;òoó&#212;&#203;&#182;ˉ
        if (Gyro_y>32768) Gyro_y = +(65535 - Gyro_y) / 16.4;
        //&#207;ò&#199;°&#212;&#203;&#182;ˉ
        if (Gyro_z<32768) Gyro_z = -(Gyro_z / 16.4);//·&#182;&#206;§&#206;a1000deg/sê±£&#172;&#187;&#187;&#203;&#227;1&#216;&#207;μ£o16.4 LSB/(deg/s)
        //&#207;òoó&#212;&#203;&#182;ˉ
        if (Gyro_z>32768) Gyro_z = +(65535 - Gyro_z) / 16.4;

        //Angle_gy = Angle_gy + Gyro_y*0.025;  //&#189;&#199;&#203;ù&#182;è&#187;y·&#214;μ&#195;μ&#189;&#199;&#227;D±&#189;&#199;&#182;è.&#212;&#189;′ó&#187;y·&#214;3&#246;à′μ&#196;&#189;&#199;&#182;è&#212;&#189;′ó
        Kalman_Filter_X(Angle_x_temp, Gyro_x);  //&#191;¨&#182;&#251;&#194;ü&#194;&#203;2¨&#188;&#198;&#203;&#227;X&#199;&#227;&#189;&#199;
//        yijiehubu_P(Angle_x_temp, Gyro_x);
//        Erjielvbo(Angle_x_temp, Gyro_x);
        Kalman_Filter_Y(Angle_y_temp, Gyro_y);  //&#191;¨&#182;&#251;&#194;ü&#194;&#203;2¨&#188;&#198;&#203;&#227;Y&#199;&#227;&#189;&#199;
        Kalman_Filter_Z(Angle_z_temp, Gyro_z);  //&#191;¨&#182;&#251;&#194;ü&#194;&#203;2¨&#188;&#198;&#203;&#227;Y&#199;&#227;&#189;&#199;
}

void Kalman_Filter_X(float Accel, float Gyro) //&#191;¨&#182;&#251;&#194;üoˉêy
{
        Angle_X_Final += (Gyro - Q_bias_x) * dt; //&#207;è&#209;é1à&#188;&#198;

        Pdot[0] = Q_angle - PP[0][1] - PP[1][0]; // Pk-&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;μ&#196;&#206;¢·&#214;

        Pdot[1] = -PP[1][1];
        Pdot[2] = -PP[1][1];
        Pdot[3] = Q_gyro;

        PP[0][0] += Pdot[0] * dt;   // Pk-&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;&#206;¢·&#214;μ&#196;&#187;y·&#214;
        PP[0][1] += Pdot[1] * dt;   // =&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;
        PP[1][0] += Pdot[2] * dt;
        PP[1][1] += Pdot[3] * dt;

        Angle_err_x = Accel - Angle_X_Final;        //zk-&#207;è&#209;é1à&#188;&#198;

        PCt_0 = C_0 * PP[0][0];
        PCt_1 = C_0 * PP[1][0];

        E = R_angle + C_0 * PCt_0;

        K_0 = PCt_0 / E;
        K_1 = PCt_1 / E;

        t_0 = PCt_0;
        t_1 = C_0 * PP[0][1];

        PP[0][0] -= K_0 * t_0;                 //oó&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;
        PP[0][1] -= K_0 * t_1;
        PP[1][0] -= K_1 * t_0;
        PP[1][1] -= K_1 * t_1;

        Angle_X_Final += K_0 * Angle_err_x;         //oó&#209;é1à&#188;&#198;
        Q_bias_x += K_1 * Angle_err_x;         //oó&#209;é1à&#188;&#198;
        Gyro_x = Gyro - Q_bias_x;         //ê&#228;3&#246;&#214;μ(oó&#209;é1à&#188;&#198;)μ&#196;&#206;¢·&#214;=&#189;&#199;&#203;ù&#182;è
}

void Kalman_Filter_Y(float Accel, float Gyro) //&#191;¨&#182;&#251;&#194;üoˉêy               
{
        Angle_Y_Final += (Gyro - Q_bias_y) * dt; //&#207;è&#209;é1à&#188;&#198;

        Pdot[0] = Q_angle - PP[0][1] - PP[1][0]; // Pk-&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;μ&#196;&#206;¢·&#214;

        Pdot[1] = -PP[1][1];
        Pdot[2] = -PP[1][1];
        Pdot[3] = Q_gyro;

        PP[0][0] += Pdot[0] * dt;   // Pk-&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;&#206;¢·&#214;μ&#196;&#187;y·&#214;
        PP[0][1] += Pdot[1] * dt;   // =&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;
        PP[1][0] += Pdot[2] * dt;
        PP[1][1] += Pdot[3] * dt;

        Angle_err_y = Accel - Angle_Y_Final;        //zk-&#207;è&#209;é1à&#188;&#198;

        PCt_0 = C_0 * PP[0][0];
        PCt_1 = C_0 * PP[1][0];

        E = R_angle + C_0 * PCt_0;

        K_0 = PCt_0 / E;
        K_1 = PCt_1 / E;

        t_0 = PCt_0;
        t_1 = C_0 * PP[0][1];

        PP[0][0] -= K_0 * t_0;                 //oó&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;
        PP[0][1] -= K_0 * t_1;
        PP[1][0] -= K_1 * t_0;
        PP[1][1] -= K_1 * t_1;

        Angle_Y_Final += K_0 * Angle_err_y;         //oó&#209;é1à&#188;&#198;
        Q_bias_y += K_1 * Angle_err_y;         //oó&#209;é1à&#188;&#198;
        Gyro_y = Gyro - Q_bias_y;         //ê&#228;3&#246;&#214;μ(oó&#209;é1à&#188;&#198;)μ&#196;&#206;¢·&#214;=&#189;&#199;&#203;ù&#182;è
}

void Kalman_Filter_Z(float Accel, float Gyro) //&#191;¨&#182;&#251;&#194;üoˉêy
{
        Angle_Z_Final += (Gyro - Q_bias_z) * dt; //&#207;è&#209;é1à&#188;&#198;

        Pdot[0] = Q_angle - PP[0][1] - PP[1][0]; // Pk-&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;μ&#196;&#206;¢·&#214;

        Pdot[1] = -PP[1][1];
        Pdot[2] = -PP[1][1];
        Pdot[3] = Q_gyro;

        PP[0][0] += Pdot[0] * dt;   // Pk-&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;&#206;¢·&#214;μ&#196;&#187;y·&#214;
        PP[0][1] += Pdot[1] * dt;   // =&#207;è&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;
        PP[1][0] += Pdot[2] * dt;
        PP[1][1] += Pdot[3] * dt;

        Angle_err_z = Accel - Angle_Z_Final;        //zk-&#207;è&#209;é1à&#188;&#198;

        PCt_0 = C_0 * PP[0][0];
        PCt_1 = C_0 * PP[1][0];

        E = R_angle + C_0 * PCt_0;

        K_0 = PCt_0 / E;
        K_1 = PCt_1 / E;

        t_0 = PCt_0;
        t_1 = C_0 * PP[0][1];

        PP[0][0] -= K_0 * t_0;                 //oó&#209;é1à&#188;&#198;&#206;ó2&#238;D-·&#189;2&#238;
        PP[0][1] -= K_0 * t_1;
        PP[1][0] -= K_1 * t_0;
        PP[1][1] -= K_1 * t_1;

        Angle_Z_Final += K_0 * Angle_err_z;         //oó&#209;é1à&#188;&#198;
        Q_bias_z += K_1 * Angle_err_z;         //oó&#209;é1à&#188;&#198;
        Gyro_z = Gyro - Q_bias_z;         //ê&#228;3&#246;&#214;μ(oó&#209;é1à&#188;&#198;)μ&#196;&#206;¢·&#214;=&#189;&#199;&#203;ù&#182;è
}[/mw_shl_code]
做事的原则:
1.每个问题重复三遍、研究三遍后再提问,直接得到答案的人什么都没学会。
2.做事要有始有终,感谢那些帮助自己解决问题的人,把解决的方法总结起来。
回复

使用道具 举报

25

主题

281

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2504
金钱
2504
注册时间
2015-8-17
在线时间
383 小时
 楼主| 发表于 2016-7-21 21:39:04 | 显示全部楼层
橙彤彤 发表于 2016-7-21 18:55
你好,可以传一下滤波的程序吗~谢谢

传了
做事的原则:
1.每个问题重复三遍、研究三遍后再提问,直接得到答案的人什么都没学会。
2.做事要有始有终,感谢那些帮助自己解决问题的人,把解决的方法总结起来。
回复

使用道具 举报

1

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2016-7-10
在线时间
6 小时
发表于 2016-7-25 16:00:56 | 显示全部楼层
回复

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
发表于 2016-8-1 11:56:30 | 显示全部楼层
wszdxmh 发表于 2016-7-21 21:38
[mw_shl_code=c,true]#include "Kalman_filter.h"
#include "math.h"

代码注释乱码
永远保持一颗学习的心态。
回复

使用道具 举报

25

主题

281

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2504
金钱
2504
注册时间
2015-8-17
在线时间
383 小时
 楼主| 发表于 2016-8-1 14:29:25 | 显示全部楼层

MDK5用的是ANSI编码,大家也这样用,如果我强行改成UTF-8就打开不了别人的了
做事的原则:
1.每个问题重复三遍、研究三遍后再提问,直接得到答案的人什么都没学会。
2.做事要有始有终,感谢那些帮助自己解决问题的人,把解决的方法总结起来。
回复

使用道具 举报

4

主题

19

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1385
金钱
1385
注册时间
2014-12-5
在线时间
303 小时
发表于 2016-8-6 15:55:13 | 显示全部楼层
你将Y和Z调换过来,输出的X角度有没有问题啊,是不是正确的角度啊
qqqq
回复

使用道具 举报

18

主题

96

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2016-10-26
在线时间
40 小时
发表于 2016-10-29 17:19:31 | 显示全部楼层
楼主  我用一阶滤波   为什么滤出的波只是正负90    为什么不可以0到360度   求大神们您指导一下
回复

使用道具 举报

25

主题

281

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2504
金钱
2504
注册时间
2015-8-17
在线时间
383 小时
 楼主| 发表于 2016-10-30 17:22:32 | 显示全部楼层
zhaoyuaiweide 发表于 2016-10-29 17:19
楼主  我用一阶滤波   为什么滤出的波只是正负90    为什么不可以0到360度   求大神们您指导一下

http://www.openedv.com/thread-79541-1-1.html
你看一下我之前发的这个帖子吧,好久没弄,忘得差不多了
做事的原则:
1.每个问题重复三遍、研究三遍后再提问,直接得到答案的人什么都没学会。
2.做事要有始有终,感谢那些帮助自己解决问题的人,把解决的方法总结起来。
回复

使用道具 举报

0

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2016-7-4
在线时间
18 小时
发表于 2017-2-21 13:47:25 | 显示全部楼层
我看了你以前的程序,你的程序是做平衡车的把,y角度是对的,x是错的
回复

使用道具 举报

33

主题

310

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
495
金钱
495
注册时间
2016-12-31
在线时间
63 小时
发表于 2017-4-5 08:49:58 | 显示全部楼层
先顶一下
回复

使用道具 举报

10

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
272
金钱
272
注册时间
2016-7-13
在线时间
41 小时
发表于 2017-8-3 16:01:03 | 显示全部楼层
顶。。。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2017-9-12
在线时间
3 小时
发表于 2017-9-12 20:45:38 | 显示全部楼层
楼主卡尔曼滤波后怎么转化为欧拉角啊
回复

使用道具 举报

5

主题

129

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
432
金钱
432
注册时间
2020-5-8
在线时间
66 小时
发表于 2020-6-28 17:52:56 | 显示全部楼层
有源码么?
回复

使用道具 举报

2

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2020-10-15
在线时间
33 小时
发表于 2022-6-4 11:09:10 | 显示全部楼层
用的波形显示图像是什么啊,可以用matlab显示吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 00:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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