try using freeform policy at all intersections, to see how it affects gridlock

This commit is contained in:
Dustin Carlino 2019-08-16 10:35:47 -07:00
parent f78c58e11d
commit 3cebc3cc44
8 changed files with 80 additions and 52 deletions

View File

@ -11,7 +11,7 @@ use ezgui::{hotkey, Color, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, Moda
use geom::{Circle, Distance, Line, PolyLine};
use map_model::{Map, LANE_THICKNESS};
use serde_derive::{Deserialize, Serialize};
use sim::{Sim, TripID};
use sim::{Sim, SimOptions, TripID};
pub struct ABTestMode {
menu: ModalMenu,
@ -245,17 +245,13 @@ impl ABTestMode {
// Temporarily move everything into this structure.
let blank_map = Map::blank();
let mut secondary = ui.secondary.take().unwrap();
let mut opts = SimOptions::new("run");
opts.use_freeform_policy_everywhere = ui.primary.current_flags.sim_flags.freeform_policy;
let ss = ABTestSavestate {
primary_map: std::mem::replace(&mut ui.primary.map, Map::blank()),
primary_sim: std::mem::replace(
&mut ui.primary.sim,
Sim::new(&blank_map, "run".to_string(), None),
),
primary_sim: std::mem::replace(&mut ui.primary.sim, Sim::new(&blank_map, opts.clone())),
secondary_map: std::mem::replace(&mut secondary.map, Map::blank()),
secondary_sim: std::mem::replace(
&mut secondary.sim,
Sim::new(&blank_map, "run".to_string(), None),
),
secondary_sim: std::mem::replace(&mut secondary.sim, Sim::new(&blank_map, opts)),
};
let path = abstutil::path2_bin(

View File

@ -155,6 +155,7 @@ fn launch_test(test: &ABTest, ui: &mut UI, ctx: &mut EventCtx) -> ABTestMode {
load,
rng_seed: current_flags.sim_flags.rng_seed,
run_name: Some(format!("{} with {}", test.test_name, test.edits2_name)),
freeform_policy: current_flags.sim_flags.freeform_policy,
},
..current_flags.clone()
},

View File

@ -10,7 +10,7 @@ use geom::{Bounds, Circle, Distance};
use map_model::{Map, Traversable};
use rand::seq::SliceRandom;
use serde_derive::{Deserialize, Serialize};
use sim::{GetDrawAgents, Sim, SimFlags};
use sim::{GetDrawAgents, Sim, SimFlags, SimOptions};
use structopt::StructOpt;
pub struct UI {
@ -489,15 +489,19 @@ impl PerMapUI {
}
pub fn reset_sim(&mut self) {
let flags = &self.current_flags.sim_flags;
// TODO savestate_every gets lost
self.sim = Sim::new(
&self.map,
self.current_flags
.sim_flags
.run_name
.clone()
.unwrap_or_else(|| "unnamed".to_string()),
None,
SimOptions {
run_name: flags
.run_name
.clone()
.unwrap_or_else(|| "unnamed".to_string()),
savestate_every: None,
use_freeform_policy_everywhere: flags.freeform_policy,
},
);
}
}

View File

@ -18,7 +18,7 @@ pub(crate) use self::mechanics::{
};
pub(crate) use self::router::{ActionAtEnd, Router};
pub(crate) use self::scheduler::{Command, Scheduler};
pub use self::sim::Sim;
pub use self::sim::{Sim, SimOptions};
pub(crate) use self::transit::TransitSimState;
pub use self::trips::{FinishedTrips, TripEnd, TripMode, TripStart, TripStatus};
pub(crate) use self::trips::{TripLeg, TripManager};

View File

@ -1,4 +1,4 @@
use crate::{Scenario, Sim};
use crate::{Scenario, Sim, SimOptions};
use abstutil;
use geom::Duration;
use map_model::{Map, MapEdits};
@ -25,6 +25,10 @@ pub struct SimFlags {
/// Run name for savestating
#[structopt(long = "run_name")]
pub run_name: Option<String>,
/// Use freeform intersection policy everywhere
#[structopt(long = "freeform_policy")]
pub freeform_policy: bool,
}
impl SimFlags {
@ -38,6 +42,7 @@ impl SimFlags {
load: PathBuf::from(abstutil::path_map(map)),
rng_seed: Some(42),
run_name: Some(run_name.to_string()),
freeform_policy: false,
}
}
@ -57,6 +62,15 @@ impl SimFlags {
) -> (Map, Sim, XorShiftRng) {
let mut rng = self.make_rng();
let mut opts = SimOptions {
run_name: self
.run_name
.clone()
.unwrap_or_else(|| "unnamed".to_string()),
savestate_every,
use_freeform_policy_everywhere: self.freeform_policy,
};
if self.load.starts_with(Path::new("../data/save/")) {
timer.note(format!("Resuming from {}", self.load.display()));
@ -81,13 +95,11 @@ impl SimFlags {
let map: Map =
abstutil::read_binary(&abstutil::path_map(&scenario.map_name), timer).unwrap();
let mut sim = Sim::new(
&map,
self.run_name
.clone()
.unwrap_or_else(|| scenario.scenario_name.clone()),
savestate_every,
);
opts.run_name = self
.run_name
.clone()
.unwrap_or_else(|| scenario.scenario_name.clone());
let mut sim = Sim::new(&map, opts);
scenario.instantiate(&mut sim, &map, &mut rng, timer);
(map, sim, rng)
@ -98,13 +110,7 @@ impl SimFlags {
.expect(&format!("Couldn't load map from {}", self.load.display()));
timer.start("create sim");
let sim = Sim::new(
&map,
self.run_name
.clone()
.unwrap_or_else(|| "unnamed".to_string()),
savestate_every,
);
let sim = Sim::new(&map, opts);
timer.stop("create sim");
(map, sim, rng)
@ -115,13 +121,7 @@ impl SimFlags {
.expect(&format!("Couldn't load map from {}", self.load.display()));
timer.start("create sim");
let sim = Sim::new(
&map,
self.run_name
.clone()
.unwrap_or_else(|| "unnamed".to_string()),
savestate_every,
);
let sim = Sim::new(&map, opts);
timer.stop("create sim");
(map, sim, rng)

View File

@ -15,6 +15,7 @@ const WAIT_AT_STOP_SIGN: Duration = Duration::const_seconds(0.5);
#[derive(Serialize, Deserialize, PartialEq)]
pub struct IntersectionSimState {
state: BTreeMap<IntersectionID, State>,
use_freeform_policy_everywhere: bool,
}
#[derive(Serialize, Deserialize, PartialEq)]
@ -30,9 +31,14 @@ struct State {
}
impl IntersectionSimState {
pub fn new(map: &Map, scheduler: &mut Scheduler) -> IntersectionSimState {
pub fn new(
map: &Map,
scheduler: &mut Scheduler,
use_freeform_policy_everywhere: bool,
) -> IntersectionSimState {
let mut sim = IntersectionSimState {
state: BTreeMap::new(),
use_freeform_policy_everywhere,
};
for i in map.all_intersections() {
sim.state.insert(
@ -133,13 +139,14 @@ impl IntersectionSimState {
let state = self.state.get_mut(&turn.parent).unwrap();
state.waiting.entry(req.clone()).or_insert(now);
let allowed = if let Some(ref signal) = map.maybe_get_traffic_signal(state.id) {
let allowed = if self.use_freeform_policy_everywhere {
state.freeform_policy(&req, map, maybe_car_and_target_queue)
} else if let Some(ref signal) = map.maybe_get_traffic_signal(state.id) {
state.traffic_signal_policy(signal, &req, speed, now, maybe_car_and_target_queue, map)
} else if let Some(ref sign) = map.maybe_get_stop_sign(state.id) {
state.stop_sign_policy(sign, &req, now, map, scheduler, maybe_car_and_target_queue)
} else {
// TODO This never gets called right now
state.freeform_policy(&req, map, maybe_car_and_target_queue)
unreachable!()
};
if allowed {
@ -186,8 +193,7 @@ impl State {
map: &Map,
maybe_car_and_target_queue: Option<(&mut Queue, &Car)>,
) -> bool {
// Allow concurrent turns that don't conflict, don't prevent target lane from spilling
// over.
// Allow concurrent turns that don't conflict
if self.any_accepted_conflict_with(req.turn, map) {
return false;
}

View File

@ -52,22 +52,43 @@ pub struct Sim {
events_since_last_step: Vec<Event>,
}
#[derive(Clone)]
pub struct SimOptions {
pub run_name: String,
pub savestate_every: Option<Duration>,
pub use_freeform_policy_everywhere: bool,
}
impl SimOptions {
pub fn new(run_name: &str) -> SimOptions {
SimOptions {
run_name: run_name.to_string(),
savestate_every: None,
use_freeform_policy_everywhere: false,
}
}
}
// Setup
impl Sim {
pub fn new(map: &Map, run_name: String, savestate_every: Option<Duration>) -> Sim {
pub fn new(map: &Map, opts: SimOptions) -> Sim {
let mut scheduler = Scheduler::new();
// TODO Gridlock detection doesn't add value right now.
if false {
scheduler.push(CHECK_FOR_GRIDLOCK_FREQUENCY, Command::CheckForGridlock);
}
if let Some(d) = savestate_every {
if let Some(d) = opts.savestate_every {
scheduler.push(d, Command::Savestate(d));
}
Sim {
driving: DrivingSimState::new(map),
parking: ParkingSimState::new(map),
walking: WalkingSimState::new(),
intersections: IntersectionSimState::new(map, &mut scheduler),
intersections: IntersectionSimState::new(
map,
&mut scheduler,
opts.use_freeform_policy_everywhere,
),
transit: TransitSimState::new(),
trips: TripManager::new(),
spawner: TripSpawner::new(),
@ -79,7 +100,7 @@ impl Sim {
map_name: map.get_name().to_string(),
// TODO
edits_name: "no_edits".to_string(),
run_name,
run_name: opts.run_name,
step_count: 0,
trip_positions: None,
events_since_last_step: Vec::new(),

View File

@ -1,7 +1,7 @@
use crate::runner::TestRunner;
use abstutil::Timer;
use geom::Duration;
use sim::{Scenario, Sim, SimFlags};
use sim::{Scenario, Sim, SimFlags, SimOptions};
pub fn run(t: &mut TestRunner) {
t.run_slow("serialization", |_| {
@ -19,7 +19,7 @@ pub fn run(t: &mut TestRunner) {
println!("Creating two simulations");
let flags = SimFlags::for_test("from_scratch_1");
let (map, mut sim1, _) = flags.load(None, &mut Timer::throwaway());
let mut sim2 = Sim::new(&map, "from_scratch_2".to_string(), None);
let mut sim2 = Sim::new(&map, SimOptions::new("from_scratch_2"));
Scenario::small_run(&map).instantiate(
&mut sim1,
&map,
@ -52,7 +52,7 @@ pub fn run(t: &mut TestRunner) {
println!("Creating two simulations");
let flags = SimFlags::for_test("with_savestating_1");
let (map, mut sim1, _) = flags.load(None, &mut Timer::throwaway());
let mut sim2 = Sim::new(&map, "with_savestating_2".to_string(), None);
let mut sim2 = Sim::new(&map, SimOptions::new("with_savestating_2"));
Scenario::small_run(&map).instantiate(
&mut sim1,
&map,