bike -> ped

This commit is contained in:
Dustin Carlino 2019-02-26 11:16:57 -08:00
parent e404780c25
commit 8ab4b403fa
5 changed files with 111 additions and 10 deletions

View File

@ -245,6 +245,16 @@ impl DrivingSimState {
Some(ActionAtEnd::GotoLaneEnd) => { Some(ActionAtEnd::GotoLaneEnd) => {
car.state = car.crossing_state(dist, time, map); car.state = car.crossing_state(dist, time, map);
} }
Some(ActionAtEnd::StopBiking(bike_rack)) => {
delete_indices.push((idx, dist));
trips.bike_reached_end(
time,
car.vehicle.id,
bike_rack,
map,
scheduler,
);
}
None => {} None => {}
} }
} }

View File

@ -13,6 +13,7 @@ use std::collections::BTreeMap;
// TODO These are comically fast. // TODO These are comically fast.
const SPEED: Speed = Speed::const_meters_per_second(3.9); const SPEED: Speed = Speed::const_meters_per_second(3.9);
const TIME_TO_START_BIKING: Duration = Duration::const_seconds(30.0); const TIME_TO_START_BIKING: Duration = Duration::const_seconds(30.0);
const TIME_TO_FINISH_BIKING: Duration = Duration::const_seconds(45.0);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct WalkingSimState { pub struct WalkingSimState {
@ -60,6 +61,11 @@ impl WalkingSimState {
b, b,
TimeInterval::new(time, time + map.get_b(b).front_path.line.length() / SPEED), TimeInterval::new(time, time + map.get_b(b).front_path.line.length() / SPEED),
), ),
SidewalkPOI::BikeRack(driving_pos) => PedState::FinishingBiking(
params.start.clone(),
Line::new(driving_pos.pt(map), params.start.sidewalk_pos.pt(map)),
TimeInterval::new(time, time + TIME_TO_FINISH_BIKING),
),
_ => ped.crossing_state(params.start.sidewalk_pos.dist_along(), time, map), _ => ped.crossing_state(params.start.sidewalk_pos.dist_along(), time, map),
}; };
@ -200,6 +206,11 @@ impl WalkingSimState {
trips.ped_ready_to_bike(time, ped.id, spot.clone(), map, scheduler); trips.ped_ready_to_bike(time, ped.id, spot.clone(), map, scheduler);
} }
} }
PedState::FinishingBiking(ref spot, _, ref time_int) => {
if time > time_int.end {
ped.state = ped.crossing_state(spot.sidewalk_pos.dist_along(), time, map);
}
}
}; };
} }
for id in delete { for id in delete {
@ -270,6 +281,9 @@ impl Pedestrian {
PedState::StartingToBike(_, ref line, ref time_int) => { PedState::StartingToBike(_, ref line, ref time_int) => {
line.percent_along(time_int.percent(time)) line.percent_along(time_int.percent(time))
} }
PedState::FinishingBiking(_, ref line, ref time_int) => {
line.percent_along(time_int.percent(time))
}
}; };
DrawPedestrianInput { DrawPedestrianInput {
@ -293,4 +307,5 @@ enum PedState {
LeavingBuilding(BuildingID, TimeInterval), LeavingBuilding(BuildingID, TimeInterval),
EnteringBuilding(BuildingID, TimeInterval), EnteringBuilding(BuildingID, TimeInterval),
StartingToBike(SidewalkSpot, Line, TimeInterval), StartingToBike(SidewalkSpot, Line, TimeInterval),
FinishingBiking(SidewalkSpot, Line, TimeInterval),
} }

View File

@ -1,4 +1,4 @@
use crate::plugins::sim::new_des_model::{ParkingSimState, ParkingSpot, Vehicle}; use crate::plugins::sim::new_des_model::{ParkingSimState, ParkingSpot, SidewalkSpot, Vehicle};
use geom::Distance; use geom::Distance;
use map_model::{BuildingID, Map, Position, Traversable}; use map_model::{BuildingID, Map, Position, Traversable};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
@ -15,6 +15,7 @@ pub enum ActionAtEnd {
Vanish, Vanish,
StartParking(ParkingSpot), StartParking(ParkingSpot),
GotoLaneEnd, GotoLaneEnd,
StopBiking(SidewalkSpot),
} }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
@ -29,6 +30,9 @@ enum Goal {
StopSuddenly { StopSuddenly {
end_dist: Distance, end_dist: Distance,
}, },
BikeThenStop {
end_dist: Distance,
},
} }
impl Router { impl Router {
@ -49,6 +53,13 @@ impl Router {
} }
} }
pub fn bike_then_stop(path: Vec<Traversable>, end_dist: Distance) -> Router {
Router {
path: VecDeque::from(path),
goal: Goal::BikeThenStop { end_dist },
}
}
pub fn head(&self) -> Traversable { pub fn head(&self) -> Traversable {
self.path[0] self.path[0]
} }
@ -67,6 +78,7 @@ impl Router {
match self.goal { match self.goal {
Goal::StopSuddenly { end_dist } => end_dist, Goal::StopSuddenly { end_dist } => end_dist,
Goal::ParkNearBuilding { spot, .. } => spot.unwrap().1, Goal::ParkNearBuilding { spot, .. } => spot.unwrap().1,
Goal::BikeThenStop { end_dist } => end_dist,
} }
} }
@ -126,6 +138,22 @@ impl Router {
None None
} }
} }
Goal::BikeThenStop { end_dist } => {
if end_dist == front {
let last_lane = self.path[0].as_lane();
Some(ActionAtEnd::StopBiking(
SidewalkSpot::bike_rack(
map.get_parent(last_lane)
.bike_to_sidewalk(last_lane)
.unwrap(),
map,
)
.unwrap(),
))
} else {
None
}
}
} }
} }

View File

@ -183,7 +183,7 @@ impl TripManager {
let router = match drive_to { let router = match drive_to {
// TODO Stop closer to the building? // TODO Stop closer to the building?
DrivingGoal::ParkNear(_) => Router::stop_suddenly( DrivingGoal::ParkNear(_) => Router::bike_then_stop(
path.convert_to_traversable_list(), path.convert_to_traversable_list(),
map.get_l(end.lane()).length() / 2.0, map.get_l(end.lane()).length() / 2.0,
), ),
@ -199,21 +199,53 @@ impl TripManager {
)); ));
} }
/*pub fn bike_reached_end(&mut self, bike: CarID) -> (TripID, PedestrianID, SidewalkSpot) { pub fn bike_reached_end(
&mut self,
time: Duration,
bike: CarID,
bike_rack: SidewalkSpot,
map: &Map,
scheduler: &mut Scheduler,
) {
let trip = &mut self.trips[self.active_trip_mode.remove(&AgentID::Car(bike)).unwrap().0]; let trip = &mut self.trips[self.active_trip_mode.remove(&AgentID::Car(bike)).unwrap().0];
match trip.legs.pop_front().unwrap() { match trip.legs.pop_front() {
TripLeg::Bike { .. } => {} Some(TripLeg::Bike(vehicle, DrivingGoal::ParkNear(_))) => assert_eq!(vehicle.id, bike),
x => panic!("First trip leg {:?} doesn't match bike_reached_end", x), _ => unreachable!(),
}; };
let walk_to = match trip.legs[0] { let walk_to = match trip.legs[0] {
TripLeg::Walk(ref to) => to, TripLeg::Walk(ref to) => to.clone(),
ref x => panic!("Next trip leg is {:?}, not walking", x), _ => unreachable!(),
}; };
(trip.id, trip.ped.unwrap(), walk_to.clone())
let path = if let Some(p) = Pathfinder::shortest_distance(
map,
PathRequest {
start: bike_rack.sidewalk_pos,
end: walk_to.sidewalk_pos,
can_use_bus_lanes: false,
can_use_bike_lanes: false,
},
) {
p
} else {
println!("Aborting a trip because no path for the walking portion!");
return;
};
scheduler.enqueue_command(Command::SpawnPed(
time,
CreatePedestrian {
id: trip.ped.unwrap(),
start: bike_rack,
goal: walk_to,
path,
trip: trip.id,
},
));
} }
pub fn ped_reached_building_or_border(&mut self, ped: PedestrianID, now: Duration) { /*pub fn ped_reached_building_or_border(&mut self, ped: PedestrianID, now: Duration) {
let trip = &mut self.trips[self let trip = &mut self.trips[self
.active_trip_mode .active_trip_mode
.remove(&AgentID::Pedestrian(ped)) .remove(&AgentID::Pedestrian(ped))

View File

@ -157,6 +157,22 @@ impl Road {
} }
} }
pub fn bike_to_sidewalk(&self, bike: LaneID) -> Option<LaneID> {
// TODO Crossing bus lanes means higher layers of sim should know to block these off
let (fwds, idx) = self.dir_and_offset(bike);
if fwds {
self.children_forwards[0..idx]
.iter()
.find(|(_, lt)| *lt == LaneType::Sidewalk)
.map(|(id, _)| *id)
} else {
self.children_backwards[0..idx]
.iter()
.find(|(_, lt)| *lt == LaneType::Sidewalk)
.map(|(id, _)| *id)
}
}
// Is this lane the arbitrary canonical lane of this road? Used for deciding who should draw // Is this lane the arbitrary canonical lane of this road? Used for deciding who should draw
// yellow center lines. // yellow center lines.
pub fn is_canonical_lane(&self, lane: LaneID) -> bool { pub fn is_canonical_lane(&self, lane: LaneID) -> bool {