|
本帖最后由 caicaptain2 于 2022-3-11 10:06 编辑
最近研究了一下卡尔曼滤波,参考了网上的几个文章,比如这个https://www.cnblogs.com/guiguzhixing/p/5930003.html
想实现一个简单的单个测量值的卡尔曼滤波。 根据这个文章的做法,发现了一些问题。
- //标量卡尔曼滤波
- typedef struct {
- float x; // 系统的状态量
- float A; // x(n)=A*x(n-1)+u(n),u(n)~N(0,q) 常规实现中,固定为1
- float H; // z(n)=H*x(n)+w(n),w(n)~N(0,r) 常规实现中,固定为1
- float q; // 预测过程噪声协方差
- float r; // 测量过程噪声协方差
- float p; // 估计误差协方差
- float gain;//卡尔曼增益
- } KalmanStructTypedef;
- /**
- *@function: - 卡尔曼滤波器
- *@kalmanFilter:卡尔曼结构体
- *@newMeasured;测量值
- *返回滤波后的值 */
- float kalmanFilter_filter(KalmanStructTypedef *kalmanFilter, float newMeasured)
- {
- /* Predict */
- kalmanFilter->x = kalmanFilter->x; //%x的先验估计由上一个时间点的后验估计值和输入信息给出
- kalmanFilter->p = kalmanFilter->p + kalmanFilter->q; /*计算先验均方差 p(n|n-1)=A^2*p(n-1|n-1)+q */
- /* Correct */
- kalmanFilter->gain = kalmanFilter->p / (kalmanFilter->p + kalmanFilter->r);
- kalmanFilter->x = kalmanFilter->x + kalmanFilter->gain * (newMeasured - kalmanFilter->x); //利用残余的信息改善对x(t)的估计,给出后验估计,这个值也就是输出
- kalmanFilter->p = (1 - kalmanFilter->gain) * kalmanFilter->p; //%计算后验均方差
- return kalmanFilter->x;
- }
复制代码
这个函数运行时,使用固定的预测方差q和测量方差r,经过十几次滤波后,卡尔曼增益会成为固定的值,从而失去了滤波效果。 卡尔曼增益收敛为固定值后,比如0.01,意义就是,每次测量值的偏差都被强制缩小100倍,那么,很难根据测量数据变化的快慢大小,来动态反应输出结果。
所以,这应该是错误的卡尔曼滤波。
那么,哪位能提供一个卡尔曼滤波函数参考一下?
|
|