displaying different bus arrival info, and experimenting with storing the data differently. no prebaking yet.

This commit is contained in:
Dustin Carlino 2019-11-04 10:41:50 -08:00
parent 8d32671834
commit 7eeebb72ec
8 changed files with 59 additions and 39 deletions

View File

@ -182,7 +182,7 @@ impl FasterTrips {
TripMode::Transit,
TripMode::Drive,
] {
distribs.insert(m, Default::default());
distribs.insert(m, DurationHistogram::new());
}
for (t, mode, dt) in &self.0 {
if *t > now {

View File

@ -3,7 +3,8 @@ use crate::game::{State, Transition};
use crate::helpers::ID;
use crate::ui::UI;
use ezgui::{hotkey, Color, EventCtx, GfxCtx, Key, Line, ModalMenu, Text};
use geom::DurationHistogram;
use geom::Duration;
use sim::CarID;
use std::collections::BTreeMap;
pub struct InfoPanel {
@ -205,20 +206,21 @@ fn info_for(id: ID, ui: &UI, ctx: &EventCtx) -> Text {
styled_kv(&mut txt, &draw_map.get_es(id).attributes);
}
ID::BusStop(id) => {
let arrivals = &sim.get_analytics().bus_arrivals;
let all_arrivals = &sim.get_analytics().bus_arrivals;
let passengers = &sim.get_analytics().total_bus_passengers;
for r in map.get_routes_serving_stop(id) {
txt.add_appended(vec![Line("- Route "), Line(&r.name).fg(name_color)]);
if let Some(ref times) = arrivals.get(&(id, r.id)) {
let arrivals: Vec<(Duration, CarID)> = all_arrivals
.iter()
.filter(|(_, _, route, stop)| r.id == *route && id == *stop)
.map(|(t, car, _, _)| (*t, *car))
.collect();
if let Some((t, car)) = arrivals.last() {
txt.add(Line(format!(
" Last bus arrived {} ago",
(sim.time() - *times.last().unwrap()).minimal_tostring()
" Last bus arrived {} ago ({})",
(sim.time() - *t).minimal_tostring(),
car
)));
let mut distrib: DurationHistogram = Default::default();
for pair in times.windows(2) {
distrib.add(pair[1] - pair[0]);
}
txt.add(Line(format!(" All arrivals: {}", distrib.describe())));
} else {
txt.add(Line(" No arrivals yet"));
}

View File

@ -6,8 +6,9 @@ use crate::ui::UI;
use abstutil::{prettyprint_usize, Timer};
use ezgui::{hotkey, Choice, Color, EventCtx, GfxCtx, Key, Line, ModalMenu, Text, Wizard};
use geom::{Duration, DurationHistogram, Statistic};
use map_model::BusRouteID;
use sim::{Scenario, TripMode};
use map_model::{BusRouteID, BusStopID};
use sim::{CarID, Scenario, TripMode};
use std::collections::BTreeMap;
#[derive(Clone)]
pub enum GameplayMode {
@ -356,22 +357,37 @@ impl GameplayState {
}
fn bus_route_panel(id: BusRouteID, ui: &UI, stat: Statistic) -> Text {
let mut per_bus: BTreeMap<CarID, Vec<(Duration, BusStopID)>> = BTreeMap::new();
for (t, car, route, stop) in &ui.primary.sim.get_analytics().bus_arrivals {
if *route == id {
per_bus
.entry(*car)
.or_insert_with(Vec::new)
.push((*t, *stop));
}
}
let mut delay_to_stop: BTreeMap<BusStopID, DurationHistogram> = BTreeMap::new();
for events in per_bus.values() {
for pair in events.windows(2) {
delay_to_stop
.entry(pair[1].1)
.or_insert_with(DurationHistogram::new)
.add(pair[1].0 - pair[0].0);
}
}
let route = ui.primary.map.get_br(id);
let arrivals = &ui.primary.sim.get_analytics().bus_arrivals;
let mut txt = Text::new();
txt.add(Line(format!("{} frequency stop is visited", stat)));
for (idx, stop) in route.stops.iter().enumerate() {
txt.add(Line(format!("Stop {}: ", idx + 1)));
if let Some(ref times) = arrivals.get(&(*stop, route.id)) {
if times.len() < 2 {
txt.append(Line("only one arrival so far"));
} else {
let mut distrib: DurationHistogram = Default::default();
for pair in times.windows(2) {
distrib.add(pair[1] - pair[0]);
}
txt.append(Line(distrib.select(stat).minimal_tostring()));
}
txt.add(Line(format!("{} delay between stops", stat)));
for idx1 in 0..route.stops.len() {
let idx2 = if idx1 == route.stops.len() - 1 {
0
} else {
idx1 + 1
};
txt.add(Line(format!("Stop {}->{}: ", idx1 + 1, idx2 + 1)));
if let Some(ref distrib) = delay_to_stop.get(&route.stops[idx2]) {
txt.append(Line(distrib.select(stat).minimal_tostring()));
} else {
txt.append(Line("no arrivals yet"));
}

View File

@ -47,7 +47,7 @@ impl Scoreboard {
.sorted_by_key(|(_, m, _)| *m)
.group_by(|(_, m, _)| *m)
{
let mut distrib: DurationHistogram = std::default::Default::default();
let mut distrib: DurationHistogram = DurationHistogram::new();
for (_, _, dt) in trips {
distrib.add(dt);
}

View File

@ -282,6 +282,10 @@ impl Default for DurationHistogram {
}
impl DurationHistogram {
pub fn new() -> DurationHistogram {
Default::default()
}
pub fn add(&mut self, t: Duration) {
if self.count == 0 {
self.min = t;

View File

@ -1,15 +1,15 @@
use crate::{Event, TripMode};
use crate::{CarID, Event, TripMode};
use abstutil::Counter;
use geom::Duration;
use map_model::{BusRouteID, BusStopID, IntersectionID, Map, RoadID, Traversable};
use std::collections::{HashMap, VecDeque};
use std::collections::VecDeque;
// Embed a deeper structure with its own impl when that makes sense, or feel free to just inline
// things.
pub struct Analytics {
pub thruput_stats: ThruputStats,
pub(crate) test_expectations: VecDeque<Event>,
pub bus_arrivals: HashMap<(BusStopID, BusRouteID), Vec<Duration>>,
pub bus_arrivals: Vec<(Duration, CarID, BusRouteID, BusStopID)>,
pub total_bus_passengers: Counter<BusRouteID>,
// TODO Hack: No TripMode means aborted
// Finish time, mode (or None as aborted), trip duration
@ -29,7 +29,7 @@ impl Default for Analytics {
count_per_intersection: Counter::new(),
},
test_expectations: VecDeque::new(),
bus_arrivals: HashMap::new(),
bus_arrivals: Vec::new(),
total_bus_passengers: Counter::new(),
finished_trips: Vec::new(),
}
@ -53,11 +53,8 @@ impl Analytics {
}
// Bus arrivals
if let Event::BusArrivedAtStop(_, route, stop) = ev {
self.bus_arrivals
.entry((stop, route))
.or_insert(Vec::new())
.push(time);
if let Event::BusArrivedAtStop(bus, route, stop) = ev {
self.bus_arrivals.push((time, bus, route, stop));
}
// Bus passengers

View File

@ -31,6 +31,7 @@ struct State {
deserialize_with = "deserialize_btreemap"
)]
waiting: BTreeMap<Request, Duration>,
// TODO Can we move this to analytics?
#[derivative(PartialEq = "ignore")]
#[serde(skip_serializing, skip_deserializing)]
delays: DurationHistogram,
@ -55,7 +56,7 @@ impl IntersectionSimState {
id: i.id,
accepted: BTreeSet::new(),
waiting: BTreeMap::new(),
delays: std::default::Default::default(),
delays: DurationHistogram::new(),
},
);
if i.is_traffic_signal() && !use_freeform_policy_everywhere {

View File

@ -94,7 +94,7 @@ impl Scheduler {
items: BinaryHeap::new(),
queued_commands: BTreeMap::new(),
latest_time: Duration::ZERO,
delta_times: std::default::Default::default(),
delta_times: DurationHistogram::new(),
}
}