mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
filter out parking lanes without any sidewalks at all nearby (and also
warn about them)
This commit is contained in:
parent
9cfd22d5e0
commit
75e155fec6
@ -6,6 +6,7 @@ use crate::debug::DebugMode;
|
|||||||
use crate::game::{State, Transition};
|
use crate::game::{State, Transition};
|
||||||
use crate::render::MIN_ZOOM_FOR_DETAIL;
|
use crate::render::MIN_ZOOM_FOR_DETAIL;
|
||||||
use crate::ui::{PerMapUI, UI};
|
use crate::ui::{PerMapUI, UI};
|
||||||
|
use abstutil::Timer;
|
||||||
use ezgui::{
|
use ezgui::{
|
||||||
hotkey, lctrl, Color, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, Line, ModalMenu, Text,
|
hotkey, lctrl, Color, EventCtx, EventLoopMode, GeomBatch, GfxCtx, Key, Line, ModalMenu, Text,
|
||||||
};
|
};
|
||||||
@ -268,12 +269,12 @@ impl ABTestMode {
|
|||||||
primary_map: std::mem::replace(&mut ui.primary.map, Map::blank()),
|
primary_map: std::mem::replace(&mut ui.primary.map, Map::blank()),
|
||||||
primary_sim: std::mem::replace(
|
primary_sim: std::mem::replace(
|
||||||
&mut ui.primary.sim,
|
&mut ui.primary.sim,
|
||||||
Sim::new(&blank_map, SimOptions::new("tmp")),
|
Sim::new(&blank_map, SimOptions::new("tmp"), &mut Timer::throwaway()),
|
||||||
),
|
),
|
||||||
secondary_map: std::mem::replace(&mut secondary.map, Map::blank()),
|
secondary_map: std::mem::replace(&mut secondary.map, Map::blank()),
|
||||||
secondary_sim: std::mem::replace(
|
secondary_sim: std::mem::replace(
|
||||||
&mut secondary.sim,
|
&mut secondary.sim,
|
||||||
Sim::new(&blank_map, SimOptions::new("tmp")),
|
Sim::new(&blank_map, SimOptions::new("tmp"), &mut Timer::throwaway()),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -470,6 +470,10 @@ impl PerMapUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_sim(&mut self) {
|
pub fn reset_sim(&mut self) {
|
||||||
self.sim = Sim::new(&self.map, self.current_flags.sim_flags.opts.clone());
|
self.sim = Sim::new(
|
||||||
|
&self.map,
|
||||||
|
self.current_flags.sim_flags.opts.clone(),
|
||||||
|
&mut Timer::new("reset simulation"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,9 +126,10 @@ impl RawMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let remap_pts = !self.gps_bounds.approx_eq(&fixes.gps_bounds);
|
||||||
|
|
||||||
for mut i in fixes.add_intersections.clone() {
|
for mut i in fixes.add_intersections.clone() {
|
||||||
// Fix up the geometry, maybe.
|
if remap_pts {
|
||||||
if !self.gps_bounds.approx_eq(&fixes.gps_bounds) {
|
|
||||||
i.point = Pt2D::forcibly_from_gps(
|
i.point = Pt2D::forcibly_from_gps(
|
||||||
i.point.to_gps(&fixes.gps_bounds).unwrap(),
|
i.point.to_gps(&fixes.gps_bounds).unwrap(),
|
||||||
&self.gps_bounds,
|
&self.gps_bounds,
|
||||||
@ -143,8 +144,7 @@ impl RawMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for mut r in fixes.add_roads.clone() {
|
for mut r in fixes.add_roads.clone() {
|
||||||
// Fix up the geometry, maybe.
|
if remap_pts {
|
||||||
if !self.gps_bounds.approx_eq(&fixes.gps_bounds) {
|
|
||||||
r.center_points = self
|
r.center_points = self
|
||||||
.gps_bounds
|
.gps_bounds
|
||||||
.forcibly_convert(&fixes.gps_bounds.must_convert_back(&r.center_points));
|
.forcibly_convert(&fixes.gps_bounds.must_convert_back(&r.center_points));
|
||||||
|
@ -92,7 +92,7 @@ impl SimFlags {
|
|||||||
if opts.run_name == "unnamed" {
|
if opts.run_name == "unnamed" {
|
||||||
opts.run_name = scenario.scenario_name.clone();
|
opts.run_name = scenario.scenario_name.clone();
|
||||||
}
|
}
|
||||||
let mut sim = Sim::new(&map, opts);
|
let mut sim = Sim::new(&map, opts, timer);
|
||||||
scenario.instantiate(&mut sim, &map, &mut rng, timer);
|
scenario.instantiate(&mut sim, &map, &mut rng, timer);
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
@ -103,7 +103,7 @@ impl SimFlags {
|
|||||||
.expect(&format!("Couldn't load map from {}", self.load));
|
.expect(&format!("Couldn't load map from {}", self.load));
|
||||||
|
|
||||||
timer.start("create sim");
|
timer.start("create sim");
|
||||||
let sim = Sim::new(&map, opts);
|
let sim = Sim::new(&map, opts, timer);
|
||||||
timer.stop("create sim");
|
timer.stop("create sim");
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
@ -114,7 +114,7 @@ impl SimFlags {
|
|||||||
.expect(&format!("Couldn't load map from {}", self.load));
|
.expect(&format!("Couldn't load map from {}", self.load));
|
||||||
|
|
||||||
timer.start("create sim");
|
timer.start("create sim");
|
||||||
let sim = Sim::new(&map, opts);
|
let sim = Sim::new(&map, opts, timer);
|
||||||
timer.stop("create sim");
|
timer.stop("create sim");
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::{AgentMetadata, CarID, CarStatus, DrawCarInput, ParkedCar, ParkingSpot, Vehicle};
|
use crate::{AgentMetadata, CarID, CarStatus, DrawCarInput, ParkedCar, ParkingSpot, Vehicle};
|
||||||
use abstutil::{
|
use abstutil::{
|
||||||
deserialize_btreemap, deserialize_multimap, serialize_btreemap, serialize_multimap, MultiMap,
|
deserialize_btreemap, deserialize_multimap, serialize_btreemap, serialize_multimap, MultiMap,
|
||||||
|
Timer,
|
||||||
};
|
};
|
||||||
use geom::{Distance, Duration, Pt2D};
|
use geom::{Distance, Duration, Pt2D};
|
||||||
use map_model;
|
use map_model;
|
||||||
@ -49,7 +50,7 @@ pub struct ParkingSimState {
|
|||||||
impl ParkingSimState {
|
impl ParkingSimState {
|
||||||
// Counterintuitive: any spots located in blackholes are just not represented here. If somebody
|
// 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.
|
// tries to drive from a blackholed spot, they couldn't reach most places.
|
||||||
pub fn new(map: &Map) -> ParkingSimState {
|
pub fn new(map: &Map, timer: &mut Timer) -> ParkingSimState {
|
||||||
let mut sim = ParkingSimState {
|
let mut sim = ParkingSimState {
|
||||||
parked_cars: BTreeMap::new(),
|
parked_cars: BTreeMap::new(),
|
||||||
occupants: BTreeMap::new(),
|
occupants: BTreeMap::new(),
|
||||||
@ -63,7 +64,7 @@ impl ParkingSimState {
|
|||||||
driving_to_offstreet: MultiMap::new(),
|
driving_to_offstreet: MultiMap::new(),
|
||||||
};
|
};
|
||||||
for l in map.all_lanes() {
|
for l in map.all_lanes() {
|
||||||
if let Some(lane) = ParkingLane::new(l, map) {
|
if let Some(lane) = ParkingLane::new(l, map, timer) {
|
||||||
sim.driving_to_parking_lanes.insert(lane.driving_lane, l.id);
|
sim.driving_to_parking_lanes.insert(lane.driving_lane, l.id);
|
||||||
sim.onstreet_lanes.insert(lane.parking_lane, lane);
|
sim.onstreet_lanes.insert(lane.parking_lane, lane);
|
||||||
}
|
}
|
||||||
@ -284,15 +285,13 @@ impl ParkingSimState {
|
|||||||
pub fn spot_to_sidewalk_pos(&self, spot: ParkingSpot, map: &Map) -> Position {
|
pub fn spot_to_sidewalk_pos(&self, spot: ParkingSpot, map: &Map) -> Position {
|
||||||
match spot {
|
match spot {
|
||||||
ParkingSpot::Onstreet(l, idx) => {
|
ParkingSpot::Onstreet(l, idx) => {
|
||||||
// TODO Consider precomputing this.
|
let lane = &self.onstreet_lanes[&l];
|
||||||
let sidewalk = map.find_closest_lane(l, vec![LaneType::Sidewalk]).unwrap();
|
|
||||||
// Always centered in the entire parking spot
|
// Always centered in the entire parking spot
|
||||||
Position::new(
|
Position::new(
|
||||||
l,
|
l,
|
||||||
self.onstreet_lanes[&l].spot_dist_along[idx]
|
lane.spot_dist_along[idx] - (map_model::PARKING_SPOT_LENGTH / 2.0),
|
||||||
- (map_model::PARKING_SPOT_LENGTH / 2.0),
|
|
||||||
)
|
)
|
||||||
.equiv_pos(sidewalk, Distance::ZERO, map)
|
.equiv_pos(lane.sidewalk, Distance::ZERO, map)
|
||||||
}
|
}
|
||||||
ParkingSpot::Offstreet(b, _) => map.get_b(b).front_path.sidewalk,
|
ParkingSpot::Offstreet(b, _) => map.get_b(b).front_path.sidewalk,
|
||||||
}
|
}
|
||||||
@ -359,29 +358,38 @@ impl ParkingSimState {
|
|||||||
struct ParkingLane {
|
struct ParkingLane {
|
||||||
parking_lane: LaneID,
|
parking_lane: LaneID,
|
||||||
driving_lane: LaneID,
|
driving_lane: LaneID,
|
||||||
|
sidewalk: LaneID,
|
||||||
// The front of the parking spot (farthest along the lane)
|
// The front of the parking spot (farthest along the lane)
|
||||||
spot_dist_along: Vec<Distance>,
|
spot_dist_along: Vec<Distance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParkingLane {
|
impl ParkingLane {
|
||||||
fn new(l: &Lane, map: &Map) -> Option<ParkingLane> {
|
fn new(lane: &Lane, map: &Map, timer: &mut Timer) -> Option<ParkingLane> {
|
||||||
if l.lane_type != LaneType::Parking {
|
if lane.lane_type != LaneType::Parking {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let driving_lane = if let Some(l) = map.get_parent(l.id).parking_to_driving(l.id) {
|
let driving_lane = if let Some(l) = map.get_parent(lane.id).parking_to_driving(lane.id) {
|
||||||
l
|
l
|
||||||
} else {
|
} else {
|
||||||
panic!("Parking lane {} has no driving lane!", l.id);
|
// Serious enough to blow up loudly.
|
||||||
|
panic!("Parking lane {} has no driving lane!", lane.id);
|
||||||
};
|
};
|
||||||
if map.get_l(driving_lane).parking_blackhole.is_some() {
|
if map.get_l(driving_lane).parking_blackhole.is_some() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
let sidewalk = if let Ok(l) = map.find_closest_lane(lane.id, vec![LaneType::Sidewalk]) {
|
||||||
|
l
|
||||||
|
} else {
|
||||||
|
timer.warn(format!("Parking lane {} has no sidewalk!", lane.id));
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
Some(ParkingLane {
|
Some(ParkingLane {
|
||||||
parking_lane: l.id,
|
parking_lane: lane.id,
|
||||||
driving_lane,
|
driving_lane,
|
||||||
spot_dist_along: (0..l.number_parking_spots())
|
sidewalk,
|
||||||
|
spot_dist_along: (0..lane.number_parking_spots())
|
||||||
.map(|idx| map_model::PARKING_SPOT_LENGTH * (2.0 + idx as f64))
|
.map(|idx| map_model::PARKING_SPOT_LENGTH * (2.0 + idx as f64))
|
||||||
.collect(),
|
.collect(),
|
||||||
})
|
})
|
||||||
|
@ -81,7 +81,7 @@ impl SimOptions {
|
|||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
impl Sim {
|
impl Sim {
|
||||||
pub fn new(map: &Map, opts: SimOptions) -> Sim {
|
pub fn new(map: &Map, opts: SimOptions, timer: &mut Timer) -> Sim {
|
||||||
let mut scheduler = Scheduler::new();
|
let mut scheduler = Scheduler::new();
|
||||||
// TODO Gridlock detection doesn't add value right now.
|
// TODO Gridlock detection doesn't add value right now.
|
||||||
if false {
|
if false {
|
||||||
@ -92,7 +92,7 @@ impl Sim {
|
|||||||
}
|
}
|
||||||
Sim {
|
Sim {
|
||||||
driving: DrivingSimState::new(map, opts.recalc_lanechanging),
|
driving: DrivingSimState::new(map, opts.recalc_lanechanging),
|
||||||
parking: ParkingSimState::new(map),
|
parking: ParkingSimState::new(map, timer),
|
||||||
walking: WalkingSimState::new(),
|
walking: WalkingSimState::new(),
|
||||||
intersections: IntersectionSimState::new(
|
intersections: IntersectionSimState::new(
|
||||||
map,
|
map,
|
||||||
|
@ -19,7 +19,11 @@ pub fn run(t: &mut TestRunner) {
|
|||||||
println!("Creating two simulations");
|
println!("Creating two simulations");
|
||||||
let flags = SimFlags::for_test("from_scratch_1");
|
let flags = SimFlags::for_test("from_scratch_1");
|
||||||
let (map, mut sim1, _) = flags.load(&mut Timer::throwaway());
|
let (map, mut sim1, _) = flags.load(&mut Timer::throwaway());
|
||||||
let mut sim2 = Sim::new(&map, SimOptions::new("from_scratch_2"));
|
let mut sim2 = Sim::new(
|
||||||
|
&map,
|
||||||
|
SimOptions::new("from_scratch_2"),
|
||||||
|
&mut Timer::throwaway(),
|
||||||
|
);
|
||||||
Scenario::small_run(&map).instantiate(
|
Scenario::small_run(&map).instantiate(
|
||||||
&mut sim1,
|
&mut sim1,
|
||||||
&map,
|
&map,
|
||||||
@ -52,7 +56,11 @@ pub fn run(t: &mut TestRunner) {
|
|||||||
println!("Creating two simulations");
|
println!("Creating two simulations");
|
||||||
let flags = SimFlags::for_test("with_savestating_1");
|
let flags = SimFlags::for_test("with_savestating_1");
|
||||||
let (map, mut sim1, _) = flags.load(&mut Timer::throwaway());
|
let (map, mut sim1, _) = flags.load(&mut Timer::throwaway());
|
||||||
let mut sim2 = Sim::new(&map, SimOptions::new("with_savestating_2"));
|
let mut sim2 = Sim::new(
|
||||||
|
&map,
|
||||||
|
SimOptions::new("with_savestating_2"),
|
||||||
|
&mut Timer::throwaway(),
|
||||||
|
);
|
||||||
Scenario::small_run(&map).instantiate(
|
Scenario::small_run(&map).instantiate(
|
||||||
&mut sim1,
|
&mut sim1,
|
||||||
&map,
|
&map,
|
||||||
|
Loading…
Reference in New Issue
Block a user