From 8ab4b403fa878bf7f28eb136f9405a2dd0209780 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Tue, 26 Feb 2019 11:16:57 -0800 Subject: [PATCH] bike -> ped --- .../sim/new_des_model/mechanics/driving.rs | 10 ++++ .../sim/new_des_model/mechanics/walking.rs | 15 ++++++ .../src/plugins/sim/new_des_model/router.rs | 30 ++++++++++- editor/src/plugins/sim/new_des_model/trips.rs | 50 +++++++++++++++---- map_model/src/road.rs | 16 ++++++ 5 files changed, 111 insertions(+), 10 deletions(-) diff --git a/editor/src/plugins/sim/new_des_model/mechanics/driving.rs b/editor/src/plugins/sim/new_des_model/mechanics/driving.rs index 6a32463d90..78c6a0807e 100644 --- a/editor/src/plugins/sim/new_des_model/mechanics/driving.rs +++ b/editor/src/plugins/sim/new_des_model/mechanics/driving.rs @@ -245,6 +245,16 @@ impl DrivingSimState { Some(ActionAtEnd::GotoLaneEnd) => { car.state = car.crossing_state(dist, time, map); } + Some(ActionAtEnd::StopBiking(bike_rack)) => { + delete_indices.push((idx, dist)); + trips.bike_reached_end( + time, + car.vehicle.id, + bike_rack, + map, + scheduler, + ); + } None => {} } } diff --git a/editor/src/plugins/sim/new_des_model/mechanics/walking.rs b/editor/src/plugins/sim/new_des_model/mechanics/walking.rs index fe51e3153b..99f5041533 100644 --- a/editor/src/plugins/sim/new_des_model/mechanics/walking.rs +++ b/editor/src/plugins/sim/new_des_model/mechanics/walking.rs @@ -13,6 +13,7 @@ use std::collections::BTreeMap; // TODO These are comically fast. const SPEED: Speed = Speed::const_meters_per_second(3.9); const TIME_TO_START_BIKING: Duration = Duration::const_seconds(30.0); +const TIME_TO_FINISH_BIKING: Duration = Duration::const_seconds(45.0); #[derive(Serialize, Deserialize)] pub struct WalkingSimState { @@ -60,6 +61,11 @@ impl WalkingSimState { b, TimeInterval::new(time, time + map.get_b(b).front_path.line.length() / SPEED), ), + SidewalkPOI::BikeRack(driving_pos) => PedState::FinishingBiking( + params.start.clone(), + Line::new(driving_pos.pt(map), params.start.sidewalk_pos.pt(map)), + TimeInterval::new(time, time + TIME_TO_FINISH_BIKING), + ), _ => ped.crossing_state(params.start.sidewalk_pos.dist_along(), time, map), }; @@ -200,6 +206,11 @@ impl WalkingSimState { trips.ped_ready_to_bike(time, ped.id, spot.clone(), map, scheduler); } } + PedState::FinishingBiking(ref spot, _, ref time_int) => { + if time > time_int.end { + ped.state = ped.crossing_state(spot.sidewalk_pos.dist_along(), time, map); + } + } }; } for id in delete { @@ -270,6 +281,9 @@ impl Pedestrian { PedState::StartingToBike(_, ref line, ref time_int) => { line.percent_along(time_int.percent(time)) } + PedState::FinishingBiking(_, ref line, ref time_int) => { + line.percent_along(time_int.percent(time)) + } }; DrawPedestrianInput { @@ -293,4 +307,5 @@ enum PedState { LeavingBuilding(BuildingID, TimeInterval), EnteringBuilding(BuildingID, TimeInterval), StartingToBike(SidewalkSpot, Line, TimeInterval), + FinishingBiking(SidewalkSpot, Line, TimeInterval), } diff --git a/editor/src/plugins/sim/new_des_model/router.rs b/editor/src/plugins/sim/new_des_model/router.rs index 24351f3a20..85e77a039d 100644 --- a/editor/src/plugins/sim/new_des_model/router.rs +++ b/editor/src/plugins/sim/new_des_model/router.rs @@ -1,4 +1,4 @@ -use crate::plugins::sim::new_des_model::{ParkingSimState, ParkingSpot, Vehicle}; +use crate::plugins::sim::new_des_model::{ParkingSimState, ParkingSpot, SidewalkSpot, Vehicle}; use geom::Distance; use map_model::{BuildingID, Map, Position, Traversable}; use serde_derive::{Deserialize, Serialize}; @@ -15,6 +15,7 @@ pub enum ActionAtEnd { Vanish, StartParking(ParkingSpot), GotoLaneEnd, + StopBiking(SidewalkSpot), } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -29,6 +30,9 @@ enum Goal { StopSuddenly { end_dist: Distance, }, + BikeThenStop { + end_dist: Distance, + }, } impl Router { @@ -49,6 +53,13 @@ impl Router { } } + pub fn bike_then_stop(path: Vec, end_dist: Distance) -> Router { + Router { + path: VecDeque::from(path), + goal: Goal::BikeThenStop { end_dist }, + } + } + pub fn head(&self) -> Traversable { self.path[0] } @@ -67,6 +78,7 @@ impl Router { match self.goal { Goal::StopSuddenly { end_dist } => end_dist, Goal::ParkNearBuilding { spot, .. } => spot.unwrap().1, + Goal::BikeThenStop { end_dist } => end_dist, } } @@ -126,6 +138,22 @@ impl Router { None } } + Goal::BikeThenStop { end_dist } => { + if end_dist == front { + let last_lane = self.path[0].as_lane(); + Some(ActionAtEnd::StopBiking( + SidewalkSpot::bike_rack( + map.get_parent(last_lane) + .bike_to_sidewalk(last_lane) + .unwrap(), + map, + ) + .unwrap(), + )) + } else { + None + } + } } } diff --git a/editor/src/plugins/sim/new_des_model/trips.rs b/editor/src/plugins/sim/new_des_model/trips.rs index b4566e0804..ecd60dc8b0 100644 --- a/editor/src/plugins/sim/new_des_model/trips.rs +++ b/editor/src/plugins/sim/new_des_model/trips.rs @@ -183,7 +183,7 @@ impl TripManager { let router = match drive_to { // TODO Stop closer to the building? - DrivingGoal::ParkNear(_) => Router::stop_suddenly( + DrivingGoal::ParkNear(_) => Router::bike_then_stop( path.convert_to_traversable_list(), map.get_l(end.lane()).length() / 2.0, ), @@ -199,21 +199,53 @@ impl TripManager { )); } - /*pub fn bike_reached_end(&mut self, bike: CarID) -> (TripID, PedestrianID, SidewalkSpot) { + pub fn bike_reached_end( + &mut self, + time: Duration, + bike: CarID, + bike_rack: SidewalkSpot, + map: &Map, + scheduler: &mut Scheduler, + ) { let trip = &mut self.trips[self.active_trip_mode.remove(&AgentID::Car(bike)).unwrap().0]; - match trip.legs.pop_front().unwrap() { - TripLeg::Bike { .. } => {} - x => panic!("First trip leg {:?} doesn't match bike_reached_end", x), + match trip.legs.pop_front() { + Some(TripLeg::Bike(vehicle, DrivingGoal::ParkNear(_))) => assert_eq!(vehicle.id, bike), + _ => unreachable!(), }; let walk_to = match trip.legs[0] { - TripLeg::Walk(ref to) => to, - ref x => panic!("Next trip leg is {:?}, not walking", x), + TripLeg::Walk(ref to) => to.clone(), + _ => unreachable!(), }; - (trip.id, trip.ped.unwrap(), walk_to.clone()) + + let path = if let Some(p) = Pathfinder::shortest_distance( + map, + PathRequest { + start: bike_rack.sidewalk_pos, + end: walk_to.sidewalk_pos, + can_use_bus_lanes: false, + can_use_bike_lanes: false, + }, + ) { + p + } else { + println!("Aborting a trip because no path for the walking portion!"); + return; + }; + + scheduler.enqueue_command(Command::SpawnPed( + time, + CreatePedestrian { + id: trip.ped.unwrap(), + start: bike_rack, + goal: walk_to, + path, + trip: trip.id, + }, + )); } - pub fn ped_reached_building_or_border(&mut self, ped: PedestrianID, now: Duration) { + /*pub fn ped_reached_building_or_border(&mut self, ped: PedestrianID, now: Duration) { let trip = &mut self.trips[self .active_trip_mode .remove(&AgentID::Pedestrian(ped)) diff --git a/map_model/src/road.rs b/map_model/src/road.rs index d42c0c6e23..364bd54776 100644 --- a/map_model/src/road.rs +++ b/map_model/src/road.rs @@ -157,6 +157,22 @@ impl Road { } } + pub fn bike_to_sidewalk(&self, bike: LaneID) -> Option { + // TODO Crossing bus lanes means higher layers of sim should know to block these off + let (fwds, idx) = self.dir_and_offset(bike); + if fwds { + self.children_forwards[0..idx] + .iter() + .find(|(_, lt)| *lt == LaneType::Sidewalk) + .map(|(id, _)| *id) + } else { + self.children_backwards[0..idx] + .iter() + .find(|(_, lt)| *lt == LaneType::Sidewalk) + .map(|(id, _)| *id) + } + } + // Is this lane the arbitrary canonical lane of this road? Used for deciding who should draw // yellow center lines. pub fn is_canonical_lane(&self, lane: LaneID) -> bool {