卡爾曼濾波理解與實現(xiàn)

作者:XU Ruilin, WANG Xuejun, ZHU Ximin, WEN Shuhan, MAO Bo

編者序言

本文為離散卡爾曼濾波算法的一 一個簡明教程疑俭,從算法思想、實現(xiàn)過程、理論推導(dǎo)和程序?qū)崿F(xiàn)四個方面闡述和分析了卡爾曼濾波算法。

XU Ruilin完成本教程主要部分的編寫宙攻,WANG Xuejun完成第3節(jié)的編寫烤蜕,ZHU Ximin完成2.2節(jié)的編寫,WEN Shuhan完成2.3節(jié)的編寫欢伏,MAO Bo完成全文整理、修訂和排版亿乳。

1 問題引入

卡爾曼濾波(Kalman Filtering)及其一系列的優(yōu)化和改進算法是目前在求解運動狀態(tài)推算問題上最為普遍和高效的方法硝拧。魯?shù)婪颉た柭?/strong>(Rudolf Emil Kalman)在NASA埃姆斯研究中心訪問時径筏,發(fā)現(xiàn)他的方法適用于解決阿波羅計劃的軌跡預(yù)測問題。阿波羅飛船的導(dǎo)航電腦就是使用這種濾波器進行軌跡預(yù)測障陶。

卡爾曼濾波尤其適用于動態(tài)系統(tǒng)滋恬,這種方法對于內(nèi)存要求極低而運算速度快,且能夠保持較好的計算精度抱究,這使得這種方法非常適合解決實時問題和應(yīng)用于嵌入式系統(tǒng)恢氯,也就是說,卡爾曼濾波天然的適用于解決艦艇指控系統(tǒng)的航跡推算問題鼓寺。在接下來的內(nèi)容里勋拟,我們將逐步領(lǐng)會卡爾曼濾波的這些絕佳特點。

不過妈候,現(xiàn)在我們先從復(fù)雜的艦艇航跡推算問題中解脫出來敢靡,從一個更加熟悉和簡單的問題中來理解這個濾波算法的思想、過程和算法州丹。

假設(shè)有一輛無人車WALL-E醋安,需要導(dǎo)引它從A點到達B點,共有兩種手段(圖1):

  • 利用WALL-E本身的GPS系統(tǒng)進行定位墓毒。
  • 利用開發(fā)者寫下的WALL-E運動模型和算法來推斷自身的位置吓揪。


    圖1:定位的基本問題.png

顯然,兩種方法都有一定的誤差所计。如果單獨采用某一種方法進行定位柠辞,WALL-E在誤差的影響下將無法到達B點。因此主胧,需要將兩種方法結(jié)合起來叭首,得到一個更加精確的結(jié)果,這就是卡爾曼濾波要解決的問題踪栋。

2 問題求解

卡爾曼濾波方法如何看待我們的問題呢焙格?在探究這個問題之前,我們先對問題進行抽象夷都,并用數(shù)學(xué)語言來描述我們的問題眷唉。

2.1 問題抽象和符號系統(tǒng)

我們用矢量\boldsymbol{x}=[\boldsymbol{p},\boldsymbol{v}]^\top來描述WALL-E的運動狀態(tài),這個列矢量\boldsymbol{x}包括位置矢量\boldsymbol{p}和速度矢量\boldsymbol{v}兩個分量囤官。在WALL-E的問題上冬阳,我們現(xiàn)在不知道位置\boldsymbol{p}和速度\boldsymbol{v}的準確值,但是知道WALL-E的運動模型滿足狀態(tài)方程F(t)党饮,定位的方法肝陪,也即觀測WALL-E運動狀態(tài)的方法滿足觀測方程G(t). 當然,我們也知道刑顺,這兩種方法都存在一定的誤差A(t)氯窍,那么我們的問題就可以轉(zhuǎn)化為一個優(yōu)化問題——

\label{inter} \min{A(t)} \quad \rm\textsf{subjected to}\quad \left\{ \begin{aligned} F(t)\\ G(t)\\ \end{aligned} \right.

在這一優(yōu)化問題中饲常,目標函數(shù)是要使預(yù)測(估計)誤差最小,同時約束于估計方法F(t)G(t)的條件下狼讨。在卡爾曼濾波中不皆,我們的估計原則(也就是最小化估計誤差的原則)是最小方差無偏估計[1],我們將通過后面的過程分析來說明這一點熊楼。

在我們正式開始引入公式分析卡爾曼濾波問題之前,我們還必須解決一個問題------把連續(xù)的線性系統(tǒng)離散化能犯,也就是將連續(xù)時域問題轉(zhuǎn)化為時間序列問題鲫骗。當然,目前我們只討論線性系統(tǒng)的情況踩晶,關(guān)于非線性系統(tǒng)問題执泰,我們有擴展卡爾曼濾波(Extended Kalman Filtering, EKF)和無跡卡爾曼濾波(Unscented Kalman Filtering, UKF)兩種方法來求解。

補充內(nèi)容------連續(xù)線性時變系統(tǒng)的離散化
設(shè)連續(xù)線性時變系統(tǒng)的時域狀態(tài)方程為

\dot{x}(t)=A(t)x(t)+W(t)u(t)

若采樣周期為T渡蜻,則從時刻t=kT到時刻t=(k+1)T术吝,有

x(k+1)=A[(k+1)T,kT]x(k)+u(k)\int_{kT}^{(k+1)T}A[(k+1)T,\tau]W(\tau)d\tau
F(k)=A[(k+1)T,kT]B(k)=\int_{kT}^{(k+1)T}A[(k+1)T,\tau]W(\tau)d\tau茸苇,則離散化的狀態(tài)方程為

x(k+1)=F(k)x(k)+B(k)u(k).

通過對線性系統(tǒng)的離散化處理排苍,我們現(xiàn)在可以考慮每一個時刻WALL-E的運動狀態(tài)。接下來学密,我們將用\hat{\boldsymbol{x_{k-1}}}來表示在t=k-1時刻運動狀態(tài)的最優(yōu)估計值淘衙;用\boldsymbol{x_{k \mid k-1}}表示用t=k-1時刻對t=k時刻的狀態(tài)預(yù)測值;用\hat{\boldsymbol{x_k}}表示對t=k時刻綜合預(yù)測和觀測兩種方法的最優(yōu)估計值腻暮。

2.2 過程詳解

在估計WALL-E位置的問題上彤守,假定我們已經(jīng)知道它是勻速直線運動,WALL-E身上還攜帶有一個GPS傳感器可以提供它的位置信息哭靖,WALL-E在前進過程中可能會遇到一些情況具垫,比如停止前進或是受到風(fēng)的影響。

加入我們已知的是WALL-E上一個時刻的最佳估計狀態(tài)试幽,即k-1時刻的位置和速度筝蚕,要求的是下一時刻即k時刻的最佳估計狀態(tài),即k時刻的位置和速度抡草,我們可以發(fā)現(xiàn)有兩種方法可以得到它的k時刻的狀態(tài):

一種是通過WALL-E設(shè)定程序計算得到下一秒的狀態(tài)饰及,比如現(xiàn)在設(shè)定是勻速直線運動,那么下一秒的速度應(yīng)該是恒定不變的康震,而位置則是在上一秒位置的基礎(chǔ)上加上時間乘以速度即一秒內(nèi)走過的路程燎含,但是現(xiàn)實生活中并不是理想的,機器人會受到摩擦力腿短、風(fēng)力等的影響屏箍,當然也可能會有頑皮的小孩擋住他前進的道路绘梦,這些因素使得WALL-E在k時的真實狀態(tài)與我們計算得到的數(shù)據(jù)有所不同。

另一種是通過WALL-E所攜帶的GPS來確定它的位置赴魁,因為GPS是測量出的就是WALL-E的實時狀態(tài)卸奉,因此它比較準確。但是GPS測量k時刻的狀態(tài)有兩個問題颖御,一是GPS只能測出WALL-E的位置榄棵,而測不出它的速度;二是GPS傳感器測量的時候也會有儀器的誤差潘拱,只能說它是比較準確的疹鳄,比較接近真實值的。

那么接下來問題來了芦岂,我們?nèi)绾蔚玫絢時刻WALL-E的真實狀態(tài)呢瘪弓?

我們將第一種方法得到的狀態(tài)值稱為預(yù)測值,第二種方法得到的狀態(tài)值稱為測量值禽最,對汽車的最佳估計就是將這兩部分信息結(jié)合起來腺怯,盡量的去逼近k時刻的真實值。

下面再深入一些思考川无,怎么將這兩部分結(jié)合起來呛占?

在初始時間k-1, \hat{\boldsymbol{x_{k-1}}}是WALL-E的最佳估計值懦趋,WALL-E其實可以是估計值附近的任何位置栓票,并且這種不確定性由該概率密度函數(shù)描述。WALL-E最有可能在這個分布的平均值附近愕够。在下一個時間走贪,估計的不確定性增加,用一個更大的方差表示惑芭,這是因為在時間步驟k-1和k之間坠狡,WALL-E可能收到了風(fēng)力的影響,或者腳可能向前滑了一點遂跟,因此逃沿,它可能已經(jīng)行進了與模型預(yù)測的距離不同的距離。

WALL-E位置的另一個信息來源來自測量幻锁,方差表示誤差測量的不確定性凯亮,真正的位置同樣可以是平均值附近的任何位置。

預(yù)測值和測量值哄尔,對WALL-E的最佳估計是將這兩部分信息結(jié)合起來假消,將兩個概率函數(shù)相乘得到另一個高斯函數(shù),該估計值的方差小于先前估計值岭接,并且該概率密度函數(shù)的平均值為我們提供了WALL-E位置的最佳估計富拗。

2.3 從控制論角度分析

    為了讓卡爾曼濾波器具體可感臼予,在進行公式推導(dǎo)之前,我們先進行原理的理解和模型的建立啃沪。
    假設(shè)現(xiàn)在有一個宇宙飛船粘拾,為了讓這個宇宙飛船能夠在宇宙空間中平穩(wěn)運行,我們需要知道他的發(fā)動機內(nèi)部溫度创千,我們知道燃料進量等信息缰雇,但是我們無法把傳感器直接加在發(fā)動機內(nèi)部,因為會被融化追驴,但是如果我們?nèi)绻軌蛘业?目的狀態(tài)“內(nèi)部溫度”和另一狀態(tài)的關(guān)系寓涨,就能夠通過建立聯(lián)系來得知內(nèi)部溫度。因此我們把傳感器加在發(fā)動機外部氯檐,測量發(fā)動機外部溫度,我們稱它為測量狀態(tài)体捏。
    如果說我們可以建立相對完善的數(shù)學(xué)模型來表達這個實際問題冠摄,我們就可以通過“燃料進量”等已知因素(在此我們稱之為 控制狀態(tài))和測量狀態(tài)“發(fā)動機外部溫度”來 估測目的狀態(tài)“內(nèi)部溫度”谬以。
     建立模型的目的在于愧驱, 使目的狀態(tài) —— 內(nèi)部溫度的估計值 , 無限趨近收斂于真實的外部溫度断序,由于我們的數(shù)學(xué)模型足夠完善年栓,只要我們讓測量狀態(tài)——外部溫度的估計值收斂于真實測量值拆挥,目的狀態(tài)自然也與之匹配。
圖2:宇宙飛船模型框圖.png
   但是某抓,如果模型對于測量狀態(tài)的估計值和測量值 有偏差怎么辦呢纸兔,我們引入控制論的思想,把測量狀態(tài)的真實值和測量值的差值 反饋回數(shù)學(xué)模型否副,對模型進行修正汉矿。
圖3:加入反饋后的宇宙飛船模型.png
   接下來,我們將這個實際的例子抽象一下备禀。
圖4:卡爾曼濾波器初步抽象模型.jpg
    我們將測量狀態(tài)和目的狀態(tài)之間的聯(lián)系洲拇,用系數(shù)矩陣C表示,目的狀態(tài)隨著時間變化的規(guī)律我們用x對時間求導(dǎo)來表示(后續(xù)的例子中曲尸,我們將會解釋另外一種目的狀態(tài)與時間建立關(guān)系的方法——抽樣)赋续,求導(dǎo)后的x受目的狀態(tài)與控制狀態(tài)的影響,我們將這種影響關(guān)系用系數(shù)矩陣AB表示。

    我們回到初衷——使模型的目的狀態(tài)估計值和實際問題的目標狀態(tài)值趨同另患,那么我們將估計值收斂于實際值之前的誤差記為e纽乱,

以下,我們將進行e的運算推導(dǎo)

設(shè):
e\ =\ x\ -\ \hat{x}

則有實際目標變量的表達式:
\dot{x}\ =\ Fx\ +\ Bu

數(shù)學(xué)模型中目標變量的表達式:
\hat{\dot{x}}\ =\ F\hat{x}\ +\ Bu\ +\ K\left( y\ -\ \hat{y} \right)

實際模型中測量變量的表達式:
y\ =\ Hx

數(shù)學(xué)模型中測量變量的表達式:
\hat{y}\ =\ H\hat{x}

將目標變量的實際值和估計值相減:
\dot{x}\ -\ \hat{\dot{x}}\ =\ F\left( \dot{x}\ -\ \hat{x} \right) \ +\ k\left( y\ -\ \hat{y} \right)

將上述方程帶入誤差e的表達式昆箕,我們可得出誤差e的解析解:
\dot{e}\ =\ \left( F\ -\ KH \right) e

e\left( t \right) \ =\ e^{\left( F\ -\ KH \right) t}e\left( 0 \right)
從推導(dǎo)結(jié)果中我們不難看出迫淹,估計值和實際值的誤差隨時間呈指數(shù)形式變化秘通,當(F-KH)<1時,隨著時間的推移敛熬,會無限趨近于零肺稀,也就是意味著估計值和實際值相吻合。這就是為什么卡爾曼濾波器可以完美預(yù)測出目標狀態(tài)值的原理应民。

    當然话原,有人會說,如果不引入這個卡爾曼增益诲锹,只要A<1繁仁,同樣會導(dǎo)致e收斂于0,這也就說明了卡爾曼濾波器的意義——更快減小預(yù)測的誤差归园,得到最優(yōu)值黄虱。

2.4 過程分析

在估計WALL-E位置的問題上,我們不知道位置\boldsymbol{p}和速度\boldsymbol{v}的準確值庸诱,但是我們可以給出一個估計區(qū)間(圖5.a)捻浦。卡爾曼濾波假設(shè)所有的變量是隨機的且符合高斯分布(正態(tài)分布)桥爽。每個變量有一個均值\mu和一個方差 \sigma^2圖5.b)朱灿。而圖5.c則表示速度和位置是相關(guān)的。

圖5:估計的不確定性.png

假如我們已知上一個狀態(tài)的位置值钠四,現(xiàn)在要預(yù)測下一個狀態(tài)的位置值盗扒。如果我們的速度值很高,我們移動的距離會遠一點缀去。相反侣灶,如果速度慢缕碎,WALL-E不會走的很遠炫隶。這種關(guān)系在跟蹤系統(tǒng)狀態(tài)時很重要,它給了我們更多的信息:一個觀測值告訴我們另一個觀測值可能是什么樣子阎曹。這就是卡爾曼濾波的目的------從所有不確定信息中提取有價值的信息伪阶。

2.4.1 利用矩陣描述問題

根據(jù)數(shù)理統(tǒng)計知識,我們知道這種兩個觀測值(隨機變量)之間的關(guān)系可以通過一個協(xié)方差矩陣
Cov(\boldsymbol{x_p},\boldsymbol{x_v})=\mathbb{E}[(\boldsymbol{x_p}-\boldsymbol{\mu_p}),(\boldsymbol{x_v}-\boldsymbol{\mu_v})]
描述(圖6)处嫌。

圖6:協(xié)方差矩陣對變量相關(guān)性的反映.png

我們假設(shè)系統(tǒng)狀態(tài)的分布為高斯分布(正態(tài)分布)栅贴,所以在k-1時刻我們需要兩個信息:最佳預(yù)估值\hat{\boldsymbol{x_{k-1}}}及其協(xié)方差矩陣\boldsymbol{P_{k-1}}(如式(2)所示)。

\hat{\boldsymbol{x_{k-1}}}=\begin{bmatrix} \boldsymbol{p}\\\boldsymbol{v}\end{bmatrix}

\boldsymbol{P_{k-1}}=\begin{bmatrix} Cov_{pp} & Cov_{pv}\\Cov_{vp} & Cov_{vv}\end{bmatrix}

下一步熏迹,我們需要通過k-1時刻的狀態(tài)來預(yù)測k時刻的狀態(tài)檐薯。請注意,我們不知道狀態(tài)的準確值,但是我們的預(yù)測函數(shù)并不在乎坛缕,它僅僅是對k-1時刻所有可能值的范圍進行預(yù)測轉(zhuǎn)移墓猎,然后得出一個k時刻新值的范圍。在這個過程中赚楚,位置\boldsymbol{p}和速度\boldsymbol{v}的變化為

\boldsymbol{p_{k \mid k-1}}=\boldsymbol{p_{k-1}}+\boldsymbol{v_{k-1}}\Delta t

\boldsymbol{v_{k \mid k-1}}=\boldsymbol{v_{k-1}}

我們可以通過一個狀態(tài)轉(zhuǎn)移矩陣\boldsymbol{F_{k \mid k-1}}來描述這個轉(zhuǎn)換關(guān)系

\boldsymbol{x_{k \mid k-1}}= \begin{bmatrix} 1 & {\Delta t} \\ 0 & 1\end{bmatrix}\hat{\boldsymbol{x_{k-1}}}\\=\boldsymbol{F_{k \mid k-1}}\hat{\boldsymbol{x_{k-1}}}

同理毙沾,我們更新協(xié)方差矩陣\boldsymbol{P_{k \mid k-1}}
\boldsymbol{P_{k \mid k-1}}= Cov(\boldsymbol{F_{k \mid k-1}}\boldsymbol{x_p},\boldsymbol{F_{k \mid k-1}}\boldsymbol{x_v})=\boldsymbol{F_{k \mid k-1}}Cov(\boldsymbol{x_p},\boldsymbol{x_v})\boldsymbol{F_{k \mid k-1}^\top}=\boldsymbol{F_{k \mid k-1}}\boldsymbol{P_{k-1}}\boldsymbol{F_{k \mid k-1}^\top}

2.4.2 考慮系統(tǒng)控制情況時的狀態(tài)描述

到目前為止,我們考慮的都是勻速運動的情況宠页,也就是系統(tǒng)沒有對WALL-E的運動狀態(tài)進行控制的情況左胞。那么,如果系統(tǒng)對WALL-E進行控制举户,例如發(fā)出一些指令啟動或者制動輪子烤宙,對這些額外的信息,我們可以通過一個向量\boldsymbol{u_{k-1}}來描述這些信息俭嘁,并將其添加到我們的預(yù)測方程里作為一個修正躺枕。假如我們通過發(fā)出的指令得到預(yù)期的加速度\boldsymbol{a},運動狀態(tài)方程就更新為

\boldsymbol{p_{k \mid k-1}}=\boldsymbol{p_{k-1}}+\boldsymbol{v_{k-1}}\Delta t+\frac{1}{2}\boldsymbol{a}{\Delta t}^2

\boldsymbol{v_{k \mid k-1}}=\boldsymbol{v_{k-1}}+\boldsymbol{a}\Delta t

引入矩陣表示為

\boldsymbol{x_{k \mid k-1}} =\boldsymbol{F_{k \mid k-1}}\hat{\boldsymbol{x_{k-1}}}+ \begin{bmatrix}\frac{{\Delta t}^2}{2} \\ \Delta t\end{bmatrix}\boldsymbol{a}\\ =\boldsymbol{F_{k \mid k-1}}\hat{\boldsymbol{x_{k-1}}}+\boldsymbol{B_{k-1}}\boldsymbol{u_{k-1}}

式中\boldsymbol{B_{k-1}}稱為控制矩陣供填,\boldsymbol{u_{k-1}}稱為控制向量(例如加速度a)拐云。當然,如果沒有任何外界動力影響的系統(tǒng)捕虽,可以忽略這一部分。

2.4.3 不確定性的影響

我們增加另一個細節(jié)坡脐,假如我們的預(yù)測轉(zhuǎn)換矩陣不是100%準確呢泄私,會發(fā)生什么?如果狀態(tài)只會根據(jù)系統(tǒng)自身特性演變备闲,那樣將不會有任何問題晌端。如果所有外界作用力對系統(tǒng)的影響可以被計算得十分準確,那樣也不會有任何問題恬砂。但是如果有些外力我們無法預(yù)測咧纠,例如我們在跟蹤一個四軸飛行器,它會受到風(fēng)力影響泻骤;或者在跟蹤一個輪式機器人漆羔,輪子可能會打滑,地面上的突起會使它減速狱掂。我們無法跟蹤這些因素演痒,而這些不確定事件發(fā)生時,預(yù)測方程將會失靈趋惨。因此鸟顺,我們將這些不確定性統(tǒng)一建模,在預(yù)測方程中增加一個不確定項器虾。

通過這種方式讯嫂,使得原始狀態(tài)中的每一個點可以都會預(yù)測轉(zhuǎn)換到一個范圍蹦锋,而不是某個確定的點(圖7.a)。\hat{\boldsymbol{x_{k-1}}}可以這樣描述------\boldsymbol{x_{k-1}}中的每個點移動到一個符合方差\boldsymbol{Q_{k-1}}的高斯分布里(圖7.b)欧芽。換言之莉掂,我們把這些不確定因素描述為方差為\boldsymbol{Q_{k-1}}的高斯噪聲,并用\boldsymbol{w_k}表示渐裸。這樣就會產(chǎn)生一個新的高斯分布巫湘,方差不同,但是均值相同(圖7.c)昏鹃。

圖7:在高斯噪聲下的狀態(tài)預(yù)測.png

通過對\boldsymbol{Q_{k-1}}的疊加擴展尚氛,得到完整的預(yù)測轉(zhuǎn)換方程為

\boldsymbol{x_{k \mid k-1}} =\boldsymbol{F_{k \mid k-1}}\hat{\boldsymbol{x_{k-1}}}+\boldsymbol{B_{k-1}}\boldsymbol{u_{k-1}}+\boldsymbol{w_k}

\boldsymbol{P_{k \mid k-1}}=\boldsymbol{F_{k \mid k-1}}\boldsymbol{P_{k-1}}\boldsymbol{F_{k \mid k-1}^\top}+\boldsymbol{Q_{k-1}}

新的預(yù)測轉(zhuǎn)換方程只是引入了已知的系統(tǒng)控制因素。新的不確定性可以通過之前的不確定性計算得到洞渤。到這里阅嘶,我們得到了一個模糊的估計范圍------通過\boldsymbol{x_{k \mid k-1}}\boldsymbol{P_{k \mid k-1}}描述的范圍。

2.4.4通過觀測校正預(yù)測

我們之前的工作仍然是在使用運動模型一種方法來估計系統(tǒng)的狀態(tài)载迄,現(xiàn)在讯柔,我們要把另一種方法,也就是觀測(本問題中為GPS定位)考慮進來护昧,以進一步修正對運動狀態(tài)的估計(圖8)魂迄。

圖8:預(yù)測對預(yù)測范圍的約束.png

我們用矩陣\boldsymbol{H_k}來描述觀測方法的作用,于是有

\boldsymbol{z_k}=\boldsymbol{H_k}\boldsymbol{x_k}

再加入觀測噪聲\boldsymbol{v_k}惋耙,觀測方程為

\boldsymbol{z_k}=\boldsymbol{H_k}\boldsymbol{x_k}+\boldsymbol{v_k}

圖9:觀測矩陣.png

從控制論的角度出發(fā)捣炬,我們定義新息(也即觀測值與預(yù)測值的誤差)為
\boldsymbol{\tilde{x_k}}=\boldsymbol{z_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}}

當然我們也知道,觀測本身也會存在誤差绽榛,比如本問題中的GPS定位精度僅有10m. 因此湿酸,我們用矩陣\boldsymbol{R_k}來描述這種不確定性(圖10圖11.a)。

圖10:觀測誤差.png

這時灭美,我們新息的協(xié)方差為

\begin{aligned} \boldsymbol{S_k}=Cov(\boldsymbol{\tilde{x_k}})=Cov(\boldsymbol{z_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})\\ =Cov(\boldsymbol{H_k}\boldsymbol{x_k}+\boldsymbol{v_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})\\ =\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}+\boldsymbol{R_k} \end{aligned}

現(xiàn)在我們需要把兩種方法得到的可能性融合起來(圖11.b)推溃。對于任何狀態(tài),有兩個可能性:1. 傳感器的觀測值更接近系統(tǒng)真實狀態(tài)届腐;2. 模型推算的估計值更接近系統(tǒng)真實狀態(tài)铁坎。如果有兩個相互獨立的獲取系統(tǒng)狀態(tài)的方式,并且我們想知道兩者都準確的概率值犁苏,于是我們可以通過加權(quán)來解決更相信誰的問題(圖11.c)厢呵。

圖11:使用觀測更新預(yù)測.png

我們現(xiàn)在知道,系統(tǒng)模型的狀態(tài)預(yù)測\boldsymbol{x_{k \mid k-1}}與對系統(tǒng)的狀態(tài)觀測\boldsymbol{z_k}服從高斯分布傀顾,把這個問題抽象一下就是——

\begin{aligned} \boldsymbol{\hat{x_k}}&=\kappa\boldsymbol{x_{k \mid k-1}}+(1-\kappa)\boldsymbol{z_k}\\ \boldsymbol{\hat{x_k}}&\sim{\mathcal N}(\kappa\mu_1+(1-\kappa)\mu_2,\kappa^2\sigma_1^2+(1-\kappa)\sigma_2^2) \end{aligned}

根據(jù)我們的一個估計準則------最小方差估計襟铭,那么這個問題可以轉(zhuǎn)化為優(yōu)化問題求解

\begin{aligned} \min f(k)=\kappa\mu_1+(1-\kappa)\mu_2,\kappa^2\sigma_1^2+(1-\kappa)\sigma_2^2\quad \rm\textsf{subjected\ to}\quad\kappa\in(0,1) \end{aligned}

求導(dǎo)數(shù)(差分)得

\fracdlldevr{d\kappa}f(\kappa)=2\kappa\sigma_1^2-2(1-\kappa)\sigma_2^2=0

\kappa=\frac{\sigma_1^2}{\sigma_1^2+\sigma_2^2},從而

\begin{aligned} \mu&=\mu_1+\kappa(\mu_2-\mu_1)\\ \sigma&=\sigma_1^2-\kappa\sigma_1^2. \end{aligned}

當維度高于一維時,我們用矩陣來描述寒砖,有

\boldsymbol{K}=\boldsymbol{\Sigma_1^2}(\boldsymbol{\Sigma_1^2}+\boldsymbol{\Sigma_2^2})^{-1}

\begin{aligned} \boldsymbol{\mu}=\boldsymbol{\mu_1}+\boldsymbol{K}(\boldsymbol{\mu_2}-\boldsymbol{\mu_1})\\ \boldsymbol{\Sigma}=\boldsymbol{\Sigma_1^2}-\boldsymbol{K}\boldsymbol{\Sigma_1^2}. \end{aligned}

這里的\boldsymbol{K}稱為卡爾曼增益(Kalman Gain)赐劣,也就是我們在解決更信任哪種方法時的偏向程度。

如果我們從兩個獨立的維度估計系統(tǒng)狀態(tài)哩都,那么根據(jù)系統(tǒng)模型的預(yù)測為

(\boldsymbol{\mu_1},\boldsymbol{\Sigma_1})=(\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}},\boldsymbol{H_k}\boldsymbol{P_k}\boldsymbol{H_k^\top})

通過傳感器的觀測為

(\boldsymbol{\mu_2},\boldsymbol{\Sigma_2})=(\boldsymbol{z_k},\boldsymbol{R_k})

我們結(jié)合著兩種方法得到

\boldsymbol{H_k}\boldsymbol{\hat{x_k}}=\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}}+\boldsymbol{K}(\boldsymbol{z_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})

\boldsymbol{H_k}\boldsymbol{P_k}\boldsymbol{H_k^\top}=\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}-\boldsymbol{K}\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}

\boldsymbol{\Sigma}=\boldsymbol{\Sigma_1}^2-\boldsymbol{K}\boldsymbol{\Sigma_1}^2可知魁兼,卡爾曼增益為

\boldsymbol{K}=\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k}^\top(\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k}^\top+\boldsymbol{R_k})^{-1}

\boldsymbol{H_k}約去(\boldsymbol{K}中也含有\boldsymbol{H_k}項),得

\boldsymbol{\hat{x_k}}=\boldsymbol{x_{k \mid k-1}}+\boldsymbol{K^\prime}(\boldsymbol{z_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})

\boldsymbol{P_k}=\boldsymbol{P_{k \mid k-1}}-\boldsymbol{K^\prime}\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}

此時的卡爾曼增益實際為

\boldsymbol{K}=\boldsymbol{K^\prime}=\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}(\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}+\boldsymbol{R_k})^{-1}

我們最后再來驗證一下估計的無偏性——

這里我們設(shè)t=k時刻的真值為\boldsymbol{x_k}漠嵌,由于

\begin{aligned} \mathbb{E}(\boldsymbol{\hat{x_k}}-\boldsymbol{x_k})&=\mathbb{E}[\boldsymbol{\hat{x_k}}+\boldsymbol{K}(\boldsymbol{z_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})-\boldsymbol{x_k}]\\ &=\mathbb{E}[\boldsymbol{\hat{x_k}}+\boldsymbol{K}(\boldsymbol{H_k}\boldsymbol{x_k}+\boldsymbol{v_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})-\boldsymbol{x_k}]\\ &=\mathbb{E}[(\boldsymbol{I}-\boldsymbol{K}\boldsymbol{H_k})(\boldsymbol{x_{k \mid k-1}}-\boldsymbol{x_k})+\boldsymbol{K}\boldsymbol{v_k}]\\ &=\mathbb{E}[(\boldsymbol{I}-\boldsymbol{K}\boldsymbol{H_k})(\boldsymbol{x_{k \mid k-1}}-\boldsymbol{x_k})]+\boldsymbol{K}\mathbb{E}(\boldsymbol{v_k})\\ &=\mathbb{E}[(\boldsymbol{I}-\boldsymbol{K}\boldsymbol{H_k})(\boldsymbol{x_{k \mid k-1}}-\boldsymbol{x_k})] \end{aligned}

由于\mathbb{E}(\boldsymbol{x_{k \mid k-1}}-\boldsymbol{x_k})=0從初值而來的無偏傳遞性)可知\mathbb{E}(\boldsymbol{\hat{x_k}}-\boldsymbol{x_k})=0咐汞,即卡爾曼濾波滿足無偏估計準則。顯然儒鹿,其中要求系統(tǒng)噪聲和觀測噪聲是不相關(guān)化撕、零期望的白噪聲,且是線性系統(tǒng)约炎,初始時刻的狀態(tài)估計是無偏的植阴。當這些條件不能滿足時,卡爾曼濾波的估計結(jié)果是有偏的圾浅。

2.5 過程整理

到這里掠手,我們已經(jīng)獲得了卡爾曼濾波的全部要素。我們可以把整個過程總結(jié)為3個基本假設(shè)

假設(shè)一\boldsymbol{w_k}\boldsymbol{v_k}都是零均值高斯白噪聲狸捕,也即\mathbb{E}(\boldsymbol{w_k})=0喷鸽,\mathbb{E}(\boldsymbol{v_k})=0.

假設(shè)二\boldsymbol{w_k}\boldsymbol{v_k}無關(guān),也即\mathbb{E}(\boldsymbol{w_k},\boldsymbol{v_k})=0.

假設(shè)三系統(tǒng)初值\boldsymbol{x_0}的均值和方差已知灸拍,且\boldsymbol{w_k}\boldsymbol{v_k}均不相關(guān)做祝。

以及5個基本方程 方程一狀態(tài)預(yù)測

\boldsymbol{x_{k \mid k-1}} =\boldsymbol{F_{k \mid k-1}}\hat{\boldsymbol{x_{k-1}}}+\boldsymbol{B_{k-1}}\boldsymbol{u_{k-1}}+\boldsymbol{w_k}

方程二協(xié)方差預(yù)測

\boldsymbol{P_{k \mid k-1}}=\boldsymbol{F_{k \mid k-1}}\boldsymbol{P_{k-1}}\boldsymbol{F_{k \mid k-1}^\top}+\boldsymbol{Q_{k-1}}

方程三卡爾曼增益

\boldsymbol{K}=\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}(\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}\boldsymbol{H_k^\top}+\boldsymbol{R_k})^{-1}

方程四狀態(tài)更新

\boldsymbol{\hat{x_k}}=\boldsymbol{x_{k \mid k-1}}+\boldsymbol{K}(\boldsymbol{z_k}-\boldsymbol{H_k}\boldsymbol{x_{k \mid k-1}})

方程五協(xié)方差更新

\boldsymbol{P_k}=\boldsymbol{P_{k \mid k-1}}-\boldsymbol{K}\boldsymbol{H_k}\boldsymbol{P_{k \mid k-1}}

3 數(shù)學(xué)推導(dǎo)

\hat{x}_k=x_{k|k-1}+K\left( z_k-Hx_{k|k-1} \right)

\ \ \ \ \ \ \ \ =x_{k|k-1}+K\left( Hx_k+v_k-Hx_{k|k-1} \right)

P_k=E\left[ \left( \hat{x}_k-x_k \right) \left( \hat{x}_k-x_k \right) ^T \right]

\ \ =E\left[ \left( x_k-\hat{x}_k \right) \left( x_k-\hat{x}_k \right) ^T \right]

=E\left[ \left[ x_k-x_{k|k-1}-K\left( Hx_k+v_k-Hx_{k|k-1} \right) \right] \left[ x_k-x_{k|k-1}-K\left( Hx_k+v_k-Hx_{k|k-1} \right) \right] ^T \right]

=E\left[ \left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) -Kv_k \right] \left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) -Kv_k \right] ^T \right]

=E\left[ \left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) \right] \left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) \right] ^T-Kv_k\left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) \right] ^T-\left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) \right] \left[ Kv_k \right] ^T+\left( Kv_k \right) \left( Kv_k \right) ^T \right]

=E\left[ \left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) \right] \left[ \left( I-KH \right) \left( x_k-x_{k|k-1} \right) \right] ^T \right] -0-0+E\left[ \left( Kv_k \right) \left( Kv_k \right) ^T \right]

=\left( I-KH \right) E\left[ \left( x_k-x_{k|k-1} \right) \left( x_k-x_{k|k-1} \right) ^T \right] \left( I-KH \right) ^T+KRK^T

=\left( I-KH \right) P_{k|k-1}\left( I-KH \right) ^T+KRK^T

=\left( P_{k|k-1}-KHP_{k|k-1} \right) \left( I-KH \right) ^T+KRK^T

=P_{k|k-1}-KHP_{k|k-1}-P_{k|k-1}H^TK^T+KHP_{k|k-1}H^TK^T+KRK^T

=P_{k|k-1}-KHP_{k|k-1}-P_{k|k-1}H^TK^T+K\left( HP_{k|k-1}H^T+R \right) K^T
協(xié)方差矩陣的對角線元素就是方差。把矩陣P的對角線元素求和株搔,定義為矩陣的跡[2][3]剖淀。
tr\left( P_K \right) =tr\left( P_{k|k-1} \right) -tr\left( KH_kP_{k|k-1} \right) -tr\left( P_{k|k-1}H_{k}^{^T}K^T \right) +tr\left( KH_kP_{k|k-1}H_{k}^{^T}K^T \right) +tr\left( KR_kK^T \right)

=tr\left( P_{k|k-1} \right) -tr\left( KH_kP_{k|k-1} \right) -tr\left( P_{k|k-1}H_{k}^{T}K^T \right) +tr\left[ K\left( H_kP_{k|k-1}H_{k}^{T}+R_k \right) K^T \right]

=tr\left( P_{k|k-1} \right) -2tr\left( KH_kP_{k|k-1} \right) +tr\left[ K\left( H_kP_{k|k-1}H_{k}^{T}+R_k \right) K^T \right]

\frac{dtr\left( P_K \right)}{dK}=-2\left( H_kP_{k|k-1} \right) ^T+2K\left( H_kP_{k|k-1}H_{k}^{^T}+R_k \right)
最小均方差就是使得上式最小纯蛾,對未知量K求導(dǎo),令導(dǎo)函數(shù)等于0纤房,就能找到K的值。
\frac{dtr\left( P_K \right)}{dK}=0

-2\left( H_kP_{k|k-1} \right) ^T+2K\left( H_kP_{k|k-1}H_{k}^{^T}+R_k \right) =0

2\left( H_kP_{k|k-1} \right) ^T=2K\left( H_kP_{k|k-1}H_{k}^{^T}+R_k \right)

K=\frac{\left( H_kP_{k|k-1} \right) ^T}{H_kP_{k|k-1}H_{k}^{T}+R_k}=\frac{P_{k|k-1}H_{k}^{^T}}{H_kP_{k|k-1}H_{k}^{T}+R_k}
注意這個計算式K翻诉,轉(zhuǎn)換矩陣H_k式常數(shù)炮姨,測量噪聲協(xié)方差R_k也是常數(shù)。因此K的大小將與預(yù)測值的誤差協(xié)方差有關(guān)碰煌。不妨進一步假設(shè)舒岸,上面式子中的矩陣維數(shù)都是1*1大小的,并假H_k=1芦圾,P_{k|k-1}不等于0蛾派。那么K可以寫成如下:K=\frac{P_{k|k-1}}{P_{k|k-1}+R_k}=\frac{1}{1+\frac{R_k}{P_{K|K-1}}}

所以P_{k|k-1}越大,那么K就越大,權(quán)重將更加重視反饋洪乍,如果P_{k|k-1}等于0眯杏,也就是預(yù)測值和真實值相等,那么K=0壳澳,估計值就等于預(yù)測值(先驗)岂贩。

     將計算出的這個K反代入Pk中,就能簡化Pk巷波,估計協(xié)方差矩陣Pk的:

P_k=P_{k|k-1}-KH_kP_{k|k-1}-P_{k|k-1}H_{k}^{T}K^T+K\left( H_kP_{k|k-1}H_{k}^{T}+R_k \right) K^T

=P_{k|k-1}-KH_kP_{k|k-1}-P_{k|k-1}H_{k}^{T}K^T+\frac{P_{k|k-1}H_{k}^{T}}{HP_{k|k-1}H_{k}^{T}+R_k}\left( H_kP_{k|k-1}H_{k}^{T}+R_k \right) K^T

=P_{k|k-1}-KH_kP_{k|k-1}-P_{k|k-1}H_{k}^{T}K^T+P_{k|k-1}H_{k}^{T}K^T

=P_{k|k-1}-KH_kP_{k|k-1}

=\left( I-KH_k \right) P_{k|k-1}
因此遞推公式中每一步的K就計算出來了萎津,同時每一步的估計協(xié)方差也能計算出來。但K的公式中好像又多了一個我們還未曾計算出來的東西 他稱之為預(yù)測值和真實值之間誤差的協(xié)方差矩陣抹镊。它的遞推計算如下:
x_{k|k-1}=F_{k|k-1}\hat{x}_{k-1}+B_{k-1}u_{k-1}+w_k

P_{k|k-1}=E\left[ e_{k|k-1}e_{k|k-1}^{T} \right]

=E\left[ \left( x_k-x_{k|k-1} \right) \left( x_k-x_{k|k-1} \right) ^T \right]

=E\left[ \left[ F_{k|k-1}x_{k-1}+B_{k-1}u_{k-1}+w_k-F_{k|k-1}\hat{x}_{k-1}-B_{k-1}u_{k-1} \right] \left[ F_{k|k-1}x_{k-1}+B_{k-1}u_{k-1}+w_k-F_{k|k-1}\hat{x}_{k-1}-B_{k-1}u_{k-1} \right] ^T \right]

=E\left[ \left[ F_{k|k-1}\left( x_{k-1}-\hat{x}_{k-1} \right) +w_k \right] \left[ F_{k|k-1}\left( x_{k-1}-\hat{x}_{k-1} \right) +w_k \right] ^T \right]

=E\left[ F_{k|k-1}\left( x_{k-1}-\hat{x}_{k-1} \right) \left( x_{k-1}-\hat{x}_{k-1} \right) ^TF_{k|k-1}^{T}+F_{k|k-1}\left( x_{k-1}-\hat{x}_{k-1} \right) w_{k}^{T}+w_k\left( x_{k-1}-\hat{x}_{k-1} \right) ^TF_{k|k-1}^{T}+w_kw_{k}^{T} \right]

=E\left[ F_{k|k-1}\left( x_{k-1}-\hat{x}_{k-1} \right) \left( x_{k-1}-\hat{x}_{k-1} \right) ^TF_{k|k-1}^{T}+w_kw_{k}^{T} \right]

=F_{k|k-1}E\left[ \left( x_{k-1}-\hat{x}_{k-1} \right) \left( x_{k-1}-\hat{x}_{k-1} \right) ^T \right] F_{k|k-1}^{T}+Q_{k-1}

=F_{k|k-1}P_{k-1}F_{k|k-1}^{T}+Q_{k-1}

P_{k|k-1}=F_{k|k-1}P_{k-1}F_{k|k-1}^{T}+Q_{k-1}

    由此也得到了$P_{k|k-1}$的遞推公式锉屈。因此我們只需設(shè)定最初的$P_k$就能不斷遞推下去。

4 仿真分析

現(xiàn)在我們使用卡爾曼濾波來解決一個實際問題髓考。在這個仿真試驗中部念,我們提供了一個基于Python 3.7的腳本程序。接下來我們將結(jié)合這個腳本程序來解釋如何使用代碼復(fù)現(xiàn)離散卡爾曼濾波算法氨菇。而實際上儡炼,不論采用何種編程語言,其復(fù)現(xiàn)思路都是一致的查蓉,無非就是將數(shù)學(xué)描述轉(zhuǎn)換為代碼描述乌询。

   # Python 3.7 編譯環(huán)境
   # 導(dǎo)入第三方庫numpy和matplotlib
   import numpy as np # 用于進行數(shù)學(xué)計算
   import matplotlib.pyplot as plt # 用于繪圖

   plt.rcParams['font.sans-serif']=['Kaiti'] # 用來正常顯示中文標簽
   plt.rcParams['axes.unicode_minus']=False # 用來正常顯示負號

   # 類就是一個模板,模板里可以包含多個函數(shù)豌研,函數(shù)里實現(xiàn)一些功能
   # 對象則是根據(jù)模板創(chuàng)建的實例妹田,通過實例,對象可以執(zhí)行類中的函數(shù)
   class KalmanFilter(object):
      # python的面向?qū)ο缶幊讨械腳_init__()方法鹃共,用以初始化新創(chuàng)建對象的狀態(tài)
      # self為實例本身鬼佣,F(xiàn),B,H,Q,R,P,x0都是實例self的屬性
      def __init__(self, F = None, B = None, H = None, Q = None, R = None, \
      P = None, x0 = None): # 所有矩陣置空
         
         # 異常處理,拋出一個異常:“設(shè)置適當?shù)南到y(tǒng)狀態(tài).”
         # 也就是說霜浴,F(xiàn)矩陣和H矩陣不能為空晶衷,這是理所當然的
         # F矩陣由我們的運動模型來確定,H矩陣由我們的觀測方法來確定
         if(F is None or H is None):
            raise ValueError("Set proper system dynamics.")
         
         # F.shape用于返回矩陣F的尺度阴孟,是一個二維列表
         # F.shape[0]為行長度晌纫,F(xiàn).shape[1]為列長度
         # 在MATLAB中,我們可以用函數(shù)size()實現(xiàn)這一功能
         self.n = F.shape[1] 
         self.m = H.shape[1]
         self.F = F # 將F的值賦給對象self.F
         self.H = H # 將H的值賦給對象self.H
         # 若未指定永丝,則定義控制矩陣為0矩陣
         self.B = 0 if B is None else B
         # 若未定義3個協(xié)方差矩陣P锹漱、Q、R慕嚷,則定義為與F矩陣維度一致的單位矩陣
         # 否則按原定義傳入
         self.Q = np.eye(self.n) if Q is None else Q
         self.R = np.eye(self.n) if R is None else R
         self.P = np.eye(self.n) if P is None else P
         # 若未定義初值x0哥牍,則定義為0向量
         self.x = np.zeros((self.n, 1)) if x0 is None else x0
      
      # 預(yù)測模塊毕泌,也就是使用系統(tǒng)運動模型進行估計
      def predict(self, u = 0):
         # 實現(xiàn)公式x(k|k-1)=F(k-1)x(k-1)+B(k-1)u(k-1)
         # np.dot(F,x)用于實現(xiàn)矩陣乘法
         self.x = np.dot(self.F, self.x) + np.dot(self.B, u)
         # 實現(xiàn)公式P(k|k-1)=F(k-1)P(k-1)F(k-1)^T+Q(k-1)
         # 在Python中,求A得轉(zhuǎn)置的語法為A.T
         # 在MATLAB中為A'
         self.P = np.dot(np.dot(self.F, self.P), self.F.T) + self.Q
         return self.x
      
      # 狀態(tài)更新模塊嗅辣,也就是使用觀測校正預(yù)測
      def update(self, z):
         # 新息公式y(tǒng)(k)=z(k)-H(k)x(k|k-1)
         y = z - np.dot(self.H, self.x)
         # 新息的協(xié)方差S(k)=H(k)P(k|k-1)H(k)^T+R(k)
         S = self.R + np.dot(self.H, np.dot(self.P, self.H.T))
         # 卡爾曼增益K=P(k|k-1)H(k)^TS(k)^-1
         # linalg.inv(S)用于求S矩陣的逆
         K = np.dot(np.dot(self.P, self.H.T), np.linalg.inv(S))
         # 狀態(tài)更新懈词,實現(xiàn)x(k)=x(k|k-1)+Ky(k)
         self.x = self.x + np.dot(K, y)
         # 定義單位陣
         I = np.eye(self.n)
         # 協(xié)方差更新,這里對式(35)進行了移項處理
         # P(k)=[I-KH(k)]P(k|k-1)
         self.P = np.dot(np.dot(I - np.dot(K, self.H), self.P), \
         (I - np.dot(K, self.H)).T) + np.dot(np.dot(K, self.R), K.T)

   # 卡爾曼濾波仿真
   def example():
      # 離散化處理辩诞,dt為采用周期
      dt = 1.0/60
      # 以下均為賦初值的過程
      F = np.array([[1, dt, 0], [0, 1, dt], [0, 0, 1]])
      H = np.array([1, 0, 0]).reshape(1, 3)
      Q = np.array([[0.05, 0.05, 0.0], [0.05, 0.05, 0.0], [0.0, 0.0, 0.0]])
      R = np.array([0.5]).reshape(1, 1)
      x = np.linspace(-10, 10, 100)
      # 加入噪聲的觀測
      measurements = - (x**2 + 2*x - 2)  + np.random.normal(0, 2, 100)
      # 將無噪聲的觀測作為真值
      actual = - (x**2 + 2*x - 2)
      
      # 動用我們之前定義的類:卡爾曼濾波器
      # 預(yù)測
      kf = KalmanFilter(F = F, H = H, Q = Q, R = R)
      predictions = []
      error = []
    
      #使用觀測更新預(yù)測
      for z in measurements:
         predictions.append(np.dot(H, kf.predict())[0])
         kf.update(z)
      
      # 求估計誤差
      for i in range(len(actual)):
         error.append(actual[i]-predictions[i])
    
      # 繪圖
      plt.plot(range(len(actual)),actual, label='真值')
      plt.plot(range(len(predictions)), np.array(predictions), label='最優(yōu)估計值')
      plt.legend()
      plt.show()
    
      # 作一個零向量用于對照
      zeros = []
      for j in range(len(actual)):
         zeros.append(0)
    
      plt.plot(range(len(error)),error,label='估計誤差')
      plt.plot(range(len(error)),zeros)
      plt.legend()
      plt.show()

   # 主程序運行
   if __name__ == '__main__':
      example()      
圖12:仿真結(jié)果.png

圖12所示坎弯,在算法經(jīng)過啟動階段后,預(yù)測值與實際值的變化值符合我們的最優(yōu)估計原則译暂。但是這種最優(yōu)依賴于理想的噪聲環(huán)境條件抠忘,在實際的應(yīng)用場景下,我們需要根據(jù)場景具體情況調(diào)整我們的算法外永。讀者如有余力崎脉,可以嘗試在此基礎(chǔ)上使用其他程序設(shè)計語言復(fù)現(xiàn)卡爾曼濾波算法。

我們也提供了更加簡潔的面向過程的Python復(fù)現(xiàn)源代碼和仿真結(jié)果(圖13)伯顶。

   # Python 3.7 編譯環(huán)境
   import numpy as np
   import matplotlib.pyplot as plt

   delta_t = 0.1                               # 每秒鐘采一次樣
   end_t = 7                                   # 時間長度
   time_t = end_t * 10                         # 采樣次數(shù)
   t = np.arange(0, end_t, delta_t)            # 設(shè)置時間數(shù)組

   u = 1                                       # 定義外界對系統(tǒng)的作用 加速度
   x = 1 / 2 * u * t ** 2                      # 實際真實位置

   v_var = 1                                   # 測量噪聲的方差
   # 創(chuàng)建高斯噪聲囚灼,精確到小數(shù)點后兩位
   v_noise = np.round(np.random.normal(0, v_var, time_t), 2)

   X = np.mat([[0], [0]])                      # 定義預(yù)測優(yōu)化值的初始狀態(tài)
   v = np.mat(v_noise)                         # 定義測量噪聲
   z = x + v                                   # 定義測量值(假設(shè)測量值=實際狀態(tài)值+噪聲)
   A = np.mat([[1, delta_t], [0, 1]])          # 定義狀態(tài)轉(zhuǎn)移矩陣
   B = [[1 / 2 * (delta_t ** 2)], [delta_t]]   # 定義輸入控制矩陣
   P = np.mat([[1, 0], [0, 1]])                # 定義初始狀態(tài)協(xié)方差矩陣
   Q = np.mat([[0.001, 0], [0, 0.001]])        # 定義狀態(tài)轉(zhuǎn)移(預(yù)測噪聲)協(xié)方差矩陣
   H = np.mat([1, 0])                          # 定義觀測矩陣
   R = np.mat([1])                             # 定義觀測噪聲協(xié)方差
   X_mat = np.zeros(time_t)                    # 初始化記錄系統(tǒng)預(yù)測優(yōu)化值的列表

   for i in range(time_t):
      # 預(yù)測
      X_predict = A * X + np.dot(B, u)        # 估算狀態(tài)變量
      P_predict = A * P * A.T + Q             # 估算狀態(tài)誤差協(xié)方差
      # 校正
      K = P_predict * H.T / (H * P_predict * H.T + R)     # 更新卡爾曼增益
      X = X_predict + K * (z[0, i] - H * X_predict)       # 更新預(yù)測優(yōu)化值
      P = (np.eye(2) - K * H) * P_predict                 # 更新狀態(tài)誤差協(xié)方差
      # 記錄系統(tǒng)的預(yù)測優(yōu)化值
      X_mat[i] = X[0, 0]

   plt.rcParams['font.sans-serif'] = ['kaiti']    # 設(shè)置正常顯示中文
   plt.plot(x, "b", label='實際狀態(tài)值')            # 設(shè)置曲線數(shù)值
   plt.plot(X_mat, "g", label='預(yù)測優(yōu)化值')
   plt.plot(z.T, "r--", label='測量值')
   plt.xlabel("時間")                             # 設(shè)置X軸的名字
   plt.ylabel("位移")                             # 設(shè)置Y軸的名字
   plt.legend()                                   # 設(shè)置圖例
   plt.show()                                     # 顯示圖表
圖13:另一組仿真結(jié)果.png

5 結(jié)語

到這里,我們已經(jīng)了解了卡爾曼濾波(離散情況)的思想祭衩、過程和實現(xiàn)方法灶体。這一濾波算法的兩大特點——

  • 線性遞推

  • 最小方差無偏估計

分別通過(1)用上一時刻的最優(yōu)估計值和當前時刻的觀測值來估計本時刻的最優(yōu)估計值(2)使狀態(tài)估計的偏差為0且方差最小 體現(xiàn)出來。由于只用存儲上一時刻的預(yù)測和本時刻的觀測掐暮,使得卡爾曼濾波算法占用空間很小蝎抽,且可以保證較高的準確性(圖12),因此適用于嵌入式系統(tǒng)和解決實時問題路克。當然樟结,這種準確性建立在我們對噪聲(誤差)的假設(shè)上。在實際應(yīng)用中精算,我們將對其進行優(yōu)化調(diào)整來解決問題瓢宦,但上述的兩大思想是不變的。

6 參考文獻

[1] Bzarg,Bot圖說卡爾曼濾波灰羽,一份通俗易懂的教程[EBOL].[2018-07-17].https://zhuanlan.zhihu.com/p/39912633?utm_source=wechat_session&utm_medium=social&utm_oi=834493203137826816
[2] 云羽落驮履,如何通俗并盡可能詳細地解釋卡爾曼濾波?[EBOL].[2019-10-04].https://www.zhihu.com/question/23971601


  1. 統(tǒng)計學(xué)上谦趣, 最小方差無偏估計(Minimum-Variance Unbiased Estimator, MVUE)是一個對于所有無偏估計中疲吸,擁有最小方差的無偏估計座每。若無論真實參數(shù)值\theta是多少前鹅,最小方差無偏估計(MVUE)都比其他不偏估計有更小或至多相等的方差,則稱此估計為一致最小方差無偏估計(Uniformly Minimum-variance Unbiased Estimator, UMVUE)峭梳。 ?

  2. 定義:在線性代數(shù)中舰绘,n乘n方陣“A”的跡蹂喻,是指“A”的主對角線各元素的總和(從左上方至右下方的對角線),例如: tr\left( A \right) =A_{1,1}+A_{2,2}+...+A_{n,n} 其中A_{i,j}代表在 i 行 j 列中的數(shù)值捂寿。同樣的口四,元素的跡是其特征值的總和,使其不變量根據(jù)選擇的基本準則而定秦陋。 ?

  3. 矩陣的跡的性質(zhì):跡是一種線性算子蔓彩。亦即,對于任兩個方陣A驳概、B和標量r赤嚼,會有下列關(guān)系: 1.主對角線不會在轉(zhuǎn)置矩陣中被換掉,所以所有的矩陣和其轉(zhuǎn)置矩陣都會有相同的跡顺又。2.tr\left( A+B \right) =tr\left( A \right) +tr\left( B \right) 3.tr\left( rA \right) =rtr\left( A \right) 4.\frac{\partial trAX}{\partial X}=A^T 5.\frac{\partial trAXB}{\partial X}=A^TB^T 6.\frac{\partial tr\left( X^TAX \right)}{\partial X}=\left( A^T+A \right) X 7.\frac{\partial tr\left( X^TAXB \right)}{\partial X}=AXB+A^TXB^T ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末更卒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子稚照,更是在濱河造成了極大的恐慌蹂空,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件果录,死亡現(xiàn)場離奇詭異上枕,居然都是意外死亡,警方通過查閱死者的電腦和手機弱恒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門姿骏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斤彼,你說我怎么就攤上這事分瘦。” “怎么了琉苇?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵嘲玫,是天一觀的道長。 經(jīng)常有香客問我并扇,道長去团,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任穷蛹,我火速辦了婚禮土陪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肴熏。我一直安慰自己鬼雀,他們只是感情好,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布蛙吏。 她就那樣靜靜地躺著源哩,像睡著了一般鞋吉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上励烦,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天谓着,我揣著相機與錄音,去河邊找鬼坛掠。 笑死赊锚,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的屉栓。 我是一名探鬼主播改抡,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼系瓢!你這毒婦竟也來了阿纤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夷陋,失蹤者是張志新(化名)和其女友劉穎欠拾,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骗绕,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡藐窄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酬土。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荆忍。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖撤缴,靈堂內(nèi)的尸體忽然破棺而出刹枉,到底是詐尸還是另有隱情,我是刑警寧澤屈呕,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布微宝,位于F島的核電站,受9級特大地震影響虎眨,放射性物質(zhì)發(fā)生泄漏蟋软。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一嗽桩、第九天 我趴在偏房一處隱蔽的房頂上張望岳守。 院中可真熱鬧箱玷,春花似錦帜讲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒙袍。三九已至,卻和暖如春嫩挤,著一層夾襖步出監(jiān)牢的瞬間害幅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工岂昭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留以现,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓约啊,卻偏偏與公主長得像邑遏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恰矩,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容