Document the sim crate

This commit is contained in:
Dustin Carlino 2020-10-06 18:25:39 -07:00
parent a3b7ed18cd
commit 0f806b2055
26 changed files with 112 additions and 5 deletions

View File

@ -1,3 +1,12 @@
// As a simulation runs, different pieces emit Events. The Analytics object listens to these,
// organizing and storing some information from them. The UI queries Analytics to draw time-series
// and display statistics.
//
// For all maps whose weekday scenario fully runs, the game's release includes some "prebaked
// results." These are just serialized Analytics after running the simulation on a map without any
// edits for the full day. This is the basis of A/B testing -- the player can edit the map, start
// running the simulation, and compare the live Analytics to the prebaked baseline Analytics.
use std::collections::{BTreeMap, VecDeque};
use serde::{Deserialize, Serialize};
@ -20,7 +29,8 @@ pub struct Analytics {
// intersection. So for now, eat the file size cost.
pub traffic_signal_thruput: TimeSeriesCount<CompressedMovementID>,
// Unlike everything else in Analytics, this is just for a moment in time.
// Most fields in Analytics are cumulative over time, but this is just for the current moment
// in time.
pub demand: BTreeMap<MovementID, usize>,
// TODO Reconsider this one
@ -463,6 +473,7 @@ pub struct TripPhase {
pub phase_type: TripPhaseType,
}
// See https://github.com/dabreegster/abstreet/issues/85
#[derive(Clone, Serialize, Deserialize)]
pub struct TimeSeriesCount<X: Ord + Clone> {
// (Road or intersection, type, hour block) -> count for that hour

View File

@ -1,3 +1,6 @@
// Some roads (grouped into zones) may have a cap on the number of vehicles that can enter per
// hour. CapSimState enforces this.
use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize};
@ -77,6 +80,8 @@ impl CapSimState {
true
}
// Before the driving portion of a trip begins, check that the desired path doesn't exceed any
// caps. If so, attempt to reroute around.
pub fn validate_path(
&mut self,
req: &PathRequest,

View File

@ -1,3 +1,6 @@
// As a simulation runs, different systems emit Events. This cleanly separates the internal
// mechanics of the simulation from consumers that just want to know what's happening.
use serde::{Deserialize, Serialize};
use geom::Duration;
@ -10,6 +13,8 @@ use crate::{
AgentID, CarID, OffMapLocation, ParkingSpot, PedestrianID, PersonID, TripID, TripMode,
};
// An Event always occurs at a particular time, plumbed separately to consumers.
//
// Many of these were created for a test framework that's been abandoned. They could be removed or
// have their API adjusted, but it's not urgent; publishing an event that's not used by Analytics
// has no performance impact.

View File

@ -1,3 +1,10 @@
// The sim crate runs a traffic simulation on top of the map_model. See also
// https://dabreegster.github.io/abstreet/trafficsim/index.html.
//
// The simulation is very roughly layered into two pieces: the low-level "mechanics" of simulating
// individual agents over time, and higher-level systems like TripManager and TransitSimState that
// glue together individual goals executed by the agents.
#[macro_use]
extern crate log;

View File

@ -1,3 +1,8 @@
// An activity model creates "people" that follow a set schedule of activities through the day.
// Each activity (like shopping, working, sleeping) lasts some time, and requires the person to go
// somewhere at some time. This is an extremely simple activity model that just uses data inferred
// from OSM.
use rand::seq::SliceRandom;
use rand::Rng;
use rand_xorshift::XorShiftRng;

View File

@ -1,3 +1,6 @@
// Some users of the API (https://dabreegster.github.io/abstreet/dev/api.html) have their own
// simulation input data; import it here.
use serde::Deserialize;
use geom::{Distance, FindClosest, LonLat, Pt2D, Time};

View File

@ -1,3 +1,6 @@
// This is a much more primitive way to randomly generate trips. activity_model.rs has something
// more realistic.
use std::collections::BTreeSet;
use rand::seq::SliceRandom;

View File

@ -1,3 +1,5 @@
// SimFlags specifies a simulation to setup.
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
@ -8,6 +10,10 @@ use crate::{Scenario, ScenarioModifier, Sim, SimOptions};
#[derive(Clone)]
pub struct SimFlags {
// A path to some file.
// - a savestate: restore the simulation exactly from some savestate
// - a scenario
// - some kind of map: start an empty simulation on the map
pub load: String,
pub modifiers: Vec<ScenarioModifier>,
pub rng_seed: u8,
@ -49,7 +55,6 @@ impl SimFlags {
XorShiftRng::from_seed([self.rng_seed; 16])
}
// Convenience method to setup everything.
pub fn load(&self, timer: &mut abstutil::Timer) -> (Map, Sim, XorShiftRng) {
let mut rng = self.make_rng();

View File

@ -1,3 +1,6 @@
// Everything needed to setup a simulation.
// https://dabreegster.github.io/abstreet/trafficsim/travel_demand.html for context.
use rand::{RngCore, SeedableRng};
use rand_xorshift::XorShiftRng;

View File

@ -1,3 +1,5 @@
// Transforms an existing Scenario before instantiating it.
use std::collections::BTreeSet;
use rand::Rng;

View File

@ -1,3 +1,5 @@
// A Scenario describes all the input to a simulation. Usually a scenario covers one day.
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
use std::fmt;
@ -20,7 +22,6 @@ use crate::{
MAX_CAR_LENGTH, MIN_CAR_LENGTH, SPAWN_DIST,
};
// How to start a simulation.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Scenario {
pub scenario_name: String,

View File

@ -1,3 +1,6 @@
// Intermediate structures used to instantiate a Scenario. Badly needs simplification:
// https://github.com/dabreegster/abstreet/issues/258
use serde::{Deserialize, Serialize};
use abstutil::{Parallelism, Timer};

View File

@ -1,3 +1,5 @@
// Represents a single vehicle. Note "car" is a misnomer; it could also be a bus or bike.
use std::collections::VecDeque;
use serde::{Deserialize, Serialize};
@ -245,6 +247,8 @@ impl Car {
}
}
// See https://dabreegster.github.io/abstreet/trafficsim/discrete_event.html for details about the
// state machine encoded here.
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum CarState {
Crossing(TimeInterval, DistanceInterval),

View File

@ -1,3 +1,5 @@
// Simulates vehicles!
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
use serde::{Deserialize, Serialize};

View File

@ -1,3 +1,12 @@
// Manages conflicts at intersections. When an agent has reached the end of a lane, they call
// maybe_start_turn to make a Request. Based on the intersection type (stop sign, traffic signal,
// or a "freeform policy"), the Request gets queued or immediately accepted. When agents finish
// turns or when some time passes (for traffic signals), the intersection also gets a chance to
// react, maybe granting one of the pending requests.
//
// Most of the complexity comes from attempting to workaround
// https://dabreegster.github.io/abstreet/trafficsim/gridlock.html.
use std::collections::{BTreeMap, BTreeSet, HashSet};
use serde::{Deserialize, Serialize};

View File

@ -1,3 +1,8 @@
// Manages the state of parked cars. There are two implementations:
// - NormalParkingSimState allows only one vehicle per ParkingSpot defined in the map
// - InfiniteParkingSimState pretends every building has infinite capacity, and onstreet parking is
// ignored
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap};
use enum_dispatch::enum_dispatch;

View File

@ -1,3 +1,7 @@
// A Queue of vehicles on a single lane or turn. No over-taking or lane-changing. This is where
// https://dabreegster.github.io/abstreet/trafficsim/discrete_event.html#exact-positions is
// implemented.
use std::collections::{BTreeMap, BTreeSet, VecDeque};
use serde::{Deserialize, Serialize};

View File

@ -1,3 +1,7 @@
// Simulates pedestrians. Unlike vehicles, pedestrians can move bidirectionally on sidewalks and
// just "ghost" through each other. There's no queueing or slowdown when many people are
// overlapping. They're simply grouped together into a DrawPedCrowdInput for rendering.
use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize};

View File

@ -1,3 +1,7 @@
// An experimental SEIR model by https://github.com/omalaspinas/ glued to the traffic simulation.
// Transmission may occur when people spend time in shared spaces like buildings, bus stops, and
// buses.
use std::ops;
pub use pandemic::{Cmd, PandemicModel};

View File

@ -1,9 +1,10 @@
// Intermediate structures so that sim and game crates don't have a cyclic dependency.
use geom::{Angle, Distance, PolyLine, Pt2D, Time};
use map_model::{BuildingID, Map, ParkingLotID, Traversable, TurnID};
use crate::{CarID, PedestrianID, PersonID, VehicleType};
// Intermediate structures so that sim and game crates don't have a cyclic dependency.
#[derive(Clone)]
pub struct DrawPedestrianInput {
pub id: PedestrianID,

View File

@ -1,3 +1,6 @@
// For vehicles only, not pedestrians. Follows a Path from map_model, but can opportunistically
// lane-change to avoid a slow lane, can can handle re-planning to look for available parking.
use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};

View File

@ -1,3 +1,7 @@
// The priority queue driving the discrete event simulation. Different pieces of the simulation
// schedule Commands to happen at a specific time, and the Scheduler hands out the commands in
// order.
use std::cmp::Ordering;
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, BinaryHeap};

View File

@ -1,3 +1,6 @@
// The Sim ties together all the pieces of the simulation. Its main property is the current time.
// This file has a jumbled mess of queries, setup, and mutating methods.
use std::collections::{BTreeSet, HashSet};
use std::panic;

View File

@ -1,3 +1,5 @@
// All sorts of read-only queries about a simulation
use std::collections::{BTreeMap, HashSet};
use abstutil::Counter;
@ -13,7 +15,6 @@ use crate::{
TripResult, VehicleType,
};
// Queries of all sorts
// TODO Many of these just delegate to an inner piece. This is unorganized and hard to maintain.
impl Sim {
pub fn time(&self) -> Time {

View File

@ -1,3 +1,6 @@
// Manages public transit vehicles (buses and trains) that follow a route. The transit model is
// currently kind of broken, so not describing the state machine yet.
use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize};

View File

@ -1,3 +1,10 @@
// Manages people, each of which executes some trips through the day. Each trip is further broken
// down into legs -- for example, a driving trip might start with somebody walking to their car,
// driving somewhere, parking, and then walking to their final destination.
// https://dabreegster.github.io/abstreet/trafficsim/trips.html describes some of the variations.
//
// Here be dragons, keep hands and feet inside the ride at all times...
use std::collections::{BTreeMap, VecDeque};
use serde::{Deserialize, Serialize};