主要内容

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

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

在此示例中,您了解如何从HDLM服务访问瓷砖层,并识别相关的道路级和车道级拓扑,几何和属性。

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

概述

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

HD映射数据的准确性使其用作地板传感器感知系统验证的地面真理数据的源。这种高精度可以更快,更准确地验证现有的已部署算法。

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

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

  • 高清车道模型:提供Lane拓扑(作为车道组和车道组连接器),高精度的几何和车道级属性。

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

有关此处HDLM层的概述,请参阅这里有高清实时地图图层

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

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

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

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

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

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

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

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

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

从中加载GPS数据gpssequence.mat.MAT-file。

data =负载(fullfile (recordedData,“gpsSequence.mat”)); gpsData=data.gpsTT;%绘制完整路线和GPS记录的第一个位置gpsPlayer = geoplayer(gpsData.Latitude(1), gpsData.Longitude(1), 18);plotRoute (gpsPlayer gpsData。纬度,gpsData.Longitude);plotPosition (gpsPlayer gpsData.Latitude (1) gpsData.Longitude (1));

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

创建一个读者,用于读取此处的HD Live Map Tiles,其涵盖驱动器中的所有录制的GPS位置。如果此前未在此处设置HDLM凭据,则对话框会提示您输入它们。输入访问密钥ID访问密钥秘密您从此处获得的技术,然后单击好吧

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

从中读取并绘制道路拓扑数据地形几何图层。此图层表示道路网络的配置。网络节点对应于交叉点和死胡同。节点之间的连接将连接街道的形状表示为多段线。这些功能的连接和几何图形包含在链接开始结节字段。

TopologyLayer =读(读者,“地形几何”)身材('姓名'“地形几何”);topologyAxes=绘图(topologyLayer);保持(topologyAxes,“开”)地理图(地形、地理纬度、地理经度、,...“博——”“显示名称”“路线”);
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”'几何体。此处为2坐标自由度'});topologyTable.Properties.VariableNames={“LinkId”'几何学'};

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

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

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

沿着特定道路的所有通道共用的特征归因于描述该道路的链接元素。一种这样的属性,速度限制描述了在链路上行驶的车辆的最大法律速度。一旦给定的地理坐标与链接匹配,就可以识别该链路的速度限制。因为速度限制的特征通常沿链路的长度变化,所以识别这些属性用于链路的特定范围。

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

speedLayer=读取(读卡器,“SpeedAttributes”);

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

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

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

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

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

laneTopologyLayer=读取(读卡器,“LaneTopology”)laneAxes=helperPlotLayer(laneTopologyLayer,...gpsdata.latitude,gpsdata.longitude);geolimits(laneAxes,[37.3823,37.3838],[-122.1151,-122.1128]);
laneTopologyLayer=LaneTopology及其属性:数据:HereTileId:309106790相交LaneGroupRefs:[56×1结构]LaneGroupConnectorIntile:[1174×1结构]LaneGroupsStartingTile:[1783×1结构]TileCenter坐标:[37.3865-122.1130]元数据:目录:'hrn:here:data::olp here had:here-hdlm-protobuf-na-2'CatalogVersion:4601使用绘图可视化LaneTopology数据。

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

LANEGROUP字段={“绵羊群”...“BoundaryGeometry.LeftBoundary.Here2dCoordinateDiffs”...“BoundaryGeometry.RightBoundary.Here2dCoordinateDiffs”};laneTopologyTable=helperGetGeometry(laneTopologyLayer.LaneGroupsStartingTile,...laneGroupFields);laneTopologyTable.Properties.VariableNames={“绵羊群”...“LeftGeometry”“右几何”};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hdlmUI=HelperHDLMUI(gpsData.纬度(1),gpsData.经度(1));%将摄像头和GPS数据同步到公共时间表中synchronizedData=同步(videoTime,gpsData);videoReader.CurrentTime=0;maxDisplayRate=videoReader.FrameRate*5;%初始化一些变量以维护历史记录prevLinkId=0;prevLaneGroupId=0;对于idx=1:高度(synchronizedData)时间戳=synchronizedData.Time(idx);%检查当前时间戳是否有GPS数据hasGPSFrame=~(ismissing(同步数据纬度(idx))||...ismissing(同步数据经度(idx));如果hasGPSFrame纬度=同步数据。纬度(idx);经度=同步数据。经度(idx);速度=同步数据。速度(idx,1:2);%匹配GPS位置链接[linkId, linkLat, linkLon] = match(linkMatcher,...纬度、经度、速度);如果linkid〜= prevlinkId%更新链接updateLink(hdlmUI、linkLat、linkLon);prevLinkId=linkId;%更新速度限制速度=速度表(speedTable.LinkId==LinkId,:);更新速度(hdlmUI,speed.Value);终止%匹配GPS位置到Lane组[laneGroupId,isForward,boundGeometry]=匹配(laneGroupMatcher,linkId,...纬度、经度、速度);如果laneGroupId~=前laneGroupId%更新车道组updateLaneGroup (hdlmUI boundGeometry);prevLaneGroupId = laneGroupId;%更新车道类型和边界标记laneAttribute=LaneAttributeTestable.LaneGroupId==LaneGroupId;绘图车道(hdlmUI,LaneAttributeTestable.Lanes{laneAttribute},...laneattributestable.laneboundaries {laneattribute},是勇敢的);终止updatePosition (hdlmUI,经度和纬度);其他的%读取视频帧imageFrame = readFrame (videoReader);终止updateImage(hdlmUI,imageFrame);updateTime(hdlmUI,时间戳);暂停(1/maxDisplayRate);终止

结论

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

  1. 从这里的HD Live Map服务中访问给定GPS序列的HD映射数据,并将该数据导入MATLAB。

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

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

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

万博1manbetx辅助功能

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

函数gx=helperPlotLayer(图层、纬度、经度)%helperPlotLayer使用图层数据和管线创建地理绘图%gx=helperPlotLayer(图层、纬度、经度)创建地理位置%轴使用绘图仪HDLM图层和纬度给定的路线进行打印%和一个新数字上的经度。图形%绘图层gx=绘图(图层);%启用向绘图添加数据持有(GX,“开”);%绘图纬度、经度数据Geoplot(GX,纬度,经度,“博——”“显示名称”“路线”);持有(GX,“关”);终止

终止训练器以表格的形式从图层中提取拓扑元素的几何图形。

函数geometryTable=helperGetGeometry(图层、字段)%促使geporyry创建一个具有拓扑元素的几何形状的表%geometryTable=helperGetGeometry(图层、字段)返回一个表%使用地形几何的指定几何字段格式化%和lanetopology层。%预先分配结构S=repmat(结构、尺寸(层));对于字段=字段C = strsplit(字段{:},'。');对于idx = 1:numel(图层)fieldname = strjoin(c,'');S(idx)。(fieldname)=getfield(层,{idx},C{:});终止终止几何表=结构表2;终止

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

函数speedTable=helperGetSpeedLimits(图层)%helperGetSpeedLimits创建具有速度限制的数据表%speedtable = helpergetspeedlimits(图层)返回格式化的表%速度限制启动,结束,方向和值沿指定链接%如图层指定的SpeedAttributes图层对象所示。速度=结构(...“LinkId”, {},...'开始', {},...“结束”, {},...“方向”, {},...'价值', {});对于idx = 1:numel(tillay.linkattribution)%分配链接IDlink=layer.linkattribute(idx);attributes=link.parametricattribute;%检查指定给链接的每个属性对于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,'kilomers_per_hour')speedLimit.Value=speedLimit.Value/1.609;终止如果strcmpi(速度限制、方向、,“都是”)速度= [速度;速度极限];%#好的终止终止终止终止终止speedTable=struct2table(速度);终止

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

函数laneRoadReferenceTable=helperGetReferences(层)% helpergetreference创建一个包含车道引用的数据表%laneRoadReferenceTable=helperGetReferences(层)返回一个表%使用指定链接上存在的所有车道组的列表格式化%由layer指定的LaneRoadReferences图层对象给出。numLinks=numel(layer.LinkLaneGroupReferences);reference=repmat(struct(“LinkId”, {},“绵羊群”,{},numLinks,1);%从到车道组的链接获取引用对于idx = 1:numlinks link = tillay.linklanegroupreferences(IDX);LaneGroups = Vertcat(link.lanegroupreferences.lanegroupref);参考(IDX).linkId = link.linklocalref;参考(idx).lanegroupid = [Lanegroups(:)。Lanegroupid]';终止laneRoadReferenceTable=struct2table(参考);终止

helpergetlanetributes以表格的形式从图层对象提取车道属性。

函数LaneAttributeTestable=helperGetLaneAttributes(图层)%helperGetLaneAttributes创建具有车道和边界类型的表%laneattributeStable = HelpergetLaneattributes(图层)返回表格%使用车道类型和每个车道的车道边界标记格式化%层指定的LaneAttributes层对象中的车道组。对于laneGroupAttrIndex = 1: numel(layer.LaneGroupAttribution);属性(laneGroupAttrIndex)。LaneGroupId = laneGroup.LaneGroupRef;%#嗯%获取每个车道组的车道类型对于laneAttrIndex=1:numel(laneGroup.LaneAttribution)lane=laneGroup.LaneAttribution(laneAttrIndex);laneAttr=vertcat(laneAttr.LANEPARAMETRIBUTION);laneAttr=vertcat(laneAttr.LANEPARAMETRIBUTION);对于idx=1:numel(laneAttr)如果~isempty(laneAttr(idx).LaneType)属性(laneGroupAttrIndex).Lanes{lane.LaneNumber}=...laneAttr (idx) .LaneType;终止终止终止%获取每个车道组的车道边界对于laneBoundary = 1: numel(laneGroup.LaneBoundaryAttribution);边界= vertcat (laneBoundary.ParametricAttribution.LaneBoundaryParametricAttribution);属性(laneGroupAttrIndex) .LaneBoundaries {laneBoundary。LaneBoundaryNumber} =...边界。LaneBoundaryMarking;终止终止laneAttributesTable = struct2table(属性);终止

helperLoadCameraData从文件夹中加载视频读取器和时间戳。

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

也可以看看

||

相关的话题