mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 01:15:12 +03:00
Make the LTN impact prediction work off autogenerated home-to-work scenarios too.
Most of the work is moving proletariat robot to synthpop, so the LTN crate doesn't depend on sim. That was a refactor that needed to happen anyway.
This commit is contained in:
parent
5722c67011
commit
3fa6aba9c8
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2245,6 +2245,8 @@ dependencies = [
|
||||
"map_gui",
|
||||
"map_model",
|
||||
"maplit",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -26,6 +26,8 @@ log = "0.4"
|
||||
maplit = "1.0.2"
|
||||
map_gui = { path = "../../map_gui" }
|
||||
map_model = { path = "../../map_model" }
|
||||
rand = "0.8.3"
|
||||
rand_xorshift = "0.3.0"
|
||||
regex = "1.5.5"
|
||||
serde = "1.0.123"
|
||||
serde_json = "1.0.61"
|
||||
|
@ -3,7 +3,6 @@ use std::collections::HashSet;
|
||||
use abstutil::Counter;
|
||||
use geom::Distance;
|
||||
use map_gui::tools::{ColorNetwork, DrawRoadLabels};
|
||||
use synthpop::Scenario;
|
||||
use widgetry::mapspace::{ToggleZoomed, World, WorldOutcome};
|
||||
use widgetry::{
|
||||
Choice, Color, DrawBaselayer, EventCtx, GeomBatch, GfxCtx, Key, Line, Outcome, Panel, State,
|
||||
@ -307,19 +306,10 @@ fn impact_widget(ctx: &EventCtx, app: &App) -> Widget {
|
||||
|
||||
if &app.session.impact.map != map_name {
|
||||
// Starting from scratch
|
||||
let scenario_name = Scenario::default_scenario_for_map(map_name);
|
||||
if scenario_name == "home_to_work" {
|
||||
return "This city doesn't have travel demand model data available".text_widget(ctx);
|
||||
}
|
||||
let size = abstio::Manifest::load()
|
||||
.get_entry(&abstio::path_scenario(map_name, &scenario_name))
|
||||
.map(|entry| abstutil::prettyprint_bytes(entry.compressed_size_bytes))
|
||||
.unwrap_or_else(|| "???".to_string());
|
||||
return Widget::col(vec![
|
||||
Text::from_multiline(vec![
|
||||
Line("This will take a moment.").small(),
|
||||
Line("The app may freeze while calculating.").small(),
|
||||
Line(format!("We need to load a {} file", size)).small(),
|
||||
])
|
||||
.into_widget(ctx),
|
||||
ctx.style().btn_outline.text("Calculate").build_def(ctx),
|
||||
|
@ -1,7 +1,11 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use rand::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
use map_gui::tools::checkbox_per_mode;
|
||||
use map_model::{Path, NORMAL_LANE_THICKNESS};
|
||||
use synthpop::make::ScenarioGenerator;
|
||||
use synthpop::{Scenario, TripMode};
|
||||
use widgetry::tools::{FileLoader, PopupMsg};
|
||||
use widgetry::{
|
||||
@ -25,16 +29,27 @@ impl ShowResults {
|
||||
let map_name = app.map.get_name().clone();
|
||||
if app.session.impact.map != map_name {
|
||||
let scenario_name = Scenario::default_scenario_for_map(&map_name);
|
||||
return FileLoader::<App, Scenario>::new_state(
|
||||
ctx,
|
||||
abstio::path_scenario(&map_name, &scenario_name),
|
||||
Box::new(move |ctx, app, timer, maybe_scenario| {
|
||||
// TODO Handle corrupt files
|
||||
let scenario = maybe_scenario.unwrap();
|
||||
app.session.impact = Impact::from_scenario(ctx, app, scenario, timer);
|
||||
Transition::Replace(ShowResults::new_state(ctx, app))
|
||||
}),
|
||||
);
|
||||
|
||||
if scenario_name != "home_to_work" {
|
||||
return FileLoader::<App, Scenario>::new_state(
|
||||
ctx,
|
||||
abstio::path_scenario(&map_name, &scenario_name),
|
||||
Box::new(move |ctx, app, timer, maybe_scenario| {
|
||||
// TODO Handle corrupt files
|
||||
let scenario = maybe_scenario.unwrap();
|
||||
app.session.impact = Impact::from_scenario(ctx, app, scenario, timer);
|
||||
Transition::Replace(ShowResults::new_state(ctx, app))
|
||||
}),
|
||||
);
|
||||
}
|
||||
ctx.loading_screen("synthesize travel demand model", |ctx, timer| {
|
||||
let scenario = ScenarioGenerator::proletariat_robot(
|
||||
&app.map,
|
||||
&mut XorShiftRng::seed_from_u64(42),
|
||||
timer,
|
||||
);
|
||||
app.session.impact = Impact::from_scenario(ctx, app, scenario, timer);
|
||||
});
|
||||
}
|
||||
|
||||
if app.session.impact.change_key != app.session.modal_filters.get_change_key() {
|
||||
|
@ -37,7 +37,7 @@ pub use crate::render::{
|
||||
pub use self::analytics::{Analytics, Problem, ProblemType, SlidingWindow, TripPhase};
|
||||
pub(crate) use self::events::Event;
|
||||
pub use self::events::{AlertLocation, TripPhaseType};
|
||||
pub use self::make::{fork_rng, BorderSpawnOverTime, ScenarioGenerator, SimFlags, SpawnOverTime};
|
||||
pub use self::make::SimFlags;
|
||||
pub(crate) use self::make::{StartTripArgs, TripSpec};
|
||||
pub(crate) use self::mechanics::{
|
||||
DrivingSimState, IntersectionSimState, ParkingSim, ParkingSimState, WalkingSimState,
|
||||
@ -54,6 +54,7 @@ pub use self::sim::{
|
||||
pub(crate) use self::transit::TransitSimState;
|
||||
pub use self::trips::{CommutersVehiclesCounts, Person, PersonState, TripInfo, TripResult};
|
||||
pub(crate) use self::trips::{TripLeg, TripManager};
|
||||
pub use synthpop::make::{fork_rng, BorderSpawnOverTime, ScenarioGenerator, SpawnOverTime};
|
||||
|
||||
mod analytics;
|
||||
mod events;
|
||||
|
@ -1,20 +1,7 @@
|
||||
//! Everything needed to setup a simulation.
|
||||
//! <https://a-b-street.github.io/docs/tech/trafficsim/travel_demand.html> for context.
|
||||
|
||||
use rand::{RngCore, SeedableRng};
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
pub use self::generator::{BorderSpawnOverTime, ScenarioGenerator, SpawnOverTime};
|
||||
pub use self::load::SimFlags;
|
||||
pub(crate) use self::spawner::{StartTripArgs, TripSpec};
|
||||
|
||||
mod activity_model;
|
||||
mod generator;
|
||||
mod load;
|
||||
mod spawner;
|
||||
|
||||
/// Need to explain this trick -- basically keeps consistency between two different simulations when
|
||||
/// each one might make slightly different sequences of calls to the RNG.
|
||||
pub fn fork_rng(base_rng: &mut XorShiftRng) -> XorShiftRng {
|
||||
XorShiftRng::seed_from_u64(base_rng.next_u64())
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ use rand_xorshift::XorShiftRng;
|
||||
use abstutil::{prettyprint_usize, Counter, Timer};
|
||||
use geom::{Distance, Speed};
|
||||
use map_model::{BuildingID, Map, OffstreetParking, RoadID};
|
||||
use synthpop::make::fork_rng;
|
||||
use synthpop::{PersonSpec, Scenario, TripEndpoint, TripMode};
|
||||
|
||||
use crate::make::fork_rng;
|
||||
use crate::{
|
||||
ParkingSpot, Sim, StartTripArgs, TripInfo, Vehicle, VehicleSpec, VehicleType, BIKE_LENGTH,
|
||||
MAX_CAR_LENGTH, MIN_CAR_LENGTH,
|
||||
|
@ -26,6 +26,7 @@ mod borders;
|
||||
mod counts;
|
||||
mod endpoint;
|
||||
mod external;
|
||||
pub mod make;
|
||||
mod modifier;
|
||||
mod scenario;
|
||||
|
||||
|
@ -11,10 +11,10 @@ use rand_xorshift::XorShiftRng;
|
||||
use abstutil::{prettyprint_usize, Timer};
|
||||
use geom::{Distance, Duration, Time};
|
||||
use map_model::{BuildingID, BuildingType, Map, PathConstraints, PathRequest};
|
||||
use synthpop::{IndividTrip, PersonSpec, Scenario, TripEndpoint, TripMode, TripPurpose};
|
||||
|
||||
use crate::make::fork_rng;
|
||||
use crate::ScenarioGenerator;
|
||||
use crate::{IndividTrip, PersonSpec, Scenario, TripEndpoint, TripMode, TripPurpose};
|
||||
|
||||
use crate::make::{fork_rng, ScenarioGenerator};
|
||||
|
||||
impl ScenarioGenerator {
|
||||
/// Designed in https://github.com/a-b-street/abstreet/issues/154
|
@ -11,7 +11,8 @@ use serde::{Deserialize, Serialize};
|
||||
use abstutil::Timer;
|
||||
use geom::{Duration, Time};
|
||||
use map_model::{IntersectionID, Map};
|
||||
use synthpop::{IndividTrip, PersonSpec, Scenario, TripEndpoint, TripMode, TripPurpose};
|
||||
|
||||
use crate::{IndividTrip, PersonSpec, Scenario, TripEndpoint, TripMode, TripPurpose};
|
||||
|
||||
// TODO This can be simplified dramatically.
|
||||
|
15
synthpop/src/make/mod.rs
Normal file
15
synthpop/src/make/mod.rs
Normal file
@ -0,0 +1,15 @@
|
||||
//! <https://a-b-street.github.io/docs/tech/trafficsim/travel_demand.html> for context.
|
||||
|
||||
use rand::{RngCore, SeedableRng};
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
pub use self::generator::{BorderSpawnOverTime, ScenarioGenerator, SpawnOverTime};
|
||||
|
||||
mod activity_model;
|
||||
mod generator;
|
||||
|
||||
/// Need to explain this trick -- basically keeps consistency between two different simulations when
|
||||
/// each one might make slightly different sequences of calls to the RNG.
|
||||
pub fn fork_rng(base_rng: &mut XorShiftRng) -> XorShiftRng {
|
||||
XorShiftRng::seed_from_u64(base_rng.next_u64())
|
||||
}
|
Loading…
Reference in New Issue
Block a user