主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

使用 RoadRunner 高清地图在 RoadRunner 中构建测试赛道 3D 场景

此示例演示如何使用 MATLAB® 函数为测试跑道构建 RoadRunner 场景。您可以使用包含经纬度坐标的 Keyhole 标记语言 (KML) 文件和包含高程的 GeoTIFF 文件构建测试轨道场景。要导入道路数据文件,您必须拥有 Mapping Toolbox™ 许可证。

导入 KML 文件用于测试轨道

在此示例中,您将轨道中心的坐标从 KML 文件(地图数据 © 2022 by Google)导入 MATLAB,然后使用 MATLAB 函数绘制从 KML 文件导入的数据来查看坐标。

通过从 KML 文件读取地理数据来创建地理空间表。

kmlData = readgeotable("TestTrackKMLData.kml");

绘制测试跑道的坐标。

geoplot(kmlData)
geobasemap topographic

Figure contains an axes object with type geoaxes. The geoaxes object contains an object of type line.

导入 GeoTIFF 文件用于测试轨道

本例中使用的样本地形数据是从 EarthExplorer 下载的,它提供了来自美国地质调查局 (USGS) 档案的地球科学数据。您可以通过将 shapefile 上传到 EarthExplorer 来从 USGS 网站下载 TIF 文件,这会将 EarthExplorer 裁剪到测试轨道的区域。

将地理空间表转换为道路中心表,即可获取测试赛道的经纬度坐标。

T = geotable2table(kmlData,["Latitude","Longitude"]);
[georefGrid,spatialRef] = readgeoraster("TestTrack.tif",OutputType="double");
[lat1,lon1] = polyjoin(T.Latitude(1),T.Longitude(1));
[lat2,lon2] = polyjoin(T.Latitude(2),T.Longitude(2));
[lat3,lon3] = polyjoin(T.Latitude(3),T.Longitude(3));
[lat4,lon4] = polyjoin(T.Latitude(4),T.Longitude(4));
[lat5,lon5] = polyjoin(T.Latitude(5),T.Longitude(5));
[lat6,lon6] = polyjoin(T.Latitude(6),T.Longitude(6));
[lat7,lon7] = polyjoin(T.Latitude(7),T.Longitude(7));

从地形数据中查询轨迹坐标的高程。

ctrElev1 = geointerp(georefGrid,spatialRef,lat1,lon1);
ctrElev2 = geointerp(georefGrid,spatialRef,lat2,lon2);
ctrElev3 = geointerp(georefGrid,spatialRef,lat3,lon3);
ctrElev4 = geointerp(georefGrid,spatialRef,lat4,lon4);
ctrElev5 = geointerp(georefGrid,spatialRef,lat5,lon5);
ctrElev6 = geointerp(georefGrid,spatialRef,lat6,lon6);
ctrElev7 = geointerp(georefGrid,spatialRef,lat7,lon7);

创建 RoadRunner 高清地图

创建 RoadRunner 高清地图并设置感兴趣区域的地理参考。

创建一个空的 RoadRunner 高清地图作为 roadrunnerHDMap 对象。

rrMap = roadrunnerHDMap;

计算道路网原点的地理坐标作为道路网边界四边形的中心。

[latLim1,lonLim1] = geoquadline(lat1,lon1);
latMean1 = mean(latLim1);
lonMean1 = mean(lonLim1);

设置感兴趣区域的地理参考。

rrMap.GeoReference = [latMean1 lonMean1];

将经纬度坐标投影至 xy 地图坐标

使用投影坐标参考系统 (CRS) 将导入的纬度和经度坐标转换为 xy 地图坐标。然后,使用 xy 地图坐标作为轨道中心,设置轨道宽度。

从 RoadRunner 高清地图读取横轴墨卡托投影 CRS。

p = readCRS(rrMap);

将纬度和经度坐标投影到 xy 坐标。

[x1,y1] = projfwd(p,lat1,lon1);
[x2,y2] = projfwd(p,lat2,lon2);
[x3,y3] = projfwd(p,lat3,lon3);
[x4,y4] = projfwd(p,lat4,lon4);
[x5,y5] = projfwd(p,lat5,lon5);
[x6,y6] = projfwd(p,lat6,lon6);
[x7,y7] = projfwd(p,lat7,lon7);

定义测试跑道的道路中心和道路宽度。

rdCtrs1 = [x1 y1 ctrElev1];
rdWidth1 = 6.5;
rdCtrs2 = [x2 y2 ctrElev2];
rdWidth2 = 10;
rdCtrs3 = [x3 y3 ctrElev3];
rdWidth3 = 5;
rdCtrs4 = [x4 y4 ctrElev4];
rdWidth4 = 3.5;

上采样道路数据

由于从 KML 文件获取的数据点稀疏,并且测试赛道包含尖锐的曲线,因此必须对数据进行上采样,以避免建模不准确的赛道车道。使用 helperRoadDimensions 辅助函数对数据进行上采样。

[lftBndry1,rgtBndry1,ctrBndry1] = helperRoadDimensions(rdCtrs1,rdWidth1);
[lftBndry2,rgtBndry2,ctrBndry2] = helperRoadDimensions(rdCtrs2,rdWidth2);
[lftBndry3,rgtBndry3,ctrBndry3] = helperRoadDimensions(rdCtrs3,rdWidth3);
[lftBndry4,rgtBndry4,ctrBndry4] = helperRoadDimensions(rdCtrs4,rdWidth4);

指定车道和车道边界

使用插值数据创建 RoadRunner 高清地图,并修改数据以类似于测试跑道。

指定 RoadRunner 高清地图的车道属性。

rrMap.Lanes(4,1) = roadrunner.hdmap.Lane;
for i = 1:4
    rrMap.Lanes(i).Geometry = eval(strcat("ctrBndry",num2str(i)));
    rrMap.Lanes(i).TravelDirection = "Bidirectional";
    rrMap.Lanes(i).ID = strcat("Lane",num2str(i));
    rrMap.Lanes(i).LaneType = "Driving";
end

指定车道边界信息。

rrMap.LaneBoundaries(8,1) = roadrunner.hdmap.LaneBoundary;
for i = 1:4
    rrMap.LaneBoundaries(i*2-1).ID = strcat("Left",num2str(i));
    rrMap.LaneBoundaries(i*2).ID = strcat("Right",num2str(i));
    rrMap.LaneBoundaries(i*2-1).Geometry = eval(strcat('lftBndry',num2str(i)));
    rrMap.LaneBoundaries(i*2).Geometry = eval(strcat('rgtBndry',num2str(i)));
end

指定车道和车道边界之间的路线。

leftBoundary(rrMap.Lanes(1),"Left1",Alignment="Forward");
rightBoundary(rrMap.Lanes(1),"Right1",Alignment="Forward");
leftBoundary(rrMap.Lanes(2),"Left2",Alignment="Forward");
rightBoundary(rrMap.Lanes(2),"Right2",Alignment="Forward");
leftBoundary(rrMap.Lanes(3),"Left3",Alignment="Forward");
rightBoundary(rrMap.Lanes(3),"Right3",Alignment="Forward");
leftBoundary(rrMap.Lanes(4),"Left4",Alignment="Forward");
rightBoundary(rrMap.Lanes(4),"Right4",Alignment="Forward");

指定车道标记

使用 roadrunner.hdmap.RelativeAssetPath 对象定义白色实线和白色虚线车道标记素材的文件路径。

wideSolidWhiteAsset = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/Germany/WideSolidSingle.rrlms");
dashedWhiteAsset = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/Germany/DashedSingle12.rrlms");

使用 roadrunner.hdmap.MarkingReference 对象为宽实心白色和虚线白色标记创建参考,以便将标记应用到车道边界。

markingRefSW = roadrunner.hdmap.MarkingReference(MarkingID=roadrunner.hdmap.Reference(ID="WideSolidWhite"));
markingRefDW = roadrunner.hdmap.MarkingReference(MarkingID=roadrunner.hdmap.Reference(ID="DashedWhite"));

使用 roadrunner.hdmap.LaneMarking 对象创建车道标记。

rrMap.LaneMarkings(2,1) = roadrunner.hdmap.LaneMarking;
rrMap.LaneMarkings(1).ID = "WideSolidWhite";
rrMap.LaneMarkings(2).ID = "DashedWhite";
rrMap.LaneMarkings(1).AssetPath = wideSolidWhiteAsset;
rrMap.LaneMarkings(2).AssetPath = dashedWhiteAsset;

使用标记参考和自定义标记跨度创建参数属性。

prmAttr1Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0 0.007],MarkingReference=markingRefSW);
prmAttr1Span2 = roadrunner.hdmap.ParametricAttribution(Span=[0.007 0.01],MarkingReference=markingRefDW);
prmAttr1Span3 = roadrunner.hdmap.ParametricAttribution(Span=[0.01 0.93],MarkingReference=markingRefSW);
prmAttr1Span4 = roadrunner.hdmap.ParametricAttribution(Span=[0.93 0.95],MarkingReference=markingRefDW);
prmAttr1Span5 = roadrunner.hdmap.ParametricAttribution(Span=[0.95 1],MarkingReference=markingRefSW);
prmAttr2Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0 0.575],MarkingReference=markingRefSW);
prmAttr2Span2 = roadrunner.hdmap.ParametricAttribution(Span=[0.575 0.602],MarkingReference=markingRefDW);
prmAttr2Span3 = roadrunner.hdmap.ParametricAttribution(Span=[0.602 1],MarkingReference=markingRefSW);
prmAttr3Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0 1],MarkingReference=markingRefSW);
prmAttr4Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0 0.439],MarkingReference=markingRefSW);
prmAttr4Span2 = roadrunner.hdmap.ParametricAttribution(Span=[0.471 0.655],MarkingReference=markingRefSW);
prmAttr4Span3 = roadrunner.hdmap.ParametricAttribution(Span=[0.684 1],MarkingReference=markingRefSW);
prmAttr5Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0.06 0.315],MarkingReference=markingRefSW);
prmAttr5Span2 = roadrunner.hdmap.ParametricAttribution(Span=[0.73 0.94],MarkingReference=markingRefSW);
prmAttr6Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0.1 0.85],MarkingReference=markingRefSW);
prmAttr7Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0 1],MarkingReference=markingRefSW);
prmAttr8Span1 = roadrunner.hdmap.ParametricAttribution(Span=[0.2 0.959],MarkingReference=markingRefSW);

指定车道边界的参数属性,使其类似于测试跑道。

rrMap.LaneBoundaries(1).ParametricAttributes = [prmAttr1Span1 prmAttr1Span2 prmAttr1Span3 prmAttr1Span4 prmAttr1Span5];
rrMap.LaneBoundaries(2).ParametricAttributes = [prmAttr2Span1 prmAttr2Span2 prmAttr2Span3];
rrMap.LaneBoundaries(3).ParametricAttributes = prmAttr3Span1;
rrMap.LaneBoundaries(4).ParametricAttributes = [prmAttr4Span1 prmAttr4Span2 prmAttr4Span3];
rrMap.LaneBoundaries(5).ParametricAttributes = [prmAttr5Span1 prmAttr5Span2];
rrMap.LaneBoundaries(6).ParametricAttributes = prmAttr6Span1;
rrMap.LaneBoundaries(7).ParametricAttributes = prmAttr7Span1;
rrMap.LaneBoundaries(8).ParametricAttributes = prmAttr8Span1;

指定隔离物

BridgeRailing 素材创建参考,用于将隔离物应用到车道边界。

path = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Extrusions/BridgeRailing.rrext");
rrMap.BarrierTypes(1) = roadrunner.hdmap.BarrierType(ID="BridgeRailing",ExtrusionPath=path);
guardRailRef = roadrunner.hdmap.Reference(ID="BridgeRailing");

使用 roadrunner.hdmap.Barrier 对象创建隔离物,并指定隔离物及其各自的几何形状。

rrMap.Barriers(5,1) = roadrunner.hdmap.Barrier;
for i = 1:5
    rrMap.Barriers(i).BarrierTypeReference = guardRailRef;
    rrMap.Barriers(i).ID = strcat('Barrier',num2str(i));
    rrMap.Barriers(i).FlipLaterally = false;
end
rrMap.Barriers(1).Geometry = lftBndry1(6:428,:);
rrMap.Barriers(2).Geometry = [x5 y5 ctrElev5];
rrMap.Barriers(3).Geometry = [x6 y6 ctrElev6];
rrMap.Barriers(4).Geometry = [x7 y7 ctrElev7];
rrMap.Barriers(5).Geometry = lftBndry4;

设置地理边界并将地图数据写入二进制文件

设置 RoadRunner 高清地图的地理边界会将场景集中在导入的道路上,使您能够将道路网络插入到场景中,而无需使用 RoadRunner 中的世界设置工具。

将地图的地理边界设置为左边界的最小和最大坐标值。

minBndry = min(lftBndry1);
maxBndry = max(lftBndry1);
rrMap.GeographicBoundary = [minBndry; maxBndry];

绘制车道中心和车道边界。

plot(rrMap)
title("RoadRunner HD Map of Test Track")
xlabel('x (m)')
ylabel('y (m)')

Figure contains an axes object. The axes object with title RoadRunner HD Map of Test Track, xlabel x (m), ylabel y (m) contains 2 objects of type line. These objects represent Lane Boundaries, Lane Centers.

使用 write 函数将 RoadRunner 高清地图写入二进制文件,并将该文件复制到项目的素材文件夹中。此代码使用示例 Windows® 项目路径。

fileName1 = "TestTrackMap.rrhd";
write(rrMap,fileName1)
copyfile TestTrackMap.rrhd C:\RR\MyProjects\Assets\

将 RoadRunner 高清地图文件导入 RoadRunner

将 RoadRunner 高清地图文件导入 RoadRunner 以构建场景,然后保存场景。

要使用 MATLAB 打开 RoadRunner,请指定项目的路径。此代码显示了 Windows 中的示例项目文件夹。使用项目的指定路径打开 RoadRunner。

rrProjectPath = "C:\RR\MyProjects";
rrApp = roadrunner(rrProjectPath);

将 RoadRunner 高清地图文件导入 RoadRunner 并构建场景。要构建场景,您必须拥有有效的 RoadRunner Scene Builder 许可证。

options = roadrunnerHDMapImportOptions(ImportStep="Load");
importScene(rrApp,fullfile("C:\RR\MyProjects\Assets\","TestTrackMap.rrhd"),"RoadRunner HD Map",options)
buildScene(rrApp,"RoadRunner HD Map")

保存构建的场景。

fileName2 = "TestTrackMap.rrscene";
saveScene(rrApp,fileName2)

此图显示了 RoadRunner 中测试赛道场景的 3D 场景。

Test track scene in RoadRunner

要可视化地形表面,您可以使用 高程图工具TestTrack.tif 文件导入 RoadRunner。

Test Track with terrain in RoadRunner

另请参阅

|

主题