Generate Scenario Variants by Modifying Actor Dimensions
This example shows how to generate scenario variants from a seed scenario by varying the ego vehicle and target actor dimensions. In this example, you generate variants of a European New Car Assessment Programme (Euro NCAP®) Car-to-Pedestrian Nearside Child (CPNC
) collision scenario by modifying the dimensions of the actors in the scenario. The collision point in the generated variant is ensured to be the same as that of the seed scenario. 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.
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. When you generate the scenario variants, you can specify the target actor to consider.
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.
Create a seed scenario.
Extract properties from the seed scenario and use them to create scenario variants.
Specify new dimensions for one or more actors in the seed scenario.
Add a collision event.
Generate the scenario variants.
Create Seed Scenario
Create the CPNC seed scenario by using the helperCreateNCAPScenario
function.
seedScenario = helperCreateNCAPScenario("AEBModifiedCPNC")
seedScenario = drivingScenario with properties: SampleTime: 0.0100 StopTime: Inf SimulationTime: 0 IsRunning: 1 Actors: [1×4 driving.scenario.Actor] Barriers: [0×0 driving.scenario.Barrier] ParkingLots: [0×0 driving.scenario.ParkingLot]
Extract Properties from Seed Scenario
Extract properties from the seed scenario and store these properties in a ScenarioDescriptor
object by using the getScenarioDescriptor
function.
seedScenarioDescriptor = getScenarioDescriptor(seedScenario,Simulator="DrivingScenario")
seedScenarioDescriptor = ScenarioDescriptor with properties: status: "DescriptorCreated"
Create a scenario variant object by using the HelperScenarioVariant
helper function. Use the generated scenario variant object to store the new dimension values required for generating the variants.
variantParams = HelperScenarioVariant(seedScenarioDescriptor)
variantParams = HelperScenarioVariant with properties: ScenarioData: [1×1 struct] VariantGenerator: [] MethodForVariations: "WaitTime" ValidScenario: []
Specify New Actor Dimension Values
Specify the actor IDs of the ego and target actors whose dimensions you want to modify. You can find the actor ID and the name of an actor by inspecting the Actors
property of the seed scenario stored as a drivingScenario
object.
egoID = 1; targetID = 2;
Modify Dimensions of Ego Vehicle
Specify a new dimension value for the ego vehicle by using the addDimensionVariation
function of the HelperScenarioVariant
object.
egoDimensions = struct(Length=1,Width=1.5,Height=1.4);
addDimensionVariation(variantParams,egoID,struct('egoDimension',egoDimensions));
To generate multiple variations of the seed scenario with ego vehicles of different dimensions, call the addDimensionVariation
function for each variation.
Specify a second dimension value for the ego vehicle to create another scenario variant.
egoDimensions = struct(Length=1.5,Width=2,Height=1.4);
addDimensionVariation(variantParams,egoID,struct('egoDimension',egoDimensions));
Modify Dimensions of Ego Vehicle and Target Actor
To modify the dimensions of both ego vehicle and target actor in the seed scenario, use the addActorMultiVariation
function of the HelperScenarioVariant
object.
egoDimensions = struct(Length=2.5,Width=1,Height=2); targetDimensions = struct(Length=2.025,Width=0.67,Height=1.5); addDimensionVariation(variantParams,[egoID,targetID],struct('egoDimension',egoDimensions,'targetDimension',targetDimensions));
Add Collision Event
Extract collision properties from the seed scenario by using the getCollisionData
function. Specify the actorIDs of the colliding vehicles.
collisionsInScenario = getCollisionData(seedScenarioDescriptor,Actor1ID=egoID,Actor2ID=targetID)
collisionsInScenario = struct with fields:
Actor1ID: 1
Actor2ID: 2
Collision: [1×1 variantgenerator.internal.Collision]
Use the HelperScenarioVariant
object and createCollisionVariant
helper function to add a collision event to the scenarios to be generated for new actor dimensions. The createCollisionVariant
function examines the possibility of a collision for the new actor dimensions. If collision does not occur, the function uses a wait time modification approach to create the collision event. In this approach, the function checks the arrival time of the ego vehicle and the target actor at the collision point. If the ego vehicle arrives at the collision point ahead of the target actor, the function computes a wait time for the ego vehicle. The ego vehicle then waits at its first waypoint to ensure that it collides with the target actor while traveling along its trajectory. Similarly, if the target actor arrives at the collision point ahead of the ego vehicle, the function computes a wait time for the target actor to ensure a collision.
createCollisionVariant(variantParams, collisionsInScenario.Collision);
Generate Scenario Variants
Generate variants of the seed scenario by using the generateVariants
helper function. The output returned by the generateVariants
function is a cell array of the scenarioVariantDescriptor
object. The function generates a scenario variant for each actor dimension variation specified in the input object. The function returns the generated scenario variations as a scenarioVariantDescriptor
object.
scenarioVariantDescriptors = generateVariants(variantParams);
Extract the scenario from the ScenarioDescriptor
object by using the getScenario
function. The getScenario
function returns the generated variants as a drivingScenario
object.
numVariants=size(scenarioVariantDescriptors,2); variantScenario = repelem(drivingScenario,numVariants); for iter = 1:numVariants variantScenario(iter) = getScenario(scenarioVariantDescriptors(iter),Simulator="DrivingScenario"); end
Display the seed scenario and the generated variants by using the helperVisualizeVariants
helper function. You can notice that the target actors in each of these scenarios wait at their first waypoint for a particular amount of time before they travel along their trajectory. You can also notice that the wait time of the target actor in each scenario is different in order to ensure the collision event occurs. The collision points in the three generated scenario variations remain the same as those in the seed scenario.
variationTitle=["Scenario Variant 1:New Ego Dimension", "Scenario Variant 2: New Ego Dimension","Scenario Variant 3: New Ego and Target Dimensions"]; helperVisualizeVariants(seedScenario,variantScenario(1:length(variantScenario)), ... FigureTitle="Generated Scenario Variations", ... GridPlotTitles = variationTitle,Mode="StandardFit",Row=2,Column=2, ... Legend="off",Waypoints="on",ActorIndicators=targetID);
Further Exploration
You can also use this example to generate variants of a custom seed scenario. If you want to generate variants of a custom seed scenario, you must ensure that the input scenario is stored as a drivingScenario
object and validate that a collision event occurs in the input scenario. Use the helperCheckScenario
helper function to check if the seed scenario meets the following requirements.
The ego vehicle and a desired target actor in the scenario collide.
The actors have at least three waypoints along their trajectories.
The actors travel at a constant speed.
Create a ScenarioDescriptor
object to extract scenario information from the custom seed scenario. Then, use the helperCheckScenario
helper function to validate the seed scenario. The function returns a value of 1
if the seed scenario is a valid scenario. Otherwise, it returns 0
.
seedScenarioDes = getScenarioDescriptor(seedScenario,Simulator="DrivingScenario");
scenarioCheckPassed = helperCheckScenario(egoID,targetID,seedScenarioDes);
If the output returned by the helperCheckScenario
helper function is 0
, you can modify the seed scenario to a valid scenario by using the helperSetScenarioCollision
helper function.
if ~scenarioCheckPassed
seedScenarioDescriptor = helperSetScenarioCollision(egoID,targetID,seedScenarioDes,method="WaitTime");
end
The helperSetScenarioCollision
function only modifies the scenario according to the following rules:
If the ego vehicle or target actor has only two waypoints, the
helperSetScenarioCollision
function adds the third waypoint at the midpoint between them and sets its speed value to that of the last waypoint.If the ego vehicle or target actor does not travel with a constant speed starting from the first waypoint, the
helperSetScenarioCollision
function sets their speed values to a constant value of 80 km/h and 10 km/h, respectively.If the ego vehicle and the target vehicle do not collide but have intersecting trajectories,
helperSetScenarioCollision
checks if a collision is possible by modifying the wait time of the target vehicle. If possible, the function modifies the wait time of the target vehicle to create a collision event. Otherwise, the function returns an error.
This example demonstrates how to generate scenario variants by modifying the dimensions of the actors in the scenario. For information on how to generate scenario variants by modifying the actor dimensions, speed, and collision point, see Generate Scenario Variants for Testing AEB Pedestrian Systems.
References
[1] European New Car Assessment Programme (Euro NCAP). Test Protocol – AEB VRU systems. Version 3.0.4. EuroNCAP, April 2021. Available from: https://cdn.euroncap.com/media/62795/euro-ncap-aeb-vru-test-protocol-v304.pdf.