赞
踩
插值(interpolation) 平滑 (smoothing) | 用 过去 的数据来拟合 过去 的数据 |
滤波 (filtering) | 用 当前 和 过去 的数据来求取 当前 的数据 |
预测 (prediction) | 用 当前 和 过去 的数据来求取 未来 的数据 |
根据小车的运动方程、小车的属性,我们可以估计处小车在下一时刻的位置
小车运动过程中,会不断地收到噪声的影响,因而t=1时刻方差(不确定性)比t=0时刻还要大。
为了避免纯理论估计估计带来的偏差,在 t=1 时刻对小车的位置坐标进行一次测量,当然对小车距离的测量也会受到种种不确定因素的影响,所以小车t=1 时的测量位置服从蓝色的正态分布:
于是我们得到了两个不同的分布,都是来描述小车的位置的。那么应该怎么结合这两个分布呢?
卡尔曼滤波的作用是找一个权重,将二者加权平均,合并为绿色的正态分布。那个就是卡尔曼滤波的结果
注:这一小节的上下标和之后卡尔曼滤波的部分会有一定的差异
离散卡尔曼滤波器用于估计离散时间过程的状态变量 (小车的方向,速度等)
这个离散时间过程由以下离散随机差分方程描述:
估计的当前状态 | |
上一时刻的状态 | |
输入值 | |
噪声(满足正态分布) |
定义观测变量 (小车的位置),我们有:
当前时刻的观测变量 | |
当前状态变量 | |
噪声(和W独立,且也满足正态分布) |
更新方程如下:
( − 代表先验,
^ 代表估计)
已知第 k 步以前状态情况下,第 k 步的先验状态估计 知道测量变量之后,第k-1步的后验状态估计
(第k-1步 卡尔曼滤波的结果)
F(后面的A)
- 将上一时刻k−1 的状态变量 线性映射到当前时刻 k 的状态转换矩阵
- 实际中 F应随时间变化,这里假设为常数。
B 控制输入矩阵,假设为常数 输入值 P−k 先验协方差 ——>通过时间更新方程,我们得到k时刻 状态变量的先验估计(均值) 和先验协方差估计
记先验和后验估计的误差为
于是先验和后验估计的协方差矩阵为
我们接下来推导
使用当前时刻的测量值来更正预测阶段估计值,得到当前时刻的后验估计值。
测量状态方程的顺序是:
如果 先验协方差估计趋近于0——>趋近于0
——>
上一时刻计算得到的后验估计被作为下一时刻计算的先验估计
令:
真实值x | -0.377 |
A(观测状态——>状态变量) | 1 |
H(状态变量——>测量值) | 1 |
R(测量噪声协方差) | 0.01 |
Q(过程激励噪声协方差(系统过程的协方差)) | 1e-5 |
- import numpy
- import pylab
- #导入库
-
- n_iter = 50
- sz = (n_iter,)
- x = -0.37727 # 真实值
- z = numpy.random.normal(x,0.1,size=sz)
- # 50个观测值 ,观测时存在噪声
- #n_iter个样本点
- xhat=numpy.zeros(sz)
- # x 滤波估计值 (后验)
-
- P=numpy.zeros(sz)
- # 滤波估计协方差矩阵 (后验)
-
- xhatminus=numpy.zeros(sz)
- # x 估计值 (先验)
-
- Pminus=numpy.zeros(sz)
- # 估计协方差矩阵 (先验)
-
- K=numpy.zeros(sz)
- # 卡尔曼增益
- Q = 1e-5
- # 过程激励噪声协方差
-
- xhat[0] = 0.0
- P[0] = 1.0
- R=0.01
- for k in range(1,n_iter):
- # 预测
- xhatminus[k] = xhat[k-1]
- #^X_k_=A^X_{k-1}+BU(k-1)
- #A=1, 这里没有输入,所以U= 0
-
- Pminus[k] = P[k-1]+Q
- #Pk_=AP_{k-1}A^T+Q
-
-
-
- # 更新
- K[k] = Pminus[k]/( Pminus[k]+R )
- #K(k)=Pk_H'/[HPk_H' + R]
- #H=1
-
- xhat[k] = xhatminus[k]+K[k]*(z[k]-xhatminus[k])
- #X_k = X_k_ + K(k)[Z(k) - HX_k_], H=1
-
- P[k] = (1-K[k])*Pminus[k]
- #Pk = (1 - K(k)H)Pk_, H=1
- pylab.figure()
- pylab.plot(z,'k+',label='noisy measurements')
- #观测值
- pylab.plot(xhat,'b-',label='a posteri estimate')
- #滤波估计值
- pylab.axhline(x,color='g',label='truth value')
- #真实值
- pylab.legend()
- pylab.xlabel('Iteration')
- pylab.ylabel('Voltage')
- from filterpy.kalman import KalmanFilter
- import numpy as np
-
-
- n_iter = 50
- sz = (n_iter,)
- x = -0.37727 # 真实值
- z = numpy.random.normal(x,0.1,size=sz)
- # 50个观测值 ,观测时存在噪声
- #n_iter个样本点
- kf = KalmanFilter(dim_x=1, dim_z=1)
- kf.F = np.array([1])
- kf.H = np.array([1])
- kf.R = np.array([0.1**2])
- kf.P = np.array([1.0])
- kf.Q = 1e-5
- xhat[0] = 0.0
- P[0] = 1.0
- for k in range(1,n_iter):
- kf.predict()
- xhat[k] = kf.x
- kf.update(z[k], 0.1**2, np.array([1]))
- pylab.figure()
- pylab.plot(z,'k+',label='noisy measurements')
- #观测值
- pylab.plot(xhat,'b-',label='a posteri estimate')
- #滤波估计值
- pylab.axhline(x,color='g',label='truth value')
- #真实值
- pylab.legend()
- pylab.xlabel('Iteration')
- pylab.ylabel('Voltage')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。