1、kd-Tree基础

kd树(k-dimensional树的简称),是一种分割k维数据空间的数据结构,主要应用于多维空间关键数据的近邻查找(Nearest Neighbor)和近似最近邻查找(Approximate Nearest Neighbor)。

如果我们要处理的对象集合是一个K维空间中的数据集,我们首先需要确定是:怎样将一个K维数据划分到左子树或右子树?

在构造1维BST树类似,只不过对于Kd树,在当前节点的比较并不是通过对K维数据进行整体的比较,而是选择某一个维度d,然后比较两个K维数据在该维度 d上的大小关系,即每次选择一个维度d来对K维数据进行划分,相当于用一个垂直于该维度d的超平面将K维数据空间一分为二,平面一边的所有K维数据 在d维度上的值小于平面另一边的所有K维数据对应维度上的值。也就是说,我们每选择一个维度进行如上的划分,就会将K维数据空间划分为两个部分,如果我 们继续分别对这两个子K维空间进行如上的划分,又会得到新的子空间,对新的子空间又继续划分,重复以上过程直到每个子空间都不能再划分为止。以上就是构造 Kd-Tree的过程,上述过程中涉及到两个重要的问题:

每次对子空间的划分时,怎样确定在哪个维度上进行划分;
在某个维度上进行划分时,怎样确保建立的树尽量地平衡,树越平衡代表着分割得越平均,搜索的时间也就是越少。

1、在哪个维度上进行划分?
一种选取轴点的策略是median of the most spread dimension pivoting strategy,统计样本在每个维度上的数据方差,挑选出对应方差最大值的那个维度。数据方差大说明沿该坐标轴方向上数据点分散的比较开。这个方向上,进行数据分割可以获得最好的平衡。

2、怎样确保建立的树尽量地平衡?
给定一个数组,怎样才能得到两个子数组,这两个数组包含的元素 个数差不多且其中一个子数组中的元素值都小于另一个子数组呢?方法很简单,找到数组中的中值(即中位数,median),然后将数组中所有元素与中值进行 比较,就可以得到上述两个子数组。同样,在维度d上进行划分时,划分点(pivot)就选择该维度d上所有数据的中值,这样得到的两个子集合数据个数就基本相同了。

因此,kdtree的构建如下:

1)、在K维数据集合中选择具有最大方差的维度k,然后在该维度上选择中值m为pivot对该数据集合进行划分,得到两个子集合;同时创建一个树结点node,用于存储;
2)、对两个子集合重复(1)步骤的过程,直至所有子集合都不能再划分为止;

2、amcl与kd-Tree

了解了kd树,那么kd树与amcl之间有什么关系呢?

在amcl中,对于每个粒子滤波器对象都有两个粒子集合,该粒子集合是为后续Resampling时,能将其中一个粒子集合作为缓存集合使用。但是由于每个粒子集合中包含的粒子数量很大(比如5000个粒子,可自定义),因此每个粒子的权重即使在多次Resampling之后都还是很小,并且这也将导致位置上相邻的粒子的权重差值不大,从而使粒子滤波器在最后输出预测位姿时不准确。

为了解决这个问题,在Ros的代码中便引入了一个新的结构体(Cluster)。Cluster是相邻粒子的一个集合,其具有权重与位姿等属性,与粒子相似。而其位姿是通过该Cluster中包含的粒子的位姿加权平均得到。由于初始化时粒子在地图上的位置是通过均匀分布得到,所以此时Cluster的数量与粒子数量相等,即每一个Cluster中只有一个粒子。 而当粒子在地图上产生聚合后,Cluster的数量就会急剧下降,此时选取权重最大的Cluster作为粒子滤波器的输出结果。

为了能高效存储粒子信息,并且能将相邻的粒子进行聚类分析,因此需要引入KD-Tree数据结构。

3、amcl中kd-Tree的插入流程

插入数据的基本流程:

1)新数据(pose, weight)加进来,计算key值,这里的key值其实就是pose的放大版;2)如果是第一个数据,此时根节点为空,所以生成第一个节点,并初始化,设置leaf=1,为叶子节点,也是root节点,相应的count增加;第一个数据插入完成3)第二个数据进来,重复14)此时根节点存在,且为叶子节点,判断第二个数据的key值是否等于根节点的key值,若等于,则更新根节点的value值,即同一个key值,权重累加。若不等于,则要根据key差值最大的维度划分左右子节点。4.1)计算key[i]的差值,确定是在(x,y,theta)中的一个维度继续进行划分,注意,这个划分就相当于直方图中划分不同组距。4.2)如当前key的某个维度的值大于根节点的key的值,则为右节点,根变成左节点;反之。(二叉排序树)4.3)左右子节点执行递归调用,对新生成的两个子节点初始化(执行2)4.4)将根节点的叶子节点的标识设置为0,因为此时已经不再是叶子节点了。第二个数据插入完成,此时树的状态是两个左右子节点,同时,第一个插入的节点根节点又是子节点,第二个节点是叶子节点。5)第三个数据进来,重复16)此时根节点存在,且存在子节点,判断根节点的划分维度的key值与当前插入数据的key值比较,然后递归调用。第三个数据插入按照前面的流程进行,此时第一个或第二个节点成为root,与第三个节点比较插入。7)所有数插入完成。

参考:

https://blog.csdn.net/qq_34107425/article/details/106321837
https://www.cnblogs.com/havain/p/15010138.html
https://www.jianshu.com/p/ba79ebddd93c

AMCL代码详解(七)amcl中的kd-Tree相关推荐

  1. maskrcnn_benchmark 代码详解(更新中...)

    前言: maskrcnn_benchmark是faceboock公司编写的一套用于目标检索的框架,该框架集成了目前用到的大部分使用深度卷积网络来进行目标检测的模型,其中包括Fast RCNN, Fas ...

  2. AMCL代码详解(六)amcl中的重采样

    1.重采样判断 上一章讲述了amcl中如何根据激光观测更新粒子权重,当粒子更新完后amcl会需要根据程序判断是否需要进行重采样.这个判断在粒子观测更新权重后进行判断,代码在amcl_node.cpp中 ...

  3. AMCL代码详解(三)创建粒子模型

    AMCL中创建粒子模型的方式有两种: 1.高斯分布模型 第一种方式的模型主要使用了高斯模型去建立了一系列粒子点: // // 使用高斯模型(均值,协方差)初始化滤波器 void pf_init(pf_ ...

  4. AMCL代码详解(五)根据激光观测更新粒子权重

    上一篇中讲述了里程计在amcl中的作用,算法根据里程计反馈对每个粒子的位姿进行更新.在粒子更新后,则需要根据激光的观测数据对粒子的权重进行更新,这里主要看一下激光电云在amcl中的作用: 1.激光回调 ...

  5. PX4飞控中利用EKF估计姿态角代码详解

    PX4飞控中利用EKF估计姿态角代码详解 PX4飞控中主要用EKF算法来估计飞行器三轴姿态角,具体c文件在px4\Firmware\src\modules\attitude_estimator_ekf ...

  6. python批量删除文件名中的下划线-代码详解

    删除文件名中的下划线 代码示例: 代码详解 对于文件名中出现的"_",如(500_600),将下划线消除,替换为(500600) 代码示例: import osdef rename ...

  7. yolov3代码详解(七)

    Pytorch | yolov3代码详解七 test.py test.py from __future__ import divisionfrom models import * from utils ...

  8. html5代码转换为视频,HTML5中的视频代码详解

    摘要 腾兴网为您分享:HTML5中的视频代码详解,智学网,云闪付,易推广,小红书等软件知识,以及360win10,流量魔盒,fitbit,上港商城,安卓2.3.7,全民惠,五年级下册英语单词表图片,t ...

  9. yii mysql 事务处理_Yii2中事务的使用实例代码详解

    前言 一般我们做业务逻辑,都不会仅仅关联一个数据表,所以,会面临事务问题. 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全 ...

最新文章

  1. Facebook:易于解释的神经元可能会阻碍深度神经网络的学习
  2. 基于朴素贝叶斯的垃圾分类算法(Python实现)
  3. 【转】CSS 与 HTML5 响应式图片
  4. OpenCV textDetectionModel和textRecognitionModel API的端到端的实例(附完整代码)
  5. Design Compiler指南——预综合过程
  6. 导入安全证书到jdk
  7. intellij idea 最常用的快捷键
  8. html中实现类似于弹幕的效果代码,javascript实现弹幕效果
  9. 计算机里的文件中的桌面不见了,电脑重启桌面文件不见了怎么办
  10. python接收163邮件以及下载附件(以163邮箱为例)
  11. 深度学习之车牌识别(中国、越南)
  12. MSF之meterpreter权限维持
  13. 解决删除chrome注册表残留问题
  14. 2020-11-04编译器下载安装及使用
  15. 2020-3-17课堂笔记
  16. 八路扫描式抢答器设计
  17. hackthebox-shock(考点:shellshock perl提权)
  18. 百趣代谢组学文献解读-膜脂代谢对桃果实冷藏过程中冷害的影响
  19. php clicaptcha,php实现的Captcha验证码类实例
  20. Request.Cookies使用方法分析

热门文章

  1. html5 input与textarea标签及其属性
  2. 二维高斯核函数(python)
  3. 一个解密IC卡密码的方法
  4. 详谈什么是接口测试?
  5. Python中返回数字绝对值的方法abs()函数
  6. tf.TensorArray简单教程
  7. iPhone尺寸规格
  8. 常用sql语句(备忘)
  9. EmguCV学习(三)
  10. win高分屏下Qt程序的界面适配处理