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/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/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/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/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/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/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 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() map.right_shift(pl_slice, SIDEWALK_THICKNESS / 4.0).unwrap()
} }
} }
PedCrowdLocation::FrontPath(b) => map PedCrowdLocation::BldgFrontPath(b) => map
.get_b(b) .get_b(b)
.front_path .front_path
.line .line
.to_polyline() .to_polyline()
.exact_slice(input.low, input.high), .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 blob = pl_shifted.make_polygons(SIDEWALK_THICKNESS / 2.0);
let mut batch = GeomBatch::new(); let mut batch = GeomBatch::new();
@ -235,7 +240,8 @@ impl DrawPedCrowd {
blob, blob,
zorder: match input.location { zorder: match input.location {
PedCrowdLocation::Sidewalk(on, _) => on.get_zorder(map), PedCrowdLocation::Sidewalk(on, _) => on.get_zorder(map),
PedCrowdLocation::FrontPath(_) => 0, PedCrowdLocation::BldgFrontPath(_) => 0,
PedCrowdLocation::LotFrontPath(_) => 0,
}, },
draw_default: prerender.upload(batch), 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 // TODO For now, ignore the mapped roads linking things and just use the same driveway approach
// that buildings use. // 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)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ParkingLotID(pub usize); pub struct ParkingLotID(pub usize);

View File

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

View File

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