Kalman實際應用總結

理論部分不詳細說明,網上大部分都給出很好的解釋python

網上大部分都是理論和簡單的例子,不多看到實戰的信息git

本博文是筆者實際使用的總結,若有錯誤,請不吝指教github

Kalman理論介紹

一. 簡單理論介紹理論

二. 昇華理論介紹

Kalman基本應用

一. Kalman跟蹤/濾波

對單個數據濾波,沒法創建運動學模型算法

經過創建和自身相關的狀態方程便可app

是一種平滑操做(上一時刻和當前時刻的關係)dom

舉例:機器學習

對一個平面運動的質點進行跟蹤(\(X、Y\))?ide

  • 速度,加速度,角速度$v、\alpha,\omega $都是未知狀態

求解:學習

fig = plt.figure()
axis = fig.add_subplot(1,1,1)

func_data = lambda x : x + x^2
z = np.mat(func_data(np.arange(1,100)))
x_mat = np.mat([[0,],[0.]])#狀態矩陣[x,delta_x]
p_mat = np.mat([[1, 0], [0, 1]])#狀態協方差矩陣
f_mat = np.mat([[1, 1],[0.,1.]])#狀態轉移矩陣
q_mat = np.mat([[0.0001, 0], [0, 0.0001]])
h_mat = np.mat([1.,0])# 觀測矩陣[x]
r_mat = np.mat([1])#觀測協方差矩陣
result = []
for i in range(z.shape[1]):
    x_predict = f_mat * x_mat
    p_predict = f_mat * p_mat * f_mat.T + q_mat
   
    kalman = p_predict * h_mat.T / (h_mat * p_predict * h_mat.T + r_mat)  
    
    x_mat = x_predict + kalman *(z[0, i] - h_mat * x_predict)
    p_mat = (np.eye(2) - kalman * h_mat) * p_predict
    result.append(x_predict[0,0])

axis.plot(result,label='predict')
axis.plot(z.tolist()[0],label='groundtruth')
axis.legend()

二. Kalman預測/融合(單傳感器)

  • [x] 運動學模型
  • [x] 單一傳感器
  • [x] 速度$、,v、\alpha,\omega $推導可知

舉例一:

一個運動小車的位置和速度的測量等信息能夠被測量(一個傳感器),也能夠經過牛頓運動學方程進行解算,這兩個到底誰佔的比例高?使用Kalman的協方差矩陣進行比例的計算。。。。具體看文檔

舉例二:

import numpy as np
import matplotlib.pyplot as plt

def kalman_xy(x, P, measurement, R,
              motion = np.matrix('0. 0. 0. 0.').T,
              Q = np.matrix(np.eye(4))):
    """
    Parameters:    
    x: initial state 4-tuple of location and velocity: (x0, x1, x0_dot, x1_dot)
    P: initial uncertainty convariance matrix
    measurement: observed position
    R: measurement noise 
    motion: external motion added to state vector x
    Q: motion noise (same shape as P)
    """
    return kalman(x, P, measurement, R, motion, Q,
                  F = np.matrix('''
                      1. 0. 1. 0.;
                      0. 1. 0. 1.;
                      0. 0. 1. 0.;
                      0. 0. 0. 1.
                      '''),
                  H = np.matrix('''
                      1. 0. 0. 0.;
                      0. 1. 0. 0.'''))

def kalman(x, P, measurement, R, motion, Q, F, H):
    '''
    Parameters:
    x: initial state
    P: initial uncertainty convariance matrix
    measurement: observed position (same shape as H*x)
    R: measurement noise (same shape as H)
    motion: external motion added to state vector x
    Q: motion noise (same shape as P)
    F: next state function: x_prime = F*x
    H: measurement function: position = H*x

    Return: the updated and predicted new values for (x, P)

    See also http://en.wikipedia.org/wiki/Kalman_filter

    This version of kalman can be applied to many different situations by
    appropriately defining F and H 
    '''
    # UPDATE x, P based on measurement m    
    # distance between measured and current position-belief
    y = np.matrix(measurement).T - H * x
    S = H * P * H.T + R  # residual convariance
    K = P * H.T * S.I    # Kalman gain
    x = x + K*y
    I = np.matrix(np.eye(F.shape[0])) # identity matrix
    P = (I - K*H)*P

    # PREDICT x, P based on motion
    x = F*x + motion
    P = F*P*F.T + Q

    return x, P

def demo_kalman_xy():
    x = np.matrix('0. 0. 0. 0.').T 
    P = np.matrix(np.eye(4))*1000 # initial uncertainty

    N = 20
    true_x = np.linspace(0.0, 10.0, N)
    true_y = true_x**2
    observed_x = true_x + 0.05*np.random.random(N)*true_x
    observed_y = true_y + 0.05*np.random.random(N)*true_y
    plt.plot(observed_x, observed_y, 'ro')
    result = []
    R = 0.01**2
    for meas in zip(observed_x, observed_y):
        x, P = kalman_xy(x, P, meas, R)
        result.append((x[:2]).tolist())
    kalman_x, kalman_y = zip(*result)
    plt.plot(kalman_x, kalman_y, 'g-')
    plt.show()

demo_kalman_xy()

這部分比較簡單,網上的例子大部分都是基於此的。。。

三. Kalman多傳感器融合A

  • [x] 運動學模型
  • [x] 多個傳感器
  • [x] 傳感器時間序列不一樣

舉例:

以汽車跟蹤爲例,目標是知道汽車時刻的狀態\(x=(p_x,p_y,v_x,v_y)\)\(x=(p_x,p_y,v_x,v_y)\)

已知的傳感器有\(、lidar、radar\)

\(lidar\):笛卡爾座標系。可檢測到位置,沒有速度信息。其測量值\(z=(px,py)z=(px,py)\)

\(radar\):極座標系。可檢測到距離,角度,速度信息,可是精度較低。其測量值\(z=(ρ,ϕ,ρ˙)z=(ρ,ϕ,ρ˙)\)

這是優達學城的一個例子,具體我也沒視頻網址。

\(matlab\)代碼地址在這裏\(python\)代碼在這裏

注意:

​ 這裏至關於創建了兩個模型,一個線性模型,一個非線性模型,在不一樣的時刻使用不一樣的傳感器進行更新

​ 其實就是單個傳感器合併到一塊兒了。。。。

四. Kalman多傳感器融合B

  • [ ] 無運動學模型
  • [x] 多傳感器
  • [x] 傳感器時序相同

舉例:

一個小車作不均則運動(速度、加速度、角速度等都是可變的),如今有兩個傳感器:儀器A儀器B,他們都能測量 \(\omega\)\(v\) ,那麼如何進行融合兩個傳感器呢?

  • 具體的代碼這裏不方便給出,有須要能夠一塊兒討論

這裏其實和Kalman的濾波比較相似,就是把兩個傳感器當作一個傳感器的不一樣時間序列 \(T_1,T_2\) 時刻測量的數據,而後濾波操做。

五. Kalman多傳感器融合C

  • [ ] 無運動學模型
  • [x] 多傳感器
  • [x] 傳感器時序相同

條件和Kalman多傳感器融合B相同,單處理方式不一樣

因爲部分傳感器精度不一樣,進行特定的取捨頗有必要(親身經歷

假設求取小車的 \(\omega\)\(v\)

傳感器A對\(\omega\) 測量較爲準確

傳感器B對 \(v\) 測量較爲準確

解決:

其實咱們若是直接按照Kalman多傳感器融合B進行操做的話,偏差基本不會縮小,可能還會增長

這個時候筆者的解決方案是把傳感器A和B當作一個總體傳感器C,傳感器C測量的 \(\omega\) 是A的,測量的 \(v\) 是B的

那麼咱們就把這個合起來的傳感器C進行濾波就好了

實測可用。。。

六. Kalman多傳感器融合D

  • [x] 運動學模型
  • [x] 多傳感器
  • [x] 傳感器時序相同

看到網上不少人問這個問題,這裏筆者沒有親自實現,只是作了猜測,不正確還望讀者指正

解決:

因爲卡爾曼只能一次融合兩個信息(預測和觀測),因此只能進行以下想法

  1. 進行兩次融合,一次是預測和傳感器A,一次結果和傳感器B(這部分就是多傳感器B
  2. 進行一次融合,預測和新的傳感器C(Kalman多傳感器融合C

七. Extend Kalman

  • 運動學模型不是線性的
  • 使用雅克比代替狀態矩陣觀測矩陣

注意:

筆者認爲這種狀況比較少見,由於 \(t\) 趨向於 \(\epsilon\) ,因此能夠認爲在無窮小的區間都近似於很恆定的

實在沒辦法的時候就使用EKF,原理都很簡單,計算代價大許多

後續可使用UKF進行操做,這部分筆者還何嘗試

本文總結

最後來個簡單的總結,什麼是卡爾曼\(K\)

兩個相同信息:A 和 B

都知足\(y=kx+b\)

那麼如何獲得 \(y\) ?

正常來講:\(y=(A+B)/2*x+b\)

可是好像不是很是好,這個\((A+B)/2\)老是不變的,假如他們某個時刻佔比改變了呢?

這個時候\(Kalman\)的做用的體現了,他計算A和B的關係(看公式吧)

得出一個係數 \(K\) 這個\(K\) 和A、B相關

此時:\(y=K*x+b\)

輸入的A、B不一樣,那麼\(K\)也不一樣

完畢!!!

相關文章
相關標籤/搜索