mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 11:44:25 +03:00
start figuring out what impact edits have on trips in a scenario. also,
count trips with the first path failing as aborted.
This commit is contained in:
parent
1c139da0e0
commit
1ff80b2e20
27
game/src/edit/impact.rs
Normal file
27
game/src/edit/impact.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::ui::UI;
|
||||
use abstutil::{prettyprint_usize, Timer};
|
||||
use sim::Scenario;
|
||||
|
||||
// Edits have been applied.
|
||||
pub fn edit_impacts(scenario: Option<Scenario>, ui: &mut UI, timer: &mut Timer) -> Vec<String> {
|
||||
let mut lines = Vec::new();
|
||||
|
||||
if let Some(s) = scenario {
|
||||
ui.primary.clear_sim();
|
||||
s.instantiate(
|
||||
&mut ui.primary.sim,
|
||||
&ui.primary.map,
|
||||
&mut ui.primary.current_flags.sim_flags.make_rng(),
|
||||
timer,
|
||||
);
|
||||
lines.push(format!(
|
||||
"{} aborted trips",
|
||||
prettyprint_usize(ui.primary.sim.get_finished_trips().aborted_trips)
|
||||
));
|
||||
ui.primary.clear_sim();
|
||||
} else {
|
||||
lines.push("No scenario, so no trips impacted".to_string());
|
||||
}
|
||||
|
||||
lines
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
mod impact;
|
||||
mod stop_signs;
|
||||
mod traffic_signals;
|
||||
|
||||
use crate::common::CommonState;
|
||||
use crate::debug::DebugMode;
|
||||
use crate::game::{State, Transition, WizardState};
|
||||
use crate::game::{msg, State, Transition, WizardState};
|
||||
use crate::helpers::{ColorScheme, ID};
|
||||
use crate::render::{
|
||||
DrawIntersection, DrawLane, DrawMap, DrawOptions, DrawRoad, DrawTurn, Renderable,
|
||||
@ -38,6 +39,7 @@ impl EditMode {
|
||||
(hotkey(Key::Escape), "back to sandbox mode"),
|
||||
(hotkey(Key::S), "save edits"),
|
||||
(hotkey(Key::L), "load different edits"),
|
||||
(None, "measure impact of edits"),
|
||||
],
|
||||
ctx,
|
||||
),
|
||||
@ -114,6 +116,15 @@ impl State for EditMode {
|
||||
// Parking state might've changed
|
||||
ui.primary.clear_sim();
|
||||
return Transition::Replace(Box::new(SandboxMode::new(ctx, ui, self.mode.clone())));
|
||||
} else if self.menu.action("measure impact of edits") {
|
||||
let mut timer = Timer::new("measure impact of edits");
|
||||
ui.primary
|
||||
.map
|
||||
.recalculate_pathfinding_after_edits(&mut timer);
|
||||
return Transition::Push(msg(
|
||||
"Impact of edits",
|
||||
impact::edit_impacts(self.mode.scenario(ui, &mut timer), ui, &mut timer),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(ID::Lane(id)) = ui.primary.current_selection {
|
||||
|
@ -47,6 +47,42 @@ pub trait GameplayState: downcast_rs::Downcast {
|
||||
}
|
||||
downcast_rs::impl_downcast!(GameplayState);
|
||||
|
||||
impl GameplayMode {
|
||||
pub fn scenario(&self, ui: &UI, timer: &mut Timer) -> Option<Scenario> {
|
||||
let name = match self {
|
||||
GameplayMode::Freeform => {
|
||||
return None;
|
||||
}
|
||||
GameplayMode::PlayScenario(ref scenario) => scenario,
|
||||
_ => "weekday_typical_traffic_from_psrc",
|
||||
};
|
||||
let num_agents = ui.primary.current_flags.num_agents;
|
||||
let builtin = if let Some(n) = num_agents {
|
||||
format!("random scenario with {} agents", n)
|
||||
} else {
|
||||
"random scenario with some agents".to_string()
|
||||
};
|
||||
Some(if name == builtin {
|
||||
if let Some(n) = num_agents {
|
||||
Scenario::scaled_run(&ui.primary.map, n)
|
||||
} else {
|
||||
Scenario::small_run(&ui.primary.map)
|
||||
}
|
||||
} else if name == "just buses" {
|
||||
let mut s = Scenario::empty(&ui.primary.map);
|
||||
s.scenario_name = "just buses".to_string();
|
||||
s.seed_buses = true;
|
||||
s
|
||||
} else {
|
||||
abstutil::read_binary(
|
||||
&abstutil::path1_bin(&ui.primary.map.get_name(), abstutil::SCENARIOS, &name),
|
||||
timer,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GameplayRunner {
|
||||
pub fn initialize(mode: GameplayMode, ui: &mut UI, ctx: &mut EventCtx) -> GameplayRunner {
|
||||
let prebaked: Analytics = abstutil::read_binary(
|
||||
@ -58,61 +94,19 @@ impl GameplayRunner {
|
||||
Analytics::new()
|
||||
});
|
||||
|
||||
let ((menu, state), maybe_scenario) = match mode.clone() {
|
||||
GameplayMode::Freeform => (freeform::Freeform::new(ctx), None),
|
||||
GameplayMode::PlayScenario(scenario) => (
|
||||
play_scenario::PlayScenario::new(&scenario, ctx),
|
||||
Some(scenario),
|
||||
),
|
||||
GameplayMode::OptimizeBus(route_name) => (
|
||||
optimize_bus::OptimizeBus::new(route_name, ctx, ui),
|
||||
Some("weekday_typical_traffic_from_psrc".to_string()),
|
||||
),
|
||||
GameplayMode::CreateGridlock => (
|
||||
create_gridlock::CreateGridlock::new(ctx),
|
||||
Some("weekday_typical_traffic_from_psrc".to_string()),
|
||||
),
|
||||
GameplayMode::FasterTrips(trip_mode) => (
|
||||
faster_trips::FasterTrips::new(trip_mode, ctx),
|
||||
Some("weekday_typical_traffic_from_psrc".to_string()),
|
||||
),
|
||||
let (menu, state) = match mode.clone() {
|
||||
GameplayMode::Freeform => freeform::Freeform::new(ctx),
|
||||
GameplayMode::PlayScenario(scenario) => {
|
||||
play_scenario::PlayScenario::new(&scenario, ctx)
|
||||
}
|
||||
GameplayMode::OptimizeBus(route_name) => {
|
||||
optimize_bus::OptimizeBus::new(route_name, ctx, ui)
|
||||
}
|
||||
GameplayMode::CreateGridlock => create_gridlock::CreateGridlock::new(ctx),
|
||||
GameplayMode::FasterTrips(trip_mode) => faster_trips::FasterTrips::new(trip_mode, ctx),
|
||||
};
|
||||
let runner = GameplayRunner {
|
||||
mode,
|
||||
menu: menu.disable_standalone_layout(),
|
||||
state,
|
||||
prebaked,
|
||||
};
|
||||
if let Some(scenario_name) = maybe_scenario {
|
||||
ctx.loading_screen("instantiate scenario", |_, timer| {
|
||||
let num_agents = ui.primary.current_flags.num_agents;
|
||||
let builtin = if let Some(n) = num_agents {
|
||||
format!("random scenario with {} agents", n)
|
||||
} else {
|
||||
"random scenario with some agents".to_string()
|
||||
};
|
||||
let scenario = if scenario_name == builtin {
|
||||
if let Some(n) = num_agents {
|
||||
Scenario::scaled_run(&ui.primary.map, n)
|
||||
} else {
|
||||
Scenario::small_run(&ui.primary.map)
|
||||
}
|
||||
} else if scenario_name == "just buses" {
|
||||
let mut s = Scenario::empty(&ui.primary.map);
|
||||
s.scenario_name = "just buses".to_string();
|
||||
s.seed_buses = true;
|
||||
s
|
||||
} else {
|
||||
abstutil::read_binary(
|
||||
&abstutil::path1_bin(
|
||||
&ui.primary.map.get_name(),
|
||||
abstutil::SCENARIOS,
|
||||
&scenario_name,
|
||||
),
|
||||
timer,
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
ctx.loading_screen("instantiate scenario", |_, timer| {
|
||||
if let Some(scenario) = mode.scenario(ui, timer) {
|
||||
scenario.instantiate(
|
||||
&mut ui.primary.sim,
|
||||
&ui.primary.map,
|
||||
@ -120,9 +114,14 @@ impl GameplayRunner {
|
||||
timer,
|
||||
);
|
||||
ui.primary.sim.step(&ui.primary.map, Duration::seconds(0.1));
|
||||
});
|
||||
}
|
||||
});
|
||||
GameplayRunner {
|
||||
mode,
|
||||
menu: menu.disable_standalone_layout(),
|
||||
state,
|
||||
prebaked,
|
||||
}
|
||||
runner
|
||||
}
|
||||
|
||||
pub fn event(
|
||||
|
@ -152,12 +152,15 @@ impl SidewalkPathfinder {
|
||||
}
|
||||
steps.push(PathStep::Turn(t));
|
||||
current_i = Some(lane1.dst_i);
|
||||
} else {
|
||||
} else if let Some(t) = back_t {
|
||||
if current_i != Some(lane1.src_i) {
|
||||
steps.push(PathStep::ContraflowLane(lane1.id));
|
||||
}
|
||||
steps.push(PathStep::Turn(back_t.unwrap()));
|
||||
steps.push(PathStep::Turn(t));
|
||||
current_i = Some(lane1.src_i);
|
||||
} else {
|
||||
println!("WARNING! No turn between sidewalks {} and {}", lane1.id, l2);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,11 +172,6 @@ impl TripSpawner {
|
||||
timer.start_iter("spawn trips", paths.len());
|
||||
for ((start_time, ped_id, car_id, spec), req, maybe_path) in paths {
|
||||
timer.next();
|
||||
if maybe_path.is_none() {
|
||||
timer.warn(format!("Some trip couldn't find the first path {}", req));
|
||||
continue;
|
||||
}
|
||||
let path = maybe_path.unwrap();
|
||||
match spec {
|
||||
TripSpec::CarAppearing {
|
||||
start_pos,
|
||||
@ -203,14 +198,22 @@ impl TripSpawner {
|
||||
}
|
||||
let trip_start = TripStart::Border(map.get_l(start_pos.lane()).src_i);
|
||||
let trip = trips.new_trip(start_time, trip_start, legs);
|
||||
let router = goal.make_router(path, map, vehicle.vehicle_type);
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnCar(
|
||||
CreateCar::for_appearing(vehicle, start_pos, router, trip),
|
||||
retry_if_no_room,
|
||||
),
|
||||
);
|
||||
if let Some(path) = maybe_path {
|
||||
let router = goal.make_router(path, map, vehicle.vehicle_type);
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnCar(
|
||||
CreateCar::for_appearing(vehicle, start_pos, router, trip),
|
||||
retry_if_no_room,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
"CarAppearing trip couldn't find the first path {}",
|
||||
req
|
||||
));
|
||||
trips.abort_trip_failed_start(trip);
|
||||
}
|
||||
}
|
||||
TripSpec::UsingParkedCar {
|
||||
start,
|
||||
@ -243,17 +246,25 @@ impl TripSpawner {
|
||||
let trip =
|
||||
trips.new_trip(start_time, TripStart::Bldg(vehicle.owner.unwrap()), legs);
|
||||
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: parking_spot,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
if let Some(path) = maybe_path {
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: parking_spot,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
"UsingParkedCar trip couldn't find the first path {}",
|
||||
req
|
||||
));
|
||||
trips.abort_trip_failed_start(trip);
|
||||
}
|
||||
}
|
||||
TripSpec::MaybeUsingParkedCar {
|
||||
start_bldg,
|
||||
@ -273,8 +284,8 @@ impl TripSpawner {
|
||||
speed: ped_speed,
|
||||
start: SidewalkSpot::building(start_bldg, map),
|
||||
goal: walk_to,
|
||||
// This is junk
|
||||
path,
|
||||
// This is guaranteed to work, and is junk anyway.
|
||||
path: maybe_path.unwrap(),
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
@ -297,17 +308,25 @@ impl TripSpawner {
|
||||
vec![TripLeg::Walk(ped_id.unwrap(), ped_speed, goal.clone())],
|
||||
);
|
||||
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
if let Some(path) = maybe_path {
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
"JustWalking trip couldn't find the first path {}",
|
||||
req
|
||||
));
|
||||
trips.abort_trip_failed_start(trip);
|
||||
}
|
||||
}
|
||||
TripSpec::UsingBike {
|
||||
start,
|
||||
@ -344,17 +363,25 @@ impl TripSpawner {
|
||||
legs,
|
||||
);
|
||||
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
if let Some(path) = maybe_path {
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
"UsingBike trip couldn't find the first path {}",
|
||||
req
|
||||
));
|
||||
trips.abort_trip_failed_start(trip);
|
||||
}
|
||||
}
|
||||
TripSpec::UsingTransit {
|
||||
start,
|
||||
@ -382,17 +409,25 @@ impl TripSpawner {
|
||||
],
|
||||
);
|
||||
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
if let Some(path) = maybe_path {
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
"UsingTransit trip couldn't find the first path {}",
|
||||
req
|
||||
));
|
||||
trips.abort_trip_failed_start(trip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user