mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-28 08:53:26 +03:00
make finished bikes become peds
This commit is contained in:
parent
b9770dc4bd
commit
5db8b4edb6
@ -42,7 +42,7 @@ minimal. Alternate idea for another branch:
|
||||
= spawn param to decide if a trip without an owned car will instead bike
|
||||
= walking state can own the 'parking/unparking' state.
|
||||
- make sure biking from border works, needs an extra bit i think
|
||||
- need a new DrivingGoal, simpler than ParkNear.
|
||||
= need a new DrivingGoal, simpler than ParkNear.
|
||||
- entirely new render code, but the same DrawCarInput (plus is_bike
|
||||
bit). that part shouldn't matter, right?
|
||||
- render peds doing bike prep differently
|
||||
|
@ -73,6 +73,7 @@ impl Eq for Car {}
|
||||
pub enum Action {
|
||||
StartParking(ParkingSpot),
|
||||
WorkOnParking,
|
||||
StartParkingBike,
|
||||
Continue(Acceleration, Vec<Request>),
|
||||
// TODO Get rid of this one
|
||||
VanishAtDeadEnd,
|
||||
@ -557,8 +558,10 @@ impl DrivingSimState {
|
||||
}
|
||||
|
||||
// Note that this populates the view BEFORE the step is applied.
|
||||
// Returns cars that reached a parking spot this step, and also the cars that vanished at a
|
||||
// border.
|
||||
// Returns
|
||||
// 1) cars that reached a parking spot this step
|
||||
// 2) the cars that vanished at a border
|
||||
// 3) the bikes that reached some ending and should start parking
|
||||
pub fn step(
|
||||
&mut self,
|
||||
view: &mut WorldView,
|
||||
@ -571,7 +574,7 @@ impl DrivingSimState {
|
||||
transit_sim: &mut TransitSimState,
|
||||
rng: &mut XorShiftRng,
|
||||
current_agent: &mut Option<AgentID>,
|
||||
) -> Result<(Vec<ParkedCar>, Vec<CarID>), Error> {
|
||||
) -> Result<(Vec<ParkedCar>, Vec<CarID>, Vec<(CarID, LaneID, Distance)>), Error> {
|
||||
self.populate_view(view);
|
||||
|
||||
// Could be concurrent, since this is deterministic -- EXCEPT for the rng, used to
|
||||
@ -600,6 +603,7 @@ impl DrivingSimState {
|
||||
|
||||
let mut finished_parking: Vec<ParkedCar> = Vec::new();
|
||||
let mut vanished_at_border: Vec<CarID> = Vec::new();
|
||||
let mut done_biking: Vec<(CarID, LaneID, Distance)> = Vec::new();
|
||||
|
||||
// Apply moves. Since lookahead behavior works, there are no conflicts to resolve, meaning
|
||||
// this could be applied concurrently!
|
||||
@ -627,6 +631,14 @@ impl DrivingSimState {
|
||||
self.cars.get_mut(&id).unwrap().parking = Some(state);
|
||||
}
|
||||
}
|
||||
Action::StartParkingBike => {
|
||||
{
|
||||
let c = self.cars.get(&id).unwrap();
|
||||
done_biking.push((*id, c.on.as_lane(), c.dist_along));
|
||||
}
|
||||
self.cars.remove(&id);
|
||||
self.routers.remove(&id);
|
||||
}
|
||||
Action::Continue(accel, ref requests) => {
|
||||
let done = {
|
||||
let c = self.cars.get_mut(&id).unwrap();
|
||||
@ -697,7 +709,7 @@ impl DrivingSimState {
|
||||
}
|
||||
}
|
||||
|
||||
Ok((finished_parking, vanished_at_border))
|
||||
Ok((finished_parking, vanished_at_border, done_biking))
|
||||
}
|
||||
|
||||
// True if the car started, false if there wasn't currently room
|
||||
|
@ -161,7 +161,7 @@ impl Sim {
|
||||
&mut self.trips_state,
|
||||
);
|
||||
|
||||
let (newly_parked, at_border) = self.driving_state.step(
|
||||
let (newly_parked, at_border, done_biking) = self.driving_state.step(
|
||||
&mut view,
|
||||
&mut events,
|
||||
self.time,
|
||||
@ -187,6 +187,11 @@ impl Sim {
|
||||
for c in at_border {
|
||||
self.trips_state.car_reached_border(c, self.time);
|
||||
}
|
||||
for (bike, lane, dist) in done_biking {
|
||||
// TODO push an event, backtrace, etc
|
||||
self.spawner
|
||||
.bike_reached_end(self.time, bike, lane, dist, &mut self.trips_state);
|
||||
}
|
||||
|
||||
self.walking_state.populate_view(&mut view);
|
||||
let (reached_parking, ready_to_bike) = self.walking_state.step(
|
||||
|
@ -265,8 +265,8 @@ impl Spawner {
|
||||
}
|
||||
Command::Bike {
|
||||
trip,
|
||||
vehicle,
|
||||
goal,
|
||||
ref vehicle,
|
||||
ref goal,
|
||||
..
|
||||
} => {
|
||||
if driving_sim.start_car_on_lane(
|
||||
@ -282,7 +282,7 @@ impl Spawner {
|
||||
start: req.0,
|
||||
dist_along: req.1,
|
||||
router: match goal {
|
||||
DrivingGoal::ParkNear(b) => {
|
||||
DrivingGoal::ParkNear(_) => {
|
||||
Router::make_bike_router(path, req.3)
|
||||
}
|
||||
DrivingGoal::Border(_, _) => {
|
||||
@ -559,8 +559,13 @@ impl Spawner {
|
||||
let bike_id = CarID(self.car_id_counter);
|
||||
self.car_id_counter += 1;
|
||||
|
||||
let first_spot = {
|
||||
let b = map.get_b(start_bldg);
|
||||
SidewalkSpot::bike_rack(b.front_path.sidewalk, b.front_path.dist_along_sidewalk)
|
||||
};
|
||||
|
||||
let mut legs = vec![
|
||||
TripLeg::Walk(SidewalkSpot::bike_rack(start_bldg, map)),
|
||||
TripLeg::Walk(first_spot.clone()),
|
||||
TripLeg::Bike(Vehicle::generate_bike(bike_id, rng), goal.clone()),
|
||||
];
|
||||
if let DrivingGoal::ParkNear(b) = goal {
|
||||
@ -571,7 +576,7 @@ impl Spawner {
|
||||
trips.new_trip(at, ped_id, legs),
|
||||
ped_id,
|
||||
SidewalkSpot::building(start_bldg, map),
|
||||
SidewalkSpot::bike_rack(start_bldg, map),
|
||||
first_spot,
|
||||
));
|
||||
}
|
||||
|
||||
@ -693,6 +698,24 @@ impl Spawner {
|
||||
));
|
||||
}
|
||||
|
||||
pub fn bike_reached_end(
|
||||
&mut self,
|
||||
at: Tick,
|
||||
bike: CarID,
|
||||
lane: LaneID,
|
||||
dist: Distance,
|
||||
trips: &mut TripManager,
|
||||
) {
|
||||
let (trip, ped, walk_to) = trips.bike_reached_end(bike);
|
||||
self.enqueue_command(Command::Walk(
|
||||
at.next(),
|
||||
trip,
|
||||
ped,
|
||||
SidewalkSpot::bike_rack(lane, dist),
|
||||
walk_to,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn ped_ready_to_bike(
|
||||
&mut self,
|
||||
at: Tick,
|
||||
|
@ -87,10 +87,24 @@ impl TripManager {
|
||||
x => panic!("First trip leg {:?} doesn't match ped_ready_to_bike", x),
|
||||
};
|
||||
let (vehicle, bike_to) = match trip.legs[0] {
|
||||
TripLeg::Bike(vehicle, to) => (vehicle, to),
|
||||
TripLeg::Bike(ref vehicle, ref to) => (vehicle, to),
|
||||
ref x => panic!("Next trip leg is {:?}, not biking", x),
|
||||
};
|
||||
(trip.id, vehicle, bike_to)
|
||||
(trip.id, vehicle.clone(), bike_to.clone())
|
||||
}
|
||||
|
||||
pub fn bike_reached_end(&mut self, bike: CarID) -> (TripID, PedestrianID, SidewalkSpot) {
|
||||
let trip = &mut self.trips[self.active_trip_mode.remove(&AgentID::Car(bike)).unwrap().0];
|
||||
|
||||
match trip.legs.pop_front().unwrap() {
|
||||
TripLeg::Bike { .. } => {}
|
||||
x => panic!("First trip leg {:?} doesn't match bike_reached_end", x),
|
||||
};
|
||||
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())
|
||||
}
|
||||
|
||||
pub fn ped_reached_building_or_border(&mut self, ped: PedestrianID, now: Tick) {
|
||||
|
@ -67,13 +67,11 @@ impl SidewalkSpot {
|
||||
}
|
||||
}
|
||||
|
||||
// These happen to be lined up with buildings right now
|
||||
pub fn bike_rack(bldg: BuildingID, map: &Map) -> SidewalkSpot {
|
||||
let front_path = &map.get_b(bldg).front_path;
|
||||
pub fn bike_rack(sidewalk: LaneID, dist_along: Distance) -> SidewalkSpot {
|
||||
SidewalkSpot {
|
||||
connection: SidewalkPOI::BikeRack,
|
||||
sidewalk: front_path.sidewalk,
|
||||
dist_along: front_path.dist_along_sidewalk,
|
||||
sidewalk,
|
||||
dist_along,
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,14 +446,23 @@ impl WalkingSimState {
|
||||
});
|
||||
}
|
||||
Action::KeepPreparingBike => {
|
||||
let p = self.peds.get_mut(&id).unwrap();
|
||||
if (now - p.bike_parking.unwrap().started_at).as_time() >= TIME_TO_PREPARE_BIKE
|
||||
{
|
||||
if p.bike_parking.unwrap().is_parking {
|
||||
let state = self
|
||||
.peds
|
||||
.get(&id)
|
||||
.unwrap()
|
||||
.bike_parking
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone();
|
||||
if (now - state.started_at).as_time() >= TIME_TO_PREPARE_BIKE {
|
||||
if state.is_parking {
|
||||
// Now they'll start walking somewhere
|
||||
p.bike_parking = None;
|
||||
self.peds.get_mut(&id).unwrap().bike_parking = None;
|
||||
} else {
|
||||
{
|
||||
let p = self.peds.get(&id).unwrap();
|
||||
ready_to_bike.push((*id, p.on.as_lane(), p.dist_along));
|
||||
}
|
||||
self.peds.remove(&id);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user