Main Content

Automatic Scenario Variant Generation for Testing AEB Systems

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.

  • 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.

Generate Seed Scenario

The seed scenario must be a collision scenario in which collision occurs between the ego vehicle and at least one of the target actors in the scenario. In this example, you generate the AEB_PedestrianTurning_Farside_50width test scenario of the European New Car Assessment Programme (Euro NCAP) test protocol as the seed scenario. The actor dimensions, positions, speed values, and trajectories are set as per the Euro NCAP test protocol requirements.

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.

Create a driving scenario object.

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")
    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.

egoVehicle = vehicle(scenario,ClassID=1,Position=[28.25 12.5 0], ...
    FrontOverhang=0.9,Mesh=driving.scenario.carMesh, ...
    Name="Vehicle under Test");
egoWaypoints = [29 15 0; 29 4 0; 29.93 1 0;
                32 -0.9 0; 34 -1.24 0.01; 49 -1.24 0];
egoSpeed = 21.24;
% Convert speed value to m/s
egoSpeed = (egoSpeed*1000)/3600;
egoSpeedVector = [0; egoSpeed; egoSpeed; egoSpeed; egoSpeed; egoSpeed];
egoYaw =  [-90; -90; NaN; -20.93; 0; 0];
trajectory(egoVehicle,egoWaypoints,egoSpeedVector,Yaw=egoYaw);

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.

movingTarget = actor(scenario,ClassID=4, ...
    Length=0.24, ...
    Width=0.5, ...
    Height=1.8, ...
    Position=[39.575 -7.71 0], ...
    RCSPattern=[-8 -8; -8 -8], ...
    Mesh=driving.scenario.pedestrianMesh, ...
    Name="Target Pedestrian");
targetWaypoints = [39.575 -7.71 0; 39.575 -6.71 0; 39.575 10 0];
targetSpeed = 5;
% Convert speed value to m/s
targetSpeed = (targetSpeed*1000)/3600;
targetSpeedVector = [0; targetSpeed; targetSpeed];
targetYaw = [90; NaN; 90];
trajectory(movingTarget,targetWaypoints,targetSpeedVector,Yaw=targetYaw);

Display the seed scenario.

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

Validate and Store Seed Scenario Data

Specify the ActorID values of the ego vehicle and the target actor. You can find the ActorID values and the names of the ego vehicle and the target actor by inspecting the Actors property of the scenario object.

egoID = 1;
targetID = 2;
table([scenario.Actors.ActorID],[scenario.Actors.Name],VariableNames={'ActorID','Name'})
ans=1×2 table
    ActorID                       Name                    
    _______    ___________________________________________

    1    2     "Vehicle under Test"    "Target Pedestrian"

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.

egoData = struct(id=egoID,speed=egoSpeedVector, ...
                 waypoints=egoWaypoints,yaw=egoYaw);
targetData = struct(id=targetID,speed=targetSpeedVector, ...
                    waypoints=targetWaypoints,yaw=targetYaw);

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.

  • 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 (Exl,Eyl) and top-right (Exr,Eyr) corners of the ego vehicle at the time of collision.

  • TargetFrontEdge — Specifies position values of the left (Txl,Tyl) and right (Txr,Tyr) 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 (Txl,Tyl) on the front edge of the target actor. The collision point (CP) and (Txl,Tyl) is related by the equation,

CP=|Exl-Txl|+|Eyl-Tyl|Egowidth.

  • EgoCollisionSideLength — Specifies the width of the ego vehicle.

collision_point.png

[collisionInformation] = helperComputeCollisionData(scenario,egoID,targetID)
collisionInformation = 
  collisionData with properties:

                      Time: 5.3800
              EgoFrontEdge: [2x3 double]
           TargetFrontEdge: [2x3 double]
               EgoPosition: [35.6595 -1.2400 0.0100]
            TargetPosition: [39.5750 -1.2378 0]
            CollisionPoint: 0.4343
    EgoCollisionSideLength: 1.8000

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);

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Seed Scenario contains 9 objects of type patch, line.","Tex":"Seed Scenario","LaTex":[]}

Generate Variants of Seed Scenario

Use the seed scenario and the collision information to generate scenario variants. You can:

  • Change the dimensions of the colliding actors in the scenario.

  • Change the collision point, which is the position at which the actors collide.

  • Change the speed of the ego vehicle. You can also set new speed values for the ego vehicle while it travels along the turns on the road.

Change Actor Dimensions

Modify the dimensions of the ego vehicle and the target actor in the seed scenario by specifying new values for one or more of these vehicle parameters: length, width, height, front overhang, rear overhang, and wheelbase. You can also compute the length of a vehicle as the sum of its front overhang, rear overhang, and wheelbase.

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);

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.

[scenarioAD,stateAD] = helperChangeActorDimensions(seedData, ...
                       egoDimensions,TargetDimensions=targetDimensions)
scenarioAD = 
  drivingScenario with properties:

        SampleTime: 0.0100
          StopTime: Inf
    SimulationTime: 0
         IsRunning: 1
            Actors: [1x2 driving.scenario.Actor]
          Barriers: [0x0 driving.scenario.Barrier]
       ParkingLots: [0x0 driving.scenario.ParkingLot]

stateAD = struct with fields:
            scenario: [1x1 drivingScenario]
       collisionData: [1x1 collisionData]
       egoMotionData: [1x1 struct]
    targetMotionData: [1x1 struct]

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
ans = 
  collisionData with properties:

                      Time: 5.4200
              EgoFrontEdge: [2x3 double]
           TargetFrontEdge: [2x3 double]
               EgoPosition: [35.8955 -1.2400 0.0100]
            TargetPosition: [39.5750 -2.4878 0]
            CollisionPoint: 0.4242
    EgoCollisionSideLength: 3

Inspect the waypoints and the speed values of the ego vehicle in the modified scenario.

stateAD.egoMotionData
ans = struct with fields:
           id: 1
        speed: [6x1 double]
    waypoints: [6x3 double]
          yaw: [6x1 double]

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
ans = 3×1

    0.9400
         0
         0

Display the scenario generated for the new actor dimensions.

figScene = figure;
set(figScene,Position=[50 50 500 500]);
hPanel1 = uipanel(figScene,Position=[0 0 1 1]);
hPlot1 = axes(hPanel1);
plot(scenarioAD,Waypoints="on",Parent=hPlot1)
title("Scenario Variant with New Actor Dimensions")
while advance(scenarioAD)
    pause(0.01)
end

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant with New Actor Dimensions contains 9 objects of type patch, line.","Tex":"Scenario Variant with New Actor Dimensions","LaTex":[]}

Change Collision Point

The collision point is the point on the front edge of the ego vehicle with which the left corner on the front edge of the target actor first collides. The value of collision point must be in the range 0 to 1.

  • 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);

Inspect the details of the collision event in the modified scenario.

stateCP.collisionData
ans = 
  collisionData with properties:

                      Time: 5.3800
              EgoFrontEdge: [2x3 double]
           TargetFrontEdge: [2x3 double]
               EgoPosition: [35.6595 -1.2400 0.0100]
            TargetPosition: [39.5750 -2.1660 0]
            CollisionPoint: 0.9495
    EgoCollisionSideLength: 1.8000

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

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant with New Collision Point contains 9 objects of type patch, line.","Tex":"Scenario Variant with New Collision Point","LaTex":[]}

Change Ego Speed

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;

Alter "WaitTime" to generate scenario variant

If you use "WaitTime" to generate the scenario variant, either the ego vehicle or the target actor waits at its first waypoint for a particular amount of time. If the new ego speed value 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. The function accomplishes this by assigning a waittime value to the 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.

Specify the modification method as "WaitTime".

method = "WaitTime";
[scenarioWT,stateWT] = helperChangeEgoSpeed(seedData,egoNewSpeed,Method=method);

Display the scenario generated with the new ego speed.

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

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant — WaitTime Method contains 9 objects of type patch, line.","Tex":"Scenario Variant — WaitTime Method","LaTex":[]}

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
ans = 
  collisionData with properties:

                      Time: 7.6100
              EgoFrontEdge: [2x3 double]
           TargetFrontEdge: [2x3 double]
               EgoPosition: [35.6259 -1.2400 0.0100]
            TargetPosition: [39.5750 -1.2317 0]
            CollisionPoint: 0.4343
    EgoCollisionSideLength: 1.8000

stateWT.targetMotionData.waittime
ans = 3×1

    2.2256
         0
         0

Check the ego speed value in the modified scenario.

stateWT.egoMotionData.speed
ans = 6×1

         0
    4.1667
    4.1667
    4.1667
    4.1667
    4.1667

Alter "EntryTime" to generate scenario variant

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.

Specify the modification method as "EntryTime".

method = "EntryTime";
[scenarioET,stateET] = helperChangeEgoSpeed(seedData,egoNewSpeed,Method=method);

Check the ego speed value in the modified scenario.

stateET.egoMotionData.speed
ans = 6×1

         0
    4.1667
    4.1667
    4.1667
    4.1667
    4.1667

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

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant — EntryTime Method contains 9 objects of type patch, line.","Tex":"Scenario Variant — EntryTime Method","LaTex":[]}

Alter "StartingPosition" to generate scenario variant

If you use "StartingPosition" to generate the scenario variant, the function modifies the starting position of the target actor. To use this method, the new ego speed value must be greater than the ego speed in the seed scenario.

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);

Check the ego speed value in the modified scenario.

stateSP.egoMotionData.speed
ans = 6×1

         0
   19.4444
   19.4444
   19.4444
   19.4444
   19.4444

Read the values of the target actor waypoints in the modified scenario.

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.

table(modifiedValue,originalValue,VariableNames={'Target Actor Waypoints in Modified Scenario','Target Actor Waypoints in Seed Scenario'})
ans=3×2 table
    Target Actor Waypoints in Modified Scenario    Target Actor Waypoints in Seed Scenario
    ___________________________________________    _______________________________________

           39.575    -2.5017          0                  39.575     -7.71         0       
           39.575    -1.4878          0                  39.575     -6.71         0       
           39.575         10          0                  39.575        10         0       

Display the scenario generated with the new ego speed.

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

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant — StartingPosition Method contains 9 objects of type patch, line.","Tex":"Scenario Variant — StartingPosition Method","LaTex":[]}

Change Ego Speed on Road Turn

If the trajectory of the ego vehicle is a curved path, the radius of curvature of the trajectory can vary depending on the speed of the ego vehicle. The radius of curvature of the ego trajectory increases for higher speed values and decreases for lower speed values. In this case, the collision time and the collision point do not remain the same as those of the seed scenario for large changes in the radius of curvature.

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);

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Seed Scenario contains 9 objects of type patch, line.","Tex":"Seed Scenario","LaTex":[]}

Check the speed value in the modified scenario.

stateAtTurn.egoMotionData.speed
ans = 8×1

         0
    2.7778
    2.7778
    2.7778
    2.7778
    2.7778
    2.7778
    2.7778

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
ans = 8×3

   29.0000   15.0000         0
   29.0000    4.0000         0
   29.0247    1.3453         0
   29.4062    0.1678         0
   30.1839   -0.7938         0
   31.3399   -1.2134    0.0073
   34.0000   -1.2400    0.0100
   49.0000   -1.2400         0

egoData.waypoints
ans = 6×3

   29.0000   15.0000         0
   29.0000    4.0000         0
   29.9300    1.0000         0
   32.0000   -0.9000         0
   34.0000   -1.2400    0.0100
   49.0000   -1.2400         0

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

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant — New Ego Speed and Trajectory at Turns contains 9 objects of type patch, line.","Tex":"Scenario Variant — New Ego Speed and Trajectory at Turns","LaTex":[]}

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".

  • To modify the actor dimensions, specify a value in the array as "dimensions".

  • To modify the collision point, specify a value in the array as "point".

  • To modify the speed of the ego vehicle and radius of curvature of ego's trajectory at road turns, specify a value in the array as "speed".

parameters = ["dimensions"; "point"; "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 = [];

Specify the new collision point.

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;

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,egoNewSpeed);
                tempSeedData = helperChangeState(tempSeedData,newState);
            end
    end
end

Display the generated scenario.

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

{"String":"Figure contains an axes object and an object of type uipanel. The axes object with title Scenario Variant New Ego Dimension, Collision Point, and Ego Speed contains 9 objects of type patch, line.","Tex":"Scenario Variant New Ego Dimension, Collision Point, and Ego Speed","LaTex":[]}

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.

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

References

[1] EURO NCAP AEB VRU Test Protocol v3.0.4. Available from: https://cdn.euroncap.com/media/62795/euro-ncap-aeb-vru-test-protocol-v304.pdf.

See Also

Apps

Functions

Related Topics