be able to toggle off block-the-box protection. initial findings:

sometimes the protection makes things worse!
This commit is contained in:
Dustin Carlino 2019-08-16 13:35:58 -07:00
parent a5b73c060a
commit bbc4492205
7 changed files with 38 additions and 39 deletions

View File

@ -30,6 +30,8 @@
- https://blogs.uw.edu/ceadvice/2019/05/08/infrastructure-week-2019-welcome-uw-cee-students-and-faculty/
- https://escience.washington.edu/dssg/
- josie kresner from transport foundry
- https://www.citylab.com/transportation/2019/08/city-planning-transportation-oakland-community-engagement/596050/
- tweeting small problems -> bug tracker
## Similar projects

View File

@ -156,8 +156,9 @@ 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,
savestate_every: None,
freeform_policy: current_flags.sim_flags.freeform_policy,
disable_block_the_box: current_flags.sim_flags.disable_block_the_box,
},
..current_flags.clone()
},

View File

@ -516,6 +516,7 @@ impl PerMapUI {
.unwrap_or_else(|| "unnamed".to_string()),
savestate_every: flags.savestate_every,
use_freeform_policy_everywhere: flags.freeform_policy,
disable_block_the_box: flags.disable_block_the_box,
},
);
}

View File

@ -26,13 +26,17 @@ pub struct SimFlags {
#[structopt(long = "run_name")]
pub run_name: Option<String>,
/// Regularly save simulation state
#[structopt(long = "savestate_every")]
pub savestate_every: Option<Duration>,
/// Use freeform intersection policy everywhere
#[structopt(long = "freeform_policy")]
pub freeform_policy: bool,
/// Regularly save simulation state
#[structopt(long = "savestate_every")]
pub savestate_every: Option<Duration>,
/// Disable block-the-box prevention
#[structopt(long = "disable_block_the_box")]
pub disable_block_the_box: bool,
}
impl SimFlags {
@ -46,8 +50,9 @@ impl SimFlags {
load: PathBuf::from(abstutil::path_map(map)),
rng_seed: Some(42),
run_name: Some(run_name.to_string()),
freeform_policy: false,
savestate_every: None,
freeform_policy: false,
disable_block_the_box: false,
}
}
@ -70,6 +75,7 @@ impl SimFlags {
.unwrap_or_else(|| "unnamed".to_string()),
savestate_every: self.savestate_every,
use_freeform_policy_everywhere: self.freeform_policy,
disable_block_the_box: self.disable_block_the_box,
};
if self.load.starts_with(Path::new("../data/save/")) {

View File

@ -16,6 +16,7 @@ const WAIT_AT_STOP_SIGN: Duration = Duration::const_seconds(0.5);
pub struct IntersectionSimState {
state: BTreeMap<IntersectionID, State>,
use_freeform_policy_everywhere: bool,
force_queue_entry: bool,
}
#[derive(Serialize, Deserialize, PartialEq)]
@ -35,10 +36,12 @@ impl IntersectionSimState {
map: &Map,
scheduler: &mut Scheduler,
use_freeform_policy_everywhere: bool,
disable_block_the_box: bool,
) -> IntersectionSimState {
let mut sim = IntersectionSimState {
state: BTreeMap::new(),
use_freeform_policy_everywhere,
force_queue_entry: disable_block_the_box,
};
for i in map.all_intersections() {
sim.state.insert(
@ -140,15 +143,22 @@ impl IntersectionSimState {
state.waiting.entry(req.clone()).or_insert(now);
let allowed = if self.use_freeform_policy_everywhere {
state.freeform_policy(&req, map, maybe_car_and_target_queue)
state.freeform_policy(&req, map)
} 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)
state.traffic_signal_policy(signal, &req, speed, now, 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)
state.stop_sign_policy(sign, &req, now, map, scheduler)
} else {
unreachable!()
};
// Don't block the box
if let Some((queue, car)) = maybe_car_and_target_queue {
if !queue.try_to_reserve_entry(car, self.force_queue_entry) {
return false;
}
}
if allowed {
assert!(!state.any_accepted_conflict_with(turn, map));
state.waiting.remove(&req).unwrap();
@ -187,24 +197,12 @@ impl State {
.any(|req| map.get_t(req.turn).conflicts_with(turn))
}
fn freeform_policy(
&self,
req: &Request,
map: &Map,
maybe_car_and_target_queue: Option<(&mut Queue, &Car)>,
) -> bool {
fn freeform_policy(&self, req: &Request, map: &Map) -> bool {
// Allow concurrent turns that don't conflict
if self.any_accepted_conflict_with(req.turn, map) {
return false;
}
// Don't block the box
if let Some((queue, car)) = maybe_car_and_target_queue {
if !queue.try_to_reserve_entry(car) {
return false;
}
}
true
}
@ -215,7 +213,6 @@ impl State {
now: Duration,
map: &Map,
scheduler: &mut Scheduler,
maybe_car_and_target_queue: Option<(&mut Queue, &Car)>,
) -> bool {
if self.any_accepted_conflict_with(req.turn, map) {
return false;
@ -251,13 +248,6 @@ impl State {
// TODO Make sure we can optimistically finish this turn before an approaching
// higher-priority vehicle wants to begin.
// Don't block the box
if let Some((queue, car)) = maybe_car_and_target_queue {
if !queue.try_to_reserve_entry(car) {
return false;
}
}
true
}
@ -267,7 +257,6 @@ impl State {
new_req: &Request,
speed: Speed,
time: Duration,
maybe_car_and_target_queue: Option<(&mut Queue, &Car)>,
map: &Map,
) -> bool {
let turn = map.get_t(new_req.turn);
@ -315,13 +304,6 @@ impl State {
}
}
// Don't block the box
if let Some((queue, car)) = maybe_car_and_target_queue {
if !queue.try_to_reserve_entry(car) {
return false;
}
}
true
}
}

View File

@ -163,12 +163,16 @@ impl Queue {
// If true, there's room and the car must actually start the turn (because the space is
// reserved).
pub fn try_to_reserve_entry(&mut self, car: &Car) -> bool {
pub fn try_to_reserve_entry(&mut self, car: &Car, force_entry: bool) -> bool {
// Sometimes a car + FOLLOWING_DISTANCE might be longer than the geom_len entirely. In that
// case, it just means the car won't totally fit on the queue at once, which is fine.
// Reserve the normal amount of space; the next car trying to enter will get rejected.
// Also allow this don't-block-the-box prevention to be disabled.
let dist = car.vehicle.length + FOLLOWING_DISTANCE;
if self.reserved_length + dist < self.geom_len || self.reserved_length == Distance::ZERO {
if self.reserved_length + dist < self.geom_len
|| self.reserved_length == Distance::ZERO
|| force_entry
{
self.reserved_length += dist;
return true;
}

View File

@ -57,6 +57,7 @@ pub struct SimOptions {
pub run_name: String,
pub savestate_every: Option<Duration>,
pub use_freeform_policy_everywhere: bool,
pub disable_block_the_box: bool,
}
impl SimOptions {
@ -65,6 +66,7 @@ impl SimOptions {
run_name: run_name.to_string(),
savestate_every: None,
use_freeform_policy_everywhere: false,
disable_block_the_box: false,
}
}
}
@ -88,6 +90,7 @@ impl Sim {
map,
&mut scheduler,
opts.use_freeform_policy_everywhere,
opts.disable_block_the_box,
),
transit: TransitSimState::new(),
trips: TripManager::new(),