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
There are two main ways to call the simulate!
function:
simulate!(scene::Frame{E}, roadway::R, models::Dict{I,M}, nticks::Int64, timestep::Float64; rng::AbstractRNG = Random.GLOBAL_RNG, scenes::Vector{Frame{E}} = [Frame(E, length(scene)) for i=1:nticks+1], callbacks = nothing)
which simply returns a vector of scenes. This vector can be pre-allocated and passed as a keyword argument. The randomness of the simulation can be controlled by passing a random number generator.simulate!(rec::EntityQueueRecord{S,D,I}, scene::EntityFrame{S,D,I}, roadway::R, models::Dict{I,M}, nticks::Int, callbacks::C)
which fills in a givenQueueRecord
object. TheQueueRecord
data structure is defined in Records.jl. This methods is slower and suffers from type stability issues. It will be deprecated in future releases.
See the tutorials for examples.
AutomotiveDrivingModels.simulate!
— FunctionDEPRECATION WARNING: this version of simulate!
is now deprecated.
simulate!(scene::Frame{E}, roadway::R, models::Dict{I,M<:DriverModel}, nticks::Int64, timestep::Float64; rng::AbstractRNG = Random.GLOBAL_RNG, scenes::Vector{Frame{E}} = [Frame(E, length(scene)) for i=1:nticks+1], callbacks=nothing)
Run nticks
steps of simulation with time step dt
and return a vector of scenes from time step 0 to nticks.
simulate!(::Type{A}, rec::EntityQueueRecord{S,D,I}, scene::EntityFrame{S,D,I}, roadway::R, models::Dict{I,M<:DriverModel}, nticks::Int)
simulate!(rec::EntityQueueRecord{S,D,I}, scene::EntityFrame{S,D,I}, roadway::R, models::Dict{I,M<:DriverModel}, nticks::Int)
Run nticks of simulation and place all nticks+1 scenes into the QueueRecord
simulate!(::Type{A},rec::EntityQueueRecord{S,D,I}, scene::EntityFrame{S,D,I}, roadway::R, models::Dict{I,M}, nticks::Int, callbacks::C) where {S,D,I,A,R,M<:DriverModel,C<:Tuple{Vararg{Any}}}
simulate!(rec::EntityQueueRecord{S,D,I}, scene::EntityFrame{S,D,I}, roadway::R, models::Dict{I,M}, nticks::Int, callbacks::C) where {S,D,I,A,R,M<:DriverModel,C<:Tuple{Vararg{Any}}}
Callback objects can also be passed in the simulate! function.
simulate!(
scene::Frame{E}, roadway::R, models::Dict{I,M},
nticks::Int64, timestep::Float64,
scenes::Vector{Frame{E}}, actions::Union{Nothing, Vector{Frame{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 Frame
s containing either Entity
s (for scenes) or EntityAction
s (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
.
Run a simulation and store the resulting scenes in the provided QueueRecord.
Only the ego vehicle is simulated; the other vehicles are as they were in the provided trajdata Other vehicle states will be interpolated
AutomotiveDrivingModels.get_actions!
— Functionget_actions!(actions::Vector{A}, scene::EntityFrame{S,D,I}, roadway::R, models::Dict{I, M},) where {S,D,I,A,R,M<:DriverModel}
Fill in actions
with the actions of each agent present in the scene. It calls observe!
and rand
for each driver models. actions
will contain the actions to apply to update the state of each vehicle.
AutomotiveDrivingModels.tick!
— Functiontick!(scene::EntityFrame{S,D,I}, roadway::R, actions::Vector{A}, Δt::Float64) where {S,D,I,A,R}
update scene
in place by updating the state of each vehicle given their current action in actions
. It calls the propagate
method for each vehicle in the scene.
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 AutomotiveDrivingModels.run_callback(
cb::ReachGoalCallback,
scenes::Vector{Frame{E}},
actions::Vector{Frame{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 frame of EntityAction
s 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 AutomotiveDrivingModels.run_callback(
cb::ReachGoalCallback,
scenes::Vector{Frame{E}},
actions::Vector{Frame{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
.
AutomotiveDrivingModels.run_callback
— Function# TODO: this should be removed, but where to document the function then?
run_callback(callback::Any, scenes::Vector{F}, roadway::R, models::Dict{I,M}, tick::Int) where {F,I,R,M<:DriverModel}
run_callback(callback::Any, rec::EntityQueueRecord{S,D,I}, roadway::R, models::Dict{I,M}, tick::Int) where {S,D,I,R,M<:DriverModel}
run callback and return whether simlation should terminate A new method should be implemented when defining a new callback object.
AutomotiveDrivingModels.CollisionCallback
— TypeCollisionCallback
Terminates the simulation once a collision occurs
Others
reset_hidden_states!(models::Dict{Int,M}) where {M<:DriverModel}
reset hidden states of all driver models in models