卡尔曼滤波器原理说明

一、原理
1.通过观测一个运动系统的输入输出,综合考虑运动误差(假定是高斯分布)和观测误差(假定为高斯分布),来预测系统的真实状态:
在这里插入图片描述

图1 误差融合的示意图
二、参数说明
卡尔曼滤波器共有6个参数,其中有4个是初始化后即固定不变参数,两个是描述系统状态的参数:

'A:',kalman.transitionMatrix(转化矩阵,将当前时刻的Xk转化为下一时刻的Xk+1,初始化后不变)
'H:',kalman.measurementMatrix(观测矩阵,将系统状态X转化为观测值的矩阵,初始化后不变)
'Q:',kalman.processNoiseCov(过程误差协方差矩阵,表示在系统运行过程时的误差程度,值越高表示误差越大,初始化后不变)
'R:',kalman.measurementNoiseCov(观测误差协方差矩阵,表示观测值的误差程度,值越高表示越不信任观测值,初始化后不变)
'P:',kalman.errorCovPost(状态协方差矩阵,用于描述系统状态中各个变量的相关性,根据系统状态不断更新)
'X:',kalman.statePost(状态矩阵,根据系统状态不断更新)
其中X和P是表示系统状态的参数,每预测和更新时都会更新一次。

三、实例分析
一个小车在直线上行驶,这时我们使用kalmanFilter对它进行预测。
首先,描述小车的状态,我们使用【距离原点的长度Position,小车运行速度velocity】两个变量,其中Position是可以通过测量的时候得到的,velocity则是一个隐藏的变量,这样的话:
在这里插入图片描述

其中k代表时间。
第二步:预测小车下一刻的位置和状态,由于知道了小车的位置和速度,所以可以预测下一刻的位置,那么如何做到这个呢,就需要我们的转化矩阵A:
在这里插入图片描述

即:
在这里插入图片描述

这里的Fk就是参数定义里的A,由上面的定义得知P是X的协方差矩阵,所以由:
在这里插入图片描述

得到:
在这里插入图片描述

但是系统的运行总是不会是完全精准的,所以,小车的位置可能会偶然向前一些或者向后一些,这里的误差用高斯分布矩阵Q来描述,例如知道小车制动性能很好,那么误差会较低,可以设Q为波峰很高分布很窄的高斯分布。那么,加上Q的话,公式则会变成:
在这里插入图片描述

至此,我们的两个需要变化的参数已经更新完成,这里的Xk和Pk就是由k-1时刻通过系统状态推测出来的k时刻的小车的位置速度以及对应的协方差矩阵,其实还有可能会有外力作用,这时需要加上控制变量C,但是为了系统简洁,这里假设没有外力作用。
第三步:更正小车的状态,这时我们知道了预测的k时刻的X和P,但是小车的速度不是一尘不变的,在k时刻我们使用测量仪器进行测量,测量结果为zmeasured,这里的z为小车的测量距离,但是我们预测出来的状态X有两个变量,这里就需要H矩阵来进行转化,我们预测的结果是:
在这里插入图片描述

这里的Zexcepted是预测出来的,预测时的系统误差高斯分布矩阵Q,预测的可能位置分布如下图中的青色线,同时我们测量结果为Zmeasured,测量结果是使用测量仪器测量出来的,也有一定的误差,这里的误差使用高斯分布矩阵R来表示,测量仪器一般较为精准,所以测量误差的高斯分布较为集中,波峰高范围小,这里的实际测量位置分布如下图的粉红色线。将这两个分布进行相乘便得到我们更正后的小车运行系统的状态了,也就是波峰最小,范围最小的绿色线,这个绿色线的分布就是所谓的卡尔曼增益K:
在这里插入图片描述

这个过程使用公式表示如下:
在这里插入图片描述

其中代表高斯分布过程误差协方差矩阵与高斯分布测量误差协方差矩阵与状态协方差矩阵,代表矫正后系统状态,代表预测时系统状态,为测量出的系统状态。
至此系统状态和协方差矩阵两个参数均已矫正更新。

四、代码详解

void KalmanFilter::init(int DP, int MP, int CP, int type)
{
	statePre = Mat::zeros(DP, 1, type);   //预测状态
	statePost = Mat::zeros(DP, 1, type);   //当前状态X
	transitionMatrix = Mat::eye(DP, DP, type);   //转化矩阵A
	processNoiseCov = Mat::eye(DP, DP, type);   //过程误差矩阵Q
	measurementMatrix = Mat::zeros(MP, DP, type);  //观测转化矩阵H
	measurementNoiseCov = Mat::eye(MP, MP, type);  //观测误差协方差矩阵R
	errorCovPre = Mat::zeros(DP, DP, type);   //预测状态协方差矩阵
	errorCovPost = Mat::zeros(DP, DP, type);  //当前状态协方差矩阵P
	gain = Mat::zeros(DP, MP, type);  //卡尔曼增益K,计算时自动生成
	if (CP > 0)
	controlMatrix = Mat::zeros(DP, CP, type);  //控制变量矩阵,暂用不到
	else
	controlMatrix.release();
	temp1.create(DP, DP, type);
	temp2.create(MP, DP, type);
	temp3.create(MP, MP, type);
	temp4.create(MP, DP, type);
	temp5.create(MP, 1, type);
}

const Mat &KalmanFilter::predict(const Mat &control)
{
	// update the state: x'(k) = A*x(k)
	statePre = transitionMatrix * statePost;
	
	if (!control.empty())
	// x'(k) = x'(k) + B*u(k)
	statePre += controlMatrix * control;
	
	// update error covariance matrices: temp1 = A*P(k)
	temp1 = transitionMatrix * errorCovPost;
	
	// P'(k) = temp1*At + Q
	gemm(temp1, transitionMatrix, 1, processNoiseCov, 1, errorCovPre, GEMM_2_T);
	
	// handle the case when there will be measurement before the next predict.
	statePre.copyTo(statePost);
	errorCovPre.copyTo(errorCovPost);
	
	return statePre;
}

const Mat &KalmanFilter::correct(const Mat &measurement)
{
	// temp2 = H*P'(k)
	temp2 = measurementMatrix * errorCovPre;
	// temp3 = temp2*Ht + R
	gemm(temp2, measurementMatrix, 1, measurementNoiseCov, 1, temp3, GEMM_2_T);
	// temp4 = inv(temp3)*temp2 = Kt(k)
	solve(temp3, temp2, temp4, DECOMP_SVD);
	// K(k)
	gain = temp4.t();
	// temp5 = z(k) - H*x'(k)
	temp5 = measurement - measurementMatrix * statePre;
	// x(k) = x'(k) + K(k)*temp5
	statePost = statePre + gain * temp5;
	// P(k) = P'(k) - K(k)*temp2
	errorCovPost = errorCovPre - gain * temp2;
	
	return statePost;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
卡尔曼滤波器的参数辨识是指确定卡尔曼滤波器中的各个参数的过程。根据引用中的代码和引用中的说明,可以看出卡尔曼滤波器的参数包括初始状态量x、状态转移矩阵A、测量矩阵H、预测噪声协方差q、测量噪声协方差r、估计误差协方差p和卡尔曼增益gain。这些参数的选择对于卡尔曼滤波器的性能至关重要。 参数辨识的过程通常是根据实际应用场景进行的。一种常用的方法是通过系统建模和数据拟合来确定参数的。首先需要根据实际情况选择合适的状态量、测量量以及系统动态方程,然后利用已有的数据进行参数辨识。常见的方法包括最小二乘法、最大似然估计等。 在卡尔曼滤波器中,初始状态量x和估计误差协方差p可以根据实际情况进行选择,通常是根据系统的先验知识或经验来确定。而状态转移矩阵A、测量矩阵H、预测噪声协方差q和测量噪声协方差r则需要通过参数辨识来确定。 具体的参数辨识方法和步骤可以根据实际情况进行选择。一般情况下,需要收集一定的实验数据,然后根据实验数据进行参数辨识并进行模型优化,以得到最佳的参数组合。 需要注意的是,参数辨识是一个复杂的过程,需要充分理解系统的特性和数据的特点,并结合实际应用场景进行合理选择。同时,参数辨识可能需要多次迭代和调整,以得到最优的参数组合。因此,在实际应用中需要进行实时监测和调整,以保证卡尔曼滤波器的性能和稳定性。 综上所述,卡尔曼滤波器的参数辨识是通过实验数据和系统建模来确定各个参数的过程,需要根据实际情况进行选择和优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [kalman滤波(一)---对各参数的理解](https://blog.csdn.net/qq_36191395/article/details/104490791)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值