滤波系列(一)卡尔曼滤波算法(KF):应用

滤波系列(一)卡尔曼滤波算法的应用

在本文,将直接给出卡尔曼滤波算法的具体应用,如果想了解卡尔曼滤波算法的详细数学推导过程,请看博客:卡尔曼滤波算法的详细数学推导

KF的应用

目标的运动模型

举一个物体做匀速直线运动的例子:
物体的状态由位置和速度组成,定义为 X t = [ x t , v t ] T X_t=[x_t,v_t ]^T Xt=[xt,vt]T,根据匀速直线运动公式可知:

x t = x t − 1 + v t − 1 ∆ t + 1 2 a ∆ t 2 ( 1 ) x_t=x_{t-1}+v_{t-1} ∆t+\frac{1}{2} a∆t^2 \quad(1) xt=xt1+vt1t+21at2(1)

v t = v t − 1 + a Δ t ( 2 ) v_t=v_{t-1}+aΔt \quad(2) vt=vt1+aΔt(2)

这里我们将最后一项 1 2 a ∆ t 2 \frac{1}{2} a∆t^2 21at2 a Δ t aΔt aΔt考虑为系统模型不准确带来的噪声(注意 a a a是一个随机变量, Δ t Δt Δt是一个确定的时间间隔), a 2 ∼ N ( 0 , Q ) a^2\sim N(0,Q) a2N(0,Q),我们可以将上面的公式合并在一起:
X t = [ x t v t ] = [ 1 ∆ t 0 1 ] [ x t − 1 v t − 1 ] + [ 1 2 a ∆ t 2 a Δ t ] ( 3 ) X_t= \begin{bmatrix} x_t\\ v_t \\ \end{bmatrix}= \begin{bmatrix} 1&∆t\\ 0&1 \\ \end{bmatrix} \begin{bmatrix} x_{t-1}\\ v_{t-1} \\ \end{bmatrix}+ \begin{bmatrix} \frac{1}{2} a∆t^2\\ aΔt \\ \end{bmatrix} \quad (3) Xt=[xtvt]=[10t1][xt1vt1]+[21at2aΔt](3)

所以t时刻状态的均值为:
E [ X t ] = [ 1 ∆ t 0 1 ] [ x t − 1 v t − 1 ] = A X t − 1 ( 4 ) E[X_t ]=\begin{bmatrix} 1&∆t\\ 0&1 \\ \end{bmatrix} \begin{bmatrix} x_{t-1}\\ v_{t-1} \\ \end{bmatrix}=AX_{t-1}\quad (4) E[Xt]=[10t1][xt1vt1]=AXt1(4)

所以t时刻状态的方差为:
注:随机变量求方差公式 V [ X ] = E [ ( X − μ ) ( X − μ ) T ] V[X]=E[(X-μ) (X-μ)^T] V[X]=E[(Xμ)(Xμ)T]

V [ X t ] = E [ ( X t − E [ X t ] ) ( X t − E [ X t ] ) T ] ( 5 ) V[X_t ]=E[(X_t-E[X_t ]) (X_t-E[X_t ])^T] (5) V[Xt]=E[(XtE[Xt])(XtE[Xt])T](5)

V [ X t ] = E [ [ 1 2 a ∆ t 2 a ∆ t ] [ 1 2 a ∆ t 2 a ∆ t ] ] = E [ 1 4 a 2 ∆ t 4 1 2 a 2 ∆ t 3 1 2 a 2 ∆ t 3 a 2 ∆ t 2 ] = E [ a 2 ] [ 1 4 ∆ t 4 1 2 ∆ t 3 1 2 ∆ t 3 ∆ t 2 ] = Q [ 1 4 ∆ t 4 1 2 ∆ t 3 1 2 ∆ t 3 ∆ t 2 ] ( 6 ) V[X_t ]=E\left[ \begin{bmatrix} \frac{1}{2}a∆t^2\\ a∆t\\ \end{bmatrix} \begin{bmatrix} \frac{1}{2}a∆t^2&a∆t\\\end{bmatrix}\right] =E \begin{bmatrix} \frac{1}{4} a^2 ∆t^4&\frac{1}{2} a^2 ∆t^3\\ \frac{1}{2} a^2 ∆t^3&a^2 ∆t^2\\\end{bmatrix} \\=E[a^2 ] \begin{bmatrix} \frac{1}{4} ∆t^4&\frac{1}{2} ∆t^3\\ \frac{1}{2} ∆t^3&∆t^2\\\end{bmatrix} =Q\begin{bmatrix} \frac{1}{4} ∆t^4&\frac{1}{2} ∆t^3\\ \frac{1}{2} ∆t^3&∆t^2\\\end{bmatrix}\quad (6) V[Xt]=E[[21at2at][21at2at]]=E[41a2t421a2t321a2t3a2t2]=E[a2][41t421t321t3t2]=Q[41t421t321t3t2](6)

传感器的量测为 Y t = [ x t ] Y_t=[x_t ] Yt=[xt],量测方程为 H = [ 1 0 ] H=\begin{bmatrix}1&0\end{bmatrix} H=[10]
假设目标初始时刻的状态为 X 1 = [ 10 , 5 ] T X_1=[10,5]^T X1=[10,5]T、协方差矩阵为 P 0 = [ 10 5 5 10 ] P_0=\begin{bmatrix}10&5\\5&10\\\end{bmatrix} P0=[105510],采样时间间隔 ∆ t = 0.1 s ∆t=0.1s t=0.1s,传感器的量测噪声为 R = [ 1 ] R=[1] R=[1]。由此产生的仿真数据如下图:
在入图片描述

图1:目标的真实位置及量测

其中,蓝色的线表示加了噪声的量测数据,橘色的线表示真实的位置。
卡尔曼滤波步骤:
μ ˉ t = A μ ^ t − 1 ( 7 ) \bar{\mu}_t=A\hat{\mu}_{t-1} \quad(7) μˉt=Aμ^t1(7)

Σ ˉ t = A Σ ^ t − 1 A T + Q ( 8 ) \bar{\Sigma}_t=A\hat{\Sigma}_{t-1} A^T+Q \quad(8) Σˉt=AΣ^t1AT+Q(8)

K t = Σ ˉ t H T ( H Σ ˉ t H T + R ) − 1 ( 9 ) K_t=\bar{\Sigma}_t H^T (H\bar{\Sigma}_t H^T+R)^{-1}\quad (9) Kt=ΣˉtHT(HΣˉtHT+R)1(9)

μ ^ t = μ ˉ t + K t ( Y t − H μ ˉ t ) ( 10 ) \hat{\mu}_t=\bar{\mu}_t+K_t (Y_t-H\bar{\mu}_t) \quad (10) μ^t=μˉt+Kt(YtHμˉt)(10)

Σ ^ t = ( I − K t H ) Σ ˉ t ( 11 ) \hat{\Sigma}_t =(I-K_t H) \bar{\Sigma}_t \quad (11) Σ^t=(IKtH)Σˉt(11)

卡尔曼滤波代码

def kalmanfilter(A, H, Q, R, z, P, x):
    
    n = A.shape[1]
    #Predict
    x = np.dot(A, x)  #公式(7)
    P = multi_dot([A, P, A.T]) + Q #公式(8)
    #Update
    y = z - np.dot(H, x) 
    S = np.matrix(multi_dot([H, P, H.T])+R) 
    K = multi_dot([P, H.T, inv(S)]) #公式(9)
    x = x + np.dot(K, y) #公式(10)
    I = np.eye(n)
    P = np.dot(I - np.dot(K, H), P) #公式(11)
    
    return x,P

完整代码

import numpy as np
from numpy.linalg import multi_dot,inv
import matplotlib.pyplot as plt
np.random.seed(2)

def kalmanfilter(A, H, Q, R, z, P, x):
    
    n = A.shape[1]
    #Predict
    x = np.dot(A, x) 
    P = multi_dot([A, P, A.T]) + Q
    #Update
    y = z - np.dot(H, x)
    S = np.matrix(R + multi_dot([H, P, H.T]))
    K = multi_dot([P, H.T, inv(S)])
    x = x + np.dot(K, y)
    I = np.eye(n)
    P = np.dot(I - np.dot(K, H), P)
    
    return x,P
                 	
def demo():
    
    dt = 0.1
    F = np.array([[1, dt], [0, 1]])
    H = np.array([1, 0]).reshape(1,2)
    Q = 1e-2*np.array([[1/4*dt**4, 1/2*dt**3], [1/2*dt**3, dt**2]])
    R = 2
    itr  = 100
    
    real_state = []
    x = np.array([10,5]).reshape(2,1)
    
    for i in range(itr):
        real_state.append(x[0,0])
        x = np.dot(F,x)+np.random.multivariate_normal(mean=(0,0),cov=Q).reshape(2,1)
    
    measurements = [x+np.random.normal(0,R) for x in real_state]
    
    # initialization
    P = np.array([[10,5],[5,10]])
    x=np.random.multivariate_normal(mean=(10,5),cov=P).reshape(2,1)
    
    #filter
    filter_result=list()
    filter_result.append(x)
    for i in range(1,itr):
        x,P = kalmanfilter(F, H, Q, R, measurements[i],P,x)
        filter_result.append(x)
    filter_result=np.squeeze(np.array(filter_result))
    
    return measurements,real_state,filter_result

def plot_result(measurements,real_state,filter_result):
    
    plt.figure(figsize=(8,4))
    plt.plot(range(1,len(measurements)), measurements[1:], label = 'Measurements')
    plt.plot(range(1,len(real_state)), real_state[1:], label = 'Real statement' )
    plt.plot(range(1,len(filter_result)), np.array(filter_result)[1:,0], label = 'Kalman Filter')
    plt.legend()
    plt.xlabel('Time',fontsize=14)
    plt.ylabel('velocity [m]',fontsize=14)
    plt.show()
    
    plt.figure(figsize=(8,4))
    plt.axhline(5, label='Real statement') #, label='$GT_x(real)$'
    plt.plot(range(1,len(filter_result)), np.array(filter_result)[1:,1], label = 'Kalman Filter')
    plt.legend()
    plt.xlabel('Time',fontsize=14)
    plt.ylabel('velocity [m]',fontsize=14)
    plt.show()

if __name__ == '__main__':
    
    measurements,real_state,filter_result=demo()
    plot_result(measurements,real_state,filter_result)

滤波后的结果如下图所示,图2表示目标位置的滤波结果,从图中可直观发现经过卡尔曼滤波后,消除了量测数据中的噪声,得到了更精确的目标位置;图3表示目标速度的滤波结果,从中可以发现经过卡尔曼滤波后,速度的估计越来越精确且逐渐收敛到了真实的速度 v = 5 m / s v=5m/s v=5m/s

在这里插入图片描述

图2:目标位置的滤波结果

在这里插入图片描述

图3:目标速度的滤波结果

KF的调试

1.状态转移方程( μ ˉ t \bar{\mu}_t μˉt = A =A =A μ ^ t − 1 \hat{\mu}_{t-1} μ^t1)的建立
对一个系统的过程建模的越准确,意味着通过状态转移得到的状态越可靠,这样过程噪声Q要相对更小些。相反如果对系统的过程不太清楚,那么选择的状态转移模型就会不准确,所以要更相信测量值,要把过程噪声Q相对调大些。如果状态转移模型很不准确但是过程噪声设的非常小,那么卡尔曼滤波算法性能将严重下降甚至发散。
2. 系统的过程噪声 Q
系统的过程噪声 Q 越大,预测的状态协方差 Σ ˉ t \bar{\Sigma}_t Σˉt = A =A =A Σ ^ t − 1 A T \hat{\Sigma}_{t-1} A^T Σ^t1AT+Q )就越大,卡尔曼增益 K t K_t Kt 越大,观测的权重越大,预测的状态的权重越小,表示越相信观测,越不相信状态转移过程,这时卡尔曼滤波算法对量测的变化响应快,但是越不容易收敛。

K t = Σ ˉ t H T ( H Σ ˉ t H T + R ) K_t=\frac{\bar{\Sigma}_t H^T }{(H\bar{\Sigma}_t H^T+R)} Kt=(HΣˉtHT+R)ΣˉtHT

μ ^ t = μ ˉ t + K t ( Y t − H μ ˉ t ) = ( I − K t H ) μ ˉ t + K t Y t \hat{\mu}_t=\bar{\mu}_t+K_t (Y_t-H\bar{\mu}_t)=(I-K_t H)\bar{\mu}_t+K_t Y_t μ^t=μˉt+Kt(YtHμˉt)=(IKtH)μˉt+KtYt

反之,系统的过程噪声 Q 越小,表示越相信预测的状态,越不相信观测,这是系统状态越容易收敛,对观测的变化响应越慢。
3.量测噪声 R
首先,传感器的量测越不准确当然量测噪声 R 越大,卡尔曼增益 K t K_t Kt 越小,预测的状态的权重越大,量测的权重越小,表示越相信预测的状态,越不相信量测,这是系统状态越容易收敛,对观测的变化响应越慢。

参考资料

卡尔曼滤波算法的详细数学推导

相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页