mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
bike -> ped
This commit is contained in:
parent
e404780c25
commit
8ab4b403fa
@ -245,6 +245,16 @@ impl DrivingSimState {
|
||||
Some(ActionAtEnd::GotoLaneEnd) => {
|
||||
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 => {}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use std::collections::BTreeMap;
|
||||
// TODO These are comically fast.
|
||||
const SPEED: Speed = Speed::const_meters_per_second(3.9);
|
||||
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)]
|
||||
pub struct WalkingSimState {
|
||||
@ -60,6 +61,11 @@ impl WalkingSimState {
|
||||
b,
|
||||
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),
|
||||
};
|
||||
|
||||
@ -200,6 +206,11 @@ impl WalkingSimState {
|
||||
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 {
|
||||
@ -270,6 +281,9 @@ impl Pedestrian {
|
||||
PedState::StartingToBike(_, ref line, ref time_int) => {
|
||||
line.percent_along(time_int.percent(time))
|
||||
}
|
||||
PedState::FinishingBiking(_, ref line, ref time_int) => {
|
||||
line.percent_along(time_int.percent(time))
|
||||
}
|
||||
};
|
||||
|
||||
DrawPedestrianInput {
|
||||
@ -293,4 +307,5 @@ enum PedState {
|
||||
LeavingBuilding(BuildingID, TimeInterval),
|
||||
EnteringBuilding(BuildingID, TimeInterval),
|
||||
StartingToBike(SidewalkSpot, Line, TimeInterval),
|
||||
FinishingBiking(SidewalkSpot, Line, TimeInterval),
|
||||
}
|
||||
|
@ -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 map_model::{BuildingID, Map, Position, Traversable};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
@ -15,6 +15,7 @@ pub enum ActionAtEnd {
|
||||
Vanish,
|
||||
StartParking(ParkingSpot),
|
||||
GotoLaneEnd,
|
||||
StopBiking(SidewalkSpot),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
@ -29,6 +30,9 @@ enum Goal {
|
||||
StopSuddenly {
|
||||
end_dist: Distance,
|
||||
},
|
||||
BikeThenStop {
|
||||
end_dist: Distance,
|
||||
},
|
||||
}
|
||||
|
||||
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 {
|
||||
self.path[0]
|
||||
}
|
||||
@ -67,6 +78,7 @@ impl Router {
|
||||
match self.goal {
|
||||
Goal::StopSuddenly { end_dist } => end_dist,
|
||||
Goal::ParkNearBuilding { spot, .. } => spot.unwrap().1,
|
||||
Goal::BikeThenStop { end_dist } => end_dist,
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +138,22 @@ impl Router {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ impl TripManager {
|
||||
|
||||
let router = match drive_to {
|
||||
// TODO Stop closer to the building?
|
||||
DrivingGoal::ParkNear(_) => Router::stop_suddenly(
|
||||
DrivingGoal::ParkNear(_) => Router::bike_then_stop(
|
||||
path.convert_to_traversable_list(),
|
||||
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];
|
||||
|
||||
match trip.legs.pop_front().unwrap() {
|
||||
TripLeg::Bike { .. } => {}
|
||||
x => panic!("First trip leg {:?} doesn't match bike_reached_end", x),
|
||||
match trip.legs.pop_front() {
|
||||
Some(TripLeg::Bike(vehicle, DrivingGoal::ParkNear(_))) => assert_eq!(vehicle.id, bike),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let walk_to = match trip.legs[0] {
|
||||
TripLeg::Walk(ref to) => to,
|
||||
ref x => panic!("Next trip leg is {:?}, not walking", x),
|
||||
TripLeg::Walk(ref to) => to.clone(),
|
||||
_ => 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
|
||||
.active_trip_mode
|
||||
.remove(&AgentID::Pedestrian(ped))
|
||||
|
@ -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
|
||||
// yellow center lines.
|
||||
pub fn is_canonical_lane(&self, lane: LaneID) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user