mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 01:13:53 +03:00
Abort cars bound to park on edited lanes. #312
This commit is contained in:
parent
53f35f5de1
commit
220f33e2ec
@ -95,8 +95,7 @@ impl EditMode {
|
||||
app.primary
|
||||
.sim
|
||||
.handle_live_edited_traffic_signals(&app.primary.map);
|
||||
app.primary.sim.handle_live_edited_lanes(&app.primary.map);
|
||||
app.primary.sim.handle_live_edited_parking(&app.primary.map);
|
||||
app.primary.sim.handle_live_edits(&app.primary.map);
|
||||
Transition::Pop
|
||||
})
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ use crate::sim::Ctx;
|
||||
use crate::{
|
||||
ActionAtEnd, AgentID, AgentProperties, CarID, Command, CreateCar, DistanceInterval,
|
||||
DrawCarInput, Event, IntersectionSimState, ParkedCar, ParkingSimState, ParkingSpot, PersonID,
|
||||
Scheduler, TimeInterval, TransitSimState, TripManager, UnzoomedAgent, Vehicle, WalkingSimState,
|
||||
FOLLOWING_DISTANCE,
|
||||
Scheduler, TimeInterval, TransitSimState, TripID, TripManager, UnzoomedAgent, Vehicle,
|
||||
WalkingSimState, FOLLOWING_DISTANCE,
|
||||
};
|
||||
use abstutil::{deserialize_btreemap, serialize_btreemap};
|
||||
use geom::{Distance, Duration, PolyLine, Time};
|
||||
use map_model::{LaneID, Map, Path, PathStep, Traversable};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{BTreeMap, HashSet, VecDeque};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
|
||||
|
||||
const TIME_TO_UNPARK_ONSTRET: Duration = Duration::const_seconds(10.0);
|
||||
const TIME_TO_PARK_ONSTREET: Duration = Duration::const_seconds(15.0);
|
||||
@ -1024,4 +1024,20 @@ impl DrivingSimState {
|
||||
pub fn target_lane_penalty(&self, l: LaneID) -> (usize, usize) {
|
||||
self.queues[&Traversable::Lane(l)].target_lane_penalty()
|
||||
}
|
||||
|
||||
pub fn find_trips_to_edited_parking(
|
||||
&self,
|
||||
spots: BTreeSet<ParkingSpot>,
|
||||
) -> Vec<(AgentID, TripID)> {
|
||||
let mut affected = Vec::new();
|
||||
for car in self.cars.values() {
|
||||
if let Some(spot) = car.router.get_parking_spot_goal() {
|
||||
if !spots.contains(spot) {
|
||||
// Buses don't park
|
||||
affected.push((AgentID::Car(car.vehicle.id), car.trip_and_person.unwrap().0));
|
||||
}
|
||||
}
|
||||
}
|
||||
affected
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ impl ParkingSimState {
|
||||
}
|
||||
|
||||
// Returns any cars that got very abruptly evicted from existence
|
||||
pub fn handle_map_updates(&mut self, map: &Map, timer: &mut Timer) -> Vec<ParkedCar> {
|
||||
pub fn handle_live_edits(&mut self, map: &Map, timer: &mut Timer) -> Vec<ParkedCar> {
|
||||
let (filled_before, _) = self.get_all_parking_spots();
|
||||
let new = ParkingSimState::new(map, timer);
|
||||
let (_, avail_after) = new.get_all_parking_spots();
|
||||
|
@ -489,25 +489,18 @@ impl WalkingSimState {
|
||||
std::mem::replace(&mut self.events, Vec::new())
|
||||
}
|
||||
|
||||
pub fn handle_live_edited_parking(
|
||||
&mut self,
|
||||
deleted_cars: Vec<ParkedCar>,
|
||||
scheduler: &mut Scheduler,
|
||||
) {
|
||||
let goals: BTreeSet<SidewalkPOI> = deleted_cars
|
||||
pub fn find_trips_to_parking(&self, evicted_cars: Vec<ParkedCar>) -> Vec<(AgentID, TripID)> {
|
||||
let goals: BTreeSet<SidewalkPOI> = evicted_cars
|
||||
.into_iter()
|
||||
.map(|p| SidewalkPOI::ParkingSpot(p.spot))
|
||||
.collect();
|
||||
let mut delete = Vec::new();
|
||||
let mut affected = Vec::new();
|
||||
for ped in self.peds.values() {
|
||||
if goals.contains(&ped.goal.connection) {
|
||||
delete.push(ped.id);
|
||||
affected.push((AgentID::Pedestrian(ped.id), ped.trip));
|
||||
}
|
||||
}
|
||||
|
||||
for id in delete {
|
||||
self.delete_ped(id, scheduler);
|
||||
}
|
||||
affected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@ pub enum ActionAtEnd {
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
enum Goal {
|
||||
// Spot and cached distance along the last driving lane
|
||||
// TODO Right now, the building is ignored when choosing the best spot.
|
||||
ParkNearBuilding {
|
||||
target: BuildingID,
|
||||
spot: Option<(ParkingSpot, Distance)>,
|
||||
@ -429,4 +428,11 @@ impl Router {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parking_spot_goal(&self) -> Option<&ParkingSpot> {
|
||||
match self.goal {
|
||||
Goal::ParkNearBuilding { ref spot, .. } => spot.as_ref().map(|(s, _)| s),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ use map_model::{
|
||||
};
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
||||
use std::panic;
|
||||
|
||||
// TODO Do something else.
|
||||
@ -849,32 +849,8 @@ impl Sim {
|
||||
.handle_live_edited_traffic_signals(self.time, map, &mut self.scheduler)
|
||||
}
|
||||
|
||||
pub fn handle_live_edited_lanes(&mut self, map: &Map) {
|
||||
// TODO Handle changes to access restrictions
|
||||
|
||||
// Find every active trip whose path crosses a modified lane or closed intersection
|
||||
let (edited_lanes, _) = map.get_edits().changed_lanes(map);
|
||||
let mut closed_intersections = HashSet::new();
|
||||
for i in map.get_edits().original_intersections.keys() {
|
||||
if map.get_i(*i).is_closed() {
|
||||
closed_intersections.insert(*i);
|
||||
}
|
||||
}
|
||||
let mut affected = Vec::new();
|
||||
for (a, trip) in self.trips.active_agents_and_trips() {
|
||||
if let Some(path) = self.get_path(*a) {
|
||||
if path
|
||||
.get_steps()
|
||||
.iter()
|
||||
.any(|step| match step.as_traversable() {
|
||||
Traversable::Lane(l) => edited_lanes.contains(&l),
|
||||
Traversable::Turn(t) => closed_intersections.contains(&t.parent),
|
||||
})
|
||||
{
|
||||
affected.push((*a, *trip));
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn handle_live_edits(&mut self, map: &Map) {
|
||||
let affected = self.find_trips_affected_by_live_edits(map);
|
||||
|
||||
// V1: Just abort every trip crossing an affected area.
|
||||
// (V2 is probably rerouting everyone, only aborting when that fails)
|
||||
@ -902,12 +878,48 @@ impl Sim {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_live_edited_parking(&mut self, map: &Map) {
|
||||
self.walking.handle_live_edited_parking(
|
||||
self.parking
|
||||
.handle_map_updates(map, &mut Timer::throwaway()),
|
||||
&mut self.scheduler,
|
||||
);
|
||||
fn find_trips_affected_by_live_edits(&mut self, map: &Map) -> Vec<(AgentID, TripID)> {
|
||||
let mut affected: Vec<(AgentID, TripID)> = Vec::new();
|
||||
|
||||
// TODO Handle changes to access restrictions
|
||||
|
||||
{
|
||||
// Find every active trip whose path crosses a modified lane or closed intersection
|
||||
let (edited_lanes, _) = map.get_edits().changed_lanes(map);
|
||||
let mut closed_intersections = HashSet::new();
|
||||
for i in map.get_edits().original_intersections.keys() {
|
||||
if map.get_i(*i).is_closed() {
|
||||
closed_intersections.insert(*i);
|
||||
}
|
||||
}
|
||||
for (a, trip) in self.trips.active_agents_and_trips() {
|
||||
if let Some(path) = self.get_path(*a) {
|
||||
if path
|
||||
.get_steps()
|
||||
.iter()
|
||||
.any(|step| match step.as_traversable() {
|
||||
Traversable::Lane(l) => edited_lanes.contains(&l),
|
||||
Traversable::Turn(t) => closed_intersections.contains(&t.parent),
|
||||
})
|
||||
{
|
||||
affected.push((*a, *trip));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let evicted_cars = self.parking.handle_live_edits(map, &mut Timer::throwaway());
|
||||
affected.extend(self.walking.find_trips_to_parking(evicted_cars));
|
||||
|
||||
let (filled, avail) = self.parking.get_all_parking_spots();
|
||||
let mut all_spots: BTreeSet<ParkingSpot> = BTreeSet::new();
|
||||
all_spots.extend(filled);
|
||||
all_spots.extend(avail);
|
||||
affected.extend(self.driving.find_trips_to_edited_parking(all_spots));
|
||||
}
|
||||
|
||||
affected
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user