mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-27 15:03:20 +03:00
revive the first parking test. make helpers to look up labeled stuff from synthetic maps. make helpers to seed specific parked cars and start certain trips again.
This commit is contained in:
parent
a9ff1906ad
commit
56c885e7ab
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "parking test",
|
"name": "parking_test",
|
||||||
"intersections": [
|
"intersections": [
|
||||||
[
|
[
|
||||||
0,
|
0,
|
@ -545,6 +545,39 @@ impl Map {
|
|||||||
let from = self.get_b(bldg).front_path.sidewalk;
|
let from = self.get_b(bldg).front_path.sidewalk;
|
||||||
self.find_closest_lane(from, types)
|
self.find_closest_lane(from, types)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO reconsider names, or put somewhere else?
|
||||||
|
pub fn bldg(&self, label: &str) -> BuildingID {
|
||||||
|
for b in &self.buildings {
|
||||||
|
if b.osm_tags.get("label") == Some(&label.to_string()) {
|
||||||
|
return b.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("No building has label {}", label);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parking_lane(&self, label: &str, expected_spots: usize) -> LaneID {
|
||||||
|
for l in &self.lanes {
|
||||||
|
if !l.is_parking() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let r = self.get_parent(l.id);
|
||||||
|
if (r.is_forwards(l.id) && r.osm_tags.get("fwd_label") == Some(&label.to_string()))
|
||||||
|
|| (r.is_backwards(l.id)
|
||||||
|
&& r.osm_tags.get("back_label") == Some(&label.to_string()))
|
||||||
|
{
|
||||||
|
let actual_spots = l.number_parking_spots();
|
||||||
|
if expected_spots != actual_spots {
|
||||||
|
panic!(
|
||||||
|
"Parking lane {} (labeled {}) has {} spots, not {}",
|
||||||
|
l.id, label, actual_spots, expected_spots
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return l.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("No parking lane has label {}", label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_border(intersection: &Intersection, map: &Map) -> bool {
|
fn is_border(intersection: &Intersection, map: &Map) -> bool {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use abstutil::WeightedUsizeChoice;
|
use abstutil::WeightedUsizeChoice;
|
||||||
use control::ControlMap;
|
use control::ControlMap;
|
||||||
use map_model::{BuildingID, BusRoute, Map, RoadID};
|
use driving::DrivingGoal;
|
||||||
|
use map_model::{BuildingID, BusRoute, LaneID, Map, RoadID};
|
||||||
use std::collections::{BTreeSet, VecDeque};
|
use std::collections::{BTreeSet, VecDeque};
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use {
|
use {
|
||||||
@ -155,6 +156,44 @@ impl Sim {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO This is for tests; rename or move it?
|
||||||
|
pub fn seed_specific_parked_cars(
|
||||||
|
&mut self,
|
||||||
|
lane: LaneID,
|
||||||
|
owner_building: BuildingID,
|
||||||
|
spots: Vec<usize>,
|
||||||
|
) -> Vec<CarID> {
|
||||||
|
self.spawner.seed_specific_parked_cars(
|
||||||
|
lane,
|
||||||
|
owner_building,
|
||||||
|
spots,
|
||||||
|
&mut self.parking_state,
|
||||||
|
&mut self.rng,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO This is for tests; rename or move it?
|
||||||
|
pub fn seed_trip_using_parked_car(
|
||||||
|
&mut self,
|
||||||
|
from_bldg: BuildingID,
|
||||||
|
to_bldg: BuildingID,
|
||||||
|
car: CarID,
|
||||||
|
map: &Map,
|
||||||
|
) {
|
||||||
|
self.spawner.start_trip_using_parked_car(
|
||||||
|
Tick::zero(),
|
||||||
|
map,
|
||||||
|
self.parking_state
|
||||||
|
.lookup_car(car)
|
||||||
|
.map(|p| p.clone())
|
||||||
|
.unwrap(),
|
||||||
|
&self.parking_state,
|
||||||
|
from_bldg,
|
||||||
|
DrivingGoal::ParkNear(to_bldg),
|
||||||
|
&mut self.trips_state,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn seed_bus_route(&mut self, route: &BusRoute, map: &Map) -> Vec<CarID> {
|
pub fn seed_bus_route(&mut self, route: &BusRoute, map: &Map) -> Vec<CarID> {
|
||||||
// TODO throw away the events? :(
|
// TODO throw away the events? :(
|
||||||
let mut events: Vec<Event> = Vec::new();
|
let mut events: Vec<Event> = Vec::new();
|
||||||
|
@ -24,9 +24,14 @@ pub struct SimFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SimFlags {
|
impl SimFlags {
|
||||||
|
// TODO rename seattle_test
|
||||||
pub fn for_test(run_name: &str) -> SimFlags {
|
pub fn for_test(run_name: &str) -> SimFlags {
|
||||||
|
SimFlags::synthetic_test("montlake", run_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn synthetic_test(map: &str, run_name: &str) -> SimFlags {
|
||||||
SimFlags {
|
SimFlags {
|
||||||
load: "../data/raw_maps/montlake.abst".to_string(),
|
load: format!("../data/raw_maps/{}.abst", map),
|
||||||
rng_seed: Some(42),
|
rng_seed: Some(42),
|
||||||
run_name: run_name.to_string(),
|
run_name: run_name.to_string(),
|
||||||
edits_name: "no_edits".to_string(),
|
edits_name: "no_edits".to_string(),
|
||||||
@ -105,8 +110,8 @@ pub fn load(
|
|||||||
.to_string();
|
.to_string();
|
||||||
info!("Loading map {}", flags.load);
|
info!("Loading map {}", flags.load);
|
||||||
let edits = load_edits(&map_name, &flags);
|
let edits = load_edits(&map_name, &flags);
|
||||||
let map =
|
let map = Map::new(&flags.load, edits.road_edits.clone(), timer)
|
||||||
Map::new(&flags.load, edits.road_edits.clone(), timer).expect("Couldn't load map");
|
.expect(&format!("Couldn't load map from {}", flags.load));
|
||||||
let control_map = ControlMap::new(&map, edits.stop_signs, edits.traffic_signals);
|
let control_map = ControlMap::new(&map, edits.stop_signs, edits.traffic_signals);
|
||||||
timer.start("create sim");
|
timer.start("create sim");
|
||||||
let sim = Sim::new(&map, flags.run_name, flags.rng_seed, savestate_every);
|
let sim = Sim::new(&map, flags.run_name, flags.rng_seed, savestate_every);
|
||||||
@ -116,7 +121,8 @@ pub fn load(
|
|||||||
assert_eq!(flags.edits_name, "no_edits");
|
assert_eq!(flags.edits_name, "no_edits");
|
||||||
|
|
||||||
info!("Loading map {}", flags.load);
|
info!("Loading map {}", flags.load);
|
||||||
let map: Map = abstutil::read_binary(&flags.load, timer).expect("Couldn't load map");
|
let map: Map = abstutil::read_binary(&flags.load, timer)
|
||||||
|
.expect(&format!("Couldn't load map from {}", flags.load));
|
||||||
// TODO Bit sad to load edits to reconstitute ControlMap, but this is necessary right now
|
// TODO Bit sad to load edits to reconstitute ControlMap, but this is necessary right now
|
||||||
let edits: MapEdits = abstutil::read_json(&format!(
|
let edits: MapEdits = abstutil::read_json(&format!(
|
||||||
"../data/edits/{}/{}.json",
|
"../data/edits/{}/{}.json",
|
||||||
|
@ -339,6 +339,32 @@ impl Spawner {
|
|||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This happens immediately; it isn't scheduled.
|
||||||
|
// TODO This is for tests; rename or move it?
|
||||||
|
// TODO duplication of code, weird responsibilities here...
|
||||||
|
pub fn seed_specific_parked_cars(
|
||||||
|
&mut self,
|
||||||
|
lane: LaneID,
|
||||||
|
owner_building: BuildingID,
|
||||||
|
spots: Vec<usize>,
|
||||||
|
parking_sim: &mut ParkingSimState,
|
||||||
|
base_rng: &mut XorShiftRng,
|
||||||
|
) -> Vec<CarID> {
|
||||||
|
let mut results: Vec<CarID> = Vec::new();
|
||||||
|
for idx in spots.into_iter() {
|
||||||
|
let car = CarID(self.car_id_counter);
|
||||||
|
parking_sim.add_parked_car(ParkedCar::new(
|
||||||
|
car,
|
||||||
|
ParkingSpot::new(lane, idx),
|
||||||
|
Vehicle::generate_car(car, base_rng),
|
||||||
|
Some(owner_building),
|
||||||
|
));
|
||||||
|
self.car_id_counter += 1;
|
||||||
|
results.push(car);
|
||||||
|
}
|
||||||
|
results
|
||||||
|
}
|
||||||
|
|
||||||
// This happens immediately; it isn't scheduled.
|
// This happens immediately; it isn't scheduled.
|
||||||
pub fn seed_parked_cars(
|
pub fn seed_parked_cars(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -458,6 +484,8 @@ impl Spawner {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_eq!(parked.owner, Some(start_bldg));
|
||||||
|
|
||||||
let ped_id = PedestrianID(self.ped_id_counter);
|
let ped_id = PedestrianID(self.ped_id_counter);
|
||||||
self.ped_id_counter += 1;
|
self.ped_id_counter += 1;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ convert_osm = { path = "../convert_osm" }
|
|||||||
dimensioned = { git = "https://github.com/paholg/dimensioned", rev = "0e1076ebfa5128d1ee544bdc9754c948987b6fe3", features = ["serde"] }
|
dimensioned = { git = "https://github.com/paholg/dimensioned", rev = "0e1076ebfa5128d1ee544bdc9754c948987b6fe3", features = ["serde"] }
|
||||||
gag = "0.1.10"
|
gag = "0.1.10"
|
||||||
geom = { path = "../geom" }
|
geom = { path = "../geom" }
|
||||||
|
map_model = { path = "../map_model" }
|
||||||
sim = { path = "../sim" }
|
sim = { path = "../sim" }
|
||||||
structopt = "0.2"
|
structopt = "0.2"
|
||||||
yansi = "0.4.0"
|
yansi = "0.4.0"
|
||||||
|
@ -3,6 +3,7 @@ extern crate convert_osm;
|
|||||||
extern crate dimensioned;
|
extern crate dimensioned;
|
||||||
extern crate gag;
|
extern crate gag;
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
|
extern crate map_model;
|
||||||
extern crate sim;
|
extern crate sim;
|
||||||
extern crate structopt;
|
extern crate structopt;
|
||||||
extern crate yansi;
|
extern crate yansi;
|
||||||
|
@ -1,33 +1,45 @@
|
|||||||
|
use abstutil::Timer;
|
||||||
use runner::TestRunner;
|
use runner::TestRunner;
|
||||||
|
use sim;
|
||||||
|
|
||||||
pub fn run(_t: &mut TestRunner) {}
|
pub fn run(t: &mut TestRunner) {
|
||||||
|
t.run_slow(
|
||||||
|
"park_on_goal_st",
|
||||||
|
Box::new(|h| {
|
||||||
|
let (map, control_map, mut sim) = sim::load(
|
||||||
|
sim::SimFlags::synthetic_test("parking_test", "park_on_goal_st"),
|
||||||
|
None,
|
||||||
|
&mut Timer::new("setup test"),
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
let north_bldg = map.bldg("north");
|
||||||
#[test]
|
let south_bldg = map.bldg("south");
|
||||||
fn park_on_goal_st() {
|
let north_parking = map.parking_lane("north", 18);
|
||||||
let (map, control_map, mut sim) = setup("park_on_goal_st", make_test_map());
|
let south_parking = map.parking_lane("south", 18);
|
||||||
let (south_parking, north_parking) = (LaneID(1), LaneID(4));
|
|
||||||
let (north_bldg, south_bldg) = (BuildingID(0), BuildingID(1));
|
|
||||||
|
|
||||||
assert_eq!(map.get_l(south_parking).number_parking_spots(), 8);
|
let car = sim.seed_specific_parked_cars(south_parking, south_bldg, vec![2])[0];
|
||||||
assert_eq!(map.get_l(north_parking).number_parking_spots(), 8);
|
// Fill up some of the first spots, forcing parking to happen at spot 4
|
||||||
let car = sim.seed_specific_parked_cars(south_parking, south_bldg, (0..8).collect())[2];
|
sim.seed_specific_parked_cars(north_parking, north_bldg, (0..4).collect());
|
||||||
sim.seed_specific_parked_cars(north_parking, north_bldg, (0..4).collect());
|
sim.seed_specific_parked_cars(north_parking, north_bldg, (5..10).collect());
|
||||||
sim.seed_specific_parked_cars(north_parking, north_bldg, (5..8).collect());
|
// TODO I just want to say (south_bldg, north_bldg), not mode...
|
||||||
sim.make_ped_using_car(&map, car, north_bldg);
|
sim.seed_trip_using_parked_car(south_bldg, north_bldg, car, &map);
|
||||||
|
h.setup_done(&sim);
|
||||||
|
|
||||||
sim.run_until_expectations_met(
|
sim.run_until_expectations_met(
|
||||||
&map,
|
&map,
|
||||||
&control_map,
|
&control_map,
|
||||||
vec![sim::Event::CarReachedParkingSpot(
|
vec![sim::Event::CarReachedParkingSpot(
|
||||||
car,
|
car,
|
||||||
sim::ParkingSpot::new(north_parking, 4),
|
sim::ParkingSpot::new(north_parking, 4),
|
||||||
)],
|
)],
|
||||||
sim::Tick::from_minutes(1),
|
sim::Tick::from_minutes(2),
|
||||||
|
);
|
||||||
|
sim.run_until_done(&map, &control_map, Box::new(|_sim| {}));
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
sim.run_until_done(&map, &control_map, Box::new(|_sim| {}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn wander_around_for_parking() {
|
fn wander_around_for_parking() {
|
||||||
let (map, control_map, mut sim) = setup("wander_around_for_parking", make_test_map());
|
let (map, control_map, mut sim) = setup("wander_around_for_parking", make_test_map());
|
||||||
@ -53,93 +65,4 @@ fn wander_around_for_parking() {
|
|||||||
);
|
);
|
||||||
sim.run_until_done(&map, &control_map, Box::new(|_sim| {}));
|
sim.run_until_done(&map, &control_map, Box::new(|_sim| {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(run_name: &str, map: map_model::Map) -> (map_model::Map, control::ControlMap, sim::Sim) {
|
|
||||||
let rng_seed = 123;
|
|
||||||
let control_map = control::ControlMap::new(&map, BTreeMap::new(), BTreeMap::new());
|
|
||||||
let sim = sim::Sim::new(&map, run_name.to_string(), Some(rng_seed), None);
|
|
||||||
(map, control_map, sim)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a test map with a single two-way road
|
|
||||||
fn make_test_map() -> map_model::Map {
|
|
||||||
use dimensioned::si;
|
|
||||||
use map_model::{raw_data, LaneType};
|
|
||||||
|
|
||||||
let left = geom::LonLat::new(100.0, 50.0);
|
|
||||||
let right = geom::LonLat::new(200.0, 50.0);
|
|
||||||
|
|
||||||
let north_pts = triangle_around(150.0, 10.0);
|
|
||||||
let south_pts = triangle_around(150.0, 90.0);
|
|
||||||
|
|
||||||
let map = map_model::Map::create_from_raw(
|
|
||||||
"test_map".to_string(),
|
|
||||||
raw_data::Map {
|
|
||||||
roads: vec![raw_data::Road {
|
|
||||||
points: vec![left, right],
|
|
||||||
osm_tags: BTreeMap::new(),
|
|
||||||
osm_way_id: 123,
|
|
||||||
}],
|
|
||||||
intersections: vec![
|
|
||||||
raw_data::Intersection {
|
|
||||||
point: left,
|
|
||||||
elevation: 0.0 * si::M,
|
|
||||||
has_traffic_signal: false,
|
|
||||||
},
|
|
||||||
raw_data::Intersection {
|
|
||||||
point: right,
|
|
||||||
elevation: 0.0 * si::M,
|
|
||||||
has_traffic_signal: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
buildings: vec![
|
|
||||||
raw_data::Building {
|
|
||||||
points: north_pts,
|
|
||||||
osm_tags: BTreeMap::new(),
|
|
||||||
osm_way_id: 456,
|
|
||||||
},
|
|
||||||
raw_data::Building {
|
|
||||||
points: south_pts,
|
|
||||||
osm_tags: BTreeMap::new(),
|
|
||||||
osm_way_id: 789,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
parcels: Vec::new(),
|
|
||||||
bus_routes: Vec::new(),
|
|
||||||
areas: Vec::new(),
|
|
||||||
coordinates_in_world_space: true,
|
|
||||||
},
|
|
||||||
map_model::RoadEdits::new(),
|
|
||||||
&mut abstutil::Timer::new("setup test"),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(map.all_roads().len(), 1);
|
|
||||||
// The south side, unless I'm backwards ><
|
|
||||||
assert_eq!(
|
|
||||||
map.get_r(map_model::RoadID(0)).children_forwards,
|
|
||||||
vec![
|
|
||||||
(LaneID(0), LaneType::Driving),
|
|
||||||
(LaneID(1), LaneType::Parking),
|
|
||||||
(LaneID(2), LaneType::Sidewalk),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
// The north side
|
|
||||||
assert_eq!(
|
|
||||||
map.get_r(map_model::RoadID(0)).children_backwards,
|
|
||||||
vec![
|
|
||||||
(LaneID(3), LaneType::Driving),
|
|
||||||
(LaneID(4), LaneType::Parking),
|
|
||||||
(LaneID(5), LaneType::Sidewalk),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
map
|
|
||||||
}
|
|
||||||
|
|
||||||
fn triangle_around(x: f64, y: f64) -> Vec<geom::LonLat> {
|
|
||||||
vec![
|
|
||||||
geom::LonLat::new(x - 5.0, y - 5.0),
|
|
||||||
geom::LonLat::new(x + 5.0, y - 5.0),
|
|
||||||
geom::LonLat::new(x, y + 5.0),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user