提示:前面写了A*、Dijkstra算法
RRT的中文名为快速随机探索树,它的原理很简单,实际上就是维护一棵路径树:从起点开始,在空间中随机采样,并找到路径树上与采样点最接近且能与它无障碍地连接的点,连接这个点与采样点,将采样点加入路径树,直至终点附近区域被探索到。这种方式无法保证得到的路径是最优的。
RRT* 在RRT基础上做了改进,主要是进行了重新选择父节点和重布线的操作。试想在RRT中,我们的采样点最终与整棵树上和它最近的点连了起来,但这未必是最好的选择,我们的最终目的是让这个点与起点的距离尽可能近。RRT* 便对此做了改进,它在采样点加入路径树以后,以其为圆心画了一个小圈,考虑是否有更好的父节点,连到那些节点上能使起点到该点的距离更短(尽管那些节点并不是离采样点最近的点)。如果选择了更加合适的父节点,那么就把它们连接起来,并去除原来的连线(重布线)。
我的原理启蒙:RRT算法原理图解
根据这篇文章,班门弄斧自己推导一遍这个过程,加强理解:

- 在空间中随机采样
如图中的蓝色圆,将其作为目标点

- 确定生长树的生长方向
以刚刚生成的随机点为目标,遍历生长树上的现存节点,计算每个节点到该随机点的距离,筛选出距离最小的节点作为最近点。此时树上仅存在起点(一颗没发芽的种子),所以直接选取起点为最近点。以最近点和随机点的连线为生长方向,如图中红色箭头所示

- 向目标点生长
生长步长是固定的,可由程序决定,但不宜太大也不宜太小,太小的话路径规划时间长,太大则会略过目标点。从此时的最近点也就是起点沿着生长方向生长一个步长得到一个生长点(紫色圆)

- 循环1~2步
随机采样(蓝色圆形)

确定生长树的生长方向,图中共有两个点,红色和紫色圆,离目标点(蓝色)最近的是红色点,以最近点和随机点的连线为生长方向,如图中红色箭头所示

从此时的最近点也就是起点沿着生长方向生长一个步长得到一个生长点(紫色圆)

随机采样(蓝色圆形)

确定生长树的生长方向,以图中离目标点(蓝色)最近的点和随机点的连线为生长方向,如图中红色箭头所示,从此时的最近点也就是起点沿着生长方向生长一个步长得到一个生长点(紫色圆)

随机采样(蓝色圆形)

确定生长树的生长方向,以图中离目标点(蓝色)最近的点和随机点的连线为生长方向,如图中红色箭头所示

从此时的最近点也就是起点沿着生长方向生长一个步长得到一个生长点(紫色圆),但是生长点都长障碍物里面去了会发生碰撞,生长失败!

剔除该生长节点,此次生长作废,不合格,树不接受。

重复以上的步骤,直到有生长节点进入终点的设定邻域

不断追溯它们的父节点,可找到一条从起点到终点的安全路径。如图中绿色线所示

- 初始化整个空间,定义初始点、终点、采样点数、点与点之间的步长t等信息
- 在空间中随机产生一个点xrand
- 在已知树的点集合中找到距离这个随机点最近的点xnear
- 在xnear到xrand的直线方向上从xnear以步长t截取点xnew
- 判断从xnear到xnew之间是否存在障碍物,若存在则舍弃该点
- 将new点加入到树集合中
- 循环2~6,循环结束条件:有一个new点在终点的设定邻域内
- 初始化整个空间,定义初始点、终点、采样点数、点与点之间的步长t等信息

- 在空间中随机产生一个点xrand,这个点不能在tree_list里面,构建一个函数
- 在已知树的点集合中找到距离这个随机点最近的点xnear,构建一个函数
- 确定方向:在xnear到xrand的直线方向上从xnear以步长t截取点xnew,构建一个函数
- 判断从xnear到xnew之间是否存在障碍物,若存在则舍弃该点
- 循环,循环结束条件:有树节点在终点的设定固定邻域之内

- 循环以找到父节点,将这些点保存在routine_list列表中,并可视化

RRT算法只能找到一条可行路径,并不能保证找到一条最优路径,RRT* 算法在RRT算法的基础上增加了两步:rewrite和random relink。也就是重写和随机重连。
重写就是在新节点xnew加入到树种之后,重新为它选择父节点,好让它到起始点的路径长度(代价)更小。
随机重连就是在重写完成之后,对新节点xnew附近一定范围内的节点进行重连。重连就是,检查一下如果把xnew附近的这些节点的父节点设置为xnew,这些节点的代价会不会减小。如果能够减小,就把这些节点的父节点更改为xnew;否则,就不更改。RRT* 算法考虑每一个节点到出发点的距离,为此每一个节点会增加一个属性:distance_to_start,即到出发点的距离。相应地在每一个节点选择父节点地时候,新节点的距离等于父节点的距离加上父节点到子节点的直线距离。
遍历整个树,
获得到新节点xnew的距离小于一定阈值(比如1.5倍的步长,也就是1.5*t)的所有节点
将这些节点加入到一个名为candidate_parent_of_newpoint的列表中,
为了方便,这些节点的distance不再用来存储到出发点的距离,而是用来存储如果把该节点设置为xnew的父节点的话,xnew到出发点的距离。
找到candidate_parent_of_newpoint列表中具有最小distance的那个节点,返回他的索引index,将新节点newpoint的父节点设置为index。
②random relink
遍历整个列表,对每一个节点执行如下动作{
if(该节点到xnew的距离小于一定的阈值,比如1.6倍的步长,也就是1.6*t){
if(该节点现在的distance>把该节点的父节点更新为newpoint之后的distance){
把该节点的父节点设置为xnew,并更新该节点的distance值
更新以该节点为根节点的子树中的每个节点的distance。
}
}
rewrite(重写):
random relink:
效果图:



版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/1324.html