Localization (using Histogram Filters)

定位指的是在传感器和移动之间来回的迭代,使得能够保持跟踪目标对象的位置、方向和速度。

这篇将写一个程序来实施定位,与GPS相比,这个的程序将极大的降低误差范围。

假设一个汽车或者机器人所处在一个一维世界,它在没有得到任何提示在哪一位置。通过一个函数对这个问题建模,纵轴表概率,横轴表这个一维世界里所有位置,利用一个当值函数给这个一维世界每一个地方分配相同权重。

为了定位必须引入其他特征,假设有三个看起来相似的门,可以从非门区域 区分一扇门,(brlief  = 信度),机器人感受到了它在一扇门的旁边,它分配这些地点更大的概率。门的度量改变了信度函数,得到新函数像这样,三个临近门的位置信度递加,其他所有地方信度递减,posterior bilief 表示它是在机器人进行感测测量后定义的。

如果机器人移动了,那么凸起的信度也会随之移动(所在位置的概率),而且凸起会因为机器人只是粗略地知道移动了多远而变得扁平化,这个过程叫卷积,卷积就是两个函数或措施的重叠,具体的说是一个函数划过另一个函数的重叠占比,介于0~1之间(CONVOLUTION 卷积)

假设汽车或机器人发现它的右边再一次靠近一扇门,此时在先于第二次测量的信度上乘以一个函数,函数如下,它在每一扇门下都有一个很小的凸起,但却有一个非常大的凸起。在先验上这是唯一一个真的很符合这个门的位置,所以其他的门有一个很低的信度,Posterior  belief 先验信度

重要的是仍然不能确定我们的位置,但是之后,会比一次或零次测量之后的测量更确定。 你认为在做了越来越多的测量后会发生什么?

这种定位称为Monte Carlo 定位,也称为直方图滤镜。


用Python程序化

sense( )


新建一个列表,在这个一维世界中,假设有5个不同的单元或者说地方,用X1~X5标识,机器人落在每个单元的概率相同,概率的和加起来是1,P(Xi)表示落在其中任何一个单元格的概率。

 #初始化向量
P = [0.2,0.2,0.2,0.2,0.2]
#创造一个长度为n的向量,可以通过变化n的值得到n个元素的向量
P =[ ]
n = ? for i in range(n)
p.append(1./n)
print p

有着5个单元格的一维世界的度量方式,假设有两个被染成红色,其他两个是绿色,分配给每一个单元的概率是0.2,现在机器人允许被感知,它先看到胡是红色,23的概率会上升,145的概率会下降,用乘法将这个度量合并到信度里。

可是这并不是一个有效的概率分布,因为概率加起来总要等于1。这些概率值的求和是0.36,为了变成有效的概率分布,把每个数除以0.36

通过引入一个变量使代码更加优雅,这个变量为每个小格指定红色或者绿色。

此外,先前说道机器人感觉到它在一个红色的区间里,所以这里定义测量到的值为红色。

然后,写一个叫sense的函数用在后面的定位器,它能对探测数据进行更新,输入初始分布p、探测值Z以及其他所有的全局变量,输出一个标准化分布q,q反应了输入概率的非标准化乘积

P = [0.2,0.2,0.2,0.2,0.2]
world = ['green','red','red','green','green']
#定义测量值为红色
Z = 'red'

pHit = 0.6
pMiss = 0. 2 def sense()
q = [ ]
for i in range(len(p)):
#用了一个二元标记,hit =0或1
hit = (Z == world[i])
#由于hit取0或1,所以每次只有一个算式成立
q.append[p[i]*(hit*pHit+(1-hit)*pMiss)]
#以下代码使输出标准化(和等于1)
s = sum(q)
for i in range(len(p)):
q[i] = q[i] / s
return q
print sense(p,z)

修改代码,通过用包含多个测量值的测量值向量替代Z

假设机器人感觉到红色,之后是绿色,修改代码使得更新两次概率,并在两次测量结合后给出后验分布,以便可以处理任何测量顺序,无论长度如何。

p = [0.2, 0.2, 0.2, 0.2, 0.2]
world = ['green', 'red', 'red', 'green', 'green'] 
#替代Z
measurements = ['red', 'green']
pHit = 0.6
pMiss = 0.2
def sense(p, Z):
    q = [ ]
    for i in range(len(p)):
        hit = (Z == world[i])
        q.append(p[i] * (hit * pHit + (1­hit) * pMiss))
    s = sum(q)
    for i in range (len(p)):
        q[i] = q[i]/s
    return q
#抓取测试值向量中元素用来更新自己的概率
for k in range(len(measurements)): 
    p = sense(p, measurements [k])
    print p 

这个sense()就是定位中的关键函数——测量更新函数,对每个测量值调用一次这个函数并且更新概率分布

 move( )


假设世界是循环的,空间的概率分布如下,并且知道机器人向右移动,若机器人向右移动一个位置,运动后的后验概率分布是多少?

定义move函数,输入初始分布p和运动量U,其中U是向右或向左移动的网格的数量,返回新分布q,如果U=0,q=p

将网格2的概率从0变为1,使得向右移动一格后,以观察到运动的效果

def move(p,U)
q = []
for i in range(len(p))
q.append(p[(i - U) % len(p)]) #a very skilled code
renturn q
for k in range(len(measurements)):
p = sense(p, measurements [k])
print move (p, 1)

机器人移动不是准确的,定位困难

需要建立更精确的机器人运动模型,假设机器人移动到目标地的概率是0.8,到目标地之前概率是0.1,超过目标概率是0.1。

已有初始分布,给出移动后的分布

如预期,概率分布已经转移和扩展。 移动导致信息丢失。

又一次,假设网格2和4的值为0.5,填充后验分布(也考虑了未达到和超过两种情况)。

再一次,给定均匀分布,填写移动后分布。

明确计算到达每格可能方式太复杂,换种思路,如果从统一的先前分配(最大混淆状态)开始,之后移动,必定最终得到均匀分布

p = [0, 1, 0, 0, 0)
world = ['green', 'red', 'red', 'green', 'green']
measurements = ['red', 'green']
pHit = 0.6
pMiss = 0.2
#Add exact probability
pExact = 0.8
#Add overshoot/undershoot probability
pOvershoot = 0.1
pUndershoot = 0.1 def move(p, U):
    #Introduce auxiliary variable s
    q= []
    for i in range(len(p)):
        s = pExact * p[(i­U) % len(p)]
        s = s + pOvershoot * p[(i-­U­-1) % len(p)]
        s = s + pUndershoot * p[(i­-U+1) % len(p)]
        q.append(s)
    return q

该函数适应了预期的低估或超调的可能性,通过遍历p中的每个网格并且在q中的三个单元上(目标网格,距离U以及过冲和下冲网格)适当地分配其概率来移动目的地。

从初始分布p = [0, 1, 0, 0, 0]开始,移动两次:

p = move(p, 1)
p = move(p, 1)
print p
>>>[0.01, 0.01, 0.16, 0.66, 0.16]

结果是一个向量,其中0.66是最大值,而不是0.8。 这是预期的:两次移动已经平坦化,扩大了分布。

而后编写移动一千步后得到的概率分布:

for k in range(1000):
    p = move(p, 1)
    print p
    #最终分布是如预期的每个网格0.2

 

机器人感知和移动


定位,特别是这里用到的Monte Carlo定位方法,只不过是传感器和移动的迭代,有一个初始的感知抛给循环。每次移动都会丢失信息(因为机器人的移动是不准确的),每次感知会获取信息,事实证明机器人移动之后概率会变得平展、延伸,感知之后会变得更加集中。 熵是衡量分布信息的度量。

机器人从均匀的的先前分部开始,再向右移动两次,首先感觉到是红色,然后感觉到是绿色, 计算后验分布

motions = [1, 1]
p = [0.2, 0.2, 0.2, 0.2, 0.2]
for k in range(len(measurements)):
    p = sense(p, measurements[k])
    p = move(p, motions[k])
    print p

查看结果概率分布,机器人最可能是从网格3出发

如果机器人感知到两次红色

 p=[0.2, 0.2, 0.2, 0.2, 0.2]
world=['green', 'red', 'red', 'green', 'green']
measurements = ['red', 'green']
motions = [1,1]
pHit = 0.6
pMiss = 0.2
pExact = 0.8
pOvershoot = 0.1
pUndershoot = 0.1 def sense(p, Z):
q=[]
for i in range(len(p)):
hit = (Z == world[i])
q.append(p[i] * (hit * pHit + (1-hit) * pMiss))
s = sum(q)
for i in range(len(q)):
q[i] = q[i] / s
return q def move(p, U):
q = []
for i in range(len(p)):
s = pExact * p[(i-U) % len(p)]
s = s + pOvershoot * p[(i-U-1) % len(p)]
s = s + pUndershoot * p[(i-U+1) % len(p)]
q.append(s)
return q for k in range(len(measurements)):
p = sense(p, measurements[k])
p = move(p, motions[k]) print p

结果表明机器人在网格4的概率大,也就是从网格2出发

这个代码就是Google自动驾驶定位代码的本质,也是精髓,特别重要的是,汽车准确知道它在哪里,对于它行驶的道路地图而言,虽然道路不能被涂成绿色或红色,但是道路有着路标代替红色绿色的格子,不仅是每一步一次的观察,而是整个场地的观察,整个照相机图片的观察,可以对照片做同样的事,只要能够将照片嵌入到模型当中,用在度量当中,也不会比这个代码难上多少代码,而Google花费这么多时间构建自动驾驶产品因为现实情况会很复杂,道路会正在铺设和重修,这些问题要处理。

定位总结


定位涉及机器人不断更新其对所有可能位置的感知。 在数学上说,可以说机器人不断更新其在样本空间上的概率分布。 对于一辆真正的自驾车,这意味着道路上的所有位置都有一个概率。

如果AI正常工作,这种概率分布应该有两个特征:

  1. 应该有一个尖峰。 这表明汽车对其当前位置有非常明确的感知。
  2. 峰值应该是正确的。

Monte Carlo定位程序可以写成一系列步骤:

  1. 从当前位置的感知开始
  2. 通过感知测量结果乘以这个分布
  3. 归一化所得到的分布
  4. 通过执行卷积移动。 这听起来比真的更复杂:这个步骤实则涉及乘法和加法,以获得每个新的概率位置。

两个数学方法


贝叶斯法则

在概率上,经常想在更新概率分布后测量。 有时这不容易直接做。

贝叶斯法则是进行测量后更新概率分布的工具。x是网格,Z是感知度量,贝叶斯法则方程式如下:

左边应该被读成“观察Z后的X的概率”,P(x)是先验分布,然后与P(Z|x)测量概率相乘,对于每个格子,可以放上下标i,P(Z)是每个格子如此操作后的和

一个用贝叶斯做癌症测试例子

全概率定理

上面是测量,再看移动,在这里要关注一个网格“xi”,并且询问机器人运动后在xi中的概率是什么。 现在,使用时间索引来表示运动前后:

P(Xi | Xj)是可从j到i的所有路径概率,利用这个定理在移动前就能算出概率分布

举个例子,抛一枚硬币,反面什么也不做。正面再抛一次,求第二次抛出正面概率

编写一个程序:

 # 定位函数用到了以下参数:
# colors:
# 2D 列表, 'R' (红色网格l) or 'G' (绿色网格)
# measurements:
# 机器人得到的测量值列表 ,'R' or 'G'
# motions:
# 机器人采取的动作列表,[dy,dx],dx表示x方向的变化(正向右移动),dy表 # 示y方向的变化(正向下移动)
#
# sensor_right:
# 测量是正确的概率,浮动在0和1之间,不正确的概率是1-sensor_right
# p_move:
# 执行移动命令的概率,浮动在0和1之间,运动命令失败的概率(仍保持原地)是
# 1-p_move; 机器人在本编程中不会超过目的地;
#
# 输出:函数返回与颜色列表尺寸相同的2D概率分布列表,最初是均匀的概率分布
#
# 每一步先行动,再测量,且任何行列是循环的 def localize(colors,measurements,motions,sensor_right,p_move):
sensor_wrong = 1.0 - sensor_right
p_stay = 1.0 - p_move if len(measurements) != len(motions)
raise ValueError,"error in size of measurement/motion vector" pinit = 1.0 / float(len(colors)) / float(len(colors[0]))
p = [[pinit for row in range(len(colors[0]))] for col in range(len(colors))] for k in range(len(measurements)):
p = move(p,measurements[k])
p = sense(p,colors,measurements[k]) show(p) def sense(p,colors,measurement):
aux = [[0.0 for row in range(len(0)) for col in range (len(p))]]
s = 0.0
for i in range(len(p)):
for j in range(len(p[i])):
hit = (measurement == colors[i][j])
aux = p[i][j]*(hit*sensor_right + (1-hit)*sensor_wrong)
s+=aux[i][j]
for i in range(len(aux)):
for j in range(len(p[i])):
aux[i][j] /= s
return aux def move(p,motion):
aux = [[0.0 for row in range(len(0)) for col in range (len(p))]]
for i in range(len(p)):
for j in range(len(p[i])):
aux = (p_move*p[i-motion[0] % len(p)][j - motion[1] % len(p[i])] + (p_stay*p[i][j]))
return aux def show(p):
rows = ['[' + ','.join(map(lambda x: '{0:.5f}'.format(x),r)) + ']' for r in p]
print '[' + ',\n '.join(rows) + ']'
def show(p)
for i in range(len(p))
print p[i] #############################################################
# For the following test case, your output should be
# [[0.01105, 0.02464, 0.06799, 0.04472, 0.02465],
# [0.00715, 0.01017, 0.08696, 0.07988, 0.00935],
# [0.00739, 0.00894, 0.11272, 0.35350, 0.04065],
# [0.00910, 0.00715, 0.01434, 0.04313, 0.03642]]
# (within a tolerance of +/- 0.001 for each entry) colors = [['R','G','G','R','R'],
['R','R','G','R','R'],
['R','R','G','G','R'],
['R','R','R','R','R']]
measurements = ['G','G','G','G','G']
motions = [[0,0],[0,1],[1,0],[1,0],[0,1]]
p = localize(colors,measurements,motions,sensor_right = 0.7, p_move = 0.8)

实际设计工作中怎样给这些概率赋值,例如pHit、pMiss等,从试验中获得还是传感器参数决定?

《概率机器人》--很大程度上由传感器决定,谷歌大量使用激光雷达作为传感器,但如果选择摄像机就需要用与测距仪不同的模型,使用激光雷达时测的是距离而非pHit、pMiss,它给出的是在特定位置测得特定距离的概率。

是否要求机器人内置地图?

yes,实时定位与地图创建SLAM

实际中的定位器是用来测什么的,显然不是一扇门?

汽车会内置地图,激光摄像头扫描周围场景,其中包含与内置地图相同的特征,要解决的概率匹配问题是将生成的附近地图叠加到全局地图上,检查能获得最佳匹配的位置。

全工况?

雨,调高亮度参数,雪,未解决

Localization的更多相关文章

  1. 论文阅读(Lukas Neuman——【ICDAR2015】Efficient Scene Text Localization and Recognition with Local Character Refinement)

    Lukas Neuman--[ICDAR2015]Efficient Scene Text Localization and Recognition with Local Character Refi ...

  2. 对 OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks 一文的理解

    一点最重要的学习方法:  当你读一篇论文读不懂时,如果又读了两遍还是懵懵懂懂时怎么办???方法就是别自己死磕了,去百度一下,如果是很好的论文,大多数肯定已经有人读过并作为笔记了的,比如我现在就把我读过 ...

  3. 【软件分析与挖掘】BOAT: An Experimental Platform for Researchers to Comparatively and Reproducibly Evaluate Bug Localization Techniques

    摘要: 目前有许多的bug定位技术,但是,由于他们基于不同的数据集,而且有些数据集还不是公开的,甚至有些技术只应用于小数据集,不具有通用性,因此,不好比较这些技术之间的优劣. 因此,BOAT应运而生. ...

  4. [SLAM] 01 "Simultaneous Localization and Mapping" basic knowledge

    发信人: leecty (Terry), 信区: ParttimeJobPost标 题: 创业公司招SLAM 算法工程师发信站: 水木社区 (Thu Jun 16 19:18:24 2016), 站内 ...

  5. 即时定位与地图构建SLAM(Simultaneous Localization and Mapping)

    SLAM 即时定位与地图构建SLAM(Simultaneous Localization and Mapping) 参考链接: 视觉SLAM漫谈,http://www.cnblogs.com/gaox ...

  6. 论文笔记之:Localizing by Describing: Attribute-Guided Attention Localization for Fine-Grained Recognition

    Localizing by Describing: Attribute-Guided Attention Localization for Fine-Grained Recognition Baidu ...

  7. 论文笔记之:Fully Convolutional Attention Localization Networks: Efficient Attention Localization for Fine-Grained Recognition

    Fully Convolutional Attention Localization Networks: Efficient Attention Localization for Fine-Grain ...

  8. 论文笔记之:Active Object Localization with Deep Reinforcement Learning

    Active Object Localization with Deep Reinforcement Learning ICCV 2015 最近Deep Reinforcement Learning算 ...

  9. dagli最早干了这样一件事儿 Localization of Cardiac-Induced Signal Change in fMRI

    Localization of Cardiac-Induced Signal Change in fMRI 这篇文章是最早做生理噪声相关组织的定位的. 很奇特,因为,这位学者甚至得出了,血管心动等变化 ...

  10. Orchard 源码探索(Localization)之国际化与本地化

    本地化与国际化 基本上相关代码都在在Orchard.Framework.Localization中. T("english")是如何调用到WebViewPage.cs中的Local ...

随机推荐

  1. Master公式计算递归时间复杂度

    我们在算递归算法的时间复杂度时,Master定理为我们提供了很强大的便利! Master公式在我们的面试编程算法中除了BFPRT算法的复杂度计算不了之外,其他都可以准确计算! 这里用求数组最大值的递归 ...

  2. redis排序

    1.sort 排序最常见的是sort命令,可以对列表或者有序集合排序,最简单的排序方式如下: > lpush list (integer) > lpush list (integer) & ...

  3. CSS样式学习-3、轮廓、伪类/元素、display-flex布局

    一.轮廓 outline绘制于元素周围的一条线,位于边框边缘外围. 属性规定元素轮廓的样式.颜色.宽度. outline-width轮廓宽度,属性:thin细轮廓.medium中等(默认值).thic ...

  4. Kettle安装Kafka Consumer和Kafka Producer插件

    1.从github上下载kettle的kafka插件,地址如下 Kafka Consumer地址: https://github.com/RuckusWirelessIL/pentaho-kafka- ...

  5. oracle数据链接

    using System; using System.Collections.Generic; using System.Data; using System.Data.OracleClient; u ...

  6. php 计算 距离

    function getdistance($lng1,$lat1,$lng2,$lat2){ //将角度转为狐度 $radLat1=deg2rad($lat1);//deg2rad()函数将角度转换为 ...

  7. 2018面向对象程序设计(Java)第18周学习指导及要求

    2018面向对象程序设计(Java) 第18周学习指导及要求(2018.12.27-2018.12.30)   学习目标 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设 ...

  8. 原子性: Interlocked 类

    public class CounterNoLock:CountBase { private int _count; public int Count { get { return _count; } ...

  9. 100-days: eighteen

    Title: Why India's election is among the world's most expensive election n.选举,当选,选举权 expensive adj.昂 ...

  10. 使用setx 命令添加环境变量(Windows)

    背景 用GUI的方法可能添加环境变量可能会比较麻烦,为此可采用命令行操作的方式. 步骤 以管理员身份运行 cmd 输入 setx /M "%path%" "%path%[ ...