mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Implement the two public TripEndpoint methods in synthpop, but without needing to drag in SidewalkSpot and DrivingGoal
This commit is contained in:
parent
3f8689b9ea
commit
9845d9cae1
@ -462,45 +462,15 @@ impl SidewalkSpot {
|
|||||||
|
|
||||||
// Recall sidewalks are bidirectional.
|
// Recall sidewalks are bidirectional.
|
||||||
pub fn start_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
|
pub fn start_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
|
||||||
let lanes = map
|
Some(SidewalkSpot {
|
||||||
.get_i(i)
|
sidewalk_pos: TripEndpoint::start_walking_at_border(i, map)?,
|
||||||
.get_outgoing_lanes(map, PathConstraints::Pedestrian);
|
connection: SidewalkPOI::Border(i),
|
||||||
if !lanes.is_empty() {
|
})
|
||||||
return Some(SidewalkSpot {
|
|
||||||
sidewalk_pos: Position::start(lanes[0]),
|
|
||||||
connection: SidewalkPOI::Border(i),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
map.get_i(i)
|
|
||||||
.get_incoming_lanes(map, PathConstraints::Pedestrian)
|
|
||||||
.get(0)
|
|
||||||
.map(|l| SidewalkSpot {
|
|
||||||
sidewalk_pos: Position::end(*l, map),
|
|
||||||
connection: SidewalkPOI::Border(i),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
|
pub fn end_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
|
||||||
if let Some(l) = map
|
|
||||||
.get_i(i)
|
|
||||||
.get_incoming_lanes(map, PathConstraints::Pedestrian)
|
|
||||||
.get(0)
|
|
||||||
{
|
|
||||||
return Some(SidewalkSpot {
|
|
||||||
sidewalk_pos: Position::end(*l, map),
|
|
||||||
connection: SidewalkPOI::Border(i),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let lanes = map
|
|
||||||
.get_i(i)
|
|
||||||
.get_outgoing_lanes(map, PathConstraints::Pedestrian);
|
|
||||||
if lanes.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(SidewalkSpot {
|
Some(SidewalkSpot {
|
||||||
sidewalk_pos: Position::start(lanes[0]),
|
sidewalk_pos: TripEndpoint::end_walking_at_border(i, map)?,
|
||||||
connection: SidewalkPOI::Border(i),
|
connection: SidewalkPOI::Border(i),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ impl TripSpec {
|
|||||||
} else {
|
} else {
|
||||||
PathConstraints::Bike
|
PathConstraints::Bike
|
||||||
};
|
};
|
||||||
let goal = to.driving_goal(constraints, map)?;
|
let goal = driving_goal(to, constraints, map)?;
|
||||||
match from {
|
match from {
|
||||||
TripEndpoint::Bldg(start_bldg) => {
|
TripEndpoint::Bldg(start_bldg) => {
|
||||||
if mode == TripMode::Drive {
|
if mode == TripMode::Drive {
|
||||||
@ -266,12 +266,12 @@ impl TripSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TripMode::Walk => TripSpec::JustWalking {
|
TripMode::Walk => TripSpec::JustWalking {
|
||||||
start: from.start_sidewalk_spot(map)?,
|
start: start_sidewalk_spot(from, map)?,
|
||||||
goal: to.end_sidewalk_spot(map)?,
|
goal: end_sidewalk_spot(to, map)?,
|
||||||
},
|
},
|
||||||
TripMode::Transit => {
|
TripMode::Transit => {
|
||||||
let start = from.start_sidewalk_spot(map)?;
|
let start = start_sidewalk_spot(from, map)?;
|
||||||
let goal = to.end_sidewalk_spot(map)?;
|
let goal = end_sidewalk_spot(to, map)?;
|
||||||
if let Some((stop1, maybe_stop2, route)) =
|
if let Some((stop1, maybe_stop2, route)) =
|
||||||
map.should_use_transit(start.sidewalk_pos, goal.sidewalk_pos)
|
map.should_use_transit(start.sidewalk_pos, goal.sidewalk_pos)
|
||||||
{
|
{
|
||||||
@ -291,3 +291,47 @@ impl TripSpec {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn start_sidewalk_spot(endpt: TripEndpoint, map: &Map) -> Result<SidewalkSpot> {
|
||||||
|
match endpt {
|
||||||
|
TripEndpoint::Bldg(b) => Ok(SidewalkSpot::building(b, map)),
|
||||||
|
TripEndpoint::Border(i) => SidewalkSpot::start_at_border(i, map)
|
||||||
|
.ok_or_else(|| anyhow!("can't start walking from {}", i)),
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => Ok(SidewalkSpot::suddenly_appear(pos, map)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_sidewalk_spot(endpt: TripEndpoint, map: &Map) -> Result<SidewalkSpot> {
|
||||||
|
match endpt {
|
||||||
|
TripEndpoint::Bldg(b) => Ok(SidewalkSpot::building(b, map)),
|
||||||
|
TripEndpoint::Border(i) => {
|
||||||
|
SidewalkSpot::end_at_border(i, map).ok_or_else(|| anyhow!("can't end walking at {}", i))
|
||||||
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn driving_goal(
|
||||||
|
endpt: TripEndpoint,
|
||||||
|
constraints: PathConstraints,
|
||||||
|
map: &Map,
|
||||||
|
) -> Result<DrivingGoal> {
|
||||||
|
match endpt {
|
||||||
|
TripEndpoint::Bldg(b) => Ok(DrivingGoal::ParkNear(b)),
|
||||||
|
// TODO Duplicates some logic from TripEndpoint::pos
|
||||||
|
TripEndpoint::Border(i) => map
|
||||||
|
.get_i(i)
|
||||||
|
.some_incoming_road(map)
|
||||||
|
.and_then(|dr| {
|
||||||
|
let lanes = dr.lanes(constraints, map);
|
||||||
|
if lanes.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// TODO ideally could use any
|
||||||
|
Some(DrivingGoal::Border(dr.dst_i(map), lanes[0]))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok_or_else(|| anyhow!("can't end at {} for {:?}", i, constraints)),
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
use std::collections::{BTreeMap, HashSet, VecDeque};
|
use std::collections::{BTreeMap, HashSet, VecDeque};
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
|
|
||||||
use abstutil::{prettyprint_usize, Counter, Timer};
|
use abstutil::{prettyprint_usize, Counter, Timer};
|
||||||
use geom::{Distance, Pt2D, Speed};
|
use geom::{Distance, Speed};
|
||||||
use map_model::{
|
use map_model::{BuildingID, Map, OffstreetParking, RoadID};
|
||||||
BuildingID, Map, OffstreetParking, PathConstraints, PathRequest, Position, RoadID,
|
|
||||||
};
|
|
||||||
use synthpop::{PersonSpec, Scenario, TripEndpoint, TripMode};
|
use synthpop::{PersonSpec, Scenario, TripEndpoint, TripMode};
|
||||||
|
|
||||||
use crate::make::fork_rng;
|
use crate::make::fork_rng;
|
||||||
use crate::{
|
use crate::{
|
||||||
DrivingGoal, ParkingSpot, SidewalkSpot, Sim, StartTripArgs, TripInfo, Vehicle, VehicleSpec,
|
ParkingSpot, Sim, StartTripArgs, TripInfo, Vehicle, VehicleSpec, VehicleType, BIKE_LENGTH,
|
||||||
VehicleType, BIKE_LENGTH, MAX_CAR_LENGTH, MIN_CAR_LENGTH,
|
MAX_CAR_LENGTH, MIN_CAR_LENGTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Sim {
|
impl Sim {
|
||||||
@ -366,111 +363,3 @@ pub fn count_parked_cars_per_bldg(scenario: &Scenario) -> Counter<BuildingID> {
|
|||||||
}
|
}
|
||||||
per_bldg
|
per_bldg
|
||||||
}
|
}
|
||||||
|
|
||||||
/*impl TripEndpoint {
|
|
||||||
/// Figure out a single PathRequest that goes between two TripEndpoints. Assume a single mode
|
|
||||||
/// the entire time -- no walking to a car before driving, for instance. The result probably
|
|
||||||
/// won't be exactly what would happen on a real trip between the endpoints because of this
|
|
||||||
/// assumption.
|
|
||||||
pub fn path_req(
|
|
||||||
from: TripEndpoint,
|
|
||||||
to: TripEndpoint,
|
|
||||||
mode: TripMode,
|
|
||||||
map: &Map,
|
|
||||||
) -> Option<PathRequest> {
|
|
||||||
let start = from.pos(mode, true, map)?;
|
|
||||||
let end = to.pos(mode, false, map)?;
|
|
||||||
Some(match mode {
|
|
||||||
TripMode::Walk | TripMode::Transit => PathRequest::walking(start, end),
|
|
||||||
TripMode::Bike => PathRequest::vehicle(start, end, PathConstraints::Bike),
|
|
||||||
// Only cars leaving from a building might turn out from the driveway in a special way
|
|
||||||
TripMode::Drive => {
|
|
||||||
if matches!(from, TripEndpoint::Bldg(_)) {
|
|
||||||
PathRequest::leave_from_driveway(start, end, PathConstraints::Car, map)
|
|
||||||
} else {
|
|
||||||
PathRequest::vehicle(start, end, PathConstraints::Car)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_sidewalk_spot(&self, map: &Map) -> Result<SidewalkSpot> {
|
|
||||||
match self {
|
|
||||||
TripEndpoint::Bldg(b) => Ok(SidewalkSpot::building(*b, map)),
|
|
||||||
TripEndpoint::Border(i) => SidewalkSpot::start_at_border(*i, map)
|
|
||||||
.ok_or_else(|| anyhow!("can't start walking from {}", i)),
|
|
||||||
TripEndpoint::SuddenlyAppear(pos) => Ok(SidewalkSpot::suddenly_appear(*pos, map)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_sidewalk_spot(&self, map: &Map) -> Result<SidewalkSpot> {
|
|
||||||
match self {
|
|
||||||
TripEndpoint::Bldg(b) => Ok(SidewalkSpot::building(*b, map)),
|
|
||||||
TripEndpoint::Border(i) => SidewalkSpot::end_at_border(*i, map)
|
|
||||||
.ok_or_else(|| anyhow!("can't end walking at {}", i)),
|
|
||||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn driving_goal(&self, constraints: PathConstraints, map: &Map) -> Result<DrivingGoal> {
|
|
||||||
match self {
|
|
||||||
TripEndpoint::Bldg(b) => Ok(DrivingGoal::ParkNear(*b)),
|
|
||||||
TripEndpoint::Border(i) => map
|
|
||||||
.get_i(*i)
|
|
||||||
.some_incoming_road(map)
|
|
||||||
.and_then(|dr| {
|
|
||||||
let lanes = dr.lanes(constraints, map);
|
|
||||||
if lanes.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
// TODO ideally could use any
|
|
||||||
Some(DrivingGoal::Border(dr.dst_i(map), lanes[0]))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ok_or_else(|| anyhow!("can't end at {} for {:?}", i, constraints)),
|
|
||||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pos(self, mode: TripMode, from: bool, map: &Map) -> Option<Position> {
|
|
||||||
match mode {
|
|
||||||
TripMode::Walk | TripMode::Transit => (if from {
|
|
||||||
self.start_sidewalk_spot(map)
|
|
||||||
} else {
|
|
||||||
self.end_sidewalk_spot(map)
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.map(|spot| spot.sidewalk_pos),
|
|
||||||
TripMode::Drive | TripMode::Bike => {
|
|
||||||
if from {
|
|
||||||
match self {
|
|
||||||
// Fall through and use DrivingGoal also to start.
|
|
||||||
TripEndpoint::Bldg(_) => {}
|
|
||||||
TripEndpoint::Border(i) => {
|
|
||||||
return map.get_i(i).some_outgoing_road(map).and_then(|dr| {
|
|
||||||
dr.lanes(mode.to_constraints(), map)
|
|
||||||
.get(0)
|
|
||||||
.map(|l| Position::start(*l))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
TripEndpoint::SuddenlyAppear(pos) => {
|
|
||||||
return Some(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.driving_goal(mode.to_constraints(), map)
|
|
||||||
.ok()
|
|
||||||
.and_then(|goal| goal.goal_pos(mode.to_constraints(), map))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a point representing where this endpoint is.
|
|
||||||
pub fn pt(&self, map: &Map) -> Pt2D {
|
|
||||||
match self {
|
|
||||||
TripEndpoint::Bldg(b) => map.get_b(*b).polygon.center(),
|
|
||||||
TripEndpoint::Border(i) => map.get_i(*i).polygon.center(),
|
|
||||||
TripEndpoint::SuddenlyAppear(pos) => pos.pt(map),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
154
synthpop/src/endpoint.rs
Normal file
154
synthpop/src/endpoint.rs
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
use geom::Pt2D;
|
||||||
|
use map_model::{BuildingID, IntersectionID, Map, PathConstraints, PathRequest, Position};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::TripMode;
|
||||||
|
|
||||||
|
/// Specifies where a trip begins or ends.
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||||
|
pub enum TripEndpoint {
|
||||||
|
Bldg(BuildingID),
|
||||||
|
Border(IntersectionID),
|
||||||
|
/// Used for interactive spawning, tests, etc. For now, only valid as a trip's start.
|
||||||
|
SuddenlyAppear(Position),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TripEndpoint {
|
||||||
|
/// Returns a point representing where this endpoint is.
|
||||||
|
pub fn pt(self, map: &Map) -> Pt2D {
|
||||||
|
match self {
|
||||||
|
TripEndpoint::Bldg(b) => map.get_b(b).polygon.center(),
|
||||||
|
TripEndpoint::Border(i) => map.get_i(i).polygon.center(),
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => pos.pt(map),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Figure out a single PathRequest that goes between two TripEndpoints. Assume a single mode
|
||||||
|
/// the entire time -- no walking to a car before driving, for instance. The result probably
|
||||||
|
/// won't be exactly what would happen on a real trip between the endpoints because of this
|
||||||
|
/// assumption.
|
||||||
|
pub fn path_req(
|
||||||
|
from: TripEndpoint,
|
||||||
|
to: TripEndpoint,
|
||||||
|
mode: TripMode,
|
||||||
|
map: &Map,
|
||||||
|
) -> Option<PathRequest> {
|
||||||
|
let start = from.pos(mode, true, map)?;
|
||||||
|
let end = to.pos(mode, false, map)?;
|
||||||
|
Some(match mode {
|
||||||
|
TripMode::Walk | TripMode::Transit => PathRequest::walking(start, end),
|
||||||
|
TripMode::Bike => PathRequest::vehicle(start, end, PathConstraints::Bike),
|
||||||
|
// Only cars leaving from a building might turn out from the driveway in a special way
|
||||||
|
TripMode::Drive => {
|
||||||
|
if matches!(from, TripEndpoint::Bldg(_)) {
|
||||||
|
PathRequest::leave_from_driveway(start, end, PathConstraints::Car, map)
|
||||||
|
} else {
|
||||||
|
PathRequest::vehicle(start, end, PathConstraints::Car)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pos(self, mode: TripMode, from: bool, map: &Map) -> Option<Position> {
|
||||||
|
match mode {
|
||||||
|
TripMode::Walk | TripMode::Transit => self.sidewalk_pos(map, from),
|
||||||
|
TripMode::Drive | TripMode::Bike => {
|
||||||
|
let constraints = mode.to_constraints();
|
||||||
|
if from {
|
||||||
|
match self {
|
||||||
|
// Fall through
|
||||||
|
TripEndpoint::Bldg(_) => {}
|
||||||
|
TripEndpoint::Border(i) => {
|
||||||
|
return map.get_i(i).some_outgoing_road(map).and_then(|dr| {
|
||||||
|
dr.lanes(constraints, map)
|
||||||
|
.get(0)
|
||||||
|
.map(|l| Position::start(*l))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => {
|
||||||
|
return Some(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self {
|
||||||
|
TripEndpoint::Bldg(b) => match constraints {
|
||||||
|
PathConstraints::Car => {
|
||||||
|
let driving_lane = map.find_driving_lane_near_building(b);
|
||||||
|
let sidewalk_pos = map.get_b(b).sidewalk_pos;
|
||||||
|
if driving_lane.road == sidewalk_pos.lane().road {
|
||||||
|
Some(sidewalk_pos.equiv_pos(driving_lane, map))
|
||||||
|
} else {
|
||||||
|
Some(Position::start(driving_lane))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathConstraints::Bike => Some(map.get_b(b).biking_connection(map)?.0),
|
||||||
|
PathConstraints::Bus
|
||||||
|
| PathConstraints::Train
|
||||||
|
| PathConstraints::Pedestrian => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TripEndpoint::Border(i) => {
|
||||||
|
map.get_i(i).some_incoming_road(map).and_then(|dr| {
|
||||||
|
let lanes = dr.lanes(constraints, map);
|
||||||
|
if lanes.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// TODO ideally could use any
|
||||||
|
Some(Position::end(lanes[0], map))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sidewalk_pos(self, map: &Map, from: bool) -> Option<Position> {
|
||||||
|
match self {
|
||||||
|
TripEndpoint::Bldg(b) => Some(map.get_b(b).sidewalk_pos),
|
||||||
|
TripEndpoint::Border(i) => {
|
||||||
|
if from {
|
||||||
|
TripEndpoint::start_walking_at_border(i, map)
|
||||||
|
} else {
|
||||||
|
TripEndpoint::end_walking_at_border(i, map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => Some(pos),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recall sidewalks are bidirectional.
|
||||||
|
pub fn start_walking_at_border(i: IntersectionID, map: &Map) -> Option<Position> {
|
||||||
|
let lanes = map
|
||||||
|
.get_i(i)
|
||||||
|
.get_outgoing_lanes(map, PathConstraints::Pedestrian);
|
||||||
|
if !lanes.is_empty() {
|
||||||
|
return Some(Position::start(lanes[0]));
|
||||||
|
}
|
||||||
|
map.get_i(i)
|
||||||
|
.get_incoming_lanes(map, PathConstraints::Pedestrian)
|
||||||
|
.get(0)
|
||||||
|
.map(|l| Position::end(*l, map))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end_walking_at_border(i: IntersectionID, map: &Map) -> Option<Position> {
|
||||||
|
if let Some(l) = map
|
||||||
|
.get_i(i)
|
||||||
|
.get_incoming_lanes(map, PathConstraints::Pedestrian)
|
||||||
|
.get(0)
|
||||||
|
{
|
||||||
|
return Some(Position::end(*l, map));
|
||||||
|
}
|
||||||
|
|
||||||
|
let lanes = map
|
||||||
|
.get_i(i)
|
||||||
|
.get_outgoing_lanes(map, PathConstraints::Pedestrian);
|
||||||
|
if lanes.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Position::start(lanes[0]))
|
||||||
|
}
|
||||||
|
}
|
@ -6,25 +6,18 @@ extern crate log;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use abstutil::{deserialize_usize, serialize_usize};
|
use abstutil::{deserialize_usize, serialize_usize};
|
||||||
use map_model::{BuildingID, IntersectionID, PathConstraints, Position};
|
use map_model::PathConstraints;
|
||||||
|
|
||||||
|
pub use self::endpoint::TripEndpoint;
|
||||||
pub use self::external::{ExternalPerson, ExternalTrip, ExternalTripEndpoint, MapBorders};
|
pub use self::external::{ExternalPerson, ExternalTrip, ExternalTripEndpoint, MapBorders};
|
||||||
pub use self::modifier::ScenarioModifier;
|
pub use self::modifier::ScenarioModifier;
|
||||||
pub use self::scenario::{IndividTrip, PersonSpec, Scenario, TripPurpose};
|
pub use self::scenario::{IndividTrip, PersonSpec, Scenario, TripPurpose};
|
||||||
|
|
||||||
|
mod endpoint;
|
||||||
mod external;
|
mod external;
|
||||||
mod modifier;
|
mod modifier;
|
||||||
mod scenario;
|
mod scenario;
|
||||||
|
|
||||||
/// Specifies where a trip begins or ends.
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
|
||||||
pub enum TripEndpoint {
|
|
||||||
Bldg(BuildingID),
|
|
||||||
Border(IntersectionID),
|
|
||||||
/// Used for interactive spawning, tests, etc. For now, only valid as a trip's start.
|
|
||||||
SuddenlyAppear(Position),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)]
|
||||||
pub enum TripMode {
|
pub enum TripMode {
|
||||||
Walk,
|
Walk,
|
||||||
|
Loading…
Reference in New Issue
Block a user