make peds board buses

This commit is contained in:
Dustin Carlino 2019-03-01 15:42:17 -08:00
parent 9c916e5d11
commit 313841b9de
7 changed files with 135 additions and 22 deletions

View File

@ -331,8 +331,7 @@ impl Pathfinder {
.pathfind(map, start, goal)?;
for s in internal_steps.into_iter() {
if let InternalPathStep::RideBus(stop1, stop2, route) = s {
//return Some((stop1, stop2, route));
return None;
return Some((stop1, stop2, route));
}
}
None

View File

@ -217,7 +217,7 @@ impl TripSpawner {
));
}
DrivingGoal::Border(_, _) => {}
}
};
let trip = trips.new_trip(start_time, legs);
scheduler.enqueue_command(Command::SpawnPed(
@ -231,8 +231,27 @@ impl TripSpawner {
},
));
}
TripSpec::UsingTransit(_, _, _, _, _) => {
panic!("implement");
TripSpec::UsingTransit(start, route, stop1, stop2, goal) => {
let walk_to = SidewalkSpot::bus_stop(stop1, map);
let trip = trips.new_trip(
start_time,
vec![
TripLeg::Walk(ped_id.unwrap(), walk_to.clone()),
TripLeg::RideBus(ped_id.unwrap(), route, stop2),
TripLeg::Walk(ped_id.unwrap(), goal),
],
);
scheduler.enqueue_command(Command::SpawnPed(
start_time,
CreatePedestrian {
id: ped_id.unwrap(),
start,
goal: walk_to,
path,
trip,
},
));
}
}
}
@ -272,9 +291,12 @@ impl TripSpec {
can_use_bike_lanes: false,
can_use_bus_lanes: false,
},
TripSpec::UsingTransit(_, _, _, _, _) => {
panic!("implement");
}
TripSpec::UsingTransit(start, _, stop1, _, _) => PathRequest {
start: start.sidewalk_pos,
end: SidewalkSpot::bus_stop(*stop1, map).sidewalk_pos,
can_use_bike_lanes: false,
can_use_bus_lanes: false,
},
}
}
}

View File

@ -2,8 +2,8 @@ use crate::mechanics::car::{Car, CarState};
use crate::mechanics::queue::Queue;
use crate::{
ActionAtEnd, AgentID, CarID, CreateCar, DrawCarInput, IntersectionSimState, ParkedCar,
ParkingSimState, Scheduler, TimeInterval, TransitSimState, TripManager, BUS_LENGTH,
FOLLOWING_DISTANCE,
ParkingSimState, Scheduler, TimeInterval, TransitSimState, TripManager, WalkingSimState,
BUS_LENGTH, FOLLOWING_DISTANCE,
};
use abstutil::{deserialize_btreemap, serialize_btreemap};
use ezgui::{Color, GfxCtx};
@ -186,6 +186,7 @@ impl DrivingSimState {
trips: &mut TripManager,
scheduler: &mut Scheduler,
transit: &mut TransitSimState,
walking: &mut WalkingSimState,
) {
// Promote Crossing to Queued and Unparking to Crossing.
for queue in self.queues.values_mut() {
@ -268,7 +269,7 @@ impl DrivingSimState {
);
}
Some(ActionAtEnd::BusAtStop) => {
transit.bus_arrived_at_stop(car.vehicle.id);
transit.bus_arrived_at_stop(car.vehicle.id, walking);
car.state = CarState::Idling(
dist,
TimeInterval::new(time, time + TIME_TO_WAIT_AT_STOP),

View File

@ -1,6 +1,7 @@
use crate::{
AgentID, CreatePedestrian, DistanceInterval, DrawPedestrianInput, IntersectionSimState,
ParkingSimState, PedestrianID, Scheduler, SidewalkPOI, SidewalkSpot, TimeInterval, TripManager,
ParkingSimState, PedestrianID, Scheduler, SidewalkPOI, SidewalkSpot, TimeInterval,
TransitSimState, TripManager,
};
use abstutil::{deserialize_multimap, serialize_multimap, MultiMap};
use geom::{Distance, Duration, Line, Speed};
@ -102,6 +103,7 @@ impl WalkingSimState {
parking: &ParkingSimState,
scheduler: &mut Scheduler,
trips: &mut TripManager,
transit: &mut TransitSimState,
) {
let mut delete = Vec::new();
for ped in self.peds.values_mut() {
@ -128,7 +130,15 @@ impl WalkingSimState {
);
}
SidewalkPOI::BusStop(stop) => {
panic!("implement");
if trips.ped_reached_bus_stop(ped.id, stop, map, transit) {
delete.push(ped.id);
self.peds_per_traversable.remove(
ped.path.current_step().as_traversable(),
ped.id,
);
} else {
ped.state = PedState::WaitingForBus;
}
}
SidewalkPOI::Border(i) => {
delete.push(ped.id);
@ -209,6 +219,7 @@ impl WalkingSimState {
ped.state = ped.crossing_state(spot.sidewalk_pos.dist_along(), time, map);
}
}
PedState::WaitingForBus => {}
};
}
for id in delete {
@ -216,6 +227,13 @@ impl WalkingSimState {
}
}
pub fn ped_boarded_bus(&mut self, id: PedestrianID) {
match self.peds.remove(&id).unwrap().state {
PedState::WaitingForBus => {}
_ => unreachable!(),
};
}
pub fn debug_ped(&self, id: PedestrianID) {
if let Some(ped) = self.peds.get(&id) {
println!("{}", abstutil::to_json(ped));
@ -289,6 +307,7 @@ impl Pedestrian {
PedState::EnteringBuilding(b, _) => map.get_b(b).front_path.sidewalk.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(),
}
}
@ -322,6 +341,7 @@ impl Pedestrian {
PedState::FinishingBiking(_, ref line, ref time_int) => {
line.percent_along(time_int.percent(time))
}
PedState::WaitingForBus => self.goal.sidewalk_pos.pt(map),
};
DrawPedestrianInput {
@ -349,4 +369,5 @@ enum PedState {
EnteringBuilding(BuildingID, TimeInterval),
StartingToBike(SidewalkSpot, Line, TimeInterval),
FinishingBiking(SidewalkSpot, Line, TimeInterval),
WaitingForBus,
}

View File

@ -275,6 +275,7 @@ impl Sim {
&mut self.trips,
&mut self.scheduler,
&mut self.transit,
&mut self.walking,
);
self.walking.step_if_needed(
self.time,
@ -283,6 +284,7 @@ impl Sim {
&self.parking,
&mut self.scheduler,
&mut self.trips,
&mut self.transit,
);
// Spawn stuff at the end, so we can see the correct state of everything else at this time.

View File

@ -1,7 +1,7 @@
use crate::{CarID, Event, PedestrianID, Router};
use crate::{CarID, Event, PedestrianID, Router, WalkingSimState};
use abstutil::{deserialize_btreemap, serialize_btreemap};
use geom::Distance;
use map_model::{BusRoute, BusRouteID, BusStop, Map, Path, PathRequest, Pathfinder};
use map_model::{BusRoute, BusRouteID, BusStop, BusStopID, Map, Path, PathRequest, Pathfinder};
use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap;
@ -33,7 +33,8 @@ impl Route {
struct Bus {
car: CarID,
route: BusRouteID,
passengers: Vec<PedestrianID>,
// Where does each passenger want to deboard?
passengers: Vec<(PedestrianID, BusStopID)>,
state: BusState,
}
@ -56,6 +57,8 @@ pub struct TransitSimState {
deserialize_with = "deserialize_btreemap"
)]
routes: BTreeMap<BusRouteID, Route>,
// Can organize this more to make querying cheaper
peds_waiting: Vec<(PedestrianID, BusStopID, BusRouteID, BusStopID)>,
events: Vec<Event>,
}
@ -65,6 +68,7 @@ impl TransitSimState {
TransitSimState {
buses: BTreeMap::new(),
routes: BTreeMap::new(),
peds_waiting: Vec::new(),
events: Vec::new(),
}
}
@ -130,15 +134,27 @@ impl TransitSimState {
);
}
pub fn bus_arrived_at_stop(&mut self, id: CarID) {
pub fn bus_arrived_at_stop(&mut self, id: CarID, walking: &mut WalkingSimState) {
let mut bus = self.buses.get_mut(&id).unwrap();
match bus.state {
BusState::DrivingToStop(stop_idx) => {
bus.state = BusState::AtStop(stop_idx);
self.events.push(Event::BusArrivedAtStop(
id,
self.routes[&bus.route].stops[stop_idx].id,
));
let stop = self.routes[&bus.route].stops[stop_idx].id;
self.events.push(Event::BusArrivedAtStop(id, stop));
// Board new passengers.
let mut still_waiting = Vec::new();
for (ped, stop1, route, stop2) in self.peds_waiting.drain(..) {
if stop == stop1 && bus.route == route {
bus.passengers.push((ped, stop2));
self.events.push(Event::PedEntersBus(ped, id));
walking.ped_boarded_bus(ped);
// TODO shift trips
} else {
still_waiting.push((ped, stop1, route, stop2));
}
}
self.peds_waiting = still_waiting;
}
BusState::AtStop(_) => unreachable!(),
};
@ -174,6 +190,35 @@ impl TransitSimState {
}
}
// If true, the pedestrian boarded a bus immediately.
pub fn ped_waiting_for_bus(
&mut self,
ped: PedestrianID,
stop1: BusStopID,
route_id: BusRouteID,
stop2: BusStopID,
) -> bool {
assert!(stop1 != stop2);
let route = &self.routes[&route_id];
for bus in &route.buses {
if let BusState::AtStop(idx) = self.buses[bus].state {
if route.stops[idx].id == stop1 {
self.buses
.get_mut(bus)
.unwrap()
.passengers
.push((ped, stop2));
// TODO shift trips
self.events.push(Event::PedEntersBus(ped, *bus));
return true;
}
}
}
self.peds_waiting.push((ped, stop1, route_id, stop2));
false
}
pub fn collect_events(&mut self) -> Vec<Event> {
self.events.drain(..).collect()
}

View File

@ -1,6 +1,7 @@
use crate::{
AgentID, CarID, Command, CreateCar, CreatePedestrian, DrivingGoal, Event, ParkingSimState,
ParkingSpot, PedestrianID, Router, Scheduler, SidewalkPOI, SidewalkSpot, TripID, Vehicle,
ParkingSpot, PedestrianID, Router, Scheduler, SidewalkPOI, SidewalkSpot, TransitSimState,
TripID, Vehicle,
};
use abstutil::{deserialize_btreemap, serialize_btreemap};
use geom::Duration;
@ -284,6 +285,28 @@ impl TripManager {
trip.finished_at = Some(time);
}
// If true, the pedestrian boarded a bus immediately.
pub fn ped_reached_bus_stop(
&mut self,
ped: PedestrianID,
stop: BusStopID,
map: &Map,
transit: &mut TransitSimState,
) -> bool {
self.events.push(Event::PedReachedBusStop(ped, stop));
let trip = &self.trips[self.active_trip_mode[&AgentID::Pedestrian(ped)].0];
assert_eq!(
trip.legs[0],
TripLeg::Walk(ped, SidewalkSpot::bus_stop(stop, map))
);
match trip.legs[1] {
TripLeg::RideBus(_, route, stop2) => {
transit.ped_waiting_for_bus(ped, stop, route, stop2)
}
_ => unreachable!(),
}
}
pub fn ped_reached_border(
&mut self,
time: Duration,