mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
Add a flag to use the infinite parking sim. Start to test for real...
This commit is contained in:
parent
a70fa0530a
commit
fcc05afda7
@ -22,7 +22,15 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingID
|
||||
}
|
||||
|
||||
let num_spots = b.num_parking_spots();
|
||||
if num_spots > 0 {
|
||||
if app.primary.sim.infinite_parking() {
|
||||
kv.push((
|
||||
"Parking",
|
||||
format!(
|
||||
"Unlimited, currently {} cars inside",
|
||||
app.primary.sim.bldg_to_parked_cars(b.id).len()
|
||||
),
|
||||
));
|
||||
} else if num_spots > 0 {
|
||||
let free = app.primary.sim.get_free_offstreet_spots(b.id).len();
|
||||
if let OffstreetParking::PublicGarage(ref n, _) = b.parking {
|
||||
kv.push((
|
||||
|
@ -54,6 +54,7 @@ impl SimFlags {
|
||||
.unwrap_or(AlertHandler::Print),
|
||||
pathfinding_upfront: args.enabled("--pathfinding_upfront"),
|
||||
live_map_edits: args.enabled("--live_map_edits"),
|
||||
infinite_parking: args.enabled("--infinite_parking"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -266,6 +266,14 @@ fn seed_parked_cars(
|
||||
base_rng: &mut XorShiftRng,
|
||||
timer: &mut Timer,
|
||||
) {
|
||||
if sim.infinite_parking() {
|
||||
for (vehicle, b) in parked_cars {
|
||||
let spot = sim.get_free_offstreet_spots(b)[0];
|
||||
sim.seed_parked_car(vehicle, spot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let mut open_spots_per_road: BTreeMap<RoadID, Vec<(ParkingSpot, Option<BuildingID>)>> =
|
||||
BTreeMap::new();
|
||||
for spot in sim.get_all_parking_spots().1 {
|
||||
|
@ -60,6 +60,7 @@ pub trait ParkingSim {
|
||||
) -> Option<(Vec<PathStep>, ParkingSpot, Position)>;
|
||||
fn collect_events(&mut self) -> Vec<Event>;
|
||||
fn all_parked_car_positions(&self, map: &Map) -> Vec<(Position, PersonID)>;
|
||||
fn bldg_to_parked_cars(&self, b: BuildingID) -> Vec<CarID>;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
@ -72,46 +73,19 @@ pub enum ParkingSimState {
|
||||
impl ParkingSimState {
|
||||
// Counterintuitive: any spots located in blackholes are just not represented here. If somebody
|
||||
// tries to drive from a blackholed spot, they couldn't reach most places.
|
||||
pub fn new(map: &Map, timer: &mut Timer) -> ParkingSimState {
|
||||
let mut sim = NormalParkingSimState {
|
||||
parked_cars: BTreeMap::new(),
|
||||
occupants: BTreeMap::new(),
|
||||
reserved_spots: BTreeSet::new(),
|
||||
pub fn new(map: &Map, infinite: bool, timer: &mut Timer) -> ParkingSimState {
|
||||
if infinite {
|
||||
ParkingSimState::Infinite(InfiniteParkingSimState::new(map))
|
||||
} else {
|
||||
ParkingSimState::Normal(NormalParkingSimState::new(map, timer))
|
||||
}
|
||||
}
|
||||
|
||||
onstreet_lanes: BTreeMap::new(),
|
||||
driving_to_parking_lanes: MultiMap::new(),
|
||||
num_spots_per_offstreet: BTreeMap::new(),
|
||||
driving_to_offstreet: MultiMap::new(),
|
||||
num_spots_per_lot: BTreeMap::new(),
|
||||
driving_to_lots: MultiMap::new(),
|
||||
|
||||
events: Vec::new(),
|
||||
};
|
||||
for l in map.all_lanes() {
|
||||
if let Some(lane) = ParkingLane::new(l, map, timer) {
|
||||
sim.driving_to_parking_lanes.insert(lane.driving_lane, l.id);
|
||||
sim.onstreet_lanes.insert(lane.parking_lane, lane);
|
||||
}
|
||||
pub fn is_infinite(&self) -> bool {
|
||||
match self {
|
||||
ParkingSimState::Normal(_) => false,
|
||||
ParkingSimState::Infinite(_) => true,
|
||||
}
|
||||
for b in map.all_buildings() {
|
||||
if let Some((pos, _)) = b.driving_connection(map) {
|
||||
if !map.get_l(pos.lane()).driving_blackhole {
|
||||
let num_spots = b.num_parking_spots();
|
||||
if num_spots > 0 {
|
||||
sim.num_spots_per_offstreet.insert(b.id, num_spots);
|
||||
sim.driving_to_offstreet
|
||||
.insert(pos.lane(), (b.id, pos.dist_along()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for pl in map.all_parking_lots() {
|
||||
if !map.get_l(pl.driving_pos.lane()).driving_blackhole {
|
||||
sim.num_spots_per_lot.insert(pl.id, pl.capacity());
|
||||
sim.driving_to_lots.insert(pl.driving_pos.lane(), pl.id);
|
||||
}
|
||||
}
|
||||
ParkingSimState::Normal(sim)
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,13 +132,55 @@ pub struct NormalParkingSimState {
|
||||
events: Vec<Event>,
|
||||
}
|
||||
|
||||
impl NormalParkingSimState {
|
||||
fn new(map: &Map, timer: &mut Timer) -> NormalParkingSimState {
|
||||
let mut sim = NormalParkingSimState {
|
||||
parked_cars: BTreeMap::new(),
|
||||
occupants: BTreeMap::new(),
|
||||
reserved_spots: BTreeSet::new(),
|
||||
|
||||
onstreet_lanes: BTreeMap::new(),
|
||||
driving_to_parking_lanes: MultiMap::new(),
|
||||
num_spots_per_offstreet: BTreeMap::new(),
|
||||
driving_to_offstreet: MultiMap::new(),
|
||||
num_spots_per_lot: BTreeMap::new(),
|
||||
driving_to_lots: MultiMap::new(),
|
||||
|
||||
events: Vec::new(),
|
||||
};
|
||||
for l in map.all_lanes() {
|
||||
if let Some(lane) = ParkingLane::new(l, map, timer) {
|
||||
sim.driving_to_parking_lanes.insert(lane.driving_lane, l.id);
|
||||
sim.onstreet_lanes.insert(lane.parking_lane, lane);
|
||||
}
|
||||
}
|
||||
for b in map.all_buildings() {
|
||||
if let Some((pos, _)) = b.driving_connection(map) {
|
||||
if !map.get_l(pos.lane()).driving_blackhole {
|
||||
let num_spots = b.num_parking_spots();
|
||||
if num_spots > 0 {
|
||||
sim.num_spots_per_offstreet.insert(b.id, num_spots);
|
||||
sim.driving_to_offstreet
|
||||
.insert(pos.lane(), (b.id, pos.dist_along()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for pl in map.all_parking_lots() {
|
||||
if !map.get_l(pl.driving_pos.lane()).driving_blackhole {
|
||||
sim.num_spots_per_lot.insert(pl.id, pl.capacity());
|
||||
sim.driving_to_lots.insert(pl.driving_pos.lane(), pl.id);
|
||||
}
|
||||
}
|
||||
|
||||
sim
|
||||
}
|
||||
}
|
||||
|
||||
impl ParkingSim for NormalParkingSimState {
|
||||
fn handle_live_edits(&mut self, map: &Map, timer: &mut Timer) -> Vec<ParkedCar> {
|
||||
let (filled_before, _) = self.get_all_parking_spots();
|
||||
let new = match ParkingSimState::new(map, timer) {
|
||||
ParkingSimState::Normal(sim) => sim,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let new = NormalParkingSimState::new(map, timer);
|
||||
let (_, avail_after) = new.get_all_parking_spots();
|
||||
let avail_after: BTreeSet<ParkingSpot> = avail_after.into_iter().collect();
|
||||
|
||||
@ -564,6 +580,17 @@ impl ParkingSim for NormalParkingSimState {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn bldg_to_parked_cars(&self, b: BuildingID) -> Vec<CarID> {
|
||||
let mut cars = Vec::new();
|
||||
for idx in 0..self.num_spots_per_offstreet.get(&b).cloned().unwrap_or(0) {
|
||||
let spot = ParkingSpot::Offstreet(b, idx);
|
||||
if let Some(car) = self.occupants.get(&spot) {
|
||||
cars.push(*car);
|
||||
}
|
||||
}
|
||||
cars
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
@ -653,6 +680,26 @@ pub struct InfiniteParkingSimState {
|
||||
}
|
||||
|
||||
impl InfiniteParkingSimState {
|
||||
fn new(map: &Map) -> InfiniteParkingSimState {
|
||||
let mut sim = InfiniteParkingSimState {
|
||||
parked_cars: BTreeMap::new(),
|
||||
occupants: BTreeMap::new(),
|
||||
|
||||
driving_to_offstreet: MultiMap::new(),
|
||||
|
||||
events: Vec::new(),
|
||||
};
|
||||
for b in map.all_buildings() {
|
||||
if let Some((pos, _)) = b.driving_connection(map) {
|
||||
if !map.get_l(pos.lane()).driving_blackhole {
|
||||
sim.driving_to_offstreet
|
||||
.insert(pos.lane(), (b.id, pos.dist_along()));
|
||||
}
|
||||
}
|
||||
}
|
||||
sim
|
||||
}
|
||||
|
||||
fn get_free_bldg_spot(&self, b: BuildingID) -> ParkingSpot {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
@ -666,12 +713,9 @@ impl InfiniteParkingSimState {
|
||||
}
|
||||
|
||||
impl ParkingSim for InfiniteParkingSimState {
|
||||
fn handle_live_edits(&mut self, map: &Map, timer: &mut Timer) -> Vec<ParkedCar> {
|
||||
fn handle_live_edits(&mut self, map: &Map, _: &mut Timer) -> Vec<ParkedCar> {
|
||||
// Can live edits possibly affect anything?
|
||||
let new = match ParkingSimState::new(map, timer) {
|
||||
ParkingSimState::Infinite(sim) => sim,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let new = InfiniteParkingSimState::new(map);
|
||||
self.driving_to_offstreet = new.driving_to_offstreet;
|
||||
|
||||
Vec::new()
|
||||
@ -682,8 +726,8 @@ impl ParkingSim for InfiniteParkingSimState {
|
||||
}
|
||||
|
||||
fn get_free_offstreet_spots(&self, b: BuildingID) -> Vec<ParkingSpot> {
|
||||
// TODO INFINITE. just return one or something?
|
||||
Vec::new()
|
||||
// Just returns the next free spot
|
||||
vec![self.get_free_bldg_spot(b)]
|
||||
}
|
||||
|
||||
fn get_free_lot_spots(&self, _: ParkingLotID) -> Vec<ParkingSpot> {
|
||||
@ -781,8 +825,7 @@ impl ParkingSim for InfiniteParkingSimState {
|
||||
}
|
||||
|
||||
fn get_all_parking_spots(&self) -> (Vec<ParkingSpot>, Vec<ParkingSpot>) {
|
||||
// TODO something very different
|
||||
(Vec::new(), Vec::new())
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn path_to_free_parking_spot(
|
||||
@ -811,4 +854,17 @@ impl ParkingSim for InfiniteParkingSimState {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn bldg_to_parked_cars(&self, b: BuildingID) -> Vec<CarID> {
|
||||
// TODO This is a very inefficient impl
|
||||
let mut cars = Vec::new();
|
||||
for (spot, car) in &self.occupants {
|
||||
if let ParkingSpot::Offstreet(bldg, _) = spot {
|
||||
if b == *bldg {
|
||||
cars.push(*car);
|
||||
}
|
||||
}
|
||||
}
|
||||
cars
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ pub struct SimOptions {
|
||||
pub alerts: AlertHandler,
|
||||
pub pathfinding_upfront: bool,
|
||||
pub live_map_edits: bool,
|
||||
pub infinite_parking: bool,
|
||||
}
|
||||
|
||||
impl std::default::Default for SimOptions {
|
||||
@ -111,6 +112,7 @@ impl SimOptions {
|
||||
alerts: AlertHandler::Print,
|
||||
pathfinding_upfront: false,
|
||||
live_map_edits: false,
|
||||
infinite_parking: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +123,7 @@ impl Sim {
|
||||
let mut scheduler = Scheduler::new();
|
||||
Sim {
|
||||
driving: DrivingSimState::new(map, opts.recalc_lanechanging, opts.handle_uber_turns),
|
||||
parking: ParkingSimState::new(map, timer),
|
||||
parking: ParkingSimState::new(map, opts.infinite_parking, timer),
|
||||
walking: WalkingSimState::new(),
|
||||
intersections: IntersectionSimState::new(
|
||||
map,
|
||||
@ -182,6 +184,10 @@ impl Sim {
|
||||
self.parking.get_all_parking_spots()
|
||||
}
|
||||
|
||||
pub fn bldg_to_parked_cars(&self, b: BuildingID) -> Vec<CarID> {
|
||||
self.parking.bldg_to_parked_cars(b)
|
||||
}
|
||||
|
||||
// Also returns the start distance of the building. TODO Do that in the Path properly.
|
||||
pub fn walking_path_to_nearest_parking_spot(
|
||||
&self,
|
||||
@ -919,11 +925,13 @@ impl Sim {
|
||||
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));
|
||||
if !self.parking.is_infinite() {
|
||||
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
|
||||
@ -1286,6 +1294,10 @@ impl Sim {
|
||||
pub fn get_cap_counter(&self, l: LaneID) -> usize {
|
||||
self.cap.get_cap_counter(l)
|
||||
}
|
||||
|
||||
pub fn infinite_parking(&self) -> bool {
|
||||
self.parking.is_infinite()
|
||||
}
|
||||
}
|
||||
|
||||
// Invasive debugging
|
||||
|
Loading…
Reference in New Issue
Block a user