fix crash in all trip viz. path request might not even be possible

This commit is contained in:
Dustin Carlino 2019-10-26 10:29:44 -07:00
parent 06ebf3cb2c
commit 1a4cf8c1a0
2 changed files with 55 additions and 46 deletions

View File

@ -5,14 +5,14 @@ use abstutil::prettyprint_usize;
use ezgui::{
hotkey, layout, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, Line, ModalMenu, Slider, Text,
};
use geom::{Circle, Distance, Duration};
use map_model::{PathRequest, LANE_THICKNESS};
use geom::{Circle, Distance, Duration, PolyLine};
use map_model::LANE_THICKNESS;
use popdat::psrc::Mode;
use popdat::{clip_trips, Trip};
pub struct TripsVisualizer {
menu: ModalMenu,
trips: Vec<Trip>,
trips: Vec<(Trip, PolyLine)>,
time_slider: Slider,
speed: SpeedControls,
@ -20,8 +20,8 @@ pub struct TripsVisualizer {
}
enum MaybeTrip {
Success(Trip),
Failure(PathRequest),
Success(Trip, PolyLine),
Failure(String),
}
impl TripsVisualizer {
@ -30,26 +30,31 @@ impl TripsVisualizer {
let (all_trips, _) = clip_trips(&ui.primary.map, &mut timer);
let map = &ui.primary.map;
let maybe_trips =
timer.parallelize("calculate paths with geometry", all_trips, |mut trip| {
let req = trip.path_req(map);
if let Some(route) = map
.pathfind(req.clone())
.and_then(|path| path.trace(map, req.start.dist_along(), None))
{
trip.route = Some(route);
MaybeTrip::Success(trip)
timer.parallelize("calculate paths with geometry", all_trips, |trip| {
if let Some(req) = trip.path_req(map) {
if let Some(route) = map
.pathfind(req.clone())
.and_then(|path| path.trace(map, req.start.dist_along(), None))
{
MaybeTrip::Success(trip, route)
} else {
MaybeTrip::Failure(req.to_string())
}
} else {
MaybeTrip::Failure(req)
MaybeTrip::Failure(format!(
"{:?} trip from {:?} to {:?}",
trip.mode, trip.from, trip.to
))
}
});
let mut final_trips = Vec::new();
for maybe in maybe_trips {
match maybe {
MaybeTrip::Success(t) => {
final_trips.push(t);
MaybeTrip::Success(t, route) => {
final_trips.push((t, route));
}
MaybeTrip::Failure(req) => {
timer.warn(format!("Couldn't satisfy {}", req));
MaybeTrip::Failure(err) => {
timer.warn(format!("Skipping trip: {}", err));
}
}
}
@ -152,7 +157,7 @@ impl State for TripsVisualizer {
.trips
.iter()
.enumerate()
.filter(|(_, trip)| time >= trip.depart_at && time <= trip.end_time())
.filter(|(_, (trip, _))| time >= trip.depart_at && time <= trip.end_time())
.map(|(idx, _)| idx)
.collect();
@ -167,10 +172,9 @@ impl State for TripsVisualizer {
let time = self.current_time();
let mut batch = GeomBatch::new();
for idx in &self.active_trips {
let trip = &self.trips[*idx];
let (trip, pl) = (&self.trips[*idx].0, &self.trips[*idx].1);
let percent = (time - trip.depart_at) / trip.trip_time;
let pl = trip.route.as_ref().unwrap();
let color = match trip.mode {
Mode::Drive => ui.cs.get("unzoomed car"),
Mode::Walk => ui.cs.get("unzoomed pedestrian"),

View File

@ -1,7 +1,7 @@
use crate::psrc::{Endpoint, Mode, Parcel, Purpose};
use crate::PopDat;
use abstutil::Timer;
use geom::{Distance, Duration, LonLat, PolyLine, Polygon, Pt2D};
use geom::{Distance, Duration, LonLat, Polygon, Pt2D};
use map_model::{BuildingID, IntersectionID, LaneType, Map, PathRequest, Position};
use sim::{DrivingGoal, Scenario, SidewalkSpot, SpawnTrip, TripSpec};
use std::collections::{BTreeMap, HashMap};
@ -16,8 +16,6 @@ pub struct Trip {
// These are an upper bound when TripEndpt::Border is involved.
pub trip_time: Duration,
pub trip_dist: Distance,
// clip_trips doesn't populate this.
pub route: Option<PolyLine>,
}
#[derive(Clone, Debug)]
@ -33,8 +31,8 @@ impl Trip {
self.depart_at + self.trip_time
}
pub fn path_req(&self, map: &Map) -> PathRequest {
match self.mode {
pub fn path_req(&self, map: &Map) -> Option<PathRequest> {
Some(match self.mode {
Mode::Walk => PathRequest {
start: self.from.start_sidewalk_spot(map).sidewalk_pos,
end: self.from.end_sidewalk_spot(map).sidewalk_pos,
@ -42,7 +40,7 @@ impl Trip {
can_use_bus_lanes: false,
},
Mode::Bike => PathRequest {
start: self.from.start_pos_driving(map),
start: self.from.start_pos_driving(map)?,
end: self
.to
.driving_goal(vec![LaneType::Biking, LaneType::Driving], map)
@ -51,7 +49,7 @@ impl Trip {
can_use_bus_lanes: false,
},
Mode::Drive => PathRequest {
start: self.from.start_pos_driving(map),
start: self.from.start_pos_driving(map)?,
end: self
.to
.driving_goal(vec![LaneType::Driving], map)
@ -79,7 +77,7 @@ impl Trip {
}
}
}
}
})
}
}
@ -121,13 +119,13 @@ impl TripEndpt {
// TODO or biking
// TODO bldg_via_driving needs to do find_driving_lane_near_building sometimes
// Doesn't adjust for starting length yet.
fn start_pos_driving(&self, map: &Map) -> Position {
fn start_pos_driving(&self, map: &Map) -> Option<Position> {
match self {
TripEndpt::Building(b) => Position::bldg_via_driving(*b, map).unwrap(),
TripEndpt::Border(i, _) => {
let lane = map.get_i(*i).get_outgoing_lanes(map, LaneType::Driving)[0];
Position::new(lane, Distance::ZERO)
}
TripEndpt::Building(b) => Position::bldg_via_driving(*b, map),
TripEndpt::Border(i, _) => Some(Position::new(
map.get_i(*i).get_outgoing_lanes(map, LaneType::Driving)[0],
Distance::ZERO,
)),
}
}
@ -209,7 +207,6 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
mode: trip.mode,
trip_time: trip.trip_time,
trip_dist: trip.trip_dist,
route: None,
};
match (&trip.from, &trip.to) {
@ -224,7 +221,7 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
if false {
// TODO Figure out why some paths fail.
// TODO Since we're doing the work anyway, store the result?
let dist = map.pathfind(trip.path_req(map))?.total_length();
let dist = map.pathfind(trip.path_req(map)?)?.total_length();
// TODO This is failing all over the place, why?
assert!(dist <= trip.trip_dist);
let trip_time = (dist / trip.trip_dist) * trip.trip_time;
@ -235,7 +232,7 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
}
(TripEndpt::Building(_), TripEndpt::Border(_, _)) => {
if false {
let dist = map.pathfind(trip.path_req(map))?.total_length();
let dist = map.pathfind(trip.path_req(map)?)?.total_length();
assert!(dist <= trip.trip_dist);
trip.trip_time = (dist / trip.trip_dist) * trip.trip_time;
trip.trip_dist = dist;
@ -264,10 +261,14 @@ pub fn trips_to_scenario(map: &Map, timer: &mut Timer) -> Scenario {
.parallelize("turn PSRC trips into SpawnTrips", trips.clone(), |trip| {
match trip.mode {
Mode::Drive => match trip.from {
TripEndpt::Border(_, _) => {
if let Some(start) =
TripSpec::spawn_car_at(trip.from.start_pos_driving(map), map)
{
TripEndpt::Border(i, _) => {
if let Some(start) = TripSpec::spawn_car_at(
Position::new(
map.get_i(i).get_outgoing_lanes(map, LaneType::Driving)[0],
Distance::ZERO,
),
map,
) {
Some(SpawnTrip::CarAppearing {
depart: trip.depart_at,
start,
@ -293,10 +294,14 @@ pub fn trips_to_scenario(map: &Map, timer: &mut Timer) -> Scenario {
trip.to
.driving_goal(vec![LaneType::Biking, LaneType::Driving], map),
)),
TripEndpt::Border(_, _) => {
if let Some(start) =
TripSpec::spawn_car_at(trip.from.start_pos_driving(map), map)
{
TripEndpt::Border(i, _) => {
if let Some(start) = TripSpec::spawn_car_at(
Position::new(
map.get_i(i).get_outgoing_lanes(map, LaneType::Driving)[0],
Distance::ZERO,
),
map,
) {
Some(SpawnTrip::CarAppearing {
depart: trip.depart_at,
start,