在实际工程应用中,运动目标的外形、大小直接影响到路径选择,针对三维复杂场景的碰撞检测和路径规划问题,提出了一种基于层次包围盒碰撞检测的实时路径规划优化算法.该优化算法在进行碰撞检测时,通过预碰撞筛选检测和精细碰撞检测的方法来规避根本不会碰撞的物体,只检测与视点小半径球有碰撞可能性的物体;在进行路径规划时,在传统A*算法进行路径规划的基础上,结合“粗试探和精搜索”的思想,最终完成路径规划…
% A* algorithm实现
clc; clear; close all;
%% 参数读取与设置
[numberOfSphere, ~] = size(obstacleMatrix);
[numberOfCylinder, ~] = size(cylinderMatrix);
Alldirec = [[1,0,0];[0,1,0];[0,0,1];[-1,0,0];[0,-1,0];[0,0,-1];...
[1,1,0];[1,0,1];[0,1,1];[-1,-1,0];[-1,0,-1];[0,-1,-1];...
[1,-1,0];[-1,1,0];[1,0,-1];[-1,0,1];[0,1,-1];[0,-1,1];...
[1,1,1];[-1,-1,-1];[1,-1,-1];[-1,1,-1];[-1,-1,1];[1,1,-1];...
[1,-1,1];[-1,1,1]];
threshold = 0.8;
stop = threshold*1.5;
g = [start, 0; goal, inf]; % 每一行前三个数为点坐标,第四个数为路径耗散
Path = [];
Parent = [];
Open = [start, g(findIndex(g,start),4) + getDist(start,goal)];
%% 绘制障碍环境
figure(1)
[n,~] = size(obstacleMatrix);
for i = 1:n %绘制静态球障碍物
[x,y,z] = sphere();
surfc(RobstacleMatrix(i)*x+obstacleMatrix(i,1),...
RobstacleMatrix(i)*y+obstacleMatrix(i,2),...
RobstacleMatrix(i)*z+obstacleMatrix(i,3));
hold on;
end
[n,~] = size(cylinderMatrix);
for i = 1:n %绘制圆柱体障碍物
[x,y,z] = cylinder(cylinderRMatrix(i));
z(2,:) = cylinderHMatrix(i);
surfc(x + cylinderMatrix(i,1),y + cylinderMatrix(i,2),...
z,'FaceColor','interp');
hold on;
end
bar1 = scatter3(start(1),start(2),start(3),80,"cyan",'filled','o');hold on
bar2 = scatter3(goal(1),goal(2),goal(3),80,"magenta",'filled',"o");
axis equal
set(gcf,'unit','centimeters','position',[30 10 20 15]);
%% 主循环
while ~isempty(Open)
[xi, index] = findMin(Open);
Open(index,:) = [];
if getDist(xi, goal) < stop
break;
end
children = getChildren(xi, Alldirec, threshold, obstacleMatrix, RobstacleMatrix,...
cylinderMatrix, cylinderRMatrix, cylinderHMatrix);
scatter3(children(:,1),children(:,2),children(:,3),1,'filled','o');
drawnow;
[n,~] = size(children);
for i = 1:n
child = children(i,:);
if findIndex(g, child) == 0 % child不在g
g = [g; child, inf];
end
a = g(findIndex(g, xi),4) + getDist(xi,child);
if a < g(findIndex(g, child),4)
g(findIndex(g, child),4) = a;
Parent = setParent(Parent, child,xi);
Open = setOpen(Open, child, a, goal);
end
end
end
lastPoint = xi;
%% 回溯轨迹
x = lastPoint;
Path = x;
[n,~] = size(Parent);
while any(x ~= start)
for i = 1:n
if Parent(i,1:3) == x
Path = [Parent(i,4:6); Path];
break;
end
end
x = Parent(i,4:6);
end
plot3([Path(:,1);goal(1)],[Path(:,2);goal(2)],[Path(:,3);goal(3)],'LineWidth',3,'color','r');
%% 计算轨迹距离
pathLength = 0;
[n,~] = size(Path);
for i = 1:n-1
pathLength = pathLength + getDist(Path(i,:),Path(i+1,:));
end
pathLength = pathLength + getDist(Path(end,:),goal);
fprintf('路径的长度为:%f',pathLength);
%% 函数
function children = getChildren(pos, Alldirec, step,circleCenter,circleR, cylinderCenter,cylinderR, cylinderH)
allchild = [];
[n,~] = size(Alldirec);
for i = 1:n
direc = Alldirec(i,:);
child = pos + direc * step;
if ~checkCol(child, circleCenter,circleR, cylinderCenter,cylinderR, cylinderH)
continue;
end
allchild = [allchild; child];
end
children = allchild;
end
function flag = checkCol(pos, circleCenter,circleR, cylinderCenter,cylinderR, cylinderH)
[numberOfSphere, ~] = size(circleCenter);
[numberOfCylinder, ~] = size(cylinderCenter);
flag = true;
for i = 1:numberOfSphere
if getDist(pos, circleCenter(i,:)) <= circleR(i)
flag = false;
break;
end
end
for i = 1:numberOfCylinder
if getDist(pos(1:2), cylinderCenter(i,:)) <= cylinderR(i) && pos(3) <= cylinderH(i)
flag = false;
break;
end
end
if pos(3) <= 0 flag = false; end
end
function Par = setParent(Parent, xj, xi)
[n,~] = size(Parent);
if n == 0
Par = [xj, xi];
else
for i = 1:n
if Parent(i,1:3) == xj
Parent(i,4:6) = xi;
Par = Parent;
break;
end
if i == n
Par = [Parent; xj, xi];
end
end
end
end