Skip all-walk if no demand (#442)

* Skip all-walk if no demand

If you create an all-walk stage and make it adaptive, if there is no demand it will be skipped. Fixed crosswalks are never skipped, as they may be necessary for queue management.
This commit is contained in:
Bruce 2021-01-27 11:13:19 -08:00 committed by GitHub
parent 37a25c0fcb
commit cf5ce637f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 5 deletions

View File

@ -403,6 +403,16 @@ impl Stage {
}; };
} }
} }
// trivial function that returns true if the stage is just crosswalks
pub fn contains_only_crosswalks(&self) -> bool {
for m in &self.protected_movements {
if !m.crosswalk {
return false;
}
}
self.yield_movements.is_empty()
}
} }
impl ControlTrafficSignal { impl ControlTrafficSignal {

View File

@ -260,23 +260,42 @@ impl IntersectionSimState {
scheduler: &mut Scheduler, scheduler: &mut Scheduler,
) { ) {
// trivial function that advances the signal stage and returns duration // trivial function that advances the signal stage and returns duration
fn advance(signal_state: &mut SignalState, signal: &ControlTrafficSignal) -> Duration { fn advance(
signal_state: &mut SignalState,
signal: &ControlTrafficSignal,
allow_crosswalk_skip: bool,
) -> Duration {
signal_state.current_stage = (signal_state.current_stage + 1) % signal.stages.len(); signal_state.current_stage = (signal_state.current_stage + 1) % signal.stages.len();
let stage = &signal.stages[signal_state.current_stage];
// only skip for variable all-walk crosswalk
if let StageType::Variable(_, _, _) = stage.stage_type {
if allow_crosswalk_skip && stage.contains_only_crosswalks() {
// we can skip this stage, as its all walk and we're allowed to skip (no
// pedestrian waiting).
signal_state.current_stage =
(signal_state.current_stage + 1) % signal.stages.len();
}
}
signal.stages[signal_state.current_stage] signal.stages[signal_state.current_stage]
.stage_type .stage_type
.simple_duration() .simple_duration()
} }
let state = self.state.get_mut(&id).unwrap(); let state = self.state.get_mut(&id).unwrap();
let signal_state = state.signal.as_mut().unwrap(); let signal_state = state.signal.as_mut().unwrap();
let signal = map.get_traffic_signal(id); let signal = map.get_traffic_signal(id);
let ped_waiting = state.waiting.keys().any(|req| {
if let AgentID::Pedestrian(_) = req.agent {
return true;
}
false
});
let duration: Duration; let duration: Duration;
// Switch to a new stage? // Switch to a new stage?
assert_eq!(now, signal_state.stage_ends_at); assert_eq!(now, signal_state.stage_ends_at);
let old_stage = &signal.stages[signal_state.current_stage]; let old_stage = &signal.stages[signal_state.current_stage];
match old_stage.stage_type { match old_stage.stage_type {
StageType::Fixed(_) => { StageType::Fixed(_) => {
duration = advance(signal_state, signal); duration = advance(signal_state, signal, false);
} }
StageType::Variable(min, delay, additional) => { StageType::Variable(min, delay, additional) => {
// test if anyone is waiting in current stage, and if so, extend the signal cycle. // test if anyone is waiting in current stage, and if so, extend the signal cycle.
@ -294,7 +313,7 @@ impl IntersectionSimState {
min, delay, additional, signal_state.extensions_count min, delay, additional, signal_state.extensions_count
), ),
)); ));
duration = advance(signal_state, signal); duration = advance(signal_state, signal, !ped_waiting);
signal_state.extensions_count = 0; signal_state.extensions_count = 0;
} else if state.waiting.keys().all(|req| { } else if state.waiting.keys().all(|req| {
if let AgentID::Pedestrian(_) = req.agent { if let AgentID::Pedestrian(_) = req.agent {
@ -305,7 +324,7 @@ impl IntersectionSimState {
old_stage.get_priority_of_turn(req.turn, signal) != TurnPriority::Protected old_stage.get_priority_of_turn(req.turn, signal) != TurnPriority::Protected
}) { }) {
signal_state.extensions_count = 0; signal_state.extensions_count = 0;
duration = advance(signal_state, signal); duration = advance(signal_state, signal, !ped_waiting);
} else { } else {
signal_state.extensions_count += 1; signal_state.extensions_count += 1;
duration = delay; duration = delay;