Simulation

Simulations can be run using the simulate function. A simulation updates the initial scene forward in time. Each simulation step consists of the following operations:

  • call the observe! function for each vehicle to update their driver model given the current scene
  • sample an action from the driver model by calling rand on the driver model.
  • update the state of each vehicle using the sampled action and the propagate method.
  • repeat for the desired number of steps
AutomotiveSimulator.simulateFunction
simulate(
    scene::Scene{E}, roadway::R, models::Dict{I,M}, nticks::Int64, timestep::Float64;
    rng::AbstractRNG = Random.GLOBAL_RNG, callbacks = nothing
) where {E<:Entity,A,R,I,M<:DriverModel}

Simulate a scene. For detailed information, consult the documentation of simulate!. By default, returns a vector containing one scene per time step.

source
AutomotiveSimulator.simulate!Function
simulate!(
    scene::Scene{E}, roadway::R, models::Dict{I,M},
    nticks::Int64, timestep::Float64,
    scenes::Vector{Scene{E}}, actions::Union{Nothing, Vector{Scene{A}}} = nothing;
    rng::AbstractRNG = Random.GLOBAL_RNG, callbacks = nothing
) where {E<:Entity,A<:EntityAction,R,I,M<:DriverModel}

Simulate the entities in scene along a roadway for a maximum of nticks time steps of size timestep. Returns the number of successfully performed timesteps.

At each time step, models is used to determine the action for each agent. scenes and actions are pre-allocated vectors of Scenes containing either Entitys (for scenes) or EntityActions (for actions). If actions is equal to nothing (default), the action history is not tracked. scenes must always be provided.

callbacks is an array of callback functions which are invoked before the simulation starts and after every simulation step. Any callback function can cause an early termination by returning true (the default return value for callback functions should be false). The random number generator for the simulation can be provided using the rng keyword argument, it defaults to Random.GLOBAL_RNG.

source

See the tutorials for more examples.

Callbacks

One can define callback functions that will be run at each simulation step. The callback function can terminate the simulation by returning true. The default return value of a callback function should be false. Callback functions are also useful to log simulation information.

To run a custom callback function in the simulation loop, you must implement a custom callback type and an associated run_callback method for that type with the following signature

function AutomotiveSimulator.run_callback(
    cb::ReachGoalCallback,
    scenes::Vector{Scene{E}},
    actions::Vector{Scene{A}},
    roadway::R,
    models::Dict{I,M},
    tick::Int,
    ) where {E<:Entity,A<:EntityAction,R,I,M<:DriverModel}
end

The scenes object holds a snapshot of a scene at each timestep in the range 1:tick, and the actions object holds a scene of EntityActions which record the action of each vehicle for the time steps 1:(tick-1).

Here is an example of a callback that checks if a vehicle's longitudinal position has reached some goal position and stops the simulation if it is the case.

struct ReachGoalCallback # a callback that checks if vehicle veh_id has reach a certain position 
    goal_pos::Float64
    veh_id::Int64
end 

function AutomotiveSimulator.run_callback(
    cb::ReachGoalCallback,
    scenes::Vector{Scene{E}},
    actions::Vector{Scene{A}},
    roadway::R,
    models::Dict{I,M},
    tick::Int,
    ) where {E<:Entity,A<:EntityAction,R,I,M<:DriverModel}
    veh = get_by_id(last(scenes), cb.veh_id)
    return veh.state.posF.s > cb.goal_pos 
end

A callback for collision is already implemented: CollisionCallback.

AutomotiveSimulator.run_callbackFunction
run_callback(callback, scenes::Vector{EntityScene}, actions::Union{Nothing, Vector{A}}, roadway::Roadway, models::Dict{I, DriverModel}, tick::Int64)

Given a callback type, run_callback will be run at every step of a simulation run using simulate. By overloading the run_callback method for a custom callback type one can log information or interrupt a simulation. The run_callback function is expected to return a boolean. If true the simulation is stopped.

Inputs:

  • callback the custom callback type used for dispatch
  • scenes where the simulation data is stored, note that it is only filled up to the current time step (scenes[1:tick+1])
  • actions where the actions are stored, it is only filled up to actions[tick]
  • roadway the roadway where entities are moving
  • models a dictionary mapping entity IDs to driver models
  • tick the index of the current time step
source

Woking with datasets

When working with datasets or pre-recorded datasets, one can replay the simulation using simulate_from_history. It allows to update the state of an ego vehicle while other vehicles follow the trajectory given in the dataset.

AutomotiveSimulator.simulate_from_historyFunction
simulate_from_history(model::DriverModel, roadway::Roadway, trajdata::Vector{Scene{E}}, egoid, timestep::Float64, 
                      start::Int = 1, stop::Int = length(trajdata);
                      rng::AbstractRNG = Random.GLOBAL_RNG) where {E<:Entity}

Replay the given trajectory except for the entity egoid which follows the given driver model. See simulate_from_history! if you want to provide a container for the results or log actions.

source
AutomotiveSimulator.simulate_from_history!Function
simulate_from_history!(model::DriverModel, roadway::Roadway, trajdata::Vector{Scene{E}}, egoid, timestep::Float64, 
                      start::Int, stop::Int, scenes::Vector{Scene{E}};
                      actions::Union{Nothing, Vector{Scene{A}}} = nothing, rng::AbstractRNG = Random.GLOBAL_RNG) where {E<:Entity}

Replay the given trajectory except for the entity egoid which follows the given driver model. The resulting trajectory is stored in scenes, the actions of the ego vehicle are stored in actions.

source
AutomotiveSimulator.observe_from_history!Function
observe_from_history!(model::DriverModel, roadway::Roadway, trajdata::Vector{<:EntityScene}, egoid, start::Int, stop::Int)

Given a prerecorded trajectory trajdata, run the observe function of a driver model for the scenes between start and stop for the vehicle of id egoid. The ego vehicle does not take any actions, it just observe the scenes,

source