diff --git a/.travis.yml b/.travis.yml index 8661ec9..225533f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,14 +26,12 @@ after_success: jobs: include: - stage: "Documentation" - julia: 1.0 + julia: 1.3 os: linux script: - - julia --project=docs/ -e 'using Pkg; - Pkg.add("Documenter"); - Pkg.add(PackageSpec(url="https://github.com/sisl/Records.jl")); - Pkg.add(PackageSpec(url="https://github.com/sisl/Vec.jl")); - Pkg.develop(PackageSpec(path=pwd())); - Pkg.instantiate()' + - git clone https://github.com/JuliaRegistries/General $(julia -e 'import Pkg; println(joinpath(Pkg.depots1(), "registries", "General"))') + - git clone https://github.com/SISL/Registry $(julia -e 'import Pkg; println(joinpath(Pkg.depots1(), "registries", "SISL"))') + - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); + Pkg.instantiate()' - julia --project=docs/ docs/make.jl after_success: skip diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..75427a7 --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,12 @@ +[deps] +AutoViz = "82aa6e0c-a491-5edf-8d4b-c16b98e4ea17" +AutomotiveDrivingModels = "99497e54-f3d6-53d3-a3a9-fa9315a7f1ba" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +Records = "5984c134-fa48-5ed5-a57f-fc2f6936871f" +Reel = "71555da5-176e-5e73-a222-aebc6c6e4f2f" + +[compat] +AutoViz = "^0.8.0" +AutomotiveDrivingModels = "^0.7.12" +Documenter = "0.24" diff --git a/docs/make.jl b/docs/make.jl index ce61cf2..650e067 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -3,7 +3,27 @@ using Documenter, AutomotiveDrivingModels makedocs( modules = [AutomotiveDrivingModels], format = Documenter.HTML(), - sitename="AutomotiveDrivingModels.jl" + sitename="AutomotiveDrivingModels.jl", + pages=[ + "Home" => "index.md", + "Examples" => [ + "examples/straight_roadway.md", + "examples/stadium.md", + "examples/intersection.md", + "examples/crosswalk.md", + "examples/sidewalk.md" + ], + "Manual" => [ + "Roadways.md", + "actions.md", + "states.md", + "agent_definitions.md", + "behaviors.md", + "simulation.md", + "collision_checkers.md", + "feature_extraction.md" + ] + ] ) deploydocs( diff --git a/docs/src/Roadways.md b/docs/src/Roadways.md index 52bcbee..fc0d2b0 100644 --- a/docs/src/Roadways.md +++ b/docs/src/Roadways.md @@ -68,7 +68,6 @@ The Frenet frame is a lane relative frame to represent a position on the road ne ```@docs Frenet - get_posG ``` ## Accessing objects and projections @@ -82,10 +81,10 @@ such as lane or curve points: RoadIndex CurveIndex RoadProjection - proj(posG::VecSE2{T}, lane::Lane, roadway::Roadway;move_along_curves::Bool = true ) where T<: Real + proj(posG::VecSE2{T}, lane::Lane{T}, roadway::Roadway{T};move_along_curves::Bool = true ) where T<: Real proj(posG::VecSE2{T}, seg::RoadSegment, roadway::Roadway) where T<: Real proj(posG::VecSE2{T}, roadway::Roadway) where T<: Real - Base.getindex(lane::Lane, ind::CurveIndex, roadway::Roadway) + Base.getindex(lane::Lane{T}, ind::CurveIndex{I,T}, roadway::Roadway{T}) where{I<:Integer, T<:Real} Base.getindex(roadway::Roadway, segid::Int) Base.getindex(roadway::Roadway, tag::LaneTag) ``` @@ -117,4 +116,4 @@ such as lane or curve points: ```@docs Base.read(io::IO, ::MIME"text/plain", ::Type{Roadway}) Base.write(io::IO, ::MIME"text/plain", roadway::Roadway) -``` \ No newline at end of file +``` diff --git a/docs/src/behaviors.md b/docs/src/behaviors.md index 4f1968a..cf28f7a 100644 --- a/docs/src/behaviors.md +++ b/docs/src/behaviors.md @@ -15,7 +15,7 @@ We provide an interface to interact with behavior model or implement your own. T action_type(::DriverModel{A}) where A set_desired_speed!(model::DriverModel, v_des::Float64) reset_hidden_state!(model::DriverModel) - observe!(model::DriverModel, scene::EntityFrame{S,D,I}, roadway::R, egoid::Integer) where {S,D,I,R} + observe!(model::DriverModel, scene::EntityFrame{S,D,I}, roadway, egoid::I) where {S,D,I} Base.rand(model::DriverModel) ``` diff --git a/docs/src/examples/crosswalk.md b/docs/src/examples/crosswalk.md new file mode 100644 index 0000000..2865da5 --- /dev/null +++ b/docs/src/examples/crosswalk.md @@ -0,0 +1,181 @@ +# Crosswalk + +In this notebook we demonstrate how to define a crosswalk with pedestrians using `AutomotiveDrivingModels`. +To do this, we define a crosswalk area as well as a pedestrian agent type. + +## Generate a crosswalk environment + +We define a new concrete type that will contain the roadway (where cars drive) +and the crosswalk definition which is just a regular lane. + + +```@example crosswalk +using AutomotiveDrivingModels +using AutoViz +AutoViz.colortheme["background"] = colorant"white"; # hide +using Random + +struct CrosswalkEnv + roadway::Roadway{Float64} + crosswalk::Lane{Float64} +end +``` + +The crosswalk lane consists of a straight road segment perpendicular to the road. +We will define the roadway just as a straight road. + +```@example crosswalk +# geometry parameters +roadway_length = 50. +crosswalk_length = 20. +crosswalk_width = 6.0 +crosswalk_pos = roadway_length/2 + +# Generate a straight 2-lane roadway and a crosswalk lane +roadway = gen_straight_roadway(2, roadway_length) +crosswalk_start = VecE2(crosswalk_pos, -crosswalk_length/2) +crosswalk_end = VecE2(crosswalk_pos, crosswalk_length/2) +crosswalk_lane = gen_straight_curve(crosswalk_start, crosswalk_end, 2) +crosswalk = Lane(LaneTag(2,1), crosswalk_lane, width = crosswalk_width) +cw_segment = RoadSegment(2, [crosswalk]) +push!(roadway.segments, cw_segment) # append it to the roadway + +# initialize crosswalk environment +env = CrosswalkEnv(roadway, crosswalk) +nothing # hide +``` + +**Render the crosswalk** + +We will define a new method to render this new environment. +The roadway part is just rendered regularly, we add specific instuction +for the crosswalk part that will display the white stripes. + +```@example crosswalk +using Cairo + +function AutoViz.add_renderable!(rendermodel::RenderModel, env::CrosswalkEnv) + + # render the road without the crosswalk + roadway = gen_straight_roadway(2, roadway_length) + add_renderable!(rendermodel, roadway) + + # render crosswalk + curve = env.crosswalk.curve + n = length(curve) + pts = Array{Float64}(undef, 2, n) + for (i,pt) in enumerate(curve) + pts[1,i] = pt.pos.x + pts[2,i] = pt.pos.y + end + + add_instruction!( + rendermodel, render_dashed_line, + (pts, colorant"white", env.crosswalk.width, 1.0, 1.0, 0.0, Cairo.CAIRO_LINE_CAP_BUTT) + ) + return rendermodel +end + +snapshot = render([env]) +write("crosswalk.svg", snapshot) # hide +``` +![crosswalk](crosswalk.svg) + + + +### Navigate the crosswalk example + +Cars will be navigating in the roadway just as before. +For the pedestrian we can define a new vehicle definition where we specify +the size of the bounding box represented by the pedestrian. + + +```@example crosswalk +# field of the VehicleDef type +fieldnames(VehicleDef) +# Agent.Class is from AutomotiveDrivingModels +const PEDESTRIAN_DEF = VehicleDef(AgentClass.PEDESTRIAN, 1.0, 1.0) +nothing # hide +``` + + +```@example crosswalk +# Car definition +car_initial_state = VehicleState(VecSE2(5.0, 0., 0.), roadway.segments[1].lanes[1],roadway, 8.0) +car = Entity(car_initial_state, VehicleDef(), :car) + +# Pedestrian definition using our new Vehicle definition +ped_initial_state = VehicleState(VecSE2(+24.5,-7.0,π/2), env.crosswalk, roadway, 0.5) +ped = Entity(ped_initial_state, PEDESTRIAN_DEF, :pedestrian) + +scene = Frame([car, ped]) + +# visualize the initial state +snapshot = render([env, scene]) +write("crosswalk_initial.svg", snapshot) # hide +``` +![initial state of crosswalk](crosswalk_initial.svg) + + +### Simulate the scenario + +As before, associate a driver model to each vehicle in the scene. +We will use the model defined in the intersection example for both agents. + + +```@example crosswalk +mutable struct LinearDriver <: DriverModel{LaneFollowingAccel} + a::LaneFollowingAccel + p::Float64 # confidence on the pedestrian intention + k::Float64 # gain +end + +AutomotiveDrivingModels.get_name(model::LinearDriver) = "linear driver" + +function AutomotiveDrivingModels.observe!(model::LinearDriver, scene::Frame, roadway::Roadway, egoid) + model.a = LaneFollowingAccel(model.k*model.p) + # change the confidence based on some policy + # you can get the position of the pedestrian from the scene + model.p = 100.0 +end +Base.rand(rng::AbstractRNG, model::LinearDriver) = model.a +``` + + +```@example crosswalk +timestep = 0.1 +nticks = 50 + +# define a model for each entities present in the scene +models = Dict{Symbol, DriverModel}() + +# Constant speed model +models[:car] = LinearDriver(LaneFollowingAccel(0.0), 20.0, -0.02) +models[:pedestrian] = IntelligentDriverModel(v_des=1.0) + +# execute the simulation +scenes = simulate(scene, roadway, models, nticks, timestep) +nothing # hide +``` + +## Generate a video with Reel.jl + +```@example crosswalk +using Reel + +function animate_record(scenes::Vector{Frame{E}},dt::Float64, env::CrosswalkEnv) where {E<:Entity} + duration = length(scenes)*dt::Float64 + fps = Int(1/dt) + function render_rec(t, dt) + frame_index = Int(floor(t/dt)) + 1 + return render([env, scenes[frame_index]]) + end + return duration, fps, render_rec +end + +duration, fps, render_hist = animate_record(scenes, timestep, env) +film = roll(render_hist, fps=fps, duration=duration) +write("crosswalk_animated.gif", film) # hide +nothing # hide +``` +![animated crosswalk](crosswalk_animated.gif) diff --git a/docs/src/examples/intersection.md b/docs/src/examples/intersection.md new file mode 100644 index 0000000..f449cfa --- /dev/null +++ b/docs/src/examples/intersection.md @@ -0,0 +1,228 @@ +# Intersection + +In this example we demonstrate how to define a T-shape intersection with `AutomotiveDrivingModels`. +You will also learn how to define your own custom action type and driver model type. + +## Generate a T-Shape intersection + +In order to generate the road network, we first initialize a Roadway object. + +```@example intersection +using AutomotiveDrivingModels +using AutoViz +AutoViz.colortheme["background"] = colorant"white"; # hide +using Random + +roadway = Roadway() +nothing # hide +``` + +Define coordinates of the entry and exit points to the intersection + +```@example intersection +r = 5.0 # turn radius +w = DEFAULT_LANE_WIDTH + +A = VecSE2(0.0,w,-π) +B = VecSE2(0.0,0.0,0.0) +C = VecSE2(r,-r,-π/2) +D = VecSE2(r+w,-r,π/2) +E = VecSE2(2r+w,0,0) +F = VecSE2(2r+w,w,-π) +nothing # hide +``` + +The next step consists in appending all the lanes to the road network. +We can define a helper function to add a new lane to the roadway. + + +```@example intersection +function append_to_curve!(target::Curve, newstuff::Curve) + s_end = target[end].s + for c in newstuff + push!(target, CurvePt(c.pos, c.s+s_end, c.k, c.kd)) + end + return target +end +nothing # hide +``` + +Example of a lane that consists of 3 road segments, a straight curve +(from the left to the center), a turning part (right turn) and a final +straight curve. + +```@example intersection +# Append right turn coming from the left +curve = gen_straight_curve(convert(VecE2, B+VecE2(-100,0)), convert(VecE2, B), 2) +append_to_curve!(curve, gen_bezier_curve(B, C, 0.6r, 0.6r, 51)[2:end]) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, C), convert(VecE2, C+VecE2(0,-50.0)), 2)) +lane = Lane(LaneTag(length(roadway.segments)+1,1), curve) +push!(roadway.segments, RoadSegment(lane.tag.segment, [lane])) + +# visualize the current lane constellation +snapshot = render([roadway]) +write("partial_intersection.svg", snapshot) # hide +``` + +![partial intersection](partial_intersection.svg) + + +Let's repeat the process and complete the T-shape intersection + +```@example intersection +# Append straight left +curve = gen_straight_curve(convert(VecE2, B+VecE2(-100,0)), convert(VecE2, B), 2) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, B), convert(VecE2, E), 2)[2:end]) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, E), convert(VecE2, E+VecE2(50,0)), 2)) +lane = Lane(LaneTag(length(roadway.segments)+1,1), curve) +push!(roadway.segments, RoadSegment(lane.tag.segment, [lane])) + +# Append straight right +curve = gen_straight_curve(convert(VecE2, F+VecE2(50,0)), convert(VecE2, F), 2) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, F), convert(VecE2, A), 2)[2:end]) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, A), convert(VecE2, A+VecE2(-100,0)), 2)) +lane = Lane(LaneTag(length(roadway.segments)+1,1), curve) +push!(roadway.segments, RoadSegment(lane.tag.segment, [lane])) + +# Append left turn coming from the right +curve = gen_straight_curve(convert(VecE2, F+VecE2(50,0)), convert(VecE2, F), 2) +append_to_curve!(curve, gen_bezier_curve(F, C, 0.9r, 0.9r, 51)[2:end]) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, C), convert(VecE2, C+VecE2(0,-50)), 2)) +lane = Lane(LaneTag(length(roadway.segments)+1,1), curve) +push!(roadway.segments, RoadSegment(lane.tag.segment, [lane])) + +# Append right turn coming from below +curve = gen_straight_curve(convert(VecE2, D+VecE2(0,-50)), convert(VecE2, D), 2) +append_to_curve!(curve, gen_bezier_curve(D, E, 0.6r, 0.6r, 51)[2:end]) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, E), convert(VecE2, E+VecE2(50,0)), 2)) +lane = Lane(LaneTag(length(roadway.segments)+1,1), curve) +push!(roadway.segments, RoadSegment(lane.tag.segment, [lane])) + +# Append left turn coming from below +curve = gen_straight_curve(convert(VecE2, D+VecE2(0,-50)), convert(VecE2, D), 2) +append_to_curve!(curve, gen_bezier_curve(D, A, 0.9r, 0.9r, 51)[2:end]) +append_to_curve!(curve, gen_straight_curve(convert(VecE2, A), convert(VecE2, A+VecE2(-100,0)), 2)) +lane = Lane(LaneTag(length(roadway.segments)+1,1), curve) +push!(roadway.segments, RoadSegment(lane.tag.segment, [lane])) + +snapshot = render([roadway]) +write("intersection.svg", snapshot) # hide +``` +![intersection](intersection.svg) + + +We can identify each lane thanks to the following user-defined functions. +We define a `LaneOverlay` object that indicate the lane to highlight. +One could implement any custom type to display other information on the lane. +We then add a new method to the `add_renderable!` function that execute the specific +action (coloring in blue). Look at `Autoviz.jl` for more detail on the function +`add_renderable!`. + +The following animation iterates over the individual lanes of the intersection +layout and highlights them: + +```@example intersection +struct LaneOverlay <: SceneOverlay + roadway::Roadway + lane::Lane + color::Colorant +end +function AutoViz.add_renderable!(rendermodel::RenderModel, overlay::LaneOverlay) + add_renderable!(rendermodel, overlay.lane, overlay.roadway, color_asphalt=overlay.color) +end + + +using Reel + +animation = roll(fps=1.0, duration=length(roadway.segments)) do t, dt + i = Int(floor(t/dt)) + 1 + renderables = [ + roadway, + LaneOverlay(roadway, roadway[LaneTag(i,1)], RGBA(0.0,0.0,1.0,0.5)) + ] + render(renderables) +end; + +write("highlighted_lanes.gif", animation) # hide +nothing # hide +``` +![highlighted lanes](highlighted_lanes.gif) + + +## Navigation in the new road network + +Let's populate the intersection + +```@example intersection +vs0 = VehicleState(B + polar(50.0,-π), roadway, 8.0) # initial state of the vehicle +scene = Scene([Vehicle(vs0, VehicleDef(), 1)]) + +snapshot = render([roadway, scene]) +write("intersection_populated.svg", snapshot) # hide +``` +![populated intersection](intersection_populated.svg) + + +We will use lateral and longitudinal acceleration to control a car in the intersection. The first step is to define a corresponding action type that will contain the acceleration inputs. + +```@example intersection +struct LaneSpecificAccelLatLon + a_lat::Float64 + a_lon::Float64 +end +``` + +Next, add a method to the propagate function to update the state using our new action type. + +```@example intersection +function AutomotiveDrivingModels.propagate(veh::Vehicle, action::LaneSpecificAccelLatLon, roadway::Roadway, Δt::Float64) + lane_tag_orig = veh.state.posF.roadind.tag + state = propagate(veh, LatLonAccel(action.a_lat, action.a_lon), roadway, Δt) + roadproj = proj(state.posG, roadway[lane_tag_orig], roadway, move_along_curves=false) + retval = VehicleState(Frenet(roadproj, roadway), roadway, state.v) + return retval +end +``` + +**Driver Model:** + +We define a driver model, +which can be seen as a distribution over actions. # TODO +Here we will define the simplest model, which is to repeat the same action. + +```@example intersection +struct InterDriver <: DriverModel{LaneSpecificAccelLatLon} + a::LaneSpecificAccelLatLon +end +AutomotiveDrivingModels.get_name(model::InterDriver) = "InterDriver" +AutomotiveDrivingModels.observe!(model::InterDriver, scene::Scene, roadway::Roadway, egoid::Int64) = model +Base.rand(::AbstractRNG, model::InterDriver) = model.a +``` + +**Simulate:** + +First associate a model to each driver in the scene using a dictionary. +Here we only have one driver identified by its ID: 1. +Then everything is ready to run the `simulate!` function. + + +```@example intersection +using Reel + +timestep = 0.1 +nticks = 100 + +vs0 = VehicleState(B + polar(50.0,-π), roadway, 8.0) +scene = Scene([Vehicle(vs0, VehicleDef(), 1)]) +models = Dict(1 => InterDriver(LaneSpecificAccelLatLon(0.0,0.0))) +scenes = simulate!(scene, roadway, models, nticks, timestep) + +animation = roll(fps=1.0/timestep, duration=nticks*timestep) do t, dt + i = Int(floor(t/dt)) + 1 + renderables = [roadway, scenes[i]] + render(renderables) +end + +write("animated_intersection.gif", animation) # hide +``` +![animated intersection](animated_intersection.gif) diff --git a/docs/src/examples/sidewalk.md b/docs/src/examples/sidewalk.md new file mode 100644 index 0000000..77a0932 --- /dev/null +++ b/docs/src/examples/sidewalk.md @@ -0,0 +1,202 @@ +# Sidewalk + +In this notebook, we will be creating a sidewalk environment in which + pedestrians can walk along the sidewalk and cross the street as cars pass. + + +```@example sidewalk +using Parameters +using AutomotiveDrivingModels +using AutoViz +AutoViz.colortheme["background"] = colorant"white"; # hide +using Cairo + +# Define sidewalk IDs +const TOP = 1 +const BOTTOM = 2 +nothing # hide +``` + +### Creating the Environment +Here, we create a new type of environment called SidewalkEnv. It consists of a roadway, crosswalk, and sidewalk. A sidewalk is a Vector of Lanes that run alongside the road. + + +```@example sidewalk +@with_kw mutable struct SidewalkEnv + roadway::Roadway + crosswalk::Lane + sidewalk::Vector{Lane} +end; +nothing # hide +``` + +#### Defining the Sidewalk +We define the sidewalk's parameters. + + +```@example sidewalk +# Geometry parameters +roadway_length = 100. +crosswalk_length = 15. +crosswalk_width = 6.0 +crosswalk_pos = roadway_length/2 +sidewalk_width = 3.0 +sidewalk_pos = crosswalk_length/2 - sidewalk_width / 2 +nothing # hide +``` + +Now we create the sidewalk environment. +Our environment will consist of: +* 1-way road with 2 lanes +* Unsignalized zebra crosswalk perpendicular to the road +* Sidewalks above and below the road + + +```@example sidewalk +# Generate straight roadway of length roadway_length with 2 lanes. +# Returns a Roadway type (Array of segments). +# There is already a method to generate a simple straight roadway, which we use here. +roadway = gen_straight_roadway(2, roadway_length) + +# Generate the crosswalk. +# Our crosswalk does not have a predefined method for generation, so we define it with a LaneTag and a curve. +n_samples = 2 # for curve generation +crosswalk = Lane(LaneTag(2,1), gen_straight_curve(VecE2(crosswalk_pos, -crosswalk_length/2), + VecE2(crosswalk_pos, crosswalk_length/2), + n_samples), width = crosswalk_width) +cw_segment = RoadSegment(2, [crosswalk]) +push!(roadway.segments, cw_segment) # Append the crosswalk to the roadway + +# Generate the sidewalk. +top_sidewalk = Lane(LaneTag(3, TOP), gen_straight_curve(VecE2(0., sidewalk_pos), + VecE2(roadway_length, sidewalk_pos), + n_samples), width = sidewalk_width) +bottom_sidewalk = Lane(LaneTag(3, BOTTOM), gen_straight_curve(VecE2(0., -(sidewalk_pos - sidewalk_width)), + VecE2(roadway_length, -(sidewalk_pos - sidewalk_width)), + n_samples), width = sidewalk_width) + # Note: we subtract the sidewalk_width from the sidewalk position so that the edge is flush with the road. + + +sw_segment = RoadSegment(3, [top_sidewalk, bottom_sidewalk]) +push!(roadway.segments, sw_segment) + +# Initialize crosswalk environment +env = SidewalkEnv(roadway, crosswalk, [top_sidewalk, bottom_sidewalk]); +nothing # hide +``` + +Since there is no defined `add_renderable!` method for the crosswalk and the sidewalk, we must define it ourselves. + + +```@example sidewalk +function AutoViz.add_renderable!(rendermodel::RenderModel, env::SidewalkEnv) + # Render sidewalk + for sw in env.sidewalk + curve = sw.curve + n = length(curve) + pts = Array{Float64}(undef, 2, n) + for (i,pt) in enumerate(curve) + pts[1,i] = pt.pos.x + pts[2,i] = pt.pos.y + end + add_instruction!(rendermodel, render_line, (pts, colorant"grey", sw.width, Cairo.CAIRO_LINE_CAP_BUTT)) + end + + # Render roadway + roadway = gen_straight_roadway(2, roadway_length) + add_renderable!(rendermodel, roadway) + + # Render crosswalk + curve = env.crosswalk.curve + n = length(curve) + pts = Array{Float64}(undef, 2, n) + for (i,pt) in enumerate(curve) + pts[1,i] = pt.pos.x + pts[2,i] = pt.pos.y + end + + # We can add render instructions from AutoViz. + # Here we want the crosswalk to appear as a white-striped zebra crossing rather than a road. + add_instruction!(rendermodel, render_dashed_line, (pts, colorant"white", env.crosswalk.width, 1.0, 1.0, 0.0, Cairo.CAIRO_LINE_CAP_BUTT)) + + return rendermodel +end +``` + + +```@example sidewalk +render([env]); +``` + +Now we can define our pedestrian. + + +```@example sidewalk +# We define its class and the dimensions of its bounding box. +const PEDESTRIAN_DEF = VehicleDef(AgentClass.PEDESTRIAN, 1.0, 1.0) +nothing # hide +``` + +We assign models to each agent in the scene. + +```@example sidewalk +timestep = 0.1 + +# Crossing pedestrian definition +ped_init_state = VehicleState(VecSE2(49.0,-3.0,0.), env.sidewalk[BOTTOM], roadway, 1.3) +ped = Entity(ped_init_state, PEDESTRIAN_DEF, :pedestrian) + +# Car definition +car_initial_state = VehicleState(VecSE2(0.0, 0., 0.), roadway.segments[1].lanes[1],roadway, 8.0) +car = Entity(car_initial_state, VehicleDef(), :car) + +scene = Frame([ped, car]) + +# Define a model for each entity present in the scene +models = Dict{Symbol, DriverModel}( + :pedestrian => SidewalkPedestrianModel( + timestep=timestep, crosswalk=env.crosswalk, + sw_origin = env.sidewalk[BOTTOM], sw_dest = env.sidewalk[TOP] + ), + :car => LatLonSeparableDriver( # produces LatLonAccels + ProportionalLaneTracker(), # lateral model + IntelligentDriverModel(), # longitudinal model + ) +) +nothing # hide +``` + + +### Simulate +Finally, we simulate and visualize the scene. + +```@example sidewalk +using Reel + +nticks = 300 +scenes = simulate(scene, roadway, models, nticks, timestep) + +animation = roll(fps=1.0/timestep, duration=nticks*timestep) do t, dt + i = Int(floor(t/dt)) + 1 + render([env, scenes[i]]) +end; +write("sidewalk_animation.gif", animation); # hide +nothing # hide +``` +![sidewalk animation](sidewalk_animation.gif) + + +We can use a slider to scroll through each frame in the simulation. This usually takes less time than rendering a video. + + +```julia +using Interact +using Reel +using Blink + +w = Window() +viz = @manipulate for i in 1 : length(scenes) + render([env, scenes[i]]) +end +body!(w, viz) +``` diff --git a/docs/src/examples/stadium.md b/docs/src/examples/stadium.md new file mode 100644 index 0000000..015011a --- /dev/null +++ b/docs/src/examples/stadium.md @@ -0,0 +1,137 @@ +# 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: + +```@example driving_in_circles +using AutomotiveDrivingModels +using AutoViz +AutoViz.colortheme["background"] = colorant"white"; # hide +using Distributions + +roadway = gen_stadium_roadway(3) +snapshot = render([roadway]) +write("stadium.svg", snapshot) # hide +``` +![three lane stadium](stadium.svg) + +As a next step, let's populate a scene with vehicles + +```@example driving_in_circles +w = DEFAULT_LANE_WIDTH +scene = Frame([ + 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) +write("stadium_with_cars.svg", snapshot) # hide +``` +![stadium with cars](stadium_with_cars.svg) + +We can assign driver models to each agent and simulate the scenario. + +```@example driving_in_circles +timestep = 0.1 +nticks = 300 + +models = Dict{Symbol, DriverModel}( + :alice => LatLonSeparableDriver( # produces LatLonAccels + ProportionalLaneTracker(), # lateral model + IntelligentDriverModel(), # longitudinal model + ), + # :bob => Tim2DDriver( + # timestep, mlane = MOBIL(timestep), + # ), + :bob => StaticDriver{AccelTurnrate, MvNormal}( + MvNormal([0.0,0.0], [1.0,0.1]) + ), + :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) +nothing # hide +``` + +An animation of the simulation can be rendered using the `Reel` package + +```@example driving_in_circles +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])..., + RenderableOverlay(IDOverlay(x_off=-2, y_off=1), scenes[i], roadway), + TextOverlay(text=[@sprintf("time: %.1fs", t)], pos=VecE2(40,40), font_size=24) + ] + render(renderables, camera=camera) +end + +write("animated_stadium.gif", animation) # hide +``` + +![animated stadium with cars](animated_stadium.gif) + +Alternatively, one can also use the `Interact` framework to inspect the simulation record interactively. + +```julia +using Interact +using Reel +using Blink + +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. We achieve this by first converting the list of scene to a `Trajdata` type and then exporting it. + + +### TODO: fix writing of Trajdata +```@example driving_in_circles +open("2Dstadium_listrec.txt", "w") do io + @warn "TODO: need to fix bug in write(trajdata)" + # write(io, MIME"text/plain"(), Trajdata(scenes, timestep)) +end +``` +The trajectory data file can be loaded in a similar way. + +```@example driving_in_circles +# listrec = open("2Dstadium_listrec.txt", "r") do io +# @warn "TODO: need to fix bug in write(trajdata)" +# read(io, MIME"text/plain"(), Trajdata) +# end + +# p = plot(listrec) +# TODO: maybe do something useful with the loaded data, like plot the speed over time or something +# write(p) # hide +``` + diff --git a/docs/src/examples/straight_roadway.md b/docs/src/examples/straight_roadway.md new file mode 100644 index 0000000..f583b3f --- /dev/null +++ b/docs/src/examples/straight_roadway.md @@ -0,0 +1,120 @@ +# Driving on a Straight Roadway + +This notebook demonstrates a simple, one-dimensional driving simulation in which +cars drive along a straight roadway. +The types are: + +- `S` - `State1D`, containing the vehicle position and speed +- `D` - `VehicleDef`, containing length, width, and class +- `I` - `Int`, a unique label for each vehicle` + +We use a `StraightRoadway` as our environment and `LaneFollowingDriver`s that produce `LaneFollowingAccel`s. + +```@example straight_roadway +using AutomotiveDrivingModels +using AutoViz +AutoViz.colortheme["background"] = colorant"white"; # hide + +roadway = StraightRoadway(200.) # 200m long straight roadway +scene = Scene1D([ + Entity(State1D(10.0, 8.0), VehicleDef(), 1), + Entity(State1D(50.0, 12.5), VehicleDef(), 2), + Entity(State1D(150.0, 6.0), VehicleDef(), 3), +]) + +camera = StaticCamera(position=VecE2(100.0,0.0), zoom=4.75, canvas_height=100) +renderables = [roadway, scene]::Vector{Any} +snapshot = render(renderables, camera=camera) +write("straight_roadway.svg", snapshot) # hide +``` +![three cars on road](straight_roadway.svg) + +In the call to the `render` function, we used the default rendering behavior for +entities. More advanced examples will show how the rendering of entities can be customized. + +We can add an overlay that displays the car id: + +```@example straight_roadway +for veh in scene + push!(renderables, + TextOverlay(text=["$(veh.id)"], coordinate_system=:scene, pos=VecE2(veh.state.s-0.7, 3)) + ) +end +snapshot = render(renderables, camera=camera) +write("straight_roadway_with_id.svg", snapshot) # hide +``` +![three cars with id](straight_roadway_with_id.svg) + + +Alternatively, we can create a new `SceneOverlay` object which takes care of +displaying information for us: + +```@example straight_roadway +using Parameters +@with_kw struct CarIDOverlay <: SceneOverlay + scene::Scene1D + roadway::StraightRoadway + textparams::TextParams=TextParams() +end +function AutoViz.add_renderable!(rendermodel::RenderModel, overlay::CarIDOverlay) + for veh in overlay.scene + x = veh.state.s - 0.7 + y = 3.0 + text = string(veh.id) + add_instruction!(rendermodel, render_text, (text, x, y, overlay.textparams.size, overlay.textparams.color), coordinate_system=:scene) + end + return rendermodel +end + +snapshot = render([roadway, scene, CarIDOverlay(scene=scene, roadway=roadway)], camera=camera) +write("straight_roadway_with_overlay.svg", snapshot) # hide +``` +![three vehicles with custom overlay](straight_roadway_with_overlay.svg) + + +To run a simulation we need driving models that produce actions. +For this we will use `LaneFollowingDriver`s that produce `LaneFollowingAccel`s. +For this demo, we will give each car a different model. + +```@example straight_roadway +models = Dict{Int, LaneFollowingDriver}( + 1 => StaticLaneFollowingDriver(0.0), # always produce zero acceleration + 2 => IntelligentDriverModel(v_des=12.0), # default IDM with a desired speed of 12 m/s + 3 => PrincetonDriver(v_des = 10.0), # default Princeton driver with a desired speed of 10m/s +) + +nticks = 100 +timestep = 0.1 +scenes = simulate(scene, roadway, models, nticks, timestep) +nothing # hide +``` +We can visualize the simulation as a sequence of images, for example using the +`Reel` package + +```@example straight_roadway +using Reel + +animation = roll(fps=1.0/timestep, duration=nticks*timestep) do t, dt + i = Int(floor(t/dt)) + 1 + renderables = [roadway, scenes[i], CarIDOverlay(scene=scenes[i], roadway=roadway)] + render(renderables, camera=camera) +end +write("straight_roadway_animated.gif", animation) # hide +nothing # hide +``` +![three vehicles animated](straight_roadway_animated.gif) + +In order to inspect the simulation interactively, we can use the `Interact` package + +```julia +using Interact +using Blink +using ElectronDisplay + +w = Window() +viz = @manipulate for step in 1 : length(scenes) + renderables = [roadway, scenes[step], CarIDOverlay(scene=scenes[step], roadway=roadway)] + render(renderables, camera=camera) +end +body!(w, viz) +``` diff --git a/docs/src/index.md b/docs/src/index.md index fdc21c6..fbaf9e7 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -14,7 +14,27 @@ See the specific section of the documentation for a more thorough explanation. This package provides a default structure for representing entity states, entities, scenes, driver models and actions. However it has been designed to support custom types. + +`AutomotiveDrivingModels` is templated to efficiently run simulations with different types of entities. +An entity represents an agent in the simulation, and it is parameterized by + +- `S`: state of the entity, may change over time +- `D`: definition of the entity, does not change over time +- `I`: unique identifier for the entity, typically an `Int64` or `Symbol` + +In addition to the state, definition and identifier for each simulation agent, +one can also customize the actions, environment and the driver models used by +the agents. + Each section of the documentation contains an interface, which is a list of functions that a user must implement to use its own types. -```@contents -``` +## Examples + +The following examples will showcase some of the simulation functionality of `AutomotiveDrivingModels` + +- [Driving on a Straight Roadway](@ref) +- [Driving in a Stadium](@ref) +- [Intersection](@ref) +- [Crosswalk](@ref) +- [Sidewalk](@ref) + diff --git a/src/AutomotiveDrivingModels.jl b/src/AutomotiveDrivingModels.jl index 6f143f1..2abef87 100644 --- a/src/AutomotiveDrivingModels.jl +++ b/src/AutomotiveDrivingModels.jl @@ -103,6 +103,13 @@ include("agent-definitions/agent_definitions.jl") ## states +export + State1D, + Vehicle1D, + Scene1D + +include("states/1d_states.jl") + export posf, posg, diff --git a/src/behaviors/MOBIL.jl b/src/behaviors/MOBIL.jl index 282404c..4af2453 100644 --- a/src/behaviors/MOBIL.jl +++ b/src/behaviors/MOBIL.jl @@ -3,11 +3,10 @@ See Treiber & Kesting, 'Modeling Lane-Changing Decisions with MOBIL' # Constructor - MOBIL(timestep::Float64;rec::SceneRecord=SceneRecord(2,timestep), mlon::LaneFollowingDriver=IntelligentDriverModel(),safe_decel::Float64=2.0, politeness::Float64=0.35,advantage_threshold::Float64=0.1) + MOBIL(timestep::Float64;mlon::LaneFollowingDriver=IntelligentDriverModel(),safe_decel::Float64=2.0, politeness::Float64=0.35,advantage_threshold::Float64=0.1) # Fields - `dir::Int` -- `rec::SceneRecord` - `mlon::LaneFollowingDriver=IntelligentDriverModel()` - `safe_decel::Float64=2.0` - `politeness::Float64=0.35` @@ -15,7 +14,6 @@ See Treiber & Kesting, 'Modeling Lane-Changing Decisions with MOBIL' """ @with_kw mutable struct MOBIL <: LaneChangeModel{LaneChangeChoice} dir::Int64 - rec::SceneRecord mlon::LaneFollowingDriver safe_decel::Float64 # safe deceleration (positive value) politeness::Float64 # politeness factor (suggested p ∈ [0.2,0.5]) @@ -24,13 +22,12 @@ end function MOBIL( timestep::Float64; - rec::SceneRecord=SceneRecord(2,timestep), mlon::LaneFollowingDriver=IntelligentDriverModel(), safe_decel::Float64=2.0, # [m/s²] politeness::Float64=0.35, advantage_threshold::Float64=0.1, ) - return MOBIL(DIR_MIDDLE, rec, mlon, safe_decel, politeness, advantage_threshold) + return MOBIL(DIR_MIDDLE, mlon, safe_decel, politeness, advantage_threshold) end """ @@ -47,16 +44,13 @@ function set_desired_speed!(model::MOBIL, v_des::Float64) end function observe!(model::MOBIL, scene::Frame{Entity{S, D, I}}, roadway::Roadway, egoid::I) where {S, D, I} - rec = model.rec - update!(rec, scene) - - vehicle_index = findfirst(egoid, rec[0]) + vehicle_index = findfirst(egoid, scene) veh_ego = scene[vehicle_index] v = vel(veh_ego.state) egostate_M = veh_ego.state - left_lane_exists = convert(Float64, get(N_LANE_LEFT, rec, roadway, vehicle_index)) > 0 - right_lane_exists = convert(Float64, get(N_LANE_RIGHT, rec, roadway, vehicle_index)) > 0 + ego_lane = get_lane(roadway, veh_ego) + fore_M = get_neighbor_fore_along_lane(scene, vehicle_index, roadway, VehicleTargetPointFront(), VehicleTargetPointRear(), VehicleTargetPointFront()) rear_M = get_neighbor_rear_along_lane(scene, vehicle_index, roadway, VehicleTargetPointFront(), VehicleTargetPointFront(), VehicleTargetPointRear()) @@ -66,7 +60,7 @@ function observe!(model::MOBIL, scene::Frame{Entity{S, D, I}}, roadway::Roadway, advantage_threshold = model.advantage_threshold - if left_lane_exists + if n_lanes_left(ego_lane, roadway) > 0 rear_L = get_neighbor_rear_along_left_lane(scene, vehicle_index, roadway, VehicleTargetPointFront(), VehicleTargetPointFront(), VehicleTargetPointRear()) @@ -130,7 +124,7 @@ function observe!(model::MOBIL, scene::Frame{Entity{S, D, I}}, roadway::Roadway, end end - if right_lane_exists + if n_lanes_right(ego_lane, roadway) > 0 rear_R = get_neighbor_rear_along_right_lane(scene, vehicle_index, roadway, VehicleTargetPointFront(), VehicleTargetPointFront(), VehicleTargetPointRear()) diff --git a/src/behaviors/lane_change_models.jl b/src/behaviors/lane_change_models.jl index 45c30a8..871f393 100644 --- a/src/behaviors/lane_change_models.jl +++ b/src/behaviors/lane_change_models.jl @@ -11,13 +11,16 @@ end Base.show(io::IO, a::LaneChangeChoice) = @printf(io, "LaneChangeChoice(%d)", a.dir) function get_lane_offset(a::LaneChangeChoice, rec::SceneRecord, roadway::Roadway, vehicle_index::Int, pastframe::Int=0) + get_lane_offset(a, rec[pastframe], roadway, vehicle_index) +end +function get_lane_offset(a::LaneChangeChoice, scene::Frame, roadway::Roadway, vehicle_index::Int) if a.dir == DIR_MIDDLE - posf(rec[pastframe][vehicle_index].state).t + posf(scene[vehicle_index].state).t elseif a.dir == DIR_LEFT - convert(Float64, get(LANEOFFSETLEFT, rec, roadway, vehicle_index, pastframe)) + convert(Float64, get(LANEOFFSETLEFT, scene, roadway, vehicle_index)) else @assert(a.dir == DIR_RIGHT) - convert(Float64, get(LANEOFFSETRIGHT, rec, roadway, vehicle_index, pastframe)) + convert(Float64, get(LANEOFFSETRIGHT, scene, roadway, vehicle_index)) end end diff --git a/src/behaviors/sidewalk_pedestrian_model.jl b/src/behaviors/sidewalk_pedestrian_model.jl index abbcbbd..21a0a00 100644 --- a/src/behaviors/sidewalk_pedestrian_model.jl +++ b/src/behaviors/sidewalk_pedestrian_model.jl @@ -104,7 +104,7 @@ function update_approaching(ped::Entity{S, D, I}, end function update_appraising(ped::Entity{S, D, I}, - scene::Scene, + scene::Frame, model::SidewalkPedestrianModel, roadway::Roadway, crosswalk::Lane, @@ -140,7 +140,7 @@ end function update_crossing(ped::Entity{S, D, I}, - scene::Scene, + scene::Frame, model::SidewalkPedestrianModel, roadway::Roadway, crosswalk::Lane @@ -158,7 +158,7 @@ end function update_leaving(ped::Entity{S, D, I}, - scene::Scene, + scene::Frame, model::SidewalkPedestrianModel, roadway::Roadway, sw_dest::Lane diff --git a/src/behaviors/tim_2d_driver.jl b/src/behaviors/tim_2d_driver.jl index aea8c28..18b6f29 100644 --- a/src/behaviors/tim_2d_driver.jl +++ b/src/behaviors/tim_2d_driver.jl @@ -3,16 +3,14 @@ Driver that combines longitudinal driver and lateral driver into one model. # Constructors - Tim2DDriver(timestep::Float64;mlon::LaneFollowingDriver=IntelligentDriverModel(), mlat::LateralDriverModel=ProportionalLaneTracker(), mlane::LaneChangeModel=TimLaneChanger(timestep),rec::SceneRecord = SceneRecord(1, timestep)) + Tim2DDriver(timestep::Float64;mlon::LaneFollowingDriver=IntelligentDriverModel(), mlat::LateralDriverModel=ProportionalLaneTracker(), mlane::LaneChangeModel=TimLaneChanger(timestep)) # Fields -- `rec::SceneRecord` A record that will hold the resulting simulation results - `mlon::LaneFollowingDriver = IntelligentDriverModel()` Longitudinal driving model - `mlat::LateralDriverModel = ProportionalLaneTracker()` Lateral driving model - `mlane::LaneChangeModel =TimLaneChanger` Lane change model """ mutable struct Tim2DDriver <: DriverModel{LatLonAccel} - rec::SceneRecord mlon::LaneFollowingDriver mlat::LateralDriverModel mlane::LaneChangeModel @@ -22,9 +20,8 @@ function Tim2DDriver( mlon::LaneFollowingDriver=IntelligentDriverModel(), mlat::LateralDriverModel=ProportionalLaneTracker(), mlane::LaneChangeModel=TimLaneChanger(timestep), - rec::SceneRecord = SceneRecord(1, timestep) ) - return Tim2DDriver(rec, mlon, mlat, mlane) + return Tim2DDriver(mlon, mlat, mlane) end get_name(::Tim2DDriver) = "Tim2DDriver" @@ -33,7 +30,7 @@ function set_desired_speed!(model::Tim2DDriver, v_des::Float64) set_desired_speed!(model.mlane, v_des) model end -function track_longitudinal!(driver::LaneFollowingDriver, scene::Frame{Entity{VehicleState, D, I}}, roadway::Roadway, vehicle_index::I, fore::NeighborLongitudinalResult) where {D, I} +function track_longitudinal!(driver::LaneFollowingDriver, scene::Frame{Entity{VehicleState, D, I}}, roadway::Roadway, vehicle_index::Int64, fore::NeighborLongitudinalResult) where {D, I} v_ego = vel(scene[vehicle_index].state) if fore.ind != nothing headway, v_oth = fore.Δs, vel(scene[fore.ind].state) @@ -44,13 +41,14 @@ function track_longitudinal!(driver::LaneFollowingDriver, scene::Frame{Entity{Ve end function observe!(driver::Tim2DDriver, scene::Frame{Entity{S, D, I}}, roadway::Roadway, egoid::I) where {S, D, I} - update!(driver.rec, scene) observe!(driver.mlane, scene, roadway, egoid) vehicle_index = findfirst(egoid, scene) + ego = scene[vehicle_index] lane_change_action = rand(driver.mlane) - laneoffset = get_lane_offset(lane_change_action, driver.rec, roadway, vehicle_index) - lateral_speed = convert(Float64, get(VELFT, driver.rec, roadway, vehicle_index)) + + laneoffset = get_lane_offset(lane_change_action, scene, roadway, vehicle_index) + lateral_speed = convert(Float64, get(VELFT, scene, roadway, vehicle_index)) if lane_change_action.dir == DIR_MIDDLE fore = get_neighbor_fore_along_lane(scene, vehicle_index, roadway, VehicleTargetPointFront(), VehicleTargetPointRear(), VehicleTargetPointFront()) diff --git a/src/deprecated.jl b/src/deprecated.jl index e3366fe..5a99feb 100644 --- a/src/deprecated.jl +++ b/src/deprecated.jl @@ -1,6 +1,6 @@ @deprecate get_vel_s velf(state).s @deprecate get_vel_t velf(state).t -@deprecate get_name nothing false +@deprecate get_name x->@sprintf("%s", typeof(x)) @deprecate propagate(veh, state, roadway, Δt) propagate(veh, state, a, roadway, Δt) diff --git a/src/feature-extraction/features.jl b/src/feature-extraction/features.jl index 9b1c0cc..2226e8f 100644 --- a/src/feature-extraction/features.jl +++ b/src/feature-extraction/features.jl @@ -10,14 +10,22 @@ end function Base.get(::Feature_Speed, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0) where {S,D,I,R} FeatureValue(vel(rec[pastframe][vehicle_index].state)) end -function Base.get(::Feature_VelFs, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0) where {S,D,I,R} - veh = rec[pastframe][vehicle_index] + +function Base.get(::Feature_VelFs, scene::Frame, roadway::R, vehicle_index::Int, pastframe::Int=0) where {R} + veh = scene[vehicle_index] FeatureValue(velf(veh.state).s) end -function Base.get(::Feature_VelFt, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0) where {S,D,I,R} - veh = rec[pastframe][vehicle_index] +function Base.get(f::Feature_VelFs, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0) where {S,D,I,R} + get(f, rec[pastframe], roadway, vehicle_index) +end + +function Base.get(::Feature_VelFt, scene::Frame, roadway::R, vehicle_index::Int, pastframe::Int=0) where {R} + veh = scene[vehicle_index] FeatureValue(velf(veh.state).t) end +function Base.get(f::Feature_VelFt, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0) where {S,D,I,R} + get(f, rec[pastframe], roadway, vehicle_index) +end generate_feature_functions("TurnRateG", :turnrateG, Float64, "rad/s") function Base.get(::Feature_TurnRateG, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0; frames_back::Int=1) where {S,D,I,R} @@ -138,8 +146,8 @@ function Base.get(::Feature_RoadEdgeDist_Right, rec::SceneRecord, roadway::Roadw FeatureValue(lane.width/2 + norm(VecE2(curvept.pos - footpoint)) + offset) end generate_feature_functions("LaneOffsetLeft", :posFtL, Float64, "m", can_be_missing=true) -function Base.get(::Feature_LaneOffsetLeft, rec::SceneRecord, roadway::Roadway, vehicle_index::Int, pastframe::Int=0) - veh_ego = rec[pastframe][vehicle_index] +function Base.get(::Feature_LaneOffsetLeft, scene::Frame, roadway::Roadway, vehicle_index::Int) + veh_ego = scene[vehicle_index] t = posf(veh_ego.state).t lane = get_lane(roadway, veh_ego) if n_lanes_left(lane, roadway) > 0 @@ -150,9 +158,12 @@ function Base.get(::Feature_LaneOffsetLeft, rec::SceneRecord, roadway::Roadway, FeatureValue(NaN, FeatureState.MISSING) end end +function Base.get(f::Feature_LaneOffsetLeft, rec::SceneRecord, roadway::Roadway, vehicle_index::Int, pastframe::Int=0) + get(f, rec[pastframe], roadway, vehicle_index) +end generate_feature_functions("LaneOffsetRight", :posFtR, Float64, "m", can_be_missing=true) -function Base.get(::Feature_LaneOffsetRight, rec::SceneRecord, roadway::Roadway, vehicle_index::Int, pastframe::Int=0) - veh_ego = rec[pastframe][vehicle_index] +function Base.get(::Feature_LaneOffsetRight, scene::Frame, roadway::Roadway, vehicle_index::Int) + veh_ego = scene[vehicle_index] t = posf(veh_ego.state).t lane = get_lane(roadway, veh_ego) if n_lanes_right(lane, roadway) > 0 @@ -163,6 +174,9 @@ function Base.get(::Feature_LaneOffsetRight, rec::SceneRecord, roadway::Roadway, FeatureValue(NaN, FeatureState.MISSING) end end +function Base.get(f::Feature_LaneOffsetRight, rec::SceneRecord, roadway::Roadway, vehicle_index::Int, pastframe::Int=0) + get(f, rec[pastframe], roadway, vehicle_index) +end generate_feature_functions("N_Lane_Right", :n_lane_right, Int, "-", lowerbound=0.0) function Base.get(::Feature_N_Lane_Right, rec::SceneRecord, roadway::Roadway, vehicle_index::Int, pastframe::Int=0) nlr = get_lane(roadway, rec[pastframe][vehicle_index]).tag.lane - 1 @@ -475,3 +489,6 @@ function Base.get(::Feature_Is_Colliding, rec::EntityQueueRecord{S,D,I}, roadway is_colliding = convert(Float64, get_first_collision(scene, vehicle_index, mem).is_colliding) FeatureValue(is_colliding) end + +# WOULD BE NICE: Base.get(scene::Frame{E}, roadway::Roadway, :n_lane_left, :ego) +# TODO: Define macro that takes care of calling generate_feature_functions diff --git a/src/feature-extraction/interface.jl b/src/feature-extraction/interface.jl index 405fee9..4a0c50e 100644 --- a/src/feature-extraction/interface.jl +++ b/src/feature-extraction/interface.jl @@ -135,4 +135,4 @@ end generate_feature_functions("JerkFt", :jerkFt, Float64, "m/s³") function Base.get(::Feature_JerkFt, rec::EntityQueueRecord{S,D,I}, roadway::R, vehicle_index::Int, pastframe::Int=0) where {S,D,I,R} _get_feature_derivative_backwards(ACCFT, rec, roadway, vehicle_index, pastframe) -end \ No newline at end of file +end diff --git a/src/simulation/simulation.jl b/src/simulation/simulation.jl index 4bd8c3e..ab1d0c3 100644 --- a/src/simulation/simulation.jl +++ b/src/simulation/simulation.jl @@ -54,7 +54,7 @@ function reset_hidden_states!(models::Dict{Int,M}) where {M<:DriverModel} end """ - DEPRECATION WARNING: this version of `simulate!` is now deprecated. +DEPRECATION 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) @@ -113,7 +113,12 @@ end """ -Simulate a scene. For detailed information, consult the documentation of `simulate!`. + simulate( + scene::Frame{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. """ function simulate( diff --git a/src/states/1d_states.jl b/src/states/1d_states.jl new file mode 100644 index 0000000..f8c9c4c --- /dev/null +++ b/src/states/1d_states.jl @@ -0,0 +1,54 @@ +""" + State1D + +A data type to represent one dimensional states + +# Fields + - `s::Float64` position + - `v::Float64` speed [m/s] +""" +struct State1D + s::Float64 # position + v::Float64 # speed [m/s] +end + +# TODO: needs more work +posf(s::State1D) = VecSE2{Float64}(s.s) +posg(s::State1D) = VecSE2{Float64}(s.s, 0., 0.) # TODO: how to derive global position & angle +vel(s::State1D) = s.v +velf(s::State1D) = (s=s.v, t=0.) +velg(s::State1D) = (x=s.v*cos(posg(s).θ), y=s.v*sin(posg(s).θ)) + + +Base.write(io::IO, ::MIME"text/plain", s::State1D) = @printf(io, "%.16e %.16e", s.s, s.v) +function Base.read(io::IO, ::MIME"text/plain", ::Type{State1D}) + i = 0 + tokens = split(strip(readline(io)), ' ') + s = parse(Float64, tokens[i+=1]) + v = parse(Float64, tokens[i+=1]) + return State1D(s,v) +end + +""" + Vehicle1D +A specific instance of the Entity type defined in Records.jl to represent vehicles in 1d environments. +""" +const Vehicle1D = Entity{State1D, VehicleDef, Int64} + +""" + Scene1D + +A specific instance of the Frame type defined in Records.jl to represent a list of vehicles in 1d environments. + +# constructors + Scene1D(n::Int=100) + Scene1D(arr::Vector{Vehicle1D}) +""" +const Scene1D = Frame{Vehicle1D} +Scene1D(n::Int=100) = Frame(Vehicle1D, n) +Scene1D(arr::Vector{Vehicle1D}) = Frame{Vehicle1D}(arr, length(arr)) + +get_center(veh::Vehicle1D) = veh.state.s +get_footpoint(veh::Vehicle1D) = veh.state.s +get_front(veh::Vehicle1D) = veh.state.s + length(veh.def)/2 +get_rear(veh::Vehicle1D) = veh.state.s - length(veh.def)/2 diff --git a/src/states/trajdatas.jl b/src/states/trajdatas.jl index 893c381..8a91a19 100644 --- a/src/states/trajdatas.jl +++ b/src/states/trajdatas.jl @@ -4,4 +4,10 @@ Trajdata is a specific instance of ListRecord defined in Records.jl. It is a col """ const Trajdata = ListRecord{VehicleState, VehicleDef, Int} Trajdata(timestep::Float64) = ListRecord(timestep, VehicleState, VehicleDef, Int) +function Trajdata(scenes::Vector{EntityFrame{S,D,I}}, timestep::Float64) where {S,D,I} + trajdata = ListRecord(timestep, S, D, I) + push!.(Ref(trajdata), scenes) + return trajdata +end + Base.show(io::IO, trajdata::Trajdata) = @printf(io, "Trajdata(%d frames)", nframes(trajdata)) diff --git a/test/test_behaviors.jl b/test/test_behaviors.jl index 72cb258..73246ee 100644 --- a/test/test_behaviors.jl +++ b/test/test_behaviors.jl @@ -11,7 +11,6 @@ struct FakeDriverModel <: DriverModel{FakeDriveAction} end @test_throws MethodError observe!(model, Scene(), roadway, 1) @test_throws MethodError prime_with_history!(model, trajdata, roadway, 1, 2, 1) - @test_throws MethodError get_name(model) @test action_type(model) <: FakeDriveAction @test_throws MethodError set_desired_speed!(model, 0.0) @test_throws ErrorException rand(model) @@ -25,7 +24,6 @@ end models = Dict{Int, DriverModel}() models[1] = IntelligentDriverModel(k_spd = 1.0, v_des = 10.0) models[2] = IntelligentDriverModel(k_spd = 1.0) - get_name(models[1]) == "IDM" set_desired_speed!(models[2], 5.0) @test models[2].v_des == 5.0 veh_state = VehicleState(Frenet(roadway[LaneTag(1,1)], 0.0), roadway, 5.) @@ -40,7 +38,8 @@ end n_steps = 40 dt = 0.1 rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) + @test_deprecated simulate!(rec, scene, roadway, models, n_steps) + simulate(scene, roadway, models, n_steps, dt) @test isapprox(get_by_id(scene, 2).state.v, models[2].v_des) @@ -53,7 +52,8 @@ end n_steps = 40 dt = 0.1 rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) + @test_deprecated simulate!(rec, scene, roadway, models, n_steps) + simulate(scene, roadway, models, n_steps, dt) prime_with_history!(IntelligentDriverModel(), rec, roadway, 2) @@ -70,7 +70,8 @@ end push!(scene, veh2) rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, 1) + @test_deprecated simulate!(rec, scene, roadway, models, 1) + simulate(scene, roadway, models, 1, dt) end struct FakeLaneChanger <: LaneChangeModel{LaneChangeChoice} end @@ -87,7 +88,6 @@ struct FakeLaneChanger <: LaneChangeModel{LaneChangeChoice} end @test_throws MethodError reset_hidden_state!(model) @test_throws MethodError observe!(model, Scene(), roadway, 1) - @test_throws MethodError get_name(model) @test_throws MethodError set_desired_speed!(model, 0.0) @test_throws ErrorException rand(model) end @@ -96,7 +96,6 @@ end timestep = 0.1 lanemodel = MOBIL(timestep) - @test get_name(lanemodel) == "MOBIL" set_desired_speed!(lanemodel,20.0) @test lanemodel.mlon.v_des == 20.0 @@ -115,19 +114,16 @@ end set_desired_speed!(models[2], 2.0) scene = Scene([veh1, veh2]) + scenes = simulate(scene, roadway, models, n_steps, dt) - rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) - - @test scene[1].state.posF.roadind.tag == LaneTag(1, 3) - @test scene[2].state.posF.roadind.tag == LaneTag(1, 1) + @test posf(last(scenes)[1]).roadind.tag == LaneTag(1, 3) + @test posf(last(scenes)[2]).roadind.tag == LaneTag(1, 1) end @testset "Tim2DDriver" begin timestep = 0.1 drivermodel = Tim2DDriver(timestep) - @test get_name(drivermodel) == "Tim2DDriver" set_desired_speed!(drivermodel,20.0) @test drivermodel.mlon.v_des == 20.0 @@ -150,7 +146,8 @@ end scene = Scene([veh1, veh2]) rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) + @test_deprecated simulate!(rec, scene, roadway, models, n_steps) + simulate(scene, roadway, models, n_steps, dt) @test scene[1].state.posF.roadind.tag == LaneTag(1, 3) @test scene[2].state.posF.roadind.tag == LaneTag(1, 2) @@ -161,17 +158,14 @@ end models = Dict{Int, DriverModel}() models[1] = StaticLaneFollowingDriver() - @test get_name(models[1]) == "ProportionalSpeedTracker" @test pdf(models[1], LaneFollowingAccel(-1.0)) ≈ 0.0 @test logpdf(models[1], LaneFollowingAccel(-1.0)) ≈ -Inf models[2] = PrincetonDriver(k = 1.0) - @test get_name(models[2]) == "PrincetonDriver" @test pdf(models[2], LaneFollowingAccel(-1.0)) == Inf @test logpdf(models[2], LaneFollowingAccel(-1.0)) == Inf set_desired_speed!(models[2], 5.0) @test models[2].v_des == 5.0 models[3] = ProportionalSpeedTracker(k = 1.0) - @test get_name(models[3]) == "ProportionalSpeedTracker" @test pdf(models[3], LaneFollowingAccel(-1.0)) == Inf @test logpdf(models[3], LaneFollowingAccel(-1.0)) == Inf set_desired_speed!(models[3], 5.0) @@ -192,7 +186,8 @@ end n_steps = 40 dt = 0.1 rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) + @test_deprecated simulate!(rec, scene, roadway, models, n_steps) + simulate(scene, roadway, models, n_steps, dt) @test isapprox(get_by_id(scene, 2).state.v, models[2].v_des, atol=1e-3) @test isapprox(get_by_id(scene, 3).state.v, models[3].v_des) @@ -212,7 +207,8 @@ end n_steps = 40 dt = 0.1 rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) + @test_deprecated simulate!(rec, scene, roadway, models, n_steps) + simulate(scene, roadway, models, n_steps, dt) @test isapprox(get_by_id(scene, 2).state.v, models[2].v_des, atol=1.0) @@ -264,7 +260,6 @@ end sw_dest = roadway[LaneTag(1,1)] ) @test ped.ttc_threshold >= 1.0 - @test get_name(ped) == "SidewalkPedestrianModel" timestep = 0.1 @@ -301,7 +296,8 @@ end nticks = 300 rec = SceneRecord(nticks+1, timestep) # Execute the simulation - simulate!(rec, scene, roadway, models, nticks) + @test_deprecated simulate!(rec, scene, roadway, models, nticks) + simulate(scene, roadway, models, nticks, timestep) ped = get_by_id(rec[0], ped_id) end diff --git a/test/test_simulation.jl b/test/test_simulation.jl index d33a6c9..2cfccec 100644 --- a/test/test_simulation.jl +++ b/test/test_simulation.jl @@ -23,10 +23,9 @@ AutomotiveDrivingModels.run_callback(callback::WithActionCallback, scenes::Vecto n_steps = 40 dt = 0.1 rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, n_steps) - - @inferred simulate(scene, roadway, models, n_steps, dt) + @test_deprecated simulate!(rec, scene, roadway, models, n_steps) @test_deprecated simulate!(scene, roadway, models, n_steps, dt) + @inferred simulate(scene, roadway, models, n_steps, dt) reset_hidden_states!(models) @@ -41,13 +40,13 @@ AutomotiveDrivingModels.run_callback(callback::WithActionCallback, scenes::Vecto push!(scene, veh2) rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, 10, (CollisionCallback(),)) + @test_deprecated simulate!(rec, scene, roadway, models, 10, (CollisionCallback(),)) scenes = @inferred simulate(scene, roadway, models, n_steps, dt, callbacks=(CollisionCallback(),)) @test length(scenes) < 10 # make sure warnings, errors and deprecations in run_callback work as expected - @test_throws MethodError simulate!(rec, scene, roadway, models, 10, (NoCallback(),)) + @test_deprecated @test_throws MethodError simulate!(rec, scene, roadway, models, 10, (NoCallback(),)) @test_deprecated simulate(scene, roadway, models, 10, .1, callbacks=(NoActionCallback(),)) @test_nowarn simulate(scene, roadway, models, 10, .1, callbacks=(WithActionCallback(),)) @@ -62,14 +61,13 @@ AutomotiveDrivingModels.run_callback(callback::WithActionCallback, scenes::Vecto push!(scene, veh2) rec = SceneRecord(n_steps, dt) - simulate!(rec, scene, roadway, models, 10, (CollisionCallback(),)) + @test_deprecated simulate!(rec, scene, roadway, models, 10, (CollisionCallback(),)) scenes = @inferred simulate(scene, roadway, models, n_steps, dt, callbacks=(CollisionCallback(),)) @test length(scenes) == 1 end - -@testset "trajdata simulation" begin +@testset "trajdata simulation" begin roadway = get_test_roadway() trajdata = get_test_trajdata(roadway) diff --git a/tutorials/.gitignore b/tutorials/.gitignore deleted file mode 100644 index 763513e..0000000 --- a/tutorials/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.ipynb_checkpoints diff --git a/tutorials/1DMobius.ipynb b/tutorials/1DMobius.ipynb deleted file mode 100644 index 7c34764..0000000 --- a/tutorials/1DMobius.ipynb +++ /dev/null @@ -1,531 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Driving on a Mobius Strip\n", - "\n", - "AutomotiveDrivingModels is templated to efficiently run different types of simulations.\n", - "Entities are parameterized by their:\n", - "\n", - "- *S* state, which changes over time\n", - "- *D* defintion, which does not change over time\n", - "- *I* id, typically an `Int`, which uniquely identifies that entity.\n", - "\n", - "In addition to these types, the actions, environment and the driver models can also be parameterized.\n", - "\n", - "This notebook demonstrates a longitudinal driving simulation where cars drive on a single straight lane that loops back on itself.\n", - "The types are:\n", - "\n", - "- *S* - `State1D`, containing the position and speed\n", - "- *D* - `VehicleDef`, containing length, width, and class\n", - "- *I* - `Int`\n", - "\n", - "We use a `StraightRoadway` as our environment and `LaneFollowingDriver`s that produce `LaneFollowingAccel`s.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "using AutomotiveDrivingModels\n", - "using AutoViz" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAABkCAYAAAAVORraAAAABmJLR0QA/wD/AP+gvaeTAAAEIklEQVR4nO3dTWtcZRgG4HtmTiafbRolbZJCCqKuCyJB/Cy4ciP+Ezd17bY7f4CLguBScOW6XSkUWkoVgyCt/TRN03xPM5mZ40LQWivEIZOhnOtancW7eN7hZh6ewznnTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIDDV7t2/caFYRcBAAAAVVd8d+nKZ8MuAgAAAKqu+P3R+rBrAAAAgMqrD7uAF8H+9lb21tzIoFrkHgAGS68FnlUMu4Bh2lt9lKkrtzP3oJ3Z7SLNsp52rZe14km6RSPd2p/rGp1uXt0ez62ZXuplmdObIymT3Du+nxvvzWbstTND3Qf8H3IPAIOl1wL9qvSA/uFXt/PJxmKSZK2+m9VGO5cm7uZ2bSPjnSIT5Uhmus2c7kxlubmelb3dvL0zl3OtubTLVh7v9rL4zcN8/cFK5pbeHPJu4GDkHgAGS68F+lXpAX2xNZaHjVbOz3+fW82tfLS5mPOrZ/+17uL0z/n2xM0kybXxR1m6cyrj5Wgmylbeai/k7g83s7x0xMVDn+QeAAZLrwX6Vel30I/1mrk8eT+/NjfTTZlOrffcdeVT1616N78U6zneG81C50RmuqM5u3PiaAqGQyD3ADBYei3Qr0oP6Mk//xihKuQeAAZLrwX6UekBfavezvs783mlfTyN1FKUz/85ak9dT/SKvN6ZyVZ9L/eKjTxu7OXq5ObRFAyHQO4BYLD0WqBflX4H/dbEk7yxfjIX75zLWn03DxvtfDn9U5ab6xkv//6Ax0JnMh9vnMlK0co7u/MZK4u008purczVkfu5tFRkftibgQOSewAYLL0W6Fft08+/qOwTOHura5m88lvmHuzn5HbjryMwNop29otaOv9xBMbCZpEytdyd3s+P785m3BEYvEDkHgAGS68F+lXpAf2g9re30mt3M/qSD3VQHXIPAIOl1wLPqvQj7gc1MnVs2CXAkZN7ABgsvRZ4VnHqZXfsAAAAYNhq167fuDDsIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg8P0BOSY325mhMHAAAAAASUVORK5CYII=", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000240bc8e0, 1000.0, 100.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "road_length = 200.0 # [meters]\n", - "roadway = StraightRoadway(road_length)\n", - "\n", - "scene = Scene1D()\n", - "push!(scene, Entity(State1D(10.0, 8.0), VehicleDef(), 1))\n", - "push!(scene, Entity(State1D(50.0, 12.5), VehicleDef(), 2))\n", - "push!(scene, Entity(State1D(150.0, 6.0), VehicleDef(), 3))\n", - "\n", - "cam = StaticCamera(VecE2(100.0,0.0), 4.75)\n", - "render(scene, roadway, cam=cam, canvas_height=100)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can add an overlay that displays the car id for convenience:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAABkCAYAAAAVORraAAAABmJLR0QA/wD/AP+gvaeTAAAEhUlEQVR4nO3dzWscZRwH8O/sTpIm6VuUtkkKKYh6LogE8bXgyYv4n3ipZ6+9+Qd4KAgeBU+e25NCoaVUsQjS2lfbNM1bs81md8eDVmusNF2y2Zb5fE5zmMNvhi/Pb55h5nkSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF5YxbALeN5VVVUVReE+UQtVVVWPjuUeAHaeXgvQp+ovw64DdsPWrMs+AOwsvRagT48GTAMndSX7ADBYei3AMzJwUkdyDwCD4ytNgD4ZPKkbmQeA3aHnAls1hl0A8PywKCIADI4JOfA0HsSfwoSFunjSQ4PsA8DOsoo7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAdhUXLl46NewiAAAAoO7K786c+2zYRQAAAEDdlb/fWxp2DQAAAFB7jWEX8CLYXFvNxqIXGdSL3APAYOm1wFblsAsYpo2Fe9l77lqmb7dzaK3MaNVIu+hlsXyYbtlMt/jzvGanm1fXxnN1qpdGVeXoykiqJDf3b+bSe4ey57VjQ70OeBZyDwCDpdcC/ar1BP3Dr67lk+W5JMliYz0LzXbOTNzItWI5450yE9VIprqjOdrZm8ujS7mzsZ63H0znRGs67aqV++u9zH1zN19/cCfT828O+Wpge+QeAAZLrwX6VesJ+lxrT+42Wzk5832ujq7mo5W5nFw4/p/zTh/4Od8evJIkuTB+L/PXj2S8GstE1cpb7dnc+OFKLs/vcvHQJ7kHgMHSa4F+1fof9H290ZydvJVfR1fSTZVO0XviedVjx61GN7+US9nfG8ts52CmumM5/uDg7hQMO0DuAWCw9FqgX7WeoCf/HhihLuQeAAZLrwX6UesJ+mqjnfcfzOSV9v40U6Ssnnw7iseOJ3plXu9MZbWxkZvlcu43N3J+cmV3CoYdIPcAMFh6LdCvWv+DfnXiYd5YOpzT109ksbGeu812vjzwUy6PLmW8+mcBj9nOZD5ePpY7ZSvvrM9kT1WmnVbWiyrnR27lzHyZmWFfDGyT3APAYOm1QL+KTz//orZf4GwsLGby3G+Zvr2Zw2vNv7fAWC7b2SyLdP5nC4zZlTJVitw4sJkf3z2UcVtg8AKRewAYLL0W6FetJ+jbtbm2ml67m7GXLNRBfcg9AAyWXgtsVetP3LdrZO++YZcAu07uAWCw9Fpgq/LIy97YAQAAwLAVFy5eOjXsIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABg5/0B2hybly78Ot8AAAAASUVORK5CYII=", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000240bba80, 1000.0, 100.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "overlays = [TextOverlay(text=[\"$(veh.id)\"], incameraframe=true, pos=VecE2(veh.state.s-0.7, 3)) for veh in scene]\n", - "render(scene, roadway, overlays, cam=cam, canvas_height=100)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or we can create a new `SceneOverlay` which does this for us:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAABkCAYAAAAVORraAAAABmJLR0QA/wD/AP+gvaeTAAAElElEQVR4nO3dzWscZRwH8O/sTpIm6VuUtkkLKYh6LogE8bXgyYv4n3ipZ6+9+Qd4KAgeBU+e60mh0FKqWARp7attmuat2Wazu+NBq2laNS7ZbMt8Pqc5zOE3y5fnN8/sM/MkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwXCqGXcCzrqqqqigKvxO1UVVV9ehY9gFg5+m1AH2o/jTsOmC3bM27/APAztJrAfrwaLA0aFJn8g8Ag6XXAps1hl3As8pyIwAAAHiGeKpJXck+AAyOVykB+mDgpK5kHwAGT78FNrPEHXiC3QsAAGD3maADjzE5B4DB8Y858G/chP8HkxXq5Gk3DfIPADvLPugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADbUVy4eOn0sIsAAACAuiu/OXvuk2EXAQAAAHVX/nZvcdg1AAAAQO01hl3A82BjdSXrCx5kUC9yDwCDpdcCW5XDLmCY1ufvZe+5a5m+3c6h1TKjVSPtopeF8mG6ZTPd4o/zmp1uXl4dz9WpXhpVlWPLI6mS3Ny/kUvvHMqeV44P9Trg/5B7ABgsvRboV60n6O9/cS0fLc0mSRYaa5lvtnN24kauFUsZ75SZqEYy1R3Nsc7eXB5dzJ31tbz5YDonW9NpV63cX+tl9qu7+fK9O5mee33IVwPbI/cAMFh6LdCvWk/QZ1t7crfZyqmZ73J1dCUfLM/m1PyJJ847c+CnfH3wSpLkwvi9zF0/kvFqLBNVK2+0j+bG91dyeW6Xi4c+yT0ADJZeC/Sr1u+g7+uN5tvJW/lldDndVOkUvaeeV206bjW6+blczP7eWI52DmaqO5YTDw7uTsGwA+QeAAZLrwX6VesJevL4wAh1IfcAMFh6LdCPWk/QVxrtvPtgJi+196eZImX19J+j2HQ80SvzamcqK4313CyXcr+5nvOTy7tTMOwAuQeAwdJrgX7V+h30qxMP89ri4Zy5fjILjbXcbbbz+YEfc3l0MePV3x/wONqZzIdLx3OnbOWttZnsqcq008paUeX8yK2cnSszM+yLgW2SewAYLL0W6Ffx8aef1XYFzvr8QibP/Zrp2xs5vNr8awuMpbKdjbJI5x+2wDi6XKZKkRsHNvLD24cybgsMniNyDwCDpdcC/ar1BH27NlZX0mt3M/aCD3VQH3IPAIOl1wJb1XqJ+3aN7N037BJg18k9AAyWXgtsVR550RM7AAAAGLbiwsVLp4ddBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsvN8BpSufnyCyQ/8AAAAASUVORK5CYII=", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000240bb1e0, 1000.0, 100.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "using Parameters\n", - "@with_kw struct CarIDOverlay <: SceneOverlay\n", - " textparams::TextParams=TextParams()\n", - "end\n", - "function AutoViz.render!(rendermodel::RenderModel, overlay::CarIDOverlay, scene::Scene1D, roadway::StraightRoadway)\n", - " for veh in scene\n", - " x = veh.state.s - 0.7\n", - " y = 3.0\n", - " text = string(veh.id)\n", - " add_instruction!(rendermodel, render_text, (text, x, y, overlay.textparams.size, overlay.textparams.color), incameraframe=true)\n", - " end\n", - " return rendermodel\n", - "end\n", - "\n", - "render(scene, roadway, [CarIDOverlay()], cam=cam, canvas_height=100)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To run a simulation we need driving models that produce actions.\n", - "For this we will use `LaneFollowingDriver`s that produce `LaneFollowingAccel`s.\n", - "We will give each car a different model, as a demonstration." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAABkCAYAAAAVORraAAAABmJLR0QA/wD/AP+gvaeTAAAHzklEQVR4nO3dy29kV50H8O+tulV22e5ud7rd7X5MJ9OTNIiXeAyKILyiRMAgYDTSbEazmP9gZljAgk1YwgoEWxY8JAQbJJiRRhppgIQNRBFpegIhr1Y/3W+33673ZeHQSSAhLNwuY38+G/uWjqXvkUo/n3Pr1vklAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwV6kYdQB2n6qqqj/8XhSF9yCwLVRVValJANuHNSPAXfbqQvt61wCjUL1s1DkA2GDNCDACii0wan+oQ+oRwPalRrNb1EYdAABGyWOTAADsah4nBbYbNQlge1KfAbaIggtsF+oRwPakPrObeMQdAADYlnTYYLexQWdLuQMKAMBfwuac3cgbni2npyWwHVkIAmwfr/ehjhoNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7TXH6zDNfGXUIAAAA2O3K/3n8qS+MOgQAAADsduW1WwujzgAAAAC7Xm3UAdi9Ordup7e2PuoYAHf0VpbTmXfjGmBbqaqsXr4y6hSwJcpRB2Dnac9dy/Sv5nL4ej8zq/WUVS2d+iDzZS/DepFBsTFuTzvZP2jk+lSV+rDK8aVG+kWVc/f088IjxzN+fHa0EwF2jM7NW5l66mJmr3Yzs1KmWdXSLYaZL9sZlPU7daneH+T+lVbO7x+mVlU5ttRIlWRuby/PfGQm4w/cO9J5AOwk/U4nxZMv5NiFdg4sJXv7jQxSZaHZTbsYpl8v7ox963wz5w7MJUkOrtQy1a/nRquX029vpv6Rd45qCrDpbNDZdP/6nVt5qL2xiL1SLqZf1fPDPWdzPkuZ7o+nNSyzv9/MoWoiv2vczq1OO/+wfCLv7RxKu1jPe1aq/PT7L+Ynn13MzKm3jHg2wE7w6Hcv5p8WTyRJ5mtruVnv5vGJy7lYLKbVLzNRNbJ/0Myx/lSeay7kemctD63O5uH12XSr9dxeG+bED2/kex+7ntkH3z/i2QDsDAd+/P957DcnkySdYpBfN69luT7Ms/XbWR12crCaSGtY5oHuvrzUWMyVznqO9ibzycVTSTXMlfZKPvXEZD53+b8y+y+fGfFsYHPYoLOpet1OTnb35MXmYr546Je52lzPv82fyn8svOtPxn714Jn8994LSZKXmkv59qVH0izG0q6t57Ptv8u1x1/MdRt0YBOcWB/Pjfp6Pn/kFznfXM6nlk7k8zff/SfjvrXvd/nR9LkkyenWrTx46XBa1VgmqvV8oHs0l395Ls89uMXhAXaow7c3fj4282R+Pnk1s4OJfO/io3lk7fhrxp1p3syXD5++c32qsy8fXJ/Nwf54Uqvy7+dO5jvraxlvTWxlfLgrfAedTdXv9bJ32Mz/TlzM1ebG98v7RfWmf3e90c7lciXTw7Gc6E9netDM2xan7nZcYJfYM2zmickrOdtcyiBV+sXwdce9ulqt1wZ5oVzI3uFYjvans38wlnevTm9NYIBdYKJX5FxjOT/bcyX9WvXGa8aieM3l882FTA0bmRlOZaY/kXf2ZrJ29vwWJIa7zwadu6N48yEAW+nNbxUC8NegKCw02bls0NlUZaORpVo3H1/9mxzptjZeq968iB7utXKsP5WFWicXyoUs1Lt5Zt/K3Y4L7BLLtW4+unokJ7t7U0+Rsnr9f3+vrlYTwzKn+vuzXOtkrlzM7XonT08ubU1ggF1grVHlvt6ePLx8NOWweOM1Y/XaW6ynOvuyUuvlRm0lN8q1nGncyMRJh3iyM/gOOpuq0RzL2eZyHmrP5geXPn7nkLivT5/JucZSpjOe8WE99/THcrKzJ59ePJH5spNPLB/PsFalW3SSqsiPWy/l2Y8ezsyoJwTsCOcn2nnfwqF869LDma+t5Ua9m2/u+22eay6kVb1ySNzR/mT+cfHeXC/X86G1IxmvynSznrWiytONK3n8wTJHRj0ZgB3i2v4qmUu+dOP96dwc5NeNq/m/iUt5YnIuq1V345C4qsz9nb355/m/zdWxjUPi/r59OP0McrNs557hZL5x39nMtt4+6unApij+80tf89Qfm6o9dy37Xm6zduhVbdYW6/30yvzZNmu92itt1lrHtFkDNkfn5nwmn7qQ2au9HFqp32mztlh20yuL9N+gzdrRpTJVilze18tvPjyTljZrAJum3+kkTz6fYxfaObhUvNJmrdFNt1alW39l7EabtY3zQw6sFJnq13OzNcjT72ik/LA2a+wcNuiMTOfW7dRa42lMtEYdBSBJ0ltZzrA7yNg9DoMD2DaqKqtzVzN5zDNM7HwecWdkxg7sH3UEgNdoTO0ZdQQA/lhR2Jyza5SHD/iUAAAAAEatOH3mma+MOgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbL7fAyGSlhHF23TAAAAAAElFTkSuQmCC", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000240bc040, 1000.0, 100.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "models = Dict{Int, LaneFollowingDriver}()\n", - "models[1] = StaticLaneFollowingDriver(0.0) # always produce zero acceleration\n", - "models[2] = IntelligentDriverModel(v_des=12.0) # default IDM with a desired speed of 12 m/s\n", - "models[3] = PrincetonDriver(v_des = 10.0) # default Princeton driver with a desired speed of 10m/s\n", - "\n", - "nticks = 100\n", - "timestep = 0.1\n", - "scenes = simulate!(scene, roadway, models, nticks, timestep)\n", - "render(last(scenes), roadway, [CarIDOverlay()], cam=cam, canvas_height=100)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can use Interact to inspect the simulation." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.webio.node+json": { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - "step" - ], - "instanceArgs": { - "namespace": "html", - "tag": "label" - }, - "nodeType": "DOM", - "props": { - "className": "interact ", - "style": { - "padding": "5px 10px 0px 10px" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-left" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "input" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}", - "orient": "horizontal", - "type": "range" - }, - "className": "slider slider is-fullwidth", - "max": 101, - "min": 1, - "step": 1, - "style": {} - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-center" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "p" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "text: formatted_val" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-right" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - ], - "instanceArgs": { - "handlers": { - "changes": [ - "(function (val){return (val!=this.model[\"changes\"]()) ? (this.valueFromJulia[\"changes\"]=true, this.model[\"changes\"](val)) : undefined})" - ], - "index": [ - "(function (val){return (val!=this.model[\"index\"]()) ? (this.valueFromJulia[\"index\"]=true, this.model[\"index\"](val)) : undefined})" - ] - }, - "id": "2014074109729369563", - "imports": { - "data": [ - { - "name": "knockout", - "type": "js", - "url": "/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js" - }, - { - "name": "knockout_punches", - "type": "js", - "url": "/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js" - }, - { - "name": null, - "type": "js", - "url": "/assetserver/7160a783468b386025b3685c9691df17912ec29b-all.js" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/c92112051a0a0326d397440da1a873f367f1d175-style.css" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/755919ab5089275528f8a583d9fba4e0adcae551-bulma_confined.min.css" - } - ], - "type": "async_block" - }, - "mount_callbacks": [ - "function () {\n var handler = (function (ko, koPunches) {\n ko.punches.enableAll();\n ko.bindingHandlers.numericValue = {\n init: function(element, valueAccessor, allBindings, data, context) {\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\n stringified.subscribe(function(value) {\n var val = parseFloat(value);\n if (!isNaN(val)) {\n valueAccessor()(val);\n }\n });\n valueAccessor().subscribe(function(value) {\n var str = JSON.stringify(value);\n if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(stringified()) >= 0))\n return;\n if ([\"null\", \"\"].indexOf(str) >= 0)\n return;\n stringified(str);\n });\n ko.applyBindingsToNode(\n element,\n {\n value: stringified,\n valueUpdate: allBindings.get('valueUpdate'),\n },\n context,\n );\n }\n };\n var json_data = {\"formatted_vals\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"29\",\"30\",\"31\",\"32\",\"33\",\"34\",\"35\",\"36\",\"37\",\"38\",\"39\",\"40\",\"41\",\"42\",\"43\",\"44\",\"45\",\"46\",\"47\",\"48\",\"49\",\"50\",\"51\",\"52\",\"53\",\"54\",\"55\",\"56\",\"57\",\"58\",\"59\",\"60\",\"61\",\"62\",\"63\",\"64\",\"65\",\"66\",\"67\",\"68\",\"69\",\"70\",\"71\",\"72\",\"73\",\"74\",\"75\",\"76\",\"77\",\"78\",\"79\",\"80\",\"81\",\"82\",\"83\",\"84\",\"85\",\"86\",\"87\",\"88\",\"89\",\"90\",\"91\",\"92\",\"93\",\"94\",\"95\",\"96\",\"97\",\"98\",\"99\",\"100\",\"101\"],\"changes\":WebIO.getval({\"name\":\"changes\",\"scope\":\"2014074109729369563\",\"id\":\"ob_10\",\"type\":\"observable\"}),\"index\":WebIO.getval({\"name\":\"index\",\"scope\":\"2014074109729369563\",\"id\":\"ob_09\",\"type\":\"observable\"})};\n var self = this;\n function AppViewModel() {\n for (var key in json_data) {\n var el = json_data[key];\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\n }\n \n [this[\"formatted_val\"]=ko.computed( function(){\n return this.formatted_vals()[parseInt(this.index())-(1)];\n }\n,this)]\n [this[\"changes\"].subscribe((function (val){!(this.valueFromJulia[\"changes\"]) ? (WebIO.setval({\"name\":\"changes\",\"scope\":\"2014074109729369563\",\"id\":\"ob_10\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"changes\"]=false}),self),this[\"index\"].subscribe((function (val){!(this.valueFromJulia[\"index\"]) ? (WebIO.setval({\"name\":\"index\",\"scope\":\"2014074109729369563\",\"id\":\"ob_09\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"index\"]=false}),self)]\n \n }\n self.model = new AppViewModel();\n self.valueFromJulia = {};\n for (var key in json_data) {\n self.valueFromJulia[key] = false;\n }\n ko.applyBindings(self.model, self.dom);\n}\n);\n (WebIO.importBlock({\"data\":[{\"name\":\"knockout\",\"type\":\"js\",\"url\":\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\"},{\"name\":\"knockout_punches\",\"type\":\"js\",\"url\":\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\"}],\"type\":\"async_block\"})).then((imports) => handler.apply(this, imports));\n}\n" - ], - "observables": { - "changes": { - "id": "ob_10", - "sync": false, - "value": 0 - }, - "index": { - "id": "ob_09", - "sync": true, - "value": 51 - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "field interact-widget" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "id": "ob_16", - "name": "obs-node" - }, - "nodeType": "ObservableNode", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "handlers": {}, - "id": "4004751049540163301", - "imports": { - "data": [], - "type": "async_block" - }, - "mount_callbacks": [], - "observables": { - "obs-node": { - "id": "ob_16", - "sync": false, - "value": { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "setInnerHtml": "" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": {}, - "type": "node" - }, - "text/html": [ - "\n", - " \n", - "\n" - ], - "text/plain": [ - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Scope(Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :label), Any[\"step\"], Dict{Symbol,Any}(:className => \"interact \",:style => Dict{Any,Any}(:padding => \"5px 10px 0px 10px\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-left\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :input), Any[], Dict{Symbol,Any}(:max => 101,:min => 1,:attributes => Dict{Any,Any}(:type => \"range\",Symbol(\"data-bind\") => \"numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}\",\"orient\" => \"horizontal\"),:step => 1,:className => \"slider slider is-fullwidth\",:style => Dict{Any,Any}()))], Dict{Symbol,Any}(:className => \"interact-flex-row-center\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :p), Any[], Dict{Symbol,Any}(:attributes => Dict(\"data-bind\" => \"text: formatted_val\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-right\"))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\")), Dict{String,Tuple{Observables.AbstractObservable,Union{Nothing, Bool}}}(\"changes\" => (Observable{Int64} with 1 listeners. Value:\n", - "0, nothing),\"index\" => (Observable{Int64} with 2 listeners. Value:\n", - "51, nothing)), Set(String[]), nothing, Asset[Asset(\"js\", \"knockout\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout.js\"), Asset(\"js\", \"knockout_punches\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout_punches.js\"), Asset(\"js\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\all.js\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\style.css\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Interact\\\\SbgIk\\\\src\\\\..\\\\assets\\\\bulma_confined.min.css\")], Dict{Any,Any}(\"changes\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"changes\\\"]()) ? (this.valueFromJulia[\\\"changes\\\"]=true, this.model[\\\"changes\\\"](val)) : undefined})\")],\"index\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"index\\\"]()) ? (this.valueFromJulia[\\\"index\\\"]=true, this.model[\\\"index\\\"](val)) : undefined})\")]), WebIO.ConnectionPool(Channel{Any}(sz_max:32,sz_curr:0), Set(AbstractConnection[]), Base.GenericCondition{Base.AlwaysLockedST}(Base.InvasiveLinkedList{Task}(Task (runnable) @0x00000000110f1cd0, Task (runnable) @0x00000000110f1cd0), Base.AlwaysLockedST(1))), WebIO.JSString[WebIO.JSString(\"function () {\\n var handler = (function (ko, koPunches) {\\n ko.punches.enableAll();\\n ko.bindingHandlers.numericValue = {\\n init: function(element, valueAccessor, allBindings, data, context) {\\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\\n stringified.subscribe(function(value) {\\n var val = parseFloat(value);\\n if (!isNaN(val)) {\\n valueAccessor()(val);\\n }\\n });\\n valueAccessor().subscribe(function(value) {\\n var str = JSON.stringify(value);\\n if ((str == \\\"0\\\") && ([\\\"-0\\\", \\\"-0.\\\"].indexOf(stringified()) >= 0))\\n return;\\n if ([\\\"null\\\", \\\"\\\"].indexOf(str) >= 0)\\n return;\\n stringified(str);\\n });\\n ko.applyBindingsToNode(\\n element,\\n {\\n value: stringified,\\n valueUpdate: allBindings.get('valueUpdate'),\\n },\\n context,\\n );\\n }\\n };\\n var json_data = {\\\"formatted_vals\\\":[\\\"1\\\",\\\"2\\\",\\\"3\\\",\\\"4\\\",\\\"5\\\",\\\"6\\\",\\\"7\\\",\\\"8\\\",\\\"9\\\",\\\"10\\\",\\\"11\\\",\\\"12\\\",\\\"13\\\",\\\"14\\\",\\\"15\\\",\\\"16\\\",\\\"17\\\",\\\"18\\\",\\\"19\\\",\\\"20\\\",\\\"21\\\",\\\"22\\\",\\\"23\\\",\\\"24\\\",\\\"25\\\",\\\"26\\\",\\\"27\\\",\\\"28\\\",\\\"29\\\",\\\"30\\\",\\\"31\\\",\\\"32\\\",\\\"33\\\",\\\"34\\\",\\\"35\\\",\\\"36\\\",\\\"37\\\",\\\"38\\\",\\\"39\\\",\\\"40\\\",\\\"41\\\",\\\"42\\\",\\\"43\\\",\\\"44\\\",\\\"45\\\",\\\"46\\\",\\\"47\\\",\\\"48\\\",\\\"49\\\",\\\"50\\\",\\\"51\\\",\\\"52\\\",\\\"53\\\",\\\"54\\\",\\\"55\\\",\\\"56\\\",\\\"57\\\",\\\"58\\\",\\\"59\\\",\\\"60\\\",\\\"61\\\",\\\"62\\\",\\\"63\\\",\\\"64\\\",\\\"65\\\",\\\"66\\\",\\\"67\\\",\\\"68\\\",\\\"69\\\",\\\"70\\\",\\\"71\\\",\\\"72\\\",\\\"73\\\",\\\"74\\\",\\\"75\\\",\\\"76\\\",\\\"77\\\",\\\"78\\\",\\\"79\\\",\\\"80\\\",\\\"81\\\",\\\"82\\\",\\\"83\\\",\\\"84\\\",\\\"85\\\",\\\"86\\\",\\\"87\\\",\\\"88\\\",\\\"89\\\",\\\"90\\\",\\\"91\\\",\\\"92\\\",\\\"93\\\",\\\"94\\\",\\\"95\\\",\\\"96\\\",\\\"97\\\",\\\"98\\\",\\\"99\\\",\\\"100\\\",\\\"101\\\"],\\\"changes\\\":WebIO.getval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"2014074109729369563\\\",\\\"id\\\":\\\"ob_10\\\",\\\"type\\\":\\\"observable\\\"}),\\\"index\\\":WebIO.getval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"2014074109729369563\\\",\\\"id\\\":\\\"ob_09\\\",\\\"type\\\":\\\"observable\\\"})};\\n var self = this;\\n function AppViewModel() {\\n for (var key in json_data) {\\n var el = json_data[key];\\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\\n }\\n \\n [this[\\\"formatted_val\\\"]=ko.computed( function(){\\n return this.formatted_vals()[parseInt(this.index())-(1)];\\n }\\n,this)]\\n [this[\\\"changes\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"changes\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"2014074109729369563\\\",\\\"id\\\":\\\"ob_10\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"changes\\\"]=false}),self),this[\\\"index\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"index\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"2014074109729369563\\\",\\\"id\\\":\\\"ob_09\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"index\\\"]=false}),self)]\\n \\n }\\n self.model = new AppViewModel();\\n self.valueFromJulia = {};\\n for (var key in json_data) {\\n self.valueFromJulia[key] = false;\\n }\\n ko.applyBindings(self.model, self.dom);\\n}\\n);\\n (WebIO.importBlock({\\\"data\\\":[{\\\"name\\\":\\\"knockout\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\\\"},{\\\"name\\\":\\\"knockout_punches\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\\\"}],\\\"type\\\":\\\"async_block\\\"})).then((imports) => handler.apply(this, imports));\\n}\\n\")])], Dict{Symbol,Any}(:className => \"field interact-widget\")), Observable{Any} with 0 listeners. Value:\n", - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000021a7900, 1000.0, 100.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\"))], Dict{Symbol,Any}())" - ] - }, - "execution_count": 7, - "metadata": { - "application/vnd.webio.node+json": { - "kernelId": "bcfeb062-fffa-4bba-a8a7-28b3fcc74d02" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "using Interact\n", - "@manipulate for step in 1 : length(scenes)\n", - " render(scenes[step], roadway, [CarIDOverlay()], cam=cam, canvas_height=100)\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "@webio": { - "lastCommId": "1221810ecf4f46b08a56bef7ff8c0926", - "lastKernelId": "bcfeb062-fffa-4bba-a8a7-28b3fcc74d02" - }, - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Julia 1.2.0", - "language": "julia", - "name": "julia-1.2" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.2.0" - }, - "widgets": { - "state": { - "6289e1b5-1d81-4a28-9336-7f36ef1e29f5": { - "views": [ - { - "cell_index": 10 - } - ] - } - }, - "version": "1.2.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/tutorials/2DStadium.ipynb b/tutorials/2DStadium.ipynb deleted file mode 100644 index 45e37fb..0000000 --- a/tutorials/2DStadium.ipynb +++ /dev/null @@ -1,583 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Driving in Circles\n", - "\n", - "AutomotiveDrivingModels is templated to efficiently run different types of simulations.\n", - "Entities are parameterized by their:\n", - "\n", - "- *S* state, which changes over time\n", - "- *D* defintion, which does not change over time\n", - "- *I* id, typically an `Int`, which uniquely identifies that entity.\n", - "\n", - "In addition to these types, the actions, environment and the driver models can also be parameterized.\n", - "\n", - "This notebook demonstrates a 2D driving simulation where cars drive in a multi-lane stadium.\n", - "The types are:\n", - "\n", - "- *S* - `VehicleState`, containing both the global and lane-relative position, and speed\n", - "- *D* - `VehicleDef`, containing length, width, and class\n", - "- *I* - `Int`\n", - "\n", - "We use a `Roadway` as our environment. The `Roadway` type is based on the RNDF format." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "┌ Info: Recompiling stale cache file C:\\Users\\Maxime\\.julia\\compiled\\v1.2\\AutomotiveDrivingModels\\ZEfHM.ji for AutomotiveDrivingModels [99497e54-f3d6-53d3-a3a9-fa9315a7f1ba]\n", - "└ @ Base loading.jl:1240\n", - "┌ Info: Recompiling stale cache file C:\\Users\\Maxime\\.julia\\compiled\\v1.2\\AutoViz\\w0rHu.ji for AutoViz [82aa6e0c-a491-5edf-8d4b-c16b98e4ea17]\n", - "└ @ Base loading.jl:1240\n" - ] - } - ], - "source": [ - "using AutomotiveDrivingModels\n", - "using AutoViz\n", - "using Distributions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We generate a 3-lane stadium roadway:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "Roadway" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "roadway = gen_stadium_roadway(3)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000015559f50, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "c = render([roadway])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's populate a scene." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000015559de0, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scene = Scene()\n", - "push!(scene,Vehicle(VehicleState(VecSE2(10.0,-DEFAULT_LANE_WIDTH,0.0), roadway, 29.0), VehicleDef(), 1))\n", - "push!(scene,Vehicle(VehicleState(VecSE2(40.0,0.0,0.0), roadway, 22.0), VehicleDef(), 2))\n", - "push!(scene,Vehicle(VehicleState(VecSE2(70.0,-DEFAULT_LANE_WIDTH,0.0), roadway, 27.0), VehicleDef(), 3))\n", - "\n", - "car_colors = get_pastel_car_colors(scene)\n", - "cam = FitToContentCamera()\n", - "render(scene, roadway, cam=cam, car_colors=car_colors)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's assign driver models." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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CzoRERERERFZprayBKKBe9CzCQu6SQZGxpFMKVbHICIiIiIimlPOWFoPSWI1BVjQAQCSKOKMpXWGZuw9chLReMKkRERERERERDTfsKADEEUBtZWlVscgIiIiIiKieYwFnYiIiIiIiCgDsKATERERERERZQAWdCIiIiIiIrJMNBa3OkLGYEEnIiIiIiKitNhtMqrKCg3NePaVXUgpqkmJ5jYWdACarqNvaMzqGERERERERHOK2+nA8sU1VsfIGizoAFRVw/Z9bVbHICIiIiIionmMBZ2IiIiIiIgoA7Cgm6QgLweyJFkdg4iIiIiIiOYo2eoA2WLdyga8vvsIgqGI1VGIiIiIiIgs1fvKc1jR14VKJYUiXcOgKKHD7kD7gnqUn32x1fEyFgs6ERERERERpUXVNERjiXf8WOSZR3D56ABWSxIkAXAKIoqhY1Uqge1HD2BvLIaci6+0KHFm4xZ3IiIiIiIiSksoEsOWHQdOfT8emsaNY4OoEARMaxqcb/24F8C4pmGxJOGannaoimJJ3kzHgk5ERERERESmiLQfQaEgwAvAK76zbvoBOFQViwQB04O9luTLdCzoREREREREZAoxlYQGwC6KcOk6UgBGAKgAHKII51ulXU/ET73GJssQrAibgfgMOhEREREREZlCXNiI0NH9OArgBUlCJwBdECDpOhYCuFRVUalp8FXVnnrNNZeejY0vbkNKUa2KnTG4gg5AEATk5XgNzXjhtT2YCkdNSkRERERERDT3ONweQNdxnyShQxCgC2+ujauCgOOCgMdFEXFBgM3usDhpZmJBByBLIi45d5WhGSlFha7rJiUiIiIiIiKae2Ljw9B0HV5Ne8+fzwEATUN0YnxWc80VLOhERERERERkCve+7XgVwLmahrL3+LZa03BQFCHsfNnqqBmJz6ATERERERGROS79c6gb7kKNrmP9e6yiv6briANwXXHd7GebA1jQiYiIiIiIyByCAAnAlPDe57JPCwK3cX8A/t4QERERERFRWgRBgE2WTn1f1zRIgoDQ+/z6aUGAoAM47fyul7bug6K+9zPr8w0LOhEREREREaUl1+vGp84/49T31VQSCV3H2Pv8+nFNgyYAqVTq1I9NTod54PZbWNABKIqKjS9utzoGERERERHRnJYMTiAgCPC8zxb3HFFEIYBUMj67weYIFnQAOoCUolgdg4iI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", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x000000002b50c620, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "timestep = 0.1\n", - "\n", - "models = Dict{Int, DriverModel}()\n", - "models[1] = LatLonSeparableDriver( # produces LatLonAccels\n", - " ProportionalLaneTracker(), # lateral model\n", - " IntelligentDriverModel(), # longitudinal model\n", - ")\n", - "models[2] = Tim2DDriver(timestep,\n", - " mlane = MOBIL(timestep),\n", - " )\n", - "models[3] = StaticDriver{AccelTurnrate, MvNormal}(MvNormal([0.0,0.0], [1.0,0.1]))\n", - "\n", - "set_desired_speed!(models[1], 12.0)\n", - "set_desired_speed!(models[2], 10.0)\n", - "set_desired_speed!(models[3], 8.0)\n", - "\n", - "nticks = 100\n", - "scenes = simulate!(scene, roadway, models, nticks, timestep)\n", - "render(last(scenes), roadway, cam=cam, car_colors=car_colors)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can use interact to inspect the simulation record. Note that the static driver just drives off the road." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.webio.node+json": { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - "step" - ], - "instanceArgs": { - "namespace": "html", - "tag": "label" - }, - "nodeType": "DOM", - "props": { - "className": "interact ", - "style": { - "padding": "5px 10px 0px 10px" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-left" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "input" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}", - "orient": "horizontal", - "type": "range" - }, - "className": "slider slider is-fullwidth", - "max": 101, - "min": 1, - "step": 1, - "style": {} - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-center" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "p" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "text: formatted_val" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-right" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - ], - "instanceArgs": { - "handlers": { - "changes": [ - "(function (val){return (val!=this.model[\"changes\"]()) ? (this.valueFromJulia[\"changes\"]=true, this.model[\"changes\"](val)) : undefined})" - ], - "index": [ - "(function (val){return (val!=this.model[\"index\"]()) ? (this.valueFromJulia[\"index\"]=true, this.model[\"index\"](val)) : undefined})" - ] - }, - "id": "5594086279636483183", - "imports": { - "data": [ - { - "name": "knockout", - "type": "js", - "url": "/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js" - }, - { - "name": "knockout_punches", - "type": "js", - "url": "/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js" - }, - { - "name": null, - "type": "js", - "url": "/assetserver/7160a783468b386025b3685c9691df17912ec29b-all.js" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/c92112051a0a0326d397440da1a873f367f1d175-style.css" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/755919ab5089275528f8a583d9fba4e0adcae551-bulma_confined.min.css" - } - ], - "type": "async_block" - }, - "mount_callbacks": [ - "function () {\n var handler = (function (ko, koPunches) {\n ko.punches.enableAll();\n ko.bindingHandlers.numericValue = {\n init: function(element, valueAccessor, allBindings, data, context) {\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\n stringified.subscribe(function(value) {\n var val = parseFloat(value);\n if (!isNaN(val)) {\n valueAccessor()(val);\n }\n });\n valueAccessor().subscribe(function(value) {\n var str = JSON.stringify(value);\n if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(stringified()) >= 0))\n return;\n if ([\"null\", \"\"].indexOf(str) >= 0)\n return;\n stringified(str);\n });\n ko.applyBindingsToNode(\n element,\n {\n value: stringified,\n valueUpdate: allBindings.get('valueUpdate'),\n },\n context,\n );\n }\n };\n var json_data = {\"formatted_vals\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"29\",\"30\",\"31\",\"32\",\"33\",\"34\",\"35\",\"36\",\"37\",\"38\",\"39\",\"40\",\"41\",\"42\",\"43\",\"44\",\"45\",\"46\",\"47\",\"48\",\"49\",\"50\",\"51\",\"52\",\"53\",\"54\",\"55\",\"56\",\"57\",\"58\",\"59\",\"60\",\"61\",\"62\",\"63\",\"64\",\"65\",\"66\",\"67\",\"68\",\"69\",\"70\",\"71\",\"72\",\"73\",\"74\",\"75\",\"76\",\"77\",\"78\",\"79\",\"80\",\"81\",\"82\",\"83\",\"84\",\"85\",\"86\",\"87\",\"88\",\"89\",\"90\",\"91\",\"92\",\"93\",\"94\",\"95\",\"96\",\"97\",\"98\",\"99\",\"100\",\"101\"],\"changes\":WebIO.getval({\"name\":\"changes\",\"scope\":\"5594086279636483183\",\"id\":\"ob_04\",\"type\":\"observable\"}),\"index\":WebIO.getval({\"name\":\"index\",\"scope\":\"5594086279636483183\",\"id\":\"ob_03\",\"type\":\"observable\"})};\n var self = this;\n function AppViewModel() {\n for (var key in json_data) {\n var el = json_data[key];\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\n }\n \n [this[\"formatted_val\"]=ko.computed( function(){\n return this.formatted_vals()[parseInt(this.index())-(1)];\n }\n,this)]\n [this[\"changes\"].subscribe((function (val){!(this.valueFromJulia[\"changes\"]) ? (WebIO.setval({\"name\":\"changes\",\"scope\":\"5594086279636483183\",\"id\":\"ob_04\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"changes\"]=false}),self),this[\"index\"].subscribe((function (val){!(this.valueFromJulia[\"index\"]) ? (WebIO.setval({\"name\":\"index\",\"scope\":\"5594086279636483183\",\"id\":\"ob_03\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"index\"]=false}),self)]\n \n }\n self.model = new AppViewModel();\n self.valueFromJulia = {};\n for (var key in json_data) {\n self.valueFromJulia[key] = false;\n }\n ko.applyBindings(self.model, self.dom);\n}\n);\n (WebIO.importBlock({\"data\":[{\"name\":\"knockout\",\"type\":\"js\",\"url\":\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\"},{\"name\":\"knockout_punches\",\"type\":\"js\",\"url\":\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\"}],\"type\":\"async_block\"})).then((imports) => handler.apply(this, imports));\n}\n" - ], - "observables": { - "changes": { - "id": "ob_04", - "sync": false, - "value": 0 - }, - "index": { - "id": "ob_03", - "sync": true, - "value": 51 - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "field interact-widget" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "id": "ob_10", - "name": "obs-node" - }, - "nodeType": "ObservableNode", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "handlers": {}, - "id": "11597674545606537677", - "imports": { - "data": [], - "type": "async_block" - }, - "mount_callbacks": [], - "observables": { - "obs-node": { - "id": "ob_10", - "sync": false, - "value": { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "setInnerHtml": "" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": {}, - "type": "node" - }, - "text/html": [ - "\n", - " \n", - "\n" - ], - "text/plain": [ - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Scope(Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :label), Any[\"step\"], Dict{Symbol,Any}(:className => \"interact \",:style => Dict{Any,Any}(:padding => \"5px 10px 0px 10px\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-left\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :input), Any[], Dict{Symbol,Any}(:max => 101,:min => 1,:attributes => Dict{Any,Any}(:type => \"range\",Symbol(\"data-bind\") => \"numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}\",\"orient\" => \"horizontal\"),:step => 1,:className => \"slider slider is-fullwidth\",:style => Dict{Any,Any}()))], Dict{Symbol,Any}(:className => \"interact-flex-row-center\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :p), Any[], Dict{Symbol,Any}(:attributes => Dict(\"data-bind\" => \"text: formatted_val\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-right\"))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\")), Dict{String,Tuple{Observables.AbstractObservable,Union{Nothing, Bool}}}(\"changes\" => (Observable{Int64} with 1 listeners. Value:\n", - "0, nothing),\"index\" => (Observable{Int64} with 2 listeners. Value:\n", - "51, nothing)), Set(String[]), nothing, Asset[Asset(\"js\", \"knockout\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout.js\"), Asset(\"js\", \"knockout_punches\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout_punches.js\"), Asset(\"js\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\all.js\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\style.css\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Interact\\\\SbgIk\\\\src\\\\..\\\\assets\\\\bulma_confined.min.css\")], Dict{Any,Any}(\"changes\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"changes\\\"]()) ? (this.valueFromJulia[\\\"changes\\\"]=true, this.model[\\\"changes\\\"](val)) : undefined})\")],\"index\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"index\\\"]()) ? (this.valueFromJulia[\\\"index\\\"]=true, this.model[\\\"index\\\"](val)) : undefined})\")]), WebIO.ConnectionPool(Channel{Any}(sz_max:32,sz_curr:0), Set(AbstractConnection[]), Base.GenericCondition{Base.AlwaysLockedST}(Base.InvasiveLinkedList{Task}(Task (runnable) @0x0000000012bd5cd0, Task (runnable) @0x0000000012bd5cd0), Base.AlwaysLockedST(1))), WebIO.JSString[WebIO.JSString(\"function () {\\n var handler = (function (ko, koPunches) {\\n ko.punches.enableAll();\\n ko.bindingHandlers.numericValue = {\\n init: function(element, valueAccessor, allBindings, data, context) {\\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\\n stringified.subscribe(function(value) {\\n var val = parseFloat(value);\\n if (!isNaN(val)) {\\n valueAccessor()(val);\\n }\\n });\\n valueAccessor().subscribe(function(value) {\\n var str = JSON.stringify(value);\\n if ((str == \\\"0\\\") && ([\\\"-0\\\", \\\"-0.\\\"].indexOf(stringified()) >= 0))\\n return;\\n if ([\\\"null\\\", \\\"\\\"].indexOf(str) >= 0)\\n return;\\n stringified(str);\\n });\\n ko.applyBindingsToNode(\\n element,\\n {\\n value: stringified,\\n valueUpdate: allBindings.get('valueUpdate'),\\n },\\n context,\\n );\\n }\\n };\\n var json_data = {\\\"formatted_vals\\\":[\\\"1\\\",\\\"2\\\",\\\"3\\\",\\\"4\\\",\\\"5\\\",\\\"6\\\",\\\"7\\\",\\\"8\\\",\\\"9\\\",\\\"10\\\",\\\"11\\\",\\\"12\\\",\\\"13\\\",\\\"14\\\",\\\"15\\\",\\\"16\\\",\\\"17\\\",\\\"18\\\",\\\"19\\\",\\\"20\\\",\\\"21\\\",\\\"22\\\",\\\"23\\\",\\\"24\\\",\\\"25\\\",\\\"26\\\",\\\"27\\\",\\\"28\\\",\\\"29\\\",\\\"30\\\",\\\"31\\\",\\\"32\\\",\\\"33\\\",\\\"34\\\",\\\"35\\\",\\\"36\\\",\\\"37\\\",\\\"38\\\",\\\"39\\\",\\\"40\\\",\\\"41\\\",\\\"42\\\",\\\"43\\\",\\\"44\\\",\\\"45\\\",\\\"46\\\",\\\"47\\\",\\\"48\\\",\\\"49\\\",\\\"50\\\",\\\"51\\\",\\\"52\\\",\\\"53\\\",\\\"54\\\",\\\"55\\\",\\\"56\\\",\\\"57\\\",\\\"58\\\",\\\"59\\\",\\\"60\\\",\\\"61\\\",\\\"62\\\",\\\"63\\\",\\\"64\\\",\\\"65\\\",\\\"66\\\",\\\"67\\\",\\\"68\\\",\\\"69\\\",\\\"70\\\",\\\"71\\\",\\\"72\\\",\\\"73\\\",\\\"74\\\",\\\"75\\\",\\\"76\\\",\\\"77\\\",\\\"78\\\",\\\"79\\\",\\\"80\\\",\\\"81\\\",\\\"82\\\",\\\"83\\\",\\\"84\\\",\\\"85\\\",\\\"86\\\",\\\"87\\\",\\\"88\\\",\\\"89\\\",\\\"90\\\",\\\"91\\\",\\\"92\\\",\\\"93\\\",\\\"94\\\",\\\"95\\\",\\\"96\\\",\\\"97\\\",\\\"98\\\",\\\"99\\\",\\\"100\\\",\\\"101\\\"],\\\"changes\\\":WebIO.getval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"5594086279636483183\\\",\\\"id\\\":\\\"ob_04\\\",\\\"type\\\":\\\"observable\\\"}),\\\"index\\\":WebIO.getval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"5594086279636483183\\\",\\\"id\\\":\\\"ob_03\\\",\\\"type\\\":\\\"observable\\\"})};\\n var self = this;\\n function AppViewModel() {\\n for (var key in json_data) {\\n var el = json_data[key];\\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\\n }\\n \\n [this[\\\"formatted_val\\\"]=ko.computed( function(){\\n return this.formatted_vals()[parseInt(this.index())-(1)];\\n }\\n,this)]\\n [this[\\\"changes\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"changes\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"5594086279636483183\\\",\\\"id\\\":\\\"ob_04\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"changes\\\"]=false}),self),this[\\\"index\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"index\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"5594086279636483183\\\",\\\"id\\\":\\\"ob_03\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"index\\\"]=false}),self)]\\n \\n }\\n self.model = new AppViewModel();\\n self.valueFromJulia = {};\\n for (var key in json_data) {\\n self.valueFromJulia[key] = false;\\n }\\n ko.applyBindings(self.model, self.dom);\\n}\\n);\\n (WebIO.importBlock({\\\"data\\\":[{\\\"name\\\":\\\"knockout\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\\\"},{\\\"name\\\":\\\"knockout_punches\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\\\"}],\\\"type\\\":\\\"async_block\\\"})).then((imports) => handler.apply(this, imports));\\n}\\n\")])], Dict{Symbol,Any}(:className => \"field interact-widget\")), Observable{Any} with 0 listeners. Value:\n", - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x000000002b50c060, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\"))], Dict{Symbol,Any}())" - ] - }, - "execution_count": 10, - "metadata": { - "application/vnd.webio.node+json": { - "kernelId": "859c74a4-c08c-4ed9-a93c-c4f85d4ad711" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "using Interact\n", - "@manipulate for step in 1 : length(scenes)\n", - " render(scenes[step], roadway, [IDOverlay()], cam=cam, car_colors=car_colors)\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The simulation results can be saved to a text file. We achieve this by first converting the list of scene to a `Trajdata` type and then exporting that." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "listrec = Trajdata(timestep)\n", - "push!.(Ref(listrec), scenes)\n", - "open(\"2Dstadium_listrec.txt\", \"w\") do io\n", - " write(io, MIME\"text/plain\"(), listrec)\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The file can be loaded in a similar way." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Trajdata(101 frames)" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "listrec2 = open(\"2Dstadium_listrec.txt\", \"r\") do io\n", - " read(io, MIME\"text/plain\"(), Trajdata)\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "@webio": { - "lastCommId": "5e74ea98c78241ac81991630bc538a49", - "lastKernelId": "859c74a4-c08c-4ed9-a93c-c4f85d4ad711" - }, - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Julia 1.2.0", - "language": "julia", - "name": "julia-1.2" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.2.0" - }, - "widgets": { - "state": { - "c2de29b4-4c20-4539-a11c-7d62a7e0fb39": { - "views": [ - { - "cell_index": 9 - } - ] - } - }, - "version": "1.2.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/tutorials/2Dstadium_listrec.txt b/tutorials/2Dstadium_listrec.txt deleted file mode 100644 index 5e18dfb..0000000 --- a/tutorials/2Dstadium_listrec.txt +++ /dev/null @@ -1,718 +0,0 @@ -Trajdata(101 frames) -1.0000000000000001e-01 -3 -2 -2 4.0000000000000000e+00 1.8000000000000000e+00 -3 -2 4.0000000000000000e+00 1.8000000000000000e+00 -1 -2 4.0000000000000000e+00 1.8000000000000000e+00 -303 -1 -1.0000000000000000e+01 -3.0000000000000000e+00 0.0000000000000000e+00 1 1.0000000000000005e-01 6 2 1.0000000000000005e+01 0.0000000000000000e+00 2.4492935982947064e-16 2.9000000000000000e+01 -2 -4.0000000000000000e+01 0.0000000000000000e+00 0.0000000000000000e+00 1 4.0000000000000008e-01 6 3 4.0000000000000007e+01 0.0000000000000000e+00 2.4492935982947064e-16 2.2000000000000000e+01 -3 -7.0000000000000000e+01 -3.0000000000000000e+00 0.0000000000000000e+00 1 6.9999999999999996e-01 6 2 7.0000000000000000e+01 0.0000000000000000e+00 2.4492935982947064e-16 2.7000000000000000e+01 -1 -1.2855000000000000e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 1.2855000000000008e-01 6 2 1.2855000000000008e+01 4.4408920985006217e-16 0.0000000000000000e+00 2.8100000000000001e+01 -2 -4.2155000000000001e+01 4.8496013246235198e-16 6.2831853071795862e+00 1 4.2155000000000009e-01 6 3 4.2155000000000008e+01 4.8496013246235198e-16 0.0000000000000000e+00 2.1100000000000001e+01 -3 -7.2703588069602873e+01 -3.0084975699863135e+00 -8.3752849445734075e-03 1 7.2703588069602876e-01 6 2 7.2703588069602873e+01 -8.4975699863134579e-03 -8.3752849445728472e-03 2.7096235515383825e+01 -1 -1.5620000000000003e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 1.5620000000000009e-01 6 2 1.5620000000000008e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.7200000000000003e+01 -2 -4.4219999999999999e+01 4.7768573047541674e-16 6.2831853071795862e+00 1 4.4220000000000004e-01 6 3 4.4220000000000006e+01 4.7768573047541674e-16 0.0000000000000000e+00 2.0200000000000003e+01 -3 -7.5414222623543907e+01 -3.0254759438595813e+00 -2.7451810542161014e-03 1 7.5414222623543903e-01 6 2 7.5414222623543907e+01 -2.5475943859581296e-02 -2.7451810542151733e-03 2.7124703016186530e+01 -1 -1.8295000000000005e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 1.8295000000000008e-01 6 2 1.8295000000000009e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.6300000000000004e+01 -2 -4.6195000000000000e+01 4.7052044451828546e-16 6.2831853071795862e+00 1 4.6195000000000008e-01 6 3 4.6195000000000007e+01 4.7052044451828546e-16 0.0000000000000000e+00 1.9300000000000004e+01 -3 -7.8121931219264013e+01 -3.0280649275121005e+00 2.0302231649272934e-03 1 7.8121931219264018e-01 6 2 7.8121931219264013e+01 -2.8064927512100546e-02 2.0302231649272037e-03 2.6997821519101478e+01 -1 -2.0880000000000006e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 2.0880000000000010e-01 6 2 2.0880000000000010e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.5400000000000006e+01 -2 -4.8079999999999998e+01 4.6346263785051117e-16 6.2831853071795862e+00 1 4.8080000000000012e-01 6 3 4.8080000000000013e+01 4.6346263785050940e-16 0.0000000000000000e+00 1.8400000000000006e+01 -3 -8.0820487161384293e+01 -3.0138295141542719e+00 1.0685459332792637e-02 1 8.0820487161384291e-01 6 2 8.0820487161384293e+01 -1.3829514154271916e-02 1.0685459332792991e-02 2.6966334429610313e+01 -1 -2.3375000000000007e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 2.3375000000000010e-01 6 2 2.3375000000000011e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.4500000000000007e+01 -2 -4.9878000000000007e+01 4.5651069828275174e-16 6.2831853071795862e+00 1 4.9878000000000017e-01 6 3 4.9878000000000014e+01 4.5651069828275174e-16 0.0000000000000000e+00 1.7560000000000006e+01 -3 -8.3521344398718398e+01 -2.9919335183295490e+00 3.8153396566864436e-03 1 8.3521344398718389e-01 6 2 8.3521344398718384e+01 8.0664816704509867e-03 3.8153396566864791e-03 2.7081468526721395e+01 -1 -2.5780000000000012e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 2.5780000000000014e-01 6 2 2.5780000000000015e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.3600000000000009e+01 -2 -5.1596200000000010e+01 4.4966303780851042e-16 6.2831853071795862e+00 1 5.1596200000000014e-01 6 3 5.1596200000000017e+01 4.4966303780851042e-16 0.0000000000000000e+00 1.6804000000000006e+01 -3 -8.6225504535627948e+01 -2.9743236936789148e+00 1.1012319329602263e-02 1 8.6225504535627950e-01 6 2 8.6225504535627948e+01 2.5676306321085196e-02 1.1012319329602139e-02 2.6976831026836052e+01 -1 -2.8095000000000010e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 2.8095000000000014e-01 6 2 2.8095000000000013e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.2700000000000010e+01 -2 -5.3242580000000011e+01 4.4291809224138275e-16 6.2831853071795862e+00 1 5.3242580000000017e-01 6 3 5.3242580000000018e+01 4.4291809224138275e-16 0.0000000000000000e+00 1.6123600000000003e+01 -3 -8.8920622068318366e+01 -2.9735330476966211e+00 -1.7586181813108732e-02 1 8.8920622068318367e-01 6 2 8.8920622068318366e+01 2.6466952303378921e-02 -1.7586181813108226e-02 2.6910715083702001e+01 -1 -3.0320000000000011e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 3.0320000000000014e-01 6 2 3.0320000000000014e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.1800000000000011e+01 -2 -5.4824322000000009e+01 4.3627432085776199e-16 6.2831853071795862e+00 1 5.4824322000000025e-01 6 3 5.4824322000000024e+01 4.3627432085776026e-16 0.0000000000000000e+00 1.5511240000000003e+01 -3 -9.1608922145313116e+01 -3.0132166026965828e+00 -1.0047198023185112e-02 1 9.1608922145313121e-01 6 2 9.1608922145313116e+01 -1.3216602696582758e-02 -1.0047198023184656e-02 2.6844779557742712e+01 -1 -3.2455000000000005e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 3.2455000000000012e-01 6 2 3.2455000000000013e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.0900000000000013e+01 -2 -5.6347889800000019e+01 4.2973020604489384e-16 6.2831853071795862e+00 1 5.6347889800000028e-01 6 3 5.6347889800000026e+01 4.2973020604489384e-16 0.0000000000000000e+00 1.4960116000000003e+01 -3 -9.4294718234947950e+01 -3.0264214121963549e+00 3.6307999552304088e-03 1 9.4294718234947961e-01 6 2 9.4294718234947965e+01 -2.6421412196354854e-02 3.6307999552305467e-03 2.6881318839056419e+01 -1 -3.4500000000000007e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 3.4500000000000014e-01 6 2 3.4500000000000014e+01 4.4408920985006262e-16 0.0000000000000000e+00 2.0000000000000014e+01 -2 -5.7819100820000017e+01 4.2328425295422046e-16 6.2831853071795862e+00 1 5.7819100820000024e-01 6 3 5.7819100820000024e+01 4.2328425295422046e-16 0.0000000000000000e+00 1.4464104400000002e+01 -3 -9.6982863187954990e+01 -3.0244437762270637e+00 -4.0894669620211788e-03 1 9.6982863187954993e-01 6 2 9.6982863187954990e+01 -2.4443776227063729e-02 -4.0894669620206159e-03 2.6881853643784765e+01 -1 -3.6455000000000005e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 3.6455000000000015e-01 6 2 3.6455000000000013e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.9100000000000016e+01 -2 -5.9243190738000024e+01 4.1693498915990716e-16 6.2831853071795862e+00 1 5.9243190738000029e-01 6 3 5.9243190738000031e+01 4.1693498915990716e-16 0.0000000000000000e+00 1.4017693960000003e+01 -3 -9.9670713559648362e+01 -3.0364379735374669e+00 -5.0838737429325324e-03 1 9.9670713559648361e-01 6 2 9.9670713559648362e+01 -3.6437973537466917e-02 -5.0838737429312886e-03 2.6873636905411331e+01 -1 -3.8320000000000007e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 3.8320000000000015e-01 6 2 3.8320000000000014e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.8200000000000017e+01 -2 -6.0624871664200022e+01 4.1068096432250853e-16 6.2831853071795862e+00 1 6.0624871664200031e-01 6 3 6.0624871664200029e+01 4.1068096432250853e-16 0.0000000000000000e+00 1.3615924564000002e+01 -3 -1.0236105022854520e+02 -3.0581898434320540e+00 -1.3081834578814630e-02 2 2.8141720236178452e-01 1 2 2.3483196736552978e+00 -1.6947958751604392e-01 -9.6950394352218083e-02 2.6955440465572579e+01 -1 -4.0095000000000006e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.0095000000000014e-01 6 2 4.0095000000000013e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.7300000000000018e+01 -2 -6.1968384497780022e+01 4.0452074985767088e-16 6.2831853071795862e+00 1 6.1968384497780027e-01 6 3 6.1968384497780029e+01 4.0452074985767088e-16 0.0000000000000000e+00 1.3254332107600002e+01 -3 -1.0505609182267564e+02 -3.0872180729419072e+00 -6.9180008563013489e-03 3 7.2555568018104377e-01 1 2 4.9948416593872409e+00 -5.5061244611515836e-01 -1.8530520297727371e-01 2.6946317109915853e+01 -1 -4.1780000000000008e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.1780000000000017e-01 6 2 4.1780000000000015e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.6400000000000020e+01 -2 -6.3277546048002023e+01 3.9845293860980582e-16 6.2831853071795862e+00 1 6.3277546048002031e-01 6 3 6.3277546048002030e+01 3.9845293860980582e-16 0.0000000000000000e+00 1.2928898896840002e+01 -3 -1.0775467026462685e+02 -3.1069144116711089e+00 -7.9322354802012409e-03 5 9.7084293881632949e-02 1 2 7.5082991192980533e+00 -1.1622893637819405e+00 -2.7608577545513135e-01 2.7053482925725788e+01 -1 -4.3382526690511092e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.3382526690511097e-01 6 2 4.3382526690511099e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.5650533810221612e+01 -2 -6.4555791443201826e+01 3.9247614453065875e-16 6.2831853071795862e+00 1 6.4555791443201826e-01 6 3 6.4555791443201826e+01 3.9247614453065875e-16 0.0000000000000000e+00 1.2636009007156002e+01 -3 -1.1046711738794100e+02 -3.1293123491660535e+00 -8.7977392706616638e-03 6 4.4463405437450287e-01 1 1 1.1046864432248753e+01 9.6996309867578812e-01 -3.6514820482707311e-01 2.7245253155910660e+01 -1 -4.4929327402482144e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.4929327402482150e-01 6 2 4.4929327402482151e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.5285480429199451e+01 -2 -6.5806212298881647e+01 3.8658900236269888e-16 6.2831853071795862e+00 1 6.5806212298881650e-01 6 3 6.5806212298881647e+01 3.8658900236269888e-16 0.0000000000000000e+00 1.2372408106440401e+01 -3 -1.1319459720232996e+02 -3.1564629963977251e+00 -1.1879568342509366e-02 7 6.9625079993463090e-01 1 1 1.3586326289786495e+01 -1.0879541488852375e-01 -4.5014815833562150e-01 2.7327670294837006e+01 -1 -4.6441448043256095e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.6441448043256112e-01 6 2 4.6441448043256109e+01 4.4408920985006089e-16 0.0000000000000000e+00 1.4956932386279506e+01 -2 -6.7031591068993478e+01 3.8079016732725838e-16 6.2831853071795862e+00 1 6.7031591068993479e-01 6 3 6.7031591068993478e+01 3.8079016732725838e-16 0.0000000000000000e+00 1.2135167295796361e+01 -3 -1.1592870132692637e+02 -3.1785402804494534e+00 -1.7359551869123397e-03 8 8.7690763753945311e-01 1 1 1.5981814378751617e+01 -1.3761706555167477e+00 -5.1727835450148074e-01 2.7365996099917410e+01 -1 -4.7922356619952659e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.7922356619952661e-01 6 2 4.7922356619952659e+01 4.4408920985006439e-16 0.0000000000000000e+00 1.4661239147651555e+01 -2 -6.8234431962094135e+01 3.7507831481734949e-16 6.2831853071795862e+00 1 6.8234431962094133e-01 6 3 6.8234431962094135e+01 3.7507831481734949e-16 0.0000000000000000e+00 1.1921650566216725e+01 -3 -1.1866670387770124e+02 -3.1602905505483707e+00 2.0660351715326087e-02 9 9.8371769104780538e-01 1 1 1.8227471385494454e+01 -2.7862672191983000e+00 -5.6732259620384973e-01 2.7406460355309846e+01 -1 -4.9375174338979548e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 4.9375174338979561e-01 6 2 4.9375174338979562e+01 4.4408920985006089e-16 0.0000000000000000e+00 1.4395115232886400e+01 -2 -6.9416988765884724e+01 3.6945214009508927e-16 6.2831853071795862e+00 1 6.9416988765884724e-01 6 3 6.9416988765884724e+01 3.6945214009508927e-16 0.0000000000000000e+00 1.1729485509595053e+01 -3 -1.2140836423305805e+02 -3.0995295313795332e+00 2.4654040615756701e-02 11 0.0000000000000000e+00 1 1 2.0289452554434082e+01 -4.3254420175877604e+00 -6.2984442888211678e-01 2.7451506818617474e+01 -1 -5.0802710286103760e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.0802710286103769e-01 6 2 5.0802710286103768e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.4155603709597761e+01 -2 -7.0581289889296258e+01 3.6391035799366291e-16 6.2831853071795862e+00 1 7.0581289889296261e-01 6 3 7.0581289889296258e+01 3.6391035799366291e-16 0.0000000000000000e+00 1.1556536958635547e+01 -3 -1.2414952334896162e+02 -3.0342720538880954e+00 2.2380533511943402e-02 11 9.3531865165257766e-01 1 1 2.2187162895032301e+01 -6.0052403115737931e+00 -6.9333439858587287e-01 2.7365790940443631e+01 -1 -5.2207492638515546e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.2207492638515551e-01 6 2 5.2207492638515554e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3940043338637985e+01 -2 -7.1729160900366637e+01 3.5845170262375795e-16 6.2831853071795862e+00 1 7.1729160900366618e-01 6 3 7.1729160900366622e+01 3.5845170262376145e-16 0.0000000000000000e+00 1.1400883262771993e+01 -3 -1.2688409909047655e+02 -2.9843346416851833e+00 1.1387563875352658e-02 12 7.4246593902178992e-01 1 1 2.3824820554184083e+01 -7.8181368770321891e+00 -7.5715503464671396e-01 2.7324870564992324e+01 -1 -5.3591796755686154e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.3591796755686161e-01 6 2 5.3591796755686161e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3746039004774186e+01 -2 -7.2862244810329955e+01 3.5307492708440504e-16 6.2831853071795862e+00 1 7.2862244810329957e-01 6 3 7.2862244810329955e+01 3.5307492708440504e-16 0.0000000000000000e+00 1.1260794936494793e+01 -3 -1.2961927182255221e+02 -2.9533830942941881e+00 1.1195874699568242e-02 13 4.2375771108411309e-01 1 1 2.5207124262682566e+01 -9.7432363424591131e+00 -8.0193716603212728e-01 2.7401158555243299e+01 -1 -5.4957670461139699e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.4957670461139707e-01 6 2 5.4957670461139706e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3571435104296768e+01 -2 -7.3982020329296958e+01 3.4777880317813897e-16 6.2831853071795862e+00 1 7.3982020329296960e-01 6 3 7.3982020329296958e+01 3.4777880317813897e-16 0.0000000000000000e+00 1.1134715442845314e+01 -3 -1.3236186462300026e+02 -2.9044293536041961e+00 2.8923074232659076e-02 14 0.0000000000000000e+00 1 1 2.6376288320764303e+01 -1.1729606784871686e+01 -8.2192493611457618e-01 2.7479758046976102e+01 -1 -5.6306956796047892e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.6306956796047902e-01 6 2 5.6306956796047899e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3414291593867091e+01 -2 -7.5089818296367270e+01 3.4256212113046687e-16 6.2831853071795862e+00 1 7.5089818296367250e-01 6 3 7.5089818296367255e+01 3.4256212113047037e-16 0.0000000000000000e+00 1.1021243898560783e+01 -3 -1.3510666466429649e+02 -2.8412586593459630e+00 1.3148791976428164e-02 14 8.6964140194483708e-01 1 1 2.8140743117177436e+01 -1.3812680805837648e+01 -8.9461711502929564e-01 2.7415164801246348e+01 -1 -5.7641314497465274e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.7641314497465279e-01 6 2 5.7641314497465281e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3272862434480382e+01 -2 -7.6186836466730526e+01 3.3742368931351332e-16 6.2831853071795862e+00 1 7.6186836466730523e-01 6 3 7.6186836466730526e+01 3.3742368931351332e-16 0.0000000000000000e+00 1.0919119508704705e+01 -3 -1.3784300528328316e+02 -2.8135539128645273e+00 5.0754977181358372e-03 15 2.2125937799776330e-01 1 1 2.8854156741418635e+01 -1.5975275127026590e+01 -9.2570375200504529e-01 2.7281067577863794e+01 -1 -5.8962236428740901e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 5.8962236428740911e-01 6 2 5.8962236428740908e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3145576191032344e+01 -2 -7.7274152820057466e+01 3.3236233397381060e-16 6.2831853071795862e+00 1 7.7274152820057485e-01 6 3 7.7274152820057481e+01 3.3236233397380710e-16 0.0000000000000000e+00 1.0827207557834235e+01 -3 -1.4057337548829878e+02 -2.7927952551277757e+00 1.1811557352988460e-02 16 0.0000000000000000e+00 1 1 3.0434178831651121e+01 -1.8176378523218808e+01 -9.6993614689382124e-01 2.7343659534469609e+01 -1 -6.0271066166888971e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.0271066166888976e-01 6 2 6.0271066166888978e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.3031018571929110e+01 -2 -7.8352737538051727e+01 3.2737689896420002e-16 6.2831853071795862e+00 1 7.8352737538051709e-01 6 3 7.8352737538051713e+01 3.2737689896420352e-16 0.0000000000000000e+00 1.0744486802050812e+01 -3 -1.4331767373191835e+02 -2.7565693023154383e+00 1.5505601457679439e-02 16 1.5677110864419602e-01 1 1 3.0752258828725363e+01 -2.0454250572094807e+01 -9.7650274785604196e-01 2.7614935321787684e+01 -1 -6.1569012931222240e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.1569012931222256e-01 6 2 6.1569012931222254e+01 4.4408920985006089e-16 0.0000000000000000e+00 1.2927916714736199e+01 -2 -7.9423463784246536e+01 3.2246624547974046e-16 6.2831853071795862e+00 1 7.9423463784246517e-01 6 3 7.9423463784246522e+01 3.2246624547974396e-16 0.0000000000000000e+00 1.0670038121845730e+01 -3 -1.4607805908535852e+02 -2.7098259166116589e+00 1.9309946418357992e-02 16 8.9490469551654472e-01 1 1 3.2249891467693438e+01 -2.2771246138894846e+01 -1.0210091331846556e+00 2.7595978566087453e+01 -1 -6.2857165019122192e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.2857165019122208e-01 6 2 6.2857165019122206e+01 4.4408920985006089e-16 0.0000000000000000e+00 1.2835125043262579e+01 -2 -8.0487117405821863e+01 3.1762925179754780e-16 6.2831853071795862e+00 1 8.0487117405821862e-01 6 3 8.0487117405821863e+01 3.1762925179754780e-16 0.0000000000000000e+00 1.0603034309661156e+01 -3 -1.4884215665702948e+02 -2.6688697861268511e+00 7.3379374321491768e-03 17 0.0000000000000000e+00 1 1 3.2463124087094528e+01 -2.5132983333670190e+01 -1.0398596137644480e+00 2.7724474643888144e+01 -1 -6.4136501898232154e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.4136501898232157e-01 6 2 6.4136501898232154e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2751612538936321e+01 -2 -8.1544405665239680e+01 3.1286481302058459e-16 6.2831853071795862e+00 1 8.1544405665239683e-01 6 3 8.1544405665239680e+01 3.1286481302058459e-16 0.0000000000000000e+00 1.0542730878695041e+01 -3 -1.5161535814399812e+02 -2.6436096741426898e+00 1.2058332462458254e-02 17 4.7625150532091365e-01 1 1 3.3429412319213178e+01 -2.7568353794832227e+01 -1.0663098068669985e+00 2.7747714025034483e+01 -1 -6.5407905089431111e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.5407905089431106e-01 6 2 6.5407905089431111e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2676451285042688e+01 -2 -8.2595965098715709e+01 3.0817184082527581e-16 6.2831853071795862e+00 1 8.2595965098715718e-01 6 3 8.2595965098715723e+01 3.0817184082527231e-16 0.0000000000000000e+00 1.0488457790825537e+01 -3 -1.5439287847224847e+02 -2.6158397766187718e+00 6.5666390192040923e-03 18 0.0000000000000000e+00 1 1 3.4492069342537938e+01 -2.9997663639358347e+01 -1.1060807591271811e+00 2.7824807825857107e+01 -1 -6.6672167961510169e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.6672167961510165e-01 6 2 6.6672167961510169e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2608806156538419e+01 -2 -8.3642368588844150e+01 3.0354926321289321e-16 6.2831853071795862e+00 1 8.3642368588844151e-01 6 3 8.3642368588844150e+01 3.0354926321289321e-16 0.0000000000000000e+00 1.0439612011742984e+01 -3 -1.5717710336242777e+02 -2.5993139855202472e+00 4.8840411279381345e-03 18 0.0000000000000000e+00 1 1 3.4492069342537938e+01 -3.2487449879157204e+01 -1.1077633570184471e+00 2.7872633414295791e+01 -1 -6.7930004546381326e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.7930004546381328e-01 6 2 6.7930004546381326e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2547925540884577e+01 -2 -8.4684131729959731e+01 2.9899602426469979e-16 6.2831853071795862e+00 1 8.4684131729959733e-01 6 3 8.4684131729959731e+01 2.9899602426469979e-16 0.0000000000000000e+00 1.0395650810568686e+01 -3 -1.5995747675506257e+02 -2.5780005963901496e+00 1.2311378226881543e-02 18 3.1517594507290786e-01 1 1 3.5131544080923504e+01 -3.5008767534165429e+01 -1.1209642372867794e+00 2.7691239605035165e+01 -1 -6.9182057472765365e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 6.9182057472765368e-01 6 2 6.9182057472765365e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2493132986796120e+01 -2 -8.5721718556963751e+01 2.9451108390072931e-16 6.2831853071795862e+00 1 8.5721718556963755e-01 6 3 8.5721718556963751e+01 2.9451108390072931e-16 0.0000000000000000e+00 1.0356085729511816e+01 -3 -1.6273102388063685e+02 -2.5232487112293871e+00 3.2096350364781631e-02 18 9.0402729021969996e-01 1 1 3.6326291223820554e+01 -3.7501940743103958e+01 -1.1397194955649139e+00 2.7824731669035415e+01 -1 -7.0428905106510996e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.0428905106510997e-01 6 2 7.0428905106510996e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2443819688116507e+01 -2 -8.6755546701267377e+01 2.9009341764221838e-16 6.2831853071795862e+00 1 8.6755546701267372e-01 6 3 8.6755546701267377e+01 2.9009341764221838e-16 0.0000000000000000e+00 1.0320477156560635e+01 -3 -1.6551328651074567e+02 -2.4335977375286943e+00 3.2402490311238333e-02 19 0.0000000000000000e+00 1 1 3.6521014597981342e+01 -4.0024767859146337e+01 -1.1456947547849339e+00 2.7857624472431510e+01 -1 -7.1671067976882071e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.1671067976882052e-01 6 2 7.1671067976882057e+01 4.4408920985006607e-16 0.0000000000000000e+00 1.2399437719304856e+01 -2 -8.7785992031140637e+01 2.8574201637758510e-16 6.2831853071795862e+00 1 8.7785992031140636e-01 6 3 8.7785992031140637e+01 2.8574201637758510e-16 0.0000000000000000e+00 1.0288429440904572e+01 -3 -1.6829722821078985e+02 -2.3384134134420922e+00 3.7135161335894687e-02 19 0.0000000000000000e+00 1 1 3.6521014597981342e+01 -4.2560369151673015e+01 -1.1409620837602770e+00 2.7852515510675687e+01 -1 -7.2909014560216022e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.2909014560216023e-01 6 2 7.2909014560216022e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2359493947374371e+01 -2 -8.8813392828026565e+01 2.8145588613192132e-16 6.2831853071795862e+00 1 8.8813392828026561e-01 6 3 8.8813392828026565e+01 2.8145588613192132e-16 0.0000000000000000e+00 1.0259586496814116e+01 -3 -1.7108482386159716e+02 -2.2212090032910332e+00 5.0149515178111073e-02 19 2.8464859515321334e-01 1 1 3.7098551014586086e+01 -4.5129494811568790e+01 -1.1465779369053104e+00 2.7981192843002802e+01 -1 -7.4143166485216582e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.4143166485216583e-01 6 2 7.4143166485216582e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2323544552636934e+01 -2 -8.9838053545223900e+01 2.7723404783994248e-16 6.2831853071795862e+00 1 8.9838053545223895e-01 6 3 8.9838053545223900e+01 2.7723404783994248e-16 0.0000000000000000e+00 1.0233627847132704e+01 -3 -1.7387773565709549e+02 -2.0852197602056330e+00 4.6155765972755294e-02 19 8.3235917858476061e-01 1 1 3.8209825804195667e+01 -4.7688693348453512e+01 -1.1864192599690400e+00 2.7930606421883056e+01 -1 -7.5373903217717086e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.5373903217717086e-01 6 2 7.5373903217717086e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2291190097373240e+01 -2 -9.0860248190701512e+01 2.7307553712234335e-16 6.2831853071795862e+00 1 9.0860248190701509e-01 6 3 9.0860248190701512e+01 2.7307553712234335e-16 0.0000000000000000e+00 1.0210265062419433e+01 -3 -1.7666281671722922e+02 -1.9687052878321316e+00 3.4556507054361349e-02 20 0.0000000000000000e+00 1 1 3.8549959853424753e+01 -5.0263137169144713e+01 -1.2089905849915983e+00 2.7783171933443427e+01 -1 -7.6601566276967546e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.6601566276967537e-01 6 2 7.6601566276967532e+01 4.4408920985006607e-16 0.0000000000000000e+00 1.2262071087635917e+01 -2 -9.1880223371631359e+01 2.6897940406550822e-16 6.2831853071795862e+00 1 9.1880223371631364e-01 6 3 9.1880223371631359e+01 2.6897940406550822e-16 0.0000000000000000e+00 1.0189238556177489e+01 -3 -1.7943996216360694e+02 -1.8518865012316186e+00 5.4506010001628011e-02 20 0.0000000000000000e+00 1 1 3.8549959853424753e+01 -5.2855349698007672e+01 -1.1890410820443318e+00 2.7818567463364928e+01 -1 -7.7826463030292942e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.7826463030292947e-01 6 2 7.7826463030292942e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2235863978872326e+01 -2 -9.2898201034468215e+01 2.6494471300452557e-16 6.2831853071795862e+00 1 9.2898201034468220e-01 6 3 9.2898201034468215e+01 2.6494471300452557e-16 0.0000000000000000e+00 1.0170314700559741e+01 -3 -1.8221551404598202e+02 -1.7047053860904720e+00 5.0429555437450410e-02 20 0.0000000000000000e+00 1 1 3.8549959853424753e+01 -5.5436293582451796e+01 -1.1931175366085087e+00 2.7754475152815360e+01 -1 -7.9048870108285811e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 7.9048870108285807e-01 6 2 7.9048870108285811e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2212277580985093e+01 -2 -9.3914380931021384e+01 2.6097054230945768e-16 6.2831853071795862e+00 1 9.3914380931021380e-01 6 3 9.3914380931021384e+01 2.6097054230945768e-16 0.0000000000000000e+00 1.0153283230503767e+01 -3 -1.8499109589548604e+02 -1.5708801269742243e+00 4.4429172154190913e-02 20 1.2775294003357529e-01 1 1 3.8809163574974825e+01 -5.8043893859437986e+01 -1.2074793302643512e+00 2.7844143846728542e+01 -1 -8.0269036478479393e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.0269036478479394e-01 6 2 8.0269036478479393e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2191049822886583e+01 -2 -9.4928942837919237e+01 2.5705598417481581e-16 6.2831853071795862e+00 1 9.4928942837919239e-01 6 3 9.4928942837919237e+01 2.5705598417481581e-16 0.0000000000000000e+00 1.0137954907453391e+01 -3 -1.8777041872503585e+02 -1.4644864238696069e+00 2.7972787984584867e-02 20 5.7565534091442316e-01 1 1 3.9717933026143733e+01 -6.0689142635227114e+01 -1.2532508580200510e+00 2.7763437752100003e+01 -1 -8.1487186211653622e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.1487186211653617e-01 6 2 8.1487186211653622e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2171944840597925e+01 -2 -9.5942048554127311e+01 2.5320014441219358e-16 6.2831853071795862e+00 1 9.5942048554127302e-01 6 3 9.5942048554127297e+01 2.5320014441219709e-16 0.0000000000000000e+00 1.0124159416708052e+01 -3 -1.9054659122649522e+02 -1.3908408286310256e+00 2.4103376878006438e-02 21 0.0000000000000000e+00 1 1 4.0578905108868163e+01 -6.3291743170829790e+01 -1.2848935621177402e+00 2.7784957871177028e+01 -1 -8.2703520971510429e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.2703520971510425e-01 6 2 8.2703520971510429e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2154750356538132e+01 -2 -9.6953843698714564e+01 2.4940214224601413e-16 6.2831853071795862e+00 1 9.6953843698714559e-01 6 3 9.6953843698714564e+01 2.4940214224601413e-16 0.0000000000000000e+00 1.0111743475037247e+01 -3 -1.9332835926491893e+02 -1.3231260748051970e+00 2.4727294780184244e-02 21 0.0000000000000000e+00 1 1 4.0578905108868163e+01 -6.5961198893964166e+01 -1.2842696442155628e+00 2.7894193590414162e+01 -1 -8.3918222255381551e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.3918222255381547e-01 6 2 8.3918222255381551e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2139275320884320e+01 -2 -9.7964459328843105e+01 2.4566111011232391e-16 6.2831853071795862e+00 1 9.7964459328843101e-01 6 3 9.7964459328843105e+01 2.4566111011232391e-16 0.0000000000000000e+00 1.0100569127533523e+01 -3 -1.9611537891874386e+02 -1.2485880105304976e+00 3.0091598558568893e-02 21 0.0000000000000000e+00 1 1 4.0578905108868163e+01 -6.8633961285349528e+01 -1.2789053404371780e+00 2.7856860266972944e+01 -1 -8.5131453410865561e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.5131453410865565e-01 6 2 8.5131453410865561e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2125347788795887e+01 -2 -9.8974013395958792e+01 2.4197619346063905e-16 6.2831853071795862e+00 1 9.8974013395958793e-01 6 3 9.8974013395958792e+01 2.4197619346063905e-16 0.0000000000000000e+00 1.0090512214780171e+01 -3 -1.9890505666908257e+02 -1.1543575270885631e+00 3.9877589379121205e-02 21 0.0000000000000000e+00 1 1 4.0578905108868163e+01 -7.1304194427681679e+01 -1.2691193496166253e+00 2.8006011811669879e+01 -1 -8.6343361450801169e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.6343361450801170e-01 6 2 8.6343361450801169e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2112813009916298e+01 -2 -9.9982612056362910e+01 2.3834655055872947e-16 6.2831853071795862e+00 1 9.9982612056362907e-01 6 3 9.9982612056362910e+01 2.3834655055872947e-16 0.0000000000000000e+00 1.0081460993302153e+01 -3 -2.0171033360521074e+02 -1.0576176730896318e+00 2.5478950443459249e-02 21 0.0000000000000000e+00 1 1 4.0578905108868163e+01 -7.3988845753545590e+01 -1.2835179885522878e+00 2.8175772510577232e+01 -1 -8.7554078686743210e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.7554078686743220e-01 6 2 8.7554078686743225e+01 4.4408920985005912e-16 0.0000000000000000e+00 1.2101531708924668e+01 -2 -1.0098964394405608e+02 3.2397588244121797e-02 3.9614034029064590e-02 1 6.0525785582747005e-01 1 3 9.9035085072660933e-01 4.2294045676938217e-16 2.1510571102112408e-16 1.0073314893971938e+01 -3 -2.0453290935227437e+02 -9.9895460187472773e-01 1.2963689645622424e-02 21 0.0000000000000000e+00 1 1 4.0578905108868163e+01 -7.6700061444216900e+01 -1.2960332493501241e+00 2.8325780946892763e+01 -1 -8.8763724199091072e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.8763724199091054e-01 6 2 8.8763724199091058e+01 4.4408920985006607e-16 0.0000000000000000e+00 1.2091378538032201e+01 -2 -1.0199434504150238e+02 8.8911611405215057e-02 7.9892630626157896e-02 2 2.2066947975372694e-01 1 3 1.9973157656539495e+00 1.3833521563638695e-17 0.0000000000000000e+00 1.0065983404574744e+01 -3 -2.0736350529863790e+02 -9.6597074893825963e-01 9.4648637760373772e-03 21 5.2417856654905580e-02 1 1 4.0685258070428645e+01 -7.9437602769750313e+01 -1.3029628159152091e+00 2.8278084225192657e+01 -1 -8.9972405160204119e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 8.9972405160204127e-01 6 2 8.9972405160204133e+01 4.4408920985005912e-16 0.0000000000000000e+00 1.2082240684228982e+01 -2 -1.0299558927625762e+02 1.8752556118952959e-01 1.2014336756354201e-01 2 8.3565543943464016e-01 1 3 3.0035841890885462e+00 3.8577697922939751e-16 1.5265566588595902e-16 1.0059385064117270e+01 -3 -2.1019461586026694e+02 -9.3461837730493846e-01 1.3752376063624040e-02 21 3.8437928724612991e-01 1 1 4.1358789640016916e+01 -8.2219379440490414e+01 -1.3204021284530505e+00 2.8370824720256351e+01 -1 -9.1180218025205889e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.1180218025205884e-01 6 2 9.1180218025205889e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2074016615806084e+01 -2 -1.0398991819066518e+02 3.3386758616292012e-01 1.6036903080718756e-01 3 4.5025830129475419e-01 1 3 4.0092257701796905e+00 -1.0959771122070199e-16 0.0000000000000000e+00 1.0053446557705543e+01 -3 -2.1302589109467991e+02 -8.7477510112165791e-01 3.3454843131059432e-02 21 7.3003699129133048e-01 1 1 4.2060110198646882e+01 -8.4955828634086402e+01 -1.3233229052123878e+00 2.8233973332571992e+01 -1 -9.2387249603707460e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.2387249603707455e-01 6 2 9.2387249603707460e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2066614954225475e+01 -2 -1.0498004670551107e+02 5.0433494281049740e-01 2.0057212772646868e-01 4 6.4516375116140626e-02 1 3 5.0143031931617141e+00 6.5277966579662378e-16 1.3877787807814457e-16 1.0048101901934988e+01 -3 -2.1584522994267758e+02 -7.8171920961898311e-01 3.2226126719560301e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -8.7649060235439705e+01 -1.3422206592259736e+00 2.8166692733701879e+01 -1 -9.3593578024358877e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.3593578024358881e-01 6 2 9.3593578024358877e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2059953458802928e+01 -2 -1.0595819938248219e+02 7.3240815871965115e-01 2.4075491495382159e-01 4 6.7846413970267649e-01 1 3 6.0188728738455346e+00 1.5094831539708478e-15 1.9428902930940239e-16 1.0043291711741489e+01 -3 -2.1866334616676951e+02 -6.8919583267379159e-01 3.3808466571875286e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -9.0394976731092356e+01 -1.3406383193736593e+00 2.8245777120713996e+01 -1 -9.4799273602945149e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.4799273602945144e-01 6 2 9.4799273602945149e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2053958112922636e+01 -2 -1.0692781282238926e+02 9.9058591244077765e-01 2.8091942345843918e-01 5 2.9213262597784923e-01 1 3 7.0229855864609778e+00 9.6003299737050631e-16 5.5511151231257827e-17 1.0038962540567340e+01 -3 -2.2148996818644858e+02 -5.7485770501689082e-01 5.1446435928601916e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -9.3144979739113936e+01 -1.3230003500169323e+00 2.8362850584360629e+01 -1 -9.6004399623672796e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.6004399623672798e-01 6 2 9.6004399623672796e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2048562301630373e+01 -2 -1.0788812379243308e+02 1.2818930604353207e+00 3.2106748111259498e-01 5 9.0554976177279112e-01 1 3 8.0266870278148748e+00 6.3209376629494958e-16 0.0000000000000000e+00 1.0035066286510606e+01 -3 -2.2432171545680652e+02 -4.2734306941535150e-01 5.3045772159811030e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -9.5893537101941433e+01 -1.3214010137857235e+00 2.8344241067769318e+01 -1 -9.7209013042327683e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.7209013042327674e-01 6 2 9.7209013042327669e+01 4.4408920985006607e-16 0.0000000000000000e+00 1.2043706071467335e+01 -2 -1.0883023006383880e+02 1.6256788226977927e+00 3.6120073300133532e-01 6 5.1874068213552493e-01 1 3 9.0300183250333799e+00 1.4540173804292596e-15 1.1102230246251565e-16 1.0031559657859546e+01 -3 -2.2715589564079283e+02 -2.8674388484109614e-01 4.3777022556802894e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -9.8645829768211925e+01 -1.3306697633887312e+00 2.8430931955281210e+01 -1 -9.8413165119117068e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.8413165119117063e-01 6 2 9.8413165119117068e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2039335464320601e+01 -2 -1.0976337785712070e+02 1.9919504570812745e+00 4.0132065970120151e-01 7 1.3172800860927608e-01 1 3 1.0033016492530038e+01 6.1320675324847512e-16 0.0000000000000000e+00 1.0028403692073592e+01 -3 -2.3000168725878268e+02 -1.7261694287632723e-01 3.3933970107338188e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -1.0141467523637264e+02 -1.3405128158381956e+00 2.8564178398157381e+01 -1 -9.9616901988227525e+01 -2.9999999999999996e+00 6.2831853071795862e+00 1 9.9616901988227524e-01 6 2 9.9616901988227525e+01 4.4408920985006262e-16 0.0000000000000000e+00 1.2035401917888541e+01 -2 -1.1067653650502125e+02 2.4056972576503375e+00 4.4142859373108118e-01 7 7.4453210058293651e-01 1 3 1.1035714843277026e+01 1.6060792619979397e-15 1.1102230246251565e-16 1.0025563322866233e+01 -3 -2.3285891972903059e+02 -8.7415945453878166e-02 2.2942745394288269e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -1.0420038489585870e+02 -1.3515040405512462e+00 2.8620129316849585e+01 -1 -1.0081967966992461e+02 -2.9731664659822425e+00 2.9295184658104868e-02 1 4.4759745092421288e-01 1 2 8.2026517042693126e-01 8.8779732611269022e-16 1.8041124150158794e-16 1.2031861726099686e+01 -2 -1.1157253781727250e+02 2.8536260405479625e+00 4.8152573435797275e-01 8 3.5717128150652089e-01 1 3 1.2038143358949318e+01 7.8718306388529965e-16 5.5511151231257827e-17 1.0023006990579610e+01 -3 -2.3572284895435158e+02 -2.4642479238333147e-02 2.0203854097059618e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -1.0699703802843210e+02 -1.3542429318484741e+00 2.8689596124902025e+01 -1 -1.0202103181229387e+02 -2.9213616787497498e+00 7.2260429800228745e-02 2 1.0405804089452689e-01 1 2 2.0232920344064080e+00 4.4293029287779049e-16 0.0000000000000000e+00 1.2028675553489718e+01 -2 -1.1245622891839328e+02 3.3259687748376279e+00 5.2161316092217525e-01 8 9.6966204248503685e-01 1 3 1.3040329023054383e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.0020706291521648e+01 -3 -2.3858793855826738e+02 3.9368678126969980e-02 2.5898517733080606e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -1.0979458778168602e+02 -1.3485482682124532e+00 2.8605558621509388e+01 -1 -1.0321775091900497e+02 -2.8034951345054431e+00 1.1521486471385467e-01 2 7.6035346273990068e-01 1 2 3.2260162119879316e+00 4.4114494562612028e-16 0.0000000000000000e+00 1.2025807998140746e+01 -2 -1.1330857359959113e+02 3.8521682802710302e+00 5.6169184482995760e-01 9 5.8201922551298779e-01 1 3 1.4042296120748942e+01 -7.5171443670115668e-16 0.0000000000000000e+00 1.0018635662369483e+01 -3 -2.4145354999817914e+02 9.9037514057303863e-02 1.2369054526679760e-02 22 0.0000000000000000e+00 1 1 4.2607850364311567e+01 -1.1259349648889061e+02 -1.3620777314188546e+00 2.8757484707256680e+01 -1 -1.0440768068555290e+02 -2.6361440155632501e+00 1.5815957042183224e-01 3 4.1650023327283137e-01 1 2 4.4284679718113029e+00 4.3854645479139973e-16 0.0000000000000000e+00 1.2023227198326671e+01 -2 -1.1414757380020276e+02 4.3983677353458539e+00 6.0176266034696169e-01 10 1.9425618838542819e-01 1 3 1.5044066508674039e+01 1.4643203278911638e-15 1.1102230246251565e-16 1.0016772096132534e+01 -3 -2.4432833801902029e+02 1.5385904547949625e-01 3.0232839624991473e-02 22 5.1490187115486421e-03 1 1 4.2618297441396550e+01 -1.1540395947769534e+02 -1.3445509488071554e+00 2.8746766353767214e+01 -1 -1.0559192190990237e+02 -2.4318176600515033e+00 2.0109551984472632e-01 4 7.2513217624560949e-02 1 2 5.6306745556523339e+00 8.7028015333799332e-16 1.1102230246251565e-16 1.2020904478494003e+01 -2 -1.1496157032758934e+02 4.9816693979081199e+00 6.4182639431226518e-01 10 8.0638495311791858e-01 1 3 1.6045659857806637e+01 -2.1343026182442803e-15 0.0000000000000000e+00 1.0015094886519281e+01 -3 -2.4720363164369755e+02 2.4151701319221297e-01 3.0884153536033632e-02 22 2.7866971201149038e-01 1 1 4.3173255954333058e+01 -1.1827471344126681e+02 -1.3618015224101940e+00 2.8798844326072270e+01 -1 -1.0676229940911873e+02 -2.1589239018904074e+00 2.4402358861104520e-01 4 7.2840579441321063e-01 1 2 6.8326604811092597e+00 2.1546624423299864e-15 2.4980018054066022e-16 1.2018814030644602e+01 -2 -1.1574816906685385e+02 5.6004150037199398e+00 6.8188375488103881e-01 11 4.1841633952444496e-01 1 3 1.7047093872025968e+01 -2.0687101309385429e-15 0.0000000000000000e+00 1.0013585397867352e+01 -3 -2.5008307035877692e+02 3.6554271093384144e-01 6.3301814135620194e-02 22 5.7021145368237269e-01 1 1 4.3764778187859903e+01 -1.2110662128006794e+02 -1.3484652241824415e+00 2.8861309209003679e+01 -1 -1.0792056116920958e+02 -1.8415803447206196e+00 2.8694456478644648e-01 5 3.8419000439509526e-01 1 2 8.0344478140205027e+00 4.2593178305396290e-16 0.0000000000000000e+00 1.2016932627580141e+01 -2 -1.1651989605277592e+02 6.2379572755285846e+00 7.2193537939293473e-01 12 3.0360085437605232e-02 1 3 1.8048384484823366e+01 -1.3332058344683706e-15 1.1102230246251565e-16 1.0012226858080616e+01 -3 -2.5296490207464208e+02 5.5036826362085711e-01 6.5288438072403587e-02 22 8.9151661960202921e-01 1 1 4.4416688779802044e+01 -1.2388045014399570e+02 -1.3675079741792748e+00 2.8904563292891226e+01 -1 -1.0906868680591893e+02 -1.4883065472868506e+00 3.2985915763002199e-01 6 3.9876684250884684e-02 1 2 9.2360564136406218e+00 -1.4705161115308122e-15 0.0000000000000000e+00 1.2015239364822127e+01 -2 -1.1725047748478150e+02 6.9222214578630075e+00 7.6198184145364101e-01 12 6.4222495490673859e-01 1 3 1.9049546036341027e+01 -1.9277093390606071e-15 0.0000000000000000e+00 1.0011004172272555e+01 -3 -2.5584788407429463e+02 7.4169195020909173e-01 6.7895720887601263e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.2668092840088094e+02 -1.3720009120077199e+00 2.8874373475181699e+01 -1 -1.1019292817886974e+02 -1.0651720567627427e+00 3.7276800547495448e-01 6 6.9547558699318812e-01 1 2 1.0437504153298725e+01 -1.6543616640391706e-15 0.0000000000000000e+00 1.2013715428339914e+01 -2 -1.1796174531092880e+02 7.6256350951184109e+00 8.0202365730827685e-01 13 2.5401883557624566e-01 1 3 2.0050591432706920e+01 0.0000000000000000e+00 1.1102230246251565e-16 1.0009903755045300e+01 -3 -2.5872833828964002e+02 9.4432135141158424e-01 7.4122007144868662e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.2951029148693686e+02 -1.3657746257504524e+00 2.8878095154635332e+01 -1 -1.1130092905401514e+02 -6.0320757874384989e-01 4.1567168282110784e-01 7 3.5099549033335076e-01 1 2 1.1638807118991011e+01 1.1172505455987457e-15 3.3306690738754696e-16 1.2012343885505922e+01 -2 -1.1864585865493082e+02 8.3560554786755414e+00 8.4206129157744902e-01 13 8.6574882632608907e-01 1 3 2.1051532289436221e+01 1.1829230614394031e-15 2.2204460492503131e-16 1.0008913379540770e+01 -3 -2.6160592983227463e+02 1.1546630625649148e+00 7.1039610285995203e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.3233580973239279e+02 -1.3688570226093262e+00 2.8810374410012045e+01 -1 -1.1239449676859986e+02 -1.0687066195263617e-01 4.5857070671835998e-01 8 6.4442942115926832e-03 1 2 1.2839979788114071e+01 2.0408192179412924e-15 2.7755575615628914e-16 1.2011109496955330e+01 -2 -1.1929148132380422e+02 9.1201062271053299e+00 8.8209516241970376e-01 14 4.7742131614823713e-01 1 3 2.2052379060492598e+01 -1.1289368085575707e-15 0.0000000000000000e+00 1.0008022041586694e+01 -3 -2.6447829063353100e+02 1.3762529810405122e+00 8.6915862146223433e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.3515467380051700e+02 -1.3529807707490979e+00 2.8807344717321740e+01 -1 -1.1345354401792811e+02 4.5920188631136405e-01 5.0146554251160114e-01 8 6.6182910857410771e-01 1 2 1.4041035190324829e+01 7.7882500554662814e-16 1.1102230246251565e-16 1.2009998547259796e+01 -2 -1.1991868228713062e+02 9.8993706099315872e+00 9.2212564617773340e-01 15 8.9042055135460346e-02 1 3 2.3053141154443338e+01 -2.1462924654066227e-15 0.0000000000000000e+00 1.0007219837428025e+01 -3 -2.6734784109382292e+02 1.6208000473937403e+00 8.1848715671609729e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.3796775506143663e+02 -1.3580479172237121e+00 2.8786553930747004e+01 -1 -1.1449348463622024e+02 1.0581571605172142e+00 5.4435660901123262e-01 9 3.1715633237246299e-01 1 2 1.5241985052314508e+01 1.1397025447318026e-15 2.2204460492503131e-16 1.2008998692533817e+01 -2 -1.2050145546615524e+02 1.0712629639395484e+01 9.6215308155996004e-01 15 7.0061621837124810e-01 1 3 2.4053827038999000e+01 -2.0312813540548223e-15 0.0000000000000000e+00 1.0006497853685222e+01 -3 -2.7021447196852523e+02 1.8497884084257605e+00 7.6146028410459421e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.4077997253278753e+02 -1.3637506044848617e+00 2.8709499581746485e+01 -1 -1.1551307121098506e+02 1.6921768354551061e+00 5.8724428314661514e-01 9 9.7243172466307504e-01 1 2 1.6442839928105219e+01 3.1423756539391600e-15 2.2204460492503131e-16 1.2008098823280434e+01 -2 -1.2105640373790628e+02 1.1544398245748873e+01 1.0021777734039639e+00 16 3.1214846343073988e-01 1 3 2.5054444335099092e+01 9.5651219023762230e-16 2.2204460492503131e-16 1.0005848068316700e+01 -3 -2.7307889276935265e+02 2.0516809029543950e+00 6.0735658086588144e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.4359353555803148e+02 -1.3791609748087330e+00 2.8725596744464497e+01 -1 -1.1649077483254187e+02 2.3887250157785482e+00 6.3012890415417366e-01 10 6.2766046859672686e-01 1 2 1.7643609316316866e+01 -1.0764077074908864e-15 0.0000000000000000e+00 1.2007288940952391e+01 -2 -1.2158467066491995e+02 1.2393920568109243e+01 1.0421999960635673e+00 16 9.2364298213157681e-01 1 3 2.6054999901589181e+01 -8.9585538598052213e-16 2.2204460492503131e-16 1.0005263261485030e+01 -3 -2.7594141719824376e+02 2.2285862724638732e+00 6.3368173116778767e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.4640847990934722e+02 -1.3765284597785428e+00 2.8603643124212823e+01 -1 -1.1744593430848198e+02 3.1148821280705299e+00 6.7301077734669079e-01 11 2.8284722900910347e-01 1 2 1.8844301765707343e+01 -1.3890195048919915e-15 0.0000000000000000e+00 1.2006560046857151e+01 -2 -1.2206329809081038e+02 1.3272038164303856e+01 1.0822199964572106e+00 17 5.3510354710961239e-01 1 3 2.7055499911430253e+01 8.3376729721629173e-16 4.4408920985006262e-16 1.0004736935336528e+01 -3 -2.7879997497665994e+02 2.4138337008716455e+00 6.6954175399697488e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.4921840268824945e+02 -1.3729424574956237e+00 2.8715404465228204e+01 -1 -1.1837386295239151e+02 3.8764134855294863e+00 7.1589017750567030e-01 11 9.3799620425233354e-01 1 2 2.0044924970158768e+01 6.7013890102707410e-16 0.0000000000000000e+00 1.2005904042171437e+01 -2 -1.2252075356474546e+02 1.4161137000893765e+01 1.1222379968114891e+00 18 1.4653355373713303e-01 1 3 2.8055949920287222e+01 0.0000000000000000e+00 2.2204460492503131e-16 1.0004263241802875e+01 -3 -2.8166839148316035e+02 2.5972581809287640e+00 5.8705552525783397e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.5203833779495730e+02 -1.3811910803695380e+00 2.8788534332265186e+01 -1 -1.1925485457592903e+02 4.6913718058844136e+00 7.5876735193446621e-01 12 5.9311117284333825e-01 1 2 2.1245485854165057e+01 -6.4453745234065609e-16 0.0000000000000000e+00 1.2005313637954293e+01 -2 -1.2293355405555411e+02 1.5072207098646926e+01 1.1622541971303402e+00 18 7.5793605784919171e-01 1 3 2.9056354928258497e+01 0.0000000000000000e+00 2.2204460492503131e-16 1.0003836917622587e+01 -3 -2.8454130274688606e+02 2.7801089035840065e+00 7.1653044180604059e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.5486280409598822e+02 -1.3682435887147175e+00 2.8785593104078416e+01 -1 -1.2010986092078255e+02 5.5329237662135107e+00 8.0164252320609697e-01 13 2.4819553544733425e-01 1 2 2.2445990649770710e+01 1.8532575368575447e-15 1.1102230246251565e-16 1.2004782274158863e+01 -2 -1.2330981090747947e+02 1.5998370260788223e+01 1.2022687774173060e+00 19 3.6931380969733235e-01 1 3 3.0056719435432644e+01 0.0000000000000000e+00 2.2204460492503131e-16 1.0003453225860328e+01 -3 -2.8740989775932684e+02 2.9944804758922174e+00 7.9492854746629565e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.5767887677538155e+02 -1.3604037781486920e+00 2.8733366565873879e+01 -1 -1.2093033578795381e+02 6.4089358663026568e+00 8.4451589163627860e-01 13 9.0325235266302450e-01 1 2 2.3646444965815800e+01 2.3593333642951199e-15 1.1102230246251565e-16 1.2004304046742977e+01 -2 -1.2366211362407225e+02 1.6934416124848990e+01 1.2422818996755751e+00 19 9.8066928450794710e-01 1 3 3.1057047491889374e+01 0.0000000000000000e+00 2.2204460492503131e-16 1.0003107903274294e+01 -3 -2.9027056380144359e+02 3.2227201852295444e+00 7.9823763796440544e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.6048527816277155e+02 -1.3600728690988806e+00 2.8637901626942735e+01 -1 -1.2170045260225861e+02 7.3290504093704181e+00 8.8738763750915650e-01 14 5.5828437902924133e-01 1 2 2.4846853850256384e+01 -5.6083126557055386e-16 0.0000000000000000e+00 1.2003873642068680e+01 -2 -1.2395439178666436e+02 1.7890802959921107e+01 1.2822937097080176e+00 20 5.9200470998478538e-01 1 3 3.2057342742700428e+01 0.0000000000000000e+00 4.4408920985006262e-16 1.0002797112946865e+01 -3 -2.9312419977481738e+02 3.4647310022819924e+00 9.2574605619594880e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.6328291213437853e+02 -1.3473220272757267e+00 2.8640776957055920e+01 -1 -1.2244153284750938e+02 8.2723502900098609e+00 9.3025792308046096e-01 15 2.1329409363093191e-01 1 2 2.6047221846252913e+01 -2.1231983500052489e-15 0.0000000000000000e+00 1.2003486277861812e+01 -2 -1.2422367703928970e+02 1.8853460303401661e+01 1.3223043387372158e+00 21 2.0332209106122576e-01 1 3 3.3057608468430381e+01 0.0000000000000000e+00 6.6613381477509392e-16 1.0002517401652179e+01 -3 -2.9597544813425748e+02 3.7197244917221242e+00 8.3559628388347990e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.6607648433962842e+02 -1.3563370045069734e+00 2.8602359908085006e+01 -1 -1.2314057421303961e+02 9.2478613858323175e+00 9.7312689438034949e-01 15 8.6828372764454553e-01 1 2 2.7247553042649781e+01 0.0000000000000000e+00 1.1102230246251565e-16 1.2003137650075631e+01 -2 -1.2445076707069843e+02 1.9827396332016228e+01 1.3623139048634938e+00 21 8.1462323217731081e-01 1 3 3.4057847621587335e+01 0.0000000000000000e+00 6.6613381477509392e-16 1.0002265661486961e+01 -3 -2.9882381857316386e+02 3.9670212843587640e+00 9.1677843471182491e-02 23 0.0000000000000000e+00 1 1 4.4636795619754970e+01 -1.6886820786588009e+02 -1.3482187894241386e+00 2.8571876268769145e+01 -1 -1.2378743116303347e+02 1.0258201189128831e+01 1.0159946828359629e+00 16 5.2325528912889352e-01 1 2 2.8447851119406966e+01 -9.3573985351627227e-16 0.0000000000000000e+00 1.2002823885068068e+01 -2 -1.2463313249869098e+02 2.0810204270937046e+01 1.4023225143771441e+00 22 4.2590975732907727e-01 1 3 3.5058062859428595e+01 0.0000000000000000e+00 4.4408920985006262e-16 1.0002039095338265e+01 -3 -3.0167181052209293e+02 4.2289894372475612e+00 9.1804447766328096e-02 23 5.4517484854515796e-02 1 1 4.4747408611989250e+01 -1.7168021850115565e+02 -1.3516603461688090e+00 2.8647271320408564e+01 -1 -1.2440263632521790e+02 1.1287973456305664e+01 1.0588614067317297e+00 17 1.7821058533689904e-01 1 2 2.9648119388488432e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2002541496561260e+01 -2 -1.2479208390644634e+02 2.1797382174355256e+01 1.4423302629394295e+00 23 3.7183128112956300e-02 1 3 3.6058256573485728e+01 0.0000000000000000e+00 4.4408920985006262e-16 1.0001835185804438e+01 -3 -3.0452312334152481e+02 4.4927889965274543e+00 9.3008880336421268e-02 23 3.2170240407511075e-01 1 1 4.5289512186167904e+01 -1.7455305871466865e+02 -1.3679431256689947e+00 2.8614285560409016e+01 -1 -1.2496832524385772e+02 1.2346302985088192e+01 1.1017271725236339e+00 17 8.3315124279619701e-01 1 2 3.0848360830661750e+01 -8.0301308137887881e-16 0.0000000000000000e+00 1.2002287346905135e+01 -2 -1.2489010063846814e+02 2.2792562755409161e+01 1.4823372366454863e+00 23 6.4844465996572953e-01 1 3 3.7058430916137148e+01 0.0000000000000000e+00 6.6613381477509392e-16 1.0001651667223994e+01 -3 -3.0736781044651201e+02 4.7644385987178985e+00 9.8869456901571368e-02 23 5.9241826521392604e-01 1 1 4.5838779848198783e+01 -1.7736606266850831e+02 -1.3798008607822601e+00 2.8513041715538549e+01 -1 -1.2548151708620480e+02 1.3430494305690670e+01 1.1445920760220620e+00 18 4.8807872538166025e-01 1 2 3.2048578128617741e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2002058612214622e+01 -2 -1.2496037378293607e+02 2.3789544288060114e+01 1.5223435129809375e+00 24 2.5969553678051754e-01 1 3 3.8058587824523428e+01 0.0000000000000000e+00 4.4408920985006262e-16 1.0001486500501596e+01 -3 -3.1020377442787930e+02 5.0496664682720214e+00 1.0252018163833185e-01 23 8.6937388475601296e-01 1 1 4.6400707638437098e+01 -1.8011101219165693e+02 -1.3942768389564124e+00 2.8485538781905234e+01 -1 -1.2596091785440957e+02 1.4530075050093615e+01 1.1874562034563618e+00 19 1.4299435058067445e-01 1 2 3.3248773696778130e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2001852750993161e+01 -2 -1.2499309164583113e+02 2.4788971610630412e+01 1.5623491616828435e+00 24 8.7093682406111594e-01 1 3 3.9058729042071079e+01 0.0000000000000000e+00 4.4408920985006262e-16 1.0001337850451437e+01 -3 -3.1303343180184771e+02 5.3393595505040432e+00 1.0119062211805582e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.8286317827968199e+02 -1.4041558577270532e+00 2.8376046955999101e+01 -1 -1.2638360445852601e+02 1.5653126417405160e+01 1.2303196324329457e+00 19 7.9789930413188037e-01 1 2 3.4448949708122484e+01 5.9319031476541902e-16 0.0000000000000000e+00 1.2001667475893845e+01 -2 -1.2500000000000000e+02 2.5788947967991550e+01 1.5707963267948970e+00 25 7.8125000000000000e-02 1 3 4.0051158169872416e+01 4.7136459303954356e-19 4.4408920985006262e-16 1.0001204065406293e+01 -3 -3.1585572720994901e+02 5.6343105223754737e+00 1.0902747327459858e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.8566014022014136e+02 -1.3963190065705104e+00 2.8377859140391863e+01 -1 -1.2675487582424221e+02 1.6793612332055229e+01 1.2731824327975858e+00 20 4.5279465320006002e-01 1 2 3.5649108118332400e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2001500728304460e+01 -2 -1.2500000000000000e+02 2.6781364386213596e+01 1.5707963267948970e+00 25 1.7773437500000000e-01 1 3 4.1047251919872416e+01 2.4619296347582371e-19 4.4408920985006262e-16 1.0001083658865664e+01 -3 -3.1867558875444035e+02 5.9236061772455928e+00 9.0901837262316681e-02 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.8845504338350824e+02 -1.4144446425827919e+00 2.8295536407085436e+01 -1 -1.2709072554973930e+02 1.7945213810021468e+01 1.3160446674114759e+00 21 1.0768135823351253e-01 1 2 3.6849250687521319e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2001350655474015e+01 -2 -1.2500000000000000e+02 2.7777446697592239e+01 1.5707963267948970e+00 25 2.7734375000000000e-01 1 3 4.2043345669872416e+01 2.4549254992426211e-19 4.4408920985006262e-16 1.0000975292979097e+01 -3 -3.2148681452607434e+02 6.1700278267065176e+00 8.1637383375139622e-02 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.9124413335798675e+02 -1.4237090964699695e+00 2.8094499887139847e+01 -1 -1.2736319756332499e+02 1.9113782545399459e+01 1.3589063928496912e+00 21 7.6256028363571449e-01 1 2 3.8049378999791351e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2001215589926613e+01 -2 -1.2500000000000000e+02 2.8773530152833015e+01 1.5707963267948970e+00 25 3.7695312500000000e-01 1 3 4.3039439419872416e+01 2.4486217772763917e-19 4.4408920985006262e-16 1.0000877763681189e+01 -3 -3.2428502601085108e+02 6.4011710657155900e+00 8.3716545874904208e-02 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.9402123616604837e+02 -1.4216299339702045e+00 2.8048964131909173e+01 -1 -1.2758657811888766e+02 2.0292103105643619e+01 1.4017676600297992e+00 22 4.1743220736979231e-01 1 2 3.9249494480834379e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2001094030933951e+01 -2 -1.2500000000000000e+02 2.9769614637549715e+01 1.5707963267948970e+00 25 4.7656250000000000e-01 1 3 4.4035533169872416e+01 2.4429484275083076e-19 4.4408920985006262e-16 1.0000789987313070e+01 -3 -3.2709128466525840e+02 6.6157298034499270e+00 6.3999792089526580e-02 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.9680745359241277e+02 -1.4413466877555825e+00 2.8304839083239102e+01 -1 -1.2777344035551600e+02 2.1477097788953298e+01 1.4446285147776108e+00 23 7.2297829602554708e-02 1 2 4.0449598413773103e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2000984627840555e+01 -2 -1.2500000000000000e+02 3.0765700048794741e+01 1.5707963267948970e+00 25 5.7617187500000000e-01 1 3 4.5031626919872416e+01 2.4378424127146390e-19 4.4408920985006262e-16 1.0000710988581762e+01 -3 -3.2991380240921768e+02 6.8246247701024032e+00 9.0335795028025773e-02 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -1.9961026572472232e+02 -1.4150106848170836e+00 2.8300309342188115e+01 -1 -1.2789104909817243e+02 2.2671199392216526e+01 1.4874889983363555e+00 23 7.2715778048413426e-01 1 2 4.1649691953417957e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2000886165056500e+01 -2 -1.2500000000000000e+02 3.1761786293915268e+01 1.5707963267948970e+00 25 6.7578125000000000e-01 1 3 4.6027720669872416e+01 2.4332469994020775e-19 4.4408920985006262e-16 1.0000639889723585e+01 -3 -3.3272692288515140e+02 7.0982383321453568e+00 1.0800854281665037e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.0239946791062061e+02 -1.3973379370284587e+00 2.8204282423478773e+01 -1 -1.2796295156472030e+02 2.3868287375744419e+01 1.5303491478249400e+00 24 3.8201262714965217e-01 1 2 4.2849776139098324e+01 0.0000000000000000e+00 0.0000000000000000e+00 1.2000797548550850e+01 -2 -1.2500000000000000e+02 3.2757873289523744e+01 1.5707963267948970e+00 25 7.7539062500000000e-01 1 3 4.7023814419872416e+01 2.4291111274218601e-19 4.4408920985006262e-16 1.0000575900751226e+01 -3 -3.3553193189064348e+02 7.4173813008078362e+00 1.2208209477632800e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.0517759822769318e+02 -1.3832643850687809e+00 2.8276273019781442e+01 -1 -1.2800000000000000e+02 2.5067554755953552e+01 1.5707963267948966e+00 25 5.8593750000000000e-03 1 2 4.4040890900257104e+01 5.4870336290787012e-19 0.0000000000000000e+00 1.2000717793695765e+01 -2 -1.2500000000000000e+02 3.3753960960571362e+01 1.5707963267948970e+00 25 8.7500000000000000e-01 1 3 4.8019908169872416e+01 2.4253888426337906e-19 4.4408920985006262e-16 1.0000518310676103e+01 -3 -3.3834046005764412e+02 7.7572587042272145e+00 1.1767925679690613e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.0795788407456351e+02 -1.3876672230482026e+00 2.8313435550026256e+01 -1 -1.2800000000000000e+02 2.6258661940401097e+01 1.5707963267948966e+00 25 1.2500000000000000e-01 1 2 4.5232297150257104e+01 5.3039087933045773e-19 0.0000000000000000e+00 1.2000646014326188e+01 -2 -1.2500000000000000e+02 3.4750049239514226e+01 1.5707963267948970e+00 25 9.7460937500000000e-01 1 3 4.9016001919872416e+01 2.4220387863288790e-19 4.4408920985006262e-16 1.0000466479608493e+01 -3 -3.4115507056936451e+02 8.0867046043461706e+00 1.1458488576604167e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.1074492149634506e+02 -1.3907615940790672e+00 2.8379648870551989e+01 -1 -1.2800000000000000e+02 2.7450061371360988e+01 1.5707963267948966e+00 25 2.4414062500000000e-01 1 2 4.6423703400257104e+01 5.2997333354829221e-19 0.0000000000000000e+00 1.2000581412893569e+01 -2 -1.2497559140399220e+02 3.5745605476556300e+01 1.6006418494174093e+00 1 4.5600599563524469e-01 2 3 7.4613806556280415e-01 -0.0000000000000000e+00 6.6613381477509392e-16 1.0000419831647644e+01 -3 -3.4397980814424375e+02 8.4151473281762268e+00 1.1769881045161992e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.1354212990933431e+02 -1.3876476693934894e+00 2.8534429860509931e+01 -1 -1.2800000000000000e+02 2.8641461484224891e+01 1.5707963267948966e+00 25 3.6328125000000000e-01 1 2 4.7615109650257104e+01 5.2959754234443024e-19 0.0000000000000000e+00 1.2000523271604212e+01 -2 -1.2493569980579477e+02 3.6744461129190505e+01 1.6406434447776701e+00 2 6.7185352417392583e-02 2 3 1.7461779495693306e+00 -0.0000000000000000e+00 4.4408920985006262e-16 1.0000377848482879e+01 -3 -3.4681919419878352e+02 8.7534206030305448e+00 1.2003835398753362e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.1635331248966568e+02 -1.3853081258575752e+00 2.8695042010460838e+01 -1 -1.2800000000000000e+02 2.9832862210802400e+01 1.5707963267948966e+00 25 4.8242187500000000e-01 1 2 4.8806515900257104e+01 5.2925933026073689e-19 0.0000000000000000e+00 1.2000470944443791e+01 -2 -1.2483769664153448e+02 3.7739503954449887e+01 1.6806448806019052e+00 2 6.7836227166861274e-01 2 3 2.7462138451752032e+00 -0.0000000000000000e+00 4.4408920985006262e-16 1.0000340063634590e+01 -3 -3.4966702406267706e+02 9.1120791204910123e+00 1.3401753268634792e-01 24 0.0000000000000000e+00 1 1 4.6665740875198388e+01 -2.1917158754185027e+02 -1.3713289471587613e+00 2.8717538703720763e+01 -101 -1 3 -4 6 -7 9 -10 12 -13 15 -16 18 -19 21 -22 24 -25 27 -28 30 -31 33 -34 36 -37 39 -40 42 -43 45 -46 48 -49 51 -52 54 -55 57 -58 60 -61 63 -64 66 -67 69 -70 72 -73 75 -76 78 -79 81 -82 84 -85 87 -88 90 -91 93 -94 96 -97 99 -100 102 -103 105 -106 108 -109 111 -112 114 -115 117 -118 120 -121 123 -124 126 -127 129 -130 132 -133 135 -136 138 -139 141 -142 144 -145 147 -148 150 -151 153 -154 156 -157 159 -160 162 -163 165 -166 168 -169 171 -172 174 -175 177 -178 180 -181 183 -184 186 -187 189 -190 192 -193 195 -196 198 -199 201 -202 204 -205 207 -208 210 -211 213 -214 216 -217 219 -220 222 -223 225 -226 228 -229 231 -232 234 -235 237 -238 240 -241 243 -244 246 -247 249 -250 252 -253 255 -256 258 -259 261 -262 264 -265 267 -268 270 -271 273 -274 276 -277 279 -280 282 -283 285 -286 288 -289 291 -292 294 -295 297 -298 300 -301 303 diff --git a/tutorials/Crosswalk.ipynb b/tutorials/Crosswalk.ipynb deleted file mode 100644 index 361b6cc..0000000 --- a/tutorials/Crosswalk.ipynb +++ /dev/null @@ -1,456 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Crosswalk" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this notebook we demonstrate how to define a crosswalk with pedestrians using AutomotiveDrivingModels. The last part also hows how to save a video from a simulation." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "using AutomotiveDrivingModels\n", - "\n", - "# All the functions related to visualization\n", - "using AutoViz\n", - "using Random" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generate a crosswalk environment" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this second example we demonstrate how to define a crosswalk area as well as a pedestrian agent type.\n", - "\n", - "We define a new concrete type that will contain the roadway (where cars drive) and the crosswalk definition which is just a regular lane." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "struct CrosswalkEnv\n", - " roadway::Roadway{Float64}\n", - " crosswalk::Lane{Float64}\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The crosswalk lane consists of a straight road segment perpendicular to the road. We will define the roadway just as a straight road." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# geometry parameters\n", - "roadway_length = 50.\n", - "crosswalk_length = 20.\n", - "crosswalk_width = 6.0\n", - "crosswalk_pos = roadway_length/2\n", - "\n", - "# Generate straight roadway of length roadway_length with 2 lanes\n", - "roadway = gen_straight_roadway(2, roadway_length) \n", - "\n", - "# generate the crosswalk\n", - "n_samples = 2 # for curve generation\n", - "crosswalk = Lane(LaneTag(2,1), gen_straight_curve(VecE2(crosswalk_pos, -crosswalk_length/2),\n", - " VecE2(crosswalk_pos, crosswalk_length/2),\n", - " n_samples), width = crosswalk_width)\n", - "cw_segment = RoadSegment(2, [crosswalk])\n", - "push!(roadway.segments, cw_segment) # append it to the roadway\n", - "\n", - "\n", - "# initialize crosswalk environment\n", - "env = CrosswalkEnv(roadway, crosswalk);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Render the crosswalk**\n", - "\n", - "We will define a new method to render this new environment. The roadway part is just rendered regularly, we add specific instuction for the crossswalk part that will display the white stripes." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "function AutoViz.render!(rendermodel::RenderModel, env::CrosswalkEnv)\n", - " roadway = gen_straight_roadway(2, roadway_length) # only render the road and not the crosswalk\n", - " render!(rendermodel, roadway)\n", - " \n", - " # render crosswalk\n", - " curve = env.crosswalk.curve\n", - " n = length(curve)\n", - " pts = Array{Float64}(undef, 2, n)\n", - " for (i,pt) in enumerate(curve)\n", - " pts[1,i] = pt.pos.x\n", - " pts[2,i] = pt.pos.y\n", - " end\n", - "\n", - " add_instruction!(rendermodel, render_dashed_line, (pts, colorant\"white\", env.crosswalk.width, 1.0, 1.0, 0.0, Cairo.CAIRO_LINE_CAP_BUTT))\n", - " return rendermodel\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAYAAADxHswlAAAABmJLR0QA/wD/AP+gvaeTAAANW0lEQVR4nO3bIY5kVRiG4TqdWsIIBKINAUECggQ2gEOyj6EVcmgHauhFIUhAkBASgugRI0awh4PHdXNPzlvF8yzg5vsz5r59a04nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA/5exewAArDDnnLs3sM4YwzsMAFfnZvcAAAAAQKADAABAgkAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALggY/cAAFhhzjl3b2CdMYZ3GACuzs3uAQAAAIBABwAAgASBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAIAAgQ4AAAABAh0AAAACBDoAAAAECHQAAAAIEOgAAAAQINABAAAgQKADAABAgEAHAACAAIEOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwQcbuAQCwwpxz7t7AOmMM7zAAXJ2b3QMAAAAAgQ4AAAAJAh0AAAACBDoAAAAECHQAAAAIEOgAAAAQINABAAAg4Pz4+Pjt7hEAAE/h/QWAa3Q+nU7f7x4BAPBE3l8AuDp+4g4AAAAB519+/2v3BgA43O3t7e4JLOT9BYBrdP7p1z92bwCAw3391Ze7J7CQ9xcArpGfuAMAAECAQAcAAIAAgQ4AAAABAh0AAAACBDoAAAAECHQAAAAIEOgAAAAQcN49AABWuLt/2D0BAOBJfEEHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAIAAgQ4AAAABAh0AAAACzrsHAMAKr1+93D2Bhe7uH3ZPAIDD+YIOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAIAAgQ4AAAABAh0AAAACBDoAAAAEnHcPAIAV7u4fdk8AAHgSX9ABAAAgQKADAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACDh/8elHhz/07bu/T2/f/X34c/+L9997cXr/vRdLnu3e/dx7HPfu597juHc/9x7Hvfu59zju3c+9xzny3vPnn3x4yIP+rfgPsurW08m9u7n3WO7dy73Hcu9e7j2We/dy77Hcu5d7j3XUvX7iDgAAAAHnn3/78/CH1v5acjqt3eTe/dx7Gc9+LvdexrOfy72X8ezncu9lPPu53HsZz34u917Gs5/Lvc1nj2+++3Ee9jQAAADgWfzEHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAICA8+4BALDC61cvd09gobv7h90TAOBwvqADAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAIAAgQ4AAAAB590DAGCFu/uH3RMAAJ7EF3QAAAAIEOgAAAAQINABAAAgQKADAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACDgvHsAAKzw+tXL3RNY6O7+YfcEADicL+gAAAAQINABAAAgQKADAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABJw/+/iD3RsAAJ7E+wsA12g8Pj7O3SMA4Gi3t7e7J7DQmzdvdk8AgMP5iTsAAAAEnE+n0w+7RwDAAt/uHsBS3l8AuDpj9wAAWGHO6b9wXbExhncYAK6On7gDAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF2TsHgAAK8w55+4NrDPG8A4DwNW52T0AAAAAEOgAAACQINABAAAgQKADAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7I2D0AAFaYc87dG1hnjOEdBoCrc7N7AAAAACDQAQAAIEGgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAIAAgQ4AAAABAh0AAAACBDoAAAAECHQAAAAIEOgAAAAQINABAAAgQKADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABckLF7AACsMOecuzewzhjDOwwAV+dm9wAAAABAoAMAAECCQAcAAIAAgQ4AAAABAh0AAAACBDoAAAAECHQAAAAIEOgAAAAQINABAAAgQKADAABAgEAHAACAAIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuCBj9wAAWGHOOXdvYJ0xhncYAK7Oze4BAAAAgEAHAACABIEOAAAAAQIdAAAAAgQ6AAAABAh0AAAACBDoAAAAECDQAQAAIECgAwAAQIBABwAAgACBDgAAAAECHQAAAAIEOgAAAAQIdAAAAAgQ6AAAABAg0AEAACBAoAMAAECAQAcAAIAAgQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAYf4BKORL5hipI2kAAAAASUVORK5CYII=", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000014fc95a0, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cam = FitToContentCamera(0.0)\n", - "render(Scene(), env, cam = cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Navigate the crosswalk example" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Cars will be navigating in the roadway just as before. For the pedestrian we can define a new vehicle definition where we specify the size of the bounding box represented by the pedestrian." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(:class, :length, :width)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# field of the VehicleDef type\n", - "fieldnames(VehicleDef)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "VehicleDef(PEDESTRIAN, 1.000, 1.000)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Agent.Class is from AutomotiveDrivingModels\n", - "const PEDESTRIAN_DEF = VehicleDef(AgentClass.PEDESTRIAN, 1.0, 1.0)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000014fc9fb0, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Car definition\n", - "car_initial_state = VehicleState(VecSE2(5.0, 0., 0.), roadway.segments[1].lanes[1],roadway, 8.0)\n", - "car = Vehicle(car_initial_state, VehicleDef(), 1)\n", - "\n", - "# Pedestrian definition using our new Vehicle definition\n", - "ped_initial_state = VehicleState(VecSE2(+24.5,-7.0,π/2), env.crosswalk, roadway, 0.5)\n", - "ped = Vehicle(ped_initial_state, PEDESTRIAN_DEF, 2)\n", - "\n", - "scene = Scene()\n", - "push!(scene, car)\n", - "push!(scene, ped)\n", - "\n", - "# visualize the initial state\n", - "render(scene, env, cam=cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Simulate!\n", - "\n", - "As before, associate a driver model to each vehicle in the scene. We will use the model defined in the intersection example for both agents." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "mutable struct LinearDriver <: DriverModel{LaneFollowingAccel}\n", - " a::LaneFollowingAccel\n", - "\n", - " p::Float64 # confidence on the pedestrian intention\n", - " k::Float64 # gain\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "function AutomotiveDrivingModels.get_name(model::LinearDriver) \n", - " return \"linear driver\"\n", - "end\n", - "\n", - "Base.rand(rng::AbstractRNG, model::LinearDriver) = model.a\n", - "\n", - "\n", - "function AutomotiveDrivingModels.observe!(model::LinearDriver, scene::EntityFrame{VehicleState, VehicleDef, Int64}, roadway::Roadway, egoid::Int) \n", - " model.a = LaneFollowingAccel(model.k*model.p)\n", - " \n", - " # change the confidence based on some policy\n", - " # you can get the position of the pedestrian from the scene\n", - " model.p = 100.0\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000014fca570, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "timestep = 0.1\n", - "\n", - "\n", - "# reset the initial scene\n", - "# Car definition\n", - "car_initial_state = VehicleState(VecSE2(5.0, 0., 0.), roadway.segments[1].lanes[1],roadway, 8.0)\n", - "car = Vehicle(car_initial_state, VehicleDef(), 1)\n", - "\n", - "# Pedestrian definition using our new Vehicle definition\n", - "ped_initial_state = VehicleState(VecSE2(+24.5,-7.0,π/2), env.crosswalk, roadway, 0.5)\n", - "ped = Vehicle(ped_initial_state, PEDESTRIAN_DEF, 2)\n", - "\n", - "scene = Scene()\n", - "push!(scene, car)\n", - "push!(scene, ped)\n", - "\n", - "# define a model for each entities present in the scene\n", - "models = Dict{Int, DriverModel}()\n", - "\n", - "ego_id = 1\n", - "ped_id = 2\n", - "# Constant speed model\n", - "models[ego_id] = LinearDriver(LaneFollowingAccel(0.0), 20.0, -0.02)\n", - "models[ped_id] = IntelligentDriverModel(v_des=1.0) # dumb model\n", - "\n", - "nticks = 50\n", - "\n", - "# execute the simulation\n", - "scenes = simulate!(scene, roadway, models, nticks, timestep)\n", - "\n", - "render(last(scenes), env, cam=cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generate a video with Reel.jl" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "using Reel" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "animate_record (generic function with 2 methods)" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "function animate_record(scenes::Vector{Scene},dt::Float64, env::CrosswalkEnv, cam=FitToContentCamera(0.0))\n", - " duration =length(scenes)*dt::Float64\n", - " fps = Int(1/dt)\n", - " function render_rec(t, dt)\n", - " frame_index = Int(floor(t/dt)) + 1\n", - " return render(scenes[frame_index], env, cam=cam)\n", - " end\n", - " return duration, fps, render_rec\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "Frames{MIME{Symbol(\"image/png\")}}(\"C:\\\\Users\\\\Maxime\\\\AppData\\\\Local\\\\Temp\\\\jl_oWSOuh\", 0x0000000000000033, 10.0, nothing)" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "duration, fps, render_hist = animate_record(scenes, timestep, env)\n", - "film = roll(render_hist, fps = fps, duration = duration)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "@webio": { - "lastCommId": null, - "lastKernelId": null - }, - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Julia 1.2.0", - "language": "julia", - "name": "julia-1.2" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.2.0" - }, - "widgets": { - "state": { - "733a867e-9029-4020-a34a-60002bbbddfa": { - "views": [ - { - "cell_index": 40 - } - ] - }, - "76a90642-0d5d-478d-b349-376a8b55bc6e": { - "views": [ - { - "cell_index": 25 - } - ] - }, - "f84f4727-ab47-40ae-8cca-02ef73504523": { - "views": [ - { - "cell_index": 14 - } - ] - } - }, - "version": "1.2.0" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} diff --git a/tutorials/Intersection.ipynb b/tutorials/Intersection.ipynb deleted file mode 100644 index 6d1a75c..0000000 --- a/tutorials/Intersection.ipynb +++ /dev/null @@ -1,995 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Intersection\n", - "\n", - "In this notebook we demonstrate how to define a T-shape intersection with AutomotiveDrivingModels. You will also learn how to define your own custom action type and driver model type.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "using AutomotiveDrivingModels\n", - "\n", - "# All the functions related to visualization\n", - "using AutoViz\n", - "using Random # for RNGs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generate a T-Shape intersection" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In order to generate the road network, one first initializes a Roadway object." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "roadway = Roadway();" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3-element VecSE2{Float64} with indices SOneTo(3):\n", - " 13.0 \n", - " 3.0 \n", - " -3.141592653589793" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Define coordinates of the entry and exit points to the intersection\n", - "r = 5.0 # turn radius\n", - "A = VecSE2(0.0,DEFAULT_LANE_WIDTH,-π)\n", - "B = VecSE2(0.0,0.0,0.0)\n", - "C = VecSE2(r,-r,-π/2)\n", - "D = VecSE2(r+DEFAULT_LANE_WIDTH,-r,π/2)\n", - "E = VecSE2(2r+DEFAULT_LANE_WIDTH,0,0)\n", - "F = VecSE2(2r+DEFAULT_LANE_WIDTH,DEFAULT_LANE_WIDTH,-π)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next step consists in appending all the lanes to the road network. We can define a helper function to add a new lane to the roadway." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "append_to_curve! (generic function with 1 method)" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "function append_to_curve!(target::Curve, newstuff::Curve)\n", - " s_end = target[end].s\n", - " for c in newstuff\n", - " push!(target, CurvePt(c.pos, c.s+s_end, c.k, c.kd))\n", - " end\n", - " return target\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Example of a lane that consists in 3 road segments, a straight curve (from the left to the center), a turning part (right turn) and a final straight curve. You can visualize the lane that has been added to the roadway" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAYAAADxHswlAAAABmJLR0QA/wD/AP+gvaeTAAAWgUlEQVR4nO3dWYyd513H8eedzbN6JuMlXlMcN2ndNImX1EkbulERUiltoVxALxDcIMEViwRIRSAukIoikLhAReKCqrRqgVYIaJqCSmjdJnXiNU7ixGkSN/EaL+MZz76cOS8XNJIbUprEzplf7c/n8t3+z+1XzznvWwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHD5qme//1xjqRcBAAAAr6XZbNaNxeZCXcp8Y2FharFZjy4uNk/XdfN4aWt/anlP557e3t6nNm3aNLbUa71c1Re/+vV6qRcBAAAAr6WtrSqdnR2lq7OjdHd1lZ6eZXVfz7J6oK+n6uzoqF65bmZ2bm5mdv74/MLCgY6O9gfWrl754IYNG0aWcu1vVPW7f/bXAh0AAICfOt1dnWVwoK9cN9hfVly3vKweHqpXrxgq3cs6q7ouZXJ6emxqem53Z2fH5wb7e/79pptumlvqNf9/BDoAAABXlcH+vrJ+zYqyYc3K8rZ1q+venmVVo7HYHJ2YfLKqy2dXDg/+w6ZNm2aXep2vJtABAAC4alWllJXDg+XGjWvKzZs2NIcH+9sWGo3FCxcnv9Pd0/WnW2+55eGlXuMrBDoAAADXjBVDy8s7N28oWzbfUPf1LKsuTkydmV1Y+IuZ8bG/+fCHP7ykL1EX6AAAAFxzqqoqm29YW7a+c1O9fs3KanpmbnpievqvBnqW/fktt9wyvxRraluKoQAAALCU6rouz790qnz1Px+pvvzArnLq7IWe1cNDf1K1dYzt3rv/D+u6bnkv20EHAACA8r8/f3/f9i31jRvXVGMTUyONRvPX3rP9tm+0ar4ddAAAACiljIyNl6/992PVV77xcFlYaFy3Ymjgwcf2P/7dZ545saIV8wU6AAAAXOLU2ZHy5Qd2tX17zxNlaKDv7qpt+vSe/Qd/862eK9ABAADgVeq6Lk8c+UH5wr8+VJ0+d6Fj1fDQ3+3Zf3DXyy+/3PdWzRToAAAA8GNMTs+Wf/uvR6uHdj9ehpb3f+Dc+Qun9z5+eNtbMUugAwAAwE/w1PdfKv/09e+WhcZi/1D/sn279x34rSs9Q6ADAADA6zAyNl6+/MCu6qWTZ6vrh4f+dveeg5+9ks8X6AAAAPA6LTQa5evf3lvtP/x8WbNq6Lf37D/44JX6ZrpABwAAgDegruvyyP6ny7cfe7KsvG7wo3sPPPHIt771rY7Lfe5lPwAAAACuRYeOHC2z8/Plnru33dXWXj1a1/WdVVUtvtnn2UEHAACAN+nZoyfKf3xnf7luoG/Hvsef2FXXdfVmnyXQAQAA4DI899Kp8s1HDpYVgwN379n/+L+82ecIdAAAALhMR46eKN/dd7isXjH0i4/uPXj/m3mGQAcAAIAr4ODTL5RDzxwtq4aX/8H3HjvwqTd6v0AHAACAK2TX3qfKyTMj9fBQ/xeeeeaZm9/IvQIdAAAArpC6rss3du2r5ucX2uYWmg8fPny46/XeK9ABAADgCpqZmy8P7tpXDfT1rJqaXfjS671PoAMAAMAV9vL50fLooSNl5XXLf/mx/fvvez33CHQAAAB4C+x/8rlyduRis6+79x+PHz/e85OuF+gAAADwFmjWdfnmIwfaerq7+k6+PPL3P+n66rF9B5utWBgAAAC8Ec1mXc8vNNpm5+fLzOx8mZyaKRcnpsqFixNl9OJkadb1Ui/xdXnvti3ljltvqifGx2/dunXr4R93XUfdrB9u5cIAAADg9Whvb+vrae/qHujrXt7R3j7Y09Pd19He1lZKKYuLzXJu9GLz5JmRtmMnz5YTZ0ZKs5m5/7zvye+Xd23eWBql7aullC0/7rqqhWsCAACAy3L06NHrx6em3jM9M39vZ0fH+/t7u7d0L+vqnF9o1C8cO10deeF4OX76XEnbW3/HjRvKve/fUc6Nj3985+23f+21rhHoAAAA/NSq67o6cuT5u8YmJn5noK/nvr7e7r6x8an6wOHnq6efP1YWQ3bVq6oqn7rvg83O9o4z27a+e91rXtPqRQEAAMBboa7rau8TT9xXLZbPrBgauGVqZq7+3oGnqyMvHI/YUd+0YU35+EfuLOcuXPyVnTu2/vOrzwt0AAAArjqHDj29fb658PmVQ8vfffrshfqh3YeqkbHxJV1TVUr51Mc+1GzvaD+54/Zbb3it8wAAAHBV2rP/8U/29iz7/LKuzv6H9x0uh478YEnXc/Om9eWjH7ijnBud+ODO7bd959JzvoMOAADAVWvnjq3/Mjw0eP3o+OQ3P3TnbeXeD9xRt7cvXQo/9+KpMjk1U9d18/5XnxPoAAAAXNXWrVs3vXP71ntePn/hj97+trXll37+fXVXZ8eSrKWu6/LEsy9WK4cGdp44cWLFpecEOgAAANeE975nx/3nRsY+sXp4sP7kL9zd7OxYmkg//NxLpZSqOn767KcvPS7QAQAAuGa8d+eOr42NTdwzPDhQPvaRnXVb1fpXs03PzpWXTp2te5ct+/VLjwt0AAAArik7d25/aPTixK+uX72y+tCdty7JGp554Vi1fKB3xZGjR2975ZhABwAA4Jpz5x3bvnJu9OJnbn3HpvKOGze0fP6LJ86URmOxHjk/+nuvHBPoAAAAXJPuumPbp0dGxw/83F231/29PS2dvdBYLC+dOlv6errve+WYQAcAAOCa1dez4p5ms9n44J231q2e/cKx09Xyvt6VL7744tpSBDoAAADXsC1bNoyMT0z+8dtvWFttXLuqpbOPnTpXSinl1Nnzv1GKQAcAAOAat/OO7X85Nj51/md3vKvZyrlTM7NldHyi2d7W/olSBDoAAADXuKqq6sZi4/dXrxhqu6HFu+jHT59v6+/tua0UgQ4AAADljm23f3FiamZs2y2bW/pf9FNnRkpvz7KeY8eOrRPoAAAAXPOqqqqnZuY+e8Pa1VV/b3fL5r58frSUUsqZ8xfuFegAAABQSlk9vPz+uq7rVn4XfXxyuszOLdQLjeZHBDoAAACUUjZv3nxx9OLkkZt/ZkNLXxZ3fvRi6eho2yrQAQAA4Ica9eKXVg0PtvV2L2vZzAtjE1V3V9dGgQ4AAAA/tOH6VZ+rqlI2rF3ZspkXLk6Uvt7ufoEOAAAAP7Rx48aTk1Mz0+tWr2jZzPHJ6dJWVZVABwAAgEtMz84/u3bVdS37H/r4xHQpxXfQAQAA4Ec0mov7hgcHqqpF86ZmZkspAh0AAAB+RGd7++6Ojvaqr7enJfNm5xfKYrNZC3QAAAC4xGD/8gOllLK8v7dlM+fmFgQ6AAAAXKqvr+tEKaX09bbuU2uz8wt+4g4AAACXWr9+/YVmXde93d0tm7mw0BDoAAAAcKmqqupGY3Gxq6ujZTPnGws+swYAAACvtri4uNjR3t6yeXXTW9wBAADg/6hLaba17ENrpSw2F+2gAwAAwKs167qU1vV5KaWygw4AAAAJBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAEAAgQ4AAAABBDoAAAAEEOgAAAAQQKADAABAAIEOAAAAAQQ6AAAABBDoAAAAEECgAwAAQACBDgAAAAEEOgAAAAQQ6AAAABBAoAMAAECAjqVeAAAAAKSZnZk7OT0z11VKOd+KeZPTsxtaMQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK5+/wNRBkteoNnM0gAAAABJRU5ErkJggg==", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000302f54b0, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Append right turn coming from the left\n", - "curve = gen_straight_curve(convert(VecE2, B+VecE2(-100,0)), convert(VecE2, B), 2)\n", - "append_to_curve!(curve, gen_bezier_curve(B, C, 0.6r, 0.6r, 51)[2:end])\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, C), convert(VecE2, C+VecE2(0,-50.0)), 2))\n", - "lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)\n", - "push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))\n", - "\n", - "#visualize first lane\n", - "cam = FitToContentCamera(0.0)\n", - "render(roadway, cam=cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's repeat the process and complete the T-shape intersection" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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Agh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAAIACCHQAAAAogEAHAACAAgh0AAAAKIBABwAAgAIIdAAAACiAQAcAaFDDo2OjA0PDE57TPzA0Cau5ZHh0NANDQ/2TNhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuHr/HxFhGEzt7AfKAAAAAElFTkSuQmCC", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x00000000302f5620, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Append straight left\n", - "curve = gen_straight_curve(convert(VecE2, B+VecE2(-100,0)), convert(VecE2, B), 2)\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, B), convert(VecE2, E), 2)[2:end])\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, E), convert(VecE2, E+VecE2(50,0)), 2))\n", - "lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)\n", - "push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))\n", - "\n", - "# Append straight right\n", - "curve = gen_straight_curve(convert(VecE2, F+VecE2(50,0)), convert(VecE2, F), 2)\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, F), convert(VecE2, A), 2)[2:end])\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, A), convert(VecE2, A+VecE2(-100,0)), 2))\n", - "lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)\n", - "push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))\n", - "\n", - "# Append left turn coming from the right\n", - "curve = gen_straight_curve(convert(VecE2, F+VecE2(50,0)), convert(VecE2, F), 2)\n", - "append_to_curve!(curve, gen_bezier_curve(F, C, 0.9r, 0.9r, 51)[2:end])\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, C), convert(VecE2, C+VecE2(0,-50)), 2))\n", - "lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)\n", - "push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))\n", - "\n", - "# Append right turn coming from below\n", - "curve = gen_straight_curve(convert(VecE2, D+VecE2(0,-50)), convert(VecE2, D), 2)\n", - "append_to_curve!(curve, gen_bezier_curve(D, E, 0.6r, 0.6r, 51)[2:end])\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, E), convert(VecE2, E+VecE2(50,0)), 2))\n", - "lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)\n", - "push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))\n", - "\n", - "# Append left turn coming from below\n", - "curve = gen_straight_curve(convert(VecE2, D+VecE2(0,-50)), convert(VecE2, D), 2)\n", - "append_to_curve!(curve, gen_bezier_curve(D, A, 0.9r, 0.9r, 51)[2:end])\n", - "append_to_curve!(curve, gen_straight_curve(convert(VecE2, A), convert(VecE2, A+VecE2(-100,0)), 2))\n", - "lane = Lane(LaneTag(length(roadway.segments)+1,1), curve)\n", - "push!(roadway.segments, RoadSegment(lane.tag.segment, [lane]))\n", - "\n", - "cam = FitToContentCamera(0.0)\n", - "render(roadway, cam=cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can identify each lane thanks to the following user-defined functions. We define a ```LaneOverlay``` object that indicate the lane to highlight. One could implement any custom type to display other information on the lane. We then add a new method to the ```render!``` function that execute the specific action (coloring in blue). Look at Autoviz.jl for more detail on the ```render!``` function.\n", - "\n", - "Use the slider to highlight each lane. The number corresponds to a road segment.\n", - "\n", - "**Note :** In order to render the intersection, one must first initialize a ```Scene``` object." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.webio.node+json": { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - "i" - ], - "instanceArgs": { - "namespace": "html", - "tag": "label" - }, - "nodeType": "DOM", - "props": { - "className": "interact ", - "style": { - "padding": "5px 10px 0px 10px" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-left" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "input" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}", - "orient": "horizontal", - "type": "range" - }, - "className": "slider slider is-fullwidth", - "max": 6, - "min": 1, - "step": 1, - "style": {} - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-center" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "p" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "text: formatted_val" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-right" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - ], - "instanceArgs": { - "handlers": { - "changes": [ - "(function (val){return (val!=this.model[\"changes\"]()) ? (this.valueFromJulia[\"changes\"]=true, this.model[\"changes\"](val)) : undefined})" - ], - "index": [ - "(function (val){return (val!=this.model[\"index\"]()) ? (this.valueFromJulia[\"index\"]=true, this.model[\"index\"](val)) : undefined})" - ] - }, - "id": "13981007195005142646", - "imports": { - "data": [ - { - "name": "knockout", - "type": "js", - "url": "/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js" - }, - { - "name": "knockout_punches", - "type": "js", - "url": "/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js" - }, - { - "name": null, - "type": "js", - "url": "/assetserver/7160a783468b386025b3685c9691df17912ec29b-all.js" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/c92112051a0a0326d397440da1a873f367f1d175-style.css" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/755919ab5089275528f8a583d9fba4e0adcae551-bulma_confined.min.css" - } - ], - "type": "async_block" - }, - "mount_callbacks": [ - "function () {\n var handler = (function (ko, koPunches) {\n ko.punches.enableAll();\n ko.bindingHandlers.numericValue = {\n init: function(element, valueAccessor, allBindings, data, context) {\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\n stringified.subscribe(function(value) {\n var val = parseFloat(value);\n if (!isNaN(val)) {\n valueAccessor()(val);\n }\n });\n valueAccessor().subscribe(function(value) {\n var str = JSON.stringify(value);\n if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(stringified()) >= 0))\n return;\n if ([\"null\", \"\"].indexOf(str) >= 0)\n return;\n stringified(str);\n });\n ko.applyBindingsToNode(\n element,\n {\n value: stringified,\n valueUpdate: allBindings.get('valueUpdate'),\n },\n context,\n );\n }\n };\n var json_data = {\"formatted_vals\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\"],\"changes\":WebIO.getval({\"name\":\"changes\",\"scope\":\"13981007195005142646\",\"id\":\"ob_18\",\"type\":\"observable\"}),\"index\":WebIO.getval({\"name\":\"index\",\"scope\":\"13981007195005142646\",\"id\":\"ob_17\",\"type\":\"observable\"})};\n var self = this;\n function AppViewModel() {\n for (var key in json_data) {\n var el = json_data[key];\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\n }\n \n [this[\"formatted_val\"]=ko.computed( function(){\n return this.formatted_vals()[parseInt(this.index())-(1)];\n }\n,this)]\n [this[\"changes\"].subscribe((function (val){!(this.valueFromJulia[\"changes\"]) ? (WebIO.setval({\"name\":\"changes\",\"scope\":\"13981007195005142646\",\"id\":\"ob_18\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"changes\"]=false}),self),this[\"index\"].subscribe((function (val){!(this.valueFromJulia[\"index\"]) ? (WebIO.setval({\"name\":\"index\",\"scope\":\"13981007195005142646\",\"id\":\"ob_17\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"index\"]=false}),self)]\n \n }\n self.model = new AppViewModel();\n self.valueFromJulia = {};\n for (var key in json_data) {\n self.valueFromJulia[key] = false;\n }\n ko.applyBindings(self.model, self.dom);\n}\n);\n (WebIO.importBlock({\"data\":[{\"name\":\"knockout\",\"type\":\"js\",\"url\":\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\"},{\"name\":\"knockout_punches\",\"type\":\"js\",\"url\":\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\"}],\"type\":\"async_block\"})).then((imports) => handler.apply(this, imports));\n}\n" - ], - "observables": { - "changes": { - "id": "ob_18", - "sync": false, - "value": 0 - }, - "index": { - "id": "ob_17", - "sync": true, - "value": 3 - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "field interact-widget" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "id": "ob_24", - "name": "obs-node" - }, - "nodeType": "ObservableNode", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "handlers": {}, - "id": "1292187770208900297", - "imports": { - "data": [], - "type": "async_block" - }, - "mount_callbacks": [], - "observables": { - "obs-node": { - "id": "ob_24", - "sync": false, - "value": { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "setInnerHtml": "" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": {}, - "type": "node" - }, - "text/html": [ - "\n", - " \n", - "\n" - ], - "text/plain": [ - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Scope(Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :label), Any[\"i\"], Dict{Symbol,Any}(:className => \"interact \",:style => Dict{Any,Any}(:padding => \"5px 10px 0px 10px\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-left\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :input), Any[], Dict{Symbol,Any}(:max => 6,:min => 1,:attributes => Dict{Any,Any}(:type => \"range\",Symbol(\"data-bind\") => \"numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}\",\"orient\" => \"horizontal\"),:step => 1,:className => \"slider slider is-fullwidth\",:style => Dict{Any,Any}()))], Dict{Symbol,Any}(:className => \"interact-flex-row-center\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :p), Any[], Dict{Symbol,Any}(:attributes => Dict(\"data-bind\" => \"text: formatted_val\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-right\"))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\")), Dict{String,Tuple{Observables.AbstractObservable,Union{Nothing, Bool}}}(\"changes\" => (Observable{Int64} with 1 listeners. Value:\n", - "0, nothing),\"index\" => (Observable{Int64} with 2 listeners. Value:\n", - "3, nothing)), Set(String[]), nothing, Asset[Asset(\"js\", \"knockout\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout.js\"), Asset(\"js\", \"knockout_punches\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout_punches.js\"), Asset(\"js\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\all.js\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\style.css\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Interact\\\\SbgIk\\\\src\\\\..\\\\assets\\\\bulma_confined.min.css\")], Dict{Any,Any}(\"changes\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"changes\\\"]()) ? (this.valueFromJulia[\\\"changes\\\"]=true, this.model[\\\"changes\\\"](val)) : undefined})\")],\"index\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"index\\\"]()) ? (this.valueFromJulia[\\\"index\\\"]=true, this.model[\\\"index\\\"](val)) : undefined})\")]), WebIO.ConnectionPool(Channel{Any}(sz_max:32,sz_curr:0), Set(AbstractConnection[]), Base.GenericCondition{Base.AlwaysLockedST}(Base.InvasiveLinkedList{Task}(Task (runnable) @0x0000000013118e70, Task (runnable) @0x0000000013118e70), Base.AlwaysLockedST(1))), WebIO.JSString[WebIO.JSString(\"function () {\\n var handler = (function (ko, koPunches) {\\n ko.punches.enableAll();\\n ko.bindingHandlers.numericValue = {\\n init: function(element, valueAccessor, allBindings, data, context) {\\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\\n stringified.subscribe(function(value) {\\n var val = parseFloat(value);\\n if (!isNaN(val)) {\\n valueAccessor()(val);\\n }\\n });\\n valueAccessor().subscribe(function(value) {\\n var str = JSON.stringify(value);\\n if ((str == \\\"0\\\") && ([\\\"-0\\\", \\\"-0.\\\"].indexOf(stringified()) >= 0))\\n return;\\n if ([\\\"null\\\", \\\"\\\"].indexOf(str) >= 0)\\n return;\\n stringified(str);\\n });\\n ko.applyBindingsToNode(\\n element,\\n {\\n value: stringified,\\n valueUpdate: allBindings.get('valueUpdate'),\\n },\\n context,\\n );\\n }\\n };\\n var json_data = {\\\"formatted_vals\\\":[\\\"1\\\",\\\"2\\\",\\\"3\\\",\\\"4\\\",\\\"5\\\",\\\"6\\\"],\\\"changes\\\":WebIO.getval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"13981007195005142646\\\",\\\"id\\\":\\\"ob_18\\\",\\\"type\\\":\\\"observable\\\"}),\\\"index\\\":WebIO.getval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"13981007195005142646\\\",\\\"id\\\":\\\"ob_17\\\",\\\"type\\\":\\\"observable\\\"})};\\n var self = this;\\n function AppViewModel() {\\n for (var key in json_data) {\\n var el = json_data[key];\\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\\n }\\n \\n [this[\\\"formatted_val\\\"]=ko.computed( function(){\\n return this.formatted_vals()[parseInt(this.index())-(1)];\\n }\\n,this)]\\n [this[\\\"changes\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"changes\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"13981007195005142646\\\",\\\"id\\\":\\\"ob_18\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"changes\\\"]=false}),self),this[\\\"index\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"index\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"13981007195005142646\\\",\\\"id\\\":\\\"ob_17\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"index\\\"]=false}),self)]\\n \\n }\\n self.model = new AppViewModel();\\n self.valueFromJulia = {};\\n for (var key in json_data) {\\n self.valueFromJulia[key] = false;\\n }\\n ko.applyBindings(self.model, self.dom);\\n}\\n);\\n (WebIO.importBlock({\\\"data\\\":[{\\\"name\\\":\\\"knockout\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\\\"},{\\\"name\\\":\\\"knockout_punches\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\\\"}],\\\"type\\\":\\\"async_block\\\"})).then((imports) => handler.apply(this, imports));\\n}\\n\")])], Dict{Symbol,Any}(:className => \"field interact-widget\")), Observable{Any} with 0 listeners. Value:\n", - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000031c7f7a0, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\"))], Dict{Symbol,Any}())" - ] - }, - "execution_count": 21, - "metadata": { - "application/vnd.webio.node+json": { - "kernelId": "c880022a-c1ea-42e7-bb55-6c5c298f8abd" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "using Interact\n", - "\n", - "scene = Scene()\n", - "\n", - "struct LaneOverlay <: SceneOverlay\n", - " lane::Lane\n", - " color::Colorant\n", - "end\n", - "function AutoViz.render!(rendermodel::RenderModel, overlay::LaneOverlay, scene::Scene, roadway::Roadway)\n", - " render!(rendermodel, overlay.lane, roadway, color_asphalt=overlay.color)\n", - " return rendermodel\n", - "end\n", - "\n", - "@manipulate for i in 1 : length(roadway.segments)\n", - " render(scene, roadway, [LaneOverlay(roadway[LaneTag(i,1)], RGBA(0.0,0.0,1.0,0.5))], cam=cam)\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Navigate in the new road network\n", - "\n", - "Let's populate the intersection" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAABAAQQ6AAAAFECgAwAAQAEEOgAAABRAoAMAAEABBDoAAAAUQKADAMxQk9P16bGJyQseZ3Rs4iLM5rTJ6emMTUyMXrQBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJlh9YkAAAASSURBVAAAAAAAAAAAAIBz9/8BCBIbhGirG3gAAAAASUVORK5CYII=", - "text/plain": [ - "Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000031c7fed0, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scene = Scene()\n", - "vs0 = VehicleState(B + polar(50.0,-π), roadway, 8.0) # initial state of the vehicle\n", - "push!(scene, Vehicle(vs0, VehicleDef(), 1)) # add vehicle with the default type\n", - "\n", - "render(scene, roadway, cam=cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will use lateral and longitudinal acceleration to control a car in the intersection. The first step is to define a corresponding action type that will contain the acceleration inputs.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "struct LaneSpecificAccelLatLon\n", - " a_lat::Float64\n", - " a_lon::Float64\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, add a method to the propagate function to update the state using our new action type. \n", - "\n", - "\n", - "**Note:** There is an existing propagate method to update the state using lateral and longitudinal acceleration. (it is used in line 3)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "function AutomotiveDrivingModels.propagate(veh::Vehicle, action::LaneSpecificAccelLatLon, roadway::Roadway, Δt::Float64)\n", - " lane_tag_orig = veh.state.posF.roadind.tag\n", - " state = propagate(veh, LatLonAccel(action.a_lat, action.a_lon), roadway, Δt)\n", - " roadproj = proj(state.posG, roadway[lane_tag_orig], roadway, move_along_curves=false)\n", - " retval = VehicleState(Frenet(roadproj, roadway), roadway, state.v)\n", - " return retval\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Driver Model:**\n", - "\n", - "We define a driver model, which can be seen as a distribution over actions. Here we will define the simplest model, which is to repeat the same action." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "struct InterDriver <: DriverModel{LaneSpecificAccelLatLon}\n", - " a::LaneSpecificAccelLatLon\n", - "end\n", - "AutomotiveDrivingModels.get_name(model::InterDriver) = \"InterDriver\"\n", - "AutomotiveDrivingModels.observe!(model::InterDriver, scene::Scene, roadway::Roadway, egoid::Int64) = model\n", - "Base.rand(::AbstractRNG, model::InterDriver) = model.a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Simulate: **\n", - "\n", - "First associate a model to each driver in the scene using a dictionnary. Here we only have one driver identified by its ID: 1. Then everything is ready to run the ```simulate!``` function." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.webio.node+json": { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - "frame_index" - ], - "instanceArgs": { - "namespace": "html", - "tag": "label" - }, - "nodeType": "DOM", - "props": { - "className": "interact ", - "style": { - "padding": "5px 10px 0px 10px" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-left" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "input" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}", - "orient": "horizontal", - "type": "range" - }, - "className": "slider slider is-fullwidth", - "max": 101, - "min": 1, - "step": 1, - "style": {} - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-center" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "p" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "text: formatted_val" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-right" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - ], - "instanceArgs": { - "handlers": { - "changes": [ - "(function (val){return (val!=this.model[\"changes\"]()) ? (this.valueFromJulia[\"changes\"]=true, this.model[\"changes\"](val)) : undefined})" - ], - "index": [ - "(function (val){return (val!=this.model[\"index\"]()) ? (this.valueFromJulia[\"index\"]=true, this.model[\"index\"](val)) : undefined})" - ] - }, - "id": "5090847059764039543", - "imports": { - "data": [ - { - "name": "knockout", - "type": "js", - "url": "/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js" - }, - { - "name": "knockout_punches", - "type": "js", - "url": "/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js" - }, - { - "name": null, - "type": "js", - "url": "/assetserver/7160a783468b386025b3685c9691df17912ec29b-all.js" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/c92112051a0a0326d397440da1a873f367f1d175-style.css" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/755919ab5089275528f8a583d9fba4e0adcae551-bulma_confined.min.css" - } - ], - "type": "async_block" - }, - "mount_callbacks": [ - "function () {\n var handler = (function (ko, koPunches) {\n ko.punches.enableAll();\n ko.bindingHandlers.numericValue = {\n init: function(element, valueAccessor, allBindings, data, context) {\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\n stringified.subscribe(function(value) {\n var val = parseFloat(value);\n if (!isNaN(val)) {\n valueAccessor()(val);\n }\n });\n valueAccessor().subscribe(function(value) {\n var str = JSON.stringify(value);\n if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(stringified()) >= 0))\n return;\n if ([\"null\", \"\"].indexOf(str) >= 0)\n return;\n stringified(str);\n });\n ko.applyBindingsToNode(\n element,\n {\n value: stringified,\n valueUpdate: allBindings.get('valueUpdate'),\n },\n context,\n );\n }\n };\n var json_data = {\"formatted_vals\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"29\",\"30\",\"31\",\"32\",\"33\",\"34\",\"35\",\"36\",\"37\",\"38\",\"39\",\"40\",\"41\",\"42\",\"43\",\"44\",\"45\",\"46\",\"47\",\"48\",\"49\",\"50\",\"51\",\"52\",\"53\",\"54\",\"55\",\"56\",\"57\",\"58\",\"59\",\"60\",\"61\",\"62\",\"63\",\"64\",\"65\",\"66\",\"67\",\"68\",\"69\",\"70\",\"71\",\"72\",\"73\",\"74\",\"75\",\"76\",\"77\",\"78\",\"79\",\"80\",\"81\",\"82\",\"83\",\"84\",\"85\",\"86\",\"87\",\"88\",\"89\",\"90\",\"91\",\"92\",\"93\",\"94\",\"95\",\"96\",\"97\",\"98\",\"99\",\"100\",\"101\"],\"changes\":WebIO.getval({\"name\":\"changes\",\"scope\":\"5090847059764039543\",\"id\":\"ob_26\",\"type\":\"observable\"}),\"index\":WebIO.getval({\"name\":\"index\",\"scope\":\"5090847059764039543\",\"id\":\"ob_25\",\"type\":\"observable\"})};\n var self = this;\n function AppViewModel() {\n for (var key in json_data) {\n var el = json_data[key];\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\n }\n \n [this[\"formatted_val\"]=ko.computed( function(){\n return this.formatted_vals()[parseInt(this.index())-(1)];\n }\n,this)]\n [this[\"changes\"].subscribe((function (val){!(this.valueFromJulia[\"changes\"]) ? (WebIO.setval({\"name\":\"changes\",\"scope\":\"5090847059764039543\",\"id\":\"ob_26\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"changes\"]=false}),self),this[\"index\"].subscribe((function (val){!(this.valueFromJulia[\"index\"]) ? (WebIO.setval({\"name\":\"index\",\"scope\":\"5090847059764039543\",\"id\":\"ob_25\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"index\"]=false}),self)]\n \n }\n self.model = new AppViewModel();\n self.valueFromJulia = {};\n for (var key in json_data) {\n self.valueFromJulia[key] = false;\n }\n ko.applyBindings(self.model, self.dom);\n}\n);\n (WebIO.importBlock({\"data\":[{\"name\":\"knockout\",\"type\":\"js\",\"url\":\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\"},{\"name\":\"knockout_punches\",\"type\":\"js\",\"url\":\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\"}],\"type\":\"async_block\"})).then((imports) => handler.apply(this, imports));\n}\n" - ], - "observables": { - "changes": { - "id": "ob_26", - "sync": false, - "value": 0 - }, - "index": { - "id": "ob_25", - "sync": true, - "value": 51 - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "field interact-widget" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "id": "ob_32", - "name": "obs-node" - }, - "nodeType": "ObservableNode", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "handlers": {}, - "id": "7120049020921087876", - "imports": { - "data": [], - "type": "async_block" - }, - "mount_callbacks": [], - "observables": { - "obs-node": { - "id": "ob_32", - "sync": false, - "value": { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "setInnerHtml": "" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": {}, - "type": "node" - }, - "text/html": [ - "\n", - " \n", - "\n" - ], - "text/plain": [ - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Scope(Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :label), Any[\"frame_index\"], Dict{Symbol,Any}(:className => \"interact \",:style => Dict{Any,Any}(:padding => \"5px 10px 0px 10px\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-left\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :input), Any[], Dict{Symbol,Any}(:max => 101,:min => 1,:attributes => Dict{Any,Any}(:type => \"range\",Symbol(\"data-bind\") => \"numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}\",\"orient\" => \"horizontal\"),:step => 1,:className => \"slider slider is-fullwidth\",:style => Dict{Any,Any}()))], Dict{Symbol,Any}(:className => \"interact-flex-row-center\")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :p), Any[], Dict{Symbol,Any}(:attributes => Dict(\"data-bind\" => \"text: formatted_val\")))], Dict{Symbol,Any}(:className => \"interact-flex-row-right\"))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\")), Dict{String,Tuple{Observables.AbstractObservable,Union{Nothing, Bool}}}(\"changes\" => (Observable{Int64} with 1 listeners. Value:\n", - "0, nothing),\"index\" => (Observable{Int64} with 2 listeners. Value:\n", - "51, nothing)), Set(String[]), nothing, Asset[Asset(\"js\", \"knockout\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout.js\"), Asset(\"js\", \"knockout_punches\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\1sDlc\\\\src\\\\..\\\\assets\\\\knockout_punches.js\"), Asset(\"js\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\all.js\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\9mFwe\\\\src\\\\..\\\\assets\\\\style.css\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Interact\\\\SbgIk\\\\src\\\\..\\\\assets\\\\bulma_confined.min.css\")], Dict{Any,Any}(\"changes\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"changes\\\"]()) ? (this.valueFromJulia[\\\"changes\\\"]=true, this.model[\\\"changes\\\"](val)) : undefined})\")],\"index\" => Any[WebIO.JSString(\"(function (val){return (val!=this.model[\\\"index\\\"]()) ? (this.valueFromJulia[\\\"index\\\"]=true, this.model[\\\"index\\\"](val)) : undefined})\")]), WebIO.ConnectionPool(Channel{Any}(sz_max:32,sz_curr:0), Set(AbstractConnection[]), Base.GenericCondition{Base.AlwaysLockedST}(Base.InvasiveLinkedList{Task}(Task (runnable) @0x000000002c242290, Task (runnable) @0x000000002c242290), Base.AlwaysLockedST(1))), WebIO.JSString[WebIO.JSString(\"function () {\\n var handler = (function (ko, koPunches) {\\n ko.punches.enableAll();\\n ko.bindingHandlers.numericValue = {\\n init: function(element, valueAccessor, allBindings, data, context) {\\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\\n stringified.subscribe(function(value) {\\n var val = parseFloat(value);\\n if (!isNaN(val)) {\\n valueAccessor()(val);\\n }\\n });\\n valueAccessor().subscribe(function(value) {\\n var str = JSON.stringify(value);\\n if ((str == \\\"0\\\") && ([\\\"-0\\\", \\\"-0.\\\"].indexOf(stringified()) >= 0))\\n return;\\n if ([\\\"null\\\", \\\"\\\"].indexOf(str) >= 0)\\n return;\\n stringified(str);\\n });\\n ko.applyBindingsToNode(\\n element,\\n {\\n value: stringified,\\n valueUpdate: allBindings.get('valueUpdate'),\\n },\\n context,\\n );\\n }\\n };\\n var json_data = {\\\"formatted_vals\\\":[\\\"1\\\",\\\"2\\\",\\\"3\\\",\\\"4\\\",\\\"5\\\",\\\"6\\\",\\\"7\\\",\\\"8\\\",\\\"9\\\",\\\"10\\\",\\\"11\\\",\\\"12\\\",\\\"13\\\",\\\"14\\\",\\\"15\\\",\\\"16\\\",\\\"17\\\",\\\"18\\\",\\\"19\\\",\\\"20\\\",\\\"21\\\",\\\"22\\\",\\\"23\\\",\\\"24\\\",\\\"25\\\",\\\"26\\\",\\\"27\\\",\\\"28\\\",\\\"29\\\",\\\"30\\\",\\\"31\\\",\\\"32\\\",\\\"33\\\",\\\"34\\\",\\\"35\\\",\\\"36\\\",\\\"37\\\",\\\"38\\\",\\\"39\\\",\\\"40\\\",\\\"41\\\",\\\"42\\\",\\\"43\\\",\\\"44\\\",\\\"45\\\",\\\"46\\\",\\\"47\\\",\\\"48\\\",\\\"49\\\",\\\"50\\\",\\\"51\\\",\\\"52\\\",\\\"53\\\",\\\"54\\\",\\\"55\\\",\\\"56\\\",\\\"57\\\",\\\"58\\\",\\\"59\\\",\\\"60\\\",\\\"61\\\",\\\"62\\\",\\\"63\\\",\\\"64\\\",\\\"65\\\",\\\"66\\\",\\\"67\\\",\\\"68\\\",\\\"69\\\",\\\"70\\\",\\\"71\\\",\\\"72\\\",\\\"73\\\",\\\"74\\\",\\\"75\\\",\\\"76\\\",\\\"77\\\",\\\"78\\\",\\\"79\\\",\\\"80\\\",\\\"81\\\",\\\"82\\\",\\\"83\\\",\\\"84\\\",\\\"85\\\",\\\"86\\\",\\\"87\\\",\\\"88\\\",\\\"89\\\",\\\"90\\\",\\\"91\\\",\\\"92\\\",\\\"93\\\",\\\"94\\\",\\\"95\\\",\\\"96\\\",\\\"97\\\",\\\"98\\\",\\\"99\\\",\\\"100\\\",\\\"101\\\"],\\\"changes\\\":WebIO.getval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"5090847059764039543\\\",\\\"id\\\":\\\"ob_26\\\",\\\"type\\\":\\\"observable\\\"}),\\\"index\\\":WebIO.getval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"5090847059764039543\\\",\\\"id\\\":\\\"ob_25\\\",\\\"type\\\":\\\"observable\\\"})};\\n var self = this;\\n function AppViewModel() {\\n for (var key in json_data) {\\n var el = json_data[key];\\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\\n }\\n \\n [this[\\\"formatted_val\\\"]=ko.computed( function(){\\n return this.formatted_vals()[parseInt(this.index())-(1)];\\n }\\n,this)]\\n [this[\\\"changes\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"changes\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"5090847059764039543\\\",\\\"id\\\":\\\"ob_26\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"changes\\\"]=false}),self),this[\\\"index\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"index\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"5090847059764039543\\\",\\\"id\\\":\\\"ob_25\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"index\\\"]=false}),self)]\\n \\n }\\n self.model = new AppViewModel();\\n self.valueFromJulia = {};\\n for (var key in json_data) {\\n self.valueFromJulia[key] = false;\\n }\\n ko.applyBindings(self.model, self.dom);\\n}\\n);\\n (WebIO.importBlock({\\\"data\\\":[{\\\"name\\\":\\\"knockout\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/d033fda28de5fdb7c6d90919cbd6683e73bd443b-knockout.js\\\"},{\\\"name\\\":\\\"knockout_punches\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/c4515e462c6c31b06468a38b24d65546d76a0006-knockout_punches.js\\\"}],\\\"type\\\":\\\"async_block\\\"})).then((imports) => handler.apply(this, imports));\\n}\\n\")])], Dict{Symbol,Any}(:className => \"field interact-widget\")), Observable{Any} with 0 listeners. Value:\n", - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Cairo.CairoSurfaceIOStream{UInt32}(Ptr{Nothing} @0x0000000031c7f630, 1000.0, 600.0, IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1))], Dict{Symbol,Any}(:className => \"interact-flex-row interact-widget\"))], Dict{Symbol,Any}())" - ] - }, - "execution_count": 26, - "metadata": { - "application/vnd.webio.node+json": { - "kernelId": "c880022a-c1ea-42e7-bb55-6c5c298f8abd" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "timestep = 0.1\n", - "\n", - "models = Dict{Int, DriverModel}()\n", - "# constant speed model\n", - "models[1] = InterDriver(LaneSpecificAccelLatLon(0.0,0.0))\n", - "\n", - "nticks = 100\n", - "scenes = simulate!(scene, roadway, models, nticks, timestep)\n", - "\n", - "# interactive visualization\n", - "@manipulate for frame_index in 1 : length(scenes)\n", - " render(scenes[frame_index], roadway, cam=cam)\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "@webio": { - "lastCommId": "c4627755eddf4bfab0866fa3cda1ec3d", - "lastKernelId": "c880022a-c1ea-42e7-bb55-6c5c298f8abd" - }, - "kernelspec": { - "display_name": "Julia 1.2.0", - "language": "julia", - "name": "julia-1.2" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.2.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/tutorials/Sidewalk.ipynb b/tutorials/Sidewalk.ipynb deleted file mode 100644 index 57e74b2..0000000 --- a/tutorials/Sidewalk.ipynb +++ /dev/null @@ -1,761 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Sidewalk" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this notebook, we will be creating a sidewalk environment in which pedestrians can walk along the sidewalk and cross the street as cars pass." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - " Unable to load WebIO. Please make sure WebIO works for your Jupyter client.\n", - " \n", - "\n" - ], - "text/plain": [ - "HTML{String}(\"\\n\\n Unable to load WebIO. Please make sure WebIO works for your Jupyter client.\\n \\n\\n\")" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "using Parameters\n", - "using AutomotiveDrivingModels\n", - "using AutoViz\n", - "using Interact" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Define sidewalk IDs\n", - "const TOP = 1\n", - "const BOTTOM = 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Creating the Environment\n", - "Here, we create a new type of environment called SidewalkEnv. It consists of a roadway, crosswalk, and sidewalk. A sidewalk is a Vector of Lanes that run alongside the road." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "SidewalkEnv" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "@with_kw mutable struct SidewalkEnv\n", - " roadway::Roadway\n", - " crosswalk::Lane\n", - " sidewalk::Vector{Lane}\n", - "end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Defining the Sidewalk\n", - "We define the sidewalk's parameters." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6.0" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Geometry parameters\n", - "roadway_length = 100.\n", - "crosswalk_length = 15.\n", - "crosswalk_width = 6.0\n", - "crosswalk_pos = roadway_length/2\n", - "sidewalk_width = 3.0\n", - "sidewalk_pos = crosswalk_length/2 - sidewalk_width / 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we create the sidewalk environment. \n", - "Our environment will consist of:\n", - "* 1-way road with 2 lanes\n", - "* Unsignalized zebra crosswalk perpendicular to the road\n", - "* Sidewalks above and below the road" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate straight roadway of length roadway_length with 2 lanes.\n", - "# Returns a Roadway type (Array of segments).\n", - "# There is already a method to generate a simple straight roadway, which we use here.\n", - "roadway = gen_straight_roadway(2, roadway_length) \n", - "\n", - "# Generate the crosswalk.\n", - "# Our crosswalk does not have a predefined method for generation, so we define it with a LaneTag and a curve.\n", - "n_samples = 2 # for curve generation\n", - "crosswalk = Lane(LaneTag(2,1), gen_straight_curve(VecE2(crosswalk_pos, -crosswalk_length/2),\n", - " VecE2(crosswalk_pos, crosswalk_length/2),\n", - " n_samples), width = crosswalk_width)\n", - "cw_segment = RoadSegment(2, [crosswalk])\n", - "push!(roadway.segments, cw_segment) # Append the crosswalk to the roadway\n", - "\n", - "# Generate the sidewalk.\n", - "top_sidewalk = Lane(LaneTag(3, TOP), gen_straight_curve(VecE2(0., sidewalk_pos),\n", - " VecE2(roadway_length, sidewalk_pos),\n", - " n_samples), width = sidewalk_width)\n", - "bottom_sidewalk = Lane(LaneTag(3, BOTTOM), gen_straight_curve(VecE2(0., -(sidewalk_pos - sidewalk_width)),\n", - " VecE2(roadway_length, -(sidewalk_pos - sidewalk_width)),\n", - " n_samples), width = sidewalk_width) \n", - " # Note: we subtract the sidewalk_width from the sidewalk position so that the edge is flush with the road.\n", - "\n", - "\n", - "sw_segment = RoadSegment(3, [top_sidewalk, bottom_sidewalk])\n", - "push!(roadway.segments, sw_segment)\n", - "\n", - "# Initialize crosswalk environment\n", - "env = SidewalkEnv(roadway, crosswalk, [top_sidewalk, bottom_sidewalk]);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since there is no defined render! method for the crosswalk and the sidewalk, we must define it ourselves." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "function AutoViz.render!(rendermodel::RenderModel, env::SidewalkEnv)\n", - " # Render sidewalk\n", - " for sw in env.sidewalk\n", - " curve = sw.curve\n", - " n = length(curve)\n", - " pts = Array{Float64}(undef, 2, n)\n", - " for (i,pt) in enumerate(curve)\n", - " pts[1,i] = pt.pos.x\n", - " pts[2,i] = pt.pos.y\n", - " end\n", - " add_instruction!(rendermodel, render_line, (pts, colorant\"grey\", sw.width, Cairo.CAIRO_LINE_CAP_BUTT))\n", - " end\n", - " \n", - " # Render roadway\n", - " roadway = gen_straight_roadway(2, roadway_length)\n", - " render!(rendermodel, roadway)\n", - " \n", - " # Render crosswalk\n", - " curve = env.crosswalk.curve\n", - " n = length(curve)\n", - " pts = Array{Float64}(undef, 2, n)\n", - " for (i,pt) in enumerate(curve)\n", - " pts[1,i] = pt.pos.x\n", - " pts[2,i] = pt.pos.y\n", - " end\n", - "\n", - " # We can add render instructions from AutoViz.\n", - " # Here we want the crosswalk to appear as a white-striped zebra crossing rather than a road.\n", - " add_instruction!(rendermodel, render_dashed_line, (pts, colorant\"white\", env.crosswalk.width, 1.0, 1.0, 0.0, Cairo.CAIRO_LINE_CAP_BUTT))\n", - "\n", - " return rendermodel\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "cam = FitToContentCamera(0.0)\n", - "render(Scene(), env, cam = cam);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can define our pedestrian." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "VehicleDef(PEDESTRIAN, 1.000, 1.000)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# We define its class and the dimensions of its bounding box.\n", - "const PEDESTRIAN_DEF = VehicleDef(AgentClass.PEDESTRIAN, 1.0, 1.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We assign models to each agent in the scene." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "LatLonSeparableDriver(ProportionalLaneTracker(NaN, NaN, 3.0, 2.0), IntelligentDriverModel\n", - " a: Float64 NaN\n", - " σ: Float64 NaN\n", - " k_spd: Float64 1.0\n", - " δ: Float64 4.0\n", - " T: Float64 1.5\n", - " v_des: Float64 29.0\n", - " s_min: Float64 5.0\n", - " a_max: Float64 3.0\n", - " d_cmf: Float64 2.0\n", - " d_max: Float64 9.0\n", - ")" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "timestep = 0.1\n", - "\n", - "# Crossing pedestrian definition\n", - "ped_init_state = VehicleState(VecSE2(49.0,-3.0,0.), env.sidewalk[BOTTOM], roadway, 1.3)\n", - "ped = Vehicle(ped_init_state, PEDESTRIAN_DEF, 1)\n", - "\n", - "# Car definition\n", - "car_initial_state = VehicleState(VecSE2(0.0, 0., 0.), roadway.segments[1].lanes[1],roadway, 8.0)\n", - "car = Vehicle(car_initial_state, VehicleDef(), 2)\n", - "\n", - "scene = Scene()\n", - "push!(scene, ped)\n", - "push!(scene, car)\n", - "\n", - "# Define a model for each entity present in the scene\n", - "models = Dict{Int, DriverModel}()\n", - "\n", - "ped_id = 1\n", - "car_id = 2\n", - "\n", - "models[ped_id] = SidewalkPedestrianModel(timestep=timestep, \n", - " crosswalk=env.crosswalk,\n", - " sw_origin = env.sidewalk[BOTTOM],\n", - " sw_dest = env.sidewalk[TOP]\n", - " )\n", - "\n", - "models[car_id] = \n", - "LatLonSeparableDriver( # produces LatLonAccels\n", - " ProportionalLaneTracker(), # lateral model\n", - " IntelligentDriverModel(), # longitudinal model\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Simulate\n", - "Finally, we simulate the scene." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAIAAAB+fFtyAAAABmJLR0QA/wD/AP+gvaeTAAAT7ElEQVR4nO3daWwc53kH8HeXuzxE6pYoW1Ikyo4sJ3ZkS8ihWDns2k4T1zYKpCmatEEDpG6bNICRwijyJUCNotentOiBFEhRu6iTAk5TJ06C1nUsq65SO7KV0IckS5ZJHaQkWhTF+9hj+kFKrLg7FFcccjTM7/dpxXd3n0ecl8P/DN+ZDQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGChyG3fvj3tHgAWpsbGxrvuuivtLupw7Nixffv2pd0FwMJ0+vTpnp6e2bxD4d57702qGwAu1tra+sADD6TdRR06Ozsfe+yxtLsAWJj27Nkzy+CeT6oVAABg7gjuAACQAYW0GwAALkfzeLT1xdBxNNcyFk205Lo7QudNYaI57baAOSO4A0D2vGN/dM93cy1jUQhRCCGE6PoD4dZd4bv35F65IeXegDkiuANAxrzzlejXvhlyUfSWrzdPhI8/Ws1X8y+9K5W+gLlljTsAZMmisXDvd0LuraH9glzI3f3d0DYyvz0B80JwB4As2f5C1DQ53RMaJ6PtL8TkeiDLBHcAyJJrunIXHv3m1vDy58OR+8OPfz/83rtDc6HGc4AFxBp3gLkyOTn5+OOPp91FHfr7+9NugUtrHf3po+XN4Yb2C4+/enf44o7wSw+H3uEQQttwFILsDguN4A4wV8rl8r59+9LugoVmvPmny2CmKm8+eOgn4ctPhb4LoX68JY3OgDkmuANAlhzfkNt4NAohhG+8HL53KIyVw2Q5jJVCePMs+7ENaXYIzBFr3AEgS/ZtiyqFXAghDE+GnuEwMB7GSiGEn6X2aj688G7rZGABEtwBIEsGVuSeum26m8Y8fVvu7Ip5aweYP5bKAEDG/HBnrqEabtsVctWfS/DVfNh9a+6ZD7gyFRYmwR0AsueZD4YD10fv/VHo6A6to2G0Lde9MXr+Pbm+9iC1w0IluANAJp1Znfv+r1z8BXkdFjhr3AEAIAMEdwAAyABLZQDmSktLy2c+85m0u6jDwYMHd+3alXYXANQmuAPMlXw+397efunnXTFOnjyZdgsAxLJUBgAAMkBwBwCADBDcAQAgAwR3AADIAMEdAAAyQHAHAIAMENwBACADcs/tfSHtHgAWpkKhcPPWG9Puog79/We7jh5LuwuAhWl0bOy3PvUbvT09l/0OhcHRiQQbAuBiP3jm2bRbAOCKUClHlUplNu9Q+P7Te5PqBgAAqKlaqfb3n53NO1jjDgAAGSC4AwBABgjuAACQAYI7AABkgOAOAAAZILgDAEAGCO4AAJABhbQbAFiwGvL5TRvWpt1FHYZGRvvODKTdBQC1Ce4Ac6WlpfkPfvvjaXdRh72dB77+2BNpdwFAbZbKAABABgjuAACQAYI7AABkgOAOAAAZILgDAEAGCO4AAJABgjsAAGSA4A4AABngA5gA5srUVOmpPS+k3UUdjveeTrsFAGIJ7gBzZapUevzJ/0m7CwAWCEtlAAAgAwR3AADIAMEdAAAyQHAHAIAMENwBACADBHcAAMgAwR0AADKgcON1G+PGTpw8c254NKlKm9avaV3UXHssCq929ZTK5UQKNTTkt2xan8/nao6OT0wdOXYykUIhhCVtizasXR032tc/2Nd/Lqlaa9tXrFi2uPZYFF4/cWpsfDKRQrkQNm9a11isfY//crlyqKunGkWJ1Gpuarx2w9W52tsqDA2PHTv5RiKFQggrly25un153GjPqf6BoZGkanWsX9M2P7M9n99yTexsn5wsHT7am0ihEMLi1paN69rjRt84O3T6zEBStda2r1yxrK32WBS6e06PjE0kUigXwuaOdY2NtWd7pVI9+PqJKKnZ3li8duPaK2K2n+4fGExstm9c1764taX2WBQOdfdMlZKZ7fl8fsumdQ0Ntc83TUyWXktutrctau5YvyZu9MzA0Kk3EpvtV69esXJ5zL49hO4TfSNj40nV2rxxbVNTseZQpVJ99fUTSe3bG4vF6zrWhpjZPjwyfrS3L5FCIYSVyxZf3b4ibvRk39n+c8NJ1dq4tn1xW+xsP3y0d3KqlEihfC635Zr1cbN9cqp0uDvB2d7SsT5233723HBv39mkal21avmqFUviRrtPJLZvDyG8fePa5pjZXq1GB18/Ua1WEynUWCxc17EubraPjE509yT5wXaF299/c9zY8y8d3rNvf1KV7rhl26KWpppDURQGhkZ6TvcnUmjlsiV33HJzLubX41Sp9A/fOJXUvmnLpvW3bH9H3OhrR3u/9/TeRAqFEG7Z/s51a1bGjUY//Mkrh48mUqi5qfHOndsKDQ01R6tRdLLv7ODIWCK11l+16o5bYmdg/7nhf/n2U4kUCiFse+c1N2yOPUzd98qRZ55/Oalat7//prZFtXfuURSGRhKLaMuXtk0z20vl8usnTlUqyeybNnes/eC7b4wbff34qcefei6RQiGEHTdvedvVsYfEu5598cVXuxIpVCwW79i5rViIme3Vam/f2cFZnL9obmr81K9+5PzjRS1NV6+OjRdTpfLx5IL7quVLli5ujRs9NzTaf26o5tDhruPP/Kizrlq37bhpaduiuNHh0cQi2vIlbXfs3JaPne2Voz2nS+VKIrU2d6z70HtiZ3t3z+lvP/lsIoVCCDtuvn6aE0BPP/di58GEZnuhcOcHthULtQ9Tq1F06sxAUkd0a9esuD1+3z44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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwC+D/AJU9dtIA/shaAAAAAElFTkSuQmCC", - "text/plain": [ - "Cairo.CairoSurfaceBase{UInt32}(Ptr{Nothing} @0x00000000209a9c00, 1000.0, 600.0)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "nticks = 300\n", - "rec = SceneRecord(nticks+1, timestep)\n", - "# Execute the simulation\n", - "simulate!(rec, scene, roadway, models, nticks)\n", - "render(rec[0], env, cam=cam)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can use a slider to scroll through each frame in the simulation. This usually takes less time than rendering a video." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.webio.node+json": { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - { - "children": [ - "frame_index" - ], - "instanceArgs": { - "namespace": "html", - "tag": "label" - }, - "nodeType": "DOM", - "props": { - "className": "interact ", - "style": { - "padding": "5px 10px 0px 10px" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-left" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "input" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "value: indexString, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}", - "orient": "horizontal", - "type": "range" - }, - "className": "slider slider is-fullwidth", - "max": 301, - "min": 1, - "step": 1, - "style": {} - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-center" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "p" - }, - "nodeType": "DOM", - "props": { - "attributes": { - "data-bind": "text: formatted_val" - } - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row-right" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - ], - "instanceArgs": { - "handlers": { - "changes": [ - "(function (val){return (val!=this.model[\"changes\"]()) ? (this.valueFromJulia[\"changes\"]=true, this.model[\"changes\"](val)) : undefined})" - ], - "index": [ - "(function (val){return (val!=this.model[\"index\"]()) ? (this.valueFromJulia[\"index\"]=true, this.model[\"index\"](val)) : undefined})" - ], - "indexString": [ - "(function (val){return (val!=this.model[\"indexString\"]()) ? (this.valueFromJulia[\"indexString\"]=true, this.model[\"indexString\"](val)) : undefined})" - ] - }, - "id": "knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f", - "imports": { - "data": [ - { - "name": "knockout", - "type": "js", - "url": "/assetserver/3eba94e42381e338b63445bb6165a6b74dfff7fe-knockout.js" - }, - { - "name": "knockout_punches", - "type": "js", - "url": "/assetserver/0b60b3bed0558f340d8f36b2e588fc19a5331e53-knockout_punches.js" - }, - { - "name": null, - "type": "js", - "url": "/assetserver/e375b04ed295e371b269e6282dd0ece1d8f25f7c-all.js" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/74ab3fe28fdc96d2cdde1dc9103cd558bf15dd78-style.css" - }, - { - "name": null, - "type": "css", - "url": "/assetserver/2b9bd1a7f1fd27241339301563046b45b31a5a73-bulma_confined.min.css" - } - ], - "type": "async_block" - }, - "mount_callbacks": [ - "function () {\n var handler = (function (ko, koPunches) {\n ko.punches.enableAll();\n ko.bindingHandlers.numericValue = {\n init : function(element, valueAccessor, allBindings, data, context) {\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\n stringified.subscribe(function(value) {\n var val = parseFloat(value);\n if (!isNaN(val)) {\n valueAccessor()(val);\n }\n })\n valueAccessor().subscribe(function(value) {\n var str = JSON.stringify(value);\n if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(stringified()) >= 0))\n return;\n if ([\"null\", \"\"].indexOf(str) >= 0)\n return;\n stringified(str);\n })\n ko.applyBindingsToNode(element, { value: stringified, valueUpdate: allBindings.get('valueUpdate')}, context);\n }\n };\n var json_data = {\"formatted_vals\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"29\",\"30\",\"31\",\"32\",\"33\",\"34\",\"35\",\"36\",\"37\",\"38\",\"39\",\"40\",\"41\",\"42\",\"43\",\"44\",\"45\",\"46\",\"47\",\"48\",\"49\",\"50\",\"51\",\"52\",\"53\",\"54\",\"55\",\"56\",\"57\",\"58\",\"59\",\"60\",\"61\",\"62\",\"63\",\"64\",\"65\",\"66\",\"67\",\"68\",\"69\",\"70\",\"71\",\"72\",\"73\",\"74\",\"75\",\"76\",\"77\",\"78\",\"79\",\"80\",\"81\",\"82\",\"83\",\"84\",\"85\",\"86\",\"87\",\"88\",\"89\",\"90\",\"91\",\"92\",\"93\",\"94\",\"95\",\"96\",\"97\",\"98\",\"99\",\"100\",\"101\",\"102\",\"103\",\"104\",\"105\",\"106\",\"107\",\"108\",\"109\",\"110\",\"111\",\"112\",\"113\",\"114\",\"115\",\"116\",\"117\",\"118\",\"119\",\"120\",\"121\",\"122\",\"123\",\"124\",\"125\",\"126\",\"127\",\"128\",\"129\",\"130\",\"131\",\"132\",\"133\",\"134\",\"135\",\"136\",\"137\",\"138\",\"139\",\"140\",\"141\",\"142\",\"143\",\"144\",\"145\",\"146\",\"147\",\"148\",\"149\",\"150\",\"151\",\"152\",\"153\",\"154\",\"155\",\"156\",\"157\",\"158\",\"159\",\"160\",\"161\",\"162\",\"163\",\"164\",\"165\",\"166\",\"167\",\"168\",\"169\",\"170\",\"171\",\"172\",\"173\",\"174\",\"175\",\"176\",\"177\",\"178\",\"179\",\"180\",\"181\",\"182\",\"183\",\"184\",\"185\",\"186\",\"187\",\"188\",\"189\",\"190\",\"191\",\"192\",\"193\",\"194\",\"195\",\"196\",\"197\",\"198\",\"199\",\"200\",\"201\",\"202\",\"203\",\"204\",\"205\",\"206\",\"207\",\"208\",\"209\",\"210\",\"211\",\"212\",\"213\",\"214\",\"215\",\"216\",\"217\",\"218\",\"219\",\"220\",\"221\",\"222\",\"223\",\"224\",\"225\",\"226\",\"227\",\"228\",\"229\",\"230\",\"231\",\"232\",\"233\",\"234\",\"235\",\"236\",\"237\",\"238\",\"239\",\"240\",\"241\",\"242\",\"243\",\"244\",\"245\",\"246\",\"247\",\"248\",\"249\",\"250\",\"251\",\"252\",\"253\",\"254\",\"255\",\"256\",\"257\",\"258\",\"259\",\"260\",\"261\",\"262\",\"263\",\"264\",\"265\",\"266\",\"267\",\"268\",\"269\",\"270\",\"271\",\"272\",\"273\",\"274\",\"275\",\"276\",\"277\",\"278\",\"279\",\"280\",\"281\",\"282\",\"283\",\"284\",\"285\",\"286\",\"287\",\"288\",\"289\",\"290\",\"291\",\"292\",\"293\",\"294\",\"295\",\"296\",\"297\",\"298\",\"299\",\"300\",\"301\"],\"changes\":WebIO.getval({\"name\":\"changes\",\"scope\":\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\",\"id\":\"ob_02\",\"type\":\"observable\"}),\"indexString\":WebIO.getval({\"name\":\"indexString\",\"scope\":\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\",\"id\":\"ob_03\",\"type\":\"observable\"}),\"index\":WebIO.getval({\"name\":\"index\",\"scope\":\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\",\"id\":\"ob_01\",\"type\":\"observable\"})};\n var self = this;\n function AppViewModel() {\n for (var key in json_data) {\n var el = json_data[key];\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\n }\n \n [this[\"formatted_val\"]=ko.computed( function(){\n return this.formatted_vals()[parseInt(this.index())-1];\n }\n,this)]\n [this[\"changes\"].subscribe((function (val){!(this.valueFromJulia[\"changes\"]) ? (WebIO.setval({\"name\":\"changes\",\"scope\":\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\",\"id\":\"ob_02\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"changes\"]=false}),self),this[\"indexString\"].subscribe((function (val){!(this.valueFromJulia[\"indexString\"]) ? (WebIO.setval({\"name\":\"indexString\",\"scope\":\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\",\"id\":\"ob_03\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"indexString\"]=false}),self),this[\"index\"].subscribe((function (val){!(this.valueFromJulia[\"index\"]) ? (WebIO.setval({\"name\":\"index\",\"scope\":\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\",\"id\":\"ob_01\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"index\"]=false}),self)]\n var obs = this.index;\n var obsString = this.indexString;\n obsString.subscribe(function(value) {\n var val = parseFloat(value);\n if (!isNaN(val)) {\n obs(val);\n }\n })\n obs.subscribe(function(value) {\n var str = JSON.stringify(value);\n if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(obsString()) >= 0))\n return;\n if ([\"null\", \"\"].indexOf(str) >= 0)\n return;\n obsString(str);\n })\n\n \n\n }\n self.model = new AppViewModel();\n self.valueFromJulia = {};\n for (var key in json_data) {\n self.valueFromJulia[key] = false;\n }\n ko.applyBindings(self.model, self.dom);\n}\n);\n (WebIO.importBlock({\"data\":[{\"name\":\"knockout\",\"type\":\"js\",\"url\":\"/assetserver/3eba94e42381e338b63445bb6165a6b74dfff7fe-knockout.js\"},{\"name\":\"knockout_punches\",\"type\":\"js\",\"url\":\"/assetserver/0b60b3bed0558f340d8f36b2e588fc19a5331e53-knockout_punches.js\"}],\"type\":\"async_block\"})).then((imports) => handler.apply(this, imports));\n}\n" - ], - "observables": { - "changes": { - "id": "ob_02", - "sync": false, - "value": 0 - }, - "index": { - "id": "ob_01", - "sync": true, - "value": 151 - }, - "indexString": { - "id": "ob_03", - "sync": false, - "value": "151" - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "field interact-widget" - }, - "type": "node" - }, - { - "children": [ - { - "children": [], - "instanceArgs": { - "id": "ob_09", - "name": "obs-node" - }, - "nodeType": "ObservableNode", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "handlers": {}, - "id": "scope-05c5f52f-549f-401a-828a-b9b7a548d947", - "imports": { - "data": [], - "type": "async_block" - }, - "mount_callbacks": [], - "observables": { - "obs-node": { - "id": "ob_09", - "sync": false, - "value": { - "children": [ - { - "children": [], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "setInnerHtml": "" - }, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": { - "className": "interact-flex-row interact-widget" - }, - "type": "node" - } - } - }, - "systemjs_options": null - }, - "nodeType": "Scope", - "props": {}, - "type": "node" - } - ], - "instanceArgs": { - "namespace": "html", - "tag": "div" - }, - "nodeType": "DOM", - "props": {}, - "type": "node" - }, - "text/html": [ - "\n", - " \n", - "\n" - ], - "text/plain": [ - "Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{DOM}(DOM(:html, :div), Any[Scope(\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\", Node{DOM}(DOM(:html, :div), Any[Node{DOM}(DOM(:html, :div), Any[Node{DOM}(DOM(:html, :label), Any[\"frame_index\"], Dict{Symbol,Any}(:className=>\"interact \",:style=>Dict{Any,Any}(:padding=>\"5px 10px 0px 10px\")), 1)], Dict{Symbol,Any}(:className=>\"interact-flex-row-left\"), 2), Node{DOM}(DOM(:html, :div), Any[Node{DOM}(DOM(:html, :input), Any[], Dict{Symbol,Any}(:max=>301,:min=>1,:attributes=>Dict{Any,Any}(:type=>\"range\",Symbol(\"data-bind\")=>\"value: indexString, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}\",\"orient\"=>\"horizontal\"),:step=>1,:className=>\"slider slider is-fullwidth\",:style=>Dict{Any,Any}()), 0)], Dict{Symbol,Any}(:className=>\"interact-flex-row-center\"), 1), Node{DOM}(DOM(:html, :div), Any[Node{DOM}(DOM(:html, :p), Any[], Dict{Symbol,Any}(:attributes=>Dict(\"data-bind\"=>\"text: formatted_val\")), 0)], Dict{Symbol,Any}(:className=>\"interact-flex-row-right\"), 1)], Dict{Symbol,Any}(:className=>\"interact-flex-row interact-widget\"), 7), Dict{String,Tuple{Observables.AbstractObservable,Union{Nothing, Bool}}}(\"changes\"=>(Observable{Int64} with 1 listeners. Value:\n", - "0, nothing),\"indexString\"=>(Observable{String} with 1 listeners. Value:\n", - "\"151\", nothing),\"index\"=>(Observable{Int64} with 2 listeners. Value:\n", - "151, nothing)), Set(String[]), nothing, Asset[Asset(\"js\", \"knockout\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\JE2Yq\\\\src\\\\..\\\\assets\\\\knockout.js\"), Asset(\"js\", \"knockout_punches\", \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Knockout\\\\JE2Yq\\\\src\\\\..\\\\assets\\\\knockout_punches.js\"), Asset(\"js\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\jyXKw\\\\src\\\\..\\\\assets\\\\all.js\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\InteractBase\\\\jyXKw\\\\src\\\\..\\\\assets\\\\style.css\"), Asset(\"css\", nothing, \"C:\\\\Users\\\\Maxime\\\\.julia\\\\packages\\\\Interact\\\\Fs3lV\\\\src\\\\..\\\\assets\\\\bulma_confined.min.css\")], Dict{Any,Any}(\"changes\"=>Any[JSString(\"(function (val){return (val!=this.model[\\\"changes\\\"]()) ? (this.valueFromJulia[\\\"changes\\\"]=true, this.model[\\\"changes\\\"](val)) : undefined})\")],\"indexString\"=>Any[JSString(\"(function (val){return (val!=this.model[\\\"indexString\\\"]()) ? (this.valueFromJulia[\\\"indexString\\\"]=true, this.model[\\\"indexString\\\"](val)) : undefined})\")],\"index\"=>Any[JSString(\"(function (val){return (val!=this.model[\\\"index\\\"]()) ? (this.valueFromJulia[\\\"index\\\"]=true, this.model[\\\"index\\\"](val)) : undefined})\")]), ConnectionPool(Channel{Any}(sz_max:9223372036854775807,sz_curr:0), Set(AbstractConnection[]), Channel{AbstractConnection}(sz_max:32,sz_curr:0)), WebIO.JSString[JSString(\"function () {\\n var handler = (function (ko, koPunches) {\\n ko.punches.enableAll();\\n ko.bindingHandlers.numericValue = {\\n init : function(element, valueAccessor, allBindings, data, context) {\\n var stringified = ko.observable(ko.unwrap(valueAccessor()));\\n stringified.subscribe(function(value) {\\n var val = parseFloat(value);\\n if (!isNaN(val)) {\\n valueAccessor()(val);\\n }\\n })\\n valueAccessor().subscribe(function(value) {\\n var str = JSON.stringify(value);\\n if ((str == \\\"0\\\") && ([\\\"-0\\\", \\\"-0.\\\"].indexOf(stringified()) >= 0))\\n return;\\n if ([\\\"null\\\", \\\"\\\"].indexOf(str) >= 0)\\n return;\\n stringified(str);\\n })\\n ko.applyBindingsToNode(element, { value: stringified, valueUpdate: allBindings.get('valueUpdate')}, context);\\n }\\n };\\n var json_data = {\\\"formatted_vals\\\":[\\\"1\\\",\\\"2\\\",\\\"3\\\",\\\"4\\\",\\\"5\\\",\\\"6\\\",\\\"7\\\",\\\"8\\\",\\\"9\\\",\\\"10\\\",\\\"11\\\",\\\"12\\\",\\\"13\\\",\\\"14\\\",\\\"15\\\",\\\"16\\\",\\\"17\\\",\\\"18\\\",\\\"19\\\",\\\"20\\\",\\\"21\\\",\\\"22\\\",\\\"23\\\",\\\"24\\\",\\\"25\\\",\\\"26\\\",\\\"27\\\",\\\"28\\\",\\\"29\\\",\\\"30\\\",\\\"31\\\",\\\"32\\\",\\\"33\\\",\\\"34\\\",\\\"35\\\",\\\"36\\\",\\\"37\\\",\\\"38\\\",\\\"39\\\",\\\"40\\\",\\\"41\\\",\\\"42\\\",\\\"43\\\",\\\"44\\\",\\\"45\\\",\\\"46\\\",\\\"47\\\",\\\"48\\\",\\\"49\\\",\\\"50\\\",\\\"51\\\",\\\"52\\\",\\\"53\\\",\\\"54\\\",\\\"55\\\",\\\"56\\\",\\\"57\\\",\\\"58\\\",\\\"59\\\",\\\"60\\\",\\\"61\\\",\\\"62\\\",\\\"63\\\",\\\"64\\\",\\\"65\\\",\\\"66\\\",\\\"67\\\",\\\"68\\\",\\\"69\\\",\\\"70\\\",\\\"71\\\",\\\"72\\\",\\\"73\\\",\\\"74\\\",\\\"75\\\",\\\"76\\\",\\\"77\\\",\\\"78\\\",\\\"79\\\",\\\"80\\\",\\\"81\\\",\\\"82\\\",\\\"83\\\",\\\"84\\\",\\\"85\\\",\\\"86\\\",\\\"87\\\",\\\"88\\\",\\\"89\\\",\\\"90\\\",\\\"91\\\",\\\"92\\\",\\\"93\\\",\\\"94\\\",\\\"95\\\",\\\"96\\\",\\\"97\\\",\\\"98\\\",\\\"99\\\",\\\"100\\\",\\\"101\\\",\\\"102\\\",\\\"103\\\",\\\"104\\\",\\\"105\\\",\\\"106\\\",\\\"107\\\",\\\"108\\\",\\\"109\\\",\\\"110\\\",\\\"111\\\",\\\"112\\\",\\\"113\\\",\\\"114\\\",\\\"115\\\",\\\"116\\\",\\\"117\\\",\\\"118\\\",\\\"119\\\",\\\"120\\\",\\\"121\\\",\\\"122\\\",\\\"123\\\",\\\"124\\\",\\\"125\\\",\\\"126\\\",\\\"127\\\",\\\"128\\\",\\\"129\\\",\\\"130\\\",\\\"131\\\",\\\"132\\\",\\\"133\\\",\\\"134\\\",\\\"135\\\",\\\"136\\\",\\\"137\\\",\\\"138\\\",\\\"139\\\",\\\"140\\\",\\\"141\\\",\\\"142\\\",\\\"143\\\",\\\"144\\\",\\\"145\\\",\\\"146\\\",\\\"147\\\",\\\"148\\\",\\\"149\\\",\\\"150\\\",\\\"151\\\",\\\"152\\\",\\\"153\\\",\\\"154\\\",\\\"155\\\",\\\"156\\\",\\\"157\\\",\\\"158\\\",\\\"159\\\",\\\"160\\\",\\\"161\\\",\\\"162\\\",\\\"163\\\",\\\"164\\\",\\\"165\\\",\\\"166\\\",\\\"167\\\",\\\"168\\\",\\\"169\\\",\\\"170\\\",\\\"171\\\",\\\"172\\\",\\\"173\\\",\\\"174\\\",\\\"175\\\",\\\"176\\\",\\\"177\\\",\\\"178\\\",\\\"179\\\",\\\"180\\\",\\\"181\\\",\\\"182\\\",\\\"183\\\",\\\"184\\\",\\\"185\\\",\\\"186\\\",\\\"187\\\",\\\"188\\\",\\\"189\\\",\\\"190\\\",\\\"191\\\",\\\"192\\\",\\\"193\\\",\\\"194\\\",\\\"195\\\",\\\"196\\\",\\\"197\\\",\\\"198\\\",\\\"199\\\",\\\"200\\\",\\\"201\\\",\\\"202\\\",\\\"203\\\",\\\"204\\\",\\\"205\\\",\\\"206\\\",\\\"207\\\",\\\"208\\\",\\\"209\\\",\\\"210\\\",\\\"211\\\",\\\"212\\\",\\\"213\\\",\\\"214\\\",\\\"215\\\",\\\"216\\\",\\\"217\\\",\\\"218\\\",\\\"219\\\",\\\"220\\\",\\\"221\\\",\\\"222\\\",\\\"223\\\",\\\"224\\\",\\\"225\\\",\\\"226\\\",\\\"227\\\",\\\"228\\\",\\\"229\\\",\\\"230\\\",\\\"231\\\",\\\"232\\\",\\\"233\\\",\\\"234\\\",\\\"235\\\",\\\"236\\\",\\\"237\\\",\\\"238\\\",\\\"239\\\",\\\"240\\\",\\\"241\\\",\\\"242\\\",\\\"243\\\",\\\"244\\\",\\\"245\\\",\\\"246\\\",\\\"247\\\",\\\"248\\\",\\\"249\\\",\\\"250\\\",\\\"251\\\",\\\"252\\\",\\\"253\\\",\\\"254\\\",\\\"255\\\",\\\"256\\\",\\\"257\\\",\\\"258\\\",\\\"259\\\",\\\"260\\\",\\\"261\\\",\\\"262\\\",\\\"263\\\",\\\"264\\\",\\\"265\\\",\\\"266\\\",\\\"267\\\",\\\"268\\\",\\\"269\\\",\\\"270\\\",\\\"271\\\",\\\"272\\\",\\\"273\\\",\\\"274\\\",\\\"275\\\",\\\"276\\\",\\\"277\\\",\\\"278\\\",\\\"279\\\",\\\"280\\\",\\\"281\\\",\\\"282\\\",\\\"283\\\",\\\"284\\\",\\\"285\\\",\\\"286\\\",\\\"287\\\",\\\"288\\\",\\\"289\\\",\\\"290\\\",\\\"291\\\",\\\"292\\\",\\\"293\\\",\\\"294\\\",\\\"295\\\",\\\"296\\\",\\\"297\\\",\\\"298\\\",\\\"299\\\",\\\"300\\\",\\\"301\\\"],\\\"changes\\\":WebIO.getval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\\\",\\\"id\\\":\\\"ob_02\\\",\\\"type\\\":\\\"observable\\\"}),\\\"indexString\\\":WebIO.getval({\\\"name\\\":\\\"indexString\\\",\\\"scope\\\":\\\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\\\",\\\"id\\\":\\\"ob_03\\\",\\\"type\\\":\\\"observable\\\"}),\\\"index\\\":WebIO.getval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\\\",\\\"id\\\":\\\"ob_01\\\",\\\"type\\\":\\\"observable\\\"})};\\n var self = this;\\n function AppViewModel() {\\n for (var key in json_data) {\\n var el = json_data[key];\\n this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\\n }\\n \\n [this[\\\"formatted_val\\\"]=ko.computed( function(){\\n return this.formatted_vals()[parseInt(this.index())-1];\\n }\\n,this)]\\n [this[\\\"changes\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"changes\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"changes\\\",\\\"scope\\\":\\\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\\\",\\\"id\\\":\\\"ob_02\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"changes\\\"]=false}),self),this[\\\"indexString\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"indexString\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"indexString\\\",\\\"scope\\\":\\\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\\\",\\\"id\\\":\\\"ob_03\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"indexString\\\"]=false}),self),this[\\\"index\\\"].subscribe((function (val){!(this.valueFromJulia[\\\"index\\\"]) ? (WebIO.setval({\\\"name\\\":\\\"index\\\",\\\"scope\\\":\\\"knockout-component-7dfdc687-c950-4e14-8de4-3d73d131df9f\\\",\\\"id\\\":\\\"ob_01\\\",\\\"type\\\":\\\"observable\\\"},val)) : undefined; return this.valueFromJulia[\\\"index\\\"]=false}),self)]\\n var obs = this.index;\\n var obsString = this.indexString;\\n obsString.subscribe(function(value) {\\n var val = parseFloat(value);\\n if (!isNaN(val)) {\\n obs(val);\\n }\\n })\\n obs.subscribe(function(value) {\\n var str = JSON.stringify(value);\\n if ((str == \\\"0\\\") && ([\\\"-0\\\", \\\"-0.\\\"].indexOf(obsString()) >= 0))\\n return;\\n if ([\\\"null\\\", \\\"\\\"].indexOf(str) >= 0)\\n return;\\n obsString(str);\\n })\\n\\n \\n\\n }\\n self.model = new AppViewModel();\\n self.valueFromJulia = {};\\n for (var key in json_data) {\\n self.valueFromJulia[key] = false;\\n }\\n ko.applyBindings(self.model, self.dom);\\n}\\n);\\n (WebIO.importBlock({\\\"data\\\":[{\\\"name\\\":\\\"knockout\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/3eba94e42381e338b63445bb6165a6b74dfff7fe-knockout.js\\\"},{\\\"name\\\":\\\"knockout_punches\\\",\\\"type\\\":\\\"js\\\",\\\"url\\\":\\\"/assetserver/0b60b3bed0558f340d8f36b2e588fc19a5331e53-knockout_punches.js\\\"}],\\\"type\\\":\\\"async_block\\\"})).then((imports) => handler.apply(this, imports));\\n}\\n\")])], Dict{Symbol,Any}(:className=>\"field interact-widget\"), 1), Observable{Any} with 0 listeners. Value:\n", - "Node{DOM}(DOM(:html, :div), Any[CairoSurfaceBase{UInt32}(Ptr{Nothing} @0x00000000209a8c60, 1000.0, 600.0)], Dict{Symbol,Any}(:className=>\"interact-flex-row interact-widget\"), 1)], Dict{Symbol,Any}(), 2)" - ] - }, - "execution_count": 11, - "metadata": { - "application/vnd.webio.node+json": { - "kernelId": "a4011d3d-7ce8-45d0-9c5b-98ef8e60f4d0" - } - }, - "output_type": "execute_result" - } - ], - "source": [ - "using Interact\n", - "@manipulate for frame_index in 1 : nframes(rec)\n", - " render(rec[frame_index-nframes(rec)], env, cam=cam)\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "@webio": { - "lastCommId": "ec5210cff4f94500ae7860b20ebcff6f", - "lastKernelId": "a4011d3d-7ce8-45d0-9c5b-98ef8e60f4d0" - }, - "kernelspec": { - "display_name": "Julia 1.1.0", - "language": "julia", - "name": "julia-1.1" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.1.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/tutorials/reel-15747935788548452579.gif b/tutorials/reel-15747935788548452579.gif deleted file mode 100644 index f229f4a..0000000 Binary files a/tutorials/reel-15747935788548452579.gif and /dev/null differ diff --git a/tutorials/roadway.svg b/tutorials/roadway.svg deleted file mode 100644 index 351b71e..0000000 --- a/tutorials/roadway.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -