mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
making the multi-leg trips handle transitions correctly
This commit is contained in:
parent
9d01183a7e
commit
bc9b559701
@ -695,6 +695,9 @@ step 2: move interactive and testish spawning stuff to init() or similar, leavin
|
||||
- separate methods that take sim and call a special method to get direct access to things?
|
||||
- i just physically want the code in a separate file. can we implement a trait in a second file?
|
||||
step 3: enhance the trip stuff to have a concept of hardcoded legs, and make it choose how to use a bus
|
||||
- seed a trip using a bus
|
||||
- wire up the transitions to board and deboard the bus
|
||||
- test a basic bus scenario
|
||||
|
||||
|
||||
## Everything as FSMs
|
||||
|
@ -291,12 +291,17 @@ impl Spawner {
|
||||
let parking_spot = SidewalkSpot::parking_spot(parked.spot, map, parking_sim);
|
||||
self.commands.push_back(Command::Walk(
|
||||
at,
|
||||
self.trips
|
||||
.new_trip(map, ped_id, start_bldg, goal_bldg, vec![
|
||||
TripLeg::Walk(parking_spot.clone()),
|
||||
TripLeg::Drive(parked, goal_bldg),
|
||||
TripLeg::Walk(SidewalkSpot::building(goal_bldg, map)),
|
||||
]),
|
||||
self.trips.new_trip(
|
||||
map,
|
||||
ped_id,
|
||||
start_bldg,
|
||||
goal_bldg,
|
||||
vec![
|
||||
TripLeg::Walk(parking_spot.clone()),
|
||||
TripLeg::Drive(parked, goal_bldg),
|
||||
TripLeg::Walk(SidewalkSpot::building(goal_bldg, map)),
|
||||
],
|
||||
),
|
||||
ped_id,
|
||||
SidewalkSpot::building(start_bldg, map),
|
||||
parking_spot,
|
||||
@ -319,7 +324,13 @@ impl Spawner {
|
||||
|
||||
self.commands.push_back(Command::Walk(
|
||||
at,
|
||||
self.trips.new_trip(map, ped_id, start_bldg, goal_bldg, vec![TripLeg::Walk(SidewalkSpot::building(goal_bldg, map))]),
|
||||
self.trips.new_trip(
|
||||
map,
|
||||
ped_id,
|
||||
start_bldg,
|
||||
goal_bldg,
|
||||
vec![TripLeg::Walk(SidewalkSpot::building(goal_bldg, map))],
|
||||
),
|
||||
ped_id,
|
||||
SidewalkSpot::building(start_bldg, map),
|
||||
SidewalkSpot::building(goal_bldg, map),
|
||||
@ -334,13 +345,13 @@ impl Spawner {
|
||||
map: &Map,
|
||||
parking_sim: &ParkingSimState,
|
||||
) {
|
||||
let (trip, ped, goal_bldg) = self.trips.car_reached_parking_spot(p.car);
|
||||
let (trip, ped, walk_to) = self.trips.car_reached_parking_spot(p.car);
|
||||
self.commands.push_back(Command::Walk(
|
||||
at.next(),
|
||||
trip,
|
||||
ped,
|
||||
SidewalkSpot::parking_spot(p.spot, map, parking_sim),
|
||||
SidewalkSpot::building(goal_bldg, map),
|
||||
walk_to,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use abstutil::{deserialize_btreemap, serialize_btreemap};
|
||||
use map_model::{BuildingID, BusStop, Map};
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
use walking::SidewalkSpot;
|
||||
use {AgentID, CarID, ParkedCar, PedestrianID, RouteID, TripID};
|
||||
|
||||
@ -29,17 +29,45 @@ impl TripManager {
|
||||
self.active_trip_mode.insert(agent, trip);
|
||||
}
|
||||
|
||||
pub fn car_reached_parking_spot(&mut self, car: CarID) -> (TripID, PedestrianID, BuildingID) {
|
||||
let trip = &self.trips[self.active_trip_mode.remove(&AgentID::Car(car)).unwrap().0];
|
||||
(trip.id, trip.ped, trip.goal_bldg)
|
||||
// Where are we walking next?
|
||||
pub fn car_reached_parking_spot(&mut self, car: CarID) -> (TripID, PedestrianID, SidewalkSpot) {
|
||||
let trip = &mut self.trips[self.active_trip_mode.remove(&AgentID::Car(car)).unwrap().0];
|
||||
|
||||
match trip.legs.pop_front().unwrap() {
|
||||
TripLeg::Drive(parked, _) => assert_eq!(car, parked.car),
|
||||
x => panic!(
|
||||
"First trip leg {:?} doesn't match car_reached_parking_spot",
|
||||
x
|
||||
),
|
||||
};
|
||||
// TODO there are only some valid sequences of trips. it'd be neat to guarantee these are
|
||||
// valid by construction with a fluent API.
|
||||
let walk_to = match trip.legs[0] {
|
||||
TripLeg::Walk(ref to) => to,
|
||||
ref x => panic!("Next trip leg is {:?}, not walking", x),
|
||||
};
|
||||
(trip.id, trip.ped, walk_to.clone())
|
||||
}
|
||||
|
||||
// Where are we driving next?
|
||||
pub fn ped_reached_parking_spot(&mut self, ped: PedestrianID) -> (TripID, BuildingID) {
|
||||
let trip = &self.trips[self.active_trip_mode
|
||||
.remove(&AgentID::Pedestrian(ped))
|
||||
.unwrap()
|
||||
.0];
|
||||
(trip.id, trip.goal_bldg)
|
||||
let trip = &mut self.trips[self.active_trip_mode
|
||||
.remove(&AgentID::Pedestrian(ped))
|
||||
.unwrap()
|
||||
.0];
|
||||
|
||||
match trip.legs.pop_front().unwrap() {
|
||||
TripLeg::Walk(_) => {}
|
||||
x => panic!(
|
||||
"First trip leg {:?} doesn't match ped_reached_parking_spot",
|
||||
x
|
||||
),
|
||||
};
|
||||
let drive_to = match trip.legs[0] {
|
||||
TripLeg::Drive(_, ref to) => to,
|
||||
ref x => panic!("Next trip leg is {:?}, not walking", x),
|
||||
};
|
||||
(trip.id, *drive_to)
|
||||
}
|
||||
|
||||
// Creation from the interactive part of spawner
|
||||
@ -54,7 +82,10 @@ impl TripManager {
|
||||
assert!(!legs.is_empty());
|
||||
match legs.last().unwrap() {
|
||||
TripLeg::Walk(to) => assert_eq!(*to, SidewalkSpot::building(goal_bldg, map)),
|
||||
x => panic!("Last leg of trip isn't walking to the goal building; it's {:?}", x),
|
||||
x => panic!(
|
||||
"Last leg of trip isn't walking to the goal building; it's {:?}",
|
||||
x
|
||||
),
|
||||
};
|
||||
|
||||
let id = TripID(self.trips.len());
|
||||
@ -63,7 +94,7 @@ impl TripManager {
|
||||
ped,
|
||||
start_bldg,
|
||||
goal_bldg,
|
||||
legs,
|
||||
legs: VecDeque::from(legs),
|
||||
});
|
||||
id
|
||||
}
|
||||
@ -83,7 +114,7 @@ struct Trip {
|
||||
ped: PedestrianID,
|
||||
start_bldg: BuildingID,
|
||||
goal_bldg: BuildingID,
|
||||
legs: Vec<TripLeg>,
|
||||
legs: VecDeque<TripLeg>,
|
||||
}
|
||||
|
||||
// Except for Drive (which has to say what car to drive), these don't say where the leg starts.
|
||||
|
Loading…
Reference in New Issue
Block a user