From 676e076ae1caa0c6fbcf55a2a62bbea8c326c2aa Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sat, 4 Aug 2018 13:17:50 -0700 Subject: [PATCH] repeating determinism tests for both driving models --- fmt.sh | 2 +- headless/src/main.rs | 6 +- sim/src/models.rs | 4 +- sim/tests/determinism.rs | 181 +++++++++++++++++++++------------------ 4 files changed, 107 insertions(+), 86 deletions(-) diff --git a/fmt.sh b/fmt.sh index ac897e182f..80b2bc0aef 100755 --- a/fmt.sh +++ b/fmt.sh @@ -1,6 +1,6 @@ #!/bin/bash -for x in `find */src | grep '.rs$' | xargs`; do +for x in `find */src */tests | grep '.rs$' | xargs`; do ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustfmt $x; done rm */src/*.bk -f; diff --git a/headless/src/main.rs b/headless/src/main.rs index 185006a603..23ce9ac735 100644 --- a/headless/src/main.rs +++ b/headless/src/main.rs @@ -18,6 +18,10 @@ struct Flags { /// Optional RNG seed #[structopt(long = "rng_seed")] rng_seed: Option, + + /// Use the old parametric sim + #[structopt(long = "parametric_sim")] + parametric_sim: bool, } fn main() { @@ -28,7 +32,7 @@ fn main() { .expect("Couldn't load map"); // TODO could load savestate let control_map = control::ControlMap::new(&map); - let mut sim = sim::Sim::new(&map, flags.rng_seed); + let mut sim = sim::Sim::new(&map, flags.rng_seed, flags.parametric_sim); // TODO need a notion of scenarios sim.seed_parked_cars(0.7); sim.start_many_parked_cars(&map, 100000); diff --git a/sim/src/models.rs b/sim/src/models.rs index 264a1ab213..aea438031e 100644 --- a/sim/src/models.rs +++ b/sim/src/models.rs @@ -4,6 +4,8 @@ use std; use std::collections::VecDeque; use On; +// This is all stuff that seems useful to share among different models. + // At all speeds (including at rest), cars must be at least this far apart. pub const FOLLOWING_DISTANCE: si::Meter = si::Meter { value_unsafe: 8.0, @@ -32,5 +34,3 @@ pub(crate) fn choose_turn( } panic!("No turn from {} to {}", from, path[0]); } - -// TODO some of DrivingSimState could maybe be parameterized diff --git a/sim/tests/determinism.rs b/sim/tests/determinism.rs index 2a109f9b41..8d1e39e30e 100644 --- a/sim/tests/determinism.rs +++ b/sim/tests/determinism.rs @@ -3,108 +3,125 @@ extern crate control; extern crate map_model; extern crate sim; +// TODO better parametric tests with separate names + #[test] fn serialization() { - // This assumes this map has been built - let input = "../data/small.abst"; - let rng_seed = 42; - let spawn_count = 10; + for parametric_sim in vec![true, false] { + // This assumes this map has been built + let input = "../data/small.abst"; + let rng_seed = 42; + let spawn_count = 10; - let map = map_model::Map::new(input, &map_model::Edits::new()).expect("Couldn't load map"); + let map = map_model::Map::new(input, &map_model::Edits::new()).expect("Couldn't load map"); - let mut sim = sim::Sim::new(&map, Some(rng_seed)); - sim.seed_pedestrians(&map, spawn_count); - sim.seed_parked_cars(0.5); - sim.start_many_parked_cars(&map, spawn_count); + let mut sim = sim::Sim::new(&map, Some(rng_seed), parametric_sim); + sim.seed_pedestrians(&map, spawn_count); + sim.seed_parked_cars(0.5); + sim.start_many_parked_cars(&map, spawn_count); - // Does savestating produce the same string? - let save1 = abstutil::to_json(&sim); - let save2 = abstutil::to_json(&sim); - assert_eq!(save1, save2); + // Does savestating produce the same string? + let save1 = abstutil::to_json(&sim); + let save2 = abstutil::to_json(&sim); + assert_eq!(save1, save2); + } } #[test] fn from_scratch() { - // This assumes this map has been built - let input = "../data/small.abst"; - let rng_seed = 42; - let spawn_count = 100; + for parametric_sim in vec![true, false] { + // This assumes this map has been built + let input = "../data/small.abst"; + let rng_seed = 42; + let spawn_count = 100; - println!("Creating two simulations"); - let map = map_model::Map::new(input, &map_model::Edits::new()).expect("Couldn't load map"); - let control_map = control::ControlMap::new(&map); + println!("Creating two simulations"); + let map = map_model::Map::new(input, &map_model::Edits::new()).expect("Couldn't load map"); + let control_map = control::ControlMap::new(&map); - let mut sim1 = sim::Sim::new(&map, Some(rng_seed)); - let mut sim2 = sim::Sim::new(&map, Some(rng_seed)); - sim1.seed_pedestrians(&map, spawn_count); - sim1.seed_parked_cars(0.5); - sim1.start_many_parked_cars(&map, spawn_count); - sim2.seed_pedestrians(&map, spawn_count); - sim2.seed_parked_cars(0.5); - sim2.start_many_parked_cars(&map, spawn_count); + let mut sim1 = sim::Sim::new(&map, Some(rng_seed), parametric_sim); + let mut sim2 = sim::Sim::new(&map, Some(rng_seed), parametric_sim); + sim1.seed_pedestrians(&map, spawn_count); + sim1.seed_parked_cars(0.5); + sim1.start_many_parked_cars(&map, spawn_count); + sim2.seed_pedestrians(&map, spawn_count); + sim2.seed_parked_cars(0.5); + sim2.start_many_parked_cars(&map, spawn_count); - for _ in 1..600 { - if sim1 != sim2 { - // TODO write to temporary files somewhere - // TODO need to sort dicts in json output to compare - abstutil::write_json("sim1_state.json", &sim1).unwrap(); - abstutil::write_json("sim2_state.json", &sim2).unwrap(); - panic!("sim state differs at {}. compare sim1_state.json and sim2_state.json", sim1.time); + for _ in 1..600 { + if sim1 != sim2 { + // TODO write to temporary files somewhere + // TODO need to sort dicts in json output to compare + abstutil::write_json("sim1_state.json", &sim1).unwrap(); + abstutil::write_json("sim2_state.json", &sim2).unwrap(); + panic!( + "sim state differs at {}. compare sim1_state.json and sim2_state.json", + sim1.time + ); + } + sim1.step(&map, &control_map); + sim2.step(&map, &control_map); } - sim1.step(&map, &control_map); - sim2.step(&map, &control_map); } } #[test] fn with_savestating() { - // This assumes this map has been built - let input = "../data/small.abst"; - let rng_seed = 42; - let spawn_count = 100; + for parametric_sim in vec![true, false] { + // This assumes this map has been built + let input = "../data/small.abst"; + let rng_seed = 42; + let spawn_count = 100; - println!("Creating two simulations"); - let map = map_model::Map::new(input, &map_model::Edits::new()).expect("Couldn't load map"); - let control_map = control::ControlMap::new(&map); + println!("Creating two simulations"); + let map = map_model::Map::new(input, &map_model::Edits::new()).expect("Couldn't load map"); + let control_map = control::ControlMap::new(&map); - let mut sim1 = sim::Sim::new(&map, Some(rng_seed)); - let mut sim2 = sim::Sim::new(&map, Some(rng_seed)); - sim1.seed_pedestrians(&map, spawn_count); - sim1.seed_parked_cars(0.5); - sim1.start_many_parked_cars(&map, spawn_count); - sim2.seed_pedestrians(&map, spawn_count); - sim2.seed_parked_cars(0.5); - sim2.start_many_parked_cars(&map, spawn_count); + let mut sim1 = sim::Sim::new(&map, Some(rng_seed), parametric_sim); + let mut sim2 = sim::Sim::new(&map, Some(rng_seed), parametric_sim); + sim1.seed_pedestrians(&map, spawn_count); + sim1.seed_parked_cars(0.5); + sim1.start_many_parked_cars(&map, spawn_count); + sim2.seed_pedestrians(&map, spawn_count); + sim2.seed_parked_cars(0.5); + sim2.start_many_parked_cars(&map, spawn_count); - for _ in 1..600 { - sim1.step(&map, &control_map); - sim2.step(&map, &control_map); + for _ in 1..600 { + sim1.step(&map, &control_map); + sim2.step(&map, &control_map); + } + + if sim1 != sim2 { + abstutil::write_json("sim1_state.json", &sim1).unwrap(); + abstutil::write_json("sim2_state.json", &sim2).unwrap(); + panic!( + "sim state differs at {}. compare sim1_state.json and sim2_state.json", + sim1.time + ); + } + + abstutil::write_json("sim1_savestate.json", &sim1).unwrap(); + + for _ in 1..60 { + sim1.step(&map, &control_map); + } + + if sim1 == sim2 { + abstutil::write_json("sim1_state.json", &sim1).unwrap(); + abstutil::write_json("sim2_state.json", &sim2).unwrap(); + panic!("sim state unexpectedly the same at {}. compare sim1_state.json and sim2_state.json", sim1.time); + } + + let sim3: sim::Sim = abstutil::read_json("sim1_savestate.json").unwrap(); + if sim3 != sim2 { + abstutil::write_json("sim3_state.json", &sim3).unwrap(); + abstutil::write_json("sim2_state.json", &sim2).unwrap(); + panic!( + "sim state differs at {}. compare sim3_state.json and sim2_state.json", + sim1.time + ); + } + + std::fs::remove_file("sim1_savestate.json").unwrap(); } - - if sim1 != sim2 { - abstutil::write_json("sim1_state.json", &sim1).unwrap(); - abstutil::write_json("sim2_state.json", &sim2).unwrap(); - panic!("sim state differs at {}. compare sim1_state.json and sim2_state.json", sim1.time); - } - - abstutil::write_json("sim1_savestate.json", &sim1).unwrap(); - - for _ in 1..60 { - sim1.step(&map, &control_map); - } - - if sim1 == sim2 { - abstutil::write_json("sim1_state.json", &sim1).unwrap(); - abstutil::write_json("sim2_state.json", &sim2).unwrap(); - panic!("sim state unexpectedly the same at {}. compare sim1_state.json and sim2_state.json", sim1.time); - } - - let sim3: sim::Sim = abstutil::read_json("sim1_savestate.json").unwrap(); - if sim3 != sim2 { - abstutil::write_json("sim3_state.json", &sim3).unwrap(); - abstutil::write_json("sim2_state.json", &sim2).unwrap(); - panic!("sim state differs at {}. compare sim3_state.json and sim2_state.json", sim1.time); - } - - std::fs::remove_file("sim1_savestate.json").unwrap(); }