主要内容

用二维激光雷达进行碰撞预警

这个例子展示了如何使用二维激光雷达数据探测障碍物和警告可能的碰撞。

概述

物流仓库正越来越多地在自动导航车辆(AGV)上安装二维激光雷达,以实现导航目的,这是由于传感器的可承受性、远程和高分辨率。传感器辅助碰撞检测是复杂环境下agv安全导航的重要任务。这个例子展示了如何表示一个充满障碍物的机器人工作空间,生成2-D激光雷达数据,检测障碍物,并在即将发生碰撞前提供警告。

创建仓库地图

要表示机器人工作空间的环境,请定义binaryOccupancyMap(导航工具箱)对象,该对象包含仓库的平面图。占用网格中的每个单元格都有一个逻辑值。被占用的位置表示为1,空闲位置表示为0。您可以使用占用信息来生成合成的二维激光雷达数据。

在地图上靠近AGV指定路线的地方添加障碍物。

%创建二进制仓库地图,并在定义的位置放置障碍物地图= helperCreateBinaryOccupancyMap;%使用障碍物和AGV可视化地图图显示(地图)标题(“带障碍物和AGV的仓库平面图”%将AGV添加到地图中姿势=[5400];helperPlotRobot(gca,姿势);

图中包含一个轴对象。以“带障碍物的仓库平面图”和“AGV”为标题的坐标轴对象包含两个类型为image、patch的对象。

模拟二维激光雷达传感器

使用一个rangeSensor对象为生成的地图收集激光雷达读数。将包含AGV预定义航路点的MAT文件加载到工作区。使用模拟激光雷达传感器返回AGV姿势的范围和角度读数,然后使用范围和角度生成导航lidarScan包含二维激光雷达扫描的对象

%模拟激光雷达传感器并将探测角度设置为[-pi/2 pi/2]激光雷达= rangeSensor;激光雷达。= [-pi/2 pi/2];%设置传感器可检测范围的最小值和最大值,单位为仪表激光雷达。范围=[05];装载AGV通过的路径点负载waypoints.mattraj = waypointsMap;选择一个路径点来可视化扫描数据车辆= traj(350,:);%生成激光雷达读数[范围,角度]=激光雷达(车辆,地图);存储和可视化二维激光雷达扫描扫描=激光雷达扫描(范围、角度);绘图(扫描)标题(“自我观”) helperPlotRobot(gca, [0 0 vehicle (3)]);

图中包含一个Axis对象。标题为Ego View的Axis对象包含两个类型为line、patch的对象。

设置可视化

设置一个图形窗口,显示AGV在仓库中的移动,相关的激光雷达扫描环境,在鸟瞰图中以填充的圆圈显示障碍,以及用颜色编码的碰撞警告信息。每个警告所使用的颜色表示碰撞的可能性,该可能性基于障碍物在该路径点所占据的检测区域。

%设置显示显示= helperVisualizer;%在显示窗口中绘制仓库地图hRobot=plotBinaryMap(显示、贴图、姿势);

基于区域的碰撞警告

只有当障碍物落在AGV的探测区域内时,才会出现碰撞警告。

定义检测区域

创建具有不同颜色、形状的自定义可检测区域,并在figure GUI上修改颜色区域的区域。运行下面的部分代码并修改多边形控制柄,以适应检测区域的要求。下面的代码创建3个半圆区域的多边形控制柄,半径为5、2、1米,AGV为Posite位于[0]的多边形。修改半径或更改多边形对象以创建自定义检测区域。

figure detAxes = gca;标题(两家,定义检测区域的)轴(detAxes,[-210-24])xlabel(detAxes,“X”) ylabel(两家,“Y”)轴(两家,“平等”)网格(两家,“小调”t = linspace(-pi/2, pi/2, 30)';%指定颜色值-白色,黄色,橙色,红色颜色= [1 1 1;1 1 0;1 0.5 0;1 0 0];%以米为单位指定半径半径= [5 2 1];%创建一个多边形类型的3x1矩阵detraeahandles=repmat(images.roi.Polygon[3 1]);pos=[cos(t)sin(t)]*半径(1);pos=[0-2;pos(14:17,:);02];detAreaHandles(1)=drawpolygon(...“父”两家,...“允许交互”“重塑”...“位置”,pos,...“StripeColor”“黑”...“颜色”,颜色(2,:);位置=[cos(t)sin(t)]*半径(2);位置=[0-1.5;位置(12:19,:);0 1.5];区域句柄(2)=drawpolygon(...“父”两家,...“允许交互”“重塑”...“位置”,pos,...“StripeColor”“黑”...“颜色”颜色(:));Pos = [cost sin(t)] * radius(3);Pos = [0 -1;: pos (21);0 1];detAreaHandles (3) = drawpolygon (...“父”两家,...“允许交互”“重塑”...“位置”,pos,...“StripeColor”“黑”...“颜色”、颜色(4:));暂停(2)%暂停以加载检测区域窗口

要保存创建的检测区域,请运行助手保存检测区域函数。使用轴柄的图形与检测区域的多边形相关联detAreaHandles变量作为输入参数。该函数以数据类型矩阵的形式输出检测区域uint8,和一个边界框。检测区域周围的蓝色矩形表示边界框。

甘氨胆酸axesDet =;%包含多边形句柄的图形窗口的轴[detArea,bbox]=助手SaveDetectionArea(axesDet,detAreaHandles);

图中包含一个轴对象。标题为“定义检测区域”的轴对象包含4个类型为image .roi的对象。多边形,形象。

%通过缩放颜色使检测区域透明%alphadata = double(detArea ~= 0) * 0.5;ax3=获取检测区域轴(显示);h=imagesc(ax3,[bbox(1)(bbox(1)+bbox(3))],...-[bbox(2)(bbox(2)+bbox(4))],...德特区);彩色地图(ax3,彩色);地块检测面积plotObstacleDisplay(显示)

运行仿真

检测区域分为三个级别:红色、橙色和黄色。每个区域都与特定的危险程度相关:

  • 红色-碰撞迫在眉睫

  • 橙色:碰撞几率高

  • 黄色-采取谨慎措施

不在探测范围内的障碍物与AGV保持安全距离。以下是碰撞预警的主要步骤:

  • 模拟二维激光雷达并提取点云数据。

  • 将点云数据分割为障碍物簇。

  • 环行每个障碍物以检查可能的碰撞。

  • 根据障碍物的危险程度发出警告。

  • 显示靠近AGV的障碍物。

移动AGV通过航路点对于ij = 27:size(traj, 1) currentPose = traj(ij,:);

模拟二维激光雷达并提取点云数据

使用模拟传感器收集激光雷达读数的地图。从路径点文件加载AGV的当前姿态。使用rangeSensor你创建的对象来获得距离和角度测量。

检索激光雷达扫描[范围,角度]= lidar(currentPose, map);scan = lidarScan(范围,角度);%存储二维扫描为点云车= scan.Cartesian;Cart (:, 3) = 0;电脑= pointCloud(购物车);

将点云数据分割成障碍簇

使用pcsegdist函数,以点间最小欧氏距离为分割准则,将扫描点云分割成簇。

基于欧几里得距离将点云分割成簇minDistance = 0.9;[标签,numClusters] = pcsegdist(pc, minDistance);

用地图和扫描数据更新可视化窗口

%更新显示地图更新更新显示(显示、机器人、当前姿势);%绘制二维激光雷达扫描图plotLidarScan(显示、扫描、currentPose (3));%从上次扫描中删除障碍物以绘制下一扫描线如果存在(“sc”“var”删除(sc)清晰sc终止

绕每个障碍物一圈,找出碰撞的可能性

根据簇的标签循环遍历簇,以提取位于簇内的点。

nearxy = 0 (numClusters, 2);maxlevel =无穷;%循环遍历pc中的所有群集对于i = 1:numClusters c = find(labels == i);% XY坐标提取障碍xy =个人电脑。位置(c, 1:2);

将每个障碍物的世界位置转换为摄像机的坐标系统。

%转换为标准化坐标系(0->最小检测位置%面积,1->检测区域最大位置)= (xy (: 1) xy(:, 2)]——repmat (bbox[1 - 2],[大小(xy, 1) 1]);B = repmat(bbox([3 4]), [size(xy, 1) 1]));xy_org = a / b;% detArea的坐标系(0,0)->(0,0),(1,1)->(宽度,高度)idx =地板(xy_org。* repmat([大小(detArea, 2)大小(detArea,1)],[大小(xy_org, 1), 1]));

提取位于检测区域的障碍物点的指标。

%仅提取detArea中的坐标作为索引valididdx = 1 <= idx(:, 1) & 1 <= idx(:, 2)...idx(: 1) < =大小(detArea, 2) & idx(:, 2) < =大小(detArea, 1);

对于每个有效的障碍点,在检测矩阵中找到对应的值。检测矩阵中所有关联点的最大值决定了该障碍物所代表的危险程度。根据障碍物的危险程度显示一个彩色圆圈警告的颜色显示窗口的窗格。

% Round the index and get the level of each obstacle from detAreacols = idx(valididdx, 1);drawtext (variddx, 2);= double(detArea(sub2ind(size(detArea), rows, cols)));如果~isempty(级别)级别=最大(级别);maxlevel=最大值(maxlevel,level);xyInds=查找(validix);xyInds=xyInds(级别==级别);获得障碍物在探测区域的最近坐标nearxy(i,:) = helperNearObstacles(xy(xyInds,:)));其他的找出障碍物在集群中最近的坐标nearxy(i,:) = helperNearObstacles(xy);终止终止%显示表示危险级别的警告颜色。如果%障碍物不落在检测区域内,不显示颜色。开关maxlevel%红色区域案例3 circleDisplay(显示,颜色(4,:)))%橙色地区案例2圈显示(显示,颜色(3,:)%的黄色区域案例1 circleDisplay(显示,颜色(2,:)))%默认情况否则circleDisplay(显示、[])终止

离自动导轮最近的障碍物显示点

由于仓库中的大多数障碍物都是线性和长的,因此仅显示每个障碍物群中离AGV最近的点。障碍物在仓库中显示为填充圆鸟瞰的情节显示窗口的窗格。

对于i=1:numClusters如果在坐标轴的范围内存在障碍显示sc(i,:) = displayObstacles(display, nearxy(i,:)); / /显示障碍物终止updateDisplay(显示)暂停(0.01)终止

Figure碰撞警告显示包含4个轴对象和uipanel类型的其他对象。标题为仓库平面图的轴对象1包含4个图像、面片、线类型的对象。标题为2-D激光雷达扫描的轴对象2包含2个类型为line、patch的对象。标题显示障碍物的轴对象3包含3个类型为“图像”、“散布”的对象。这些物体代表AGV,障碍物。轴对象4包含散射类型的对象。

碰撞警告显示包含4个轴对象和其他类型的uipanel对象。标题为“仓库平面图”的坐标轴对象1包含686个类型为图像、补丁、线的对象。轴物体2与标题2- d激光雷达扫描包含2个对象的类型线,补丁。轴对象3,标题为“显示障碍”,包含3个类型为“图像,散点”的对象。这些物体代表AGV,障碍。axis对象4包含一个散点类型的对象。

金宝app支持文件

helperCreateBinaryOccupancyMap创建机器人工作区的仓库地图

函数地图= helperCreateBinaryOccupancyMap ()% helperCreateBinaryOccupancyMap创建一个指定的仓库映射%作为参数传递给BinaryOccupencyMap的决议map = binaryOccupancyMap(100, 80, 1);Occ = 0 (80, 100);Occ (1,:) = 1;Occ (end,:) = 1;Occ ([1:30, 51:80], 1) = 1;Occ ([1:30, 51:80], end) = 1;Occ (40, 20:80) = 1;Occ (28:52, [20:21 32:33 44:45 56:57 68:69 80:81]) = 1;Occ (1:12, [20:21 32:33 44:45 56:57 68:69 80:81]) = 1;Occ (end-12:end, [20:21 32:33 44:45 56:57 68:69 80:81]) = 1;%设置位置的占用值车辆占用率(地图、occ);在地图的特定位置添加障碍。输入%helperaddobstack是obstacleWidth、obstaclehight和obstacleLocation。helperAddObstacle(map, 5,5, [10,30]);helperAddObstacle(map, 5,5, [20,17]);helperAddObstacle(map, 5,5, [40,17]);终止%helperAddObstacle为占用地图添加障碍物函数helperAddObstacle(map, obstacleWidth, obstacleHeight, obstacleocation) values = ones(obstacleHeight, obstacleWidth);setOccupancy(地图,obstacleLocation,值)终止

另请参阅

binaryOccupancyMap(导航工具箱)|lidarScan|rangeSensor|pcsegdist