四元数更新算法
- /****************************************************/
- delta_2=(2*halfT*gx)*(2*halfT*gx)+(2*halfT*gy)*(2*halfT*gy)+(2*halfT*gz)*(2*halfT*gz);
- q0 = (1-delta_2/8)*q0 + (-q1*gx - q2*gy - q3*gz)*halfT; // 整合四元数率 四元数微分方程 四元数更新算法,二阶毕卡法
- q1 = (1-delta_2/8)*q1 + (q0*gx + q2*gz - q3*gy)*halfT;
- q2 = (1-delta_2/8)*q2 + (q0*gy - q1*gz + q3*gx)*halfT;
- q3 = (1-delta_2/8)*q3 + (q0*gz + q1*gy - q2*gx)*halfT;
- /****************************************************/
- /*
- // integrate quaternion rate and normalise,四元数更新算法,一阶龙格-库塔法
- q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
- q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
- q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
- q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;
- */
卡尔曼滤波:
- //============================================================================
- // 卡尔曼滤波参数
- float Q_angle=0.001,
- Q_gyro=0.005,
- R_angle=0.5,
- dt=0.0055,//注意:dt的取值为kalman滤波器采样时间;
- angle,
- angle_dot;
- float P[2][2] = { { 1, 0 },
- { 0, 1 }
- }; //alpha_k
-
- float Pdot[4] ={0,0,0,0}; //Pdot = (u_k-bias)
- const char C_0 = 1; //H = [1 0]矩阵,用于提取
- float q_bias , //陀螺仪常值偏差bias
- angle_err, //观测值减去估计值
- PCt_0, PCt_1, //计算K的中间步骤,分子 PCT = PH_T
- E, //计算K的中间步骤,分母 E =(HPH_T + R)
- K_0, K_1, //K为卡尔曼增益,K = P(K),矩阵
- t_0, t_1; //更新alpha的中间步骤
- //============================================================================
- //函数名称:Kalman_Filter
- //功能概要:卡尔曼滤波
- void Kalman_Filter(float angle_m,float gyro_m) //gyro_m:gyro_measure
- {
-
- // 卡尔曼滤波开始
-
- angle+=(gyro_m-q_bias) * dt;//先验估计
- Pdot[0]=Q_angle - P[0][1] - P[1][0];// Pk-' 先验估计误差协方差的微分
- Pdot[1]=- P[1][1];
- Pdot[2]=- P[1][1];
- Pdot[3]=Q_gyro; //Pdot = (u_k-bias)
-
- P[0][0] += Pdot[0] * dt; // Pk- 先验估计误差协方差微分的积分 = 先验估计误差协方差
- P[0][1] += Pdot[1] * dt;
- P[1][0] += Pdot[2] * dt;
- P[1][1] += Pdot[3] * dt; //alpha_k = alpha_k-1 + [(u_k-bias)*dt]
-
-
- angle_err = angle_m - angle; //zk-先验估计 观测值减去估计值
-
-
- PCt_0 = C_0 * P[0][0];
- PCt_1 = C_0 * P[1][0]; //计算K的中间步骤,分子 PCT = PH^T
-
- E = R_angle + C_0 * PCt_0; //计算K的中间步骤,分母 E =(HPH^T + R)
-
- K_0 = PCt_0 / E; //K = PH^T / (HPH^T + R)
- K_1 = PCt_1 / E;
-
- t_0 = PCt_0; //更新alpha的中间步骤
- t_1 = C_0 * P[0][1];
- P[0][0] -= K_0 * t_0; //后验估计误差协方差
- P[0][1] -= K_0 * t_1;
- P[1][0] -= K_1 * t_0; //alpha_k+1 = alpha_k - KH*alpha_k
- P[1][1] -= K_1 * t_1;
-
-
- angle+= K_0 * angle_err;//后验估计 更新估计值作为最终结果
- q_bias+= K_1 * angle_err;//后验估计 更新bias的值
- angle_dot=gyro_m-q_bias;//输出值(后验估计)的微分 = 角速度
-
- // 卡尔曼滤波结束
- }
来源http://forum.eepw.com.cn/thread/264504/1
IMU加速度积分得到速度参考 : http://blog.csdn.net/me_sky_2012/article/details/31350909
数字信号处理:IIR滤波
单变量卡尔曼滤波:http://www.amobbs.com/thread-5475821-2-1.html