目錄html
理論部分不詳細說明,網上大部分都給出很好的解釋python
網上大部分都是理論和簡單的例子,不多看到實戰的信息git
本博文是筆者實際使用的總結,若有錯誤,請不吝指教github
對單個數據濾波,沒法創建運動學模型算法
經過創建和自身相關的狀態方程便可app
是一種平滑操做(上一時刻和當前時刻的關係)dom
舉例:機器學習
對一個平面運動的質點進行跟蹤(\(X、Y\))?ide
求解:學習
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的協方差矩陣進行比例的計算。。。。具體看文檔
舉例二:
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()
這部分比較簡單,網上的例子大部分都是基於此的。。。
舉例:
以汽車跟蹤爲例,目標是知道汽車時刻的狀態\(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\)代碼在這裏
注意:
這裏至關於創建了兩個模型,一個線性模型,一個非線性模型,在不一樣的時刻使用不一樣的傳感器進行更新
其實就是單個傳感器合併到一塊兒了。。。。
舉例:
一個小車作不均則運動(速度、加速度、角速度等都是可變的),如今有兩個傳感器:儀器A和儀器B,他們都能測量 \(\omega\) 和 \(v\) ,那麼如何進行融合兩個傳感器呢?
這裏其實和Kalman的濾波比較相似,就是把兩個傳感器當作一個傳感器的不一樣時間序列 \(T_1,T_2\) 時刻測量的數據,而後濾波操做。
條件和Kalman多傳感器融合B相同,單處理方式不一樣
因爲部分傳感器精度不一樣,進行特定的取捨頗有必要(親身經歷)
假設求取小車的 \(\omega\) 和 \(v\)
傳感器A對\(\omega\) 測量較爲準確
傳感器B對 \(v\) 測量較爲準確
解決:
其實咱們若是直接按照Kalman多傳感器融合B進行操做的話,偏差基本不會縮小,可能還會增長
這個時候筆者的解決方案是把傳感器A和B當作一個總體傳感器C,傳感器C測量的 \(\omega\) 是A的,測量的 \(v\) 是B的
那麼咱們就把這個合起來的傳感器C進行濾波就好了
實測可用。。。
看到網上不少人問這個問題,這裏筆者沒有親自實現,只是作了猜測,不正確還望讀者指正
解決:
因爲卡爾曼只能一次融合兩個信息(預測和觀測),因此只能進行以下想法
注意:
筆者認爲這種狀況比較少見,由於 \(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\)也不一樣
完畢!!!