From 7e8407466e9c1b802c136eff9be23e3930cf9a89 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Tue, 4 Sep 2018 10:48:13 -0700 Subject: [PATCH] gluing transit sim to trip manager for boarding a bus --- sim/src/helpers.rs | 13 +++++++++---- sim/src/sim.rs | 24 +++++++++++++++++++----- sim/src/spawn.rs | 24 ++++++++++++------------ sim/src/transit.rs | 11 ++++++++--- sim/src/trips.rs | 20 ++++++++++++++++++++ 5 files changed, 68 insertions(+), 24 deletions(-) diff --git a/sim/src/helpers.rs b/sim/src/helpers.rs index 9e8dad11f0..178553d4cd 100644 --- a/sim/src/helpers.rs +++ b/sim/src/helpers.rs @@ -215,6 +215,7 @@ impl Sim { &self.parking_state, start_bldg, goal_bldg, + &mut self.trips_state, ); } @@ -222,13 +223,17 @@ impl Sim { assert!(map.get_l(sidewalk).is_sidewalk()); let start_bldg = pick_bldg_from_sidewalk(&mut self.rng, map, sidewalk); let goal_bldg = pick_ped_goal(&mut self.rng, map, sidewalk); - self.spawner - .spawn_specific_pedestrian(self.time.next(), map, start_bldg, goal_bldg); + self.spawn_specific_pedestrian(map, start_bldg, goal_bldg); } pub fn spawn_specific_pedestrian(&mut self, map: &Map, from: BuildingID, to: BuildingID) { - self.spawner - .spawn_specific_pedestrian(self.time.next(), map, from, to); + self.spawner.spawn_specific_pedestrian( + self.time.next(), + map, + from, + to, + &mut self.trips_state, + ); } pub fn seed_walking_trips(&mut self, map: &Map, num: usize) { diff --git a/sim/src/sim.rs b/sim/src/sim.rs index e0ea3714a3..a81d67201f 100644 --- a/sim/src/sim.rs +++ b/sim/src/sim.rs @@ -17,6 +17,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::f64; use std::time::{Duration, Instant}; use transit::TransitSimState; +use trips::TripManager; use walking::WalkingSimState; use {AgentID, CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP}; @@ -43,6 +44,7 @@ pub struct Sim { pub(crate) parking_state: ParkingSimState, pub(crate) walking_state: WalkingSimState, pub(crate) transit_state: TransitSimState, + pub(crate) trips_state: TripManager, pub(crate) car_properties: BTreeMap, } @@ -64,6 +66,7 @@ impl Sim { rng, driving_state: DrivingSimState::new(map), spawner: Spawner::empty(), + trips_state: TripManager::new(), intersection_state: IntersectionSimState::new(map), parking_state: ParkingSimState::new(map), walking_state: WalkingSimState::new(), @@ -136,6 +139,7 @@ impl Sim { &mut self.parking_state, &mut self.walking_state, &mut self.driving_state, + &mut self.trips_state, &self.car_properties, ); @@ -151,8 +155,13 @@ impl Sim { )? { events.push(Event::CarReachedParkingSpot(p.clone())); self.parking_state.add_parked_car(p.clone()); - self.spawner - .car_reached_parking_spot(self.time, p, map, &self.parking_state); + self.spawner.car_reached_parking_spot( + self.time, + p, + map, + &self.parking_state, + &mut self.trips_state, + ); } for (ped, spot) in @@ -160,12 +169,17 @@ impl Sim { .step(&mut events, TIMESTEP, map, &mut self.intersection_state)? { events.push(Event::PedReachedParkingSpot(ped, spot)); - self.spawner - .ped_reached_parking_spot(self.time, ped, spot, &self.parking_state); + self.spawner.ped_reached_parking_spot( + self.time, + ped, + spot, + &self.parking_state, + &mut self.trips_state, + ); } self.transit_state - .step(&mut events, &mut self.walking_state); + .step(&mut events, &mut self.walking_state, &mut self.trips_state); // TODO want to pass self as a lazy QueryCar trait, but intersection_state is mutably // borrowed :( diff --git a/sim/src/spawn.rs b/sim/src/spawn.rs index 2d7845e9ac..aac20c5b4c 100644 --- a/sim/src/spawn.rs +++ b/sim/src/spawn.rs @@ -57,9 +57,6 @@ pub struct Spawner { car_id_counter: usize, ped_id_counter: usize, - - // No real use in being owned by Sim. All of the transitions will need us to spawn something. - trips: TripManager, } impl Spawner { @@ -68,7 +65,6 @@ impl Spawner { commands: VecDeque::new(), car_id_counter: 0, ped_id_counter: 0, - trips: TripManager::new(), } } @@ -80,6 +76,7 @@ impl Spawner { parking_sim: &mut ParkingSimState, walking_sim: &mut WalkingSimState, driving_sim: &mut DrivingSimState, + trips: &mut TripManager, properties: &BTreeMap, ) { let mut commands: Vec = Vec::new(); @@ -127,7 +124,7 @@ impl Spawner { map, properties, ) { - self.trips.agent_starting_trip_leg(AgentID::Car(car), trip); + trips.agent_starting_trip_leg(AgentID::Car(car), trip); parking_sim.remove_parked_car(parked_car.clone()); spawned_agents += 1; } else { @@ -137,8 +134,7 @@ impl Spawner { } } Command::Walk(_, trip, ped, spot1, spot2) => { - self.trips - .agent_starting_trip_leg(AgentID::Pedestrian(ped), trip); + trips.agent_starting_trip_leg(AgentID::Pedestrian(ped), trip); walking_sim.seed_pedestrian( events, ped, @@ -271,13 +267,14 @@ impl Spawner { parking_sim: &ParkingSimState, start_bldg: BuildingID, goal_bldg: BuildingID, + trips: &mut TripManager, ) { if let Some(cmd) = self.commands.back() { assert!(at >= cmd.at()); } // Don't add duplicate commands. - if let Some(trip) = self.trips.get_trip_using_car(parked.car) { + if let Some(trip) = trips.get_trip_using_car(parked.car) { println!( "{} is already a part of {}, ignoring new request", parked.car, trip @@ -291,7 +288,7 @@ impl Spawner { let parking_spot = SidewalkSpot::parking_spot(parked.spot, map, parking_sim); self.commands.push_back(Command::Walk( at, - self.trips.new_trip( + trips.new_trip( map, ped_id, start_bldg, @@ -314,6 +311,7 @@ impl Spawner { map: &Map, start_bldg: BuildingID, goal_bldg: BuildingID, + trips: &mut TripManager, ) { if let Some(cmd) = self.commands.back() { assert!(at >= cmd.at()); @@ -324,7 +322,7 @@ impl Spawner { self.commands.push_back(Command::Walk( at, - self.trips.new_trip( + trips.new_trip( map, ped_id, start_bldg, @@ -344,8 +342,9 @@ impl Spawner { p: ParkedCar, map: &Map, parking_sim: &ParkingSimState, + trips: &mut TripManager, ) { - let (trip, ped, walk_to) = self.trips.car_reached_parking_spot(p.car); + let (trip, ped, walk_to) = trips.car_reached_parking_spot(p.car); self.commands.push_back(Command::Walk( at.next(), trip, @@ -361,8 +360,9 @@ impl Spawner { ped: PedestrianID, spot: ParkingSpot, parking_sim: &ParkingSimState, + trips: &mut TripManager, ) { - let (trip, goal_bldg) = self.trips.ped_reached_parking_spot(ped); + let (trip, goal_bldg) = trips.ped_reached_parking_spot(ped); self.commands.push_back(Command::Drive( at.next(), trip, diff --git a/sim/src/transit.rs b/sim/src/transit.rs index 64657d2121..795395495f 100644 --- a/sim/src/transit.rs +++ b/sim/src/transit.rs @@ -5,6 +5,7 @@ use events::Event; use map_model; use map_model::{BusStop, LaneID, Map}; use std::collections::{BTreeMap, VecDeque}; +use trips::TripManager; use walking::WalkingSimState; use {CarID, Distance, PedestrianID, RouteID, Tick}; @@ -185,15 +186,19 @@ impl TransitSimState { } } - pub fn step(&mut self, events: &mut Vec, walking_sim: &mut WalkingSimState) { + pub fn step( + &mut self, + events: &mut Vec, + walking_sim: &mut WalkingSimState, + trips: &mut TripManager, + ) { for b in self.buses.values_mut() { if let BusState::AtStop(stop_idx, _) = b.state { let stop = self.routes[&b.route].stops[stop_idx].clone(); // Let anybody new on? for p in walking_sim.get_peds_waiting_at_stop(&stop).into_iter() { - println!("TODO should {} board bus {}?", p, b.car); - if true { + if trips.should_ped_board_bus(p, b.route) { events.push(Event::PedEntersBus(p, b.car)); b.passengers.push(p); walking_sim.ped_joined_bus(p, &stop); diff --git a/sim/src/trips.rs b/sim/src/trips.rs index 8d32db3cbb..740c1eff9c 100644 --- a/sim/src/trips.rs +++ b/sim/src/trips.rs @@ -70,6 +70,26 @@ impl TripManager { (trip.id, *drive_to) } + // Combo query/transition from transit + pub fn should_ped_board_bus(&mut self, ped: PedestrianID, route: RouteID) -> bool { + let trip = &mut self.trips[self.active_trip_mode[&AgentID::Pedestrian(ped)].0]; + + let board = match trip.legs[1] { + TripLeg::RideBus(r, _) => r == route, + ref x => panic!("{} is at a bus stop, but next leg is {:?}", ped, x), + }; + if !board { + return false; + } + + // They're boarding! + self.active_trip_mode.remove(&AgentID::Pedestrian(ped)); + // Could assert that the first leg is walking to the right bus stop + trip.legs.pop_front(); + + true + } + // Creation from the interactive part of spawner pub fn new_trip( &mut self,