mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Refactor: Store the input PathRequest inside the resulting Path. This
saves lots of callers from cloning the request and separately plumbing around the requested start/end distance. Also a step towards exposing more granular distance crossed in a path for #392. Still a few more places to simplify, but will do in a separate, smaller change.
This commit is contained in:
parent
e8f7e7444c
commit
fccc98205c
@ -637,7 +637,7 @@
|
||||
"size_bytes": 59144729
|
||||
},
|
||||
"data/system/seattle/prebaked_results/lakeslice/weekday.bin": {
|
||||
"checksum": "4c4c942ed0f791eabf4389985098fc54",
|
||||
"checksum": "dab9c56147f1e3e66ca60d7dcd946ee0",
|
||||
"size_bytes": 66439671
|
||||
},
|
||||
"data/system/seattle/prebaked_results/montlake/car vs bike contention.bin": {
|
||||
@ -645,7 +645,7 @@
|
||||
"size_bytes": 5277
|
||||
},
|
||||
"data/system/seattle/prebaked_results/montlake/weekday.bin": {
|
||||
"checksum": "ea42c12f997bddc31d147038a0105418",
|
||||
"checksum": "30027ab5ae12145c50102824f4bfaed4",
|
||||
"size_bytes": 8533785
|
||||
},
|
||||
"data/system/seattle/scenarios/ballard/weekday.bin": {
|
||||
|
@ -74,7 +74,7 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingID
|
||||
.primary
|
||||
.sim
|
||||
.walking_path_to_nearest_parking_spot(&app.primary.map, id)
|
||||
.and_then(|(path, start_dist)| path.trace(&app.primary.map, start_dist, None))
|
||||
.and_then(|path| path.trace(&app.primary.map, path.get_req().start.dist_along(), None))
|
||||
{
|
||||
let color = app.cs.parking_trip;
|
||||
// TODO But this color doesn't show up well against the info panel...
|
||||
|
@ -322,7 +322,7 @@ impl State<App> for AgentSpawner {
|
||||
{
|
||||
self.goal = Some((
|
||||
to,
|
||||
path.trace(&app.primary.map, Distance::ZERO, None)
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along(), None)
|
||||
.map(|pl| pl.make_polygons(NORMAL_LANE_THICKNESS)),
|
||||
));
|
||||
} else {
|
||||
@ -387,7 +387,7 @@ impl State<App> for AgentSpawner {
|
||||
{
|
||||
self.goal = Some((
|
||||
hovering,
|
||||
path.trace(&app.primary.map, Distance::ZERO, None)
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along(), None)
|
||||
.map(|pl| pl.make_polygons(NORMAL_LANE_THICKNESS)),
|
||||
));
|
||||
} else {
|
||||
|
@ -102,7 +102,7 @@ impl Zone {
|
||||
}
|
||||
steps.push(PathStep::Lane(req.end.lane()));
|
||||
assert_eq!(steps[0], PathStep::Lane(req.start.lane()));
|
||||
Some(Path::new(map, steps, req.end.dist_along(), Vec::new()))
|
||||
Some(Path::new(map, steps, req, Vec::new()))
|
||||
}
|
||||
|
||||
// TODO Not happy this works so differently
|
||||
|
@ -68,7 +68,7 @@ fn calc_path(graph: DiGraphMap<LaneID, TurnID>, req: &PathRequest, map: &Map) ->
|
||||
}
|
||||
steps.push(PathStep::Lane(req.end.lane()));
|
||||
assert_eq!(steps[0], PathStep::Lane(req.start.lane()));
|
||||
Some(Path::new(map, steps, req.end.dist_along(), Vec::new()))
|
||||
Some(Path::new(map, steps, req.clone(), Vec::new()))
|
||||
}
|
||||
|
||||
// TODO Not happy this works so differently
|
||||
|
@ -116,7 +116,7 @@ impl VehiclePathfinder {
|
||||
}
|
||||
steps.push(PathStep::Lane(req.end.lane()));
|
||||
Some((
|
||||
Path::new(map, steps, req.end.dist_along(), uber_turns),
|
||||
Path::new(map, steps, req.clone(), uber_turns),
|
||||
raw_path.get_weight(),
|
||||
))
|
||||
}
|
||||
|
@ -102,7 +102,9 @@ impl PathStep {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct Path {
|
||||
steps: VecDeque<PathStep>,
|
||||
end_dist: Distance,
|
||||
// The original request used to produce this path. Calling shift(), add(), modify_step(), etc
|
||||
// will NOT affect this.
|
||||
orig_req: PathRequest,
|
||||
|
||||
// Also track progress along the original path.
|
||||
total_length: Distance,
|
||||
@ -119,7 +121,7 @@ impl Path {
|
||||
pub(crate) fn new(
|
||||
map: &Map,
|
||||
steps: Vec<PathStep>,
|
||||
end_dist: Distance,
|
||||
orig_req: PathRequest,
|
||||
uber_turns: Vec<UberTurn>,
|
||||
) -> Path {
|
||||
// Haven't seen problems here in a very long time. Noticeably saves some time to skip.
|
||||
@ -136,7 +138,7 @@ impl Path {
|
||||
}
|
||||
Path {
|
||||
steps: VecDeque::from(steps),
|
||||
end_dist,
|
||||
orig_req,
|
||||
total_length,
|
||||
crossed_so_far: Distance::ZERO,
|
||||
uber_turns: uber_turns.into_iter().collect(),
|
||||
@ -144,25 +146,15 @@ impl Path {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn one_step(l: LaneID, map: &Map) -> Path {
|
||||
Path::new(
|
||||
map,
|
||||
vec![PathStep::Lane(l)],
|
||||
map.get_l(l).length(),
|
||||
Vec::new(),
|
||||
)
|
||||
pub fn one_step(req: PathRequest, map: &Map) -> Path {
|
||||
assert_eq!(req.start.lane(), req.end.lane());
|
||||
Path::new(map, vec![PathStep::Lane(req.start.lane())], req, Vec::new())
|
||||
}
|
||||
|
||||
/// Only used for weird serialization magic.
|
||||
pub fn dummy() -> Path {
|
||||
Path {
|
||||
steps: VecDeque::new(),
|
||||
end_dist: Distance::ZERO,
|
||||
total_length: Distance::ZERO,
|
||||
crossed_so_far: Distance::ZERO,
|
||||
uber_turns: VecDeque::new(),
|
||||
currently_inside_ut: None,
|
||||
}
|
||||
/// The original PathRequest used to produce this path. If the path has been modified since
|
||||
/// creation, the start and end of the request won't match up with the current path steps.
|
||||
pub fn get_req(&self) -> &PathRequest {
|
||||
&self.orig_req
|
||||
}
|
||||
|
||||
pub fn crossed_so_far(&self) -> Distance {
|
||||
@ -293,7 +285,8 @@ impl Path {
|
||||
self.steps[self.steps.len() - 1]
|
||||
}
|
||||
|
||||
/// dist_ahead is unlimited when None.
|
||||
/// dist_ahead is unlimited when None. Note this starts at the beginning (or end, for some
|
||||
/// walking paths) of the first lane, not accounting for the original request's start distance.
|
||||
pub fn trace(
|
||||
&self,
|
||||
map: &Map,
|
||||
@ -302,12 +295,13 @@ impl Path {
|
||||
) -> Option<PolyLine> {
|
||||
let mut pts_so_far: Option<PolyLine> = None;
|
||||
let mut dist_remaining = dist_ahead;
|
||||
let orig_end_dist = self.orig_req.end.dist_along();
|
||||
|
||||
if self.steps.len() == 1 {
|
||||
let dist = if start_dist < self.end_dist {
|
||||
self.end_dist - start_dist
|
||||
let dist = if start_dist < orig_end_dist {
|
||||
orig_end_dist - start_dist
|
||||
} else {
|
||||
start_dist - self.end_dist
|
||||
start_dist - orig_end_dist
|
||||
};
|
||||
if let Some(d) = dist_remaining {
|
||||
if dist < d {
|
||||
@ -346,9 +340,9 @@ impl Path {
|
||||
if i == self.steps.len() - 1 {
|
||||
let end_dist = match self.steps[i] {
|
||||
PathStep::ContraflowLane(l) => {
|
||||
map.get_l(l).lane_center_pts.reversed().length() - self.end_dist
|
||||
map.get_l(l).lane_center_pts.reversed().length() - orig_end_dist
|
||||
}
|
||||
_ => self.end_dist,
|
||||
_ => orig_end_dist,
|
||||
};
|
||||
if let Some(d) = dist_remaining {
|
||||
if end_dist < d {
|
||||
|
@ -45,7 +45,7 @@ impl Pathfinder {
|
||||
if req.constraints == PathConstraints::Pedestrian {
|
||||
let steps =
|
||||
walking_path_to_steps(z1.pathfind_walking(req.clone(), map)?, map);
|
||||
return Some(Path::new(map, steps, req.end.dist_along(), Vec::new()));
|
||||
return Some(Path::new(map, steps, req, Vec::new()));
|
||||
}
|
||||
return z1.pathfind(req, map);
|
||||
}
|
||||
@ -102,7 +102,7 @@ impl Pathfinder {
|
||||
return Some(one_step_walking_path(&req, map));
|
||||
}
|
||||
let steps = walking_path_to_steps(self.simple_walking_path(&req, map)?, map);
|
||||
return Some(Path::new(map, steps, req.end.dist_along(), Vec::new()));
|
||||
return Some(Path::new(map, steps, req, Vec::new()));
|
||||
}
|
||||
self.simple_pathfind(&req, map)
|
||||
}
|
||||
@ -221,7 +221,7 @@ impl Pathfinder {
|
||||
};
|
||||
interior_path.extend(main_path);
|
||||
let steps = walking_path_to_steps(interior_path, map);
|
||||
return Some(Path::new(map, steps, req.end.dist_along(), Vec::new()));
|
||||
return Some(Path::new(map, steps, req, Vec::new()));
|
||||
}
|
||||
|
||||
let mut interior_path = zone.pathfind(interior_req, map)?;
|
||||
@ -279,7 +279,7 @@ impl Pathfinder {
|
||||
end: req.end,
|
||||
constraints: req.constraints,
|
||||
};
|
||||
let orig_end_dist = req.end.dist_along();
|
||||
let orig_req = req.clone();
|
||||
req.end = if map.get_l(src).dst_i == i.id {
|
||||
Position::end(src, map)
|
||||
} else {
|
||||
@ -301,13 +301,13 @@ impl Pathfinder {
|
||||
|
||||
main_path.extend(interior_path);
|
||||
let steps = walking_path_to_steps(main_path, map);
|
||||
return Some(Path::new(map, steps, orig_end_dist, Vec::new()));
|
||||
return Some(Path::new(map, steps, orig_req, Vec::new()));
|
||||
}
|
||||
|
||||
let interior_path = zone.pathfind(interior_req, map)?;
|
||||
let mut main_path = self.simple_pathfind(&req, map)?;
|
||||
main_path.append(interior_path, map);
|
||||
main_path.end_dist = orig_end_dist;
|
||||
main_path.orig_req = orig_req;
|
||||
Some(main_path)
|
||||
}
|
||||
}
|
||||
|
@ -462,21 +462,21 @@ pub fn one_step_walking_path(req: &PathRequest, map: &Map) -> Path {
|
||||
Path::new(
|
||||
map,
|
||||
vec![PathStep::Lane(req.start.lane())],
|
||||
req.start.dist_along(),
|
||||
req.clone(),
|
||||
Vec::new(),
|
||||
)
|
||||
} else if req.start.dist_along() < req.end.dist_along() {
|
||||
Path::new(
|
||||
map,
|
||||
vec![PathStep::Lane(req.start.lane())],
|
||||
req.end.dist_along(),
|
||||
req.clone(),
|
||||
Vec::new(),
|
||||
)
|
||||
} else {
|
||||
Path::new(
|
||||
map,
|
||||
vec![PathStep::ContraflowLane(req.start.lane())],
|
||||
req.end.dist_along(),
|
||||
req.clone(),
|
||||
Vec::new(),
|
||||
)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use geom::{Duration, Time};
|
||||
use map_model::{LaneID, Map, Path, PathConstraints, PathRequest, PathStep, TurnID};
|
||||
use map_model::{LaneID, Map, Path, PathConstraints, PathStep, TurnID};
|
||||
|
||||
use crate::mechanics::IntersectionSimState;
|
||||
use crate::{CarID, SimOptions, VehicleType};
|
||||
@ -79,7 +79,6 @@ impl CapSimState {
|
||||
/// dynamic limits.
|
||||
pub fn maybe_cap_path(
|
||||
&mut self,
|
||||
req: &PathRequest,
|
||||
path: Path,
|
||||
now: Time,
|
||||
car: CarID,
|
||||
@ -112,14 +111,14 @@ impl CapSimState {
|
||||
avoid_lanes.insert(*l);
|
||||
}
|
||||
}
|
||||
match map.pathfind_avoiding_lanes(req.clone(), avoid_lanes) {
|
||||
match map.pathfind_avoiding_lanes(path.get_req().clone(), avoid_lanes) {
|
||||
Some(path) => CapResult::Reroute(path),
|
||||
None => {
|
||||
if let Some(delay) = self.delay_trips_instead_of_cancelling {
|
||||
CapResult::Delay(delay)
|
||||
} else {
|
||||
CapResult::Cancel {
|
||||
reason: format!("no path avoiding caps: {}", req),
|
||||
reason: format!("no path avoiding caps: {}", path.get_req()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -581,7 +581,6 @@ pub(crate) struct CreatePedestrian {
|
||||
pub start: SidewalkSpot,
|
||||
pub speed: Speed,
|
||||
pub goal: SidewalkSpot,
|
||||
pub req: PathRequest,
|
||||
pub path: Path,
|
||||
pub trip: TripID,
|
||||
pub person: PersonID,
|
||||
|
@ -70,10 +70,17 @@ impl Router {
|
||||
owner,
|
||||
}
|
||||
}
|
||||
pub fn vanish_bus(owner: CarID, l: LaneID, map: &Map) -> Router {
|
||||
let lane = map.get_l(l);
|
||||
pub fn vanish_bus(owner: CarID, start: Position, map: &Map) -> Router {
|
||||
let lane = map.get_l(start.lane());
|
||||
Router {
|
||||
path: Path::one_step(l, map),
|
||||
path: Path::one_step(
|
||||
PathRequest {
|
||||
start,
|
||||
end: Position::end(lane.id, map),
|
||||
constraints: PathConstraints::Bus,
|
||||
},
|
||||
map,
|
||||
),
|
||||
goal: Goal::EndAtBorder {
|
||||
end_dist: lane.length(),
|
||||
i: lane.dst_i,
|
||||
|
@ -273,12 +273,7 @@ impl Sim {
|
||||
self.parking.bldg_to_parked_cars(b)
|
||||
}
|
||||
|
||||
/// Also returns the start distance of the building. TODO Do that in the Path properly.
|
||||
pub fn walking_path_to_nearest_parking_spot(
|
||||
&self,
|
||||
map: &Map,
|
||||
b: BuildingID,
|
||||
) -> Option<(Path, Distance)> {
|
||||
pub fn walking_path_to_nearest_parking_spot(&self, map: &Map, b: BuildingID) -> Option<Path> {
|
||||
let vehicle = Vehicle {
|
||||
id: CarID(0, VehicleType::Car),
|
||||
owner: None,
|
||||
@ -306,14 +301,12 @@ impl Sim {
|
||||
|
||||
let start = SidewalkSpot::building(b, map).sidewalk_pos;
|
||||
let end = SidewalkSpot::parking_spot(spot, map, &self.parking).sidewalk_pos;
|
||||
let path = map
|
||||
.pathfind(PathRequest {
|
||||
start,
|
||||
end,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
})
|
||||
.ok()?;
|
||||
Some((path, start.dist_along()))
|
||||
map.pathfind(PathRequest {
|
||||
start,
|
||||
end,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
|
||||
pub(crate) fn new_person(
|
||||
@ -572,7 +565,7 @@ impl Sim {
|
||||
events.push(Event::TripPhaseStarting(
|
||||
create_ped.trip,
|
||||
create_ped.person,
|
||||
Some(create_ped.req.clone()),
|
||||
Some(create_ped.path.get_req().clone()),
|
||||
TripPhaseType::Walking,
|
||||
));
|
||||
self.analytics.record_demand(&create_ped.path, map);
|
||||
|
@ -287,7 +287,6 @@ impl TransitSimState {
|
||||
bus.state = BusState::DrivingOffMap;
|
||||
Router::follow_bus_route(id, path, req.end.dist_along())
|
||||
} else {
|
||||
let on = stop.driving_pos.lane();
|
||||
route.active_vehicles.remove(&id);
|
||||
for (person, stop2) in &bus.passengers {
|
||||
panic!(
|
||||
@ -297,7 +296,7 @@ impl TransitSimState {
|
||||
);
|
||||
}
|
||||
bus.state = BusState::Done;
|
||||
Router::vanish_bus(id, on, map)
|
||||
Router::vanish_bus(id, stop.driving_pos, map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ impl TripManager {
|
||||
end: walking_goal.sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
};
|
||||
match ctx.map.pathfind(req.clone()) {
|
||||
match ctx.map.pathfind(req) {
|
||||
Ok(path) => {
|
||||
ctx.scheduler.push(
|
||||
now,
|
||||
@ -235,7 +235,6 @@ impl TripManager {
|
||||
start,
|
||||
goal: walking_goal,
|
||||
path,
|
||||
req,
|
||||
trip,
|
||||
person: person.id,
|
||||
}),
|
||||
@ -292,7 +291,7 @@ impl TripManager {
|
||||
end: goal.sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
};
|
||||
match ctx.map.pathfind(req.clone()) {
|
||||
match ctx.map.pathfind(req) {
|
||||
Ok(path) => {
|
||||
ctx.scheduler.push(
|
||||
now,
|
||||
@ -302,7 +301,6 @@ impl TripManager {
|
||||
start,
|
||||
goal,
|
||||
path,
|
||||
req,
|
||||
trip,
|
||||
person: person.id,
|
||||
}),
|
||||
@ -323,7 +321,7 @@ impl TripManager {
|
||||
end: walk_to.sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
};
|
||||
match ctx.map.pathfind(req.clone()) {
|
||||
match ctx.map.pathfind(req) {
|
||||
Ok(path) => {
|
||||
// Where we start biking may have slightly changed due to live map
|
||||
// edits!
|
||||
@ -345,7 +343,6 @@ impl TripManager {
|
||||
start: SidewalkSpot::building(start, ctx.map),
|
||||
goal: walk_to,
|
||||
path,
|
||||
req,
|
||||
trip,
|
||||
person: person.id,
|
||||
}),
|
||||
@ -402,7 +399,7 @@ impl TripManager {
|
||||
end: walk_to.sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
};
|
||||
match ctx.map.pathfind(req.clone()) {
|
||||
match ctx.map.pathfind(req) {
|
||||
Ok(path) => {
|
||||
ctx.scheduler.push(
|
||||
now,
|
||||
@ -412,7 +409,6 @@ impl TripManager {
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
req,
|
||||
trip,
|
||||
person: person.id,
|
||||
}),
|
||||
@ -946,7 +942,7 @@ impl TripManager {
|
||||
end: walk_to.sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
};
|
||||
match ctx.map.pathfind(req.clone()) {
|
||||
match ctx.map.pathfind(req) {
|
||||
Ok(path) => {
|
||||
let person = &self.people[trip.person.0];
|
||||
ctx.scheduler.push(
|
||||
@ -957,7 +953,6 @@ impl TripManager {
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
req,
|
||||
trip: id,
|
||||
person: person.id,
|
||||
}),
|
||||
@ -979,10 +974,10 @@ impl TripManager {
|
||||
req: PathRequest,
|
||||
car: CarID,
|
||||
) -> Result<Path, String> {
|
||||
let path = ctx.map.pathfind(req.clone())?;
|
||||
let path = ctx.map.pathfind(req)?;
|
||||
match ctx
|
||||
.cap
|
||||
.maybe_cap_path(&req, path, now, car, ctx.intersections, ctx.map)
|
||||
.maybe_cap_path(path, now, car, ctx.intersections, ctx.map)
|
||||
{
|
||||
CapResult::OK(path) => Ok(path),
|
||||
CapResult::Reroute(path) => {
|
||||
|
Loading…
Reference in New Issue
Block a user