mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
fix crash in all trip viz. path request might not even be possible
This commit is contained in:
parent
06ebf3cb2c
commit
1a4cf8c1a0
@ -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"),
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user