作者: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)
我們用矢量來描述WALL-E的運動狀態(tài),這個列矢量
包括位置矢量
和速度矢量
兩個分量囤官。在WALL-E的問題上冬阳,我們現(xiàn)在不知道位置
和速度
的準確值,但是知道WALL-E的運動模型滿足狀態(tài)方程
党饮,定位的方法肝陪,也即觀測WALL-E運動狀態(tài)的方法滿足觀測方程
. 當然,我們也知道刑顺,這兩種方法都存在一定的誤差
氯窍,那么我們的問題就可以轉(zhuǎn)化為一個優(yōu)化問題——
在這一優(yōu)化問題中饲常,目標函數(shù)是要使預(yù)測(估計)誤差最小,同時約束于估計方法和
的條件下狼讨。在卡爾曼濾波中不皆,我們的估計原則(也就是最小化估計誤差的原則)是最小方差無偏估計[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)方程為
若采樣周期為渡蜻,則從時刻
到時刻
术吝,有
令,
茸苇,則離散化的狀態(tài)方程為
通過對線性系統(tǒng)的離散化處理排苍,我們現(xiàn)在可以考慮每一個時刻WALL-E的運動狀態(tài)。接下來学密,我們將用來表示在
時刻運動狀態(tài)的最優(yōu)估計值淘衙;用
表示用
時刻對
時刻的狀態(tài)預(yù)測值;用
表示對
時刻綜合預(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, 是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)自然也與之匹配。
但是某抓,如果模型對于測量狀態(tài)的估計值和測量值 有偏差怎么辦呢纸兔,我們引入控制論的思想,把測量狀態(tài)的真實值和測量值的差值 反饋回數(shù)學(xué)模型否副,對模型進行修正汉矿。
接下來,我們將這個實際的例子抽象一下备禀。
我們將測量狀態(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è):
則有實際目標變量的表達式:
數(shù)學(xué)模型中目標變量的表達式:
實際模型中測量變量的表達式:
數(shù)學(xué)模型中測量變量的表達式:
將目標變量的實際值和估計值相減:
將上述方程帶入誤差e的表達式昆箕,我們可得出誤差e的解析解:
從推導(dǎo)結(jié)果中我們不難看出迫淹,估計值和實際值的誤差隨時間呈指數(shù)形式變化秘通,當(F-KH)<1時,隨著時間的推移敛熬,會無限趨近于零肺稀,也就是意味著估計值和實際值相吻合。這就是為什么卡爾曼濾波器可以完美預(yù)測出目標狀態(tài)值的原理应民。
當然话原,有人會說,如果不引入這個卡爾曼增益诲锹,只要A<1繁仁,同樣會導(dǎo)致e收斂于0,這也就說明了卡爾曼濾波器的意義——更快減小預(yù)測的誤差归园,得到最優(yōu)值黄虱。
2.4 過程分析
在估計WALL-E位置的問題上,我們不知道位置和速度
的準確值庸诱,但是我們可以給出一個估計區(qū)間(圖5.a)捻浦。卡爾曼濾波假設(shè)所有的變量是隨機的且符合高斯分布(正態(tài)分布)桥爽。每個變量有一個均值
和一個方差
(圖5.b)朱灿。而圖5.c則表示速度和位置是相關(guān)的。
假如我們已知上一個狀態(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é)方差矩陣
描述(圖6)处嫌。
我們假設(shè)系統(tǒng)狀態(tài)的分布為高斯分布(正態(tài)分布)栅贴,所以在時刻我們需要兩個信息:最佳預(yù)估值
及其協(xié)方差矩陣
(如式(2)所示)。
下一步熏迹,我們需要通過時刻的狀態(tài)來預(yù)測
時刻的狀態(tài)檐薯。請注意,我們不知道狀態(tài)的準確值,但是我們的預(yù)測函數(shù)并不在乎坛缕,它僅僅是對
時刻所有可能值的范圍進行預(yù)測轉(zhuǎn)移墓猎,然后得出一個k時刻新值的范圍。在這個過程中赚楚,位置
和速度
的變化為
我們可以通過一個狀態(tài)轉(zhuǎn)移矩陣來描述這個轉(zhuǎn)換關(guān)系
同理毙沾,我們更新協(xié)方差矩陣為
2.4.2 考慮系統(tǒng)控制情況時的狀態(tài)描述
到目前為止,我們考慮的都是勻速運動的情況宠页,也就是系統(tǒng)沒有對WALL-E的運動狀態(tài)進行控制的情況左胞。那么,如果系統(tǒng)對WALL-E進行控制举户,例如發(fā)出一些指令啟動或者制動輪子烤宙,對這些額外的信息,我們可以通過一個向量來描述這些信息俭嘁,并將其添加到我們的預(yù)測方程里作為一個修正躺枕。假如我們通過發(fā)出的指令得到預(yù)期的加速度
,運動狀態(tài)方程就更新為
引入矩陣表示為
式中稱為控制矩陣供填,
稱為控制向量(例如加速度
)拐云。當然,如果沒有任何外界動力影響的系統(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)。可以這樣描述------
中的每個點移動到一個符合方差
的高斯分布里(圖7.b)欧芽。換言之莉掂,我們把這些不確定因素描述為方差為
的高斯噪聲,并用
表示渐裸。這樣就會產(chǎn)生一個新的高斯分布巫湘,方差不同,但是均值相同(圖7.c)昏鹃。
通過對的疊加擴展尚氛,得到完整的預(yù)測轉(zhuǎn)換方程為
新的預(yù)測轉(zhuǎn)換方程只是引入了已知的系統(tǒng)控制因素。新的不確定性可以通過之前的不確定性計算得到洞渤。到這里阅嘶,我們得到了一個模糊的估計范圍------通過和
描述的范圍。
2.4.4通過觀測校正預(yù)測
我們之前的工作仍然是在使用運動模型一種方法來估計系統(tǒng)的狀態(tài)载迄,現(xiàn)在讯柔,我們要把另一種方法,也就是觀測(本問題中為GPS定位)考慮進來护昧,以進一步修正對運動狀態(tài)的估計(圖8)魂迄。
我們用矩陣來描述觀測方法的作用,于是有
再加入觀測噪聲惋耙,觀測方程為
從控制論的角度出發(fā)捣炬,我們定義新息(也即觀測值與預(yù)測值的誤差)為
當然我們也知道,觀測本身也會存在誤差绽榛,比如本問題中的GPS定位精度僅有10m. 因此湿酸,我們用矩陣來描述這種不確定性(圖10及圖11.a)。
這時灭美,我們新息的協(xié)方差為
現(xiàn)在我們需要把兩種方法得到的可能性融合起來(圖11.b)推溃。對于任何狀態(tài),有兩個可能性:1. 傳感器的觀測值更接近系統(tǒng)真實狀態(tài)届腐;2. 模型推算的估計值更接近系統(tǒng)真實狀態(tài)铁坎。如果有兩個相互獨立的獲取系統(tǒng)狀態(tài)的方式,并且我們想知道兩者都準確的概率值犁苏,于是我們可以通過加權(quán)來解決更相信誰的問題(圖11.c)厢呵。
我們現(xiàn)在知道,系統(tǒng)模型的狀態(tài)預(yù)測與對系統(tǒng)的狀態(tài)觀測
服從高斯分布傀顾,把這個問題抽象一下就是——
根據(jù)我們的一個估計準則------最小方差估計襟铭,那么這個問題可以轉(zhuǎn)化為優(yōu)化問題求解
求導(dǎo)數(shù)(差分)得
則,從而
當維度高于一維時,我們用矩陣來描述寒砖,有
這里的稱為卡爾曼增益(Kalman Gain)赐劣,也就是我們在解決更信任哪種方法時的偏向程度。
如果我們從兩個獨立的維度估計系統(tǒng)狀態(tài)哩都,那么根據(jù)系統(tǒng)模型的預(yù)測為
通過傳感器的觀測為
我們結(jié)合著兩種方法得到
由可知魁兼,卡爾曼增益為
將約去(
中也含有
項),得
此時的卡爾曼增益實際為
我們最后再來驗證一下估計的無偏性——
這里我們設(shè)時刻的真值為
漠嵌,由于
由于(從初值而來的無偏傳遞性)可知
咐汞,即卡爾曼濾波滿足無偏估計準則。顯然儒鹿,其中要求系統(tǒng)噪聲和觀測噪聲是不相關(guān)化撕、零期望的白噪聲,且是線性系統(tǒng)约炎,初始時刻的狀態(tài)估計是無偏的植阴。當這些條件不能滿足時,卡爾曼濾波的估計結(jié)果是有偏的圾浅。
2.5 過程整理
到這里掠手,我們已經(jīng)獲得了卡爾曼濾波的全部要素。我們可以把整個過程總結(jié)為3個基本假設(shè)
假設(shè)一和
都是零均值高斯白噪聲狸捕,也即
喷鸽,
假設(shè)二與
無關(guān),也即
假設(shè)三系統(tǒng)初值的均值和方差已知灸拍,且
與
均不相關(guān)做祝。
以及5個基本方程 方程一狀態(tài)預(yù)測
方程二協(xié)方差預(yù)測
方程三卡爾曼增益
方程四狀態(tài)更新
方程五協(xié)方差更新
3 數(shù)學(xué)推導(dǎo)
協(xié)方差矩陣的對角線元素就是方差。把矩陣P的對角線元素求和株搔,定義為矩陣的跡[2][3]剖淀。
最小均方差就是使得上式最小纯蛾,對未知量K求導(dǎo),令導(dǎo)函數(shù)等于0纤房,就能找到K的值。
注意這個計算式翻诉,轉(zhuǎn)換矩陣
式常數(shù)炮姨,測量噪聲協(xié)方差
也是常數(shù)。因此
的大小將與預(yù)測值的誤差協(xié)方差有關(guān)碰煌。不妨進一步假設(shè)舒岸,上面式子中的矩陣維數(shù)都是1*1大小的,并假
=1芦圾,
不等于0蛾派。那么
可以寫成如下:
所以越大,那么
就越大,權(quán)重將更加重視反饋洪乍,如果
等于0眯杏,也就是預(yù)測值和真實值相等,那么
壳澳,估計值就等于預(yù)測值(先驗)岂贩。
將計算出的這個K反代入Pk中,就能簡化Pk巷波,估計協(xié)方差矩陣Pk的:
因此遞推公式中每一步的K就計算出來了萎津,同時每一步的估計協(xié)方差也能計算出來。但K的公式中好像又多了一個我們還未曾計算出來的東西 他稱之為預(yù)測值和真實值之間誤差的協(xié)方差矩陣抹镊。它的遞推計算如下:
由此也得到了$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所示坎弯,在算法經(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() # 顯示圖表
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
-
統(tǒng)計學(xué)上谦趣, 最小方差無偏估計(Minimum-Variance Unbiased Estimator, MVUE)是一個對于所有無偏估計中疲吸,擁有最小方差的無偏估計座每。若無論真實參數(shù)值
是多少前鹅,最小方差無偏估計(MVUE)都比其他不偏估計有更小或至多相等的方差,則稱此估計為一致最小方差無偏估計(Uniformly Minimum-variance Unbiased Estimator, UMVUE)峭梳。 ?
-
定義:在線性代數(shù)中舰绘,n乘n方陣“A”的跡蹂喻,是指“A”的主對角線各元素的總和(從左上方至右下方的對角線),例如:
其中
代表在 i 行 j 列中的數(shù)值捂寿。同樣的口四,元素的跡是其特征值的總和,使其不變量根據(jù)選擇的基本準則而定秦陋。 ?
-
矩陣的跡的性質(zhì):跡是一種線性算子蔓彩。亦即,對于任兩個方陣A驳概、B和標量r赤嚼,會有下列關(guān)系: 1.主對角線不會在轉(zhuǎn)置矩陣中被換掉,所以所有的矩陣和其轉(zhuǎn)置矩陣都會有相同的跡顺又。2.
3.
4.
5.
6.
7.
?