make finished bikes become peds

This commit is contained in:
Dustin Carlino 2018-11-16 13:51:28 -08:00
parent b9770dc4bd
commit 5db8b4edb6
6 changed files with 85 additions and 24 deletions

View File

@ -42,7 +42,7 @@ minimal. Alternate idea for another branch:
= spawn param to decide if a trip without an owned car will instead bike = spawn param to decide if a trip without an owned car will instead bike
= walking state can own the 'parking/unparking' state. = walking state can own the 'parking/unparking' state.
- make sure biking from border works, needs an extra bit i think - 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 - entirely new render code, but the same DrawCarInput (plus is_bike
bit). that part shouldn't matter, right? bit). that part shouldn't matter, right?
- render peds doing bike prep differently - render peds doing bike prep differently

View File

@ -73,6 +73,7 @@ impl Eq for Car {}
pub enum Action { pub enum Action {
StartParking(ParkingSpot), StartParking(ParkingSpot),
WorkOnParking, WorkOnParking,
StartParkingBike,
Continue(Acceleration, Vec<Request>), Continue(Acceleration, Vec<Request>),
// TODO Get rid of this one // TODO Get rid of this one
VanishAtDeadEnd, VanishAtDeadEnd,
@ -557,8 +558,10 @@ impl DrivingSimState {
} }
// Note that this populates the view BEFORE the step is applied. // 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 // Returns
// border. // 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( pub fn step(
&mut self, &mut self,
view: &mut WorldView, view: &mut WorldView,
@ -571,7 +574,7 @@ impl DrivingSimState {
transit_sim: &mut TransitSimState, transit_sim: &mut TransitSimState,
rng: &mut XorShiftRng, rng: &mut XorShiftRng,
current_agent: &mut Option<AgentID>, 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); self.populate_view(view);
// Could be concurrent, since this is deterministic -- EXCEPT for the rng, used to // 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 finished_parking: Vec<ParkedCar> = Vec::new();
let mut vanished_at_border: Vec<CarID> = 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 // Apply moves. Since lookahead behavior works, there are no conflicts to resolve, meaning
// this could be applied concurrently! // this could be applied concurrently!
@ -627,6 +631,14 @@ impl DrivingSimState {
self.cars.get_mut(&id).unwrap().parking = Some(state); 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) => { Action::Continue(accel, ref requests) => {
let done = { let done = {
let c = self.cars.get_mut(&id).unwrap(); 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 // True if the car started, false if there wasn't currently room

View File

@ -161,7 +161,7 @@ impl Sim {
&mut self.trips_state, &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 view,
&mut events, &mut events,
self.time, self.time,
@ -187,6 +187,11 @@ impl Sim {
for c in at_border { for c in at_border {
self.trips_state.car_reached_border(c, self.time); 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); self.walking_state.populate_view(&mut view);
let (reached_parking, ready_to_bike) = self.walking_state.step( let (reached_parking, ready_to_bike) = self.walking_state.step(

View File

@ -265,8 +265,8 @@ impl Spawner {
} }
Command::Bike { Command::Bike {
trip, trip,
vehicle, ref vehicle,
goal, ref goal,
.. ..
} => { } => {
if driving_sim.start_car_on_lane( if driving_sim.start_car_on_lane(
@ -282,7 +282,7 @@ impl Spawner {
start: req.0, start: req.0,
dist_along: req.1, dist_along: req.1,
router: match goal { router: match goal {
DrivingGoal::ParkNear(b) => { DrivingGoal::ParkNear(_) => {
Router::make_bike_router(path, req.3) Router::make_bike_router(path, req.3)
} }
DrivingGoal::Border(_, _) => { DrivingGoal::Border(_, _) => {
@ -559,8 +559,13 @@ impl Spawner {
let bike_id = CarID(self.car_id_counter); let bike_id = CarID(self.car_id_counter);
self.car_id_counter += 1; 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![ 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()), TripLeg::Bike(Vehicle::generate_bike(bike_id, rng), goal.clone()),
]; ];
if let DrivingGoal::ParkNear(b) = goal { if let DrivingGoal::ParkNear(b) = goal {
@ -571,7 +576,7 @@ impl Spawner {
trips.new_trip(at, ped_id, legs), trips.new_trip(at, ped_id, legs),
ped_id, ped_id,
SidewalkSpot::building(start_bldg, map), 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( pub fn ped_ready_to_bike(
&mut self, &mut self,
at: Tick, at: Tick,

View File

@ -87,10 +87,24 @@ impl TripManager {
x => panic!("First trip leg {:?} doesn't match ped_ready_to_bike", x), x => panic!("First trip leg {:?} doesn't match ped_ready_to_bike", x),
}; };
let (vehicle, bike_to) = match trip.legs[0] { 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), 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) { pub fn ped_reached_building_or_border(&mut self, ped: PedestrianID, now: Tick) {

View File

@ -67,13 +67,11 @@ impl SidewalkSpot {
} }
} }
// These happen to be lined up with buildings right now pub fn bike_rack(sidewalk: LaneID, dist_along: Distance) -> SidewalkSpot {
pub fn bike_rack(bldg: BuildingID, map: &Map) -> SidewalkSpot {
let front_path = &map.get_b(bldg).front_path;
SidewalkSpot { SidewalkSpot {
connection: SidewalkPOI::BikeRack, connection: SidewalkPOI::BikeRack,
sidewalk: front_path.sidewalk, sidewalk,
dist_along: front_path.dist_along_sidewalk, dist_along,
} }
} }
@ -448,14 +446,23 @@ impl WalkingSimState {
}); });
} }
Action::KeepPreparingBike => { Action::KeepPreparingBike => {
let p = self.peds.get_mut(&id).unwrap(); let state = self
if (now - p.bike_parking.unwrap().started_at).as_time() >= TIME_TO_PREPARE_BIKE .peds
{ .get(&id)
if p.bike_parking.unwrap().is_parking { .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 // Now they'll start walking somewhere
p.bike_parking = None; self.peds.get_mut(&id).unwrap().bike_parking = None;
} else { } else {
{
let p = self.peds.get(&id).unwrap();
ready_to_bike.push((*id, p.on.as_lane(), p.dist_along)); ready_to_bike.push((*id, p.on.as_lane(), p.dist_along));
}
self.peds.remove(&id); self.peds.remove(&id);
} }
} }