Remove the adaptive traffic signal experiment, now that Bruce's variable signals work. The adaptive case was added as a proof-of-concept, and its behavior is subsumed by the variable ones. Fixes #124

This commit is contained in:
Dustin Carlino 2021-01-05 13:06:44 -08:00
parent 6f5f001406
commit 6346302338
9 changed files with 37 additions and 49 deletions

View File

@ -52,11 +52,10 @@ impl ChangeDuration {
ctx,
"stage type",
"fixed",
"adaptive",
"variable",
None,
match signal.stages[idx].stage_type {
StageType::Fixed(_) => true,
StageType::Adaptive(_) => false,
StageType::Variable(_, _, _) => false,
},
),
@ -71,7 +70,6 @@ impl ChangeDuration {
(1, 300),
match signal.stages[idx].stage_type {
StageType::Fixed(_) => 0,
StageType::Adaptive(_) => 0,
StageType::Variable(_, _, additional) => {
additional.inner_seconds() as isize
}
@ -89,7 +87,6 @@ impl ChangeDuration {
(1, 300),
match signal.stages[idx].stage_type {
StageType::Fixed(_) => 0,
StageType::Adaptive(_) => 0,
StageType::Variable(_, delay, _) => delay.inner_seconds() as isize,
},
)

View File

@ -600,7 +600,7 @@ fn make_side_panel(
let mut col = vec![txt.draw(ctx)];
col.push(Widget::horiz_separator(ctx, 0.2));
// TODO Say "normally" to account for adaptive stages?
// TODO Say "normally" to account for variable stages?
col.push(
format!(
"One full cycle lasts {}",
@ -643,7 +643,6 @@ fn make_side_panel(
Widget::row(vec![
match canonical_stage.stage_type {
StageType::Fixed(d) => format!("Stage {}: {}", idx + 1, d),
StageType::Adaptive(d) => format!("Stage {}: {} (adaptive)", idx + 1, d),
StageType::Variable(min, delay, additional) => format!(
"Stage {}: {}, {}, {} (variable)",
idx + 1,

View File

@ -94,7 +94,7 @@ pub fn make_previewer(
// Start at the current stage
let signal = app.primary.map.get_traffic_signal(*i);
// TODO Use the offset correctly
// TODO If there are adaptive stages, this could land anywhere
// TODO If there are variable stages, this could land anywhere
let mut step = Duration::ZERO;
for idx in 0..stage {
step += signal.stages[idx].stage_type.simple_duration();

View File

@ -283,7 +283,6 @@ pub fn traffic_signal(
rows.push(
match stage.stage_type {
StageType::Fixed(d) => Line(format!("Stage {}: {}", idx + 1, d)),
StageType::Adaptive(d) => Line(format!("Stage {}: {} (adaptive)", idx + 1, d)),
StageType::Variable(min, delay, additional) => Line(format!(
"Stage {}: {}, {}, {} (variable)",
idx + 1,

View File

@ -68,6 +68,13 @@ pub fn upgrade(mut value: Value, map: &Map) -> Result<PermanentMapEdits> {
.unwrap()
.insert("version".to_string(), Value::Number(5.into()));
}
if value["version"] == Value::Number(5.into()) {
fix_adaptive_stages(&mut value);
value
.as_object_mut()
.unwrap()
.insert("version".to_string(), Value::Number(6.into()));
}
abstutil::from_json(&value.to_string().into_bytes())
}
@ -253,6 +260,26 @@ fn fix_phase_to_stage(value: &mut Value) {
});
}
// 34e8b0536a4517c68b0e16e5d55cb5e22dae37d8 remove adaptive signal stages.
fn fix_adaptive_stages(value: &mut Value) {
walk(value, &|map| {
if let Some(seconds) = map.remove("Adaptive") {
// The old adaptive policy would repeat the entire stage if there was any demand at
// all, so this isn't quite equivalent, since it only doubles the original time at
// most. This adaptive policy never made any sense, so capturing its behavior more
// clearly here isn't really worth it.
let minimum = seconds.clone();
let delay = Value::Number(1.into());
let additional = seconds;
map.insert(
"Variable".to_string(),
Value::Array(vec![minimum, delay, additional]),
);
}
false
});
}
// These're old structs used in fix_old_lane_cmds.
#[derive(Debug, Deserialize)]
struct OriginalLane {

View File

@ -138,7 +138,7 @@ impl MapEdits {
map_name: map.get_name().clone(),
edits_name: self.edits_name.clone(),
// Increase this every time there's a schema change
version: 5,
version: 6,
proposal_description: self.proposal_description.clone(),
proposal_link: self.proposal_link.clone(),
commands: self.commands.iter().map(|cmd| cmd.to_perma(map)).collect(),

View File

@ -8,7 +8,6 @@ use abstutil::{deserialize_btreemap, retain_btreeset, serialize_btreemap, Timer}
use geom::{Distance, Duration, Speed};
use crate::make::traffic_signals::{brute_force, get_possible_policies};
use crate::objects::traffic_signals::StageType::{Adaptive, Fixed, Variable};
use crate::raw::OriginalRoad;
use crate::{
osm, CompressedMovementID, DirectedRoadID, Direction, IntersectionID, Map, Movement,
@ -47,10 +46,6 @@ pub struct Stage {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum StageType {
Fixed(Duration),
/// Same as fixed, but when this stage would normally end, if there's still incoming demand,
/// repeat the stage entirely.
// TODO This is a silly policy, but a start towards variable timers.
Adaptive(Duration),
/// Minimum is the minimum duration, 0 allows cycle to be skipped if no demand.
/// Delay is the elapsed time with no demand that ends a cycle.
/// Additional is the additional duration for an extended cycle.
@ -61,7 +56,7 @@ impl StageType {
// TODO Maybe don't have this; force callers to acknowledge different policies
pub fn simple_duration(&self) -> Duration {
match self {
StageType::Fixed(d) | StageType::Adaptive(d) => *d,
StageType::Fixed(d) => *d,
StageType::Variable(duration, delay, _) => {
if *duration > Duration::ZERO {
*duration
@ -326,9 +321,10 @@ impl Stage {
);
if time > self.stage_type.simple_duration() {
self.stage_type = match self.stage_type {
StageType::Adaptive(_) => Adaptive(time),
StageType::Fixed(_) => Fixed(time),
StageType::Variable(_, delay, additional) => Variable(time, delay, additional),
StageType::Fixed(_) => StageType::Fixed(time),
StageType::Variable(_, delay, additional) => {
StageType::Variable(time, delay, additional)
}
};
}
}
@ -356,9 +352,6 @@ impl ControlTrafficSignal {
StageType::Fixed(d) => {
traffic_signal_data::StageType::Fixed(d.inner_seconds() as usize)
}
StageType::Adaptive(d) => {
traffic_signal_data::StageType::Adaptive(d.inner_seconds() as usize)
}
StageType::Variable(min, delay, additional) => {
traffic_signal_data::StageType::Variable(
min.inner_seconds() as usize,
@ -411,9 +404,6 @@ impl ControlTrafficSignal {
traffic_signal_data::StageType::Fixed(d) => {
StageType::Fixed(Duration::seconds(d as f64))
}
traffic_signal_data::StageType::Adaptive(d) => {
StageType::Adaptive(Duration::seconds(d as f64))
}
traffic_signal_data::StageType::Variable(min, delay, additional) => {
StageType::Variable(
Duration::seconds(min as f64),

View File

@ -74,7 +74,7 @@ struct SignalState {
current_stage: usize,
// The time when the signal is checked for advancing
stage_ends_at: Time,
// The count of time an adaptive signal has been extended during the current stage.
// The number of times a variable signal has been extended during the current stage.
extensions_count: usize,
}
@ -273,27 +273,6 @@ impl IntersectionSimState {
StageType::Fixed(_) => {
duration = advance(signal_state, signal);
}
StageType::Adaptive(_) => {
// TODO Make a better policy here. For now, if there's _anyone_ waiting to start a
// protected turn, repeat this stage for the full duration. Note that "waiting" is
// only defined as "at the end of the lane, ready to start the turn." If a
// vehicle/ped is a second away from the intersection, this won't detect that. We
// could pass in all of the Queues here and use that to count all incoming agents,
// even ones a little farther away.
if state.waiting.keys().all(|req| {
old_stage.get_priority_of_turn(req.turn, signal) != TurnPriority::Protected
}) {
duration = advance(signal_state, signal);
self.events.push(Event::Alert(
AlertLocation::Intersection(id),
"Repeating an adaptive stage".to_string(),
));
} else {
duration = signal.stages[signal_state.current_stage]
.stage_type
.simple_duration();
}
}
StageType::Variable(min, delay, additional) => {
// test if anyone is waiting in current stage, and if so, extend the signal cycle.
// Filter out pedestrians, as they've had their chance and the delay

View File

@ -36,9 +36,6 @@ pub struct Stage {
pub enum StageType {
/// A fixed number of seconds.
Fixed(usize),
/// Some multiple of a fixed number of seconds. At the end of this stage, based on incoming
/// demand, this stage may repeat.
Adaptive(usize),
/// Minimum, Delay, Additional
/// Minimum is the minimum cycle duration, 0 allows it to be skipped if no demand.
/// Delay is the duration with no demand needed to end a cycle, 0 ends as soon as there is no