Compare commits

...

2 Commits

Author SHA1 Message Date
66cb6a9fe3 添加RTT算法 2025-06-02 19:49:45 +08:00
5d2b4d951a 新增RTT算法 2025-06-02 19:49:22 +08:00
2 changed files with 161 additions and 11 deletions

144
RTT/RTT.m Normal file
View File

@ -0,0 +1,144 @@
function path = rtt(map, start, goal)
maxIterations = 5000;
stepSize = 5;
goalThreshold = 5; %
mapSize = size(map);
%
tree.nodes = start;
tree.parents = 0;
for i = 1:maxIterations
%
randPoint = sampler(mapSize, goal);
%
[nearestIdx, nearestPoint] = find_nearest(tree.nodes, randPoint);
%
newPoint = local_planner(map, nearestPoint, randPoint, stepSize);
%
if isempty(newPoint)
continue;
end
%
tree.nodes = [tree.nodes; newPoint];
tree.parents = [tree.parents; nearestIdx];
%
if norm(newPoint - goal) < goalThreshold
tree.nodes = [tree.nodes; goal];
tree.parents = [tree.parents; size(tree.nodes, 1) - 1];
path = make_path(tree);
return;
end
end
%
path = [];
end
function point = sampler(mapSize, goal)
% 10%90%
if rand() < 0.1
point = goal;
else
point = round([rand()*mapSize(1), rand()*mapSize(2)]);
%
point(1) = max(min(point(1), mapSize(1)), 1);
point(2) = max(min(point(2), mapSize(2)), 1);
end
end
function [idx, nearest] = find_nearest(nodes, point)
% point
dists = vecnorm(nodes - point, 2, 2);
[~, idx] = min(dists);
nearest = nodes(idx, :);
end
function newPoint = local_planner(map, nearestPoint, randPoint, stepSize)
% 沿
direction = randPoint - nearestPoint;
if norm(direction) == 0
newPoint = [];
return;
end
direction = direction / norm(direction);
newPoint = round(nearestPoint + direction * stepSize);
%
if newPoint(1) < 1 || newPoint(2) < 1 || ...
newPoint(1) > size(map, 1) || newPoint(2) > size(map, 2)
newPoint = [];
return;
end
% (线)
if isCollision(map, nearestPoint, newPoint)
newPoint = [];
return;
end
end
function collision = isCollision(map, p1, p2)
% 使Bresenham
linePts = bresenham(p1, p2);
collision = false;
for i = 1:size(linePts,1)
pt = linePts(i,:);
if map(pt(1), pt(2)) == 1
collision = true;
return;
end
end
end
function pts = bresenham(p1, p2)
% Bresenham线
x1 = p1(1); y1 = p1(2);
x2 = p2(1); y2 = p2(2);
dx = abs(x2 - x1); dy = abs(y2 - y1);
sx = sign(x2 - x1); sy = sign(y2 - y1);
err = dx - dy;
pts = [];
while true
pts = [pts; x1, y1];
if x1 == x2 && y1 == y2
break;
end
e2 = 2*err;
if e2 > -dy
err = err - dy;
x1 = x1 + sx;
end
if e2 < dx
err = err + dx;
y1 = y1 + sy;
end
end
end
function path = make_path(tree)
%
path = tree.nodes(end, :);
idx = size(tree.nodes, 1);
while tree.parents(idx) ~= 0
idx = tree.parents(idx);
path = [tree.nodes(idx, :); path];
end
%
if ~isempty(path)
disp('');
for i = 1:size(path, 1)
fprintf('(%d, %d)\n', path(i, 2), path(i, 1));
end
else
disp('');
end
end

View File

@ -13,7 +13,7 @@ map = [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0; % 1
1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0; %10
0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0; %11
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0; %12
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0; %13
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0; %13
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0; %14
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0; %15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0; %16
@ -30,10 +30,12 @@ goal = [19, 19];
path_Astar = Astar(map, start, goal);
% Dijkstra
path_Dijkstra = Dijkstras(map, start, goal);
%RTT
path_RTT = RTT(map, start, goal);
visualize_path(map, start, goal, path_Astar, path_Dijkstra);
visualize_path(map, start, goal, path_Astar, path_Dijkstra, path_RTT);
function visualize_path(map, start, goal, path_Astar, path_Dijkstra)
function visualize_path(map, start, goal, path_Astar, path_Dijkstra, path_RTT)
% 01
imagesc(map);
colormap(flipud(gray)); % 0 1
@ -42,25 +44,29 @@ function visualize_path(map, start, goal, path_Astar, path_Dijkstra)
%
plot(start(2), start(1), 'bo', 'MarkerSize', 10, 'LineWidth', 2);
%
plot(goal(2), goal(1), 'ro', 'MarkerSize', 10, 'LineWidth', 2);
% A*
if ~isempty(path_Astar)
%
if ~isequal(path_Astar(1,:), start)
path_Astar = [start; path_Astar];
end
%
if ~isequal(path_Astar(end,:), goal)
path_Astar = [path_Astar; goal];
end
plot(path_Astar(:,2), path_Astar(:,1), 'r-', 'LineWidth', 2);
plot(path_Astar(:,2), path_Astar(:,1), 'ro', 'MarkerSize', 4, 'MarkerFaceColor', 'r');
end
% 线
plot(path_Astar(:,2), path_Astar(:,1), 'r-', 'LineWidth', 2); % 绿线
plot(path_Astar(:,2), path_Astar(:,1), 'ro', 'MarkerSize', 4, 'MarkerFaceColor', 'r'); %
plot(path_Dijkstra(:,2), path_Dijkstra(:,1), 'g-', 'LineWidth', 2); % 绿线
plot(path_Dijkstra(:,2), path_Dijkstra(:,1), 'go', 'MarkerSize', 4, 'MarkerFaceColor', 'g'); %
% Dijkstra
if ~isempty(path_Dijkstra)
plot(path_Dijkstra(:,2), path_Dijkstra(:,1), 'g-', 'LineWidth', 2);
plot(path_Dijkstra(:,2), path_Dijkstra(:,1), 'go', 'MarkerSize', 4, 'MarkerFaceColor', 'g');
end
% RTT
if ~isempty(path_RTT)
plot(path_RTT(:,2), path_RTT(:,1), 'b-', 'LineWidth', 2);
end
% 线