搜索
bottom↓
回复: 15

卡尔曼滤波探索以及疑问,使用的zlstone滤波代码,

[复制链接]

出0入0汤圆

发表于 2013-7-30 22:06:55 | 显示全部楼层 |阅读模式
本帖最后由 wujohn 于 2013-7-31 10:25 编辑

输入为陀螺仪的角度值和加速度计的角速度,由卡尔曼知识可知,卡尔曼滤波器最重要的是对预测值的协方差(Q),和测量值的协方差(R)进行估计,当我赋值Q=0.001,R=0.5时输出到滤波器的角度和输出角度波形如下:

Q=0.001,R=0.5.png






此时输出波形一直在0点左右,我的初始预测值为0;但是由卡尔曼原理可知,预测值会不断根据最后输出值更新,也就是说输出值对测量值有一个跟踪过程,但是我这个一直在0点左右,我的猜想是我的预测值没有更新,于是我对Q,R做了下面
改动,其他值不变
Q=0.9,R=0.5波形如下:





Q=0.9,R=0.5.png
当Q=1.5,R=0.5时波形如下:
Q=1.5,R=0.5.png





,做到这一步后我又去看了一下原理

Q/(Q+R)的值就是卡尔曼增益的收敛值,比如其值为0.2,那么卡尔曼增益会向0.2收敛(对于0.2的含义解释一下,比如预测角度值是5度,角度测量值是10度,那么最优化角度为:5+0.2*(10-5)=6。从这里可以看出,卡尔曼增益越小,说明预测值越可靠,最优化角度越接近预测值;相反的,卡尔曼增益越大,说明测量值越可靠,最优化角度越接近测量值)。

总结一下:
两个疑问;第一由上面的三个波形是否可以说明我的预测值没有更新??第二:当Q=1.5,R=0.5时此时滤波器设置是否合理??
最后附上代码:
#include"includes.h"
//******卡尔曼参数************
////******kalman参数************
float Gyro_y;        //Y轴陀螺仪数据暂存
float Angle;         //小车最终倾斜角度               
float code Q_angle=1.5;  
float code Q_gyro=0.003;
float code R_angle=0.5;
float code dt=0.01;                          //dt为kalman滤波器采样时间;
char  code C_0 = 1;
float xdata Q_bias, Angle_err;//
float xdata PCt_0, PCt_1, E;
float xdata K_0, K_1, t_0, t_1;
float xdata Pdot[4] ={0,0,0,0};
float xdata PP[2][2] = { { 1, 0 },{ 0, 1 } };

//*********************************************************
// 卡尔曼滤波
// 卡尔曼滤波
//*********************************************************

//Kalman滤波,20MHz的处理时间约0.77ms;

void Kalman_Filter(float Accel,float Gyro)               
{
       
        Angle+=(Gyro-Q_bias)* dt; //第一步为卡尔曼第一个方程X(k|k-1)=A X(k-1|k-1)+B U(k) ……….. (1)

       
        Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分     

        Pdot[1]=- PP[1][1];
        Pdot[2]=- PP[1][1];
        Pdot[3]=Q_gyro;
       
        PP[0][0] += Pdot[0] * dt;   // Pk-先验估计误差协方差微分的积分
        PP[0][1] += Pdot[1] * dt;   // =先验估计误差协方差
        PP[1][0] += Pdot[2] * dt;
        PP[1][1] += Pdot[3] * dt;
               
        Angle_err = Accel - Angle;        //zk-先验估计
       
        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;                 //后验估计误差协方差
        PP[0][1] -= K_0 * t_1;
        PP[1][0] -= K_1 * t_0;
        PP[1][1] -= K_1 * t_1;
               
        Angle        += K_0 * Angle_err;         //后验估计
        Q_bias        += K_1 * Angle_err;         //后验估计
        Gyro_y   = Gyro - Q_bias;         //输出值(后验估计)的微分=角速度

}


void main ()
{
        float Angle_accel_x,Palstance_gyro_x;
        float PWM;           //综合PWM计算
        Init_PWM();
        Init_Motor();
        LCD_Init();
        InitMPU6050();
        Chuankou_Init();
        Delay200ms( );
        while(1)
        {
        Angle_accel_x=Read_Acc_x( );
         Display_dec(0x80,Angle_accel_x);
         Palstance_gyro_x=Read_Gry_x( );
         Display_dec(0x90,Palstance_gyro_x);
                
        //-------卡尔曼滤波融合-----------------------

        Kalman_Filter(Angle_accel_x,Palstance_gyro_x);       //卡尔曼滤波计算倾角
        Display_dec(0x84,Angle);
        Display_dec(0x94,Gyro_y);
        Send_data((int)Angle_accel_x);
        Send_data((int)Angle);
        Send_data((int)Palstance_gyro_x);
        Send_data((int)Gyro_y);       
               
         PWM  = 4.7*Angle + 0*Gyro_y;  //PID:角速度和角度
         
//                 PPWM_R =PWM;   
//                PPWM_L =PWM;         
                        if(Angle_accel_x<-40||Angle_accel_x>40)               //角度过大,关闭电机
                        {  
                                   PWM=0;
                          }
                   Display_dec(0x88,PWM);
                PWM_Motor(PWM,PWM);         
        }        
}

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-7-30 23:39:18 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2013-7-31 09:16:49 来自手机 | 显示全部楼层
一、是的,可以这么理解。Q矩阵比较小的含义是认为预测方程的误差很小,那么卡尔曼滤波就会更相信预测方程的结果。如果你的预测方程是状态不变,那滤波结果就倾向于不变。

出0入0汤圆

发表于 2013-7-31 09:28:11 来自手机 | 显示全部楼层
二、我感觉R还可以更小些。这两个误差阵不应该是试出来的,具体要看应用场景,您还没说您测的是什么……

出0入0汤圆

 楼主| 发表于 2013-7-31 10:11:32 | 显示全部楼层
本帖最后由 wujohn 于 2013-7-31 10:14 编辑
K.O.Carnivist 发表于 2013-7-31 09:16
一、是的,可以这么理解。Q矩阵比较小的含义是认为预测方程的误差很小,那么卡尔曼滤波就会更相信预测方程 ...


陀螺仪的角度值!做两轮平衡车,使用的代码为 zistone的,

出0入0汤圆

 楼主| 发表于 2013-7-31 10:12:34 | 显示全部楼层
K.O.Carnivist 发表于 2013-7-31 09:28
二、我感觉R还可以更小些。这两个误差阵不应该是试出来的,具体要看应用场景,您还没说您测的是什么…… ...

我可不是大神,建模这个东西,玩不起

出0入0汤圆

 楼主| 发表于 2013-7-31 10:38:02 | 显示全部楼层
K.O.Carnivist 发表于 2013-7-31 09:16
一、是的,可以这么理解。Q矩阵比较小的含义是认为预测方程的误差很小,那么卡尔曼滤波就会更相信预测方程 ...

源代码Q_bias没有赋值我把我的代码的Q_bias=0;了,不知道这样改对不?、

出0入0汤圆

发表于 2013-7-31 10:50:39 | 显示全部楼层
wujohn 发表于 2013-7-31 10:12
我可不是大神,建模这个东西,玩不起

先不急着建模,建模是用来修正状态更新方程的。R是传感器误差算出来的;Q主要取决于整体运动的程度(如果不建模修正状态方程的话),运动越剧烈这个值越大。两个误差可以实际测一下。

出0入0汤圆

发表于 2013-8-20 17:06:54 | 显示全部楼层
学习了~~~

出0入0汤圆

发表于 2013-8-23 14:31:38 | 显示全部楼层
正在学习中啊。。现在也是卡在卡尔曼滤波。。

出0入0汤圆

发表于 2013-8-26 01:50:07 | 显示全部楼层
能问下串口猎人如何使用?

出0入0汤圆

发表于 2013-10-15 23:45:33 | 显示全部楼层
支持一下,顺便看看你怎么调试的

出0入0汤圆

发表于 2013-11-17 00:23:20 | 显示全部楼层
wujohn 发表于 2013-7-31 10:12
我可不是大神,建模这个东西,玩不起

请问Q_bias含义是什么

出0入0汤圆

发表于 2013-11-17 01:27:48 | 显示全部楼层
K.O.Carnivist 发表于 2013-7-31 10:50
先不急着建模,建模是用来修正状态更新方程的。R是传感器误差算出来的;Q主要取决于整体运动的程度(如果 ...

请问高手您能解释一下楼主代码里面各卡尔曼参数的作用么?我也和楼主用的是同一个程序。

出0入0汤圆

发表于 2013-11-17 10:52:21 | 显示全部楼层
个人感觉,提高Q/R的比例,会提高加速度计数据在滤波数据所占的权重比例,换句话来说。Q/R高了,系统结果就更偏向于加速度计,反之就是陀螺仪。不知我的理解对不对?下面的图像分别是加速度计输出(红色)卡尔曼滤波输出(蓝色)在Q/R不同时做的对比,分别作了垂直于旋转轴的位移,和绕旋转轴旋转的运动。

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-11-17 10:53:46 | 显示全部楼层
再顶一下,车子能勉强站起来了,希望能通过这次对卡尔曼滤波有更多的了解。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-2 08:04

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

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