Main Content

Esta página se ha traducido mediante traducción automática. Haga clic aquí para ver la última versión en inglés.

Cree una escena de RoadRunner con intersecciones y objetos estáticos usando el mapa HD de RoadRunner

Este ejemplo muestra cómo crear un mapa RoadRunner HD a partir de un archivo Keyhole Markup Language (KML) que contiene las coordenadas de latitud y longitud de una intersección de carreteras. Puede importar los datos del mapa HD de RoadRunner a RoadRunner y usarlos para crear una escena 3D que contenga la intersección de la carretera y los objetos estáticos circundantes, como árboles y edificios. Para importar los archivos de datos de la carretera, debe tener una licencia de Mapping Toolbox™ .

Importar archivos KML

En este ejemplo, utilizará archivos KML para importar formas puntuales para la intersección de carreteras y formas poligonales para los edificios y árboles. Este ejemplo utiliza datos de mapas (© 2022 de Google) para un área alrededor de Whitesville Road en Nueva Jersey, EE. UU.

Lea los datos de los archivos KML usando la función readgeotable , que solo lee las formas, nombres y descripciones.

kmlRoadData = readgeotable("RoadIntersection.kml");
kmlTreeData = readgeotable("Trees.kml");
kmlBuildingData = readgeotable("Buildings.kml");

Traza las coordenadas de la carretera, muestra los edificios y renderiza polígonos para las ubicaciones de los árboles.

geoplot(kmlRoadData)
hold on
geoplot(kmlTreeData)
geoplot(kmlBuildingData)
geobasemap topographic

Convierta la tabla geoespacial en una tabla de centros de carreteras para obtener las coordenadas de latitud y longitud de dos carreteras que se encuentran en una intersección.

T1 = geotable2table(kmlRoadData,["Latitude","Longitude"]);
[lat1,lon1] = polyjoin(T1.Latitude(1),T1.Longitude(1)); % Road centers of the first road meeting at the intersection
[lat2,lon2] = polyjoin(T1.Latitude(2),T1.Longitude(2)); % Road centers of the second road meeting at the intersection

Convierta la tabla geoespacial en una tabla de vértices de polígonos para obtener las coordenadas de latitud y longitud de los árboles dentro de los polígonos y los edificios.

T2 = geotable2table(kmlTreeData,["Latitude","Longitude"]);
[lat3,lon3] = polyjoin(T2.Latitude(1),T2.Longitude(1)); % Polygon geometry to form trees inside of polygon
[lat4,lon4] = polyjoin(T2.Latitude(2),T2.Longitude(2)); % Polygon geometry to form trees inside of polygon
[lat5,lon5] = polyjoin(T2.Latitude(3),T2.Longitude(3)); % Polygon geometry to form trees inside of polygon

T3 = geotable2table(kmlBuildingData,["Latitude","Longitude"]);
lat6 = T3.Latitude; % Geometry for buildings
lon6 = T3.Longitude; % Geometry for buildings

Crear mapa RoadRunner HD

Crea un mapa RoadRunner HD vacío.

rrMap = roadrunnerHDMap;

Calcule el origen de referencia geográfica como el centro del cuadrilátero delimitador.

[latlim,lonlim] = geoquadline([lat1; lat2],[lon1; lon2]);
lat0 = mean(latlim);
lon0 = mean(lonlim);

Establezca la referencia geográfica para la región de interés.

rrMap.GeoReference = [lat0 lon0];

Proyecto Coordenadas Latitud-Longitud a xy Coordenadas del Mapa

Lea el CRS transversal proyectado por Mercator en el mapa HD de RoadRunner .

p = readCRS(rrMap);

Proyecte las coordenadas de latitud y longitud en coordenadas xy.

% Road geometry data
[x1,y1] = projfwd(p,lat1,lon1);
[x2,y2] = projfwd(p,lat2,lon2);
% Trees geometry data
[x3,y3] = projfwd(p,lat3,lon3);
[x4,y4] = projfwd(p,lat4,lon4);
[x5,y5] = projfwd(p,lat5,lon5);
% Buildings geometry data
[x6,y6] = projfwd(p,lat6,lon6);

Calcular geometrías para carriles y límites de carriles

Crea las ecuaciones lineales para los dos caminos de la intersección.

coefficients1 = polyfit([x1(1) x1(2)],[y1(1) y1(2)],1);
coefficients2 = polyfit([x2(1) x2(2)],[y2(1) y2(2)],1);

Calcule las geometrías de los carriles usando las ecuaciones de líneas.

m1 = coefficients1(1);
c1 = coefficients1(2);
% Specify lane widths, estimated using the measurement tool of Google Earth
leftLanesWidth = [0 -3.659 -3.686 -3.643 -2.988];
rightLanesWidth = [2.820 3.764 3.698];
% Find cumulative width of all lanes to compute the geometries of parallel lanes
leftLanesWidth = cumsum(leftLanesWidth);
rightLanesWidth = cumsum(rightLanesWidth);
rightLanesWidth = flip(rightLanesWidth);
d1 = [rightLanesWidth leftLanesWidth];

m2 = coefficients2(1);
c2 = coefficients2(2);
% Specify lane widths, estimated using the measurement tool of Google Earth
leftLanesWidth2 = [0 -3.614 -3.610 -3.661];
rightLanesWidth2 = [3.621 3.685];
% Find cumulative width of all lanes to compute the geometries of parallel lanes
leftLanesWidth2 = cumsum(leftLanesWidth2);
rightLanesWidth2 = cumsum(rightLanesWidth2);
rightLanesWidth2 = flip(rightLanesWidth2);
d2 = [rightLanesWidth2 leftLanesWidth2];

d = [d1 d2];
numLanes = size(d,2);
x = cell(numLanes,1);
[x{1:8}] = deal(x1);
[x{9:14}] = deal(x2);
m(1:8) = deal(m1);
m(9:14) = deal(m2);
c(1:8) = deal(c1);
c(9:14) = deal(c2);
y = cell(numLanes,1);
for i = 1:numLanes
   y{i} =  m(i)*x{i} + c(i) + d(i)*sqrt(1+m(i)^2);
end

Crear intersección de carreteras

Cree la red de carreteras de RoadRunner HD Map utilizando los datos calculados y modifique las carreteras para que se parezcan a la carretera real, que consta de varios carriles y varios límites de carriles. Luego, aplique marcas de carril apropiadas a los límites de los carriles como en la escena real. Para mejorar el rendimiento, a medida que aumenta la cantidad de objetos en el mapa, inicialice las propiedades Lanes y LaneBoundaries del mapa HD.

rrMap.Lanes(12,1) = roadrunner.hdmap.Lane;
rrMap.LaneBoundaries(14,1) = roadrunner.hdmap.LaneBoundary;

Asigne valores a la propiedad Lanes .

laneIds = ["Lane1","Lane2","Lane3","Lane4","Lane5","Lane6","Lane7","Lane8","Lane9","Lane10","Lane11","Lane12"];
travelDirection = ["Undirected","Forward","Forward","Backward","Backward","Backward","Undirected","Backward","Backward","Backward","Forward","Forward"];
for i = 1:size(rrMap.Lanes,1)
    rrMap.Lanes(i).ID = laneIds(i);
    rrMap.Lanes(i).TravelDirection = travelDirection(i);
    rrMap.Lanes(i).LaneType = "Driving";
    if (i<8) % Assign coordinates to the Geometry properties of the lanes of the first road meeting at intersection
        rrMap.Lanes(i).Geometry = ([x{i} y{i}] + [x{i} y{i+1}])/2;
    elseif (i>8) % Assign coordinates to the Geometry properties of the lanes of the second road meeting at intersection
       rrMap.Lanes(i).Geometry = ([x{i} y{i+1}] + [x{i} y{i+2}])/2;
    end
end

Asigne ID y sus coordenadas correspondientes a los límites de los carriles.

laneBoundaries = ["LB1","LB2","LB3","LB4","LB5","LB6","LB7","LB8","LB9","LB10","LB11","LB12","LB13","LB14"];
for i = 1:size(rrMap.LaneBoundaries,1) 
    rrMap.LaneBoundaries(i).ID = laneBoundaries(i);
    rrMap.LaneBoundaries(i).Geometry = [x{i} y{i}];
end

Asocie los límites de los carriles con sus carriles utilizando los ID de los límites de los carriles.

for i = 1:size(rrMap.Lanes,1)
    if (i<8) % Associate lane boundaries of the first road meeting at intersection
        leftBoundary(rrMap.Lanes(i),"LB"+i,Alignment="Forward");
        rightBoundary(rrMap.Lanes(i),"LB"+(i+1),Alignment="Forward");
    else % Associate lane boundaries of the second road meeting at intersection
        leftBoundary(rrMap.Lanes(i),"LB"+(i+1),Alignment="Backward");
        rightBoundary(rrMap.Lanes(i),"LB"+(i+2),Alignment="Backward");
    end
end

Defina las rutas de los archivos a los recursos de señalización de carril de RoadRunner .

% Define path to a dashed single white lane marking asset
dashedSingleWhiteAsset = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/DashedSingleWhite.rrlms");
% Define path to a solid white lane marking asset
solidWhiteAsset = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/SolidSingleWhite.rrlms");
% Define path to a solid double yellow lane marking asset
doubleYellowAsset = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/SolidDoubleYellow.rrlms");
rrMap.LaneMarkings(3,1) = roadrunner.hdmap.LaneMarking;
[rrMap.LaneMarkings.ID] = deal("DashedSingleWhite","SolidWhite","DoubleYellow");
[rrMap.LaneMarkings.AssetPath] = deal(dashedSingleWhiteAsset,solidWhiteAsset,doubleYellowAsset);

Especifique que las marcas abarquen toda la longitud de los límites de sus carriles. Luego, asigne marcas blancas sólidas a los límites de los carriles cerca de los bordes de la carretera, marcas de carril blancas con trazos a los límites de los carriles intermedios y marcas amarillas dobles al límite del carril central.

% Specify the span for markings as the entire lengths of their lane boundaries
markingSpan = [0 1];

markingRefDSW = roadrunner.hdmap.MarkingReference(MarkingID=roadrunner.hdmap.Reference(ID="DashedSingleWhite"));
markingAttribDSW = roadrunner.hdmap.ParametricAttribution(MarkingReference=markingRefDSW,Span=markingSpan);

markingRefSY = roadrunner.hdmap.MarkingReference(MarkingID=roadrunner.hdmap.Reference(ID="DoubleYellow"));
markingAttribSY = roadrunner.hdmap.ParametricAttribution(MarkingReference=markingRefSY,Span=markingSpan);

markingRefSW = roadrunner.hdmap.MarkingReference(MarkingID=roadrunner.hdmap.Reference(ID="SolidWhite"));
markingAttribSW = roadrunner.hdmap.ParametricAttribution(MarkingReference=markingRefSW,Span=markingSpan);

% Assign the markings to lane boundaries
[rrMap.LaneBoundaries.ParametricAttributes] = deal(markingAttribSW,markingAttribSW,markingAttribDSW,markingAttribSY,markingAttribDSW,markingAttribDSW,markingAttribSW,markingAttribSW, ...
    markingAttribSW,markingAttribDSW,markingAttribDSW,markingAttribSY,markingAttribDSW,markingAttribSW);

Calcular geometrías de objetos estáticos

Calcule las coordenadas de los vértices de cada polígono de árboles utilizando la función auxiliar helperInsidePolygon .

[X3,Y3] = helperInsidePolygon(x3,y3);
[X4,Y4] = helperInsidePolygon(x4,y4);
[X5,Y5] = helperInsidePolygon(x5,y5);
X = [X3'; X4'; X5'];
Y = [Y3'; Y4'; Y5']; 
numOfTrees = size(X);

Crear objetos estáticos

Defina un objeto estático para los árboles y luego agregue los árboles al modelo y defina sus propiedades.

% Define tree static object type
path = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Props/Trees/Eucalyptus_Sm01.fbx");
rrMap.StaticObjectTypes(1) = roadrunner.hdmap.StaticObjectType(ID="StaticObjectType1",AssetPath=path);

rrMap.StaticObjects(numOfTrees,1) = roadrunner.hdmap.StaticObject;
objectRef1 = roadrunner.hdmap.Reference(ID="StaticObjectType1");

% Specify the length, width, and height values of the trees, estimated using Google Earth.
length = 9;
width = 9;
height = 23;

for i = 1:numOfTrees
    x = X(i);
    y = Y(i);
    aGeoOrientedBoundingBox = roadrunner.hdmap.GeoOrientedBoundingBox;
    aGeoOrientedBoundingBox.Center = [x y 0];
    aGeoOrientedBoundingBox.Dimension = [length width height/2];
    geoAngle3 = mathworks.scenario.common.GeoAngle3;
    geoAngle3.roll = -2;
    geoAngle3.pitch = -2;
    geoAngle3.heading = 90;
    geoOrientation3 = mathworks.scenario.common.GeoOrientation3;
    geoOrientation3.geo_angle = geoAngle3;
    aGeoOrientedBoundingBox.GeoOrientation = [deg2rad(-2) deg2rad(-2) deg2rad(90)];

    treeID = "Tree" + string(i);
    rrMap.StaticObjects(i) = roadrunner.hdmap.StaticObject(ID=treeID, ...
        Geometry=aGeoOrientedBoundingBox, ...
        ObjectTypeReference=objectRef1);
end

Defina un objeto estático para construir y luego agregue los edificios al modelo y defina sus propiedades.

numberOfBuildings = size(x6);
% Add static object type info
path = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Buildings/Downtown_30mX30m_6storey.fbx");
% Define static object type
rrMap.StaticObjectTypes(2) = roadrunner.hdmap.StaticObjectType(ID="StaticObjectType2",AssetPath=path);

% Initialize elements in the StaticObjects property of the HD map object, for better performance as the number of objects in the map increases
rrMap.StaticObjects(numberOfBuildings,1) = roadrunner.hdmap.StaticObject;
objectRef2 = roadrunner.hdmap.Reference(ID="StaticObjectType2");

% Specify the length, width, and height values of the buildings, estimated using Google Earth.
length = [26 26];
width = [26 46];
height = 28;
ID = ["Building1","Building2"];
for i= 1:numberOfBuildings
    x = x6(i);
    y = y6(i);
    aGeoOrientedBoundingBox = roadrunner.hdmap.GeoOrientedBoundingBox;
    aGeoOrientedBoundingBox.Center = [x y 0];
    aGeoOrientedBoundingBox.Dimension = [length(i) width(i) height/2];
    geoAngle3 = mathworks.scenario.common.GeoAngle3;
    geoAngle3.roll = 0;
    geoAngle3.pitch = 0;
    geoAngle3.heading = 0.4697;
    geoOrientation3 = mathworks.scenario.common.GeoOrientation3;
    geoOrientation3.geo_angle = geoAngle3;
    aGeoOrientedBoundingBox.GeoOrientation = [deg2rad(-2) deg2rad(-2) deg2rad(90)];

    rrMap.StaticObjects(i) = roadrunner.hdmap.StaticObject(ID=ID(i), ...
        Geometry=aGeoOrientedBoundingBox, ...
        ObjectTypeReference = objectRef2);
end

Establecer límites geográficos y referencias

Configurar los límites geográficos y la referencia para el mapa RoadRunner HD centra la escena en la carretera importada y le permite insertar la carretera en la escena sin usar la herramienta Configuración mundial en RoadRunner.

Establezca los límites geográficos del mapa como los valores de coordenadas mínimo y máximo del límite central.

geometries = [x1 y1; x2 y2];
geoBounds = [min(geometries) 0; max(geometries) 0];
rrMap.GeographicBoundary = geoBounds;

Trazar los centros de los carriles y los límites de los carriles.

plot(rrMap,ShowStaticObjects=true)
title("RoadRunner HD Map of Road Intersection Scene")
xlabel("x (m)")
ylabel("y (m)")

Guarde el mapa RoadRunner HD en un archivo.

write(rrMap,"RoadIntersection")

Importar archivo de mapa HD a RoadRunner y crear escena

Para abrir RoadRunner usando MATLAB, especifique la ruta a su proyecto. Este código muestra una carpeta de proyecto de muestra en Windows®. Abra RoadRunner usando la ruta especificada a su proyecto.

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

Importe los datos del mapa RoadRunner HD desde un archivo específico a la escena abierta actualmente y cree el mapa. Para crear la escena, debe tener una licencia activa de RoadRunner Scene Builder .

Copie el archivo de mapa RoadRunner HD al proyecto RoadRunner .

copyfile("RoadIntersection.rrhd","C:\RR\MyProjects\Assets")

Especifique opciones de importación para el mapa RoadRunner HD.

importOptions = roadrunnerHDMapImportOptions(ImportStep="Load");

Importe el mapa RoadRunner HD a RoadRunner.

importScene(rrApp,"RoadIntersection.rrhd","RoadRunner HD Map",importOptions)

El lienzo de edición de escena muestra el mapa RoadRunner HD de la escena. Para verificar los datos importados, puede seleccionar puntos de control, carriles, límites de carriles y objetos estáticos en el lienzo de edición de escena y ver sus propiedades desde el panel Atributos.

Preview of the imported RoadRunner HD Map data.

Especifique opciones para crear una escena a partir del mapa RoadRunner HD importado. Desactive los grupos de superposición para permitir que RoadRunner cree cruces automáticos en la superposición geométrica de las carreteras.

enableOverlapGroupsOptions = enableOverlapGroupsOptions(IsEnabled=0);
buildOptions = roadrunnerHDMapBuildOptions(DetectAsphaltSurfaces=true,EnableOverlapGroupsOptions=enableOverlapGroupsOptions);

Cree y visualice una escena a partir de los datos importados del mapa RoadRunner HD. Para crear escenas, debe tener una licencia de RoadRunner Scene Builder .

buildScene(rrApp,"RoadRunner HD Map",buildOptions)

La escena de RoadRunner construido contiene carreteras que se cruzan, así como árboles y edificios. Modifique la intersección para que se parezca al cruce real ajustando el radio de la esquina del cruce usando la herramienta Esquina de cruce.

Built RoadRunner scene.

Consulte también

|

Temas relacionados