卡尔曼滤波器(Kalman Filters)

卡尔曼滤波器,这是一种使用噪声传感器测量(和贝叶斯规则)来生成未知量的可靠估计的算法(例如车辆可能在3秒内的位置)。

我们知道高斯方程包含两个主要参数:

  • 一个是平均数\mu
  • 一个是方差,通常写为平方值\sigma^2
    一般来说,高斯方程是这样的:

p(x) = \frac{1}{{ \sqrt {2\pi \sigma ^2 } }}e^{{ - ( {x - \mu } )^2 }/{2\sigma ^2 }}

我们将该方程的第一部分称为 系数,第二部分称为 指数。第二部分在定义高斯的形状时最为重要,而系数是一个归一化因子。

对于不确定的连续数量,例如自动驾驶汽车的预估位置,我们使用高斯方程来表示该数量的不确定性。方差越小,我们对数量越有把握。

# import math functions
from math import *
import matplotlib.pyplot as plt
import numpy as np

# gaussian function
def f(mu, sigma2, x):
    ''' f takes in a mean and squared variance, and an input x
       and returns the gaussian value.'''
    coefficient = 1.0 / sqrt(2.0 * pi *sigma2)
    exponential = exp(-0.5 * (x-mu) ** 2 / sigma2)
    return coefficient * exponential
# an example Gaussian
gauss_1 = f(10, 4, 8)
print(gauss_1)
绘制高斯分布图

由于我们的函数仅返回x的特定值的值,因此我们可以通过遍历x值范围并创建高斯分布值g的结果列表来绘制高斯分布图

# display a gaussian over a range of x values
# define the parameters
mu = 10
sigma2 = 4

# define a range of x values
x_axis = np.arange(0, 20, 0.1)

# create a corresponding list of gaussian values
g = []
for x in x_axis:
    g.append(f(mu, sigma2, x))

# plot the result 
plt.plot(x_axis, g)
新的均值和方差

该程序要接收两个均值和方差,并为高斯方程返回一个全新的、已更新的均值和方差。此步骤称为参数或测量更新,因为它是当初始置信度(由下面的蓝色高斯表示)与新信息(具有一定不确定性的测量,即橙色高斯))合并时发生的更新。
已知两个均值和方差: ( {\mu , \sigma^2 } ) , ({\ v , r ^2})
更新之后的公式:\mu ' = \frac{r^2\mu+\sigma^2v}{r ^2+\sigma^2}
\sigma^ {2'} = \frac{1}{\frac{1}{r^2}+\frac{1}{\sigma^2}}

更新的高斯将是这两个高斯的组合,其中新的均值介于两者之间,并且方差小于两个给定方差中的最小值。这意味着在测量之后,我们的新均值比初始置信度更加确定!

# import math functions
from math import *
import matplotlib.pyplot as plt
import numpy as np

# gaussian function
def f(mu, sigma2, x):
    ''' f takes in a mean and squared variance, and an input x
       and returns the gaussian value.'''
    coefficient = 1.0 / sqrt(2.0 * pi *sigma2)
    exponential = exp(-0.5 * (x-mu) ** 2 / sigma2)
    return coefficient * exponential
# the update function
def update(mean1, var1, mean2, var2):
    ''' This function takes in two means and two squared variance terms,
        and returns updated gaussian parameters.'''
    ## TODO: Calculate the new parameters
    new_mean = (var2 * mean1 + var1 * mean2) / (var1 + var2)
    new_var = 1 / (1 / var1 + 1 / var2)
    
    return [new_mean, new_var]
# display a gaussian over a range of x values
# define the parameters
mu = new_params[0]
sigma2 = new_params[1]

# define a range of x values
x_axis = np.arange(0, 20, 0.1)

# create a corresponding list of gaussian values
g = []
for x in x_axis:
    g.append(f(mu, sigma2, x))

# plot the result 
plt.plot(x_axis, g)
高斯函数移动

\mu +u \to \mu'
\sigma^2 + r^2 \to \sigma ^{2'}

收集一些新测量之后,执行参数更新,然后,下一步是将运动合并到我们的高斯计算中。回想一下,在我们判断机器人或自动驾驶汽车位置的时候:

  • 测量更新增加了 我们的判断确定性
  • 运动更新/预测降低了我们的判断确定性
    这是因为每次运动都有可能未达到或超越预期目的位置,并且由于运动的不准确性,我们最终会在每次运动后失去对确切位置的判断确定性。
# import math functions
from math import *
import matplotlib.pyplot as plt
import numpy as np

# gaussian function
def f(mu, sigma2, x):
    ''' f takes in a mean and squared variance, and an input x
       and returns the gaussian value.'''
    coefficient = 1.0 / sqrt(2.0 * pi *sigma2)
    exponential = exp(-0.5 * (x-mu) ** 2 / sigma2)
    return coefficient * exponential
# the update function
def update(mean1, var1, mean2, var2):
    ''' This function takes in two means and two squared variance terms,
        and returns updated gaussian parameters.'''
    # Calculate the new parameters
    new_mean = (var2*mean1 + var1*mean2)/(var2+var1)
    new_var = 1/(1/var2 + 1/var1)
    
    return [new_mean, new_var]
# the motion update/predict function
def predict(mean1, var1, mean2, var2):
    ''' This function takes in two means and two squared variance terms,
        and returns updated gaussian parameters, after motion.'''
    ## TODO: Calculate the new parameters
    new_mean = mean1 + mean2
    new_var = var1 + var2
    
    return [new_mean, new_var]

通过遍历一系列x值并创建高斯值 g的结果列表来绘制一个高斯图,如下所示。你可以尝试更改mu和sigma2的值,看一看会发生什么。

# display a gaussian over a range of x values
# define the parameters
mu = new_params[0]
sigma2 = new_params[1]

# define a range of x values
x_axis = np.arange(0, 40, 0.1)

# create a corresponding list of gaussian values
g = []
for x in x_axis:
    g.append(f(mu, sigma2, x))

# plot the result 
plt.plot(x_axis, g)
1D 卡尔曼滤波器代码

机器人在这个空间中移动时,它会通过执行以下循环来定位自己:

  1. 感测并执行测量更新任务
  2. 移动并执行动作更新任务
    实现此滤波器后,你应该看到,一个非常不确定的位置高斯会变为一个越来越确定的高斯,如下图所示。



    下面是常用的高斯方程和导入。

# import math functions
from math import *
import matplotlib.pyplot as plt
import numpy as np

# gaussian function
def f(mu, sigma2, x):
    ''' f takes in a mean and squared variance, and an input x
       and returns the gaussian value.'''
    coefficient = 1.0 / sqrt(2.0 * pi *sigma2)
    exponential = exp(-0.5 * (x-mu) ** 2 / sigma2)
    return coefficient * exponential

以下是update代码,该代码在合并初始置信度和新测量信息时执行参数更新。此外,完整的predict代码在合并一个运动后会对高斯值进行更新。

```python
# the update function
def update(mean1, var1, mean2, var2):
    ''' This function takes in two means and two squared variance terms,
        and returns updated gaussian parameters.'''
    # Calculate the new parameters
    new_mean = (var2*mean1 + var1*mean2)/(var2+var1)
    new_var = 1/(1/var2 + 1/var1)
    
    return [new_mean, new_var]
# the motion update/predict function
def predict(mean1, var1, mean2, var2):
    ''' This function takes in two means and two squared variance terms,
        and returns updated gaussian parameters, after motion.'''
    # Calculate the new parameters
    new_mean = mean1 + mean2
    new_var = var1 + var2
    
    return [new_mean, new_var]
初始不确定性

初始参数,其中包括初始位置估计mu 和平方方差sig。注意,初始估计设置为位置0,方差非常大;这是一种高度混乱的状态,就像我们在直方图滤波器中使用的 均匀 分布一样。

# measurements for mu and motions, U
measurements = [5., 6., 7., 9., 10.]
motions = [1., 1., 2., 1., 1.]

# initial parameters
measurement_sig = 4.
motion_sig = 2.
mu = 0.
sig = 10000.

## TODO: Loop through all measurements/motions
## Print out and display the resulting Gaussian 

# your code here
## TODO: Loop through all measurements/motions
# this code assumes measurements and motions have the same length
# so their updates can be performed in pairs
for n in range(len(measurements)):
    # measurement update, with uncertainty
    mu, sig = update(mu, sig, measurements[n], measurement_sig)
    print('Update: [{}, {}]'.format(mu, sig))
    # motion update, with uncertainty
    mu, sig = predict(mu, sig, motions[n], motion_sig)
    print('Predict: [{}, {}]'.format(mu, sig))

    
# print the final, resultant mu, sig
print('\n')
print('Final result: [{}, {}]'.format(mu, sig))
## Print out and display the final, resulting Gaussian 
# set the parameters equal to the output of the Kalman filter result
mu = mu
sigma2 = sig

# define a range of x values
x_axis = np.arange(-20, 20, 0.1)

# create a corresponding list of gaussian values
g = []
for x in x_axis:
    g.append(f(mu, sigma2, x))

# plot the result 
plt.plot(x_axis, g)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • 卡尔曼滤波在我当学生的时候就用过,但是当年我似乎就是套公式,没有理解其精髓,加之时间久了有点模糊,突然需要指导学生...
    Roger_罗杰阅读 83,802评论 41 159
  • 经过看各种博客和文章,让我最清楚明白的,是xiahouzuoxin 的博客,之后又看了一些国外的文献进行自己的理解...
    marine0131阅读 7,421评论 4 11
  • 预估器 我们希望可以最大限度地使用测量结果来估计移动物体的运动。所以,多个测量的累积可以让我们检测出不受噪声影响的...
    JasonDing阅读 6,775评论 4 10
  • 如果你将举行婚礼,那么今天你最想做的事情是什么呢? 我曾经以为新婚前将会是各种忙碌,随时脸上都充满了喜悦,联...
    贱癌入骨阅读 456评论 1 0
  • 之一夏日随感 像紧锁的眉头失去快乐的钥匙像忧郁的面庞没有了微笑的呵护 乌云绑架了天空想尽快打开夏日干瘪的喉咙哗哗的...
    闲不语阅读 204评论 0 8