gluing transit sim to trip manager for boarding a bus

This commit is contained in:
Dustin Carlino 2018-09-04 10:48:13 -07:00
parent bc9b559701
commit 7e8407466e
5 changed files with 68 additions and 24 deletions

View File

@ -215,6 +215,7 @@ impl Sim {
&self.parking_state, &self.parking_state,
start_bldg, start_bldg,
goal_bldg, goal_bldg,
&mut self.trips_state,
); );
} }
@ -222,13 +223,17 @@ impl Sim {
assert!(map.get_l(sidewalk).is_sidewalk()); assert!(map.get_l(sidewalk).is_sidewalk());
let start_bldg = pick_bldg_from_sidewalk(&mut self.rng, map, sidewalk); let start_bldg = pick_bldg_from_sidewalk(&mut self.rng, map, sidewalk);
let goal_bldg = pick_ped_goal(&mut self.rng, map, sidewalk); let goal_bldg = pick_ped_goal(&mut self.rng, map, sidewalk);
self.spawner self.spawn_specific_pedestrian(map, start_bldg, goal_bldg);
.spawn_specific_pedestrian(self.time.next(), map, start_bldg, goal_bldg);
} }
pub fn spawn_specific_pedestrian(&mut self, map: &Map, from: BuildingID, to: BuildingID) { pub fn spawn_specific_pedestrian(&mut self, map: &Map, from: BuildingID, to: BuildingID) {
self.spawner self.spawner.spawn_specific_pedestrian(
.spawn_specific_pedestrian(self.time.next(), map, from, to); self.time.next(),
map,
from,
to,
&mut self.trips_state,
);
} }
pub fn seed_walking_trips(&mut self, map: &Map, num: usize) { pub fn seed_walking_trips(&mut self, map: &Map, num: usize) {

View File

@ -17,6 +17,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use std::f64; use std::f64;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use transit::TransitSimState; use transit::TransitSimState;
use trips::TripManager;
use walking::WalkingSimState; use walking::WalkingSimState;
use {AgentID, CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP}; use {AgentID, CarID, CarState, Event, InvariantViolated, PedestrianID, Tick, TIMESTEP};
@ -43,6 +44,7 @@ pub struct Sim {
pub(crate) parking_state: ParkingSimState, pub(crate) parking_state: ParkingSimState,
pub(crate) walking_state: WalkingSimState, pub(crate) walking_state: WalkingSimState,
pub(crate) transit_state: TransitSimState, pub(crate) transit_state: TransitSimState,
pub(crate) trips_state: TripManager,
pub(crate) car_properties: BTreeMap<CarID, Vehicle>, pub(crate) car_properties: BTreeMap<CarID, Vehicle>,
} }
@ -64,6 +66,7 @@ impl Sim {
rng, rng,
driving_state: DrivingSimState::new(map), driving_state: DrivingSimState::new(map),
spawner: Spawner::empty(), spawner: Spawner::empty(),
trips_state: TripManager::new(),
intersection_state: IntersectionSimState::new(map), intersection_state: IntersectionSimState::new(map),
parking_state: ParkingSimState::new(map), parking_state: ParkingSimState::new(map),
walking_state: WalkingSimState::new(), walking_state: WalkingSimState::new(),
@ -136,6 +139,7 @@ impl Sim {
&mut self.parking_state, &mut self.parking_state,
&mut self.walking_state, &mut self.walking_state,
&mut self.driving_state, &mut self.driving_state,
&mut self.trips_state,
&self.car_properties, &self.car_properties,
); );
@ -151,8 +155,13 @@ impl Sim {
)? { )? {
events.push(Event::CarReachedParkingSpot(p.clone())); events.push(Event::CarReachedParkingSpot(p.clone()));
self.parking_state.add_parked_car(p.clone()); self.parking_state.add_parked_car(p.clone());
self.spawner self.spawner.car_reached_parking_spot(
.car_reached_parking_spot(self.time, p, map, &self.parking_state); self.time,
p,
map,
&self.parking_state,
&mut self.trips_state,
);
} }
for (ped, spot) in for (ped, spot) in
@ -160,12 +169,17 @@ impl Sim {
.step(&mut events, TIMESTEP, map, &mut self.intersection_state)? .step(&mut events, TIMESTEP, map, &mut self.intersection_state)?
{ {
events.push(Event::PedReachedParkingSpot(ped, spot)); events.push(Event::PedReachedParkingSpot(ped, spot));
self.spawner self.spawner.ped_reached_parking_spot(
.ped_reached_parking_spot(self.time, ped, spot, &self.parking_state); self.time,
ped,
spot,
&self.parking_state,
&mut self.trips_state,
);
} }
self.transit_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 // TODO want to pass self as a lazy QueryCar trait, but intersection_state is mutably
// borrowed :( // borrowed :(

View File

@ -57,9 +57,6 @@ pub struct Spawner {
car_id_counter: usize, car_id_counter: usize,
ped_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 { impl Spawner {
@ -68,7 +65,6 @@ impl Spawner {
commands: VecDeque::new(), commands: VecDeque::new(),
car_id_counter: 0, car_id_counter: 0,
ped_id_counter: 0, ped_id_counter: 0,
trips: TripManager::new(),
} }
} }
@ -80,6 +76,7 @@ impl Spawner {
parking_sim: &mut ParkingSimState, parking_sim: &mut ParkingSimState,
walking_sim: &mut WalkingSimState, walking_sim: &mut WalkingSimState,
driving_sim: &mut DrivingSimState, driving_sim: &mut DrivingSimState,
trips: &mut TripManager,
properties: &BTreeMap<CarID, Vehicle>, properties: &BTreeMap<CarID, Vehicle>,
) { ) {
let mut commands: Vec<Command> = Vec::new(); let mut commands: Vec<Command> = Vec::new();
@ -127,7 +124,7 @@ impl Spawner {
map, map,
properties, 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()); parking_sim.remove_parked_car(parked_car.clone());
spawned_agents += 1; spawned_agents += 1;
} else { } else {
@ -137,8 +134,7 @@ impl Spawner {
} }
} }
Command::Walk(_, trip, ped, spot1, spot2) => { Command::Walk(_, trip, ped, spot1, spot2) => {
self.trips trips.agent_starting_trip_leg(AgentID::Pedestrian(ped), trip);
.agent_starting_trip_leg(AgentID::Pedestrian(ped), trip);
walking_sim.seed_pedestrian( walking_sim.seed_pedestrian(
events, events,
ped, ped,
@ -271,13 +267,14 @@ impl Spawner {
parking_sim: &ParkingSimState, parking_sim: &ParkingSimState,
start_bldg: BuildingID, start_bldg: BuildingID,
goal_bldg: BuildingID, goal_bldg: BuildingID,
trips: &mut TripManager,
) { ) {
if let Some(cmd) = self.commands.back() { if let Some(cmd) = self.commands.back() {
assert!(at >= cmd.at()); assert!(at >= cmd.at());
} }
// Don't add duplicate commands. // 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!( println!(
"{} is already a part of {}, ignoring new request", "{} is already a part of {}, ignoring new request",
parked.car, trip parked.car, trip
@ -291,7 +288,7 @@ impl Spawner {
let parking_spot = SidewalkSpot::parking_spot(parked.spot, map, parking_sim); let parking_spot = SidewalkSpot::parking_spot(parked.spot, map, parking_sim);
self.commands.push_back(Command::Walk( self.commands.push_back(Command::Walk(
at, at,
self.trips.new_trip( trips.new_trip(
map, map,
ped_id, ped_id,
start_bldg, start_bldg,
@ -314,6 +311,7 @@ impl Spawner {
map: &Map, map: &Map,
start_bldg: BuildingID, start_bldg: BuildingID,
goal_bldg: BuildingID, goal_bldg: BuildingID,
trips: &mut TripManager,
) { ) {
if let Some(cmd) = self.commands.back() { if let Some(cmd) = self.commands.back() {
assert!(at >= cmd.at()); assert!(at >= cmd.at());
@ -324,7 +322,7 @@ impl Spawner {
self.commands.push_back(Command::Walk( self.commands.push_back(Command::Walk(
at, at,
self.trips.new_trip( trips.new_trip(
map, map,
ped_id, ped_id,
start_bldg, start_bldg,
@ -344,8 +342,9 @@ impl Spawner {
p: ParkedCar, p: ParkedCar,
map: &Map, map: &Map,
parking_sim: &ParkingSimState, 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( self.commands.push_back(Command::Walk(
at.next(), at.next(),
trip, trip,
@ -361,8 +360,9 @@ impl Spawner {
ped: PedestrianID, ped: PedestrianID,
spot: ParkingSpot, spot: ParkingSpot,
parking_sim: &ParkingSimState, 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( self.commands.push_back(Command::Drive(
at.next(), at.next(),
trip, trip,

View File

@ -5,6 +5,7 @@ use events::Event;
use map_model; use map_model;
use map_model::{BusStop, LaneID, Map}; use map_model::{BusStop, LaneID, Map};
use std::collections::{BTreeMap, VecDeque}; use std::collections::{BTreeMap, VecDeque};
use trips::TripManager;
use walking::WalkingSimState; use walking::WalkingSimState;
use {CarID, Distance, PedestrianID, RouteID, Tick}; use {CarID, Distance, PedestrianID, RouteID, Tick};
@ -185,15 +186,19 @@ impl TransitSimState {
} }
} }
pub fn step(&mut self, events: &mut Vec<Event>, walking_sim: &mut WalkingSimState) { pub fn step(
&mut self,
events: &mut Vec<Event>,
walking_sim: &mut WalkingSimState,
trips: &mut TripManager,
) {
for b in self.buses.values_mut() { for b in self.buses.values_mut() {
if let BusState::AtStop(stop_idx, _) = b.state { if let BusState::AtStop(stop_idx, _) = b.state {
let stop = self.routes[&b.route].stops[stop_idx].clone(); let stop = self.routes[&b.route].stops[stop_idx].clone();
// Let anybody new on? // Let anybody new on?
for p in walking_sim.get_peds_waiting_at_stop(&stop).into_iter() { for p in walking_sim.get_peds_waiting_at_stop(&stop).into_iter() {
println!("TODO should {} board bus {}?", p, b.car); if trips.should_ped_board_bus(p, b.route) {
if true {
events.push(Event::PedEntersBus(p, b.car)); events.push(Event::PedEntersBus(p, b.car));
b.passengers.push(p); b.passengers.push(p);
walking_sim.ped_joined_bus(p, &stop); walking_sim.ped_joined_bus(p, &stop);

View File

@ -70,6 +70,26 @@ impl TripManager {
(trip.id, *drive_to) (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 // Creation from the interactive part of spawner
pub fn new_trip( pub fn new_trip(
&mut self, &mut self,