基于matlab的RRT&RRT*算法实现以及可视化

本文介绍了基于Matlab实现的RRT和RRT*路径规划算法,包括主要步骤、动态效果展示及优缺点。作者提出了改进的采样策略,以提高在狭窄通道情况下的效率,并探讨了RRT*的优化方法,如Informed RRT*和kd树优化。此外,还讨论了双向RRT策略。
摘要由CSDN通过智能技术生成

内容来源

记录学习深蓝路径规划课程-基于采样的路径规划一节的作业和笔记,实现基于matlab的RRT以及RRT*算法实现以及可视化。

RRT

  1. 伪代码
    RRT伪代码
  2. 树结构
    x, y记录此节点位置
    xPrev, yPrev记录父节点位置
    dist记录此节点到起点的距离(与作业源码不符,我自己进行了修改)
    indPrev记录父节点在树中的索引
    在这里插入图片描述

主要步骤

  1. 采样:Sample
    %Step 1:在地图中随机采样一个点x_rand
    %提示用(x_rand(1), x_rand(2))表示环境中采样点的坐标
	x_rand = randi(800, 1, 2);  % 全局随机采样
  1. 搜索邻近节点:Near
function [x_near, near_Idx] = Near(x_rand, T)
% 在树T中搜索距离随机点x_rand最近的节点,返回它及其它在树中的索引
    count = size(T.v,2);
    min_dis = 10000;
    for node = 1: count
        dis = sqrt(power((T.v(node).x-x_rand(1)) ,2) + power((T.v(node).y - x_rand(2)), 2) );
        if dis<min_dis
            min_dis = dis;
            near_Idx = node;
            x_near(1) = T.v(node).x;
            x_near(2) = T.v(node).y;
        end
    end
end
  1. 生成新节点:Steer
function  x_new = Steer(x_rand, x_near, StepSize)
% 将距离随机点x_rand最近的节点x_near在x_rand方向上平移StepSize的距离,生成新节点x_new
    dis = distance(x_near, x_rand);
    % 强迫症,想让新节点坐标为整数,fix 舍余取整(也可不取整数)
    x_new(1) = fix(((dis-StepSize)*x_near(1) + StepSize*x_rand(1)) / dis);
    x_new(2) = fix(((dis-StepSize)*x_near(2) + StepSize*x_rand(2)) / dis);
end
  1. 碰撞检测:collisionChecking(作业源码中已给-基于给定的环境图片设计的)
function feasible=collisionChecking(startPose,goalPose,map)
% 输入为两节点坐标和地图信息,若两节点直线连接不会经过障碍物,则返回true, 碰到障碍物则为返回false
feasible
  • 30
    点赞
  • 210
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
以下是一个简单的MATLAB实现,包括基于RRT*算法的路径规划和路径可视化: ``` classdef RRTStar < handle properties q_start q_goal obstacle_list step_size max_iter goal_tolerance tree fig_handle axis_handle plot_handle end methods function obj = RRTStar(q_start, q_goal, obstacle_list, step_size, max_iter, goal_tolerance) obj.q_start = q_start; obj.q_goal = q_goal; obj.obstacle_list = obstacle_list; obj.step_size = step_size; obj.max_iter = max_iter; obj.goal_tolerance = goal_tolerance; obj.tree = [q_start, NaN]; obj.fig_handle = figure; obj.axis_handle = gca; obj.plot_handle = plot(q_start(1), q_start(2), 'ro'); axis([0 10 0 10]); hold on; end function [q_new, nearest_node] = extend(obj) q_rand = obj.sample(); nearest_node = obj.nearest(q_rand); q_new = obj.steer(nearest_node, q_rand); if obj.check_collision(nearest_node, q_new) [q_min, c_min] = obj.find_best_parent(q_new, nearest_node); obj.tree = [obj.tree, [q_new; q_min]]; obj.rewire(q_new, c_min); obj.plot(q_new, q_min); end end function q_rand = sample(obj) if rand() < 0.05 q_rand = obj.q_goal; else q_rand = 10 * rand(2, 1); end end function nearest_node = nearest(obj, q_rand) d_min = inf; nearest_node = obj.q_start; for i = 1:size(obj.tree, 2) d = norm(q_rand - obj.tree(1:2, i)); if d < d_min d_min = d; nearest_node = obj.tree(1:2, i); end end end function q_new = steer(obj, nearest_node, q_rand) if norm(q_rand - nearest_node) > obj.step_size q_new = nearest_node + (q_rand - nearest_node) * obj.step_size / norm(q_rand - nearest_node); else q_new = q_rand; end end function collision = check_collision(obj, q1, q2) collision = false; for i = 1:size(obj.obstacle_list, 2) if obj.line_circle_collision(q1, q2, obj.obstacle_list(:, i), 0.5) collision = true; break; end end end function collision = line_circle_collision(obj, q1, q2, c, r) collision = false; d = norm(c - q1); theta = atan2(q2(2) - q1(2), q2(1) - q1(1)); x = c(1) + r * cos(theta); y = c(2) + r * sin(theta); if x < min(q1(1), q2(1)) || x > max(q1(1), q2(1)) || ... y < min(q1(2), q2(2)) || y > max(q1(2), q2(2)) return; end if d < r collision = true; end end function [q_min, c_min] = find_best_parent(obj, q_new, nearest_node) neighbor_nodes = obj.find_near_nodes(q_new); q_min = nearest_node; c_min = obj.cost(q_min) + norm(q_new - q_min); for i = 1:size(neighbor_nodes, 2) if obj.check_collision(neighbor_nodes(:, i), q_new) temp_cost = obj.cost(neighbor_nodes(:, i)) + norm(q_new - neighbor_nodes(:, i)); if temp_cost < c_min q_min = neighbor_nodes(:, i); c_min = temp_cost; end end end end function neighbor_nodes = find_near_nodes(obj, q_new) r = 2 * obj.step_size; neighbor_nodes = []; for i = 1:size(obj.tree, 2) if norm(q_new - obj.tree(1:2, i)) < r neighbor_nodes = [neighbor_nodes, obj.tree(1:2, i)]; end end end function cost = cost(obj, q) cost = 0; for i = 1:size(obj.tree, 2) if all(obj.tree(1:2, i) == q) cost = obj.tree(3, i); return; end end end function rewire(obj, q_new, c_min) r = 2 * obj.step_size; for i = 1:size(obj.tree, 2) if norm(q_new - obj.tree(1:2, i)) < r && obj.tree(3, i) > c_min + norm(q_new - obj.tree(1:2, i)) && obj.check_collision(q_new, obj.tree(1:2, i)) obj.tree(3, i) = c_min + norm(q_new - obj.tree(1:2, i)); obj.tree(4, i) = size(obj.tree, 2); obj.plot(obj.tree(1:2, i), q_new); end end end function plot(obj, q1, q2) obj.plot_handle = plot([q1(1), q2(1)], [q1(2), q2(2)], 'g'); drawnow; end function [path, path_cost] = plan(obj) for i = 1:obj.max_iter [q_new, nearest_node] = obj.extend(); if norm(q_new - obj.q_goal) < obj.goal_tolerance path = obj.get_path(); path_cost = obj.cost(q_new); return; end end path = []; path_cost = inf; end function path = get_path(obj) path = obj.q_goal; node_index = size(obj.tree, 2); while all(obj.tree(1:2, node_index) ~= obj.q_start) path = [obj.tree(1:2, node_index), path]; node_index = obj.tree(4, node_index); end path = [obj.q_start, path]; end end end ``` 这个实现假设环境是一个二维平面,机器人可以在十个单位的空间内自由移动。障碍物是圆形,半径为0.5个单位。`RRTStar`类包括以下方法: - `extend`:根据RRT*算法的过程,从树中选择一个节点并从这个节点向一个新的随机点生长一条新的分支。如果新分支不与环境中的障碍物发生碰撞,则添加到树中。如果添加成功,则调用`rewire`方法以重新连接树,以便最小化从起始位置到新节点的代价。 - `sample`:从随机样本空间中生成一个新的随机点。这个方法有5%的概率生成目标点,有95%的概率生成完全随机的点。 - `nearest`:从树中选择与给定点最接近的节点,并返回该节点。 - `steer`:将机器人从最近的节点移动到给定的新点。如果新点与最近的节点之间的距离大于步长,则机器人只移动到新点的一定距离处。 - `check_collision`:检查机器人从一个节点到另一个节点的路径是否与任何障碍物发生碰撞。 - `line_circle_collision`:检查机器人从一个节点到另一个节点的直线路径是否与一个圆形障碍物发生碰撞。 - `find_best_parent`:从机器人的邻居节点中选择一个最好的父节点,以最小化从起始位置到新节点的代价。 - `find_near_nodes`:返回离给定节点最近的所有邻居节点。 - `cost`:返回树中给定节点的代价。 - `rewire`:重新连接树,以最小化从起始位置到任何节点的代价。 - `plot`:绘制机器人从一个节点到另一个节点的路径。 - `plan`:使用RRT*算法规划机器人的路径,直到找到一条从起始位置到目标位置的路径。 可以使用以下代码测试此实现: ``` obstacle_list = [3, 3, 2; 7, 7, 2; 5, 2, 2]'; rrt_star = RRTStar([1; 1], [9; 9], obstacle_list, 0.5, 500, 0.1); [path, path_cost] = rrt_star.plan(); if ~isempty(path) disp(['Found path with cost ', num2str(path_cost)]); plot(path(1, :), path(2, :), 'r', 'LineWidth', 2); else disp('Failed to find path'); end ``` 这个例子在一个10x10的平面上规划机器人从起始位置到目标位置的路径。环境中有三个障碍物,它们的位置和大小都在`obstacle_list`中指定。机器人的步长为0.5个单位,最大迭代次数为500次,目标容差为0.1个单位。如果路径规划成功,它将显示规划出的路径并输出其代价。否则,它将输出失败消息。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值