mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 12:43:38 +03:00
enum for trip phases
This commit is contained in:
parent
08cd956faa
commit
cc1ee8384a
@ -221,9 +221,9 @@ f9f0a109966db097617a13122ecaa6f3 data/system/scenarios/downtown/weekday.bin
|
||||
dd54763cfda7fce4c401ae122c6daf57 data/system/scenarios/huge_seattle/weekday.bin
|
||||
47dea892a1c4331da02494d15ce02a02 data/system/scenarios/caphill/weekday.bin
|
||||
7d6a8e8f5d716ce8674ed63d27f2da51 data/system/scenarios/montlake/weekday.bin
|
||||
678efca4f16d5d8ce6bd88efd3afe957 data/system/prebaked_results/23rd/weekday.bin
|
||||
d14e39816482a53c2d05e593f5f47249 data/system/prebaked_results/signal_single/tutorial lvl1.bin
|
||||
22a6458bcf4bbb1cd875e12bcf012c08 data/system/prebaked_results/signal_single/tutorial lvl2.bin
|
||||
460bd68fcc0c4686db7d654de372f46d data/system/prebaked_results/montlake/car vs bike contention.bin
|
||||
12b13a7c7fd8cb2592607aa79b55558b data/system/prebaked_results/montlake/weekday.bin
|
||||
160ff09f5c38d96fe83c4e9fcddfb019 data/system/prebaked_results/montlake/car vs bus contention.bin
|
||||
b50d41d25ba40504df5a56945769bb27 data/system/prebaked_results/23rd/weekday.bin
|
||||
c83401e693ea9bb2c437ecdcc33fadbf data/system/prebaked_results/signal_single/tutorial lvl1.bin
|
||||
e8cdc329b7c10914df88ea3d4df6abd0 data/system/prebaked_results/signal_single/tutorial lvl2.bin
|
||||
b8137879ec00add4cd2a39e8c985420f data/system/prebaked_results/montlake/car vs bike contention.bin
|
||||
029227cdea45492954e3b1666b0dc5b9 data/system/prebaked_results/montlake/weekday.bin
|
||||
994677ade10b0d021f3a0eb91696265c data/system/prebaked_results/montlake/car vs bus contention.bin
|
||||
|
@ -14,7 +14,9 @@ use ezgui::{
|
||||
};
|
||||
use geom::{Angle, Circle, Distance, Duration, Polygon, Pt2D, Statistic, Time};
|
||||
use map_model::{IntersectionID, IntersectionType, RoadID};
|
||||
use sim::{AgentID, CarID, TripEnd, TripID, TripMode, TripResult, TripStart, VehicleType};
|
||||
use sim::{
|
||||
AgentID, CarID, TripEnd, TripID, TripMode, TripPhaseType, TripResult, TripStart, VehicleType,
|
||||
};
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
|
||||
pub struct InfoPanel {
|
||||
@ -1036,10 +1038,16 @@ fn trip_details(
|
||||
let mut timeline = Vec::new();
|
||||
let num_phases = phases.len();
|
||||
for (idx, p) in phases.into_iter().enumerate() {
|
||||
// TODO based on segment type
|
||||
let color = rotating_color_map(timeline.len());
|
||||
let color = match p.phase_type {
|
||||
TripPhaseType::Driving => Color::hex("#D63220"),
|
||||
TripPhaseType::Walking => Color::hex("#DF8C3D"),
|
||||
TripPhaseType::Parking => Color::hex("#4E30A6"),
|
||||
// TODO The others
|
||||
_ => rotating_color_map(timeline.len()),
|
||||
}
|
||||
.alpha(0.7);
|
||||
|
||||
let mut txt = Text::from(Line(&p.description));
|
||||
let mut txt = Text::from(Line(&p.phase_type.describe(&app.primary.map)));
|
||||
txt.add(Line(format!(
|
||||
"- Started at {}",
|
||||
p.start_time.ampm_tostring()
|
||||
@ -1070,27 +1078,24 @@ fn trip_details(
|
||||
);
|
||||
}
|
||||
}
|
||||
// TODO Hardcoded layouting...
|
||||
normal.add_svg(
|
||||
ctx.prerender,
|
||||
if p.description == "driving" {
|
||||
"../data/system/assets/timeline/driving.svg"
|
||||
} else if p.description == "walking" {
|
||||
"../data/system/assets/timeline/walking.svg"
|
||||
} else if p.description == "parking on the current lane"
|
||||
|| p.description == "parking somewhere else"
|
||||
{
|
||||
"../data/system/assets/timeline/parking.svg"
|
||||
} else {
|
||||
// TODO Placeholder
|
||||
"../data/system/assets/timeline/parking.svg"
|
||||
},
|
||||
Pt2D::new(0.5 * phase_width, -20.0),
|
||||
1.0,
|
||||
Angle::ZERO,
|
||||
);
|
||||
if let Some(icon) = match p.phase_type {
|
||||
TripPhaseType::Driving => Some("../data/system/assets/timeline/driving.svg"),
|
||||
TripPhaseType::Walking => Some("../data/system/assets/timeline/walking.svg"),
|
||||
TripPhaseType::Parking => Some("../data/system/assets/timeline/parking.svg"),
|
||||
// TODO Add in more
|
||||
_ => None,
|
||||
} {
|
||||
normal.add_svg(
|
||||
ctx.prerender,
|
||||
icon,
|
||||
// TODO Hardcoded layouting...
|
||||
Pt2D::new(0.5 * phase_width, -20.0),
|
||||
1.0,
|
||||
Angle::ZERO,
|
||||
);
|
||||
}
|
||||
|
||||
let mut hovered = GeomBatch::from(vec![(colors::HOVERING, rect.clone())]);
|
||||
let mut hovered = GeomBatch::from(vec![(color.alpha(1.0), rect.clone())]);
|
||||
for (c, p) in normal.clone().consume().into_iter().skip(1) {
|
||||
hovered.push(c, p);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{CarID, Event, TripID, TripMode};
|
||||
use crate::{CarID, Event, TripID, TripMode, TripPhaseType};
|
||||
use abstutil::Counter;
|
||||
use derivative::Derivative;
|
||||
use geom::{Distance, Duration, DurationHistogram, PercentageHistogram, Time};
|
||||
@ -21,7 +21,7 @@ pub struct Analytics {
|
||||
// Finish time, ID, mode (or None as aborted), trip duration
|
||||
pub finished_trips: Vec<(Time, TripID, Option<TripMode>, Duration)>,
|
||||
// TODO This subsumes finished_trips
|
||||
pub trip_log: Vec<(Time, TripID, Option<PathRequest>, String)>,
|
||||
pub trip_log: Vec<(Time, TripID, Option<PathRequest>, TripPhaseType)>,
|
||||
pub intersection_delays: BTreeMap<IntersectionID, Vec<(Time, Duration)>>,
|
||||
|
||||
// After we restore from a savestate, don't record anything. This is only going to make sense
|
||||
@ -148,16 +148,15 @@ impl Analytics {
|
||||
|
||||
// TODO Kinda hacky, but these all consume the event, so kinda bundle em.
|
||||
match ev {
|
||||
Event::TripPhaseStarting(id, _, maybe_req, metadata) => {
|
||||
self.trip_log.push((time, id, maybe_req, metadata));
|
||||
Event::TripPhaseStarting(id, _, maybe_req, phase_type) => {
|
||||
self.trip_log.push((time, id, maybe_req, phase_type));
|
||||
}
|
||||
Event::TripAborted(id, _) => {
|
||||
self.trip_log
|
||||
.push((time, id, None, format!("trip aborted for some reason")));
|
||||
self.trip_log.push((time, id, None, TripPhaseType::Aborted));
|
||||
}
|
||||
Event::TripFinished(id, _, _) => {
|
||||
self.trip_log
|
||||
.push((time, id, None, format!("trip finished")));
|
||||
.push((time, id, None, TripPhaseType::Finished));
|
||||
}
|
||||
Event::PathAmended(path) => {
|
||||
self.record_demand(&path, map);
|
||||
@ -420,14 +419,14 @@ impl Analytics {
|
||||
|
||||
pub fn get_trip_phases(&self, trip: TripID, map: &Map) -> Vec<TripPhase> {
|
||||
let mut phases: Vec<TripPhase> = Vec::new();
|
||||
for (t, id, maybe_req, md) in &self.trip_log {
|
||||
for (t, id, maybe_req, phase_type) in &self.trip_log {
|
||||
if *id != trip {
|
||||
continue;
|
||||
}
|
||||
if let Some(ref mut last) = phases.last_mut() {
|
||||
last.end_time = Some(*t);
|
||||
}
|
||||
if md == "trip finished" || md == "trip aborted for some reason" {
|
||||
if *phase_type == TripPhaseType::Finished || *phase_type == TripPhaseType::Aborted {
|
||||
break;
|
||||
}
|
||||
phases.push(TripPhase {
|
||||
@ -437,7 +436,7 @@ impl Analytics {
|
||||
path: maybe_req
|
||||
.as_ref()
|
||||
.map(|req| (req.start.dist_along(), map.pathfind(req.clone()).unwrap())),
|
||||
description: md.clone(),
|
||||
phase_type: *phase_type,
|
||||
})
|
||||
}
|
||||
phases
|
||||
@ -445,16 +444,16 @@ impl Analytics {
|
||||
|
||||
fn get_all_trip_phases(&self) -> BTreeMap<TripID, Vec<TripPhase>> {
|
||||
let mut trips = BTreeMap::new();
|
||||
for (t, id, _, md) in &self.trip_log {
|
||||
for (t, id, _, phase_type) in &self.trip_log {
|
||||
let phases: &mut Vec<TripPhase> = trips.entry(*id).or_insert_with(Vec::new);
|
||||
if let Some(ref mut last) = phases.last_mut() {
|
||||
last.end_time = Some(*t);
|
||||
}
|
||||
if md == "trip finished" {
|
||||
if *phase_type == TripPhaseType::Finished {
|
||||
continue;
|
||||
}
|
||||
// Remove aborted trips
|
||||
if md == "trip aborted for some reason" {
|
||||
if *phase_type == TripPhaseType::Aborted {
|
||||
trips.remove(id);
|
||||
continue;
|
||||
}
|
||||
@ -463,7 +462,7 @@ impl Analytics {
|
||||
end_time: None,
|
||||
// Don't compute any paths
|
||||
path: None,
|
||||
description: md.clone(),
|
||||
phase_type: *phase_type,
|
||||
})
|
||||
}
|
||||
trips
|
||||
@ -482,17 +481,14 @@ impl Analytics {
|
||||
let mut overhead = Duration::ZERO;
|
||||
for p in phases {
|
||||
let dt = p.end_time.unwrap() - p.start_time;
|
||||
// TODO New enum instead of strings, if there'll be more analyses like this
|
||||
if p.description.starts_with("CarID(") {
|
||||
driving_time += dt;
|
||||
} else if p.description == "parking somewhere else"
|
||||
|| p.description == "parking on the current lane"
|
||||
{
|
||||
overhead += dt;
|
||||
} else if p.description.starts_with("PedestrianID(") {
|
||||
overhead += dt;
|
||||
} else {
|
||||
// Waiting for a bus. Irrelevant.
|
||||
match p.phase_type {
|
||||
TripPhaseType::Driving => {
|
||||
driving_time += dt;
|
||||
}
|
||||
TripPhaseType::Parking | TripPhaseType::Walking => {
|
||||
overhead += dt;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// Only interested in trips with both
|
||||
@ -615,7 +611,7 @@ pub struct TripPhase {
|
||||
pub end_time: Option<Time>,
|
||||
// Plumb along start distance
|
||||
pub path: Option<(Distance, Path)>,
|
||||
pub description: String,
|
||||
pub phase_type: TripPhaseType,
|
||||
}
|
||||
|
||||
struct Window {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{AgentID, CarID, ParkingSpot, PedestrianID, TripID, TripMode};
|
||||
use geom::Duration;
|
||||
use map_model::{
|
||||
BuildingID, BusRouteID, BusStopID, IntersectionID, LaneID, Path, PathRequest, Traversable,
|
||||
BuildingID, BusRouteID, BusStopID, IntersectionID, LaneID, Map, Path, PathRequest, Traversable,
|
||||
};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
@ -27,9 +27,36 @@ pub enum Event {
|
||||
|
||||
TripFinished(TripID, TripMode, Duration),
|
||||
TripAborted(TripID, TripMode),
|
||||
TripPhaseStarting(TripID, TripMode, Option<PathRequest>, String),
|
||||
TripPhaseStarting(TripID, TripMode, Option<PathRequest>, TripPhaseType),
|
||||
|
||||
// Just use for parking replanning. Not happy about copying the full path in here, but the way
|
||||
// to plumb info into Analytics is Event.
|
||||
PathAmended(Path),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum TripPhaseType {
|
||||
Driving,
|
||||
Walking,
|
||||
Biking,
|
||||
Parking,
|
||||
WaitingForBus(BusRouteID),
|
||||
RidingBus(BusRouteID),
|
||||
Aborted,
|
||||
Finished,
|
||||
}
|
||||
|
||||
impl TripPhaseType {
|
||||
pub fn describe(self, map: &Map) -> String {
|
||||
match self {
|
||||
TripPhaseType::Driving => "driving".to_string(),
|
||||
TripPhaseType::Walking => "walking".to_string(),
|
||||
TripPhaseType::Biking => "biking".to_string(),
|
||||
TripPhaseType::Parking => "parking".to_string(),
|
||||
TripPhaseType::WaitingForBus(r) => format!("waiting for bus {}", map.get_br(r).name),
|
||||
TripPhaseType::RidingBus(r) => format!("riding bus {}", map.get_br(r).name),
|
||||
TripPhaseType::Aborted => "trip aborted due to some bug".to_string(),
|
||||
TripPhaseType::Finished => "trip finished".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ mod transit;
|
||||
mod trips;
|
||||
|
||||
pub use self::analytics::{Analytics, TripPhase};
|
||||
pub use self::events::Event;
|
||||
pub use self::events::{Event, TripPhaseType};
|
||||
pub use self::make::{
|
||||
ABTest, BorderSpawnOverTime, OriginDestination, Scenario, SeedParkedCars, SimFlags,
|
||||
SpawnOverTime, SpawnTrip, TripSpawner, TripSpec,
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::mechanics::Queue;
|
||||
use crate::{Event, ParkingSimState, ParkingSpot, SidewalkSpot, TripID, TripMode, Vehicle};
|
||||
use crate::{
|
||||
Event, ParkingSimState, ParkingSpot, SidewalkSpot, TripID, TripMode, TripPhaseType, Vehicle,
|
||||
};
|
||||
use geom::Distance;
|
||||
use map_model::{
|
||||
BuildingID, IntersectionID, LaneID, Map, Path, PathConstraints, PathRequest, PathStep,
|
||||
@ -200,7 +202,7 @@ impl Router {
|
||||
end: new_pos,
|
||||
constraints: PathConstraints::Car,
|
||||
}),
|
||||
format!("parking on the current lane"),
|
||||
TripPhaseType::Parking,
|
||||
));
|
||||
*spot = Some((new_spot, new_pos.dist_along()));
|
||||
} else {
|
||||
@ -221,7 +223,7 @@ impl Router {
|
||||
end: new_pos,
|
||||
constraints: PathConstraints::Car,
|
||||
}),
|
||||
format!("parking somewhere else"),
|
||||
TripPhaseType::Parking,
|
||||
));
|
||||
} else {
|
||||
println!(
|
||||
|
@ -3,8 +3,8 @@ use crate::{
|
||||
DrawPedestrianInput, DrivingGoal, DrivingSimState, Event, GetDrawAgents, IntersectionSimState,
|
||||
ParkedCar, ParkingSimState, ParkingSpot, PedestrianID, Router, Scheduler, SidewalkPOI,
|
||||
SidewalkSpot, TransitSimState, TripCount, TripEnd, TripID, TripLeg, TripManager, TripMode,
|
||||
TripPositions, TripResult, TripSpawner, TripSpec, TripStart, UnzoomedAgent, VehicleSpec,
|
||||
VehicleType, WalkingSimState, BUS_LENGTH,
|
||||
TripPhaseType, TripPositions, TripResult, TripSpawner, TripSpec, TripStart, UnzoomedAgent,
|
||||
VehicleSpec, VehicleType, WalkingSimState, BUS_LENGTH,
|
||||
};
|
||||
use abstutil::Timer;
|
||||
use derivative::Derivative;
|
||||
@ -440,9 +440,9 @@ impl Sim {
|
||||
},
|
||||
Some(create_car.req.clone()),
|
||||
if create_car.vehicle.id.1 == VehicleType::Car {
|
||||
"driving".to_string()
|
||||
TripPhaseType::Driving
|
||||
} else {
|
||||
"biking".to_string()
|
||||
TripPhaseType::Biking
|
||||
},
|
||||
));
|
||||
self.analytics
|
||||
@ -524,7 +524,7 @@ impl Sim {
|
||||
create_ped.trip,
|
||||
TripMode::Walk,
|
||||
Some(create_ped.req.clone()),
|
||||
"walking".to_string(),
|
||||
TripPhaseType::Walking,
|
||||
));
|
||||
self.analytics.record_demand(&create_ped.path, map);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::{
|
||||
CarID, Event, PedestrianID, Router, Scheduler, TripManager, TripMode, WalkingSimState,
|
||||
CarID, Event, PedestrianID, Router, Scheduler, TripManager, TripMode, TripPhaseType,
|
||||
WalkingSimState,
|
||||
};
|
||||
use abstutil::{deserialize_btreemap, serialize_btreemap};
|
||||
use geom::{Distance, Time};
|
||||
@ -192,7 +193,7 @@ impl TransitSimState {
|
||||
end: map.get_bs(stop2).driving_pos,
|
||||
constraints: PathConstraints::Bus,
|
||||
}),
|
||||
format!("riding bus {}", map.get_br(route).name),
|
||||
TripPhaseType::RidingBus(route),
|
||||
));
|
||||
} else {
|
||||
still_waiting.push((ped, route, stop2, started_waiting));
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
AgentID, CarID, Command, CreateCar, CreatePedestrian, DrivingGoal, Event, ParkingSimState,
|
||||
ParkingSpot, PedestrianID, Scheduler, SidewalkPOI, SidewalkSpot, TransitSimState, TripID,
|
||||
Vehicle, VehicleType, WalkingSimState,
|
||||
TripPhaseType, Vehicle, VehicleType, WalkingSimState,
|
||||
};
|
||||
use abstutil::{deserialize_btreemap, serialize_btreemap, Counter};
|
||||
use geom::{Speed, Time};
|
||||
@ -353,7 +353,7 @@ impl TripManager {
|
||||
trip.id,
|
||||
trip.mode,
|
||||
None,
|
||||
format!("waiting for bus {}", map.get_br(route).name),
|
||||
TripPhaseType::WaitingForBus(route),
|
||||
));
|
||||
if transit.ped_waiting_for_bus(now, ped, stop, route, stop2) {
|
||||
trip.legs.pop_front();
|
||||
|
Loading…
Reference in New Issue
Block a user