陀螺仪+加速度计卡尔曼

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//float gyro_m:陀螺仪测得的量(角速度)

//float incAngle:加计测得的角度值

#define dt 0.0015//卡尔曼滤波采样频率

#define R_angle 0.69 //测量噪声的协方差(即是测量偏差)

#define Q_angle 0.0001//过程噪声的协方差

#define Q_gyro 0.0003 //过程噪声的协方差过程噪声协方差为一个一行两列矩阵float kalmanUpdate(const float gyro_m,const float incAngle)

{

float K_0;//含有卡尔曼增益的另外一个函数,用于计算最优估计值

float K_1;//含有卡尔曼增益的函数,用于计算最优估计值的偏差

float Y_0;

float Y_1

float Rate;//去除偏差后的角速度

float Pdot[4];//过程协方差矩阵的微分矩阵

float angle_err;//角度偏量

float E;//计算的过程量

static float angle = 0; //下时刻最优估计值角度

static float q_bias = 0; //陀螺仪的偏差

static float P[2][2] = {{ 1, 0 }, { 0, 1 }};//过程协方差矩阵

Rate = gyro_m - q_bias;

//计算过程协方差矩阵的微分矩阵

Pdot[0] = Q_angle - P[0][1] - P[1][0];//??????

Pdot[1] = - P[1][1];

Pdot[2] = - P[1][1];

Pdot[3] = Q_gyro;//??????

angle += Rate * dt; //角速度积分得出角度

P[0][0] += Pdot[0] * dt; //计算协方差矩阵

P[0][1] += Pdot[1] * dt;

P[1][0] += Pdot[2] * dt;

P[1][1] += Pdot[3] * dt;

angle_err = incAngle - angle; //计算角度偏差

E = R_angle + P[0][0];

K_0 = P[0][0] / E; //计算卡尔曼增益

K_1 = P[1][0] / E;

Y_0 = P[0][0];

Y_1 = P[0][1];

P[0][0] -= K_0 * Y_0; //跟新协方差矩阵

P[0][1] -= K_0 * Y_1;

P[1][0] -= K_1 * Y_0;

P[1][1] -= K_1 * Y_1;

angle += K_0 * angle_err; //给出最优估计值

q_bias += K_1 * angle_err;//跟新最优估计值偏差

return angle;}

加速度模块角度计算:

如果传感器x 轴朝下,y 轴朝前

那竖直方向弧度计算公式为:angle = atan2(y, z) //结果以弧度表示并介于-pi 到pi 之间(不包括-pi)

如果要换算成具体角度:angle = atan2(y, z) * (180/3.14)

陀螺仪角度计算:

式中angle(n)为陀螺仪采样到第n次的角度值;

angle(n-1)为陀螺仪第n-1次采样时的角度值;

gyron为陀螺仪的第n次采样得到的瞬时角速率值;

dt为运行一遍所用时间;

angle_n += gyro(n) * dt //积分计算

卡尔曼滤波

网上找的kalman滤波,具体代码如下

static const float dt = 0.02;

static float P[2][2] = {{ 1, 0 }, { 0, 1 }};

float angle;

float q_bias;

float rate;

static const float R_angle = 0.5 ;

static const float Q_angle = 0.001;

static const float Q_gyro = 0.003;

float stateUpdate(const float gyro_m){

float q;

float Pdot[4];

q = gyro_m - q_bias;

Pdot[0] = Q_angle - P[0][1] - P[1][0]; /* 0,0 */

Pdot[1] = - P[1][1]; /* 0,1 */

Pdot[2] = - P[1][1]; /* 1,0 */

Pdot[3] = Q_gyro; /* 1,1 */

rate = q;

angle += q * dt;

P[0][0] += Pdot[0] * dt;

P[0][1] += Pdot[1] * dt;

P[1][0] += Pdot[2] * dt;

P[1][1] += Pdot[3] * dt;

return angle;

}

float kalmanUpdate(const float incAngle)

{

float angle_m = incAngle;

float angle_err = angle_m - angle;

float h_0 = 1;

const float PHt_0 = h_0*P[0][0]; /* + h_1*P[0][1] = 0*/ const float PHt_1 = h_0*P[1][0]; /* + h_1*P[1][1] = 0*/ float E = R_angle +(h_0 * PHt_0);

float K_0 = PHt_0 / E;

float K_1 = PHt_1 / E;

float Y_0 = PHt_0; /*h_0 * P[0][0]*/

float Y_1 = h_0 * P[0][1];

P[0][0] -= K_0 * Y_0;

P[0][1] -= K_0 * Y_1;

P[1][0] -= K_1 * Y_0;

P[1][1] -= K_1 * Y_1;

angle += K_0 * angle_err;

q_bias += K_1 * angle_err;

return angle;

}

相关文档
最新文档