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
= 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

View File

@ -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

View File

@ -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(

View File

@ -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,

View File

@ -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) {

View File

@ -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);
}
}