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) => {
|
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 => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user