前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >卡尔曼滤波器(Kalman Filters)

卡尔曼滤波器(Kalman Filters)

作者头像
小飞侠xp
发布2018-10-22 15:58:20
1.5K0
发布2018-10-22 15:58:20
举报

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

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

  • 一个是平均数
\mu
\mu
  • 一个是方差,通常写为平方值
\sigma^2
\sigma^2

。 一般来说,高斯方程是这样的:

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

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

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

代码语言:javascript
复制
# 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
代码语言:javascript
复制
# an example Gaussian
gauss_1 = f(10, 4, 8)
print(gauss_1)
绘制高斯分布图

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

代码语言:javascript
复制
# 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 , \sigma^2 } ) , ({\ v , r ^2})

更新之后的公式:

\mu ' = \frac{r^2\mu+\sigma^2v}{r ^2+\sigma^2}
\mu ' = \frac{r^2\mu+\sigma^2v}{r ^2+\sigma^2}
\sigma^ {2'} = \frac{1}{\frac{1}{r^2}+\frac{1}{\sigma^2}}
\sigma^ {2'} = \frac{1}{\frac{1}{r^2}+\frac{1}{\sigma^2}}

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

代码语言:javascript
复制
# 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'
\mu +u \to \mu'
\sigma^2 + r^2 \to \sigma ^{2'}
\sigma^2 + r^2 \to \sigma ^{2'}

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

  • 测量更新增加了 我们的判断确定性
  • 运动更新/预测降低了我们的判断确定性 这是因为每次运动都有可能未达到或超越预期目的位置,并且由于运动的不准确性,我们最终会在每次运动后失去对确切位置的判断确定性。
代码语言:javascript
复制
# 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的值,看一看会发生什么。

代码语言:javascript
复制
# 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. 移动并执行动作更新任务 实现此滤波器后,你应该看到,一个非常不确定的位置高斯会变为一个越来越确定的高斯,如下图所示。

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

代码语言:javascript
复制
# 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代码在合并一个运动后会对高斯值进行更新。

代码语言:javascript
复制
```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]
代码语言:javascript
复制
# 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,方差非常大;这是一种高度混乱的状态,就像我们在直方图滤波器中使用的 均匀 分布一样。

代码语言:javascript
复制
# 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))
代码语言:javascript
复制
## 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)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.10.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 绘制高斯分布图
  • 新的均值和方差
  • 高斯函数移动
  • 1D 卡尔曼滤波器代码
  • 初始不确定性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档