mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
dont serialize paths of yet-to-be-spawned stuff. drastically reduces savestate size.
This commit is contained in:
parent
a1ff95e80a
commit
959a89e81c
@ -111,7 +111,7 @@ impl State for DebugMode {
|
||||
.find_previous_savestate(ui.primary.sim.time());
|
||||
match prev_state
|
||||
.clone()
|
||||
.and_then(|path| Sim::load_savestate(path, &mut timer).ok())
|
||||
.and_then(|path| Sim::load_savestate(path, &ui.primary.map, &mut timer).ok())
|
||||
{
|
||||
Some(new_sim) => {
|
||||
ui.primary.sim = new_sim;
|
||||
@ -132,7 +132,7 @@ impl State for DebugMode {
|
||||
let next_state = ui.primary.sim.find_next_savestate(ui.primary.sim.time());
|
||||
match next_state
|
||||
.clone()
|
||||
.and_then(|path| Sim::load_savestate(path, &mut timer).ok())
|
||||
.and_then(|path| Sim::load_savestate(path, &ui.primary.map, &mut timer).ok())
|
||||
{
|
||||
Some(new_sim) => {
|
||||
ui.primary.sim = new_sim;
|
||||
@ -401,7 +401,8 @@ fn load_savestate(wiz: &mut Wizard, ctx: &mut EventCtx, ui: &mut UI) -> Option<T
|
||||
let ss_path = format!("{}/{}.bin", ui.primary.sim.save_dir(), ss);
|
||||
|
||||
ctx.loading_screen("load savestate", |ctx, mut timer| {
|
||||
ui.primary.sim = Sim::load_savestate(ss_path, &mut timer).expect("Can't load savestate");
|
||||
ui.primary.sim = Sim::load_savestate(ss_path, &ui.primary.map, &mut timer)
|
||||
.expect("Can't load savestate");
|
||||
ui.recalculate_current_selection(ctx);
|
||||
});
|
||||
Some(Transition::Pop)
|
||||
|
@ -116,6 +116,16 @@ impl Path {
|
||||
}
|
||||
}
|
||||
|
||||
// Only used for weird serialization magic.
|
||||
pub fn dummy() -> Path {
|
||||
Path {
|
||||
steps: VecDeque::new(),
|
||||
end_dist: Distance::ZERO,
|
||||
total_length: Distance::ZERO,
|
||||
crossed_so_far: Distance::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn num_lanes(&self) -> usize {
|
||||
let mut count = 0;
|
||||
for s in &self.steps {
|
||||
|
@ -22,6 +22,11 @@ pub struct Analytics {
|
||||
// TODO This subsumes finished_trips
|
||||
pub trip_log: Vec<(Time, TripID, Option<PathRequest>, String)>,
|
||||
pub intersection_delays: BTreeMap<IntersectionID, Vec<(Time, Duration)>>,
|
||||
|
||||
// After we restore from a savestate, don't record anything. This is only going to make sense
|
||||
// if savestates are only used for quickly previewing against prebaked results, where we have
|
||||
// the full Analytics anyway.
|
||||
record_anything: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Derivative)]
|
||||
@ -54,10 +59,15 @@ impl Analytics {
|
||||
finished_trips: Vec::new(),
|
||||
trip_log: Vec::new(),
|
||||
intersection_delays: BTreeMap::new(),
|
||||
record_anything: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event(&mut self, ev: Event, time: Time, map: &Map) {
|
||||
if !self.record_anything {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Plumb a flag
|
||||
let raw_thruput = true;
|
||||
|
||||
@ -480,7 +490,9 @@ impl Analytics {
|
||||
|
||||
impl Default for Analytics {
|
||||
fn default() -> Analytics {
|
||||
Analytics::new()
|
||||
let mut a = Analytics::new();
|
||||
a.record_anything = false;
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ use abstutil::Cloneable;
|
||||
use geom::{Distance, Pt2D, Speed, Time};
|
||||
use map_model::{
|
||||
BuildingID, BusStopID, DirectedRoadID, IntersectionID, LaneID, Map, Path, PathConstraints,
|
||||
Position,
|
||||
PathRequest, Position,
|
||||
};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
@ -453,6 +453,7 @@ pub struct CreatePedestrian {
|
||||
pub start: SidewalkSpot,
|
||||
pub speed: Speed,
|
||||
pub goal: SidewalkSpot,
|
||||
pub req: PathRequest,
|
||||
pub path: Path,
|
||||
pub trip: TripID,
|
||||
}
|
||||
@ -461,6 +462,7 @@ pub struct CreatePedestrian {
|
||||
pub struct CreateCar {
|
||||
pub vehicle: Vehicle,
|
||||
pub router: Router,
|
||||
pub req: PathRequest,
|
||||
pub start_dist: Distance,
|
||||
pub maybe_parked_car: Option<ParkedCar>,
|
||||
pub trip: TripID,
|
||||
@ -471,11 +473,13 @@ impl CreateCar {
|
||||
vehicle: Vehicle,
|
||||
start_pos: Position,
|
||||
router: Router,
|
||||
req: PathRequest,
|
||||
trip: TripID,
|
||||
) -> CreateCar {
|
||||
CreateCar {
|
||||
vehicle,
|
||||
router,
|
||||
req,
|
||||
start_dist: start_pos.dist_along(),
|
||||
maybe_parked_car: None,
|
||||
trip,
|
||||
@ -486,12 +490,14 @@ impl CreateCar {
|
||||
pub fn for_parked_car(
|
||||
parked_car: ParkedCar,
|
||||
router: Router,
|
||||
req: PathRequest,
|
||||
start_dist: Distance,
|
||||
trip: TripID,
|
||||
) -> CreateCar {
|
||||
CreateCar {
|
||||
vehicle: parked_car.vehicle.clone(),
|
||||
router,
|
||||
req,
|
||||
start_dist,
|
||||
maybe_parked_car: Some(parked_car),
|
||||
trip,
|
||||
|
@ -61,18 +61,21 @@ impl SimFlags {
|
||||
|
||||
let mut opts = self.opts.clone();
|
||||
|
||||
if self.load.starts_with("../data/player/save/") {
|
||||
if self.load.starts_with("../data/player/saves/") {
|
||||
timer.note(format!("Resuming from {}", self.load));
|
||||
|
||||
let sim: Sim = abstutil::read_binary(self.load.clone(), timer);
|
||||
let mut sim: Sim = abstutil::read_binary(self.load.clone(), timer);
|
||||
|
||||
let mut map = Map::new(abstutil::path_map(&sim.map_name), false, timer);
|
||||
map.apply_edits(
|
||||
MapEdits::load(map.get_name(), &sim.edits_name, timer),
|
||||
timer,
|
||||
);
|
||||
map.mark_edits_fresh();
|
||||
map.recalculate_pathfinding_after_edits(timer);
|
||||
if sim.edits_name != "no_edits" {
|
||||
map.apply_edits(
|
||||
MapEdits::load(map.get_name(), &sim.edits_name, timer),
|
||||
timer,
|
||||
);
|
||||
map.mark_edits_fresh();
|
||||
map.recalculate_pathfinding_after_edits(timer);
|
||||
}
|
||||
sim.restore_paths(&map, timer);
|
||||
|
||||
(map, sim, rng)
|
||||
} else if self.load.starts_with("../data/system/scenarios/") {
|
||||
|
@ -231,8 +231,7 @@ impl TripSpawner {
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnCar(
|
||||
CreateCar::for_appearing(vehicle, start_pos, router, trip),
|
||||
req,
|
||||
CreateCar::for_appearing(vehicle, start_pos, router, req, trip),
|
||||
retry_if_no_room,
|
||||
),
|
||||
);
|
||||
@ -278,17 +277,15 @@ impl TripSpawner {
|
||||
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,
|
||||
},
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: parking_spot,
|
||||
path,
|
||||
req,
|
||||
),
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
@ -311,18 +308,16 @@ impl TripSpawner {
|
||||
|
||||
scheduler.quick_push(
|
||||
start_time,
|
||||
Command::SpawnPed(
|
||||
CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start: SidewalkSpot::building(start_bldg, map),
|
||||
goal: walk_to,
|
||||
// This is guaranteed to work, and is junk anyway.
|
||||
path: maybe_path.unwrap(),
|
||||
trip,
|
||||
},
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start: SidewalkSpot::building(start_bldg, map),
|
||||
goal: walk_to,
|
||||
// This is guaranteed to work, and is junk anyway.
|
||||
path: maybe_path.unwrap(),
|
||||
req,
|
||||
),
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
}
|
||||
TripSpec::JustWalking {
|
||||
@ -346,17 +341,15 @@ impl TripSpawner {
|
||||
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,
|
||||
},
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal,
|
||||
path,
|
||||
req,
|
||||
),
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
@ -404,17 +397,15 @@ impl TripSpawner {
|
||||
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,
|
||||
},
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
req,
|
||||
),
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
@ -453,17 +444,15 @@ impl TripSpawner {
|
||||
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,
|
||||
},
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped_id.unwrap(),
|
||||
speed: ped_speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
req,
|
||||
),
|
||||
trip,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
timer.warn(format!(
|
||||
|
@ -329,6 +329,10 @@ impl Router {
|
||||
self.path.modify_step(2, PathStep::Lane(best_lane), map);
|
||||
self.path.modify_step(3, PathStep::Turn(turn2), map);
|
||||
}
|
||||
|
||||
pub fn replace_path_for_serialization(&mut self, path: Path) -> Path {
|
||||
std::mem::replace(&mut self.path, path)
|
||||
}
|
||||
}
|
||||
|
||||
// Unrealistically assumes the driver has knowledge of currently free parking spots, even if
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{AgentID, CarID, CreateCar, CreatePedestrian, PedestrianID};
|
||||
use derivative::Derivative;
|
||||
use geom::{Duration, DurationHistogram, Time};
|
||||
use map_model::{IntersectionID, PathRequest};
|
||||
use map_model::{IntersectionID, Path, PathRequest};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{BTreeMap, BinaryHeap};
|
||||
@ -9,8 +9,8 @@ use std::collections::{BTreeMap, BinaryHeap};
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
pub enum Command {
|
||||
// If true, retry when there's no room to spawn somewhere
|
||||
SpawnCar(CreateCar, PathRequest, bool),
|
||||
SpawnPed(CreatePedestrian, PathRequest),
|
||||
SpawnCar(CreateCar, bool),
|
||||
SpawnPed(CreatePedestrian),
|
||||
UpdateCar(CarID),
|
||||
// Distinguish this from UpdateCar to avoid confusing things
|
||||
UpdateLaggyHead(CarID),
|
||||
@ -29,8 +29,8 @@ impl Command {
|
||||
|
||||
pub fn to_type(&self) -> CommandType {
|
||||
match self {
|
||||
Command::SpawnCar(ref create, _, _) => CommandType::Car(create.vehicle.id),
|
||||
Command::SpawnPed(ref create, _) => CommandType::Ped(create.id),
|
||||
Command::SpawnCar(ref create, _) => CommandType::Car(create.vehicle.id),
|
||||
Command::SpawnPed(ref create) => CommandType::Ped(create.id),
|
||||
Command::UpdateCar(id) => CommandType::Car(*id),
|
||||
Command::UpdateLaggyHead(id) => CommandType::CarLaggyHead(*id),
|
||||
Command::UpdatePed(id) => CommandType::Ped(*id),
|
||||
@ -184,4 +184,63 @@ impl Scheduler {
|
||||
pub fn describe_stats(&self) -> String {
|
||||
format!("delta times for events: {}", self.delta_times.describe())
|
||||
}
|
||||
|
||||
// It's much more efficient to save without the paths, and to recalculate them when loading
|
||||
// later.
|
||||
// TODO Why not just implement Default on Path and use skip_serializing? Because we want to
|
||||
// serialize paths inside Router for live agents. We need to defer calling make_router and just
|
||||
// store the input in CreateCar.
|
||||
pub fn get_requests_for_savestate(&self) -> Vec<PathRequest> {
|
||||
let mut reqs = Vec::new();
|
||||
for (cmd, _) in self.queued_commands.values() {
|
||||
match cmd {
|
||||
Command::SpawnCar(ref create_car, _) => {
|
||||
reqs.push(create_car.req.clone());
|
||||
}
|
||||
Command::SpawnPed(ref create_ped) => {
|
||||
reqs.push(create_ped.req.clone());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
reqs
|
||||
}
|
||||
|
||||
pub fn before_savestate(&mut self) -> Vec<Path> {
|
||||
let mut restore = Vec::new();
|
||||
for (cmd, _) in self.queued_commands.values_mut() {
|
||||
match cmd {
|
||||
Command::SpawnCar(ref mut create_car, _) => {
|
||||
restore.push(
|
||||
create_car
|
||||
.router
|
||||
.replace_path_for_serialization(Path::dummy()),
|
||||
);
|
||||
}
|
||||
Command::SpawnPed(ref mut create_ped) => {
|
||||
restore.push(std::mem::replace(&mut create_ped.path, Path::dummy()));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
restore
|
||||
}
|
||||
|
||||
pub fn after_savestate(&mut self, mut restore: Vec<Path>) {
|
||||
restore.reverse();
|
||||
for (cmd, _) in self.queued_commands.values_mut() {
|
||||
match cmd {
|
||||
Command::SpawnCar(ref mut create_car, _) => {
|
||||
create_car
|
||||
.router
|
||||
.replace_path_for_serialization(restore.pop().unwrap());
|
||||
}
|
||||
Command::SpawnPed(ref mut create_ped) => {
|
||||
std::mem::replace(&mut create_ped.path, restore.pop().unwrap());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
assert!(restore.is_empty());
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ impl Sim {
|
||||
|
||||
// Try to spawn just ONE bus anywhere.
|
||||
// TODO Be more realistic. One bus per stop is too much, one is too little.
|
||||
for (next_stop_idx, mut path, end_dist) in
|
||||
for (next_stop_idx, req, mut path, end_dist) in
|
||||
self.transit.create_empty_route(route, map).into_iter()
|
||||
{
|
||||
let id = CarID(self.car_id_counter, VehicleType::Bus);
|
||||
@ -251,10 +251,12 @@ impl Sim {
|
||||
l
|
||||
} else {
|
||||
path.shift(map);
|
||||
// TODO Technically should update request, but it shouldn't matter
|
||||
continue;
|
||||
};
|
||||
if map.get_l(start_lane).length() < vehicle.length {
|
||||
path.shift(map);
|
||||
// TODO Technically should update request, but it shouldn't matter
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -264,6 +266,7 @@ impl Sim {
|
||||
CreateCar {
|
||||
start_dist: vehicle.length,
|
||||
vehicle: vehicle.clone(),
|
||||
req: req.clone(),
|
||||
router: Router::follow_bus_route(path.clone(), end_dist),
|
||||
maybe_parked_car: None,
|
||||
trip,
|
||||
@ -377,7 +380,7 @@ impl Sim {
|
||||
self.time = time;
|
||||
let mut events = Vec::new();
|
||||
match cmd {
|
||||
Command::SpawnCar(create_car, req, retry_if_no_room) => {
|
||||
Command::SpawnCar(create_car, retry_if_no_room) => {
|
||||
if self.driving.start_car_on_lane(
|
||||
self.time,
|
||||
create_car.clone(),
|
||||
@ -395,7 +398,7 @@ impl Sim {
|
||||
}
|
||||
events.push(Event::TripPhaseStarting(
|
||||
create_car.trip,
|
||||
Some(req),
|
||||
Some(create_car.req.clone()),
|
||||
format!("{}", create_car.vehicle.id),
|
||||
));
|
||||
self.analytics
|
||||
@ -404,7 +407,7 @@ impl Sim {
|
||||
// TODO Record this in the trip log
|
||||
self.scheduler.push(
|
||||
self.time + BLIND_RETRY_TO_SPAWN,
|
||||
Command::SpawnCar(create_car, req, retry_if_no_room),
|
||||
Command::SpawnCar(create_car, retry_if_no_room),
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
@ -414,19 +417,19 @@ impl Sim {
|
||||
self.trips.abort_trip_failed_start(create_car.trip);
|
||||
}
|
||||
}
|
||||
Command::SpawnPed(mut create_ped, mut req) => {
|
||||
Command::SpawnPed(mut create_ped) => {
|
||||
let ok = if let SidewalkPOI::DeferredParkingSpot(b, driving_goal) =
|
||||
create_ped.goal.connection.clone()
|
||||
{
|
||||
if let Some(parked_car) = self.parking.dynamically_reserve_car(b) {
|
||||
create_ped.goal =
|
||||
SidewalkSpot::parking_spot(parked_car.spot, map, &self.parking);
|
||||
req = PathRequest {
|
||||
create_ped.req = PathRequest {
|
||||
start: create_ped.start.sidewalk_pos,
|
||||
end: create_ped.goal.sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
};
|
||||
if let Some(path) = map.pathfind(req.clone()) {
|
||||
if let Some(path) = map.pathfind(create_ped.req.clone()) {
|
||||
create_ped.path = path;
|
||||
let mut legs = vec![
|
||||
TripLeg::Walk(
|
||||
@ -478,7 +481,7 @@ impl Sim {
|
||||
);
|
||||
events.push(Event::TripPhaseStarting(
|
||||
create_ped.trip,
|
||||
Some(req),
|
||||
Some(create_ped.req.clone()),
|
||||
format!(
|
||||
"{} from {:?} to {:?}",
|
||||
create_ped.id,
|
||||
@ -724,7 +727,9 @@ impl Sim {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn save(&self) -> String {
|
||||
pub fn save(&mut self) -> String {
|
||||
let restore = self.scheduler.before_savestate();
|
||||
|
||||
if true {
|
||||
println!("sim savestate breakdown:");
|
||||
println!(
|
||||
@ -763,6 +768,9 @@ impl Sim {
|
||||
|
||||
let path = self.save_path(self.time);
|
||||
abstutil::write_binary(path.clone(), self);
|
||||
|
||||
self.scheduler.after_savestate(restore);
|
||||
|
||||
path
|
||||
}
|
||||
|
||||
@ -774,8 +782,23 @@ impl Sim {
|
||||
abstutil::find_next_file(self.save_path(base_time))
|
||||
}
|
||||
|
||||
pub fn load_savestate(path: String, timer: &mut Timer) -> Result<Sim, std::io::Error> {
|
||||
abstutil::maybe_read_binary(path, timer)
|
||||
pub fn load_savestate(
|
||||
path: String,
|
||||
map: &Map,
|
||||
timer: &mut Timer,
|
||||
) -> Result<Sim, std::io::Error> {
|
||||
let mut sim: Sim = abstutil::maybe_read_binary(path, timer)?;
|
||||
sim.restore_paths(map, timer);
|
||||
Ok(sim)
|
||||
}
|
||||
|
||||
pub fn restore_paths(&mut self, map: &Map, timer: &mut Timer) {
|
||||
let paths = timer.parallelize(
|
||||
"calculate paths",
|
||||
self.scheduler.get_requests_for_savestate(),
|
||||
|req| map.pathfind(req).unwrap(),
|
||||
);
|
||||
self.scheduler.after_savestate(paths);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ type StopIdx = usize;
|
||||
struct StopForRoute {
|
||||
id: BusStopID,
|
||||
driving_pos: Position,
|
||||
req: PathRequest,
|
||||
path_to_next_stop: Path,
|
||||
next_stop_idx: StopIdx,
|
||||
}
|
||||
@ -74,7 +75,7 @@ impl TransitSimState {
|
||||
&mut self,
|
||||
bus_route: &BusRoute,
|
||||
map: &Map,
|
||||
) -> Vec<(StopIdx, Path, Distance)> {
|
||||
) -> Vec<(StopIdx, PathRequest, Path, Distance)> {
|
||||
assert!(bus_route.stops.len() > 1);
|
||||
|
||||
let route = Route {
|
||||
@ -90,19 +91,19 @@ impl TransitSimState {
|
||||
} else {
|
||||
idx + 1
|
||||
};
|
||||
let path = map
|
||||
.pathfind(PathRequest {
|
||||
start: stop1.driving_pos,
|
||||
end: map.get_bs(bus_route.stops[stop2_idx]).driving_pos,
|
||||
constraints: PathConstraints::Bus,
|
||||
})
|
||||
.expect(&format!(
|
||||
"No route between bus stops {:?} and {:?}",
|
||||
stop1_id, bus_route.stops[stop2_idx]
|
||||
));
|
||||
let req = PathRequest {
|
||||
start: stop1.driving_pos,
|
||||
end: map.get_bs(bus_route.stops[stop2_idx]).driving_pos,
|
||||
constraints: PathConstraints::Bus,
|
||||
};
|
||||
let path = map.pathfind(req.clone()).expect(&format!(
|
||||
"No route between bus stops {:?} and {:?}",
|
||||
stop1_id, bus_route.stops[stop2_idx]
|
||||
));
|
||||
StopForRoute {
|
||||
id: *stop1_id,
|
||||
driving_pos: stop1.driving_pos,
|
||||
req,
|
||||
path_to_next_stop: path,
|
||||
next_stop_idx: stop2_idx,
|
||||
}
|
||||
@ -116,6 +117,7 @@ impl TransitSimState {
|
||||
.map(|s| {
|
||||
(
|
||||
s.next_stop_idx,
|
||||
s.req.clone(),
|
||||
s.path_to_next_stop.clone(),
|
||||
route.stops[s.next_stop_idx].driving_pos.dist_along(),
|
||||
)
|
||||
|
@ -212,8 +212,13 @@ impl TripManager {
|
||||
scheduler.push(
|
||||
now,
|
||||
Command::SpawnCar(
|
||||
CreateCar::for_parked_car(parked_car.clone(), router, start.dist_along(), trip.id),
|
||||
req,
|
||||
CreateCar::for_parked_car(
|
||||
parked_car.clone(),
|
||||
router,
|
||||
req,
|
||||
start.dist_along(),
|
||||
trip.id,
|
||||
),
|
||||
true,
|
||||
),
|
||||
);
|
||||
@ -266,8 +271,7 @@ impl TripManager {
|
||||
scheduler.push(
|
||||
now,
|
||||
Command::SpawnCar(
|
||||
CreateCar::for_appearing(vehicle, driving_pos, router, trip.id),
|
||||
req,
|
||||
CreateCar::for_appearing(vehicle, driving_pos, router, req, trip.id),
|
||||
true,
|
||||
),
|
||||
);
|
||||
@ -630,17 +634,15 @@ impl Trip {
|
||||
|
||||
scheduler.push(
|
||||
now,
|
||||
Command::SpawnPed(
|
||||
CreatePedestrian {
|
||||
id: ped,
|
||||
speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
trip: self.id,
|
||||
},
|
||||
Command::SpawnPed(CreatePedestrian {
|
||||
id: ped,
|
||||
speed,
|
||||
start,
|
||||
goal: walk_to,
|
||||
path,
|
||||
req,
|
||||
),
|
||||
trip: self.id,
|
||||
}),
|
||||
);
|
||||
true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user