change gridlock score to use number of finished trips

This commit is contained in:
Dustin Carlino 2019-11-07 08:59:29 -08:00
parent 5b50cac80e
commit e82abafb70
4 changed files with 82 additions and 62 deletions

View File

@ -91,7 +91,7 @@ impl SpeedControls {
let mut slider = Slider::new(); let mut slider = Slider::new();
// Start with speed=1.0 // Start with speed=1.0
slider.set_percent(ctx, (SPEED_CAP / 5.0).powf(-1.0 / std::f64::consts::E)); slider.set_percent(ctx, (SPEED_CAP / 1.0).powf(-1.0 / std::f64::consts::E));
slider.set_pos(ScreenPt::new(0.0, 100.0), 150.0); slider.set_pos(ScreenPt::new(0.0, 100.0), 150.0);
let (small_step_btn, large_step_btn, jump_to_time_btn) = if step_controls { let (small_step_btn, large_step_btn, jump_to_time_btn) = if step_controls {

View File

@ -9,7 +9,7 @@ use abstutil::{prettyprint_usize, Timer};
use ezgui::{hotkey, Choice, Color, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, Wizard}; use ezgui::{hotkey, Choice, Color, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, Wizard};
use geom::{Duration, Statistic}; use geom::{Duration, Statistic};
use map_model::BusRouteID; use map_model::BusRouteID;
use sim::{Analytics, Scenario, Sim, TripMode}; use sim::{Analytics, Scenario, TripMode};
#[derive(Clone)] #[derive(Clone)]
pub enum GameplayMode { pub enum GameplayMode {
@ -143,7 +143,7 @@ impl GameplayState {
GameplayState { GameplayState {
mode, mode,
menu: ModalMenu::new( menu: ModalMenu::new(
&format!("Speed up {:?} trips", trip_mode), &format!("Speed up {} trips", trip_mode),
vec![(hotkey(Key::H), "help")], vec![(hotkey(Key::H), "help")],
ctx, ctx,
) )
@ -454,34 +454,58 @@ fn bus_delays(id: BusRouteID, ui: &UI, ctx: &mut EventCtx) -> Plot<Duration> {
) )
} }
fn gridlock_panel(ui: &UI, _prebaked: &Analytics) -> Text { fn gridlock_panel(ui: &UI, prebaked: &Analytics) -> Text {
let now = GridlockDelays::from(&ui.primary.sim); let (now_all, now_per_mode) = ui
// TODO Derive this from something in Analytics .primary
let baseline = GridlockDelays::from(&ui.primary.sim); .sim
.get_analytics()
let now_total = (now.lt_1m + now.lt_5m + now.stuck) as f64; .all_finished_trips(ui.primary.sim.time());
let baseline_total = (baseline.lt_1m + baseline.lt_5m + baseline.stuck) as f64; let (baseline_all, baseline_per_mode) = prebaked.all_finished_trips(ui.primary.sim.time());
let mut txt = Text::new(); let mut txt = Text::new();
txt.add(Line("How long have agents been stuck?"));
txt.add(Line(format!( txt.add(Line(format!(
"under 1 min: {} ({:.1}%, vs {:.1}%)", "{} total finished trips (",
prettyprint_usize(now.lt_1m), prettyprint_usize(now_all.count())
(now.lt_1m as f64) / now_total * 100.0,
(baseline.lt_1m as f64) / baseline_total * 100.0
)));
txt.add(Line(format!(
"under 5 mins: {} ({:.1}%, vs {:.1}%)",
prettyprint_usize(now.lt_5m),
(now.lt_5m as f64) / now_total * 100.0,
(baseline.lt_5m as f64) / baseline_total * 100.0
)));
txt.add(Line(format!(
"over 5 mins: {} ({:.1}%, vs {:.1}%)",
prettyprint_usize(now.stuck),
(now.stuck as f64) / now_total * 100.0,
(baseline.stuck as f64) / baseline_total * 100.0
))); )));
if now_all.count() < baseline_all.count() {
txt.append(
Line(format!(
"{} fewer",
prettyprint_usize(baseline_all.count() - now_all.count())
))
.fg(Color::GREEN),
);
} else if now_all.count() > baseline_all.count() {
txt.append(
Line(format!(
"{} more",
prettyprint_usize(now_all.count() - baseline_all.count())
))
.fg(Color::RED),
);
} else {
txt.append(Line("same as baseline"));
}
txt.append(Line(")"));
for mode in TripMode::all() {
let a = now_per_mode[&mode].count();
let b = baseline_per_mode[&mode].count();
txt.add(Line(format!(
" {}: {} (",
mode,
prettyprint_usize(now_per_mode[&mode].count())
)));
if a < b {
txt.append(Line(format!("{} fewer", prettyprint_usize(b - a))).fg(Color::GREEN));
} else if b > a {
txt.append(Line(format!("{} more", prettyprint_usize(a - b))).fg(Color::RED));
} else {
txt.append(Line("same as baseline"));
}
txt.append(Line(")"));
}
txt txt
} }
@ -495,7 +519,7 @@ fn faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &Analytics) -> Text {
let mut txt = Text::new(); let mut txt = Text::new();
txt.add(Line(format!( txt.add(Line(format!(
"{} finished {:?} trips (vs {})", "{} finished {} trips (vs {})",
prettyprint_usize(now.count()), prettyprint_usize(now.count()),
mode, mode,
prettyprint_usize(baseline.count()), prettyprint_usize(baseline.count()),
@ -609,29 +633,3 @@ fn manage_acs(
ui.agent_cs = AgentColorScheme::VehicleTypes; ui.agent_cs = AgentColorScheme::VehicleTypes;
} }
} }
// TODO Figure out what we really want to measure here.
struct GridlockDelays {
lt_1m: usize,
lt_5m: usize,
stuck: usize,
}
impl GridlockDelays {
fn from(sim: &Sim) -> GridlockDelays {
let mut delays = GridlockDelays {
lt_1m: 0,
lt_5m: 0,
stuck: 0,
};
for a in sim.get_agent_metadata() {
if a.time_spent_blocked < Duration::minutes(1) {
delays.lt_1m += 1;
} else if a.time_spent_blocked < Duration::minutes(5) {
delays.lt_5m += 1;
} else {
delays.stuck += 1;
}
}
delays
}
}

View File

@ -8,7 +8,7 @@ use crate::sandbox::bus_explorer::ShowBusRoute;
use crate::sandbox::SandboxMode; use crate::sandbox::SandboxMode;
use crate::ui::{ShowEverything, UI}; use crate::ui::{ShowEverything, UI};
use abstutil::{prettyprint_usize, Counter}; use abstutil::{prettyprint_usize, Counter};
use ezgui::{Choice, Color, EventCtx, GfxCtx, Line, MenuUnderButton, Text}; use ezgui::{Choice, Color, EventCtx, GfxCtx, Key, Line, MenuUnderButton, Text};
use geom::Duration; use geom::Duration;
use map_model::PathStep; use map_model::PathStep;
use sim::{ParkingSpot, TripMode}; use sim::{ParkingSpot, TripMode};
@ -41,13 +41,13 @@ impl Overlays {
wiz.wrap(ctx).choose("Show which analytics overlay?", || { wiz.wrap(ctx).choose("Show which analytics overlay?", || {
// TODO Filter out the current // TODO Filter out the current
vec![ vec![
Choice::new("none", ()), Choice::new("none", ()).key(Key::N),
Choice::new("parking availability", ()), Choice::new("parking availability", ()).key(Key::P),
Choice::new("intersection delay", ()), Choice::new("intersection delay", ()).key(Key::I),
Choice::new("cumulative throughput", ()), Choice::new("cumulative throughput", ()).key(Key::T),
Choice::new("finished trips", ()), Choice::new("finished trips", ()).key(Key::F),
Choice::new("chokepoints", ()), Choice::new("chokepoints", ()).key(Key::C),
Choice::new("bike network", ()), Choice::new("bike network", ()).key(Key::B),
] ]
})?; })?;
Some(Transition::PopWithData(Box::new(move |state, ui, ctx| { Some(Transition::PopWithData(Box::new(move |state, ui, ctx| {

View File

@ -92,6 +92,28 @@ impl Analytics {
distrib distrib
} }
// Returns (all trips except aborted, trips by mode)
pub fn all_finished_trips(
&self,
now: Duration,
) -> (DurationHistogram, BTreeMap<TripMode, DurationHistogram>) {
let mut per_mode = TripMode::all()
.into_iter()
.map(|m| (m, DurationHistogram::new()))
.collect::<BTreeMap<_, _>>();
let mut all = DurationHistogram::new();
for (t, m, dt) in &self.finished_trips {
if *t > now {
break;
}
if let Some(mode) = *m {
all.add(*dt);
per_mode.get_mut(&mode).unwrap().add(*dt);
}
}
(all, per_mode)
}
pub fn bus_arrivals( pub fn bus_arrivals(
&self, &self,
now: Duration, now: Duration,