debug tooltip showing how far an agent has traveled and how much

remains. seems to have small perf impact on initially calculating paths.
:(
This commit is contained in:
Dustin Carlino 2019-08-16 14:06:51 -07:00
parent bbc4492205
commit a9267c76c7
8 changed files with 67 additions and 12 deletions

View File

@ -391,6 +391,9 @@ impl<'a> std::ops::Drop for Timer<'a> {
} }
self.println(String::new()); self.println(String::new());
} }
// In case of lots of notes and warnings, repeat the overall timing.
Timer::selfless_println(&mut self.sink, self.results[0].clone());
} }
} }

View File

@ -40,6 +40,10 @@ impl Distance {
Distance::meters(1609.34 * value) Distance::meters(1609.34 * value)
} }
pub fn centimeters(value: usize) -> Distance {
Distance::meters((value as f64) / 100.0)
}
pub fn abs(self) -> Distance { pub fn abs(self) -> Distance {
if self.0 > 0.0 { if self.0 > 0.0 {
self self

View File

@ -1,6 +1,7 @@
use crate::pathfind::node_map::{deserialize_nodemap, NodeMap}; use crate::pathfind::node_map::{deserialize_nodemap, NodeMap};
use crate::{LaneID, LaneType, Map, Path, PathRequest, PathStep, TurnID}; use crate::{LaneID, LaneType, Map, Path, PathRequest, PathStep, TurnID};
use fast_paths::{FastGraph, InputGraph, PathCalculator}; use fast_paths::{FastGraph, InputGraph, PathCalculator};
use geom::Distance;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::cell::RefCell; use std::cell::RefCell;
use thread_local::ThreadLocal; use thread_local::ThreadLocal;
@ -70,7 +71,12 @@ impl VehiclePathfinder {
})); }));
} }
steps.push(PathStep::Lane(req.end.lane())); steps.push(PathStep::Lane(req.end.lane()));
Some(Path::new(map, steps, req.end.dist_along())) Some(Path::new(
map,
steps,
req.end.dist_along(),
Distance::centimeters(raw_path.get_weight()),
))
} }
pub fn apply_edits(&mut self, map: &Map) { pub fn apply_edits(&mut self, map: &Map) {

View File

@ -88,11 +88,19 @@ impl PathStep {
pub struct Path { pub struct Path {
steps: VecDeque<PathStep>, steps: VecDeque<PathStep>,
end_dist: Distance, end_dist: Distance,
// Also track progress along the original path.
total_length: Distance,
crossed_so_far: Distance,
} }
impl Path { impl Path {
// TODO pub for DrawCarInput... bleh. pub(crate) fn new(
pub fn new(map: &Map, steps: Vec<PathStep>, end_dist: Distance) -> Path { map: &Map,
steps: Vec<PathStep>,
end_dist: Distance,
total_length: Distance,
) -> Path {
// Haven't seen problems here in a very long time. Noticeably saves some time to skip. // Haven't seen problems here in a very long time. Noticeably saves some time to skip.
if false { if false {
validate(map, &steps); validate(map, &steps);
@ -100,6 +108,8 @@ impl Path {
Path { Path {
steps: VecDeque::from(steps), steps: VecDeque::from(steps),
end_dist, end_dist,
total_length,
crossed_so_far: Distance::ZERO,
} }
} }
@ -114,6 +124,14 @@ impl Path {
count count
} }
pub fn crossed_so_far(&self) -> Distance {
self.crossed_so_far
}
pub fn total_length(&self) -> Distance {
self.total_length
}
pub fn is_last_step(&self) -> bool { pub fn is_last_step(&self) -> bool {
self.steps.len() == 1 self.steps.len() == 1
} }
@ -122,11 +140,14 @@ impl Path {
self.steps.len() > 1 self.steps.len() > 1
} }
pub fn shift(&mut self) -> PathStep { pub fn shift(&mut self, map: &Map) -> PathStep {
self.steps.pop_front().unwrap() let step = self.steps.pop_front().unwrap();
self.crossed_so_far += step.as_traversable().length(map);
step
} }
pub fn add(&mut self, step: PathStep) { pub fn add(&mut self, step: PathStep, map: &Map) {
self.total_length += step.as_traversable().length(map);
self.steps.push_back(step); self.steps.push_back(step);
} }

View File

@ -4,6 +4,7 @@ use crate::{
PathRequest, PathStep, Position, PathRequest, PathStep, Position,
}; };
use fast_paths::{FastGraph, InputGraph, PathCalculator}; use fast_paths::{FastGraph, InputGraph, PathCalculator};
use geom::Distance;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::cell::RefCell; use std::cell::RefCell;
use thread_local::ThreadLocal; use thread_local::ThreadLocal;
@ -88,6 +89,7 @@ impl SidewalkPathfinder {
pub fn pathfind(&self, req: &PathRequest, map: &Map) -> Option<Path> { pub fn pathfind(&self, req: &PathRequest, map: &Map) -> Option<Path> {
// Special-case one-step paths. // Special-case one-step paths.
if req.start.lane() == req.end.lane() { if req.start.lane() == req.end.lane() {
let len = map.get_l(req.start.lane()).length();
// Weird case, but it can happen for walking from a building path to a bus stop that're // Weird case, but it can happen for walking from a building path to a bus stop that're
// actually at the same spot. // actually at the same spot.
if req.start.dist_along() == req.end.dist_along() { if req.start.dist_along() == req.end.dist_along() {
@ -95,18 +97,21 @@ impl SidewalkPathfinder {
map, map,
vec![PathStep::Lane(req.start.lane())], vec![PathStep::Lane(req.start.lane())],
req.start.dist_along(), req.start.dist_along(),
len,
)); ));
} else if req.start.dist_along() < req.end.dist_along() { } else if req.start.dist_along() < req.end.dist_along() {
return Some(Path::new( return Some(Path::new(
map, map,
vec![PathStep::Lane(req.start.lane())], vec![PathStep::Lane(req.start.lane())],
req.end.dist_along(), req.end.dist_along(),
len,
)); ));
} else { } else {
return Some(Path::new( return Some(Path::new(
map, map,
vec![PathStep::ContraflowLane(req.start.lane())], vec![PathStep::ContraflowLane(req.start.lane())],
req.end.dist_along(), req.end.dist_along(),
len,
)); ));
} }
} }
@ -169,7 +174,12 @@ impl SidewalkPathfinder {
unreachable!(); unreachable!();
} }
Some(Path::new(map, steps, req.end.dist_along())) Some(Path::new(
map,
steps,
req.end.dist_along(),
Distance::centimeters(raw_path.get_weight()),
))
} }
// Attempt the pathfinding and see if we should ride a bus. // Attempt the pathfinding and see if we should ride a bus.

View File

@ -776,10 +776,16 @@ impl DrivingSimState {
pub fn tooltip_lines(&self, id: CarID, now: Duration) -> Option<Vec<String>> { pub fn tooltip_lines(&self, id: CarID, now: Duration) -> Option<Vec<String>> {
let car = self.cars.get(&id)?; let car = self.cars.get(&id)?;
let path = car.router.get_path();
Some(vec![ Some(vec![
format!("{} on {}", id, car.router.head()), format!("{} on {}", id, car.router.head()),
format!("Owned by {:?}", car.vehicle.owner), format!("Owned by {:?}", car.vehicle.owner),
format!("{} lanes left", car.router.get_path().num_lanes()), format!("{} lanes left", path.num_lanes()),
format!(
"Crossed {} / {} of path",
path.crossed_so_far(),
path.total_length()
),
format!( format!(
"Blocked for {}", "Blocked for {}",
car.blocked_since.map(|t| now - t).unwrap_or(Duration::ZERO) car.blocked_since.map(|t| now - t).unwrap_or(Duration::ZERO)

View File

@ -243,6 +243,11 @@ impl WalkingSimState {
vec![ vec![
format!("{} on {:?}", p.id, p.path.current_step()), format!("{} on {:?}", p.id, p.path.current_step()),
format!("{} lanes left in path", p.path.num_lanes()), format!("{} lanes left in path", p.path.num_lanes()),
format!(
"Crossed {} / {} of path",
p.path.crossed_so_far(),
p.path.total_length()
),
format!( format!(
"Blocked for {}", "Blocked for {}",
p.blocked_since.map(|t| now - t).unwrap_or(Duration::ZERO) p.blocked_since.map(|t| now - t).unwrap_or(Duration::ZERO)
@ -455,7 +460,7 @@ impl Pedestrian {
} }
peds_per_traversable.remove(self.path.current_step().as_traversable(), self.id); peds_per_traversable.remove(self.path.current_step().as_traversable(), self.id);
self.path.shift(); self.path.shift(map);
let start_dist = match self.path.current_step() { let start_dist = match self.path.current_step() {
PathStep::Lane(_) => Distance::ZERO, PathStep::Lane(_) => Distance::ZERO,
PathStep::ContraflowLane(l) => map.get_l(l).length(), PathStep::ContraflowLane(l) => map.get_l(l).length(),

View File

@ -118,7 +118,7 @@ impl Router {
parking: &ParkingSimState, parking: &ParkingSimState,
map: &Map, map: &Map,
) -> Traversable { ) -> Traversable {
let prev = self.path.shift().as_traversable(); let prev = self.path.shift(map).as_traversable();
if self.last_step() { if self.last_step() {
// Do this to trigger the side-effect of looking for parking. // Do this to trigger the side-effect of looking for parking.
self.maybe_handle_end(Distance::ZERO, vehicle, parking, map); self.maybe_handle_end(Distance::ZERO, vehicle, parking, map);
@ -228,7 +228,7 @@ impl Router {
all_choices[0] all_choices[0]
}; };
turns_attempted_while_roaming.insert(turn.id); turns_attempted_while_roaming.insert(turn.id);
self.path.add(PathStep::Turn(turn.id)); self.path.add(PathStep::Turn(turn.id), map);
self.path.add(PathStep::Lane(turn.id.dst)); self.path.add(PathStep::Lane(turn.id.dst), map);
} }
} }