diff --git a/map_model/src/pathfind.rs b/map_model/src/pathfind.rs index 3fdc78ee40..7a246ce36d 100644 --- a/map_model/src/pathfind.rs +++ b/map_model/src/pathfind.rs @@ -42,6 +42,9 @@ impl PathStep { if dist_ahead < 0.0 * si::M { panic!("Negative dist_ahead?! {}", dist_ahead); } + if dist_ahead == 0.0 * si::M { + return None; + } match self { PathStep::Lane(id) => { @@ -137,7 +140,7 @@ impl Path { map: &Map, start_dist: si::Meter, dist_ahead: si::Meter, - ) -> Trace { + ) -> Option { let mut pts_so_far: Option = None; let mut dist_remaining = dist_ahead; @@ -153,21 +156,24 @@ impl Path { } // Special case the first step. - // TODO I think should modify start_dist here for ContraflowLane if let Some((pts, dist)) = self.steps[0].slice(map, start_dist, dist_remaining) { pts_so_far = Some(pts); dist_remaining = dist; } if self.steps.len() == 1 { - // TODO uh, there's one case where this won't work - return pts_so_far.unwrap(); + // It's possible there are paths on their last step that're effectively empty, because + // they're a 0-length turn, or something like a pedestrian crossing a front path and + // immediately getting on a bike. + return pts_so_far; } // Crunch through the intermediate steps, as long as we can. for i in 1..self.steps.len() { if dist_remaining <= 0.0 * si::M { - return pts_so_far.unwrap(); + // We know there's at least some geometry if we made it here, so unwrap to verify + // that understanding. + return Some(pts_so_far.unwrap()); } // If we made it to the last step, maybe use the end_dist. if i == self.steps.len() - 1 && self.end_dist < dist_remaining { @@ -192,7 +198,7 @@ impl Path { } } - return pts_so_far.unwrap(); + return Some(pts_so_far.unwrap()); } pub fn get_steps(&self) -> &VecDeque { diff --git a/sim/src/driving.rs b/sim/src/driving.rs index c522459b28..f4da2020c3 100644 --- a/sim/src/driving.rs +++ b/sim/src/driving.rs @@ -849,7 +849,7 @@ impl DrivingSimState { } let r = self.routers.get(&id)?; let c = &self.cars[&id]; - Some(r.trace_route(c.dist_along, map, dist_ahead)) + r.trace_route(c.dist_along, map, dist_ahead) } pub fn get_path(&self, id: CarID) -> Option<&Path> { diff --git a/sim/src/router.rs b/sim/src/router.rs index 45b376308f..4532d3782a 100644 --- a/sim/src/router.rs +++ b/sim/src/router.rs @@ -204,7 +204,12 @@ impl Router { None } - pub fn trace_route(&self, start_dist: Distance, map: &Map, dist_ahead: Distance) -> Trace { + pub fn trace_route( + &self, + start_dist: Distance, + map: &Map, + dist_ahead: Distance, + ) -> Option { self.path.trace(map, start_dist, dist_ahead) } diff --git a/sim/src/walking.rs b/sim/src/walking.rs index de3a68e9ae..b784f19f75 100644 --- a/sim/src/walking.rs +++ b/sim/src/walking.rs @@ -666,7 +666,7 @@ impl WalkingSimState { pub fn trace_route(&self, id: PedestrianID, map: &Map, dist_ahead: Distance) -> Option { let p = self.peds.get(&id)?; - Some(p.path.trace(map, p.dist_along, dist_ahead)) + p.path.trace(map, p.dist_along, dist_ahead) } pub fn get_path(&self, id: PedestrianID) -> Option<&Path> {