Cache the list of nearby intersections to wake up for uber-turns. #497 (#513)

This shouldn't have any behavioral change.
This commit is contained in:
Dustin Carlino 2021-02-12 22:12:46 -08:00 committed by GitHub
parent d6ba8e92af
commit 3685f7b18a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 11 deletions

View File

@ -121,6 +121,7 @@ Others:
- Lots of help with rendering SVG and fonts from - Lots of help with rendering SVG and fonts from
[RazrFalcon](https://github.com/RazrFalcon) and [RazrFalcon](https://github.com/RazrFalcon) and
[nical](https://github.com/nical) [nical](https://github.com/nical)
- Lots of traffic signal and uber-turn work from [Bruce](https://github.com/BruceBrown)
Data: Data:

View File

@ -6,7 +6,7 @@ use std::collections::HashSet;
use aabb_quadtree::QuadTree; use aabb_quadtree::QuadTree;
use geojson::{Feature, FeatureCollection, GeoJson}; use geojson::{Feature, FeatureCollection, GeoJson};
use rand::{SeedableRng, Rng}; use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use abstutil::{CmdArgs, Timer}; use abstutil::{CmdArgs, Timer};
@ -24,7 +24,11 @@ fn main() {
let houses = generate_buildings_on_empty_residential_roads(&map, &mut rng, &mut timer); let houses = generate_buildings_on_empty_residential_roads(&map, &mut rng, &mut timer);
if houses.len() <= num_required { if houses.len() <= num_required {
panic!("Only generated {} houses, but wanted at least {}", houses.len(), num_required); panic!(
"Only generated {} houses, but wanted at least {}",
houses.len(),
num_required
);
} }
let mut features = Vec::new(); let mut features = Vec::new();

View File

@ -64,6 +64,9 @@ struct State {
// complete the entire sequence. This is especially necessary since groups of traffic signals // complete the entire sequence. This is especially necessary since groups of traffic signals
// are not yet configured as one. // are not yet configured as one.
reserved: BTreeSet<Request>, reserved: BTreeSet<Request>,
// In some cases, a turn completing at one intersection may affect agents waiting to start an
// uber-turn at nearby intersections.
uber_turn_neighbors: Vec<IntersectionID>,
signal: Option<SignalState>, signal: Option<SignalState>,
} }
@ -111,11 +114,16 @@ impl IntersectionSimState {
accepted: BTreeSet::new(), accepted: BTreeSet::new(),
waiting: BTreeMap::new(), waiting: BTreeMap::new(),
reserved: BTreeSet::new(), reserved: BTreeSet::new(),
uber_turn_neighbors: Vec::new(),
signal: None, signal: None,
}; };
if i.is_traffic_signal() { if i.is_traffic_signal() {
state.signal = Some(SignalState::new(i.id, Time::START_OF_DAY, map, scheduler)); state.signal = Some(SignalState::new(i.id, Time::START_OF_DAY, map, scheduler));
} }
if let Some(mut set) = map_model::IntersectionCluster::autodetect(i.id, map) {
set.remove(&i.id);
state.uber_turn_neighbors.extend(set);
}
sim.state.insert(i.id, state); sim.state.insert(i.id, state);
} }
sim sim
@ -130,13 +138,6 @@ impl IntersectionSimState {
map: &Map, map: &Map,
handling_live_edits: bool, handling_live_edits: bool,
) { ) {
// wake up intersections in the cluster in order to start uber-turns.
if let Some(set) = map_model::IntersectionCluster::autodetect(turn.parent, map) {
for id in &set {
self.wakeup_waiting(now, *id, scheduler, map);
}
}
let state = self.state.get_mut(&turn.parent).unwrap(); let state = self.state.get_mut(&turn.parent).unwrap();
assert!(state.accepted.remove(&Request { agent, turn })); assert!(state.accepted.remove(&Request { agent, turn }));
state.reserved.remove(&Request { agent, turn }); state.reserved.remove(&Request { agent, turn });
@ -145,11 +146,19 @@ impl IntersectionSimState {
} }
if self.break_turn_conflict_cycles { if self.break_turn_conflict_cycles {
if let AgentID::Car(car) = agent { if let AgentID::Car(car) = agent {
// todo: when drain_filter() is no longer experimental, use it instead of // TODO when drain_filter() is no longer experimental, use it instead of
// retian_btreeset() // retain_btreeset()
retain_btreeset(&mut self.blocked_by, |(_, c)| *c != car); retain_btreeset(&mut self.blocked_by, |(_, c)| *c != car);
} }
} }
// If this intersection has uber-turns going through it, then we may need to wake up agents
// with a reserved uber-turn that're waiting at nearby intersections. They may have
// reserved their sequence of turns but then gotten stuck by somebody filling up a queue a
// few steps away.
for id in &self.state[&turn.parent].uber_turn_neighbors {
self.wakeup_waiting(now, *id, scheduler, map);
}
} }
/// For deleting cars /// For deleting cars
@ -561,6 +570,14 @@ impl IntersectionSimState {
} }
(None, None) => {} (None, None) => {}
} }
// It's unlikely, but the player might create/destroy traffic signals close together and
// change the uber-turns that exist. To be safe, recalculate everywhere.
state.uber_turn_neighbors.clear();
if let Some(mut set) = map_model::IntersectionCluster::autodetect(state.id, map) {
set.remove(&state.id);
state.uber_turn_neighbors.extend(set);
}
} }
} }