当前位置:   article > 正文

手把手教学RRT三维算法MATLAB仿真(代码可直接运行,视频手把手教学)_if cubeflag || cylinderflag || sphereflag continue

if cubeflag || cylinderflag || sphereflag continue; end

最近有很多人问我RRT算法的一些问题,就是怎么添加自己的障碍物还有碰撞检测部分,于是给大家做了这期教学视频,讲解的很详细,每个细节都涉及到,以及最后的程序演示和代码都给大家安利了下去。视频制作不易,希望大家喜欢。

视频地址在这里  手把手教rrt算法(1)-变量定义_哔哩哔哩_bilibili

这里是算法演示后的展示效果,当然也可以通过自己修改障碍物信息以及初始位置目标位置信息得到自己想要的演示图。整个代码每个模块相对来说比较独立,可移植性非常好。如果有用到这套算法的朋友可以去看看我的视频讲解,会对你理解代码有很大的帮助。

废话不多说直接上代码:

1.main函数(主函数)

在进行RRT算法时首先要定义变量,关于空间位置以及大小的描述还有障碍物信息的描述,在这里给大家演示了三种最常用的障碍物,长方体,圆柱和球形障碍物。最后也是根据RRT寻找的路径进行可图形的绘制操作。

  1. %% 清空变量
  2. clear;
  3. clc
  4. %% 定义变量
  5. axisStart = [0 0 0];
  6. axisLWH = [1000 1000 1000];
  7. %定义障碍物
  8. cubeInfo.exist = 0;
  9. cylinderInfo.exist = 0;
  10. sphereInfo.exist = 0;
  11. pathPoint = [0 0 0;
  12. 100 100 100;
  13. 1000 1000 1000]; %一系列的路径点
  14. cubeInfo = createCubeObject(cubeInfo); %创建长方体障碍物信息
  15. cylinderInfo = createCylinderObject(cylinderInfo); %创建圆柱障碍物信息
  16. sphereInfo = createSphereObject(sphereInfo); %创建球形障碍物信息
  17. %% 画图
  18. figure(1)
  19. colorMatCube = [1 0 0];
  20. colorMatCylinder = [0 1 0];
  21. colorMatSphere = [0 0 1];
  22. pellucidity = 0.6; %透明度
  23. hold on;
  24. scatter3(pathPoint(1,1),pathPoint(1,2),pathPoint(1,3),'MarkerEdgeColor','k','MarkerFaceColor',[1 0 0]);
  25. scatter3(pathPoint(end,1),pathPoint(end,2),pathPoint(end,3),'MarkerEdgeColor','k','MarkerFaceColor','b');
  26. drawCubeObject(cubeInfo,colorMatCube,pellucidity); %画长方体障碍物
  27. drawCylinderObject(cylinderInfo,colorMatCylinder,pellucidity); %画圆柱体障碍物
  28. drawSphereObject(sphereInfo,colorMatSphere,pellucidity); %画球形障碍物
  29. text(pathPoint(1,1),pathPoint(1,2),pathPoint(1,3),'起点');
  30. text(pathPoint(end,1),pathPoint(end,2),pathPoint(end,3),'终点');
  31. view(3)
  32. grid on;
  33. axis equal;
  34. axis([0 1000 0 1000 0 1000])
  35. xlabel('x')
  36. ylabel('y')
  37. zlabel('z')
  38. %% 寻找路径
  39. totalPath = [];
  40. for k1 = 1:size(pathPoint,1)-1
  41. startPoint = pathPoint(k1,:);
  42. goalPoint = pathPoint(k1+1,:);
  43. Path = RRT(startPoint,axisStart,axisLWH,goalPoint,cubeInfo,cylinderInfo,sphereInfo);
  44. if ~isempty(Path)
  45. for k2 = 1:size(Path,1)-1
  46. line([Path(k2,1) Path(k2+1,1)],[Path(k2,2) Path(k2+1,2)],[Path(k2,3) Path(k2+1,3)],'LineWidth',1,'Color','red');
  47. end
  48. totalPath = [totalPath;Path];
  49. end
  50. end

2.createCubeObject(创建长方体障碍物)

  1. function cubeInfo = createCubeObject(cubeInfo)
  2. cubeInfo.axisX = [500 300];
  3. cubeInfo.axisY = [200 400];
  4. cubeInfo.axisZ = [100 100];
  5. cubeInfo.length = [100 100];
  6. cubeInfo.width = [100 50];
  7. cubeInfo.height = [100 100];
  8. cubeInfo.exist = 1;
  9. end

3.createCylinderObject(创建圆柱体障碍物)

  1. function cylinderInfo = createCylinderObject(cylinderInfo)
  2. cylinderInfo.X = [500 300];
  3. cylinderInfo.Y = [500 300];
  4. cylinderInfo.Z = [100 100];
  5. cylinderInfo.radius = [50 20];
  6. cylinderInfo.height = [200 100];
  7. cylinderInfo.exist = 1;
  8. end

4.createSphereObject(创建球形障碍物信息)

  1. function sphereInfo = createSphereObject(sphereInfo)
  2. sphereInfo.centerX = [700 800];
  3. sphereInfo.centerY = [700 800];
  4. sphereInfo.centerZ = [700 800];
  5. sphereInfo.radius = [50 80];
  6. sphereInfo.exist = 1;
  7. end

5.drawCubeObject(绘制长方体障碍物)

  1. function drawCubeObject(cubeInfo,colorMatCube,pellucidity)
  2. % 画长方体障碍物的函数
  3. if cubeInfo.exist
  4. for k1 = 1:size(cubeInfo.axisX,2)
  5. plotcube([cubeInfo.length(k1) cubeInfo.width(k1) cubeInfo.height(k1)],[cubeInfo.axisX(k1) cubeInfo.axisY(k1) cubeInfo.axisZ(k1)],pellucidity,colorMatCube);
  6. end
  7. end
  8. end

6.drawCylinderObject(绘制圆柱体障碍物)

  1. function drawCylinderObject(cylinderInfo,colorMatCylinder,pellucidity)
  2. if cylinderInfo.exist
  3. % 第一个参数是圆柱体的底部圆心坐标值,第二个参数是圆柱体直径,第三个参数是圆柱高度
  4. % 第四个参数是透明度,第五个参数是颜色矩阵
  5. for k1 = 1:size(cylinderInfo.X,2)
  6. coor = [cylinderInfo.X(k1) cylinderInfo.Y(k1) cylinderInfo.Z(k1)];
  7. diameter = cylinderInfo.radius(k1)*2;
  8. height = cylinderInfo.height(k1);
  9. facealpha = pellucidity;
  10. color = colorMatCylinder;
  11. plotcylinder(coor,diameter,height,facealpha,color)
  12. end
  13. end
  14. end

7.drawSphereObject(绘制球形障碍物)

  1. function drawSphereObject(sphereInfo,colorMatSphere,pellucidity)
  2. if sphereInfo.exist
  3. for k1 = 1:size(sphereInfo.centerX,2)
  4. xCoor = sphereInfo.centerX(k1);
  5. yCoor = sphereInfo.centerY(k1);
  6. zCoor = sphereInfo.centerZ(k1);
  7. radius = sphereInfo.radius(k1);
  8. [x,y,z] = sphere(50);
  9. mesh(x*radius+xCoor,y*radius+yCoor,z*radius+zCoor,'FaceColor',colorMatSphere,'EdgeColor','none','FaceAlpha',pellucidity);
  10. end
  11. end
  12. end

8.expandPoint(RRT算法扩展新点)

  1. function newCoor = expandPoint(nearCoor,randCoor,step)
  2. deltaX = randCoor(1) - nearCoor(1);
  3. deltaY = randCoor(2) - nearCoor(2);
  4. deltaZ = randCoor(3) - nearCoor(3);
  5. r = sqrt(deltaX^2+deltaY^2+deltaZ^2);
  6. fai = atan2(deltaY,deltaX);
  7. theta = acos(deltaZ/r);
  8. x = step*sin(theta)*cos(fai);
  9. y = step*sin(theta)*sin(fai);
  10. z = step*cos(theta);
  11. newCoor = [x+nearCoor(1) ,y+nearCoor(2),z+nearCoor(3)];
  12. end

9.findNearPoint(RRT算法寻找树上最近点)

  1. function [nearCoor,preIndex] = findNearPoint(randCoor,T)
  2. tempDis = inf;
  3. calcuDis = @(x,y) sqrt((x(1)-y(1))^2+(x(2)-y(2))^2+(x(3)-y(3))^2);
  4. for k1 = 1:size(T.x,2)
  5. dis = calcuDis([T.x(k1) T.y(k1) T.z(k1)],randCoor);
  6. if tempDis>dis
  7. tempDis = dis;
  8. index = k1;
  9. end
  10. end
  11. nearCoor = [T.x(index) T.y(index) T.z(index)];
  12. preIndex = index;
  13. end

10.isCubeCollision(长方体障碍物碰撞检测)

  1. function cubeFlag = isCubeCollision(cubeInfo,nearCoor,newCoor,step)
  2. %% 长方体碰撞检测函数,如果发生碰撞则返回1
  3. cubeFlag = 0;
  4. if cubeInfo.exist
  5. for k1 = size(cubeInfo.axisX,2)
  6. xMin = cubeInfo.axisX(k1);
  7. xMax = cubeInfo.axisX(k1)+cubeInfo.length(k1);
  8. yMin = cubeInfo.axisY(k1);
  9. yMax = cubeInfo.axisY(k1)+cubeInfo.length(k1);
  10. zMin = cubeInfo.axisZ(k1);
  11. zMax = cubeInfo.axisZ(k1)+cubeInfo.length(k1);
  12. for k2 = 0:step/100:step
  13. deltaX = newCoor(1) - nearCoor(1);
  14. deltaY = newCoor(2) - nearCoor(2);
  15. deltaZ = newCoor(3) - nearCoor(3);
  16. r = sqrt(deltaX^2+deltaY^2+deltaZ^2);
  17. fai = atan2(deltaY,deltaX);
  18. theta = acos(deltaZ/r);
  19. x = k2*sin(theta)*cos(fai);
  20. y = k2*sin(theta)*sin(fai);
  21. z = k2*cos(theta);
  22. checkPoint = [x+nearCoor(1),y+nearCoor(2),z+nearCoor(3)];
  23. if (xMin<checkPoint(1) && checkPoint(1) < xMax) && (yMin<checkPoint(2) && checkPoint(2) < yMax) && (zMin<checkPoint(3) && checkPoint(3) < zMax)
  24. cubeFlag = 1;
  25. return;
  26. end
  27. end
  28. end
  29. end
  30. end

11.isCylinderCollision(圆柱体障碍物碰撞检测)

  1. function cylinderFlag = isCylinderCollision(cylinderInfo,nearCoor,newCoor,step)
  2. %% 圆柱体碰撞检测函数,当发生碰撞的时候返回1
  3. cylinderFlag = 0;
  4. calcuDis = @(x,y) sqrt((x(1)-y(1))^2+(x(2)-y(2))^2);
  5. if cylinderInfo.exist
  6. for k1 = 1:size(cylinderInfo.X,2)
  7. zMin = cylinderInfo.Z(k1);
  8. zMax = zMin+cylinderInfo.height(k1);
  9. for k2 = 0:step/100:step
  10. deltaX = newCoor(1) - nearCoor(1);
  11. deltaY = newCoor(2) - nearCoor(2);
  12. deltaZ = newCoor(3) - nearCoor(3);
  13. r = sqrt(deltaX^2+deltaY^2+deltaZ^2);
  14. fai = atan2(deltaY,deltaX);
  15. theta = acos(deltaZ/r);
  16. x = k2*sin(theta)*cos(fai);
  17. y = k2*sin(theta)*sin(fai);
  18. z = k2*cos(theta);
  19. checkPoint = [x+nearCoor(1),y+nearCoor(2),z+nearCoor(3)];
  20. if calcuDis(checkPoint(1:2),[cylinderInfo.X(k1) cylinderInfo.Y(k1)])<cylinderInfo.radius(k1) && zMin<checkPoint(3) & checkPoint(3) < zMax
  21. cylinderFlag = 1;
  22. return;
  23. end
  24. end
  25. end
  26. end
  27. end

12.isSphereCollision(球形障碍物碰撞检测)

  1. function sphereFlag = isSphereCollision(sphereInfo,nearCoor,newCoor,step)
  2. sphereFlag = 0;
  3. calcuDis = @(x,y) sqrt((x(1)-y(1))^2+(x(2)-y(2))^2+(x(3)-y(3))^2);
  4. if sphereInfo.exist
  5. for k1 = 1:size(sphereInfo.centerX,2)
  6. center = [sphereInfo.centerX(k1) sphereInfo.centerY(k1) sphereInfo.centerZ(k1)];
  7. for k2 = 0:step/100:step
  8. deltaX = newCoor(1) - nearCoor(1);
  9. deltaY = newCoor(2) - nearCoor(2);
  10. deltaZ = newCoor(3) - nearCoor(3);
  11. r = sqrt(deltaX^2+deltaY^2+deltaZ^2);
  12. fai = atan2(deltaY,deltaX);
  13. theta = acos(deltaZ/r);
  14. x = k2*sin(theta)*cos(fai);
  15. y = k2*sin(theta)*sin(fai);
  16. z = k2*cos(theta);
  17. checkPoint = [x+nearCoor(1),y+nearCoor(2),z+nearCoor(3)];
  18. if calcuDis(checkPoint,center)<sphereInfo.radius(k1)
  19. sphereFlag = 1;
  20. return;
  21. end
  22. end
  23. end
  24. end
  25. end

13.plotcube(绘制长方体障碍物关键函数)

  1. function plotcube(varargin)
  2. % https://ww2.mathworks.cn/matlabcentral/fileexchange/15161-plotcube
  3. % PLOTCUBE - Display a 3D-cube in the current axes
  4. %
  5. % PLOTCUBE(EDGES,ORIGIN,ALPHA,COLOR) displays a 3D-cube in the current axes
  6. % with the following properties:
  7. % * EDGES : 3-elements vector that defines the length of cube edges
  8. % * ORIGIN: 3-elements vector that defines the start point of the cube
  9. % * ALPHA : scalar that defines the transparency of the cube faces (from 0
  10. % to 1)
  11. % * COLOR : 3-elements vector that defines the faces color of the cube
  12. %
  13. % Example:
  14. % >> plotcube([5 5 5],[ 2 2 2],.8,[1 0 0]);
  15. % >> plotcube([5 5 5],[10 10 10],.8,[0 1 0]);
  16. % >> plotcube([5 5 5],[20 20 20],.8,[0 0 1]);
  17. % Default input arguments
  18. inArgs = { ...
  19. [10 56 100] , ... % Default edge sizes (x,y and z)
  20. [10 10 10] , ... % Default coordinates of the origin point of the cube
  21. .7 , ... % Default alpha value for the cube's faces
  22. [1 0 0] ... % Default Color for the cube
  23. };
  24. % Replace default input arguments by input values
  25. inArgs(1:nargin) = varargin;
  26. % Create all variables
  27. [edges,origin,alpha,clr] = deal(inArgs{:});
  28. XYZ = { ...
  29. [0 0 0 0] [0 0 1 1] [0 1 1 0] ; ...
  30. [1 1 1 1] [0 0 1 1] [0 1 1 0] ; ...
  31. [0 1 1 0] [0 0 0 0] [0 0 1 1] ; ...
  32. [0 1 1 0] [1 1 1 1] [0 0 1 1] ; ...
  33. [0 1 1 0] [0 0 1 1] [0 0 0 0] ; ...
  34. [0 1 1 0] [0 0 1 1] [1 1 1 1] ...
  35. };
  36. XYZ = mat2cell(...
  37. cellfun( @(x,y,z) x*y+z , ...
  38. XYZ , ...
  39. repmat(mat2cell(edges,1,[1 1 1]),6,1) , ...
  40. repmat(mat2cell(origin,1,[1 1 1]),6,1) , ...
  41. 'UniformOutput',false), ...
  42. 6,[1 1 1]);
  43. cellfun(@patch,XYZ{1},XYZ{2},XYZ{3},...
  44. repmat({clr},6,1),...
  45. repmat({'FaceAlpha'},6,1),...
  46. repmat({alpha},6,1)...
  47. );
  48. view(3);

14.plotcylinder(绘制圆柱体障碍物关键函数)

  1. function plotcylinder(coor,diameter,height,facealpha,color)
  2. %% plot_cylinder(dat_xia(k2,1:3),dat_xia(k2,4),dat_xia(k2,5),1,rand(1,3));
  3. % 第一个参数是圆柱体的底部圆心坐标值,第二个参数是圆柱体直径,第三个参数是圆柱高度
  4. % 第四个参数是透明度,第五个参数是颜色矩阵
  5. %% 函数解释:把这个函数当做黑箱处理,只需要记住函数的输入就可以,知道是干什么的,内部实现过于复杂,很难解释清楚
  6. % coor: 中心坐标
  7. % diameter: 直径
  8. % height: 高度
  9. % facealpha: 透明度
  10. % color: 颜色
  11. r = diameter/2;
  12. theta = 0:0.3:pi*2;
  13. hold on
  14. for k1 = 1:length(theta)-1
  15. X=[coor(1)+r*cos(theta(k1)) coor(1)+r*cos(theta(k1+1)) coor(1)+r*cos(theta(k1+1)) coor(1)+r*cos(theta(k1))];
  16. Y=[coor(2)+r*sin(theta(k1)) coor(2)+r*sin(theta(k1+1)) coor(2)+r*sin(theta(k1+1)) coor(2)+r*sin(theta(k1))];
  17. Z=[coor(3),coor(3),coor(3)+height,coor(3)+height];
  18. h=fill3(X,Y,Z,color);
  19. set(h,'edgealpha',0,'facealpha',facealpha)
  20. end
  21. X=[coor(1)+r*cos(theta(end)) coor(1)+r*cos(theta(1)) coor(1)+r*cos(theta(1)) coor(1)+r*cos(theta(end))];
  22. Y=[coor(2)+r*sin(theta(end)) coor(2)+r*sin(theta(1)) coor(2)+r*sin(theta(1)) coor(2)+r*sin(theta(end))];
  23. Z=[coor(3),coor(3),coor(3)+height,coor(3)+height];
  24. h=fill3(X,Y,Z,color);
  25. set(h,'edgealpha',0,'facealpha',facealpha)
  26. fill3(coor(1)+r*cos(theta),coor(2)+r*sin(theta),coor(3)*ones(1,size(theta,2)),color)
  27. fill3(coor(1)+r*cos(theta),coor(2)+r*sin(theta),height+coor(3)*ones(1,size(theta,2)),color)
  28. view(3)

15.RRT(RRT算法逻辑)

  1. function Path = RRT(startPoint,axisStart,axisLWH,goalPoint,cubeInfo,cylinderInfo,sphereInfo)
  2. %% RRT算法寻找路径点
  3. %% 变量定义
  4. calcuDis = @(x,y) sqrt((x(1)-y(1))^2+(x(2)-y(2))^2+(x(3)-y(3))^2);
  5. iterMax = 5000; %最大迭代次数
  6. iter = 0; %当前迭代次数
  7. step = 5; %步长
  8. count = 1; %计数器
  9. Thr = 10; %阈值
  10. %构建树
  11. T.x(1) = startPoint(1);
  12. T.y(1) = startPoint(2);
  13. T.z(1) = startPoint(3);
  14. T.pre(1) = 0;
  15. while iter < iterMax
  16. iter = iter+1;
  17. %% 在空间中随机采样
  18. randCoor = samplePoint(axisStart,axisLWH,goalPoint);
  19. %% 寻找树上最近点
  20. [nearCoor,preIndex] = findNearPoint(randCoor,T);
  21. %% 按照指定步长生成新的扩展点
  22. newCoor = expandPoint(nearCoor,randCoor,step);
  23. %% 碰撞检测
  24. cubeFlag = isCubeCollision(cubeInfo,nearCoor,newCoor,step); %长方体碰撞检测函数
  25. cylinderFlag = isCylinderCollision(cylinderInfo,nearCoor,newCoor,step); %圆柱体碰撞检测函数
  26. sphereFlag = isSphereCollision(sphereInfo,nearCoor,newCoor,step); %球形障碍物碰撞检测函数
  27. if cubeFlag || cylinderFlag || sphereFlag
  28. continue;
  29. end
  30. %% 将新点插入树中
  31. count = count+1;
  32. T.x(count) = newCoor(1);
  33. T.y(count) = newCoor(2);
  34. T.z(count) = newCoor(3);
  35. T.pre(count) = preIndex;
  36. line([nearCoor(1) newCoor(1)],[nearCoor(2) newCoor(2)],[nearCoor(3) newCoor(3)],'LineWidth',1); %绘制每一个新点
  37. % pause(0.01);
  38. if calcuDis(newCoor,goalPoint)<Thr
  39. break;
  40. end
  41. end
  42. if iter==iterMax
  43. Path = [];
  44. disp('路径规划失败');
  45. return;
  46. end
  47. %% 寻找路径
  48. index = T.pre(end);
  49. count = 1;
  50. while T.pre(index)~=0
  51. Path(count,1) = T.x(index);
  52. Path(count,2) = T.y(index);
  53. Path(count,3) = T.z(index);
  54. index = T.pre(index);
  55. count = count+1;
  56. end
  57. %将初始点添加到Path中
  58. Path(count,1) = startPoint(1);
  59. Path(count,2) = startPoint(2);
  60. Path(count,3) = startPoint(3);
  61. %将目标点添加到Path中
  62. Path = flipud(Path);
  63. count = count+1;
  64. Path(count,1) = goalPoint(1);
  65. Path(count,2) = goalPoint(2);
  66. Path(count,3) = goalPoint(3);
  67. end

16.samplePoint(RRT算法空间随机采样)

  1. function randCoor = samplePoint(axisStart,axisLWH,goalPoint)
  2. if rand<0.5
  3. randX = rand*axisLWH(1)+axisStart(1);
  4. randY = rand*axisLWH(2)+axisStart(2);
  5. randZ = rand*axisLWH(3)+axisStart(3);
  6. randCoor = [randX randY randZ];
  7. else
  8. randCoor = goalPoint;
  9. end
  10. end

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/314768?site
推荐阅读
相关标签
  

闽ICP备14008679号