RRT算法简介

RRT(快速探索随机树)是一种适用于各种机器人类型的通用路径规划方法。它能够在复杂的环境中快速探索并寻找路径,尤其擅长处理高维空间的问题。尽管生成的路径可能不够光滑且远离最优解,但其强大的探索能力和快速收敛特性使其成为机器人领域的重要工具。

声明:本文为转载内容非原创,来源会在文末声明,绝无冒犯之意,只为一时复习之方便,侵权必删!

感谢原作者写出如此优秀的博文,让我对RRT算法有个大致的理解。

对RRT算法感兴趣,是因为我对它不仅在二维平面上适用,在高维空间也能使用而感到心动,最近比较忙,下周或者什么时候要要用代码亲自实现一下。

 路径规划都有哪些方法呢?比较流行的有:图搜索、势场法、RRT 等等。 

   RRT(快速探索随机树) 是一种通用的方法,不管什么机器人类型、不管自由度是多少、不管约束有多复杂都能用。而且它的原理很简单,这是它在机器人领域流行的主要原因之一。不过它的缺点也很明显,它得到的路径一般质量都不是很好,例如可能包含棱角,不够光滑,通常也远离最优路径


RRT 能在众多的规划方法中脱颖而出,它到底厉害在哪里呢? 
  天下武功唯快不破,“快”是 RRT 的一大优点。RRT 的思想是快速扩张一群像树一样的路径以探索(填充)空间的大部分区域,伺机找到可行的路径。之所以选择“树”是因为它能够探索空间。我们知道,阳光几乎是树木唯一的能量来源。为了最大程度地利用阳光,树木要用尽量少的树枝占据尽量多的空间。当然了,能探索空间的不一定非得是树,比如Peano曲线也可以做到,而且要多密有多密,如上图左所示的例子。虽然像Peano曲线这样的单条连续曲线也能探索空间,但是它太“确定”了。在搜索轨迹的时候我们可不知道出路应该在哪里,如果不在“确定”的搜索方向上,我们怎么找也找不到(找到的概率是0)。这时“随机”的好处就体现出来了,虽然不知道出路在哪里,但是通过随机的反复试探还是能碰对的,而且碰对的概率随着试探次数的增多越来越大,就像买彩票一样,买的数量越多中奖的概率越大(RRT名字中“随机”的意思)。可是随机试探也讲究策略,如果我们从树中随机取一个点,然后向着随机的方向生长,那么结果是什么样的呢?见上图右。可以看到,同样是随机树,但是这棵树并没很好地探索空间,它一直在起点(红点)附近打转。这可不好,我们希望树尽量经济地、均匀地探索空间,不要过度探索一个地方,更不能漏掉大部分地方。这样的一棵树怎么构造呢? 

 RRT 的基本步骤是: 
  1. 起点作为一颗种子,从它开始生长枝丫; 
  2. 在机器人的“构型”空间中,生成一个随机点 A; 
  3. 在树上找到距离 AA 最近的那个点,记为 B 吧; 
  4. B 朝着 A的方向生长,如果没有碰到障碍物就把生长后的树枝和端点添加到树上,返回 2; 
  随机点一般是均匀分布的,所以没有障碍物时树会近似均匀地向各个方向生长,这样可以快速探索空间(RRT名字中“快速探索”的意思)。当然如果你事先掌握了最有可能发现路径的区域信息,可以集中兵力重点探索这个区域,这时就不宜用均匀分布了。 

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


 RRT探索空间的能力还是不错的,例如下图左所示的例子,障碍物多而且杂乱(借助 Mathematica 本身具有的强大函数库,实现这个例子所需的所有代码应该不会超过30行)。还有没有环境能难住RRT呢?下图右所示的迷宫对RRT就是个挑战。这个时候空间被分割得非常严重,RRT显得有些力不从心了,可见随机策略不是什么时候都有效的。 

  “随机”使得RRT有很强的探索能力。但是成也萧何败也萧何,“随机”也导致 RRT 很盲目,像个无头苍蝇一样到处乱撞。如果机器人对环境一无所知,那么采用随机的策略可以接受。可实际情况是,机器人对于它的工作环境多多少少是知道一些的(即使不是完全知道)。我的博客一直强调信息对于机器人的重要性。这些已知的信息就可以用来改进算法。一个改进的办法就是给它一双“慧眼”:在势场法中,势函数携带了障碍物和目标的信息,如果能把这个信息告诉 RRT,让它在探索空间时有倾向地沿着势场的方向前进会更好。这样,RRT 出色的探索能力刚好可以弥补势场法容易陷入局部极小值的缺点。


  将RRT方法用在机械臂上的效果如下图所示(绿色表示目标状态)。我设置了4个障碍物(其中一个是大地),这对机械臂是个小小的挑战。由于我们生活在三维空间,没办法看到六维关节空间,所以我把六维关节空间拆成了两个三维空间,分别对应前三个关节和后三个关节(严格来说,六维转动关节空间不是一个欧式空间,它是个流形,不过这里我们不必纠结这个差别): 




转载来源:

基于Mathematica的机器人仿真环境(机械臂篇) - 优快云博客
https://blog.youkuaiyun.com/robinvista/article/details/70231205


### 关于RRT算法的实现方式与代码示例 #### RRT算法简介 RRT(Rapidly-exploring Random Trees)是一种高效的路径规划算法,能够适应复杂的环境并找到从起点到终点的可行路径[^1]。尽管如此,原始RRT算法所得到的路径通常并非最优,因此后续出现了诸如RRT*等改进版本来优化路径质量。 以下是几种常见编程语言中的RRT算法实现方法: --- #### Python实现RRT算法 Python因其简洁性和丰富的库支持成为实现RRT算法的理想选择之一。下面是一个简单的RRT算法实现示例,用于解决二维平面内的路径规划问题。 ```python import random import math from collections import deque class Node: def __init__(self, x, y): self.x = x self.y = y self.parent = None def distance(node1, node2): return math.sqrt((node1.x - node2.x)**2 + (node1.y - node2.y)**2) def is_collision_free(node1, node2, obstacles): step_size = 0.1 steps = int(distance(node1, node2) / step_size) for i in range(steps): t = i * step_size / distance(node1, node2) point_x = node1.x + t * (node2.x - node1.x) point_y = node1.y + t * (node2.y - node1.y) if any(obstacle.contains(point_x, point_y) for obstacle in obstacles): return False return True def rrt(start, goal, obstacles, max_iter=1000, delta=0.5): nodes = [Node(*start)] for _ in range(max_iter): rand_node = Node(random.uniform(0, 10), random.uniform(0, 10)) nearest_node = min(nodes, key=lambda n: distance(n, rand_node)) new_node = Node(nearest_node.x + delta * (rand_node.x - nearest_node.x), nearest_node.y + delta * (rand_node.y - nearest_node.y)) if not is_collision_free(nearest_node, new_node, obstacles): continue new_node.parent = nearest_node nodes.append(new_node) if distance(new_node, Node(*goal)) < delta and \ is_collision_free(new_node, Node(*goal), obstacles): final_path = [] current = new_node while current: final_path.append(current) current = current.parent final_path.reverse() final_path.append(Node(*goal)) return [(n.x, n.y) for n in final_path] return None ``` 上述代码实现了基本的RRT算法逻辑,并提供了碰撞检测功能以及目标节点附近的终止条件判断。 --- #### MATLAB实现RRT算法 对于熟悉MATLAB的用户来说,也可以利用其强大的矩阵运算能力轻松实现RRT算法。以下是一段简化版的MATLAB代码示例: ```matlab function path = rrt_planner(start, goal, map, iter_max, step_len) % 初始化变量 nodes = struct('pos', start, 'parent', []); for it = 1:iter_max % 随机采样 sample_pos = [randi([0 size(map, 1)]), randi([0 size(map, 2)])]; % 寻找最近邻居 distances = arrayfun(@(k) norm(sample_pos - nodes(k).pos), 1:length(nodes)); [~, idx_nearest] = min(distances); nearest_node = nodes(idx_nearest); % 扩展新节点 direction = normalize(sample_pos - nearest_node.pos)'; new_pos = round(nearest_node.pos + step_len * direction); % 碰撞检测 if ~map(sub2ind(size(map), new_pos(1), new_pos(2))) newNode = struct('pos', new_pos, 'parent', idx_nearest); nodes(end+1) = newNode; % 判断是否接近目标 if norm(goal - new_pos) <= step_len && ... ~any(arrayfun(@(p) map(p), sub2ind(size(map), p))); fprintf('Path found!\n'); % 构造路径 path = []; curr_idx = length(nodes); while curr_idx ~= 0 path(:, end+1) = nodes(curr_idx).pos'; curr_idx = nodes(curr_idx).parent; end break; end end end if isempty(path) disp('No valid path found.'); end end ``` 此代码片段展示了如何在离散地图上执行RRT路径规划操作[^2]。 --- #### 改进型RRT*算法概述 为了克服传统RRT无法提供最佳路径的问题,提出了RRT*算法。相比原版RRTRRT*增加了重连机制,在每次新增节点时尝试重新连接周围已有节点以降低整体代价函数值[^4]。这种特性使其更适合应用于实际机器人导航任务中追求更优解的需求场景下。 --- #### 性能影响因素分析 无论是标准形式还是增强版本,RRT算法的表现均会受到若干关键参数调节的影响,比如最大迭代次数、步长设置等都会直接影响最终结果的质量和计算效率[^3]。 ---
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值