Professional Documents
Culture Documents
Automatic Scenario Variant Generation Example
Automatic Scenario Variant Generation Example
This example shows how to automatically generate variants of a seed scenario in which two actors collide.
You can generate random variants of a collision scenario that you can use for the design and validation of
autonomous driving applications such as automated emergency braking (AEB) systems. In this example, you
generate the scenario variants by modifying the speed of the ego vehicle, actor dimensions, and the collision
point. The collision point is a position on the ego vehicle at which the ego vehicle and target actor collide. This
example assumes that the ego vehicle and the target actor always collide at 90 degrees, and the target actor
collides with a point on the front edge of the ego vehicle. However, the collision time remains the same as in the
seed scenario.
• If the ego vehicle collides with a target actor multiple times, this example generates scenario variants
based on only the first collision instance.
• If the ego vehicle collides with multiple target actors at different times in a scenario, this example
generates scenario variants for only one target actor. You can specify which target actor to consider for
generating the scenario variants.
This example uses the drivingScenario object to create a seed scenario and provides helper functions to
generate the variants from the seed scenario. The rest of the example demonstrates the steps involved in
generating the scenario variants.
Generate Seed Scenario — Create a collision scenario by using a drivingScenario object. The scenario can
contain any number of actors and collision instances. However, this example generates a variant based on only
the first collision instance that occurs between the ego vehicle and the specified target actor.
Validate and Store Seed Scenario Data — To generate the variants, the seed scenario must meet these
requirements:
• The ego vehicle and the target actor in the seed scenario must have three waypoints along their
trajectories.
• The speeds of the ego vehicle and the target actor at the first waypoint must be zero. For the rest of the
waypoints, the speed values of the ego vehicle and the target actor must remain constant in reference to
themselves.
Use the helperValidateScenario function to validate that the input seed scenario meets the requirements. To
get information from the seed scenario about the collision time instant and recorded states of the ego vehicle
and target actor during simulation, as well as the ego and target actor poses, trajectories, and waypoints, use
the helperValidateScenario and helperComputeCollisionData functions. Store the information from the
seed scenario to a scenarioData object, a custom object class returned by the helperScenarioData function.
You can then use the scenarioData object to generate variants of the seed scenario.
Generate Variant of Seed Scenario — Modify the seed scenario by using the helper functions
helperChangeActorDimensions, helperChangeCollisionPoint, and helperChangeEgoSpeed. These
helper functions enable you to generate variants of the seed scenario by altering the dimensions of the actors in
the scenario, the collision point, and the speed of the ego actor.
1
• Specify New Actor Dimensions and Modify Seed Scenario — Use the
helperChangeActorDimensions function to specify new dimensions for the ego vehicle, the target actor,
or both in the variant scenario. You can specify new values for the length, width, height, front overhang,
rear overhang, and wheelbase of the actors in the scenario. However, the collision point in the generated
scenario variant remains the same as that of the seed scenario. If the new actor dimensions cause the
ego vehicle to arrive at the collision point ahead of the target actor, then the function makes the ego
vehicle wait at its first waypoint long enough to preserve the expected collision time. Similarly, if the
target actor arrives at the collision point ahead of the ego vehicle, the function makes the target actor
wait at its first waypoint.
• Specify New Collision Point and Modify Seed Scenario — Specify a new collision point relative to the
width of the ego vehicle. Use the helperChangeCollisionPoint function to generate a variant of the
seed scenario by modifying the collision point in the seed scenario to the new value.
• Specify New Ego Speed and Modify Seed Scenario — Specify the new ego speed value and the
parameter to alter for generating the variant. Use the helperChangeEgoSpeed function to compute the
parameters required for altering the arrival times of the ego and the target actor at each waypoint
along their trajectories. The helperChangeEgoSpeed function uses the collision information in the
scenarioData object to generate a scenario variant with the new ego speed value.
Visualize Generated Scenario — Simulate and display the generated scenario variants by using the plot
function.
The scenario has an ego vehicle and an actor. The actor is a pedestrian, which is the moving target with which
the ego vehicle collides. The collision occurs only once during the simulation time. The ego vehicle and the
target actor must have at least three waypoints along their trajectories and travel at constant speeds starting
from their second waypoint. The speed value for the ego vehicle and the target actor must be zero at their first
waypoint.
scenario = drivingScenario;
Specify the width and the road centers to create a road by using the road function. Add two driving lanes to the
road by using the lanespec function.
roadCenters = [30 30 0;
30 -30 0];
marking = [laneMarking("Solid")
laneMarking("Dashed")
2
laneMarking("Solid")];
laneSpecification = lanespec([1 1],Width=3.5,Marking=marking);
road(scenario,roadCenters,Lanes=laneSpecification,Name="Road");
roadCenters = [10 0 0;
50 0 0];
marking = [laneMarking("Solid")
laneMarking("Dashed")
laneMarking("Solid")];
laneSpecification = lanespec([1 1],Width=3.5,Marking=marking);
road(scenario,roadCenters,Lanes=laneSpecification,Name="Road1");
Add an ego vehicle to the scenario and set its trajectory by specifying the waypoints and speed. Because this
example uses the Name field to identify the ego vehicle in a scenario, the name for the ego vehicle must contain
the word "Ego" or "Test". Set the name of the ego vehicle to "Vehicle Under Test". Set the speed of the ego
vehicle to 21.24 km/h.
Add an actor of class Pedestrian to the scenario, and set its trajectory by specifying the waypoints and the
speed. Specify waypoints and the speed such that it collides with the ego vehicle. Because this example uses
the Name field to identify the moving target in a scenario, the name for the target actor must contain the word
"Target". Set the name for the target vehicle to "Target Pedestrian". Set the speed of the target actor to 5
km/h.
3
trajectory(movingTarget,targetWaypoints,targetSpeedVector,Yaw=targetYaw);
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenario,Waypoints="on",Parent=hPlot1)
title("Seed Scenario")
while advance(scenario)
pause(0.01)
end
egoID = 1;
targetID = 2;
table([scenario.Actors.ActorID],[scenario.Actors.Name],VariableNames={'ActorID','Name'})
Store the speed, waypoints, yaw, and ActorID data of the ego vehicle and the target actor as structures. If you
do not know the ActorID and yaw information for the ego vehicle and the target actor, you can leave the id and
yaw fields, respectively, while creating the structures.
Use the helperValidateScenario function to validate the ego data egoData and the target data targetData
collected from the seed scenario. If the id field specifying the ActorID value is not present in a structure,
the helperValidateScenario function checks the input drivingScenario object for actors with names that
contain the words Ego or Test and Target. If the actor names are not available, the function selects the vehicle
with an ActorID value 1 as the ego vehicle, and the actor with an ActorID value 2 as the target actor.
The helperValidateScenario function checks if the ego vehicle and the target actor have at least three
waypoints along their trajectories, a speed value of zero at the first waypoint, and travel at a constant speed
starting from the second waypoint.
• If the ego vehicle or target actor has only two waypoints, the helperValidateScenario function adds a
third waypoint at the midpoint between them and sets its speed value to that of the last waypoint.
• If the speed value of the ego vehicle or target actor at its first waypoint is not zero, the
helperValidateScenario function changes the value to zero.
4
• If the ego vehicle or target actor does not travel with a constant speed starting from the second waypoint,
the helperValidateScenario function sets its speed value to a constant. In the case of ego vehicle, it
sets the speed value to 60 km/h. For target actor, it sets the speed value to 65 km/h.
The helperValidateScenario function returns information about the validated ego vehicle and target actor
data.
[egoID,targetID,egoData,targetData] = helperValidateScenario(scenario,egoData,targetData);
To generate variants of the seed scenario, you must compute information about the first collision event
that occurs in the seed scenario. Use the helperComputeCollisionData function to compute the collision
information. The helperComputeCollisionData function returns a collisionData object with these
properties:
• Time — Specifies the time instant at which collision occurs between the ego vehicle and the target actor
in the seed scenario. Unit is in seconds.
• EgoFrontEdge — Specifies position values of the top-left and top-right corners of the
ego vehicle at the time of collision.
• TargetFrontEdge — Specifies position values of the left and right corners on the front
edge of the target actor at the time of collision.
• EgoPosition — Specifies the centroid of the ego vehicle at the time of collision.
• TargetPosition — Specifies the centroid of the target actor at the time of collision.
• CollisionPoint — Specifies the relative position on the front edge of the ego vehicle that collides first
with the left corner on the front edge of the target actor. The collision point (CP) and is
related by the equation,
5
[collisionInformation] = helperComputeCollisionData(scenario,egoID,targetID)
Use the helperScenarioData function to store the seed scenario, information about the first collision event,
and the recorded actor poses to a scenarioData object.
seedData = helperScenarioData(scenario,egoData,targetData,collisionInformation);
Specify the new dimension values for the ego vehicle and the target actor. Store the values as a structure.
egoDimensions = struct(FrontOverhang=2,RearOverhang=2,Width=3,Height=3);
targetDimensions = struct(Length=3,Width=2,Height=2);
6
Use the helperChangeActorDimensions function to modify the dimensions of the actors in the seed scenario.
• If you specify a new value for the length parameter, the helperChangeActorDimensions function
adjusts only the front overhang parameter to modify the length of the vehicle to the new value.
• If you specify a new value for the rear overhang or wheelbase parameter, the
helperChangeActorDimensions function, in addition, will adjust the front overhang value to maintain
the specified length of the actor.
• If you specify a new value for the front overhang parameter, the helperChangeActorDimensions
function adjusts only the wheelbase parameter to maintain the specified length of the actor.
The collision time instant and the collision point in the new scenario remain the same as those of the seed
scenario. To achieve this, the helperChangeActorDimensions function modifies the wait time of the ego
vehicle, the target actor, or both at the first waypoint. If the new ego dimension causes the ego vehicle to arrive
at the collision point ahead of the target actor, then the function makes the ego vehicle wait at its first waypoint.
Similarly, if the target actor arrives at the collision point ahead of the ego vehicle, the function makes the target
actor wait at its first waypoint.
The function returns the modified scenario as a drivingScenario object. You can also get the details of the
collision information, actor poses, and trajectories in the new scenario as a second output, which the function
returns as a structure. In this example, this structure is stateAD.
To instead modify the dimensions of only the ego vehicle, you can use this syntax:
helperChangeActorDimensions(seedData,egoDimensions).
Inspect the details of the collision event in the modified scenario. Note that the collision time and the collision
point in the modified scenario are the same as those of the seed scenario and the ego vehicle width is modified
to 3.
stateAD.collisionData
Inspect the waypoints and the speed values of the ego vehicle in the modified scenario.
stateAD.egoMotionData
Inspect the waypoints and the speed values of the target actor in the modified scenario. Note that the function
makes the target actor wait at its first waypoint for 0.94 s.
stateAD.targetMotionData.waittime
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
7
plot(scenarioAD,Waypoints="on",Parent=hPlot1)
title("Scenario Variant with New Actor Dimensions")
while advance(scenarioAD)
pause(0.01)
end
• If you specify the collision point value as 0.5, the left corner of the front edge of the target actor first
collides with the center of the ego vehicle's front edge.
• If the collision point value is less than 0.5, the left corner of the front edge of the target actor first collides
with a position on the ego vehicle's front edge closer to the top-left corner of the ego vehicle.
• If the collision point value is greater than 0.5, the left corner of the front edge of the target vehicle first
collides with a position on the ego vehicle's front edge closer to the top-right corner of the ego vehicle.
Specify the new collision point value as 0.95. Use the helperChangeCollisionPoint function to generate a
scenario with the modified collision point. The function returns the modified scenario as a drivingScenario
object and also returns a structure that stores the collision information and the actor data of the modified
scenario. The collision time instant in the new scenario remains the same as that of the seed scenario. To
achieve this, the helperChangeCollisionPoint function makes the target actor wait at its first waypoint.
newCP = 0.95;
[scenarioCP,stateCP] = helperChangeCollisionPoint(seedData,newCP);
stateCP.collisionData
Display the scenario generated for the new collision point. Note that the collision point is shifted toward the right
of the ego vehicle's front edge and the collision time remains the same as that of the seed scenario. To inspect
the ego vehicle and target actor data, check the egoMotionData and targetMotionData fields in the output
structure, stateCP.
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenarioCP,Waypoints="on",Parent=hPlot1)
title("Scenario Variant with New Collision Point")
while advance(scenarioCP)
pause(0.01)
end
8
Use the helperChangeEgoSpeed helper function to compute modifications to the arrival times of the ego vehicle
and the target actor at each waypoint along their trajectories. You can compute the modifications using one
of these three processes: "WaitTime", "EntryTime", or "StartingPosition". The function estimates new
collision time for the new ego speed value using the process you select.
Specify the new speed value for the ego vehicle as 15 km/h.
egoNewSpeed = 15;
% Convert the speed value to m/s
egoNewSpeed = (egoNewSpeed*1000)/3600;
method = "WaitTime";
[scenarioWT,stateWT] = helperChangeEgoSpeed(seedData,egoNewSpeed,Method=method);
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenarioWT,Waypoints="on",Parent=hPlot1)
title("Scenario Variant — WaitTime Method")
while advance(scenarioWT)
pause(0.01)
end
Inspect the details of the collision event and the target actor data in the modified scenario. Note that the collision
point and the collision time remain the same as those of the seed scenario. The function makes the target actor
wait at its first waypoint to adjust the collision event to the new ego speed value.
stateWT.collisionData
stateWT.targetMotionData.waittime
stateWT.egoMotionData.speed
9
If you use "EntryTime" to generate the scenario variant, the function modifies the entry time of either the ego
vehicle or target actor.
• The function modifies the entry time of the ego vehicle if the ego vehicle is estimated to reach the
collision point ahead of the target actor.
• The function modifies the entry time of the target actor if the target actor is estimated to reach the
collision point ahead of the ego vehicle.
method = "EntryTime";
[scenarioET,stateET] = helperChangeEgoSpeed(seedData,egoNewSpeed,Method=method);
stateET.egoMotionData.speed
Display the scenario generated with the new ego speed. Note that the target actor appears in the scenario only
after a particular time.
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenarioET,Waypoints="on",Parent=hPlot1)
title("Scenario Variant — EntryTime Method")
while advance(scenarioET)
pause(0.01)
end
Specify the ego speed value as 70 km/h. Specify the modification method as "StartingPosition". The
function alters the starting position of the target actor based on the time difference.
egoSpeedSP = 70;
% Convert value to m/s
egoSpeedSP = (egoSpeedSP*1000)/3600;
method = "StartingPosition";
[scenarioSP,stateSP] = helperChangeEgoSpeed(seedData,egoSpeedSP,Method=method);
stateSP.egoMotionData.speed
Read the values of the target actor waypoints in the modified scenario.
10
modifiedValue = stateSP.targetMotionData.waypoints;
Read the values of the target actor waypoints in the seed scenario.
originalValue = targetData.waypoints;
Compare the values of the target actor waypoints in the modified scenario with those in the seed scenario. Note
the change in the first and the second waypoints of the target actor in the modified scenario.
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenarioSP,Waypoints="on",Parent=hPlot1)
title("Scenario Variant — StartingPosition Method")
while advance(scenarioSP)
pause(0.01)
end
Specify the new ego speed value. Use the helperChangeEgoTrajectoryAtTurn helper function to generate a
variant of the seed scenario by modifying the radius of curvature of the ego trajectory for a given ego speed
value.
egoNewSpeed = 10;
% Convert the speed value to m/s
egoNewSpeed = (egoNewSpeed*1000)/3600;
[scenarioAtTurn,stateAtTurn] = helperChangeEgoTrajectoryAtTurn(seedData,egoNewSpeed);
stateAtTurn.egoMotionData.speed
Read the values of the ego vehicle waypoints in the modified scenario and the seed scenario. Note the change
in the number of ego vehicle waypoints and their values in the modified scenario.
stateAtTurn.egoMotionData.waypoints
egoData.waypoints
11
Display the generated scenario. Note that the radius of curvature of the ego trajectory has decreased for the
given ego speed value.
figScene = figure;
set(figScene,Position=[50,50,500,500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenarioAtTurn,Waypoints="on",Parent=hPlot1)
title("Scenario Variant — New Ego Speed and Trajectory at Turns")
while advance(scenarioAtTurn)
pause(0.01)
end
Further Exploration
You can also generate a scenario variant by modifying actor dimensions, the collision point, and ego speed at
the same time by iterating through them.
Create a vector specifying which parameters of the scenario to modify. The vector must contain a combination
of these values: "dimensions", "point", or "speed".
Specify new dimensions for the ego vehicle. If you want to change the dimensions of the target actor, specify a
value for the targetDimensions variable. Otherwise, set the variable value to [].
egoDimensions = struct(Length=2,Width=1,Height=3);
targetDimensions = [];
newCP = 0.2;
Specify the new ego speed and the method to use for modifying the ego speed. To modify the radius of
curvature of the ego vehicle trajectory at turns, set the egoSpeedAtTurn parameter to true. Otherwise, set the
value to false.
egoNewSpeed = 5;
% Convert the speed value to m/s
egoNewSpeed = (egoNewSpeed*1000)/3600;
method = "WaitTime";
egoSpeedAtTurn = false;
12
Generate a scenario variant by modifying the specified parameters in sequence using a loop. The
helperChangeState function sets the state of the seed scenario to the newly generated scenario variant.
Then, the next iteration of the loop uses parameters of the updated seed scenario to generate another variant.
tempSeedData = seedData;
for i = 1:size(parameters,1)
switch parameters(i)
case "point"
[newScenario,newState] = helperChangeCollisionPoint(tempSeedData,newCP);
tempSeedData = helperChangeState(tempSeedData,newState);
case "dimensions"
if isempty(targetDimensions) == 0
[newScenario,newState] = helperChangeActorDimensions(tempSeedData, ...
egoDimensions,TargetDimensions=targetDimensions);
else
[newScenario,newState] = helperChangeActorDimensions(tempSeedData,egoDimensions
end
tempSeedData = helperChangeState(tempSeedData,newState);
case "speed"
[newScenario,newState] = helperChangeEgoSpeed(tempSeedData, ...
egoNewSpeed,Method=method);
tempSeedData = helperChangeState(tempSeedData,newState);
if egoSpeedAtTurn == true
[newScenario,newState] = helperChangeEgoTrajectoryAtTurn(tempSeedData,egoNewSpe
tempSeedData = helperChangeState(tempSeedData,newState);
end
end
end
figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(newScenario,Waypoints="on",Parent=hPlot1)
title(["Scenario Variant", "New Ego Dimension, Collision Point, and Ego Speed"])
while advance(newScenario)
pause(0.01)
end
Helper Function
The helperChangeState helper function sets the state of the seed scenario to the state of the
generated variant scenario. Use this function to update the state of the seed scenario when generating
a scenario variant by modifying multiple parameters at the same time by iterating through them. The
helperScenarioVariantUpdateState adds the road information, states of the ego vehicle and target actor
during simulation to the updated seed scenario.
13
function tempSeedData = helperChangeState(tempSeedData,newState)
tempSeedData.SeedScenario = newState.scenario;
tempSeedData.CollisionInformation = newState.collisionData;
tempSeedData.EgoMotionData = newState.egoMotionData;
tempSeedData.TargetMotionData = newState.targetMotionData;
tempSeedData = helperScenarioVariantUpdateState(tempSeedData);
end
14