Main Content

road

Add road to driving scenario or road group

Description

Add Roads To Driving Scenario

road(scenario,roadcenters) adds a road to a driving scenario, scenario. You specify the road shape and the orientation of a road in the 2-D plane by using a set of road centers, roadcenters, at discrete points. When you specify the number of lanes on a road, the lanes are numbered with respect to the road centers. For more information, see Draw Direction of Road and Numbering of Lanes.

example

road(scenario,roadcenters,roadwidth) adds a road with the specified width, roadwidth.

road(scenario,roadcenters,roadwidth,bankingangle) adds a road with the specified width and banking angle, bankingangle.

example

road(scenario,roadcenters,'Lanes',lspec) adds a road with the specified lanes, lspec.

example

road(scenario,roadcenters,bankingangle,'Lanes',lspec) adds a road with the specified banking angle and lanes.

road(___,'Heading',roadheadings) adds a road with the specified heading angle roadheadings, using any of the input argument combinations from previous syntaxes.

example

road(___,'Name',name) specifies the name of the road.

rd = road(___) returns a Road object that stores the properties of the created road.

Add Roads to Road Group

road(rg,roadcenters) adds a road segment to a road group, rg. Use a road group to create a road junction or intersection. You specify the shape and the orientation of the road segment in the 2-D plane by using a set of road centers, roadcenters, at discrete points. When you specify the number of lanes on a road segment, the lanes are numbered with respect to the road centers. For more information, see Draw Direction of Road and Numbering of Lanes.

example

road(rg,roadcenters,roadwidth) adds a road segment with the specified width, roadwidth, to the road group.

example

road(rg,roadcenters,roadwidth,bankingangle) adds a road segment with the specified width and banking angle, bankingangle, to the road group.

road(rg,roadcenters,'Lanes',lspec) adds a road segment with the specified lanes, lspec, to the road group.

example

road(rg,roadcenters,bankingangle,'Lanes',lspec) adds a road segment with the specified banking angle and lanes to the road group.

example

road(___,'Heading',roadheadings) adds a road segment with the specified heading angle roadheadings to the road group, using any of the input argument combinations from previous syntaxes.

example

road(___,'Name',name) specifies the name of the road segment.

example

Examples

collapse all

Create a driving scenario containing a curved road, two straight roads, and two actors: a car and a bicycle. Both actors move along the road for 60 seconds.

Create the driving scenario object.

scenario = drivingScenario('SampleTime',0.1','StopTime',60);

Create the curved road using road center points following the arc of a circle with an 800-meter radius. The arc starts at 0°, ends at 90°, and is sampled at 5° increments.

angs = [0:5:90]';
R = 800;
roadcenters = R*[cosd(angs) sind(angs) zeros(size(angs))];
roadwidth = 10;
cr = road(scenario,roadcenters,roadwidth);

Add two straight roads with the default width, using road center points at each end. To the first straight road add barriers on both road edges.

roadcenters = [700 0 0; 100 0 0];
sr1 = road(scenario,roadcenters);
barrier(scenario,sr1)
barrier(scenario,sr1,'RoadEdge','left')
roadcenters = [400 400 0; 0 0 0];
road(scenario,roadcenters);

Get the road boundaries.

rbdry = roadBoundaries(scenario);

Add a car and a bicycle to the scenario. Position the car at the beginning of the first straight road.

car = vehicle(scenario,'ClassID',1,'Position',[700 0 0], ...
    'Length',3,'Width',2,'Height',1.6);

Position the bicycle farther down the road.

bicycle = actor(scenario,'ClassID',3,'Position',[706 376 0]', ...
    'Length',2,'Width',0.45,'Height',1.5);

Plot the scenario.

plot(scenario,'Centerline','on','RoadCenters','on');
title('Scenario');

Figure contains an axes object. The axes object with title Scenario, xlabel X (m), ylabel Y (m) contains 1221 objects of type patch, line.

Display the actor poses and profiles.

allActorPoses = actorPoses(scenario)
allActorPoses=242×1 struct array with fields:
    ActorID
    Position
    Velocity
    Roll
    Pitch
    Yaw
    AngularVelocity

allActorProfiles = actorProfiles(scenario)
allActorProfiles=242×1 struct array with fields:
    ActorID
    ClassID
    Length
    Width
    Height
    OriginOffset
    MeshVertices
    MeshFaces
    RCSPattern
    RCSAzimuthAngles
    RCSElevationAngles

Because there are barriers in this scenario, and each barrier segment is considered an actor, actorPoses and actorProfiles functions return the poses of all stationary and non-stationary actors. To only obtain the poses and profiles of non-stationary actors such as vehicles and bicycles, first obtain their corresponding actor IDs using the scenario.Actors.ActorID property.

movableActorIDs = [scenario.Actors.ActorID];

Then, use those IDs to filter only non-stationary actor poses and profiles.

movableActorPoseIndices = ismember([allActorPoses.ActorID],movableActorIDs);

movableActorPoses = allActorPoses(movableActorPoseIndices)
movableActorPoses=2×1 struct array with fields:
    ActorID
    Position
    Velocity
    Roll
    Pitch
    Yaw
    AngularVelocity

movableActorProfiles = allActorProfiles(movableActorPoseIndices)
movableActorProfiles=2×1 struct array with fields:
    ActorID
    ClassID
    Length
    Width
    Height
    OriginOffset
    MeshVertices
    MeshFaces
    RCSPattern
    RCSAzimuthAngles
    RCSElevationAngles

Create a driving scenario containing a figure-8 road specified in the world coordinates of the scenario. Convert the world coordinates of the scenario to the coordinate system of the ego vehicle.

Create an empty driving scenario.

scenario = drivingScenario;

Add a figure-8 road to the scenario. Display the scenario.

roadCenters = [0  0  1
             20 -20  1
             20  20  1
            -20 -20  1
            -20  20  1
              0   0  1];

roadWidth = 3;
bankAngle = [0 15 15 -15 -15 0];
road(scenario,roadCenters,roadWidth,bankAngle);
plot(scenario)

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 4 objects of type patch, line.

Add an ego vehicle to the scenario. Position the vehicle at world coordinates (20, –20) and orient it at a –15 degree yaw angle.

ego = actor(scenario,'ClassID',1,'Position',[20 -20 0],'Yaw',-15);

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 5 objects of type patch, line.

Obtain the road boundaries in ego vehicle coordinates by using the roadBoundaries function. Specify the ego vehicle as the input argument.

rbEgo1 = roadBoundaries(ego);

Display the result on a bird's-eye plot.

bep = birdsEyePlot;
lbp = laneBoundaryPlotter(bep,'DisplayName','Road');
plotLaneBoundary(lbp,rbEgo1)

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains an object of type line. This object represents Road.

Obtain the road boundaries in world coordinates by using the roadBoundaries function. Specify the scenario as the input argument.

rbScenario = roadBoundaries(scenario);

Obtain the road boundaries in ego vehicle coordinates by using the driving.scenario.roadBoundariesToEgo function.

rbEgo2 = driving.scenario.roadBoundariesToEgo(rbScenario,ego);

Display the road boundaries on a bird's-eye plot.

bep = birdsEyePlot;
lbp = laneBoundaryPlotter(bep,'DisplayName','Road boundaries');
plotLaneBoundary(lbp,{rbEgo2})

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains an object of type line. This object represents Road boundaries.

Create a driving scenario containing a car and pedestrian on a straight road. Then, create and display the lane markings of the road on a bird's-eye plot.

Create an empty driving scenario.

scenario = drivingScenario;

Create a straight, 25-meter road segment with two travel lanes in one direction.

lm = [laneMarking('Solid')
      laneMarking('Dashed','Length',2,'Space',4)
      laneMarking('Solid')];
l = lanespec(2,'Marking',lm);
road(scenario,[0 0 0; 25 0 0],'Lanes',l);

Add to the driving scenario a pedestrian crossing the road at 1 meter per second and a car following the road at 10 meters per second.

ped = actor(scenario,'ClassID',4,'Length',0.2,'Width',0.4,'Height',1.7);
car = vehicle(scenario,'ClassID',1);
smoothTrajectory(ped,[15 -3 0; 15 3 0],1);
smoothTrajectory(car,[car.RearOverhang 0 0; 25-car.Length+car.RearOverhang 0 0],10);

Display the scenario and corresponding chase plot.

plot(scenario)

chasePlot(car)

Run the simulation.

  1. Create a bird's-eye plot.

  2. Create an outline plotter, lane boundary plotter, and lane marking plotter for the bird's-eye plot.

  3. Obtain the road boundaries and target outlines.

  4. Obtain the lane marking vertices and faces.

  5. Display the lane boundaries and lane markers.

  6. Run the simulation loop.

bep = birdsEyePlot('XLim',[-25 25],'YLim',[-10 10]);
olPlotter = outlinePlotter(bep);
lbPlotter = laneBoundaryPlotter(bep);
lmPlotter = laneMarkingPlotter(bep,'DisplayName','Lanes');
legend('off');
while advance(scenario)
    rb = roadBoundaries(car);
    [position,yaw,length,width,originOffset,color] = targetOutlines(car);
    [lmv,lmf] = laneMarkingVertices(car);
    plotLaneBoundary(lbPlotter,rb);
    plotLaneMarking(lmPlotter,lmv,lmf);
    plotOutline(olPlotter,position,yaw,length,width, ...
        'OriginOffset',originOffset,'Color',color);
end

Create a driving scenario containing two curved roads to connect. Specify the heading angles of each road center to fine-tune the shape of the road at the connecting region.

Create an empty driving scenario.

scenario = drivingScenario;

Add two roads to the driving scenario by defining their road centers and road heading angles.

% Add the first road
roadCenters = [-7 20; 0 0; 30 0; 30 -20; 10 -30];
roadHeadings = [-90; 0; NaN; NaN; -90];
laneMark = laneMarking('Solid');
laneSpecification = lanespec(2,Marking=laneMark);
road(scenario,roadCenters,'Lanes',laneSpecification, ...
    'Heading',roadHeadings,'Name','Road 1');

%Add the second road
roadCenters = [10 -30; 30 -40; 30 -60; 0 -60; -7 -80];
roadHeadings = [-90; NaN; NaN; 180; -90];
laneMark = laneMarking('Dashed');
laneSpecification = lanespec(2,Marking=laneMark);
road(scenario,roadCenters,'Lanes',laneSpecification, ...
    'Heading',roadHeadings,'Name','Road 2');

Plot the scenario.

plot(scenario,'RoadCenters','on')

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 5 objects of type patch, line. One or more of the lines displays its values using only markers

A three-way intersection is a Y-Junction in which two adjacent roads intersect the third road at an obtuse angle, as shown in this figure. To connect the three roads, you will create a Y-Junction by adding three road segments.

yintersection.png

Add Three Roads to Driving Scenario

Create an empty driving scenario.

scenario = drivingScenario;

Specify the number of lanes and the width of each lane in the roads.

ls = lanespec(2,'Width',5);

Define the road centers for three roads and add them to the driving scenario. The first road is diagonally oriented to the left of the scenario canvas, second road is diagonally oriented to the right of the scenario canvas, and the third road is oriented vertically.

% Add the first road
roadCenters = [-20 0; 6 0];
road(scenario,roadCenters,'Name','Road 1','Lanes',ls);

% Add the second road
roadCenters = [23 7; 50 33];
road(scenario,roadCenters,'Name','Road 2','Lanes',ls);

% Add the third road
roadCenters = [23 -7; 50 -33];
road(scenario,roadCenters,'Name','Road 3','Lanes',ls);

Plot the scenario.

figure
plot(scenario)

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 5 objects of type patch, line.

Create Y-Junction to Connect Roads

Create a RoadGroup object. Specify the width for each road segment that forms the Y-junction.

rg = driving.scenario.RoadGroup('Name','Y-Junction');
roadWidth = 10;

Specify the road centers for three road segments, and add these road segments to the RoadGroup object by using the road function. These road segments intersect with each other.

% Add the first road segment
roadCenters = [23 7; 14 1; 6 0];
road(rg,roadCenters,roadWidth,'Name','Segment 1');

% Add the second road segment
roadCenters = [23 -7; 14 -1; 6 0];
road(rg,roadCenters,roadWidth,'Name','Segment 2');

% Add the third road segment
roadCenters = [23 7; 21 4; 21 -4; 23 -7];
road(rg,roadCenters,roadWidth,'Name','Segment 3');

Add Y-Junction to Driving Scenario

Add the road segments stored in the RoadGroup object to the driving scenario by using the roadGroup function. The road segments form a Y-Junction that connects the three roads in the driving scenario.

roadGroup(scenario,rg);

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 3 objects of type patch, line.

Create a driving scenario with three roads, and use a road junction to connect them, as shown in this figure.

heading_to_roadgroup.png

Add Three Roads to Driving Scenario

Create an empty driving scenario.

scenario = drivingScenario;

Specify the number of lanes and the width of each lane in the roads.

ls = lanespec(2,'Width',5);

Define the road centers for three roads and add them to the driving scenario. The first and second roads are vertically oriented, to the left and to the center of the scenario canvas respectively. The third road is horizontally oriented, to the right of the first two roads and between them vertically.

% Add the first road
roadCenters = [70 30; 30 30];
road(scenario,roadCenters,'Name','Road 1','Lanes',ls);

% Add the second road
roadCenters = [0 0; -40 0];
road(scenario,roadCenters,'Name','Road 2','Lanes',ls);

% Add the third road
roadCenters = [15 -20; 15 -60];
road(scenario,roadCenters,'Name','Road 3','Lanes',ls);

Plot the scenario.

plot(scenario)

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 5 objects of type patch, line.

Create a Junction to Connect Roads

Create a RoadGroup object. Specify the width of each road segment that forms the junction.

rg = driving.scenario.RoadGroup('Name','Junction');
roadWidth = 10;

Specify the road centers for two road segments, and specify heading angles for the first road segment. Add these road segments to the RoadGroup object by using the road function. These road segments intersect each other.

%Add the first road segment and specify its heading angles
roadCenters = [31 30; 15 20; 15 -21];
roadHeadings = [180; -90; -90];
road(rg,roadCenters,roadWidth, ...
    'Name','Segment 1','Heading',roadHeadings);
 
% Add the second road segment
roadCenters = [15 0; -1 0];
road(rg,roadCenters,roadWidth, ...
    'Name','Segment 2');

Add Junction to Driving Scenario

Add the road segments stored in the RoadGroup object to the driving scenario by using the roadGroup function. The road segments form a junction that connects the three roads in the driving scenario.

roadGroup(scenario,rg);

Figure contains an axes object. The axes object with xlabel X (m), ylabel Y (m) contains 3 objects of type patch, line.

Input Arguments

collapse all

Driving scenario, specified as a drivingScenario object.

Road group that defines a road junction or intersection, specified as a RoadGroup object.

Road centers used to define a road, specified as a real-valued N-by-2 or N-by-3 matrix. Road centers determine the center line of the road at discrete points.

  • If roadcenters is an N-by-2 matrix, then each matrix row represents the (x, y) coordinates of a road center. The z-coordinate of each road center is zero.

  • If roadcenters is an N-by-3 matrix, then each matrix row represents the (x, y, z) coordinates of a road center.

If the first row of the matrix is the same as the last row, the road is a loop. Units are in meters.

Data Types: double

Width of road, specified as a positive real scalar. The width is constant along the entire road. Units are in meters.

To specify the bankingangle input but not roadwidth, specify roadwidth as an empty argument, [].

If you specify roadwidth, then you cannot specify the lspec input.

Data Types: double

Banking angle of road, specified as a real-valued N-by-1 vector. N is the number of road centers. The banking angle is the roll angle of the road along the direction of the road. Units are in degrees.

Lane specification, specified as a lanespec or compositeLaneSpec object. Use a lanespec object to create a road with a single lane specification. You can specify the number of lanes, the width of each lane, and the type of lane markings using the lanespec object. To specify the lane markings within lanespec, use the laneMarking function.

Use a compositeLaneSpec object to create a road with multiple road segments that have different lane specifications. For more details, see compositeLaneSpec.

If you specify lspec, then you cannot specify the roadwidth input.

Example: 'Lanes',lanespec(3) specifies a three-lane road with default lane widths and lane markings.

Name of the road, specified as a character vector or string scalar.

Example: 'Name','Road1'

Example: "Name","Road1"

Data Types: char | string

Heading angle of the road, specified as a real-valued N-by-1 vector of angles in the range [–180, 180]. N is the number of road centers. Units are in degrees.

The heading angles constrain the associated road centers. To avoid constraining the road center points, you must specify the corresponding elements of roadheadings as NaN. The road function automatically determines the heading angles for the unconstrained road centers. For more information, see Heading Angle.

Output Arguments

collapse all

Output road, returned as a Road object that has the properties described in this table. With the exception of RoadID, which is a scenario-generated property, the property names correspond to the input arguments used to create the road. All properties are read-only.

PropertyValue
Name

Name of road, specified as a string scalar

The name input argument sets this property. Even if you specify name as a character vector, the Name property value is a string scalar.

RoadID

Identifier of road, specified as a positive integer

The scenario input argument generates a unique ID for each road in the driving scenario.

RoadCenters

Road centers used to define a road, specified as a real-valued N-by-2 or N-by-3 matrix, where N is the number of road centers

The roadcenters input argument sets this property.

RoadWidth

Width of road, specified as a positive real scalar

The roadwidth input argument sets this property.

BankAngle

Banking angle of road, specified as an N-by-1 real-valued vector, where N is the number of road centers in the road

The bankingangle input argument sets this property.

Heading

Heading angle of road, specified as an N-by-1 real-valued vector, where N is the number of road centers in the road

The roadheadings input argument sets this property.

More About

collapse all

Draw Direction of Road and Numbering of Lanes

To create a road by using the road function, specify the road centers as a matrix input. The function creates a directed line that traverses the road centers, starting from the coordinates in the first row of the matrix and ending at the coordinates in the last row of the matrix. The coordinates in the first two rows of the matrix specify the draw direction of the road. These coordinates correspond to the first two consecutive road centers. The draw direction is the direction in which the roads render in the scenario plot.

To create a road by using the Driving Scenario Designer app, you can either specify the Road Centers parameter or interactively draw on the Scenario Canvas. For a detailed example, see Create a Driving Scenario. In this case, the draw direction is the direction in which roads render in the Scenario Canvas.

  • For a road with a top-to-bottom draw direction, the difference between the x-coordinates of the first two consecutive road centers is positive.

  • For a road with a bottom-to-top draw direction, the difference between the x-coordinates of the first two consecutive road centers is negative.

Road with top-to-bottom draw direction

Road with bottom-to-top draw direction

  • For a road with a left-to-right draw direction, the difference between the y-coordinates of the first two consecutive road centers is positive.

  • For a road with a right-to-left draw direction, the difference between the y-coordinates of the first two consecutive road centers is negative.

Road with left-to-right draw direction

Road with right-to-left draw direction

Numbering Lanes

Lanes must be numbered from left to right, with the left edge of the road defined relative to the draw direction of the road. For a one-way road, by default, the left edge of the road is a solid yellow marking which indicates the end of the road in transverse direction (direction perpendicular to draw direction). For a two-way road, by default, both edges are marked with solid white lines.

For example, these diagrams show how the lanes are numbered in a one-way and two-way road with a draw direction from top-to-bottom.

Numbering Lanes in a One-Way RoadNumbering Lanes in a Two-Way Road

Specify the number of lanes as a positive integer for a one-way road. If you set the integer value as 3, then the road has three lanes that travel in the same direction. The lanes are numbered starting from the left edge of the road.

1, 2, 3 denote the first, second, and third lanes of the road, respectively.

Lane numbers in one-way road

Specify the number of lanes as a two-element vector of positive integer for a two-way road. If you set the vector as [1 2], then the road has three lanes: two lanes traveling in one direction and one lane traveling in the opposite direction. Because of the draw direction, the road has one left lane and two right lanes. The lanes are numbered starting from the left edge of the road.

1L denote the only left lane of the road. 1R and 2R denote the first and second right lanes of the road, respectively.

Lane numbers in two-way road

The lane specifications apply by the order in which the lanes are numbered.

Heading Angle

The heading angle refers to the angle of the road at a given road center point heading towards the next road center, measured counterclockwise with respect to the x-axis in the range [–180, 180] degrees.

road heading angles

Specifying heading angles as a constraint to the road center points enables precise control over the shape and orientation of the roads.

For example, create a road by specifying its road centers. Plot the road

scenario = drivingScenario;
roadCenters = [0 35; 0 18; 15 10; 32 3; 32 -12];
roadHeadings = [NaN; NaN; 0; NaN; NaN];
road(scenario,roadCenters,'Heading',roadHeadings);
plot(scenario,'Centerline','on','RoadCenters','on')

This figure shows the road with one constrained road heading angle and its respective road center specified in this example. The other road centers are unconstrained and their heading angles are determined automatically by the road function.

road heading angle example unconstrained

Now specify heading angles for each of the road center points in the road. Plot the new road.

scenario = drivingScenario;
roadCenters = [0 35; 0 18; 15 10; 32 3; 32 -12];
roadHeadings = [-90; -90; 0; -90; -90];
road(scenario,roadCenters,'Heading',roadHeadings);
plot(scenario,'Centerline','on','RoadCenters','on')

This figure shows the road with the road heading angles and their respective road centers specified in the example.

road heading angle example

Algorithms

The road function creates a road for an actor to follow in a driving scenario. You specify the road using N two-dimensional or three-dimensional waypoints. Each of the N – 1 segments between waypoints defines a curve whose curvature varies linearly with distance along the segment. The function fits a piecewise clothoid curve to the (x, y) coordinates of the waypoints by matching the curvature on both sides of the waypoint. For a nonclosed curve, the curvature at the first and last waypoint is zero. If the first and last waypoints coincide, then the curvatures before and after the endpoints are matched. The z-coordinates of the road are interpolated using a shape-preserving piecewise cubic curve.

Version History

Introduced in R2017a