主要内容

使用这里的高清实时地图数据来验证车道配置

这个例子展示了如何从HERE HD Live Map (HERE HDLM)服务读取和可视化记录的行车路线的车道配置。这种可视化可以用来验证由车载传感器(如单目摄像机)的感知系统检测到的车道配置。

在本例中,您将学习如何从HDLM服务访问平铺层,并识别相关的道路级别和车道级别拓扑、几何图形和属性。

要读取数据,使用这里对象使用HERE HD Live Map服务需要有效的HERE HDLM凭据。您需要与HERE签订单独的协议,以便访问HDLM服务,并获得使用HERE服务所需的凭据(访问密钥id和访问密钥机密)。

概述

高清(HD)地图是指专门为自动驾驶应用开发的地图服务。这些地图的精确几何结构(赤道附近分辨率高达1厘米)使其适合于传统路线图路线规划应用之外的自动驾驶工作流。此类工作流包括车道级别验证、本地化和路径规划。此示例演示如何使用HD地图数据中的车道级别信息验证车道检测系统的性能。

高清地图数据的准确性使其能够用作验证机载传感器感知系统的地面真实数据源。这种高精度能够更快、更准确地验证现有部署的算法。

这里HD Live Map(HEDLM)是由此开发的基于云的高清地图服务,以支持高度自动化的驾驶。万博1manbetx数据由瓷砖映射层组成,可提供对道路网络的准确几何和鲁棒属性的访问。将图层分组为以下模型:

  • 道路中心线模型:提供道路拓扑(在图中指定为节点和链接)、形状几何和其他道路级属性。

  • 高清车道模型:提供车道拓扑(作为车道组和车道组连接件)、高精度几何图形和车道级别属性。

  • 高清本地化模式:提供支持车辆本地化策略的功能。万博1manbetx

关于HERE HDLM层的概述,请参见这里是高清实时地图图层.

在自动驾驶中,摄像头用来收集车辆周围道路拓扑的语义信息。车道边界检测、车道类型分类和路标检测算法构成了该摄像机处理管线的核心。您可以使用HERE HDLM服务,以及安装在车辆上的高精度GPS,来评估这些算法的准确性并验证它们的性能。

在此示例中,您将学习如何:

  1. 阅读Road和Lane信息的HEDLM服务以获取录制的GPS序列。

  2. 对记录的GPS数据采用启发式路径匹配方法。由于GPS数据往往不精确,因此有必要解决记录的地理坐标与路网表示的匹配问题。

  3. 识别与车辆相关的环境属性。一旦车辆在地图环境中成功定位,您可以使用与车辆相关的道路和车道属性来验证车辆的车载摄像头传感器记录的数据。

加载和显示摄像头和GPS数据

首先从记录的驱动器加载数据。本例中的记录数据来自Udacity®自动驾驶汽车团队收集的驾驶数据集。这些数据包括由前置单目摄像机拍摄的视频,以及由GPS记录的车辆位置和速度。

加载中央摄像机摄像机视频数据和相应的视频时间戳。

recordedData=fullfile(toolboxdir(“驾驶”),'divertdata',...“udacity”,'驾驶室段'09'29'16'); [videoReader,videoTime]=helperLoadCameraData(完整文件(recordedData));显示相机数据的第一帧imageFrame = readFrame (videoReader);imshow (imageFrame“边界”,“紧”);

从中加载GPS数据gpsSequence.matMAT-file。

data =负载(fullfile (recordedData,“gpsSequence.mat”)); gpsData=data.gpsTT;%绘制完整路线和GPS记录的第一个位置gpsplayer = geoplayer(gpsdata.latitude(1),GPSData.Longitude(1),18);PlotRoute(GPSPlayer,GPSData.latitude,GPSData.Longitude);绘图(GPSPlayer,GPSData.Lititude(1),GPSData.Longitude(1));

将记录的车辆位置与道路匹配

创建一个读卡器,用于读取覆盖驱动器中所有记录的GPS位置的HERE HD Live Map磁贴。如果您以前没有设置HERE HDLM凭据,则会出现一个对话框提示您输入这些凭据。输入访问密钥ID访问关键秘密您从这里获得的技术,然后点击好吧.

读者= hereHDLMReader (gpsData。纬度,gpsData.Longitude);

从中读取并绘制道路拓扑数据地形几何层。这一层代表道路网络的结构。网络的节点对应于交叉口和终端。节点之间的连接用折线表示连接街道的形状。这些特征的连通性和几何形状包含在链接开始nodesintile.领域。

topologyLayer=读取(读卡器,“TopologyGeometry”)身材(“姓名”,“TopologyGeometry”);topologyAxes =情节(topologyLayer);持有(topologyAxes'在');geoplot (topologyAxes gpsData。纬度,gpsData。经度,...'bo-',“DisplayName的”,“路线”);
topologyLayer=具有属性的拓扑几何:数据:HereTileId:309106790相交链接参考:[44×1结构]链接开始链接:[895×1结构]节点实体:[651×1结构]TileCenter坐标:[37.3865-122.1130]元数据:目录:'hrn:here:data::olp here had:here-hdlm-protobuf-na-2'目录版本:4601使用绘图可视化地形几何数据。

的绘图功能被捕获螺旋桨层功能,可从HD Live Map层与记录驱动器在同一地理轴上的可用数据可视化。这个在示例末尾定义的函数将用于绘制后续层。

给定沿车道记录的GPS位置,您可以使用路线匹配算法来确定记录的位置对应于网络上的哪条道路。本例使用启发式路线匹配算法,该算法在空间上考虑与记录的地理点最近的链路。该算法应用车辆的行驶方向这种路线匹配方法不考虑道路连通性、车辆访问或GPS数据具有高位置误差。因此,这种方法可能不适用于所有场景。

这个辅助几何函数从给定的拓扑层提取几何信息,并在带有相应链接的表中返回该信息。

topologyTable = helperGetGeometry (topologyLayer。LinksStartingInTile,...{'linkid',的几何形状。Here2dCoordinateDiffs”});topologyTable.Properties.VariableNames = {'linkid',“几何学”};

这个HelperLinkMatcher类创建链接匹配器,其中包含所需地图平铺中每个链接的形状几何体。此类使用基本空间分析将记录的位置与道路链接的形状坐标相匹配。

linkMatcher = HelperLinkMatcher (topologyTable);%将记录路由的第一个点匹配到最可能的链接[linkId, linkLat, linkLon] = match(linkMatcher, gpsData.Latitude(1),...经度(1),速度(1,1:2);%绘制链接的形状几何形状geoplot (gpsPlayer。轴,linkLat linkLon,“r.-”);

检索匹配道路上的速度限制

给定道路上所有车道的共同特征都归因于描述该道路的链接元素。其中一个属性speed limit(速度限制)描述了在链接上行驶的车辆的最大法定速度。一旦给定的地理坐标与链接匹配,您就可以识别该链接上的速度限制。因为速度限制通常随链接长度而变化,这些属性针对链接的特定范围进行标识。

这个SpeedAttributes图层包含链接上预期车辆速度的信息,包括张贴的速度限制。

SpeedLayer =读(读者,“SpeedAttributes”);

这个螺旋铲除限制功能提取链路相关长度和方向的速度限制数据。与提取链路的几何信息一样,特别是捕获速度限制数据需要专门的代码。

speedTable = helperGetSpeedLimits (speedLayer);%找到匹配链接的速度限制条目速度= speedTable (speedTable。LinkId == LinkId,:);

将记录的位置与车道组匹配

HD Lane模型包含道路级几何和道路属性,提供支持自动驾驶应用所需的详细信息。万博1manbetx与道路中心线模型一样,HD车道模型还遵循使用拓扑的模式来描述车道水平的道路网络。然后,车道组的功能归因于该拓扑的元素。在高清车道模型中,主要拓扑元素是车道组。

读取和绘制车道拓扑数据来自LaneTopology层。这一层将车道拓扑表示为车道组和车道组连接器。车道组表示一个路段(路段)内的一组车道。车道组连接器将单独的车道组相互连接。这些特征的连通性和几何形状包含在Lanegroupsstartingintile.LaneGroupConnectorstile.字段,分别用于车道组和车道组连接器。

lanetopologylayer =读(读者,'lanetopology') laneAxes = helperPlotLayer(lanetopoologylayer,...gpsData.纬度,gpsData.经度);地质界限(laneAxes[37.3823,37.3838]、-122.1151、-122.1128]);
laneTopologyLayer = LaneTopology属性:数据:HereTileId: 309106790 IntersectingLaneGroupRefs:[56×1 struct] LaneGroupConnectorsInTile:[1174×1 struct] LaneGroupsStartingInTile:[1783×1 struct] TileCenterHere2dCoordinate:[37.3865 - -122.1130]元数据:目录:“hrn::数据::olp-here-had: here-hdlm-protobuf-na-2”CatalogVersion:4601使用plot将lanettopology数据可视化。

车道组代表多个车道。因此,该元素的几何形状由组所采用的多边形形状给出,如通道组的左和右边界所表达的。通过使用通过使用车道边界获取此车道几何形状辅助几何功能。

LANEGROUP字段={“LaneGroupId”,...“BoundaryGeometry.LeftBoundary.Here2dCoordinateDiffs”,...'boundardgeometry.rightboutnary.here2dcoordindiffs'};laneTopologyTable = helperGetGeometry (laneTopologyLayer。LaneGroupsStartingInTile,...LaneGroupFields);lanetopologytable.properties.variablenames = {“LaneGroupId”,...“LeftGeometry”,'命令大学'};

与开发匹配算法以识别最可能的旅行链路一样,与给定的GPS数据匹配到最可能的车道组可以遵循多种方法。这里描述的方法使用两层:LaneRoadReferencesLaneTopology.

  • 这个LaneRoadReferences层可以让你将道路中心线模型上的一个位置(通过链接给出)转换到高清车道模型上的相应位置(通过车道组给出)。由于链接之前已被识别,您可以筛选候选车道组匹配到平铺中可用的所有车道组的更小子集。

  • 这个LaneTopology层给出几何数据,可以用来考虑存在于每个候选车道组的空间边界内的数据。与GPS数据与链接的空间匹配一样,这种方法容易产生误差,并取决于记录的GPS数据的准确性。除了匹配车道组,你还需要匹配车辆的方向向量相对于车道组的方向。这个步骤是必要的,因为车道的属性是根据拓扑方向定义的。

使用helperGetReferences函数生成存在至少一些链路的所有通道组的表。

referenceLayer =阅读(读者,“LaneRoadReferences”);referenceTable=helperGetReferences(referenceLayer);

创建车道组匹配器,该匹配器包含所需地图平铺中每个车道组的边界几何图形HelperLaneGroupMatcher类创建一个车道组匹配器,其中包含所需地图块中的每个车道组的边界形状几何。它还包含与Lane组链接的参考表。和我们一样HelperLinkMatcher类,此类使用简单的空间分析方法来确定是否存在在车道组的边界内存在给定的录制坐标。

LaneGroupMatcher = HelperlaneGroupMatcher(参考,LanetopologyTable);匹配车道组和相对方向[laneGroupId,isForward,boundGeometry]=匹配(laneGroupMatcher,linkId,...GPSDATA.lititude(1),GPSDATA.Longitude(1),GPSDATA.VELOCITY(1,1:2));%绘制车道组的边界几何geoplot (gpsPlayer。轴,boundGeometry (: 1), boundGeometry (:, 2),'M.-');

检索匹配车道组的车道配置

与由标识符映射到链接的速度属性一样,车道属性也通过使用车道组ID将特征分配给车道组。这个LaneAttributes图层包含有关车道组的信息,包括组中每个车道的类型和车道边界的特征。

使用helperGetLaneAttributes用于提取瓦片中的每个车道组的不同通道类型和车道边界标记的功能。

laneAttributesLayer=读取(读卡器,'laneattributes');laneAttributesTable=helperGetLaneAttributes(laneAttributesLayer);%找到匹配的车道组的Lane属性条目laneAttribute = laneAttributesTable。LaneGroupId = = LaneGroupId;

使用此处的HDLM数据可视化并验证记录的驱动器

为识别道路和车道属性而生成的匹配算法和表格可以扩展到记录的GPS坐标序列。对于每个时间步长,车辆的位置与道路上的路段和车道组相匹配。此外,车速限制和车道配置显示,以及相应的摄像头图像。

这个HelperHDLMUI类创建用于从录制的驱动器流式传输视频和GPS数据的工具,并在每个录制的车辆位置显示来自所选HD Live Map层的相关信息。

hdlmui = helperhdlmui(gpsdata.latitude(1),GPSData.Longitude(1));同步相机和GPS数据到一个共同的时间表synchronizedData = synchronize(videoTime, gpsData); / /同步videoReader。CurrentTime = 0;maxDisplayRate = videoReader。帧速率* 5;%初始化一些变量以维护历史记录prevLinkId=0;prevLaneGroupId=0;为了IDX = 1:高度(SynchronizedData)时间戳= SynchronizedData.time(IDX);%检查当前时间戳是否有GPS数据hasGPSFrame=~(ismissing(同步数据纬度(idx))||...ismissing(同步数据经度(idx));如果hasGPSFrame latitude = synchronizedData.Latitude(idx);经度= synchronizedData.Longitude (idx);速度= synchronizedData。速度(idx 1:2);%将GPS位置与链路匹配[linkid,linklat,linklon] =匹配(linkmatcher,...纬度、经度、速度);如果linkId~=prevLinkId%更新链接updateLink (hdlmUI linkLat linkLon);prevLinkId = linkId;%更新速度限制速度=速度表(speedTable.LinkId==LinkId,:);更新速度(hdlmUI,speed.Value);结尾%将GPS位置与车道组匹配[laneGroupId,isForward,boundGeometry]=匹配(laneGroupMatcher,linkId,...纬度、经度、速度);如果LaneGroupid〜= prevlanegroupid%更新车道组UpdatelaneGroup(HDLMUI,BroundGeometry);prevlanegroupid = lanegroupid;%更新车道类型和边界标记laneAttribute=LaneAttributeTestable.LaneGroupId==LaneGroupId;绘图车道(hdlmUI,LaneAttributeTestable.Lanes{laneAttribute},...LaneAttributeTestable.LaneBoundaries{laneAttribute},isForward);结尾updatePosition (hdlmUI,经度和纬度);别的%读取视频帧imageFrame = readFrame (videoReader);结尾UpdateImage(HDLMUI,ImageFrame);UpdateTime(HDLMUI,时间戳);暂停(1 / maxdisplayrate);结尾

结论

在本例中,您探讨了如何:

  1. 从HERE HD Live Map服务访问给定GPS序列的高清地图数据,并将该数据导入MATLAB。

  2. 将记录的GPS数据与导入的道路网数据进行匹配,以查找每个地理坐标的相关路段和车道组。

  3. 查询匹配路段和车道组的属性,例如速度限制和车道类型,以开发一个工具,根据记录的摄像头数据直观地验证道路特征。

本例中讨论的技术可以进一步扩展,以支持感知算法的自动验证。万博1manbetx

万博1manbetx支持功能

螺旋桨层在地理图上绘制层数据和路由。

函数GX =螺旋平板(层,纬度,经度)%helperPlotLayer使用图层数据和管线创建地理绘图%gx=helperPlotLayer(图层、纬度、经度)创建地理位置%轴使用绘图仪HDLM图层和纬度给定的路线进行打印%和经度的新数字。数字;%绘图层gx =情节(层);%允许向图中添加数据保持(gx,'在');%绘图纬度、经度数据地理地块(gx、纬度、经度、,'bo-',“DisplayName的”,“路线”);保持(gx,“关”);结尾

辅助几何以表格的形式从图层中提取拓扑元素的几何图形。

函数GeometRytable =螺杆凝固率(图层,字段)%helperGetGeometry使用拓扑元素的几何图形创建表% geometryTable = helperGetGeometry(layer, fields)返回一个表百分比与顶部Geefometry的指定几何字段格式化%和LaneTopology层。%预先分配结构S=repmat(结构、尺寸(层));为了field=fields C=strsplit(字段{:},'.');为了idx=1:numel(图层)字段名=strjoin(C,'');s(idx)。(fieldname)= getfield(图层,{idx},c {:});结尾结尾geometrytable = struct2table;结尾

螺旋铲除限制以表格的形式从图层中提取速度限制数据。

函数speedTable = helperGetSpeedLimits(层)%HerpergetSpeedLimits创建具有速度限制的数据表%speedTable=helperGetSpeedLimits(图层)返回格式为%沿指定链接的速度限制开始、结束、方向和值%由layer指定的SpeedAttributes层对象给出。speed = struct(...'linkid',{},...“开始”,{},...'结尾',{},...“方向”,{},...“价值”, {});为了idx=1:numel(layer.linkattribute)%指定链路IDlink = layer.linkAttribution(IDX);属性= link.parameTricAttribution;%检查分配给链接的每个属性为了attrIndex=1:numel(属性)linkAttr=vertcat(属性.LinkParameterAttribute);每个属性的%,检查速度限制信息是否是%列出。如果提供速度限制,则进行条目。为了linkAttrIndex = 1: numel(linkAttr)如果〜isempty(linkattr(linkattrindex).speedlimit)%为指定的链路指定速度限制speedLimit=struct;speedLimit.LinkId=link.LinkLocalRef;speedLimit.Start=属性(attrIndex)。AppliesToRange.RangeOffsetFromStart;speedLimit.End=属性(attrIndex)。AppliesToRange.RangeOffsetFromEnd;speedLimit.Direction=属性(attrIndex)。AppliesToDirection;speedLimit.Value=linkAttr(linkAttrIndex)。speedLimit.Value;将KPH转换为MPH如果strcmpi(linkAttr(linkAttrIndex).SpeedLimit.Unit,“每小时公里数”) speedLimit。值= speedLimit。价值/ 1.609;结尾如果Strcmpi(speedlimit.direction,“两个”)速度=[速度;速度限制];%#OK 结尾结尾结尾结尾结尾speedTable = struct2table(速度);结尾

helperGetReferences以表格的形式从图层对象中提取车道引用。

函数laneRoadReferenceTable = helperGetReferences(层)% helpergetreference创建一个包含车道引用的数据表%laneRoadReferenceTable=helperGetReferences(层)返回一个表%格式化,其中包含在指定链接上存在的所有通道组列表由图层指定的laneroocoReferstations对象给出的%。numlinks = numel(layer.linklanegroupreferences;参考= repmat(结构('linkid',{},“LaneGroupId”,{},numLinks,1);%获取与Lane组链接的引用为了idx=1:numLinks link=layer.LinkLaneGroupReferences(idx);laneGroups=vertcat(link.LaneGroupReferences.LaneGroupRef);reference(idx).LinkId=link.LinkLocalRef;reference(idx).LaneGroupId=[laneGroups(:).LaneGroupId];结尾laneroadreferenceTable = struct2table(参考);结尾

helperGetLaneAttributes以表格的形式从图层对象中提取lane属性。

函数laneAttributesTable = helperGetLaneAttributes(层)%helperGetLaneAttributes创建一个lane和boundary类型的表%laneAttributesTable=helperGetLaneAttributes(层)返回一个表%格式化的车道类型和每个车道边界标记%层指定的LaneAttributes层对象中的车道组。为了laneGroupAttrIndex = 1: numel(layer.LaneGroupAttribution);属性(laneGroupAttrIndex)。LaneGroupId = laneGroup.LaneGroupRef;% #好吧%GET LANE类型为每个车道组为了laneAttrIndex=1:numel(laneGroup.LaneAttribution)lane=laneGroup.LaneAttribution(laneAttrIndex);laneAttr=vertcat(laneAttr.LANEPARAMETRIBUTION);laneAttr=vertcat(laneAttr.LANEPARAMETRIBUTION);为了idx = 1: num (laneAttr)如果~ isempty (laneAttr (idx) .LaneType)属性(laneGroupAttrIndex) .Lanes{巷。LaneNumber} =...laneAttr (idx) .LaneType;结尾结尾结尾得到每个车道组的车道边界为了laneBoundary = 1: numel(laneGroup.LaneBoundaryAttribution);边界= vertcat (laneBoundary.ParametricAttribution.LaneBoundaryParametricAttribution);属性(laneGroupAttrIndex) .LaneBoundaries {laneBoundary。LaneBoundaryNumber} =...边界。LaneBoundaryMarking;结尾结尾laneAttributesTable = struct2table(属性);结尾

helperLoadCameraData从文件夹加载一个视频阅读器和时间戳。

函数[videoReader, videoTime] = helperLoadCameraData(dirName)%helperLoadCameraData从时间表中的文件夹中加载摄像机图像%[videoReader,videoTime]=helperLoadCameraData(dirName)加载视频%从文件夹DirName。视频的时间戳是从a读取的%名为timeStamps.MAT的文件夹中的MAT文件。如果~ isfolder(目录名)错误('预期dirName是文件夹的路径。')结尾matFileName = fullfile(目录名,“中央照相机时间.垫”);如果存在(Matfilename,“文件”) ~= 2错误('预期dirName有一个名为centerCameraTime的mat文件。包含时间戳垫。”)结尾%加载带有时间戳的MAT文件ts = load(matfilename);FieldNames =字段(TS);时间= ts。(fieldnames {1});Videofilename = fullfile(dirname,'centercamera.avi');如果存在(Matfilename,“文件”) ~= 2错误('预期的垃圾名是有一个名为centercamera.avi的视频文件。)结尾%加载视频文件videoTime =时间表(时间);videoReader = videoReader (videoFileName);结尾

另见

||

相关的话题