主要内容

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

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

在本例中,您将了解如何访问来自HDLM服务的平铺层,并识别相关的道路级和车道级拓扑、几何结构和属性。

要读取数据,使用Herehdlm阅读器对象。使用HERE高清实时地图服务需要有效的HERE HDLM凭证。您需要与HERE签订单独的协议,以获得对HDLM服务的访问权,并获得使用HERE服务所需的凭证(access_key_id和access_key_secret)。

概述

高清地图是指专为自动驾驶应用而开发的地图服务。这些地图的精确几何形状(赤道附近分辨率可达1厘米)使其适合于自动驾驶工作流程,超越了传统道路地图的路线规划应用。这样的工作流程包括道级验证、定位和路径规划。这个示例向您展示了如何使用来自高清映射数据的车道级别信息来验证车道检测系统的性能。

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

HERE HD Live Map(HERE HDLM)是HERE Technologies开发的基于云的高清地图服务,用于支持高度自动化的驾驶。数据由平铺的地图层组成,这些地图层提供对道路网金宝app络精确几何结构和稳健属性的访问。这些层分为以下模型:

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

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

  • 高清定位模型:提供支持车辆本地化策略的功能。金宝app

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

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

在本例中,您将学习如何:

  1. 从HERE HDLM服务读取记录的GPS序列的道路和车道信息。

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

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

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

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

加载centerCamera.avi摄像机视频数据和相应的视频时间戳。

recordedData = fullfile (toolboxdir (“开车”),“驱动数据”...“udacity”“drive_segment_09_29_16”);[视频阅读器,视频时间]= helperLoadCameraData(fullfile(recordedData));显示相机数据的第一帧imageFrame = readFrame (videoReader);imshow (imageFrame“边界”“紧”);

从中加载GPS数据gpsSequence.mat垫锉。

data =负载(fullfile (recordedData,“gpsSequence.mat”));gpsData = data.gpsTT;绘制完整的路线和GPS记录的第一个位置gpsPlayer=地质层(gpsData.纬度(1),gpsData.经度(1),18);绘图路线(gpsPlayer、gpsData.纬度、gpsData.经度);绘图位置(gpsPlayer、gpsData.纬度(1)、gpsData.经度(1));

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

创建一个读取HERE高清实时地图的阅读器,覆盖硬盘中所有记录的GPS位置。如果您以前没有设置HERE HDLM凭据,则会出现一个对话框提示您输入凭据。进入访问密钥ID访问密钥秘密您从此处获得的技术,然后单击好吧

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

读取和绘制道路拓扑数据TopologyGeometry层。这一层代表道路网络的结构。网络的节点对应于交叉口和终端。节点之间的连接用折线表示连接街道的形状。这些特征的连通性和几何形状包含在LinksStartingInTile结节字段。

topologyLayer =阅读(读者,“TopologyGeometry”图()“名字”“TopologyGeometry”);topologyAxes =情节(topologyLayer);持有(topologyAxes“开”);geoplot (topologyAxes gpsData。纬度,gpsData。经度,...“博——”“DisplayName的”“路线”);
topologyLayer = TopologyGeometry with properties: Data: HereTileId: 309106790 IntersectingLinkRefs: [44×1 struct] LinksStartingInTile: [895×1 struct] NodesInTile: [651×1 struct] TileCenterHere2dCoordinate: [37.3865 -122.1130] Metadata: Catalog: 'hrn:here: Data::olp-here-had:here- hdl2 -protobuf-na-2' CatalogVersion:使用plot可视化TopologyGeometry数据。

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

给定沿着驱动器记录的GPS位置,你可以使用路线匹配算法来确定记录的位置对应网络上的哪条道路。此示例使用启发式路由匹配算法,该算法考虑到与所记录的地理点在空间上最近的链接。该算法应用车辆的行驶方向来确定最可能的路段。这种路径匹配方法不考虑道路连通性、车辆出入或定位误差较大的GPS数据。因此,此方法可能不适用于所有场景。

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

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

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

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

在匹配的道路上恢复限速

沿着给定道路的所有车道共有的特征归因于描述该道路的链接元素。其中一个属性是速度限制,它描述了在该链接上行驶的车辆的最高法定速度。一旦给定的地理坐标与某个链接相匹配,您就可以确定沿着该链接的速度限制。因为像速度限制这样的特性往往会随着链接的长度而改变,所以这些属性是针对链接的特定范围进行标识的。

SpeedAttributes层包含链接上有关预期车辆速度的信息,包括发布的速度限制。

speedLayer=读取(读卡器,“速度属性”);

helperGetSpeedLimits函数提取链接的相关长度和方向的限速数据。与提取链接的几何信息一样,专门捕获限速数据需要专门的代码。

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

匹配记录的位置到一个车道组

HD车道模型包含车道级的几何图形和道路属性,为支持自动驾驶应用提供必要的细节。金宝app与道路中心线模型相似,HD车道模型也遵循一种模式,即在车道层面使用拓扑来描述道路网络。然后,将通道组的特征归于该拓扑的元素。在HD车道模型中,主要的拓扑元素是车道群。

从中读取和打印车道拓扑数据LaneTopology层。这一层将车道拓扑表示为车道组和车道组连接器。车道组表示一个路段(路段)内的一组车道。车道组连接器将单独的车道组相互连接。这些特征的连通性和几何形状包含在LANEGROUPSSTARTINGTILE线束连接器字段,分别用于车道组和车道组连接器。

laneTopologyLayer=读取(读卡器,“LaneTopology”) laneAxes = helperPlotLayer(lanetopoologylayer,...gpsData。纬度,gpsData.Longitude);geolimits(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数据可视化。

车道组表示多条车道。因此,该元素的几何图形由该组采用的多边形形状表示,如车道组的左右边界所示。使用helperGetGeometry作用

laneGroupFields = {“LaneGroupId”...“BoundaryGeometry.LeftBoundary.Here2dCoordinateDiffs”...“BoundaryGeometry.RightBoundary.Here2dCoordinateDiffs”};laneTopologyTable = helperGetGeometry (laneTopologyLayer。LaneGroupsStartingInTile,...laneGroupFields);laneTopologyTable.Properties.VariableNames={“LaneGroupId”...“LeftGeometry”“右几何”};

与开发匹配算法以识别最可能的行驶路段一样,将给定GPS数据与最可能的车道组进行匹配可以遵循多种方法。此处描述的方法使用两个层:LaneRoadReferencesLaneTopology

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

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

使用helperGetReferences函数生成一个表,其中包含至少存在一定长度路段的所有车道组。

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

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

laneGroupMatcher=HelperLaneGroupMatcher(可参考,laneTopologyTable);匹配车道组和相对方向[laneGroupId, isForward, boundGeometry] = match(laneGroupMatcher, linkId,...gpsData.纬度(1),gpsData.经度(1),gpsData.速度(1,1:2));%绘制车道组的边界几何图形geoplot (gpsPlayer。轴,boundGeometry (: 1), boundGeometry (:, 2),“m.-”);

检索匹配的Lane组的Lane配置

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

使用helperGetLaneAttributes函数为平铺中的每个车道组提取不同的车道类型和车道边界标记。

laneAttributesLayer =阅读(读者,“兰尼特贡品”);laneAttributesTable = helperGetLaneAttributes (laneAttributesLayer);%查找匹配车道组的车道属性条目laneAttribute = laneAttributesTable。LaneGroupId = = LaneGroupId;

可视化和验证记录驱动器与这里的HDLM数据

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

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

hdlmUI=HelperHDLMUI(gpsData.纬度(1),gpsData.经度(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(synchronizedData.Latitude(idx))...ismissing (synchronizedData.Longitude (idx)));如果hasGPSFrame latitude = synchronizedData.Latitude(idx);经度= synchronizedData.Longitude (idx);速度= synchronizedData。速度(idx 1:2);%匹配GPS位置链接[linkId, linkLat, linkLon] = match(linkMatcher,...经度、纬度、速度);如果linkId ~ = prevLinkId%更新链接updateLink (hdlmUI linkLat linkLon);prevLinkId = linkId;%更新速度限制速度= speedTable (speedTable。LinkId == LinkId,:);updateSpeed (hdlmUI speed.Value);终止%匹配GPS位置到车道组[laneGroupId, isForward, boundGeometry] = match(laneGroupMatcher, linkId,...经度、纬度、速度);如果laneGroupId~=前laneGroupId%更新车道组updateLaneGroup(hdlmUI,boundGeometry);prevLaneGroupId=laneGroupId;更新车道类型和边界标记laneAttribute = laneAttributesTable。LaneGroupId = = LaneGroupId;plotLanes (hdlmUI laneAttributesTable。车道{laneAttribute},...laneAttributesTable。LaneBoundaries {laneAttribute}, isForward);终止updatePosition (hdlmUI,经度和纬度);其他的%读取视频帧imageFrame = readFrame (videoReader);终止updateImage(hdlmUI,imageFrame);updateTime(hdlmUI,时间戳);暂停(1/maxDisplayRate);终止

结论

在本例中,您了解了如何:

  1. 从HERE高清实时地图服务中获取给定GPS序列的高清地图数据,并将该数据导入MATLAB。

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

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

本例中讨论的技术可以进一步扩展,以支持感知算法的自动验证。金宝app

金宝app支持功能

帮手在地理图上绘制层数据和路由。

函数gx=helperPlotLayer(图层、纬度、经度)%helperPlotLayer创建带有层数据和路由的地理图% gx = helperPlotLayer(layer, latitude, longitude)创建一个地理位置% axes plot with the plottable HDLM layer and the route given by latitude . % axes plot with the plottable HDLM layer and the route given by latitude%和经度的新数字。图形%绘制层gx =情节(层);%允许向图中添加数据持有(gx“开”);%绘制纬度、经度数据geoplot (gx,经度,纬度,“博——”“DisplayName的”“路线”);持有(gx“关闭”);终止

helperGetGeometry以表格的形式从层中提取拓扑元素的几何形状。

函数geometryTable=helperGetGeometry(图层、字段)%helperGetGeometry为拓扑元素创建一个具有几何形状的表% geometryTable = helperGetGeometry(layer, fields)返回一个表%使用地形几何的指定几何字段格式化%和lanettopology层。%预先分配结构S = repmat(struct, size(layer));对于strsplit(field{:},“。”);对于字段名= strjoin(C,'');S(idx)。(fieldname)=getfield(层,{idx},C{:});终止终止几何表=结构表2;终止

helperGetSpeedLimits以表格的形式从层中提取速度限制数据。

函数speedTable = helperGetSpeedLimits(层)%helperGetSpeedLimits创建具有速度限制的数据表% speedTable = helperGetSpeedLimits(layer)返回格式化为%速度限制开始,结束,方向和值沿指定的链接%由layer指定的SpeedAttributes层对象给出。速度=结构(...“LinkId”, {},...“开始”, {},...“结束”, {},...“方向”, {},...“价值”, {});对于idx = 1: numel(layer.LinkAttribution)%指定链路IDlink=layer.linkattribute(idx);attributes=link.parametricattribute;%检查分配给链接的每个属性对于attrIndex = 1: numel(attributions) linkAttr = vertcat(attributions. linkparameterattribution);%对于每个属性,检查速度限制信息是否正确%上市。如果提供了速度限制,请输入。对于linkAttrIndex = 1: numel(linkAttr)如果~isempty(linkAttr(linkAttrIndex).SpeedLimit)给指定的链接指定速度限制speedLimit =结构;speedLimit。LinkId = link.LinkLocalRef;speedLimit。开始=归因(attrIndex) .AppliesToRange.RangeOffsetFromStart;speedLimit。结束=归因(attrIndex) .AppliesToRange.RangeOffsetFromEnd;speedLimit。方向=归因(attrIndex) .AppliesToDirection;speedLimit。Value = linkAttr(linkAttrIndex).SpeedLimit.Value;将KPH转换为MPH如果strcmpi (linkAttr .SpeedLimit.Unit (linkAttrIndex),“KILOMETERS_PER_HOUR”) speedLimit。值= speedLimit。价值/ 1.609;终止如果strcmpi(速度限制、方向、,“两个”) speed =[速度;speedLimit];%#好的终止终止终止终止终止speedTable = struct2table(速度);终止

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

函数laneRoadReferenceTable = helperGetReferences(层)% helpergetreference创建一个包含车道引用的数据表% laneRoadReferenceTable = helperGetReferences(layer)返回一个表%使用指定链接上存在的所有车道组的列表格式化%由layer指定的LaneRoadReferences图层对象给出。numLinks=numel(layer.LinkLaneGroupReferences);reference=repmat(struct(“LinkId”, {},“LaneGroupId”, {}), numLinks, 1);%从到车道组的链接获取引用对于idx = 1: numLinks link = layer.LinkLaneGroupReferences(idx);laneGroups = vertcat (link.LaneGroupReferences.LaneGroupRef);参考(idx)。LinkId = link.LinkLocalRef;参考(idx)。LaneGroupId = [laneGroups (:) .LaneGroupId];终止laneRoadReferenceTable=struct2table(参考);终止

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

函数laneAttributesTable = helperGetLaneAttributes(层)%helperGetLaneAttributes创建一个lane和boundary类型的表% laneattribu可测试= helperGetLaneAttributes(layer)返回一个表%使用车道类型和每个车道的车道边界标记格式化% lane组在lane attributes层对象中由layer指定。对于laneGroupAttrIndex = 1: numel(layer.LaneGroupAttribution);属性(laneGroupAttrIndex)。LaneGroupId = laneGroup.LaneGroupRef;% #好吧%获取每个车道组的车道类型对于laneAttrIndex = 1: numel(laneGroup.LaneAttribution);laneAttr = vertcat (lane.ParametricAttribution);laneAttr = vertcat (laneAttr.LaneParametricAttribution);对于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} =...boundaries.LaneBoundaryMarking;终止终止LaneAttributeTestable=struct2table(属性);终止

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

函数[videoReader, videoTime] = helperLoadCameraData(dirName)%helperLoadCameraData从时间表中的文件夹中加载摄像机图像% [videoReader, videoTime] = helperLoadCameraData(dirName)加载视频%从文件夹dirName中读取视频的时间戳在名为timeStamps.mat的文件夹中的% mat文件。如果~ isfolder(目录名)错误(预期dirName是文件夹的路径。终止matFileName = fullfile(目录名,“centerCameraTime.mat”);如果存在(文件名,“文件”) ~= 2错误('预期dirName有一个名为centerCameraTime的mat文件。包含时间戳垫。”终止%加载带有时间戳的mat -文件ts=load(matFileName);fieldNames=fields(ts);Time=ts(fieldNames{1});videoFileName=fullfile(dirName,“中心摄像机,avi”);如果存在(文件名,“文件”) ~= 2错误('预期dirName包含名为centerCamera.avi的视频文件。'终止%加载视频文件videoTime =时间表(时间);videoReader = videoReader (videoFileName);终止

另请参阅

||

相关的话题