filter out parking lanes without any sidewalks at all nearby (and also

warn about them)
This commit is contained in:
Dustin Carlino 2019-10-26 17:53:09 -07:00
parent 9cfd22d5e0
commit 75e155fec6
7 changed files with 48 additions and 27 deletions

View File

@ -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()),
), ),
}; };

View File

@ -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"),
);
} }
} }

View File

@ -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));

View File

@ -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)

View File

@ -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(),
}) })

View File

@ -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,

View File

@ -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,