1 use crate::sim::Ctx; 2 use crate::{ 3 CarID, Event, PedestrianID, PersonID, Router, TripID, TripManager, TripPhaseType, VehicleType, 4 WalkingSimState, 5 }; 6 use abstutil::{deserialize_btreemap, serialize_btreemap}; 7 use geom::Time; 8 use map_model::{BusRoute, BusRouteID, BusStopID, Map, Path, PathRequest, Position}; 9 use serde::{Deserialize, Serialize}; 10 use std::collections::{BTreeMap, BTreeSet}; 11 12 // These index stops along a route, not stops along a single sidewalk. 13 type StopIdx = usize; 14 15 #[derive(Serialize, Deserialize, Clone)] 16 struct Stop { 17 id: BusStopID, 18 driving_pos: Position, 19 next_stop: Option<(PathRequest, Path)>, 20 } 21 22 #[derive(Serialize, Deserialize, Clone)] 23 struct Route { 24 stops: Vec<Stop>, 25 start: (PathRequest, Path), 26 end_at_border: Option<(PathRequest, Path)>, 27 active_vehicles: BTreeSet<CarID>, 28 } 29 30 #[derive(Serialize, Deserialize, Clone)] 31 struct Bus { 32 car: CarID, 33 route: BusRouteID, 34 // Where does each passenger want to deboard? 35 passengers: Vec<(PersonID, Option<BusStopID>)>, 36 state: BusState, 37 } 38 39 #[derive(Serialize, Deserialize, Clone)] 40 enum BusState { 41 DrivingToStop(StopIdx), 42 AtStop(StopIdx), 43 DrivingOffMap, 44 Done, 45 } 46 47 // This kind of acts like TripManager, managing transitions... but a bit more statefully. 48 #[derive(Serialize, Deserialize, Clone)] 49 pub struct TransitSimState { 50 #[serde( 51 serialize_with = "serialize_btreemap", 52 deserialize_with = "deserialize_btreemap" 53 )] 54 buses: BTreeMap<CarID, Bus>, 55 #[serde( 56 serialize_with = "serialize_btreemap", 57 deserialize_with = "deserialize_btreemap" 58 )] 59 routes: BTreeMap<BusRouteID, Route>, 60 // waiting at => (ped, route, bound for, started waiting) 61 #[serde( 62 serialize_with = "serialize_btreemap", 63 deserialize_with = "deserialize_btreemap" 64 )] 65 peds_waiting: BTreeMap<BusStopID, Vec<(PedestrianID, BusRouteID, Option<BusStopID>, Time)>>, 66 67 events: Vec<Event>, 68 } 69 70 impl TransitSimState { new(map: &Map) -> TransitSimState71 pub fn new(map: &Map) -> TransitSimState { 72 // Keep this filled out always so get_passengers can return &Vec without a hassle 73 let mut peds_waiting = BTreeMap::new(); 74 for bs in map.all_bus_stops().keys() { 75 peds_waiting.insert(*bs, Vec::new()); 76 } 77 78 TransitSimState { 79 buses: BTreeMap::new(), 80 routes: BTreeMap::new(), 81 peds_waiting, 82 events: Vec::new(), 83 } 84 } 85 86 // Returns the path for the first leg. create_empty_route(&mut self, bus_route: &BusRoute, map: &Map) -> (PathRequest, Path)87 pub fn create_empty_route(&mut self, bus_route: &BusRoute, map: &Map) -> (PathRequest, Path) { 88 if !self.routes.contains_key(&bus_route.id) { 89 assert!(bus_route.stops.len() > 1); 90 let mut stops = Vec::new(); 91 for (idx, stop1_id) in bus_route.stops.iter().enumerate() { 92 let stop1 = map.get_bs(*stop1_id); 93 if idx == bus_route.stops.len() - 1 { 94 stops.push(Stop { 95 id: stop1.id, 96 driving_pos: stop1.driving_pos, 97 next_stop: None, 98 }); 99 continue; 100 } 101 let req = PathRequest { 102 start: stop1.driving_pos, 103 end: map.get_bs(bus_route.stops[idx + 1]).driving_pos, 104 constraints: bus_route.route_type, 105 }; 106 if let Some(path) = map.pathfind(req.clone()) { 107 if path.is_empty() { 108 panic!("Empty path between stops?! {}", req); 109 } 110 stops.push(Stop { 111 id: stop1.id, 112 driving_pos: stop1.driving_pos, 113 next_stop: Some((req, path)), 114 }); 115 } else { 116 panic!("No route between stops: {}", req); 117 } 118 } 119 let start_req = PathRequest { 120 start: Position::start(bus_route.start), 121 end: map.get_bs(bus_route.stops[0]).driving_pos, 122 constraints: bus_route.route_type, 123 }; 124 let start = ( 125 start_req.clone(), 126 map.pathfind(start_req).expect("no route to first stop"), 127 ); 128 let end_at_border = if let Some(l) = bus_route.end_border { 129 let req = PathRequest { 130 start: map.get_bs(*bus_route.stops.last().unwrap()).driving_pos, 131 end: Position::end(l, map), 132 constraints: bus_route.route_type, 133 }; 134 let path = map 135 .pathfind(req.clone()) 136 .expect("no route from last stop to border"); 137 Some((req, path)) 138 } else { 139 None 140 }; 141 self.routes.insert( 142 bus_route.id, 143 Route { 144 active_vehicles: BTreeSet::new(), 145 stops, 146 start, 147 end_at_border, 148 }, 149 ); 150 } 151 152 self.routes[&bus_route.id].start.clone() 153 } 154 bus_created(&mut self, bus: CarID, r: BusRouteID)155 pub fn bus_created(&mut self, bus: CarID, r: BusRouteID) { 156 let route = self.routes.get_mut(&r).unwrap(); 157 route.active_vehicles.insert(bus); 158 self.buses.insert( 159 bus, 160 Bus { 161 car: bus, 162 route: r, 163 passengers: Vec::new(), 164 state: BusState::DrivingToStop(0), 165 }, 166 ); 167 } 168 169 // If true, the bus is idling. If false, the bus actually arrived at a border and should now 170 // vanish. bus_arrived_at_stop( &mut self, now: Time, id: CarID, trips: &mut TripManager, walking: &mut WalkingSimState, ctx: &mut Ctx, ) -> bool171 pub fn bus_arrived_at_stop( 172 &mut self, 173 now: Time, 174 id: CarID, 175 trips: &mut TripManager, 176 walking: &mut WalkingSimState, 177 ctx: &mut Ctx, 178 ) -> bool { 179 let mut bus = self.buses.get_mut(&id).unwrap(); 180 match bus.state { 181 BusState::DrivingToStop(stop_idx) => { 182 bus.state = BusState::AtStop(stop_idx); 183 let stop1 = self.routes[&bus.route].stops[stop_idx].id; 184 self.events 185 .push(Event::BusArrivedAtStop(id, bus.route, stop1)); 186 187 // Deboard existing passengers. 188 let mut still_riding = Vec::new(); 189 for (person, maybe_stop2) in bus.passengers.drain(..) { 190 if Some(stop1) == maybe_stop2 { 191 trips.person_left_bus(now, person, bus.car, ctx); 192 self.events.push(Event::PassengerAlightsTransit( 193 person, bus.car, bus.route, stop1, 194 )); 195 } else { 196 still_riding.push((person, maybe_stop2)); 197 } 198 } 199 bus.passengers = still_riding; 200 201 // Board new passengers. 202 let mut still_waiting = Vec::new(); 203 for (ped, route, maybe_stop2, started_waiting) in 204 self.peds_waiting.remove(&stop1).unwrap() 205 { 206 if bus.route == route { 207 let (trip, person) = trips.ped_boarded_bus( 208 now, 209 ped, 210 bus.car, 211 now - started_waiting, 212 walking, 213 ); 214 self.events.push(Event::PassengerBoardsTransit( 215 person, 216 bus.car, 217 bus.route, 218 stop1, 219 now - started_waiting, 220 )); 221 self.events.push(Event::TripPhaseStarting( 222 trip, 223 person, 224 Some(PathRequest { 225 start: ctx.map.get_bs(stop1).driving_pos, 226 end: if let Some(stop2) = maybe_stop2 { 227 ctx.map.get_bs(stop2).driving_pos 228 } else { 229 self.routes[&route].end_at_border.as_ref().unwrap().0.end 230 }, 231 constraints: bus.car.1.to_constraints(), 232 }), 233 TripPhaseType::RidingBus(route, stop1, bus.car), 234 )); 235 bus.passengers.push((person, maybe_stop2)); 236 } else { 237 still_waiting.push((ped, route, maybe_stop2, started_waiting)); 238 } 239 } 240 self.peds_waiting.insert(stop1, still_waiting); 241 true 242 } 243 BusState::DrivingOffMap => { 244 self.routes 245 .get_mut(&bus.route) 246 .unwrap() 247 .active_vehicles 248 .remove(&id); 249 bus.state = BusState::Done; 250 for (person, maybe_stop2) in bus.passengers.drain(..) { 251 if let Some(stop2) = maybe_stop2 { 252 panic!( 253 "{} fell asleep on {} and just rode off-map, but they were supposed \ 254 to hop off at {}", 255 person, bus.car, stop2 256 ); 257 } 258 trips.transit_rider_reached_border(now, person, id, ctx); 259 } 260 false 261 } 262 BusState::AtStop(_) | BusState::Done => unreachable!(), 263 } 264 } 265 bus_departed_from_stop(&mut self, id: CarID, map: &Map) -> Router266 pub fn bus_departed_from_stop(&mut self, id: CarID, map: &Map) -> Router { 267 let mut bus = self.buses.get_mut(&id).unwrap(); 268 let route = self.routes.get_mut(&bus.route).unwrap(); 269 match bus.state { 270 BusState::DrivingToStop(_) | BusState::DrivingOffMap | BusState::Done => unreachable!(), 271 BusState::AtStop(stop_idx) => { 272 let stop = &route.stops[stop_idx]; 273 self.events 274 .push(Event::BusDepartedFromStop(id, bus.route, stop.id)); 275 if let Some((req, path)) = stop.next_stop.clone() { 276 bus.state = BusState::DrivingToStop(stop_idx + 1); 277 Router::follow_bus_route(id, path, req.end.dist_along()) 278 } else { 279 if let Some((req, path)) = route.end_at_border.clone() { 280 bus.state = BusState::DrivingOffMap; 281 Router::follow_bus_route(id, path, req.end.dist_along()) 282 } else { 283 let on = stop.driving_pos.lane(); 284 route.active_vehicles.remove(&id); 285 for (person, stop2) in &bus.passengers { 286 panic!( 287 "{} of {} is vanishing at its last stop, but {} is still riding \ 288 until {:?}", 289 bus.car, bus.route, person, stop2 290 ); 291 } 292 bus.state = BusState::Done; 293 Router::vanish_bus(id, on, map) 294 } 295 } 296 } 297 } 298 } 299 300 // Returns the bus if the pedestrian boarded immediately. ped_waiting_for_bus( &mut self, now: Time, ped: PedestrianID, trip: TripID, person: PersonID, stop1: BusStopID, route_id: BusRouteID, maybe_stop2: Option<BusStopID>, map: &Map, ) -> Option<CarID>301 pub fn ped_waiting_for_bus( 302 &mut self, 303 now: Time, 304 ped: PedestrianID, 305 trip: TripID, 306 person: PersonID, 307 stop1: BusStopID, 308 route_id: BusRouteID, 309 maybe_stop2: Option<BusStopID>, 310 map: &Map, 311 ) -> Option<CarID> { 312 assert!(Some(stop1) != maybe_stop2); 313 if let Some(route) = self.routes.get(&route_id) { 314 for bus in &route.active_vehicles { 315 if let BusState::AtStop(idx) = self.buses[bus].state { 316 if route.stops[idx].id == stop1 { 317 self.buses 318 .get_mut(bus) 319 .unwrap() 320 .passengers 321 .push((person, maybe_stop2)); 322 self.events.push(Event::TripPhaseStarting( 323 trip, 324 person, 325 Some(PathRequest { 326 start: map.get_bs(stop1).driving_pos, 327 end: if let Some(stop2) = maybe_stop2 { 328 map.get_bs(stop2).driving_pos 329 } else { 330 route.end_at_border.as_ref().unwrap().0.end 331 }, 332 constraints: bus.1.to_constraints(), 333 }), 334 TripPhaseType::RidingBus(route_id, stop1, *bus), 335 )); 336 return Some(*bus); 337 } 338 } 339 } 340 } else { 341 println!( 342 "WARNING: {} waiting for {}, but that route hasn't been instantiated", 343 ped, route_id 344 ); 345 } 346 347 self.peds_waiting 348 .get_mut(&stop1) 349 .unwrap() 350 .push((ped, route_id, maybe_stop2, now)); 351 None 352 } 353 collect_events(&mut self) -> Vec<Event>354 pub fn collect_events(&mut self) -> Vec<Event> { 355 self.events.drain(..).collect() 356 } 357 get_passengers(&self, bus: CarID) -> &Vec<(PersonID, Option<BusStopID>)>358 pub fn get_passengers(&self, bus: CarID) -> &Vec<(PersonID, Option<BusStopID>)> { 359 &self.buses[&bus].passengers 360 } 361 bus_route(&self, bus: CarID) -> BusRouteID362 pub fn bus_route(&self, bus: CarID) -> BusRouteID { 363 self.buses[&bus].route 364 } 365 366 // also stop idx that the bus is coming from buses_for_route(&self, route: BusRouteID) -> Vec<(CarID, Option<usize>)>367 pub fn buses_for_route(&self, route: BusRouteID) -> Vec<(CarID, Option<usize>)> { 368 if let Some(ref r) = self.routes.get(&route) { 369 r.active_vehicles 370 .iter() 371 .map(|bus| { 372 let stop = match self.buses[bus].state { 373 BusState::DrivingToStop(idx) => { 374 if idx == 0 { 375 None 376 } else { 377 Some(idx - 1) 378 } 379 } 380 BusState::AtStop(idx) => Some(idx), 381 BusState::DrivingOffMap => Some(r.stops.len() - 1), 382 BusState::Done => unreachable!(), 383 }; 384 (*bus, stop) 385 }) 386 .collect() 387 } else { 388 Vec::new() 389 } 390 } 391 392 // (buses, trains) active_vehicles(&self) -> (usize, usize)393 pub fn active_vehicles(&self) -> (usize, usize) { 394 let mut buses = 0; 395 let mut trains = 0; 396 for r in self.routes.values() { 397 let len = r.active_vehicles.len(); 398 if len > 0 { 399 if r.active_vehicles.iter().next().unwrap().1 == VehicleType::Bus { 400 buses += len; 401 } else { 402 trains += len; 403 } 404 } 405 } 406 (buses, trains) 407 } 408 get_people_waiting_at_stop( &self, at: BusStopID, ) -> &Vec<(PedestrianID, BusRouteID, Option<BusStopID>, Time)>409 pub fn get_people_waiting_at_stop( 410 &self, 411 at: BusStopID, 412 ) -> &Vec<(PedestrianID, BusRouteID, Option<BusStopID>, Time)> { 413 &self.peds_waiting[&at] 414 } 415 } 416