mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
make peds board buses
This commit is contained in:
parent
9c916e5d11
commit
313841b9de
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user