Feature Extraction

AutomotiveSimulator.jl provides useful functions to extract information from a scene.

Feature Extraction Pipeline

The function extract_features can be used to extract information from a list of scenes. It takes as input a vector of scenes (which could be the output of simulate), as well as a list of feature functions to use. The output is a dictionary of DataFrame from DataFrames.jl.

AutomotiveSimulator.extract_featuresFunction
extract_features(features, roadway::Roadway, scenes::Vector{<:Scene}, ids::Vector{I}) where I

Extract information from a list of scenes. It returns a dictionary of DataFrame objects.

Inputs

  • features: a tuple of feature functions. The feature types supported are EntityFeature, SceneFeature and TemporalFeature. Check the documentation for the list of available feature functions, and how to implement you own feature function.
  • roadway::Roadway : the roadway associated to the scenes.
  • scenes::Vector{<:Scene} : the simulation data from which we wish to extract information from. Each scene in the vector corresponds to one time step.
  • ids::Vector{I}: a list of entity IDs for which we want to extract the information.

Output

A dictionary mapping IDs to DataFrame objects. For a given ID, the DataFrame's columns correspond to the name of the input feature functions. The row correspond to the feature value for each scene (time history).

Example:

roadway = gen_straight_roadway(4, 100.0) 

scene_0 = Scene([
            Entity(VehicleState(VecSE2( 0.0,0.0,0.0), roadway, 10.0), VehicleDef(AgentClass.CAR, 5.0, 2.0), 1),
            Entity(VehicleState(VecSE2(10.0,0.0,0.0), roadway, 10.0), VehicleDef(AgentClass.CAR, 5.0, 2.0), 2),
        ])

scene_1 = Scene([
            Entity(VehicleState(VecSE2( 10.0,0.0,0.0), roadway, 10.0), VehicleDef(AgentClass.CAR, 5.0, 2.0), 1),
            Entity(VehicleState(VecSE2(20.0,0.0,0.0), roadway, 10.0), VehicleDef(AgentClass.CAR, 5.0, 2.0), 2),
        ])

dfs = extract_features((posgx, iscolliding), roadway, [scene_0, scene_1], [1,2])

dfs[1].posgx # history of global x position for vehicle of ID 1
source

Finding neighbors

Finding neighbors of an entity is a common query and can be done using the find_neighbor function. This function allows to find the neighbor of an entity within a scene using a forward search method. The search algorithm moves longitudinally along a given lane and its successors (according to the given road topology). Once it finds a car it stops searching and return the results as a NeighborLongitudinalResult

AutomotiveSimulator.NeighborLongitudinalResultType
NeighborLongitudinalResult

A structure to retrieve information about a neihbor in the longitudinal direction i.e. rear and front neighbors on the same lane. If the neighbor index is equal to nothing it means there is no neighbor.

Fields

  • ind::Union{Nothing, Int64} index of the neighbor in the scene
  • Δs::Float64 positive distance along the lane between vehicles positions
source

The find_neighbor function accepts different keyword argument to search front or rear neighbors, or neighbors on different lanes.

AutomotiveSimulator.find_neighborFunction
find_neighbor(scene::Scene, roadway::Roawday, ego::Entity; kwargs...)

Search through lanes and road segments to find a neighbor of ego in the scene. Returns a NeighborLongitudinalResult object with the index of the neighbor in the scene and its relative distance.

Arguments

  • scene::Scene the scene containing all the entities
  • roadway::Roadway the road topology on which entities are driving
  • ego::Entity the entity that we want to compute the neighbor of.

Keyword arguments

  • lane::Union{Nothing, Lane} the lane on which to search the neighbor, if different from the ego vehicle current lane, it uses the projection of the ego vehicle on the given lane as a reference point. If nothing, returns nothing.
  • rear::Bool = false set to true to search for rear neighbor, search forward neighbor by default
  • max_distance::Float64 = 250.0 stop searching after this distance is reached, if the neighbor is further than max_distance, returns nothing
  • targetpoint_ego::VehicleTargetPoint the point on the ego vehicle used for distance calculation, see VehicleTargetPoint for more info
  • targetpoint_neighbor::VehicleTargetPoint the point on the neighbor vehicle used for distance calculation, see VehicleTargetPoint for more info
  • ids_to_ignore::Union{Nothing, Set{I}} = nothing a list of entity ids to ignore for the search, ego is always ignored.
source

When computing the distance to a neighbor, one might want to choose different reference points on the vehicle (center to center, bumper to bumper, etc...). AutomotiveSimulator provides the VehicleTargetPoint types to do so. One can choose among three possible instances to use the front, center, or rear point of a vehicle to compute the distance to the neighbor.

AutomotiveSimulator.VehicleTargetPointType
VehicleTargetPoint

Defines a point on an entity that is used to measure distances. The following target points are supported and are subtypes of VehicleTargetPoint:

  • VehicleTargetPointFront
  • VehicleTargetPointCenter
  • VehicleTargetPointRear

The method targetpoint_delta(::VehicleTargetPoint, ::Entity) can be used to compute the delta in the longitudinal direction to add when considering a specific target point.

source

To get the relative position of two vehicles in the Frenet frame, the get_frenet_relative_position can be used. It stores the result in a FrenetRelativePosition object.

AutomotiveSimulator.get_frenet_relative_positionFunction
get_frenet_relative_position(veh_fore::Entity, veh_rear::Entity, roadway::Roadway)

return the Frenet relative position between the two vehicles. It projects the position of the first vehicle onto the lane of the second vehicle. The result is stored as a FrenetRelativePosition.

Lower level: getfrenetrelativeposition(posG::VecSE2{Float64}, roadind::RoadIndex, roadway::Roadway; maxdistancefore::Float64 = 250.0, # max distance to search forward [m] maxdistancerear::Float64 = 250.0, # max distance to search backward [m] improvementthreshold::Float64 = 1e-4, )

Project the given point to the same lane as the given RoadIndex. This will return the projection of the point, along with the Δs along the lane from the RoadIndex. The returned type is a FrenetRelativePosition object.

source
AutomotiveSimulator.FrenetRelativePositionType
FrenetRelativePosition

Contains information about the projection of a point on a lane. See get_frenet_relative_position.

Fields

  • origin::RoadIndex original roadindex used for the projection, contains the target lane ID.
  • target::RoadIndex roadindex reached after projection
  • Δs::Float64 longitudinal distance to the original roadindex
  • t::Float64 lateral distance to the original roadindex in the frame of the target lane
  • ϕ::Float64 angle with the original roadindex in the frame of the target lane
source

Implementing Your Own Feature Function

In AutomotiveSimulator, features are functions. The current interface supports three methods:

  • myfeature(::Roadway, ::Entity)
  • myfeature(::Roadway, ::Scene, ::Entity)
  • myfeature(::Roadway, ::Vector{<:Scene}, ::Entity)

For each of those methods, the last argument correspond to the entity with one of the ID given to the top level extract_features function. Creating a new feature consists of implementing one of those methods for your feature function.

As an example, let's define a feature function that returns the distance to the rear neighbor. Such feature will use the second method since it needs information about the whole scene to find the neighbor. If there are not rear neighbor then the function will return missing. DataFrame are designed to handled missing values so it should not be an issue.

function distance_to_rear_neighbor(roadway::Roadway, scene::Scene, ego::Entity)
    neighbor = find_neighbor(scene, roadway, ego, rear=true)
    if neighbor.ind === nothing 
        return missing 
    else 
        return neighbor.Δs
    end
end

Now you can use your feature function in extract features, the name of the function is used to name the column of the dataframe:

    dfs = extract_features((distance_to_rear_neighbor,), roadway, scenes, [1])
    dfs[1].distance_to_rear_neighbor # contains history of distances to rear neighor

!!!note If the supported methods are limiting for your use case please open an issue or submit a PR. It should be straightforward to extend the extract_features function to support other methods, as well as adding new feature trait.

List of Available Features

AutomotiveSimulator.distance_toFunction
distance_to(egoid)

generate a feature function distancetoegoid.

distance_to_$egoid(roadway, scene, veh) returns the distance between veh and the vehicle of id egoid in the scene.

source
AutomotiveSimulator.accFunction
acc(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the history of acceleration of the entity of id vehid using finite differences on the velocity. The first element is missing.

source
AutomotiveSimulator.accfsFunction
accfs(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the history of longitudinal acceleration in the Frenet frame of the entity of id vehid using finite differences on the velocity. The first element is missing.

source
AutomotiveSimulator.accftFunction
accft(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the history of lateral acceleration in the Frenet frame of the entity of id vehid using finite differences on the velocity. The first element is missing.

source
AutomotiveSimulator.jerkFunction
jerk(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the jerk history of the entity of id vehid using finite differences on acceleration (which uses finite differences on velocity). The first two elements are missing.

source
AutomotiveSimulator.jerkftFunction
jerkft(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the lateral jerk history in the Frenet frame of the entity of id vehid using finite differences on acceleration (which uses finite differences on velocity). The first two elements are missing.

source
AutomotiveSimulator.turn_rate_gFunction
turn_rate_g(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the turn rate history in the Frenet frame of the entity of id vehid using finite differences on global heading. The first element is missing.

source
AutomotiveSimulator.turn_rate_fFunction
turn_rate_g(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

returns the turn rate history in the Frenet frame of the entity of id vehid using finite differences on heading in the Frenet frame. The first element is missing.

source
AutomotiveSimulator.isbrakingFunction
isbraking(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

history of braking events: true when the acceleration is negative. The first element is missing.

source
AutomotiveSimulator.isacceleratingFunction
isaccelerating(roadway::Roadway, scenes::Vector{<:Scene}, vehid)

history of acceleration events: true when the acceleration is positive The first element is missing.

source
AutomotiveSimulator.dist_to_front_neighborFunction
dist_to_front_neighbor(roadway::Roadway, scene::Scene, veh::Entity)

Feature function to extract the longitudinal distance to the front neighbor (in the Frenet frame). Returns missing if there are no front neighbor.

source
AutomotiveSimulator.front_neighbor_speedFunction
front_neighbor_speed(roadway::Roadway, scene::Scene, veh::Entity)

Feature function to extract the velocity of the front neighbor. Returns missing if there are no front neighbor.

source
AutomotiveSimulator.time_to_collisionFunction
time_to_collision(roadway::Roadway, scene::Scene, veh::Entity)

Feature function to extract the time to collision with the front neighbor. Returns missing if there are no front neighbor.

source