传统的路径规划算法有人工势场法、模糊规则法、遗传算法、神经网络、模拟退火算法、蚁群优化算法等。但这些方法都需要在一个确定的空间内对障碍物进行建模,计算复杂度与机器人自由度呈指数关系,不适合解决多自由度机器人在复杂环境中的规划。基于快速扩展随机树(RRT / rapidly exploring random tree)的路径规划算法,通过对状态空间中的采样点进行碰撞检测,避免了对空间的建模,能够有效地解决高维空间和复杂约束的路径规划问题。该方法的特点是能够快速有效地搜索高维空间,通过状态空间的随机采样点,把搜索导向空白区域,从而寻找到一条从起始点到目标点的规划路径,适合解决多自由度机器人在复杂环境下和动态环境中的路径规划。与PRM类似,该方法是概率完备且不最优的。

  

  RRT是一种多维空间中有效率的规划方法。它以一个初始点作为根节点,通过随机采样增加叶子节点的方式,生成一个随机扩展树,当随机树中的叶子节点包含了目标点或进入了目标区域,便可以在随机树中找到一条由从初始点到目标点的路径。基本RRT算法如下面伪代码所示:

 function BuildRRT(qinit, K, Δq)
T.init(qinit)
for k = to K
qrand = Sample() -- chooses a random configuration
qnearest = Nearest(T, qrand) -- selects the node in the RRT tree that is closest to qrand
if Distance(qnearest, qgoal) < Threshold then
return true
qnew = Extend(qnearest, qrand, Δq) -- moving from qnearest an incremental distance in the direction of qrand
if qnew ≠ NULL then
T.AddNode(qnew)
return false function Sample() -- Alternatively,one could replace Sample with SampleFree(by using a collision detection algorithm to reject samples in C_obstacle
p = Random(, 1.0)
if < p < Prob then
return qgoal
elseif Prob < p < 1.0 then
return RandomNode()

  初始化时随机树T只包含一个节点:根节点qinit。首先Sample函数从状态空间中随机选择一个采样点qrand(4行);然后Nearest函数从随机树中选择一个距离qrand最近的节点qnearest(5行);最后Extend函数通过从qnearest向qrand扩展一段距离,得到一个新的节点qnew(8行)。如果qnew与障碍物发生碰撞,则Extend函数返回空,放弃这次生长,否则将qnew加入到随机树中。重复上述步骤直到qnearest和目标点qgaol距离小于一个阈值,则代表随机树到达了目标点,算法返回成功(6~7行)。为了使算法可控,可以设定运行时间上限或搜索次数上限(3行)。如果在限制次数内无法到达目标点,则算法返回失败。
  为了加快随机树到达目标点的速度,简单的改进方法是:在随机树每次的生长过程中,根据随机概率来决定qrand是目标点还是随机点。在Sample函数中设定参数Prob,每次得到一个0到1.0的随机值p,当0<p<Prob的时候,随机树朝目标点生长行;当Prob<p<1.0时,随机树朝一个随机方向生长。

  上述算法的效果是随机采样点会“拉着”树向外生长,这样能更快、更有效地探索空间(The effect is that the nearly uniformly distributed samples “pull” the tree toward them, causing the tree to rapidly explore C-Space)。随机探索也讲究策略,如果我们从树中随机取一个点,然后向着随机的方向生长,那么结果是什么样的呢?见下图(Left: A tree generated by applying a uniformly-distributed random motion from a randomly chosen tree node does not explore very far. Right: A tree generated by the RRT algorithm using samples drawn randomly from a uniform distribution. Both trees have 2000 nodes )。可以看到,同样是随机树,但是这棵树并没很好地探索空间。

  根据上面的伪代码,可以用MATLAB实现一个简单的RRT路径规划(参考这里)。输入一幅像素尺寸为500×500的地图,使用RRT算法搜索出一条无碰撞路径:

%% RRT parameters
map=im2bw(imread('map1.bmp')); % input map read from a bmp file. for new maps write the file name here
source=[10 10]; % source position in Y, X format
goal=[490 490]; % goal position in Y, X format
stepsize = 20; % size of each step of the RRT
threshold = 20; % nodes closer than this threshold are taken as almost the same
maxFailedAttempts = 10000;
display = true; % display of RRT if ~feasiblePoint(source,map), error('source lies on an obstacle or outside map'); end
if ~feasiblePoint(goal,map), error('goal lies on an obstacle or outside map'); end
if display,imshow(map);rectangle('position',[1 1 size(map)-1],'edgecolor','k'); end tic; % tic-toc: Functions for Elapsed Time RRTree = double([source -1]); % RRT rooted at the source, representation node and parent index
failedAttempts = 0;
counter = 0;
pathFound = false; while failedAttempts <= maxFailedAttempts % loop to grow RRTs
  %% chooses a random configuration
if rand < 0.5
sample = rand(1,2) .* size(map); % random sample
else
sample = goal; % sample taken as goal to bias tree generation to goal
end   %% selects the node in the RRT tree that is closest to qrand
[A, I] = min( distanceCost(RRTree(:,1:2),sample) ,[],1); % find the minimum value of each column
closestNode = RRTree(I(1),1:2);   %% moving from qnearest an incremental distance in the direction of qrand
theta = atan2(sample(1)-closestNode(1),sample(2)-closestNode(2)); % direction to extend sample to produce new node
newPoint = double(int32(closestNode(1:2) + stepsize * [sin(theta) cos(theta)]));
if ~checkPath(closestNode(1:2), newPoint, map) % if extension of closest node in tree to the new point is feasible
failedAttempts = failedAttempts + 1;
continue;
end if distanceCost(newPoint,goal) < threshold, pathFound = true; break; end % goal reached [A, I2] = min( distanceCost(RRTree(:,1:2),newPoint) ,[],1); % check if new node is not already pre-existing in the tree
if distanceCost(newPoint,RRTree(I2(1),1:2)) < threshold, failedAttempts = failedAttempts + 1; continue; end RRTree = [RRTree; newPoint I(1)]; % add node
failedAttempts = 0;
if display, line([closestNode(2);newPoint(2)],[closestNode(1);newPoint(1)]);counter = counter + 1; M(counter) = getframe; end % Capture movie frame
end % getframe returns a movie frame, which is a structure having two fields
if display && pathFound, line([closestNode(2);goal(2)],[closestNode(1);goal(1)]); counter = counter+1;M(counter) = getframe; end if display, disp('click/press any key'); waitforbuttonpress; end
if ~pathFound, error('no path found. maximum attempts reached'); end %% retrieve path from parent information
path = [goal];
prev = I(1);
while prev > 0
path = [RRTree(prev,1:2); path];
prev = RRTree(prev,3);
end pathLength = 0;
for i=1:length(path)-1, pathLength = pathLength + distanceCost(path(i,1:2),path(i+1,1:2)); end % calculate path length
fprintf('processing time=%d \nPath Length=%d \n\n', toc, pathLength);
imshow(map);rectangle('position',[1 1 size(map)-1],'edgecolor','k');
line(path(:,2),path(:,1));

  其它M文件:

%% distanceCost.m
function h=distanceCost(a,b)
h = sqrt(sum((a-b).^2, 2)); %% checkPath.m
function feasible=checkPath(n,newPos,map)
feasible=true;
dir=atan2(newPos(1)-n(1),newPos(2)-n(2));
for r=0:0.5:sqrt(sum((n-newPos).^2))
posCheck=n+r.*[sin(dir) cos(dir)];
if ~(feasiblePoint(ceil(posCheck),map) && feasiblePoint(floor(posCheck),map) && ...
feasiblePoint([ceil(posCheck(1)) floor(posCheck(2))],map) && feasiblePoint([floor(posCheck(1)) ceil(posCheck(2))],map))
feasible=false;break;
end
if ~feasiblePoint(newPos,map), feasible=false; end
end %% feasiblePoint.m
function feasible=feasiblePoint(point,map)
feasible=true;
% check if collission-free spot and inside maps
if ~(point(1)>=1 && point(1)<=size(map,1) && point(2)>=1 && point(2)<=size(map,2) && map(point(1),point(2))==1)
feasible=false;
end

  RRT算法也有一些缺点,它是一种纯粹的随机搜索算法对环境类型不敏感,当C-空间中包含大量障碍物或狭窄通道约束时,算法的收敛速度慢,效率会大幅下降:

  RRT 的一个弱点是难以在有狭窄通道的环境找到路径。因为狭窄通道面积小,被碰到的概率低。下图展示的例子是 RRT 应对一个人为制作的很短的狭窄通道,有时RRT很快就找到了出路,有时则一直被困在障碍物里面:

  上述基础RRT算法中有几处可以改进的地方:

  • how to sample from C-Space (line 4). 如何进行随机采样
  • how to define the “nearest” node in T (line 5). 如何定义“最近”点
  • how to plan the motion to make progress toward sample (line 8). 如何进行树的扩展

  Even a small change to the sampling method, for example, can yield a dramatic change in the running time of the planner. A wide variety of planners have been proposed in the literature based on these choices and other variations. 根据以上几个方向,多种RRT改进算法被提出。

  • Defining the Nearest Node

  查找最近点的基础是计算C-Space中两点间的距离。计算距离最直观的方法是使用欧氏距离,但对很多C-Space来说这样做的直观意义并不明显。Finding the “nearest” node depends on a definition of distance. A natural choice for the distance between two points is simply the Euclidean distance. For other spaces, the choice is less obvious. 举个例子,如下图所示,对于一个car-like robot来说其C-space为R2×S1.  虚线框分别代表三种不同的机器人构型:第一个构型绕其旋转了20°,第二个在它后方2米处,最后一个在侧方位1米处。那么哪一种距离灰色的目标“最近”呢?汽车型机器人的运动约束导致其不能直接进行横向运动和原地转动。因此,对于这种机器人来说从第二种构型移动到目标位置“最近”。

  从上面的例子可以看出来,定义一个距离需要考虑以下两点:

  • combining components of different units (e.g., degrees, meters, degrees/s,meters/s) into a single distance measure;
  • taking into account the motion constraints of the robot

  结合不同单位的一个简单办法是使用加权平均计算距离,不同分量的重要程度用权值大小表示(The weights express the relative importance of the different components)。寻找最近点在计算机科学和机器人学等领域中是一个非常普遍的问题,已经有各种用于加速计算的方法,比如K-d树、hash算法等。

  • The Sampler

  The reason that the tree ends up covering the entire search space (in most cases) is because of the combination of the sampling strategy, and always looking to connect from the nearest point in the tree. The choice of where to place the next vertex that you will attempt to connect to is the sampling problem. In simple cases, where search is low dimensional, uniform random placement (or uniform random placement biased toward the goal) works adequately. In high dimensional problems, or when motions are very complex (when joints have positions, velocities and accelerations), or configuration is difficult to control, sampling strategies for RRTs are still an open research area.

  •  The Local Planner

  The job of the local planner is to find a motion from qnearest to some point qnew which is closer to qrand. The planner should be simple and it should run quickly.

  • A straight-line planner. The plan is a straight line to qnew, which may be chosen at qrand or at a fixed distance d from qnearest on the straight line to qrand. This is suitable for kinematic systems with no motion constraints.

Bidirectional RRT / RRT Connect

  基本的RRT每次搜索都只有从初始状态点生长的快速扩展随机树来搜索整个状态空间,如果从初始状态点和目标状态点同时生长两棵快速扩展随机树来搜索状态空间,效率会更高。为此,基于双向扩展平衡的连结型双树RRT算法,即RRT_Connect算法被提出。

  该算法与原始RRT相比,在目标点区域建立第二棵树进行扩展。每一次迭代中,开始步骤与原始的RRT算法一样,都是采样随机点然后进行扩展。然后扩展完第一棵树的新节点

RRT路径规划算法的更多相关文章

  1. RRT路径规划算法(matlab实现)

    基于快速扩展随机树(RRT / rapidly exploring random tree)的路径规划算法,通过对状态空间中的采样点进行碰撞检测,避免了对空间的建模,能够有效地解决高维空间和复杂约束的 ...

  2. ROS(indigo)RRT路径规划

    源码地址:https://github.com/nalin1096/path_planning 路径规划 使用ROS实现了基于RRT路径规划算法. 发行版 - indigo 算法在有一个障碍的环境找到 ...

  3. 路径规划: PRM 路径规划算法 (Probabilistic Roadmaps 随机路标图)

    随机路标图-Probabilistic Roadmaps (路径规划算法) 路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法如: 1. A* 2. Djstar 3. ...

  4. 全局路径规划算法Dijkstra(迪杰斯特拉算法)- matlab

    参考博客链接:https://www.cnblogs.com/kex1n/p/4178782.html Dijkstra是常用的全局路径规划算法,其本质上是一个最短路径寻优算法.算法的详细介绍参考上述 ...

  5. DWA局部路径规划算法论文阅读:The Dynamic Window Approach to Collision Avoidance。

    DWA(动态窗口)算法是用于局部路径规划的算法,已经在ROS中实现,在move_base堆栈中:http://wiki.ros.org/dwa_local_planner DWA算法第一次提出应该是1 ...

  6. 基础路径规划算法(Dijikstra、A*、D*)总结

    引言 在一张固定地图上选择一条路径,当存在多条可选的路径之时,需要选择代价最小的那条路径.我们称这类问题为最短路径的选择问题.解决这个问题最经典的算法为Dijikstra算法,其通过贪心选择的步骤从源 ...

  7. PRM路径规划算法

    路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法:如人工势场法.单元分解法.随机路标图(PRM)法.快速搜索树(RRT)法等.传统的人工势场.单元分解法需要对空间中的 ...

  8. 路径规划算法之Bellman-Ford算法

    最近由于工作需要一直在研究Bellman-Ford算法,这也是我第一次用C++编写代码. 1.Bellman-Ford算法总结 (1)Bellman-Ford算法计算从源点(起始点)到任意一点的最短路 ...

  9. 机器人路径规划其一 Dijkstra Algorithm【附动态图源码】

    首先要说明的是,机器人路径规划与轨迹规划属于两个不同的概念,一般而言,轨迹规划针对的对象为机器人末端坐标系或者某个关节的位置速度加速度在时域的规划,常用的方法为多项式样条插值,梯形轨迹等等,而路径规划 ...

随机推荐

  1. SEM(搜索引擎营销)

    ylbtech-Miscellaneos:SEM(搜索引擎营销) 搜索引擎营销:英文Search Engine Marketing ,我们通常简称为“SEM”.就是根据用户使用搜索引擎的方式利用用户检 ...

  2. 样条之埃尔米特(Hermite)

    埃尔米特(Charles Hermite,1822—1901) 法国数学家.巴黎综合工科学校毕业.曾任法兰西学院.巴黎高等师范学校.巴黎大学教授.法兰西科学院院士.在函数论.高等代数.微分方程等方面都 ...

  3. CentOS6.4下安装Chrome

    因为蛋疼的glibc问题,(我就纳闷了,为何CentOS支持的glibc的版本就那么低呢,害得我至今还没把genymotion安装上), Chrome浏览器一直没安装上,不过终于找到了解决方案,安装派 ...

  4. ds18b20驱动及应用程序

    ---------------------------------------------------------------------------------------------------- ...

  5. 一个简易的WebServer程序

    现在这个公司的it管理真不知道说什么了,我主要从事.net方向的开发,公司电脑配置还是win7了,可是自己没有安装iis的权限,it也拒绝安装,想玩玩web安全都不行.于是乎决定开发一个window ...

  6. iOS开发-KVC和KVO的理解

    KVC和KVO看起来很专业,其实用起来还是比较简单的,KVC(Key-value coding)可以理解为键值对编码,如果对象的基本类型,那么键值对编码实际上和get,set方法没有区别,如果是属性是 ...

  7. Word Search leetcode java

    题目: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed fr ...

  8. Android -- EventBus使用

    EventBus EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信.比如请求网络,等网络返回时通过Handler ...

  9. Github用.gitignore忽略指定文件

    .gitignore Github提供.gitignore这种功能,可以自己指定哪些文件可以不被管理.具体方法是在版本管理的根目录下(与.git文件夹同级)创建一个.gitignore. 应用实例 项 ...

  10. Solidworks如何把装配体做成单个零件

    先把装配体另存为IGS格式   再把IGS打开之后另存为SLDPRT格式(打开IGS需要比较长的时间,中途会弹出提示,而且IGS文件体积也比较大)   另存为SLDPRT之后体积就很小了       ...