【教程】卡尔曼滤波的详解与C语言实现

一、什么是卡尔曼滤波

卡尔曼滤波(Kalman filtering)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。
数据滤波是去除噪声还原真实数据的一种数据处理技术,Kalman滤波在测量方差已知的情况下能够从一系列存在测量噪声的数据中,估计动态系统的状态。由于它便于计算机编程实现,并能够对现场采集的数据进行实时的更新和处理,Kalman滤波是目前应用最为广泛的滤波方法,在通信,导航,制导与控制等多领域得到了较好的应用。

二、如何理解 卡尔曼滤波

在理解卡尔曼之前我们先讲个故事,比如现在我们要测一个房间的温度,那么我们需要一个温度计。假设市场上买两种温度计,一种测得温度非常准没有误差。另一种只能大概测量。当然测得准的温度计,比较贵,另外一个比较便宜。如果你是土豪那么你可以买比较贵的就是没有误差的,那么你就跟卡尔曼没有故事了。
现在假设你是一个中等屌丝,你可以卖得起两个破的温度计,现在两个温度计测量得到两个值,我们假设他一个是23度,一个是25度,那么实际应该是多少度呢。如果你对他们求平均(即权值是0.5,0.5),你会得到24度左右。再说的明确一点呢24±1度,应为这个是你猜的,所以你不能肯定,那么这个1度就是你的不确定度。可能你是天蝎座的,比较偏心,不想然两个温度计都雨露均沾,我们假设你比较相信前一个温度计,不相信另一个,这里我们取权值为(0.7,0.3),那么你得到的温度值就是0.7*23+0.3*25=23.6度,那么不确定度可能是1(感觉自己偏心的有道理,猜的比较准),可能是6度(这个6是随便写的,猜的不准误差比较大)。根据上面这个问题我们发现
1.不确定我们猜的准不准,换句话来说就是不确定度不知道多少
2.权值该怎么取才合理
省略1W字。。。。。。。
更多请查看:https://blog.csdn.net/CBQ5789789/article/details/78858160

---------------------------------------------

最近做的项目用到iPhone收集的蓝牙信号强度,即RSSI值。发现果然如文献中所说,即使手机保持静止,检测到的来自同一蓝牙信标的信号强度也会不停地上下波动,且数据(滤除粗大误差后)呈高斯分布。许多文献中也提到,对付这样的噪声可以用卡尔曼滤波器。同样地,做自平衡车、四旋翼等用到的陀螺仪、加速度数据也常常用到卡尔曼滤波

省略1W字。。。。。。。
更多请查看:https://www.jianshu.com/p/c512a2b82907

---------------------------------------------

https://blog.csdn.net/von_kent/article/details/76610952

---------------------------------------------

三、C语言实现 卡尔曼滤波

/*
 ============================================================================
 Name        : KaerMan.c
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>



static double p_last = 0;
static double x_last = 0;

//过程噪音   买的破温度计有多破。。
#define P_Q 0.1
//测量噪声
#define M_R 0.01
/*
        Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏
        R:测量噪声,R增大,动态响应变慢,收敛稳定性变好

        其中p的初值可以随便取,但是不能为0(为0的话卡尔曼滤波器就认为已经是最优滤波器了)
q,r的值需要我们试出来,讲白了就是(买的破温度计有多破,以及你的超人力有多强)

r参数调整滤波后的曲线与实测曲线的相近程度,r越小越接近。

q参数调滤波后的曲线平滑程度,q越小越平滑。

*/
static double KalmanFilter(const double ResrcData)
{

    double R = M_R;
    double Q = P_Q;

    double x_mid = x_last;
    double x_now;

    double p_mid ;
    double p_now;

    double kg;

    //这里p_last 等于 kalmanFilter_A 的p直接取0
    x_mid=x_last;                       //x_last=x(k-1|k-1),x_mid=x(k|k-1)
    p_mid=p_last+Q;                     //p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声

    /*
      *  卡尔曼滤波的五个重要公式
      */
    kg=p_mid/(p_mid+R);                 //kg为kalman filter,R 为噪声
    x_now=x_mid+kg*(ResrcData-x_mid);   //估计出的最优值
    p_now=(1-kg)*p_mid;                 //最优值对应的covariance
    p_last = p_now;                     //更新covariance 值
    x_last = x_now;                     //更新系统状态值

    return x_now;
}

float kalmanFilter_A(float inData)
{
  static float prevData=0;
  //其中p的初值可以随便取,但是不能为0(为0的话卡尔曼滤波器就认为已经是最优滤波器了)
  static float p=0.01, q=P_Q, r=M_R, kGain=0;
    p = p+q;
    kGain = p/(p+r);

    inData = prevData+(kGain*(inData-prevData));
    p = (1-kGain)*p;

    prevData = inData;

    return inData;
}

int main(void) {
	double datas[] = {99, 33, 45, 99, 100, 24};
	int len = sizeof(datas)/ sizeof(datas[0]);

	for(int i = 0; i < len; i++){
		printf("datas[i]=%lf, number=%lf, %f\n", datas[i], KalmanFilter(datas[i]), kalmanFilter_A(datas[i]));
	}

	return 0;
}

我这里摘录了两种不同写法的卡尔曼的实现代码。(实现都相同,写法不同。结果不同,因为p的取值不同

运行结果为:

datas[i]=99.000000, number=90.000000, 90.750000
datas[i]=33.000000, number=37.786260, 37.846153
datas[i]=45.000000, number=44.394619, 44.399647
datas[i]=99.000000, number=94.417504, 94.417923
datas[i]=100.000000, number=99.531516, 99.531548
datas[i]=24.000000, number=30.338621, 30.338623

 

 

### 回答1: 卡尔曼滤波算法是一种用于组合估计的算法,其目的是通过将传感器测量值与系统预测值进行加权平均,得到更准确的状态估计值。 卡尔曼滤波算法通过两个主要步骤实现:预测和更新。在预测步骤中,通过使用系统的动力学模型和先前状态的估计值,计算下一时刻的状态预测值和协方差矩阵。在更新步骤中,通过将传感器测量值与预测值进行对比,计算优化的状态估计值和协方差矩阵。 卡尔曼滤波算法的核心是协方差矩阵的更新,通过这个矩阵可以反映系统的状态估计的可信度,进而在预测和更新中进行权衡。卡尔曼滤波算法对噪声的建模也非常重要,通过对预测和更新中的噪声进行合理的建模,可以更准确地估计系统的状态。 在C语言实现卡尔曼滤波算法,需要使用矩阵运算和协方差矩阵的计算。可以通过定义结构体或数组来表示矩阵和向量,并使用相应的运算函数进行矩阵运算。同时,需要根据系统的动力学模型和传感器的特性,进行相应的参数配置和计算。 在实现中,首先需要初始化协方差矩阵和状态估计值。然后,在每个时间步骤中,根据系统的动力学模型进行状态预测,并计算预测的协方差矩阵。接着,根据传感器的测量值,计算卡尔曼增益,用于将预测值和测量值进行加权平均得到最终的状态估计值。最后,更新协方差矩阵。 实现卡尔曼滤波算法需要一定的数学知识和编程技巧。同时,需要根据具体的应用场景和系统特性进行参数的调整和优化,以获得更好的滤波效果。 ### 回答2: 卡尔曼滤波算法是一种用于估计线性系统状态的优化算法。它通过融合传感器的测量数据和系统模型,提供对系统状态的最优估计。卡尔曼滤波算法的核心思想是在每个时间步更新状态的估计,并同时计算估计的不确定性。 卡尔曼滤波算法的过程如下: 1. 初始化:给定系统的初始状态和初始不确定性。 2. 预测:根据系统模型,使用先前的状态估计和控制输入来预测当前状态的估计和不确定性。 3. 更新:通过融合传感器的测量数据和预测得到的状态估计,计算更新后的状态估计和不确定性。 在C语言实现卡尔曼滤波算法,需要定义系统模型、传感器模型和卡尔曼滤波算法的具体计算过程。首先,需要定义状态向量、状态转移矩阵、控制输入矩阵、观测向量和观测矩阵等系统模型参数。然后,可以利用这些参数实现卡尔曼滤波算法的预测和更新过程。预测过程中,根据系统模型和先前的状态估计,计算当前状态的预测估计和预测不确定性。更新过程中,利用传感器的测量数据和预测得到的状态估计,计算最优的状态估计和不确定性。最后,通过迭代进行多次预测和更新,即可得到系统状态的最优估计。 总结来说,卡尔曼滤波算法是一种用于估计线性系统状态的优化算法,通过融合传感器的测量数据和系统模型,提供对系统状态的最优估计。在C语言实现卡尔曼滤波算法,需要定义系统模型和实现卡尔曼滤波算法的预测和更新过程。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江西省遂川县常驻深圳大使

喜欢本文,打赏下作者吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值