mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 03:41:09 +03:00
bundling all map edits together
This commit is contained in:
parent
bbfe00ce63
commit
7b718b4621
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,7 +3,7 @@
|
||||
*.swp
|
||||
|
||||
editor/editor_state
|
||||
editor/road_edits.json
|
||||
editor/map_edits.json
|
||||
|
||||
data/input/*
|
||||
data/maps/*.abst
|
||||
|
@ -22,7 +22,11 @@ pub struct ControlMap {
|
||||
}
|
||||
|
||||
impl ControlMap {
|
||||
pub fn new(map: &Map) -> ControlMap {
|
||||
pub fn new(
|
||||
map: &Map,
|
||||
stop_signs: &BTreeMap<IntersectionID, ModifiedStopSign>,
|
||||
traffic_signals: &BTreeMap<IntersectionID, ModifiedTrafficSignal>,
|
||||
) -> ControlMap {
|
||||
let mut ctrl = ControlMap {
|
||||
traffic_signals: HashMap::new(),
|
||||
stop_signs: HashMap::new(),
|
||||
@ -38,11 +42,18 @@ impl ControlMap {
|
||||
}
|
||||
}
|
||||
|
||||
for (i, s) in traffic_signals {
|
||||
ctrl.traffic_signals.get_mut(i).unwrap().load_savestate(s);
|
||||
}
|
||||
for (i, s) in stop_signs {
|
||||
ctrl.stop_signs.get_mut(i).unwrap().load_savestate(s);
|
||||
}
|
||||
|
||||
ctrl
|
||||
}
|
||||
|
||||
pub fn get_traffic_signals_savestate(&self) -> HashMap<IntersectionID, ModifiedTrafficSignal> {
|
||||
let mut h = HashMap::new();
|
||||
pub fn get_traffic_signals_savestate(&self) -> BTreeMap<IntersectionID, ModifiedTrafficSignal> {
|
||||
let mut h = BTreeMap::new();
|
||||
for (i, s) in &self.traffic_signals {
|
||||
if let Some(state) = s.get_savestate() {
|
||||
h.insert(*i, state);
|
||||
@ -51,8 +62,8 @@ impl ControlMap {
|
||||
h
|
||||
}
|
||||
|
||||
pub fn get_stop_signs_savestate(&self) -> HashMap<IntersectionID, ModifiedStopSign> {
|
||||
let mut h = HashMap::new();
|
||||
pub fn get_stop_signs_savestate(&self) -> BTreeMap<IntersectionID, ModifiedStopSign> {
|
||||
let mut h = BTreeMap::new();
|
||||
for (i, s) in &self.stop_signs {
|
||||
if let Some(state) = s.get_savestate() {
|
||||
h.insert(*i, state);
|
||||
@ -60,19 +71,6 @@ impl ControlMap {
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
pub fn load_savestate(
|
||||
&mut self,
|
||||
traffic_signals: &HashMap<IntersectionID, ModifiedTrafficSignal>,
|
||||
stop_signs: &HashMap<IntersectionID, ModifiedStopSign>,
|
||||
) {
|
||||
for (i, s) in traffic_signals {
|
||||
self.traffic_signals.get_mut(i).unwrap().load_savestate(s);
|
||||
}
|
||||
for (i, s) in stop_signs {
|
||||
self.stop_signs.get_mut(i).unwrap().load_savestate(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// General problem: TurnIDs change as code does. Serialized state is kinda tied to code version.
|
||||
|
@ -257,3 +257,23 @@ current TreeMenu:
|
||||
|
||||
|
||||
Back up and think about ideal for these background controls...
|
||||
|
||||
## Managing different map edits
|
||||
|
||||
Should be simple -- I want to bundle together map edits as named things, to
|
||||
prep for A/B tests. But loading a different set of edits could be kind of
|
||||
tough...
|
||||
|
||||
- new control map state has to propagate to intersection editors.
|
||||
- easy fix: pass them mut ref from control map every tick. then just have to reload control map.
|
||||
- road edits have to propogate
|
||||
- theres a way to do that live right now, but it's kind of brittle and funky. probably safer to load from scratch.
|
||||
- but then have to reload things like steepness visualizer plugin... actually, just that, seemingly.
|
||||
- er, but also the hider plugin -- it holds onto laneIDs, which may change!
|
||||
|
||||
Alright, I think this is the sequence of things to do:
|
||||
|
||||
1) make a few plugins less stateful anyway, by taking refs to map/control map stuff instead of caching stuff. thats useful regardless.
|
||||
- but wait, then road editor kind of cant work, because mut borrow edits from map while holding immutable lane/road refs. theyre really indep things, so cant store together.
|
||||
2) make it possible to completely reload UI and everything from scratch, from a plugin. rationale: it'd be nice to switch maps from inside the editor anyway. not necessary, but useful.
|
||||
3) make road edits propogate correctly, and somehow have a strategy for ensuring nothing is forgotten. impl today is VERY incomplete.
|
||||
|
@ -1,20 +1,23 @@
|
||||
use control::ControlMap;
|
||||
use ezgui::UserInput;
|
||||
use map_model::{EditReason, Edits, LaneID, LaneType, Map};
|
||||
use map_model::{EditReason, LaneID, LaneType, Map, RoadEdits};
|
||||
use objects::{EDIT_MAP, ID};
|
||||
use piston::input::Key;
|
||||
use plugins::Colorizer;
|
||||
use render::DrawMap;
|
||||
use sim::Sim;
|
||||
|
||||
pub enum RoadEditor {
|
||||
Inactive(Edits),
|
||||
Active(Edits),
|
||||
pub struct RoadEditor {
|
||||
edits: RoadEdits,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
impl RoadEditor {
|
||||
pub fn new(edits: Edits) -> RoadEditor {
|
||||
RoadEditor::Inactive(edits)
|
||||
pub fn new(edits: RoadEdits) -> RoadEditor {
|
||||
RoadEditor {
|
||||
edits,
|
||||
active: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event(
|
||||
@ -26,63 +29,60 @@ impl RoadEditor {
|
||||
control_map: &ControlMap,
|
||||
sim: &mut Sim,
|
||||
) -> bool {
|
||||
let mut new_state: Option<RoadEditor> = None;
|
||||
// TODO a bit awkward that we can't pull this info from Edits easily
|
||||
// TODO a bit awkward that we can't pull this info from RoadEdits easily
|
||||
let mut changed: Option<(LaneID, LaneType)> = None;
|
||||
|
||||
match self {
|
||||
RoadEditor::Inactive(edits) => match selected {
|
||||
None => {
|
||||
if input.unimportant_key_pressed(Key::E, EDIT_MAP, "Start editing roads") {
|
||||
// TODO cloning edits sucks! want to consume self
|
||||
new_state = Some(RoadEditor::Active(edits.clone()));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
RoadEditor::Active(edits) => {
|
||||
if input.key_pressed(Key::Return, "stop editing roads") {
|
||||
new_state = Some(RoadEditor::Inactive(edits.clone()));
|
||||
} else if let Some(ID::Lane(id)) = selected {
|
||||
let lane = map.get_l(id);
|
||||
let road = map.get_r(lane.parent);
|
||||
let reason = EditReason::BasemapWrong; // TODO be able to choose
|
||||
if !self.active && selected.is_none() {
|
||||
if input.unimportant_key_pressed(Key::E, EDIT_MAP, "Start editing roads") {
|
||||
self.active = true;
|
||||
}
|
||||
}
|
||||
if self.active {
|
||||
if input.key_pressed(Key::Return, "stop editing roads") {
|
||||
self.active = false;
|
||||
} else if let Some(ID::Lane(id)) = selected {
|
||||
let lane = map.get_l(id);
|
||||
let road = map.get_r(lane.parent);
|
||||
let reason = EditReason::BasemapWrong; // TODO be able to choose
|
||||
|
||||
if lane.lane_type != LaneType::Sidewalk {
|
||||
if lane.lane_type != LaneType::Driving
|
||||
&& input.key_pressed(Key::D, "make this a driving lane")
|
||||
if lane.lane_type != LaneType::Sidewalk {
|
||||
if lane.lane_type != LaneType::Driving
|
||||
&& input.key_pressed(Key::D, "make this a driving lane")
|
||||
{
|
||||
if self
|
||||
.edits
|
||||
.change_lane_type(reason, road, lane, LaneType::Driving)
|
||||
{
|
||||
if edits.change_lane_type(reason, road, lane, LaneType::Driving) {
|
||||
changed = Some((lane.id, LaneType::Driving));
|
||||
}
|
||||
changed = Some((lane.id, LaneType::Driving));
|
||||
}
|
||||
if lane.lane_type != LaneType::Parking
|
||||
&& input.key_pressed(Key::P, "make this a parking lane")
|
||||
}
|
||||
if lane.lane_type != LaneType::Parking
|
||||
&& input.key_pressed(Key::P, "make this a parking lane")
|
||||
{
|
||||
if self
|
||||
.edits
|
||||
.change_lane_type(reason, road, lane, LaneType::Parking)
|
||||
{
|
||||
if edits.change_lane_type(reason, road, lane, LaneType::Parking) {
|
||||
changed = Some((lane.id, LaneType::Parking));
|
||||
}
|
||||
changed = Some((lane.id, LaneType::Parking));
|
||||
}
|
||||
if lane.lane_type != LaneType::Biking
|
||||
&& input.key_pressed(Key::B, "make this a bike lane")
|
||||
}
|
||||
if lane.lane_type != LaneType::Biking
|
||||
&& input.key_pressed(Key::B, "make this a bike lane")
|
||||
{
|
||||
if self
|
||||
.edits
|
||||
.change_lane_type(reason, road, lane, LaneType::Biking)
|
||||
{
|
||||
if edits.change_lane_type(reason, road, lane, LaneType::Biking) {
|
||||
changed = Some((lane.id, LaneType::Biking));
|
||||
}
|
||||
changed = Some((lane.id, LaneType::Biking));
|
||||
}
|
||||
if input.key_pressed(Key::Backspace, "delete this lane") {
|
||||
if edits.delete_lane(road, lane) {
|
||||
warn!(
|
||||
"Have to reload the map from scratch to pick up this change!"
|
||||
);
|
||||
}
|
||||
}
|
||||
if input.key_pressed(Key::Backspace, "delete this lane") {
|
||||
if self.edits.delete_lane(road, lane) {
|
||||
warn!("Have to reload the map from scratch to pick up this change!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(s) = new_state {
|
||||
*self = s;
|
||||
}
|
||||
if let Some((id, new_type)) = changed {
|
||||
let intersections = map.get_l(id).intersections();
|
||||
@ -114,17 +114,11 @@ impl RoadEditor {
|
||||
}
|
||||
}
|
||||
|
||||
match self {
|
||||
RoadEditor::Inactive(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
self.active
|
||||
}
|
||||
|
||||
pub fn get_edits(&self) -> &Edits {
|
||||
match self {
|
||||
RoadEditor::Inactive(edits) => edits,
|
||||
RoadEditor::Active(edits) => edits,
|
||||
}
|
||||
pub fn get_edits(&self) -> &RoadEdits {
|
||||
&self.edits
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
use abstutil;
|
||||
use colors::{ColorScheme, Colors};
|
||||
use control::ControlMap;
|
||||
use control::{ModifiedStopSign, ModifiedTrafficSignal};
|
||||
use ezgui::{Canvas, EventLoopMode, GfxCtx, Text, ToggleableLayer, UserInput, BOTTOM_LEFT, GUI};
|
||||
use flame;
|
||||
use graphics::types::Color;
|
||||
@ -37,8 +36,7 @@ use plugins::warp::WarpState;
|
||||
use plugins::Colorizer;
|
||||
use render::{DrawMap, RenderOptions};
|
||||
use sim;
|
||||
use sim::Sim;
|
||||
use std::collections::HashMap;
|
||||
use sim::{MapEdits, Sim};
|
||||
use std::process;
|
||||
|
||||
// TODO ideally these would be tuned kind of dynamically based on rendering speed
|
||||
@ -77,13 +75,12 @@ impl UIWrapper {
|
||||
let logs = DisplayLogs::new();
|
||||
|
||||
flame::start("setup");
|
||||
let (map, edits, control_map, sim) = sim::load(
|
||||
let (map, control_map, sim) = sim::load(
|
||||
load,
|
||||
scenario_name,
|
||||
rng_seed,
|
||||
Some(sim::Tick::from_seconds(30)),
|
||||
);
|
||||
|
||||
let extra_shapes = if let Some(path) = kml {
|
||||
kml::load(&path, &map.get_gps_bounds()).expect("Couldn't load extra KML shapes")
|
||||
} else {
|
||||
@ -98,6 +95,7 @@ impl UIWrapper {
|
||||
flame::dump_stdout();
|
||||
|
||||
let steepness_viz = SteepnessVisualizer::new(&map);
|
||||
let road_editor = RoadEditor::new(map.get_road_edits().clone());
|
||||
|
||||
let mut ui = UI {
|
||||
// TODO organize this by section
|
||||
@ -107,6 +105,7 @@ impl UIWrapper {
|
||||
sim,
|
||||
|
||||
steepness_viz,
|
||||
road_editor,
|
||||
sim_ctrl: SimController::new(),
|
||||
|
||||
layers: ToggleableLayers::new(),
|
||||
@ -123,7 +122,6 @@ impl UIWrapper {
|
||||
osm_classifier: OsmClassifier::new(),
|
||||
traffic_signal_editor: TrafficSignalEditor::new(),
|
||||
stop_sign_editor: StopSignEditor::new(),
|
||||
road_editor: RoadEditor::new(edits),
|
||||
color_picker: ColorPicker::new(),
|
||||
geom_validator: Validator::new(),
|
||||
turn_cycler: TurnCyclerState::new(),
|
||||
@ -143,8 +141,6 @@ impl UIWrapper {
|
||||
ui.canvas.cam_x = state.cam_x;
|
||||
ui.canvas.cam_y = state.cam_y;
|
||||
ui.canvas.cam_zoom = state.cam_zoom;
|
||||
ui.control_map
|
||||
.load_savestate(&state.traffic_signals, &state.stop_signs);
|
||||
}
|
||||
_ => {
|
||||
warn!("Couldn't load editor_state or it's for a different map, so just centering initial view");
|
||||
@ -384,15 +380,21 @@ impl UI {
|
||||
cam_x: self.canvas.cam_x,
|
||||
cam_y: self.canvas.cam_y,
|
||||
cam_zoom: self.canvas.cam_zoom,
|
||||
traffic_signals: self.control_map.get_traffic_signals_savestate(),
|
||||
stop_signs: self.control_map.get_stop_signs_savestate(),
|
||||
};
|
||||
// TODO maybe make state line up with the map, so loading from a new map doesn't break
|
||||
abstutil::write_json("editor_state", &state).expect("Saving editor_state failed");
|
||||
abstutil::write_json("color_scheme", &self.cs).expect("Saving color_scheme failed");
|
||||
abstutil::write_json("road_edits.json", self.road_editor.get_edits())
|
||||
.expect("Saving road_edits.json failed");
|
||||
info!("Saved editor_state, color_scheme, and road_edits.json");
|
||||
abstutil::write_json(
|
||||
"map_edits.json",
|
||||
&MapEdits {
|
||||
edits_name: "nameless".to_string(),
|
||||
map_name: self.map.get_name().to_string(),
|
||||
road_edits: self.road_editor.get_edits().clone(),
|
||||
stop_signs: self.control_map.get_stop_signs_savestate(),
|
||||
traffic_signals: self.control_map.get_traffic_signals_savestate(),
|
||||
},
|
||||
).expect("Saving map_edits.json failed");
|
||||
info!("Saved editor_state, color_scheme, and map_edits.json");
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
@ -538,9 +540,6 @@ pub struct EditorState {
|
||||
pub cam_x: f64,
|
||||
pub cam_y: f64,
|
||||
pub cam_zoom: f64,
|
||||
|
||||
pub traffic_signals: HashMap<IntersectionID, ModifiedTrafficSignal>,
|
||||
pub stop_signs: HashMap<IntersectionID, ModifiedStopSign>,
|
||||
}
|
||||
|
||||
pub struct ToggleableLayers {
|
||||
|
@ -44,7 +44,7 @@ fn main() {
|
||||
log::set_max_level(LevelFilter::Debug);
|
||||
log::set_logger(&LOG_ADAPTER).unwrap();
|
||||
|
||||
let (map, _, control_map, mut sim) = sim::load(
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
flags.load.clone(),
|
||||
flags.scenario_name,
|
||||
flags.rng_seed,
|
||||
|
@ -4,14 +4,14 @@ use {Lane, LaneType, Road, RoadID};
|
||||
// TODO bring in the intersection modifications from the control crate here. for now, road edits
|
||||
// are here, since map construction maybe needs to know these?
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Edits {
|
||||
pub struct RoadEdits {
|
||||
// TODO detect when we wind up editing back to the original thing
|
||||
pub(crate) roads: BTreeMap<RoadID, RoadEdit>,
|
||||
}
|
||||
|
||||
impl Edits {
|
||||
pub fn new() -> Edits {
|
||||
Edits {
|
||||
impl RoadEdits {
|
||||
pub fn new() -> RoadEdits {
|
||||
RoadEdits {
|
||||
roads: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ mod turn;
|
||||
pub use area::{Area, AreaID, AreaType};
|
||||
pub use building::{Building, BuildingID, FrontPath};
|
||||
pub use bus_stop::{BusRoute, BusStop, BusStopID};
|
||||
pub use edits::{EditReason, Edits};
|
||||
pub use edits::{EditReason, RoadEdits};
|
||||
pub use intersection::{Intersection, IntersectionID};
|
||||
pub use lane::{Lane, LaneID, LaneType, PARKING_SPOT_LENGTH};
|
||||
pub use map::Map;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use edits::Edits;
|
||||
use edits::RoadEdits;
|
||||
use lane::LaneType;
|
||||
use raw_data;
|
||||
use road::RoadID;
|
||||
@ -75,7 +75,7 @@ impl LaneSpec {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_lane_specs(r: &raw_data::Road, id: RoadID, edits: &Edits) -> Vec<LaneSpec> {
|
||||
pub(crate) fn get_lane_specs(r: &raw_data::Road, id: RoadID, edits: &RoadEdits) -> Vec<LaneSpec> {
|
||||
let (side1_types, side2_types) = if let Some(e) = edits.roads.get(&id) {
|
||||
info!("Using edits for {}", id);
|
||||
(e.forwards_lanes.clone(), e.backwards_lanes.clone())
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
use abstutil;
|
||||
use edits::Edits;
|
||||
use edits::RoadEdits;
|
||||
use flame;
|
||||
use geom::{Bounds, HashablePt2D, PolyLine, Pt2D};
|
||||
use make;
|
||||
@ -30,10 +30,11 @@ pub struct Map {
|
||||
bounds: Bounds,
|
||||
|
||||
name: String,
|
||||
road_edits: RoadEdits,
|
||||
}
|
||||
|
||||
impl Map {
|
||||
pub fn new(path: &str, edits: &Edits) -> Result<Map, Error> {
|
||||
pub fn new(path: &str, road_edits: RoadEdits) -> Result<Map, Error> {
|
||||
// TODO I think I want something a bit different than flame:
|
||||
// - Print as each phase occurs
|
||||
// - Print with nicely formatted durations
|
||||
@ -48,14 +49,15 @@ impl Map {
|
||||
.into_string()
|
||||
.unwrap(),
|
||||
data,
|
||||
edits,
|
||||
road_edits,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn create_from_raw(name: String, data: raw_data::Map, edits: &Edits) -> Map {
|
||||
pub fn create_from_raw(name: String, data: raw_data::Map, road_edits: RoadEdits) -> Map {
|
||||
let bounds = data.get_gps_bounds();
|
||||
let mut m = Map {
|
||||
name,
|
||||
road_edits,
|
||||
bounds,
|
||||
roads: Vec::new(),
|
||||
lanes: Vec::new(),
|
||||
@ -108,7 +110,7 @@ impl Map {
|
||||
let i2 = pt_to_intersection[&HashablePt2D::from(road_center_pts.last_pt())];
|
||||
|
||||
// TODO move this to make/lanes.rs too
|
||||
for lane in make::get_lane_specs(r, road_id, edits) {
|
||||
for lane in make::get_lane_specs(r, road_id, &m.road_edits) {
|
||||
let id = LaneID(counter);
|
||||
counter += 1;
|
||||
|
||||
@ -394,6 +396,10 @@ impl Map {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn get_road_edits(&self) -> &RoadEdits {
|
||||
&self.road_edits
|
||||
}
|
||||
|
||||
pub fn all_bus_stops(&self) -> &BTreeMap<BusStopID, BusStop> {
|
||||
&self.bus_stops
|
||||
}
|
||||
|
25
sim/src/edits.rs
Normal file
25
sim/src/edits.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use control::{ModifiedStopSign, ModifiedTrafficSignal};
|
||||
use map_model::{IntersectionID, RoadEdits};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct MapEdits {
|
||||
pub edits_name: String,
|
||||
pub map_name: String,
|
||||
|
||||
pub road_edits: RoadEdits,
|
||||
pub stop_signs: BTreeMap<IntersectionID, ModifiedStopSign>,
|
||||
pub traffic_signals: BTreeMap<IntersectionID, ModifiedTrafficSignal>,
|
||||
}
|
||||
|
||||
impl MapEdits {
|
||||
pub fn new() -> MapEdits {
|
||||
MapEdits {
|
||||
edits_name: "unnamed".to_string(),
|
||||
map_name: "TODO".to_string(), // TODO er
|
||||
road_edits: RoadEdits::new(),
|
||||
stop_signs: BTreeMap::new(),
|
||||
traffic_signals: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,10 @@ use abstutil;
|
||||
use control::ControlMap;
|
||||
use flame;
|
||||
use geom::Polygon;
|
||||
use map_model::{BuildingID, BusRoute, BusStopID, Edits, LaneID, Map};
|
||||
use map_model::{BuildingID, BusRoute, BusStopID, LaneID, Map};
|
||||
use rand::Rng;
|
||||
use std::collections::VecDeque;
|
||||
use {CarID, Event, PedestrianID, RouteID, Scenario, Sim, Tick};
|
||||
use {CarID, Event, MapEdits, PedestrianID, RouteID, Scenario, Sim, Tick};
|
||||
|
||||
// Convenience method to setup everything.
|
||||
pub fn load(
|
||||
@ -13,8 +13,9 @@ pub fn load(
|
||||
scenario_name: String,
|
||||
rng_seed: Option<u8>,
|
||||
savestate_every: Option<Tick>,
|
||||
) -> (Map, Edits, ControlMap, Sim) {
|
||||
let edits: Edits = abstutil::read_json("road_edits.json").unwrap_or(Edits::new());
|
||||
) -> (Map, ControlMap, Sim) {
|
||||
// TODO read a specific one
|
||||
let edits: MapEdits = abstutil::read_json("map_edits.json").unwrap_or(MapEdits::new());
|
||||
|
||||
if input.contains("data/save/") {
|
||||
info!("Resuming from {}", input);
|
||||
@ -23,17 +24,17 @@ pub fn load(
|
||||
flame::end("read sim savestate");
|
||||
// TODO assuming the relative path :(
|
||||
let map_path = format!("../data/maps/{}.abst", sim.map_name);
|
||||
let map =
|
||||
Map::new(&map_path, &edits).expect(&format!("Couldn't load map from {}", map_path));
|
||||
let control_map = ControlMap::new(&map);
|
||||
(map, edits, control_map, sim)
|
||||
let map = Map::new(&map_path, edits.road_edits.clone())
|
||||
.expect(&format!("Couldn't load map from {}", map_path));
|
||||
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
|
||||
(map, control_map, sim)
|
||||
} else if input.contains("data/scenarios/") {
|
||||
info!("Seeding the simulation from scenario {}", input);
|
||||
let scenario: Scenario = abstutil::read_json(&input).expect("loading scenario failed");
|
||||
let map_path = format!("../data/maps/{}.abst", scenario.map_name);
|
||||
let map =
|
||||
Map::new(&map_path, &edits).expect(&format!("Couldn't load map from {}", map_path));
|
||||
let control_map = ControlMap::new(&map);
|
||||
let map = Map::new(&map_path, edits.road_edits.clone())
|
||||
.expect(&format!("Couldn't load map from {}", map_path));
|
||||
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
|
||||
let mut sim = Sim::new(
|
||||
&map,
|
||||
scenario.scenario_name.clone(),
|
||||
@ -41,15 +42,15 @@ pub fn load(
|
||||
savestate_every,
|
||||
);
|
||||
scenario.instantiate(&mut sim, &map);
|
||||
(map, edits, control_map, sim)
|
||||
(map, control_map, sim)
|
||||
} else {
|
||||
info!("Loading map {}", input);
|
||||
let map = Map::new(&input, &edits).expect("Couldn't load map");
|
||||
let control_map = ControlMap::new(&map);
|
||||
let map = Map::new(&input, edits.road_edits.clone()).expect("Couldn't load map");
|
||||
let control_map = ControlMap::new(&map, &edits.stop_signs, &edits.traffic_signals);
|
||||
flame::start("create sim");
|
||||
let sim = Sim::new(&map, scenario_name, rng_seed, savestate_every);
|
||||
flame::end("create sim");
|
||||
(map, edits, control_map, sim)
|
||||
(map, control_map, sim)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ extern crate serde_derive;
|
||||
mod macros;
|
||||
|
||||
mod driving;
|
||||
mod edits;
|
||||
mod events;
|
||||
mod helpers;
|
||||
mod instrument;
|
||||
@ -51,6 +52,7 @@ mod walking;
|
||||
|
||||
use abstutil::Cloneable;
|
||||
use dimensioned::si;
|
||||
pub use edits::MapEdits;
|
||||
pub use events::Event;
|
||||
use geom::{Angle, Pt2D};
|
||||
pub use helpers::load;
|
||||
|
@ -5,7 +5,7 @@ extern crate sim;
|
||||
|
||||
#[test]
|
||||
fn aorta_model_completes() {
|
||||
let (map, _, control_map, mut sim) = sim::load(
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"aorta_model_completes".to_string(),
|
||||
Some(42),
|
||||
|
@ -5,7 +5,7 @@ extern crate sim;
|
||||
|
||||
#[test]
|
||||
fn serialization() {
|
||||
let (map, _, _, mut sim) = sim::load(
|
||||
let (map, _, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"serialization".to_string(),
|
||||
Some(42),
|
||||
@ -22,7 +22,7 @@ fn serialization() {
|
||||
#[test]
|
||||
fn from_scratch() {
|
||||
println!("Creating two simulations");
|
||||
let (map, _, control_map, mut sim1) = sim::load(
|
||||
let (map, control_map, mut sim1) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"from_scratch_1".to_string(),
|
||||
Some(42),
|
||||
@ -49,7 +49,7 @@ fn from_scratch() {
|
||||
#[test]
|
||||
fn with_savestating() {
|
||||
println!("Creating two simulations");
|
||||
let (map, _, control_map, mut sim1) = sim::load(
|
||||
let (map, control_map, mut sim1) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"with_savestating_1".to_string(),
|
||||
Some(42),
|
||||
|
@ -5,6 +5,7 @@ extern crate map_model;
|
||||
extern crate sim;
|
||||
|
||||
use map_model::LaneID;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// TODO refactor a few more things to make these more succinct?
|
||||
|
||||
@ -62,7 +63,7 @@ fn setup(
|
||||
map: map_model::Map,
|
||||
) -> (map_model::Map, control::ControlMap, sim::Sim) {
|
||||
let rng_seed = 123;
|
||||
let control_map = control::ControlMap::new(&map);
|
||||
let control_map = control::ControlMap::new(&map, &BTreeMap::new(), &BTreeMap::new());
|
||||
let sim = sim::Sim::new(&map, scenario_name.to_string(), Some(rng_seed), None);
|
||||
(map, control_map, sim)
|
||||
}
|
||||
@ -71,7 +72,6 @@ fn setup(
|
||||
fn make_test_map() -> map_model::Map {
|
||||
use dimensioned::si;
|
||||
use map_model::{raw_data, LaneType};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let left = geom::LonLat::new(100.0, 50.0);
|
||||
let right = geom::LonLat::new(200.0, 50.0);
|
||||
@ -116,7 +116,7 @@ fn make_test_map() -> map_model::Map {
|
||||
areas: Vec::new(),
|
||||
coordinates_in_world_space: true,
|
||||
},
|
||||
&map_model::Edits::new(),
|
||||
map_model::RoadEdits::new(),
|
||||
);
|
||||
|
||||
assert_eq!(map.all_roads().len(), 1);
|
||||
|
@ -5,7 +5,7 @@ extern crate sim;
|
||||
|
||||
#[test]
|
||||
fn bus_reaches_stops() {
|
||||
let (map, _, control_map, mut sim) = sim::load(
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"bus_reaches_stops".to_string(),
|
||||
Some(42),
|
||||
@ -33,7 +33,7 @@ fn bus_reaches_stops() {
|
||||
// TODO this test is strictly more complicated than bus_reaches_stops, should it subsume it?
|
||||
#[test]
|
||||
fn ped_uses_bus() {
|
||||
let (map, _, control_map, mut sim) = sim::load(
|
||||
let (map, control_map, mut sim) = sim::load(
|
||||
"../data/maps/small.abst".to_string(),
|
||||
"bus_reaches_stops".to_string(),
|
||||
Some(42),
|
||||
|
Loading…
Reference in New Issue
Block a user