Main Content

Generate Scenario Variants for Emergency Lane Keeping Testing

This example shows you how to generate scenario variants from a seed scenario to use for Emergency Lane Keeping (ELK) testing in accordance with the European New Car Assessment Programme (Euro NCAP®) test protocol standards.

ELK is an advanced driver assistance system (ADAS) that aids a driver in keeping a running vehicle within marked lane boundaries during emergency driving situations. The ELK system has sensors to detect lane boundaries, surrounding objects, and target vehicles. If the system detects the vehicle veering out of its lane during an emergency, such as suddenly swerving to avoid a collision, it can automatically steer the vehicle back into its lane and help avoid crashes or accidents. To perform safety assessments of autonomous vehicles, Euro NCAP® has developed specific test procedures for ELK.

In this example, you:

  • Create a seed scenario specific to the Euro NCAP test standards for ELK testing.

  • Extract actor parameters for generating variations. The parameters to vary in the seed scenario, include actor waypoints, speed, and yaw.

  • Generate variants for the input scenario.

  • Visualize the generated scenario variants next to the seed scenario.

  • Export the scenario variants to the ASAM OpenSCENARIO® file format.

Create Seed Scenario

In this example, you create a seed scenario for an ELK overtaking vehicle test. In this scenario, the ego vehicle unintentionally changes lanes, overtakes a vehicle in the other lane, and collides with that vehicle.

This example requires Automated Driving Toolbox™ Test Suite for Euro NCAP® Protocols support package. Check if the support package is installed.

helperCheckSupportPackageInstalled

Specify the ELK test type and create a seed scenario using the helperCreateNCAPScenario function.

ELKTestType = "ELK_OvertakingVehicle";
[seedScenario,seedTitle] = helperCreateNCAPScenario(ELKTestType);

Extract Parameters for Scenario Variant Generation

Extract the properties from the seed scenario and store these properties in a ScenarioDescriptor object using the getScenarioDescriptor function.

seedScenarioDescriptor = getScenarioDescriptor(seedScenario,Simulator="DrivingScenario")
seedScenarioDescriptor = 
  ScenarioDescriptor with properties:

    Status: "DescriptorCreated"

Get the ELK testing parameters for the Euro NCAP protocol standards by using the helperGetNCAPParameters function.

ELKParams = helperGetNCAPParameters(ELKTestType);

Perform Parameter Variations

Specify the ActorID values of the ego and target actors by using the identifyActorOfInterest function.

actorIDs = identifyActorOfInterest(seedScenarioDescriptor);

Create an array of objects to store variations by using the variationProperties object. Use the Euro NCAP parameters stored in ELKParams variable for varying ego properties. Add variations to the seed scenario by using the varyActorProperties and the varyCollisionProperties object functions. To specify waypoints for performing lane drift, you can generate new waypoint values by using the generateWaypoints function.

numVariations = size(ELKParams.lateralVelocity,2);
variants = variationProperties.empty(numVariations,0);
for vCounter = 1:numVariations
    variants(vCounter) = variationProperties;
    waypoints = generateWaypoints(seedScenarioDescriptor,"LaneDrift",seedScenario.Actors(actorIDs.EgoID, 1).Position, ...
        ELKParams.Radius(vCounter),"curveDriftDistance",ELKParams.d1(vCounter),seedScenario.Actors(actorIDs.EgoID,1).Width, ...
        preDriftTravelDistance=10,direction=ELKParams.Turn,postDriftTravelDistance=0);
    varyActorProperties(variants(vCounter),actorIDs.EgoID,Waypoints=waypoints);
    if isequal(ELKTestType,"ELK_OvertakingVehicle") || isequal(ELKTestType,"ELK_OvertakingVehicle_Intentional") || isequal(ELKTestType,"ELK_OncomingVehicle")
        varyCollisionProperties(variants(vCounter),actorIDs.EgoID,actorIDs.TargetIDs);
    end
end

Generate Scenario Variants

Vary the actor parameters of a seed scenario and generate variant scenarios by using the generateVariants function.

[variantDescriptors,variantInfo] = generateVariants(seedScenarioDescriptor,variants);

For each of the generated variant scenarios, get a drivingScenario object from the corresponding ScenarioDescriptor object by using the getScenario function.

variantScenarios = getScenario(variantDescriptors,Simulator="DrivingScenario");

Visualize Generated Variants

Get the title of the figure using the helperGetVisualizationProperties helper function. The function also returns variantTitles, which specifies the grid titles. Additionally, the function also returns the stopAtCollisionFlag, using which you can stop the simulation at collision.

[figureTitle,variantTitles,stopAtCollisionFlag] = helperGetVisualizationProperties(ELKTestType,ELKParams);

Visualize the seed scenario and the generated variants by using the helperVisualizeVariants helper function.

helperVisualizeVariants(seedScenario,variantScenarios,Title=figureTitle,SeedTitle=seedTitle, ...
    VariantTitles=variantTitles,Waypoints="off",StopAtCollision=stopAtCollisionFlag);

Figure Variant Visualization contains 5 axes objects and other objects of type subplottext, uipanel. Axes object 1 with title Lateral Velocity = 0.6 m/s contains 6 objects of type patch, line. Axes object 2 with title Lateral Velocity = 0.5 m/s contains 6 objects of type patch, line. Axes object 3 with title Lateral Velocity = 0.4 m/s contains 6 objects of type patch, line. Axes object 4 with title Lateral Velocity = 0.3 m/s contains 6 objects of type patch, line. Axes object 5 with title Lateral Velocity = 0.2 m/s contains 6 objects of type patch, line.

Export to ASAM OpenSCENARIO

Export the generated scenario variant to ASAM OpenSCENARIO file format 1.0.

for iter = 1:length(variantScenarios)
    export(variantScenarios(iter),"OpenSCENARIO","variantScenario_" + ELKTestType + iter + ".xosc")
end

Further Exploration

In this example, you have explored scenario variant generation for the ELK overtaking vehicle test.

You can visualize the scenario in a 3D simulation environment by following these steps:

  1. Enter this command to open the scenario in the Driving Scenario Designer app: drivingScenarioDesigner(variantScenarios(1));

  2. On the app toolstrip, select 3D Display > View Simulation in 3D Display.

  3. After the app opens the Simulation 3D Viewer window, click Run.

Visualization of ELK overtaking vehicle scenario in 3D simulation environment.

To generate scenario variants for another ELK testing scenario, specify one of these values for the ELKTestType variable, and then follow the rest of the procedure in this example.

  • ELK_OvertakingVehicle — The ego vehicle unintentionally changes lanes and attempts to overtake the target vehicle in the other lane, colliding with the target vehicle.

  • ELK_OvertakingVehicle_Intentional — The ego vehicle intentionally changes lanes and attempts to overtake the target vehicle in the other lane, colliding with the target vehicle.

  • ELK_OncomingVehicle — The ego vehicle unintentionally drifts out of the lane toward the oncoming target vehicle in the other lane and collides with that vehicle.

  • ELK_SolidLine_Left — The ego vehicle drifts out of the road toward the left side with a solid lane marking.

  • ELK_SolidLine_Right — The ego vehicle drifts out of the road toward the right side with solid lane marking.

  • ELK_RoadEdge — The ego vehicle is drifts out of the road toward the right side of a road with no lane marking and no dashed center line.

  • ELK_RoadEdge_CenterLine — The ego vehicle is drifts out of the road toward the right side of a road with no lane marking and a dashed center line.

For example, to generate a seed scenario for an ELK oncoming vehicle test, use this code.

ELKTestType = "ELK_OncomingVehicle";

seedScenario = helperCreateNCAPScenario(ELKTestType);

Helper Functions

helperGetVisualizationProperties

This function returns the title of a figure and a flag that specifies whether the simulation should stop or continue when a collision occurs in the scenario.

function [figureTitle,gridPlotTitles,stopAtCollisionFlag] =  helperGetVisualizationProperties(ELKTestType,variantParams)
    switch ELKTestType
        case "ELK_SolidLine_Left"
            stopAtCollisionFlag = "off";
            figureTitle = "Variants of ELK Solid Line Left Turn Scenario";
        case "ELK_SolidLine_Right"
            stopAtCollisionFlag = "off";
            figureTitle = "Variants of ELK Solid Line Right Turn Scenario";
        case "ELK_RoadEdge_CenterLine"
            stopAtCollisionFlag = "off";
            figureTitle = "Variants of ELK Road Edge with Center Line Scenario";
        case "ELK_RoadEdge"
            stopAtCollisionFlag = "off";
            figureTitle = "Variants of ELK Road Edge Scenario";
        case "ELK_OncomingVehicle"
            stopAtCollisionFlag = "on";
            figureTitle = "Variants of ELK Oncoming Vehicle Scenario";
        case "ELK_OvertakingVehicle"
            stopAtCollisionFlag = "on";
            figureTitle = "Variants of ELK Overtaking Vehicle Unintentional Lane Change Scenario";
        case "ELK_OvertakingVehicle_Intentional"
            stopAtCollisionFlag = "on";
            figureTitle = "Variants of ELK Overtaking Vehicle Intentional Lane Change Scenario";
        otherwise
            error("Invalid type of seed scenario for ELK Test.")
    end

    gridPlotTitles = "";
    numVariants = length(variantParams.lateralVelocity);
    for iter = 1:numVariants
        gridPlotTitles(iter) = "Lateral Velocity = " + num2str(variantParams.lateralVelocity(iter)) + " m/s";
    end
end

References

[1] European New Car Assessment Programme (Euro NCAP). Test Protocol – Lane Support Systems, Version 4.2. Euro NCAP, November 2022. https://cdn.euroncap.com/media/75440/euro-ncap-lss-test-protocol-v42.pdf

See Also

Functions

Related Topics