金牌会员
- 积分
- 2915
- 威望
- 1628
- 贡献
- 643
- 兑换币
- 264
- 注册时间
- 2012-1-15
- 在线时间
- 322 小时
|
qinlu123 发表于 2012-3-3 12:40
也不是
这个??
/***************************************************************************/
/* kalman.c */
/* 1-D 卡尔曼滤波算法, 通过加速度计(倾角)和陀螺仪完成 */
/* Author: Rich Chi Ooi */
/* Version: 1.0 */
/* Date:30.05.2003 */
/* 改编自 Trammel Hudson(hudson@rotomotion.com) */
/* ------------------------------- */
/* 程序编译: */
/* Linux */
/* gcc68 -c XXXXXX.c (to create object file) */
/* gcc68 -o XXXXXX.hex XXXXXX.o ppwa.o */
/* Upload data : */
/* ul filename.txt */
/***************************************************************************/
/* 本版内容: */
/***************************************************************************/
/* This is a free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published */
/* by the Free Software Foundation; either version 2 of the License, */
/* or (at your option) any later version. */
/* */
/* this code is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with Autopilot; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, */
/* MA 02111-1307 USA */
/***************************************************************************/
#include <math.h>
#include "eyebot.h"
/*
* 陀螺仪采样周期20ms
* 更新频率不同的话可以改变
*/
static const float dt = 0.02; //陀螺仪采样周期
/*
* 协方差矩阵.每次更新决定传感器跟踪实际状态的好坏
*/
static float P[2][2] = {{ 1, 0 }, //协方差矩阵
{ 0, 1 }};
/*
* 两个状态,角度和陀螺仪偏差.作为计算角度和偏差的副产品,我们可以得到无偏的角速率
* 以下是该模块对于作者的只读量
*/
float angle;
float q_bias;
float rate; //3个无偏输出量
/*
* R为测量协方差noise.R=E[vvT]
* 这种情况下为1×1矩阵
* 0.1 rad jitter from the inclinometer.
* for a 1x1 matrix in this case v = 0.1
*/
static const float R_angle = 0.001 ;
/*
* Q是2×2过程协方差矩阵噪声.
* 表示对加速度计和陀螺仪的信任程度
*/
static const float Q_angle = 0.001;
static const float Q_gyro = 0.0015;
/*
* 状态每次通过带有偏移量量的陀螺仪测量值进行更新。更新当前的角度和角速率
*
* 采集到的陀螺仪测量值应该转换为实际单位,但是不需要进行偏移补偿。滤波器会自动跟踪偏移量
*
* A = [ 0 -1 ]
* [ 0 0 ]
*/
void stateUpdate(const float q_m){
float q;
float Pdot[4];
/*去除陀螺仪偏差*/
q = q_m - q_bias;//当前角速度:测量值-偏差
/*
* Compute the derivative of the covariance matrix
* 计算协方差矩阵的导数
* (equation 22-1)
* Pdot = A*P + P*A' + Q
*/
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;
/*
* Update our angle estimate
* angle += angle_dot * dt
* += (gyro - gyro_bias) * dt
* += q * dt
*/
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; //why?
}
/*
* kalman_update在加速度计更新时由用户调用
* 不需要每次都调用,但加速度计采样频率和陀螺仪一样的话就可以
*
* H = [ 1 0 ]
*
* 因为角度测量直接符合角度估计而且角度测量和陀螺仪没有关联
*/
void kalmanUpdate(const float incAngle)
{
/* 估计角度测量值和测量偏差 */
float angle_m = incAngle;
float angle_err = angle_m - angle;//1.12 zk-H*xk_dot
/*
h_0表示状态估计值和状态量的相关程度
* H = [h_0 h_1]
*
* The h_1 shows that the state measurement does not relate
* to the gyro bias estimate. We don't actually use this, so
* we comment it out.
*/
float h_0 = 1;
/* const float h_1 = 0; */
/*
* 先验 P*H' 用到两次
*/
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*/
/*
* 估计误差:
* (equation 21-1)
* E = H P H' + R
*/
float E = R_angle +(h_0 * PHt_0);
/*
* 估计卡尔曼增益:
* (equation 21-2)
*
* K = P H' inv(E)
*/
float K_0 = PHt_0 / E;
float K_1 = PHt_1 / E;
/*
* 更新协方差矩阵:
* (equation 21-3)
*
* P = P - K H P
* Let
* Y = H P
*/
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;
/*
* 后验估计:
*
* Xnew = X + K * error
*
* err is a measurement of the difference in the measured state
* and the estimate state. In our case, it is just the difference
* between the inclinometer measured angle and the estimated angle.
*/
angle += K_0 * angle_err;
q_bias += K_1 * angle_err;
}
|
|