这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 关于卡尔曼滤波和互补滤波

共2条 1/1 1 跳转至

关于卡尔曼滤波和互补滤波

助工
2014-09-02 21:17:06     打赏

在EEPW看了很多也学了一些,一些网友总是对滤波有些疑问,对于卡尔曼滤波大家也觉得很难整定卡尔曼参数。下面想针对楼主自己调试kalman滤波器和互补滤波器的一些经验(主要是kalman滤波):

1>工欲善其事必先利其器——串口调试工具(用以将数据传到电脑上进行对比),楼主这里用的是Serial Digtal V2(Serial_Digital_Scope V2.rar),这个软件还需要下位机对应的代码这里也分享一下(Debug Ways.rar)。

2>下位机软件准备(kalman),记得滤多个数据的话,得准备几个kalman滤波器,参数什么的都不一样,当然也可以整合为一个kalman滤波器下面分享一下代码。(悄悄的告诉大家这是我在烈火四轴里采用的参数什么,代码都是一样的),注释变成乱码了不好意思.........................代码分享()Kalman filter.rar

/*-------------------------------------------------------------------------------------------------------------------------------------------*/

#include "kalman_filter.h" 
klm_result klm_all_res ;   /* 卡尔曼滤波器输出结果 */
   
//****************************************************************
//kalman滤波所需参数初始化
//****************************************************************
klm_prameter kalman_pra ;  /* 定义滤波参数结构体 */

void kalman_prameter_init(void)
{
	/* X轴滤波所需参数 */
	kalman_pra.x_Q_angle =500.0 ; 
	kalman_pra.x_Q_gyro =500.0;
	kalman_pra.x_R_angle = 3000.0 ;    
	/* Y轴滤波所需参数 * /
	kalman_pra.y_Q_angle = 500.0; 
	kalman_pra.y_Q_gyro = 500.0 ;
	kalman_pra.y_R_angle = 3000.0;  
	/* 由于没有指南所以不需要Z轴,Z轴为航向为陀螺仪直接积分 */
}

//*******************************************************************
//Kalman 滤波器
//*******************************************************************
const float dt=0.005; /* dt为采样时间 */ 
static float x_P[2][2] = {
    { 1, 0 },
    { 0, 1 }
};
static float y_P[2][2] = {
    { 1, 0 },
    { 0, 1 }
};


static float x_Pdot[4] ={0,0,0,0};
static float y_Pdot[4] ={0,0,0,0};


static const char C_0 = 1;

static float  x_PCt_0, x_PCt_1, x_E, x_K_0, x_K_1, x_t_0, x_t_1;
static float  y_PCt_0, y_PCt_1, y_E, y_K_0, y_K_1, y_t_0, y_t_1;

//-------------------------------------------------------
void Kalman_Filter(S_FLOAT_XYZ *angle_m,S_FLOAT_XYZ *gyro_m )      
  //gyro_m:gyro_measure
{		
    klm_all_res.x_angle +=(gyro_m->X - kalman_pra.x_q_bias) * dt;
    klm_all_res.y_angle +=(gyro_m->Y - kalman_pra.y_q_bias) * dt;
  
	
    x_Pdot[0]=kalman_pra.x_Q_angle - x_P[0][1] - x_P[1][0]; //Q_angle - 1 - 0 ;
    x_Pdot[1]= -x_P[1][1]; // Pdot[1] = -1
    x_Pdot[2]= -x_P[1][1]; // -1
    x_Pdot[3]=kalman_pra.x_Q_gyro;
	
    y_Pdot[0]=kalman_pra.y_Q_angle - y_P[0][1] - y_P[1][0]; //Q_angle - 1 - 0 ;
    y_Pdot[1]= -y_P[1][1]; // Pdot[1] = -1
    y_Pdot[2]= -y_P[1][1]; // -1
    y_Pdot[3]=kalman_pra.y_Q_gyro;
	
    x_P[0][0] += x_Pdot[0] * dt;
    x_P[0][1] += x_Pdot[1] * dt;
    x_P[1][0] += x_Pdot[2] * dt;
    x_P[1][1] += x_Pdot[3] * dt;
		
    y_P[0][0] += y_Pdot[0] * dt;
    y_P[0][1] += y_Pdot[1] * dt;
    y_P[1][0] += y_Pdot[2] * dt;
    y_P[1][1] += y_Pdot[3] * dt;
		
    kalman_pra.x_angle_err = angle_m->X - klm_all_res.x_angle;
    kalman_pra.y_angle_err = angle_m->Y - klm_all_res.y_angle;
    
    x_PCt_0 = C_0 * x_P[0][0];
    x_PCt_1 = C_0 * x_P[1][0];     
 
    y_PCt_0 = C_0 * y_P[0][0];
    y_PCt_1 = C_0 * y_P[1][0];    
      
    x_E = kalman_pra.x_R_angle + C_0 * x_PCt_0;
    y_E = kalman_pra.y_R_angle + C_0 * y_PCt_0;
   
    x_K_0 = x_PCt_0 / x_E;
    x_K_1 = x_PCt_1 / x_E;  
    
    y_K_0 = y_PCt_0 / y_E;
    y_K_1 = y_PCt_1 / y_E;  
    
    x_t_0 = x_PCt_0;
    x_t_1 = C_0 * x_P[0][1];
		
    y_t_0 = y_PCt_0;
    y_t_1 = C_0 * y_P[0][1];
				
    x_P[0][0] -= x_K_0 * x_t_0;
    x_P[0][1] -= x_K_0 * x_t_1;
    x_P[1][0] -= x_K_1 * x_t_0;
    x_P[1][1] -= x_K_1 * x_t_1;
		
    y_P[0][0] -= y_K_0 * y_t_0;
    y_P[0][1] -= y_K_0 * y_t_1;
    y_P[1][0] -= y_K_1 * y_t_0;
    y_P[1][1] -= y_K_1 * y_t_1;
	
    klm_all_res.x_angle += x_K_0 * kalman_pra.x_angle_err;
    kalman_pra.x_q_bias= kalman_pra.x_q_bias + x_K_1 * kalman_pra.x_angle_err;
    klm_all_res.x_angle_dot = gyro_m->X-kalman_pra.x_q_bias;  
		
    klm_all_res.y_angle += y_K_0 * kalman_pra.y_angle_err;
    kalman_pra.y_q_bias= kalman_pra.y_q_bias + y_K_1 * kalman_pra.y_angle_err;
    klm_all_res.y_angle_dot = gyro_m->Y-kalman_pra.y_q_bias;  
}

/*------------------------------------------------------------------------------ */
这里说一下注意事项:
1> Serial Digital Scop只能用9600波特率,其它波特率不支持
2> 话说2呢,嗯就没有2了,
/*-------------------------------------------------------------------------------*/
申明:
     楼主只讲调试经验,理论楼主不行,自行研究。完毕。
/*-------------------------------------------------------------------------------*/
如何调试kalman滤波?
kalman滤波一个轴只需要三个参数进行调试,你需要将ACC转化的角度和通过Kalman滤波器滤波的角度通过下位机程序发送到上位机上,通过观察波形来确定参数的调试。这里我们都认为ACC的角度时时都是比较准确的只是噪声比较大,没法直接用。
下面说一个几个参数的作用:
1>Q_angle控制的是kalman滤波的左右平移。(大概是这样的,至于为什么请大神探讨。)
2>Q_gyro这个参数表式你信任gyro有多少,数字越大你信任得越少。这里没有图片还没发说。我去,等等吧会有机会的。(这里等楼主再完善吧)
3>R_angle表示的是你信任ACC有多少,越大信任越小。这个主要是调试整体滤出波形跟随ACC转化的情况。
这个参数越大滤出的波形跟随ACC转化的波越慢。
/*-------------------------------------------------------------------------------*/
1>此贴未完,且听下回分解。(谢谢)
2>最后申明此贴是楼主私人观点,有何疑问清留言。有问题一起讨论不要骂楼主。

 

 




关键词: kalman     滤波器    

菜鸟
2014-09-02 21:27:00     打赏
2楼
高深,顶一下。。。。。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]