make peds use front paths for parking lots too

This commit is contained in:
Dustin Carlino 2020-06-06 14:04:09 -07:00
parent a643f039ad
commit 65b500509e
5 changed files with 125 additions and 38 deletions

View File

@ -374,9 +374,9 @@ data/system/maps/montlake.bin,d58d14b9fbae8cfdf6c547fe140ff3fe,https://www.dropb
data/system/maps/mt_baker.bin,09dd0d4220e1ebbed4fc730ed2081933,https://www.dropbox.com/s/cetje663p04cbgp/mt_baker.bin.zip?dl=0
data/system/maps/udistrict.bin,4de690facca9297f148396f3f09c3a6a,https://www.dropbox.com/s/zqt2je8fadssz5j/udistrict.bin.zip?dl=0
data/system/maps/west_seattle.bin,867b16afdf12c484d680bfbc73cbd919,https://www.dropbox.com/s/5pp1ik9l40yj3wh/west_seattle.bin.zip?dl=0
data/system/prebaked_results/lakeslice/weekday.bin,cbd73a7a14a8406a99cafac4e2eedf5b,https://www.dropbox.com/s/1c1sohvy50263wg/weekday.bin.zip?dl=0
data/system/prebaked_results/lakeslice/weekday.bin,5402db739bd44a5f763f64fa14887733,https://www.dropbox.com/s/1c1sohvy50263wg/weekday.bin.zip?dl=0
data/system/prebaked_results/montlake/car vs bike contention.bin,ac46a6b81a65431209075a7de5ed9227,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
data/system/prebaked_results/montlake/weekday.bin,cd953900d32389809fb2dda206789528,https://www.dropbox.com/s/1aq7n9ow8tfqb5d/weekday.bin.zip?dl=0
data/system/prebaked_results/montlake/weekday.bin,0a06da39f1f76199744d27b137bc1bc0,https://www.dropbox.com/s/1aq7n9ow8tfqb5d/weekday.bin.zip?dl=0
data/system/scenarios/ballard/weekday.bin,60d3eb1cdb8672e2d29cf3acf23ccabe,https://www.dropbox.com/s/67hys1v7m7oe979/weekday.bin.zip?dl=0
data/system/scenarios/downtown/weekday.bin,8821147124da650f975483ed1e5bbb69,https://www.dropbox.com/s/pstvu4p7xj3gaoi/weekday.bin.zip?dl=0
data/system/scenarios/huge_seattle/weekday.bin,31bfc23f39bb54bef939119f6cfbd2e2,https://www.dropbox.com/s/u3pmsshwnf13g83/weekday.bin.zip?dl=0

View File

@ -212,12 +212,17 @@ impl DrawPedCrowd {
map.right_shift(pl_slice, SIDEWALK_THICKNESS / 4.0).unwrap()
}
}
PedCrowdLocation::FrontPath(b) => map
PedCrowdLocation::BldgFrontPath(b) => map
.get_b(b)
.front_path
.line
.to_polyline()
.exact_slice(input.low, input.high),
PedCrowdLocation::LotFrontPath(pl) => map
.get_pl(pl)
.sidewalk_line
.to_polyline()
.exact_slice(input.low, input.high),
};
let blob = pl_shifted.make_polygons(SIDEWALK_THICKNESS / 2.0);
let mut batch = GeomBatch::new();
@ -235,7 +240,8 @@ impl DrawPedCrowd {
blob,
zorder: match input.location {
PedCrowdLocation::Sidewalk(on, _) => on.get_zorder(map),
PedCrowdLocation::FrontPath(_) => 0,
PedCrowdLocation::BldgFrontPath(_) => 0,
PedCrowdLocation::LotFrontPath(_) => 0,
},
draw_default: prerender.upload(batch),
}

View File

@ -6,6 +6,12 @@ use std::fmt;
// TODO For now, ignore the mapped roads linking things and just use the same driveway approach
// that buildings use.
// TODO Nits:
// - handle relations with individual slots, like https://www.openstreetmap.org/relation/2580595?
// - Northlake: onstreet or a lot?
// - E1 at UW filtered out
// - aisle clipping isnt perfect (23rd and rainier, pepsi)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ParkingLotID(pub usize);

View File

@ -6,7 +6,9 @@ use crate::{
};
use abstutil::{deserialize_multimap, serialize_multimap, MultiMap};
use geom::{Distance, Duration, Line, PolyLine, Speed, Time};
use map_model::{BuildingID, BusRouteID, Map, Path, PathStep, Traversable, SIDEWALK_THICKNESS};
use map_model::{
BuildingID, BusRouteID, Map, ParkingLotID, Path, PathStep, Traversable, SIDEWALK_THICKNESS,
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
@ -73,6 +75,10 @@ impl WalkingSimState {
TimeInterval::new(now, now + map.get_b(b).front_path.line.length() / ped.speed),
)
}
SidewalkPOI::ParkingSpot(ParkingSpot::Lot(pl, _)) => PedState::LeavingParkingLot(
pl,
TimeInterval::new(now, now + map.get_pl(pl).sidewalk_line.length() / ped.speed),
),
SidewalkPOI::BikeRack(driving_pos) => PedState::FinishingBiking(
params.start.clone(),
Line::new(driving_pos.pt(map), params.start.sidewalk_pos.pt(map)),
@ -122,6 +128,17 @@ impl WalkingSimState {
if ped.path.is_last_step() {
match ped.goal.connection {
SidewalkPOI::ParkingSpot(spot) => {
if let ParkingSpot::Lot(pl, _) = spot {
ped.state = PedState::EnteringParkingLot(
pl,
TimeInterval::new(
now,
now + map.get_pl(pl).sidewalk_line.length() / ped.speed,
),
);
scheduler
.push(ped.state.get_end_time(), Command::UpdatePed(ped.id));
} else {
self.peds_per_traversable
.remove(ped.path.current_step().as_traversable(), ped.id);
trips.ped_reached_parking_spot(
@ -135,6 +152,7 @@ impl WalkingSimState {
);
self.peds.remove(&id);
}
}
SidewalkPOI::Building(b) => {
ped.state = PedState::EnteringBuilding(
b,
@ -247,6 +265,27 @@ impl WalkingSimState {
);
self.peds.remove(&id);
}
PedState::LeavingParkingLot(pl, _) => {
ped.state = ped.crossing_state(map.get_pl(pl).sidewalk_pos.dist_along(), now, map);
scheduler.push(ped.state.get_end_time(), Command::UpdatePed(ped.id));
}
PedState::EnteringParkingLot(_, _) => {
self.peds_per_traversable
.remove(ped.path.current_step().as_traversable(), ped.id);
trips.ped_reached_parking_spot(
now,
ped.id,
match ped.goal.connection {
SidewalkPOI::ParkingSpot(spot) => spot,
_ => unreachable!(),
},
ped.total_blocked_time,
map,
parking,
scheduler,
);
self.peds.remove(&id);
}
PedState::StartingToBike(ref spot, _, _) => {
self.peds_per_traversable
.remove(ped.path.current_step().as_traversable(), ped.id);
@ -364,10 +403,11 @@ impl WalkingSimState {
on: Traversable,
map: &Map,
) -> (Vec<DrawPedestrianInput>, Vec<DrawPedCrowdInput>) {
// Classify into direction-based groups or by building front path.
// Classify into direction-based groups or by building/parking lot front path.
let mut forwards: Vec<(PedestrianID, Distance)> = Vec::new();
let mut backwards: Vec<(PedestrianID, Distance)> = Vec::new();
let mut front_path: MultiMap<BuildingID, (PedestrianID, Distance)> = MultiMap::new();
let mut bldg_front_path: MultiMap<BuildingID, (PedestrianID, Distance)> = MultiMap::new();
let mut lot_front_path: MultiMap<ParkingLotID, (PedestrianID, Distance)> = MultiMap::new();
for id in self.peds_per_traversable.get(on) {
let ped = &self.peds[id];
@ -390,11 +430,19 @@ impl WalkingSimState {
}
PedState::LeavingBuilding(b, ref int) => {
let len = map.get_b(b).front_path.line.length();
front_path.insert(b, (*id, int.percent(now) * len));
bldg_front_path.insert(b, (*id, int.percent(now) * len));
}
PedState::EnteringBuilding(b, ref int) => {
let len = map.get_b(b).front_path.line.length();
front_path.insert(b, (*id, (1.0 - int.percent(now)) * len));
bldg_front_path.insert(b, (*id, (1.0 - int.percent(now)) * len));
}
PedState::LeavingParkingLot(pl, ref int) => {
let len = map.get_pl(pl).sidewalk_line.length();
lot_front_path.insert(pl, (*id, int.percent(now) * len));
}
PedState::EnteringParkingLot(pl, ref int) => {
let len = map.get_pl(pl).sidewalk_line.length();
lot_front_path.insert(pl, (*id, (1.0 - int.percent(now)) * len));
}
PedState::StartingToBike(_, _, _)
| PedState::FinishingBiking(_, _, _)
@ -422,12 +470,19 @@ impl WalkingSimState {
),
]
.into_iter()
.chain(front_path.consume().into_iter().map(|(b, set)| {
.chain(bldg_front_path.consume().into_iter().map(|(b, set)| {
(
set.into_iter().collect::<Vec<_>>(),
PedCrowdLocation::FrontPath(b),
PedCrowdLocation::BldgFrontPath(b),
map.get_b(b).front_path.line.length(),
)
}))
.chain(lot_front_path.consume().into_iter().map(|(pl, set)| {
(
set.into_iter().collect::<Vec<_>>(),
PedCrowdLocation::LotFrontPath(pl),
map.get_pl(pl).sidewalk_line.length(),
)
})) {
if group.is_empty() {
continue;
@ -493,8 +548,12 @@ impl Pedestrian {
match self.state {
PedState::Crossing(ref dist_int, ref time_int) => dist_int.lerp(time_int.percent(now)),
PedState::WaitingToTurn(dist, _) => dist,
PedState::LeavingBuilding(b, _) => map.get_b(b).front_path.sidewalk.dist_along(),
PedState::EnteringBuilding(b, _) => map.get_b(b).front_path.sidewalk.dist_along(),
PedState::LeavingBuilding(b, _) | PedState::EnteringBuilding(b, _) => {
map.get_b(b).front_path.sidewalk.dist_along()
}
PedState::LeavingParkingLot(pl, _) | PedState::EnteringParkingLot(pl, _) => {
map.get_pl(pl).sidewalk_pos.dist_along()
}
PedState::StartingToBike(ref spot, _, _) => spot.sidewalk_pos.dist_along(),
PedState::FinishingBiking(ref spot, _, _) => spot.sidewalk_pos.dist_along(),
PedState::WaitingForBus(_, _) => self.goal.sidewalk_pos.dist_along(),
@ -540,22 +599,33 @@ impl Pedestrian {
)
}
PedState::LeavingBuilding(b, ref time_int) => {
let front_path = &map.get_b(b).front_path;
let line = &map.get_b(b).front_path.line;
(
front_path
.line
.dist_along(time_int.percent(now) * front_path.line.length()),
front_path.line.angle(),
line.dist_along(time_int.percent(now) * line.length()),
line.angle(),
)
}
PedState::EnteringBuilding(b, ref time_int) => {
let front_path = &map.get_b(b).front_path;
let line = &map.get_b(b).front_path.line;
(
front_path
.line
.reverse()
.dist_along(time_int.percent(now) * front_path.line.length()),
front_path.line.angle().opposite(),
line.reverse()
.dist_along(time_int.percent(now) * line.length()),
line.angle().opposite(),
)
}
PedState::LeavingParkingLot(pl, ref time_int) => {
let line = &map.get_pl(pl).sidewalk_line;
(
line.dist_along(time_int.percent(now) * line.length()),
line.angle(),
)
}
PedState::EnteringParkingLot(pl, ref time_int) => {
let line = &map.get_pl(pl).sidewalk_line;
(
line.reverse()
.dist_along(time_int.percent(now) * line.length()),
line.angle().opposite(),
)
}
PedState::StartingToBike(_, ref line, ref time_int) => {
@ -639,6 +709,8 @@ enum PedState {
WaitingToTurn(Distance, Time),
LeavingBuilding(BuildingID, TimeInterval),
EnteringBuilding(BuildingID, TimeInterval),
LeavingParkingLot(ParkingLotID, TimeInterval),
EnteringParkingLot(ParkingLotID, TimeInterval),
StartingToBike(SidewalkSpot, Line, TimeInterval),
FinishingBiking(SidewalkSpot, Line, TimeInterval),
WaitingForBus(BusRouteID, Time),
@ -651,6 +723,8 @@ impl PedState {
PedState::WaitingToTurn(_, _) => unreachable!(),
PedState::LeavingBuilding(_, ref time_int) => time_int.end,
PedState::EnteringBuilding(_, ref time_int) => time_int.end,
PedState::LeavingParkingLot(_, ref time_int) => time_int.end,
PedState::EnteringParkingLot(_, ref time_int) => time_int.end,
PedState::StartingToBike(_, _, ref time_int) => time_int.end,
PedState::FinishingBiking(_, _, ref time_int) => time_int.end,
PedState::WaitingForBus(_, _) => unreachable!(),

View File

@ -1,6 +1,6 @@
use crate::{CarID, PedestrianID, PersonID, VehicleType};
use geom::{Angle, Distance, PolyLine, Pt2D, Time};
use map_model::{BuildingID, Map, Traversable, TurnID};
use map_model::{BuildingID, Map, ParkingLotID, Traversable, TurnID};
// Intermediate structures so that sim and game crates don't have a cyclic dependency.
#[derive(Clone)]
@ -25,7 +25,8 @@ pub struct DrawPedCrowdInput {
pub enum PedCrowdLocation {
// bool is contraflow
Sidewalk(Traversable, bool),
FrontPath(BuildingID),
BldgFrontPath(BuildingID),
LotFrontPath(ParkingLotID),
}
#[derive(Clone)]