mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 04:35:51 +03:00
sharing flags for specifying sim to load
This commit is contained in:
parent
04acd6723b
commit
190d9be972
@ -41,42 +41,24 @@ mod plugins;
|
||||
mod render;
|
||||
mod ui;
|
||||
|
||||
use sim::SimFlags;
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "editor")]
|
||||
struct Flags {
|
||||
/// Map or savestate to load
|
||||
#[structopt(name = "load")]
|
||||
load: String,
|
||||
|
||||
/// Optional RNG seed
|
||||
#[structopt(long = "rng_seed")]
|
||||
rng_seed: Option<u8>,
|
||||
#[structopt(flatten)]
|
||||
sim_flags: SimFlags,
|
||||
|
||||
/// Extra KML to display
|
||||
#[structopt(long = "kml")]
|
||||
kml: Option<String>,
|
||||
|
||||
/// Run name for savestating
|
||||
#[structopt(long = "run_name", default_value = "editor")]
|
||||
run_name: String,
|
||||
|
||||
/// Name of map edits
|
||||
#[structopt(long = "edits_name", default_value = "no_edits")]
|
||||
edits_name: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let flags = Flags::from_args();
|
||||
ezgui::run(
|
||||
ui::UIWrapper::new(
|
||||
flags.load,
|
||||
flags.run_name,
|
||||
flags.edits_name,
|
||||
flags.rng_seed,
|
||||
flags.kml,
|
||||
),
|
||||
ui::UIWrapper::new(flags.sim_flags, flags.kml),
|
||||
"A/B Street",
|
||||
1024,
|
||||
768,
|
||||
|
@ -36,7 +36,7 @@ use plugins::warp::WarpState;
|
||||
use plugins::Colorizer;
|
||||
use render::{DrawMap, RenderOptions};
|
||||
use sim;
|
||||
use sim::{MapEdits, Sim};
|
||||
use sim::{MapEdits, Sim, SimFlags};
|
||||
use std::process;
|
||||
|
||||
// TODO ideally these would be tuned kind of dynamically based on rendering speed
|
||||
@ -65,24 +65,12 @@ impl GUI for UIWrapper {
|
||||
|
||||
impl UIWrapper {
|
||||
// nit: lots of this logic could live in UI, if it mattered
|
||||
pub fn new(
|
||||
load: String,
|
||||
run_name: String,
|
||||
edits_name: String,
|
||||
rng_seed: Option<u8>,
|
||||
kml: Option<String>,
|
||||
) -> UIWrapper {
|
||||
pub fn new(flags: SimFlags, kml: Option<String>) -> UIWrapper {
|
||||
// Do this first, so anything logged by sim::load isn't lost.
|
||||
let logs = DisplayLogs::new();
|
||||
|
||||
flame::start("setup");
|
||||
let (map, control_map, sim) = sim::load(
|
||||
load,
|
||||
run_name,
|
||||
edits_name,
|
||||
rng_seed,
|
||||
Some(sim::Tick::from_seconds(30)),
|
||||
);
|
||||
let (map, control_map, sim) = sim::load(flags, Some(sim::Tick::from_seconds(30)));
|
||||
let extra_shapes = if let Some(path) = kml {
|
||||
kml::load(&path, &map.get_gps_bounds()).expect("Couldn't load extra KML shapes")
|
||||
} else {
|
||||
|
@ -10,6 +10,7 @@ extern crate structopt;
|
||||
extern crate yansi;
|
||||
|
||||
use log::{LevelFilter, Log, Metadata, Record};
|
||||
use sim::SimFlags;
|
||||
use structopt::StructOpt;
|
||||
|
||||
static LOG_ADAPTER: LogAdapter = LogAdapter;
|
||||
@ -17,13 +18,8 @@ static LOG_ADAPTER: LogAdapter = LogAdapter;
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "headless")]
|
||||
struct Flags {
|
||||
/// Map or savestate to load
|
||||
#[structopt(name = "load")]
|
||||
load: String,
|
||||
|
||||
/// Optional RNG seed
|
||||
#[structopt(long = "rng_seed")]
|
||||
rng_seed: Option<u8>,
|
||||
#[structopt(flatten)]
|
||||
sim_flags: SimFlags,
|
||||
|
||||
/// Optional time to savestate
|
||||
#[structopt(long = "save_at")]
|
||||
@ -32,14 +28,6 @@ struct Flags {
|
||||
/// Big or large random scenario?
|
||||
#[structopt(long = "big_sim")]
|
||||
big_sim: bool,
|
||||
|
||||
/// Run name for savestating
|
||||
#[structopt(long = "run_name", default_value = "headless")]
|
||||
run_name: String,
|
||||
|
||||
/// Name of map edits
|
||||
#[structopt(long = "edits_name", default_value = "no_edits")]
|
||||
edits_name: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -48,16 +36,11 @@ fn main() {
|
||||
log::set_max_level(LevelFilter::Debug);
|
||||
log::set_logger(&LOG_ADAPTER).unwrap();
|
||||
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
flags.load.clone(),
|
||||
flags.run_name,
|
||||
flags.edits_name,
|
||||
flags.rng_seed,
|
||||
Some(sim::Tick::from_seconds(30)),
|
||||
);
|
||||
|
||||
// TODO not the ideal way to distinguish what thing we loaded
|
||||
if flags.load.contains("data/maps/") {
|
||||
let load = flags.sim_flags.load.clone();
|
||||
let (map, control_map, mut sim) = sim::load(flags.sim_flags, Some(sim::Tick::from_seconds(30)));
|
||||
|
||||
if load.contains("data/maps/") {
|
||||
if flags.big_sim {
|
||||
sim.big_spawn(&map);
|
||||
} else {
|
||||
|
@ -24,3 +24,4 @@ rand = { version = "0.5.1", features = ["serde1"] }
|
||||
rayon = "1.0"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
structopt = "0.2"
|
||||
|
@ -7,35 +7,60 @@ use rand::Rng;
|
||||
use std::collections::VecDeque;
|
||||
use {CarID, Event, MapEdits, PedestrianID, RouteID, Scenario, Sim, Tick};
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "sim_flags")]
|
||||
pub struct SimFlags {
|
||||
/// Map, scenario, or savestate to load
|
||||
#[structopt(name = "load")]
|
||||
pub load: String,
|
||||
|
||||
/// Optional RNG seed
|
||||
#[structopt(long = "rng_seed")]
|
||||
pub rng_seed: Option<u8>,
|
||||
|
||||
/// Run name for savestating
|
||||
#[structopt(long = "run_name", default_value = "unnamed")]
|
||||
pub run_name: String,
|
||||
|
||||
/// Name of map edits
|
||||
#[structopt(long = "edits_name", default_value = "no_edits")]
|
||||
pub edits_name: String,
|
||||
}
|
||||
|
||||
impl SimFlags {
|
||||
pub fn for_test(run_name: &str) -> SimFlags {
|
||||
SimFlags {
|
||||
load: "../data/maps/small.abst".to_string(),
|
||||
rng_seed: Some(42),
|
||||
run_name: run_name.to_string(),
|
||||
edits_name: "no_edits".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience method to setup everything.
|
||||
pub fn load(
|
||||
input: String,
|
||||
run_name: String,
|
||||
edits_name: String,
|
||||
rng_seed: Option<u8>,
|
||||
savestate_every: Option<Tick>,
|
||||
) -> (Map, ControlMap, Sim) {
|
||||
if input.contains("data/save/") {
|
||||
info!("Resuming from {}", input);
|
||||
pub fn load(flags: SimFlags, savestate_every: Option<Tick>) -> (Map, ControlMap, Sim) {
|
||||
if flags.load.contains("data/save/") {
|
||||
info!("Resuming from {}", flags.load);
|
||||
flame::start("read sim savestate");
|
||||
let sim: Sim = abstutil::read_json(&input).expect("loading sim state failed");
|
||||
let sim: Sim = abstutil::read_json(&flags.load).expect("loading sim state failed");
|
||||
flame::end("read sim savestate");
|
||||
// TODO assuming the relative path :(
|
||||
let edits: MapEdits = abstutil::read_json(&format!(
|
||||
"../data/edits/{}/{}.json",
|
||||
sim.map_name, edits_name
|
||||
sim.map_name, flags.edits_name
|
||||
)).unwrap_or(MapEdits::new());
|
||||
let map_path = format!("../data/maps/{}.abst", sim.map_name);
|
||||
let map = Map::new(&map_path, edits.road_edits.clone())
|
||||
.expect(&format!("Couldn't load map from {}", map_path));
|
||||
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
|
||||
(map, control_map, sim)
|
||||
} else if input.contains("data/scenarios/") {
|
||||
info!("Seeding the simulation from scenario {}", input);
|
||||
let scenario: Scenario = abstutil::read_json(&input).expect("loading scenario failed");
|
||||
} else if flags.load.contains("data/scenarios/") {
|
||||
info!("Seeding the simulation from scenario {}", flags.load);
|
||||
let scenario: Scenario = abstutil::read_json(&flags.load).expect("loading scenario failed");
|
||||
let edits: MapEdits = abstutil::read_json(&format!(
|
||||
"../data/edits/{}/{}.json",
|
||||
scenario.map_name, edits_name
|
||||
scenario.map_name, flags.edits_name
|
||||
)).unwrap_or(MapEdits::new());
|
||||
let map_path = format!("../data/maps/{}.abst", scenario.map_name);
|
||||
let map = Map::new(&map_path, edits.road_edits.clone())
|
||||
@ -44,26 +69,28 @@ pub fn load(
|
||||
let mut sim = Sim::new(
|
||||
&map,
|
||||
scenario.scenario_name.clone(),
|
||||
rng_seed,
|
||||
flags.rng_seed,
|
||||
savestate_every,
|
||||
);
|
||||
scenario.instantiate(&mut sim, &map);
|
||||
(map, control_map, sim)
|
||||
} else {
|
||||
// TODO relative dir is brittle; match more cautiously
|
||||
let map_name = input
|
||||
let map_name = flags
|
||||
.load
|
||||
.trim_left_matches("../data/maps/")
|
||||
.trim_right_matches(".abst")
|
||||
.to_string();
|
||||
info!("Loading map {}", input);
|
||||
let edits: MapEdits =
|
||||
abstutil::read_json(&format!("../data/edits/{}/{}.json", map_name, edits_name))
|
||||
.unwrap_or(MapEdits::new());
|
||||
let map = Map::new(&input, edits.road_edits.clone()).expect("Couldn't load map");
|
||||
info!("Loading map {}", flags.load);
|
||||
let edits: MapEdits = abstutil::read_json(&format!(
|
||||
"../data/edits/{}/{}.json",
|
||||
map_name, flags.edits_name
|
||||
)).unwrap_or(MapEdits::new());
|
||||
let map = Map::new(&flags.load, edits.road_edits.clone()).expect("Couldn't load map");
|
||||
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
|
||||
flame::start("create sim");
|
||||
// Note this is the only time we actually use the run name!
|
||||
let sim = Sim::new(&map, run_name, rng_seed, savestate_every);
|
||||
let sim = Sim::new(&map, flags.run_name, flags.rng_seed, savestate_every);
|
||||
flame::end("create sim");
|
||||
(map, control_map, sim)
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ extern crate rayon;
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate structopt;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
@ -55,7 +57,7 @@ use dimensioned::si;
|
||||
pub use edits::MapEdits;
|
||||
pub use events::Event;
|
||||
use geom::{Angle, Pt2D};
|
||||
pub use helpers::load;
|
||||
pub use helpers::{load, SimFlags};
|
||||
pub use instrument::save_backtraces;
|
||||
use map_model::{LaneID, Map, TurnID};
|
||||
pub use scenario::{Neighborhood, Scenario, SeedParkedCars, SpawnOverTime};
|
||||
|
@ -6,10 +6,7 @@ extern crate sim;
|
||||
#[test]
|
||||
fn aorta_model_completes() {
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"aorta_model_completes".to_string(),
|
||||
"no_edits".to_string(),
|
||||
Some(42),
|
||||
sim::SimFlags::for_test("aorta_model_completes"),
|
||||
Some(sim::Tick::from_seconds(30)),
|
||||
);
|
||||
sim.small_spawn(&map);
|
||||
|
@ -5,13 +5,7 @@ extern crate sim;
|
||||
|
||||
#[test]
|
||||
fn serialization() {
|
||||
let (map, _, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"serialization".to_string(),
|
||||
"no_edits".to_string(),
|
||||
Some(42),
|
||||
None,
|
||||
);
|
||||
let (map, _, mut sim) = sim::load(sim::SimFlags::for_test("serialization"), None);
|
||||
sim.small_spawn(&map);
|
||||
|
||||
// Does savestating produce the same string?
|
||||
@ -23,13 +17,7 @@ fn serialization() {
|
||||
#[test]
|
||||
fn from_scratch() {
|
||||
println!("Creating two simulations");
|
||||
let (map, control_map, mut sim1) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"from_scratch_1".to_string(),
|
||||
"no_edits".to_string(),
|
||||
Some(42),
|
||||
None,
|
||||
);
|
||||
let (map, control_map, mut sim1) = sim::load(sim::SimFlags::for_test("from_scratch_1"), None);
|
||||
let mut sim2 = sim::Sim::new(&map, "from_scratch_2".to_string(), Some(42), None);
|
||||
sim1.small_spawn(&map);
|
||||
sim2.small_spawn(&map);
|
||||
@ -51,13 +39,8 @@ fn from_scratch() {
|
||||
#[test]
|
||||
fn with_savestating() {
|
||||
println!("Creating two simulations");
|
||||
let (map, control_map, mut sim1) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"with_savestating_1".to_string(),
|
||||
"no_edits".to_string(),
|
||||
Some(42),
|
||||
None,
|
||||
);
|
||||
let (map, control_map, mut sim1) =
|
||||
sim::load(sim::SimFlags::for_test("with_savestating_1"), None);
|
||||
let mut sim2 = sim::Sim::new(&map, "with_savestating_2".to_string(), Some(42), None);
|
||||
sim1.small_spawn(&map);
|
||||
sim2.small_spawn(&map);
|
||||
|
@ -6,10 +6,7 @@ extern crate sim;
|
||||
#[test]
|
||||
fn bus_reaches_stops() {
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"bus_reaches_stops".to_string(),
|
||||
"no_edits".to_string(),
|
||||
Some(42),
|
||||
sim::SimFlags::for_test("bus_reaches_stops"),
|
||||
Some(sim::Tick::from_seconds(30)),
|
||||
);
|
||||
|
||||
@ -35,10 +32,7 @@ fn bus_reaches_stops() {
|
||||
#[test]
|
||||
fn ped_uses_bus() {
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"bus_reaches_stops".to_string(),
|
||||
"no_edits".to_string(),
|
||||
Some(42),
|
||||
sim::SimFlags::for_test("bus_reaches_stops"),
|
||||
Some(sim::Tick::from_seconds(30)),
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user