Driving in a Stadium

This example demonstrates a 2D driving simulation where cars drive around a three-lane stadium. The entities are defined by the types:

  • S - VehicleState, containing the vehicle position (both globally and relative to the lane) and speed
  • D - VehicleDef, containing length, width, and class
  • I - Symbol, a unique label for each vehicle

The environment is represented by a Roadway object which allows to define roads consisting of multiple lanes based on the RNDF format.

We load relevant modules and generate a 3-lane stadium roadway:

using AutomotiveSimulator
using AutomotiveVisualization
using Distributions

roadway = gen_stadium_roadway(3)
snapshot = render([roadway])

three lane stadium

As a next step, let's populate a scene with vehicles

w = DEFAULT_LANE_WIDTH
scene = Scene([
    Entity(VehicleState(VecSE2(10.0,  -w, 0.0), roadway, 29.0), VehicleDef(), :alice),
    Entity(VehicleState(VecSE2(40.0, 0.0, 0.0), roadway, 22.0), VehicleDef(), :bob),
    Entity(VehicleState(VecSE2(30.0, -2w, 0.0), roadway, 27.0), VehicleDef(), :charlie),
])
car_colors = get_pastel_car_colors(scene)
renderables = [
    roadway,
    (FancyCar(car=veh, color=car_colors[veh.id]) for veh in scene)...
]
snapshot = render(renderables)

stadium with cars

We can assign driver models to each agent and simulate the scenario.

timestep = 0.1
nticks = 300

models = Dict{Symbol, DriverModel}(
    :alice => LatLonSeparableDriver( # produces LatLonAccels
        ProportionalLaneTracker(), # lateral model
        IntelligentDriverModel(), # longitudinal model
    ),
    :bob => Tim2DDriver(
         mlane = MOBIL(),
    ),
    :charlie => StaticDriver{AccelTurnrate, MvNormal}(
        MvNormal([0.0,0.0], [1.0,0.1])
    )
)

set_desired_speed!(models[:alice],   12.0)
set_desired_speed!(models[:bob],     10.0)
set_desired_speed!(models[:charlie],  8.0)

scenes = simulate(scene, roadway, models, nticks, timestep)
301-element Vector{EntityScene{VehicleState, VehicleDef, Symbol}}:
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 ⋮
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)
 Scene{Entity{VehicleState, VehicleDef, Symbol}}(3 entities)

md nothing # hide

An animation of the simulation can be rendered using the Reel package

using Reel
using Printf

camera = TargetFollowCamera(:alice; zoom=10.)

animation = roll(fps=1.0/timestep, duration=nticks*timestep) do t, dt
    i = Int(floor(t/dt)) + 1
    update_camera!(camera, scenes[i])
    renderables = [
        roadway,
        (FancyCar(car=veh, color=car_colors[veh.id]) for veh in scenes[i])...,
        IDOverlay(x_off=-2, y_off=1, scene=scenes[i]),
        TextOverlay(text=[@sprintf("time: %.1fs", t)], pos=VecE2(40,40), font_size=24)
    ]
    render(renderables, camera=camera)
end
"animated_stadium.gif"

animated stadium with cars

Alternatively, one can also use the Interact framework to inspect the simulation record interactively.

using Interact
using Reel
using Blink
#md
w = Window()
viz = @manipulate for step in 1 : length(scenes)
    render([roadway, scenes[step]])
end
body!(w, viz)

The simulation results can be saved to a text file. Only entities using VehicleState and VehicleDef are supported out of the box. If you wish to do IO operation with different states and definition types you have to implement Base.write and Base.read for those new types.

open("2Dstadium_listrec.txt", "w") do io
    write(io, scenes)
end

The trajectory data file can be loaded in a similar way. You need to specify the output type.

loaded_scenes = open("2Dstadium_listrec.txt", "r") do io
    read(io, Vector{EntityScene{VehicleState, VehicleDef, String}})
end
render([roadway, loaded_scenes[1]])

stadium with cars after load


This page was generated using Literate.jl.