主要内容

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

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

概述

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

创建仓库地图

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

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

%创建一个二进制仓库地图,并在定义的位置放置障碍地图= helperCreateBinaryOccupancyMap;可视化带有障碍物和AGV的地图图显示(地图)标题(“带障碍物和AGV的仓库平面图”%添加AGV到地图[5 40 0];甘氨胆酸helperPlotRobot(构成);

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

模拟二维激光雷达传感器

模拟二维激光雷达传感器使用rangeSensor对象为生成的地图收集激光雷达读数。将包含AGV预定义路径点的mat文件加载到工作空间中。使用模拟的激光雷达传感器返回AGV姿态的距离和角度读数,然后使用距离和角度生成一个lidarScan包含二维激光雷达扫描的对象

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

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

建立可视化

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

%设置显示显示= helperVisualizer;%在显示窗口绘制仓库地图hRobot = plotBinaryMap(display, map, pose);

基于区域的碰撞预警

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

定义检测区域

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

figure detAxes = gca;标题(两家,定义检测区域的)轴(de交税,[-2 10 -2 4])xlabel(de交税,“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矩阵detAreaHandles = repmat (images.roi。多边形,[3]);Pos = [cos(t) sint] *半径(1);Pos = [0 -2;pos(真理:);0 2];detAreaHandles (1) = drawpolygon (...“父”两家,...“InteractionsAllowed”“重塑”...“位置”、pos、...“StripeColor”“黑”...“颜色”颜色(:));Pos = [cost sin(t)] * radius(2);Pos = [0 -1.5;: pos (19);0 1.5);detAreaHandles (2) = drawpolygon (...“父”两家,...“InteractionsAllowed”“重塑”...“位置”、pos、...“StripeColor”“黑”...“颜色”颜色(:));Pos = [cost sin(t)] * radius(3);Pos = [0 -1;: pos (21);0 1];detAreaHandles (3) = drawpolygon (...“父”两家,...“InteractionsAllowed”“重塑”...“位置”、pos、...“StripeColor”“黑”...“颜色”、颜色(4:));暂停(2)%暂停以加载检测区域窗口

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

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

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

%通过缩放颜色使检测区域透明%alphadata = double(detArea ~= 0) * 0.5;ax3 = getDetectionAreaAxes(显示);= imagesc(ax3, [bbox(1) + bbox(3)]),...-[bbox(2) (bbox(2) + bbox(4)],...detArea);colormap (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);

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

%更新显示地图updateMapDisplay(显示、hRobot currentPose);%绘制二维激光雷达扫描图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(levels) level = max(levels);Maxlevel = max(Maxlevel, level);xyInds =找到(validIdx);xinds = xinds (level == level);获得障碍物在探测区域的最近坐标nearxy(i,:) = helperNearObstacles(xy(xyInds,:)));其他的找出障碍物在集群中最近的坐标nearxy(i,:) = helperNearObstacles(xy);结束结束%显示表示危险级别的警告颜色。如果%障碍物不落在检测区域内,不显示颜色。开关maxlevel%红色区域情况下3 circleDisplay(显示,颜色(4,:)))%的橙色区域情况下2 circleDisplay(显示,颜色(3,:)))%的黄色区域情况下1 circleDisplay(显示,颜色(2,:)))%默认情况下否则circleDisplay(显示、[])结束

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

由于仓库中的障碍物大多是线性的,并且是长的,所以只显示每个障碍物群中最接近AGV的点。障碍物显示为填充的圆圈鸟瞰的情节显示窗口的窗格。

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

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

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

万博1manbetx支持文件

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

函数地图= helperCreateBinaryOccupancyMap ()% helperCreateBinaryOccupancyMap创建一个指定的仓库映射%分辨率作为参数传递给binaryOccupancyMapmap = 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;%设置位置的占用值setOccupancy(地图,occ);在地图的特定位置添加障碍。输入% helperAddObstacle是obstacleWidth, obstacleHeight和obstacleocation。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