mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
plumb through exact off-map locations from popdat->scenario
This commit is contained in:
parent
65ef5d4149
commit
dd1c9f936d
@ -91,16 +91,16 @@ d14c96851d6289b867e008432f54320d data/input/neighborhoods/caphill/Broadway.json
|
||||
955835e85d15a2fb6c4a8586b8e5cb73 data/input/neighborhoods/caphill/Montlake.json
|
||||
19e8073a9f6c807b4492681b2c7570de data/input/blockface.bin
|
||||
db63d7d606e8702d12f9399e87e6a00f data/input/parcels_urbansim.txt
|
||||
dc1968d1701598bccf41d1f396ae23e9 data/input/raw_maps/huge_seattle.bin
|
||||
e59204b20ae17a56e128e4d8b0c3b447 data/input/raw_maps/ballard.bin
|
||||
5474231e70e6edbf16837a0b54bdf33e data/input/raw_maps/downtown.bin
|
||||
194e089ea73b6dd383d84ab64661c0f3 data/input/raw_maps/caphill.bin
|
||||
6ea08ee5c85c302671b569cb3113387d data/input/raw_maps/lakeslice.bin
|
||||
dd7a37e55ccfb450d87ad3195ba614c9 data/input/raw_maps/montlake.bin
|
||||
b26a07ee49ec56a5ca80b2e01a56f1b5 data/input/raw_maps/intl_district.bin
|
||||
14eaa51e2ed5235b2423300fc41b93a3 data/input/raw_maps/23rd.bin
|
||||
0bea891a45667240ff5d5d0d8b484c1c data/input/raw_maps/huge_seattle.bin
|
||||
a6f96f5e96b520783684778561a965c6 data/input/raw_maps/ballard.bin
|
||||
21d44b9ca54677ef0c301e238382e536 data/input/raw_maps/downtown.bin
|
||||
c80b13eaf83c11fb34a8c92611c33f82 data/input/raw_maps/caphill.bin
|
||||
556045ed604ac0ff2312b45eef17f3ab data/input/raw_maps/lakeslice.bin
|
||||
3edecaa20da69f94f920fd6a8252ce45 data/input/raw_maps/montlake.bin
|
||||
2b34d9513ec0d9782216d8723060eeb3 data/input/raw_maps/intl_district.bin
|
||||
671b84c17f8137503cba9036fbd71257 data/input/raw_maps/23rd.bin
|
||||
2bc84e4d194d7cea6007ae3b93f3b11b data/input/neighborhoods.geojson
|
||||
a0461cb7047fbc6f8f44a284cd6c19a4 data/input/popdat.bin
|
||||
416bfeea026d52aa8989f496fae5fe29 data/input/popdat.bin
|
||||
428bc2e92ea02089cedbb614ce1d8f25 data/input/polygons/caphill.poly
|
||||
4f291bbe84ac32a98d7d100be79ddc4b data/input/polygons/huge_seattle.poly
|
||||
6b221b5e68a38f16f34e46a208c7ca15 data/input/polygons/lakeslice.poly
|
||||
@ -110,26 +110,26 @@ a0461cb7047fbc6f8f44a284cd6c19a4 data/input/popdat.bin
|
||||
0304847f270859fcfc19c8ca122ed793 data/input/polygons/23rd.poly
|
||||
54f5f16e5ec925cb29b4d1405a89ef94 data/input/polygons/downtown.poly
|
||||
58485a3bdff2aea9769fffd207e3cf30 data/input/offstreet_parking.bin
|
||||
139f6e0a688bd07a69a4984495b3f2e5 data/input/screenshots/montlake/02x05_i124.png
|
||||
87b182b3e4269b955fff61a41198da44 data/input/screenshots/montlake/01x06_i26.png
|
||||
1717bfb53aa375bd3359de6e7db860ff data/input/screenshots/montlake/01x01_i19.png
|
||||
7c3927abc1b31191c7c24efeb6e9940f data/input/screenshots/montlake/MANIFEST
|
||||
b681d564271051e5e60cb63d0ee1d6b1 data/input/screenshots/montlake/03x06_i27.png
|
||||
89abe949e1a8184a084df873dbace415 data/input/screenshots/montlake/02x03_i1.png
|
||||
612d5c710d77ae2fcd639fc8c1716dac data/input/screenshots/montlake/02x04_i25.png
|
||||
2b2fffe66932402f6885865217a13175 data/input/screenshots/montlake/03x02_i8.png
|
||||
75ea4a81b2371fa1b03d756c8fc0fa54 data/input/screenshots/montlake/01x04_i31.png
|
||||
7dbf9830b6a37f6e58d3effc54363de7 data/input/screenshots/montlake/02x05_i124.png
|
||||
244fe61defcf394590775582ef438f17 data/input/screenshots/montlake/01x06_i26.png
|
||||
e6e912d845568358261fd74576b57f87 data/input/screenshots/montlake/01x01_i19.png
|
||||
d0720059c524ec65637eb8184a1a41c8 data/input/screenshots/montlake/MANIFEST
|
||||
d66611b36bd11a567f1b8da95420fc9f data/input/screenshots/montlake/03x06_i27.png
|
||||
4fdfb67049a6208f6b929154cea457d3 data/input/screenshots/montlake/02x03_i1.png
|
||||
a84ce197439197750399b91522158c81 data/input/screenshots/montlake/02x04_i25.png
|
||||
a13baeaa78255c5b14f0cd6826ee6495 data/input/screenshots/montlake/03x02_i8.png
|
||||
c6f46ce8b497eb1b4fa2823cf99468a7 data/input/screenshots/montlake/01x04_i31.png
|
||||
4f507c78977c8ff62f4c2a0e011329ee data/input/screenshots/montlake/combine.sh
|
||||
301fa5745ff7c7e1c43e7300e38add50 data/input/screenshots/montlake/03x01_i0.png
|
||||
e0f2b904b21fec546372c737bc4872da data/input/screenshots/montlake/01x03_i4.png
|
||||
482f9da940c8c9ed52aa81fcd04b34bc data/input/screenshots/montlake/01x02_i20.png
|
||||
b1929464274d34c3bce5040821f7869d data/input/screenshots/montlake/03x04_i112.png
|
||||
33b3c92b72edd8fd757e2df73eb87a52 data/input/screenshots/montlake/02x02_i288.png
|
||||
1028e0631bdfcc27913de602356b89e0 data/input/screenshots/montlake/03x03_i59.png
|
||||
587a29517ab20ebe69c03cc2d0eb6b9e data/input/screenshots/montlake/02x01_i24.png
|
||||
3a92ad12d5875db4dabb7f04bc684435 data/input/screenshots/montlake/03x05_i2.png
|
||||
3d3733fb494ca616e4070c9146206ebf data/input/screenshots/montlake/02x06_i85.png
|
||||
25855b7aa895686d13bd054d3bba7051 data/input/screenshots/montlake/01x05_i40.png
|
||||
df00e33a986f93e3b33938a927d062a9 data/input/screenshots/montlake/03x01_i0.png
|
||||
3a4dbcb76ce8853f8414abb5fdb727f1 data/input/screenshots/montlake/01x03_i4.png
|
||||
ce30a66567ab09cb1c36d731c15cd5e1 data/input/screenshots/montlake/01x02_i20.png
|
||||
7036b3cf99ed1dfd4e856455f1a4978e data/input/screenshots/montlake/03x04_i112.png
|
||||
1d5849d54d78c0431a9dcbd000fba25c data/input/screenshots/montlake/02x02_i288.png
|
||||
83b0e07b42d2c50a1ab70fbf69abb97d data/input/screenshots/montlake/03x03_i59.png
|
||||
211f6c2a020d2d555574ebaf289d21e9 data/input/screenshots/montlake/02x01_i24.png
|
||||
9eb0005ac206fba788042e655cfbe300 data/input/screenshots/montlake/03x05_i2.png
|
||||
d12a9d72fcbf32cb75d2820a78fa5e22 data/input/screenshots/montlake/02x06_i85.png
|
||||
a7fec0718264a554de0fc282f9737ea0 data/input/screenshots/montlake/01x05_i40.png
|
||||
129b460f56f5eb41cab3bfd70fb5fde9 data/input/sidewalks.bin
|
||||
0db4e23e51f7680538b0bbbc72208e07 data/input/N47W122.hgt
|
||||
51dbf7a263fe5f0ea24e43c3aad3fec2 data/input/google_transit/stop_times.txt
|
||||
@ -217,27 +217,27 @@ d02d0d103f7b00672a5f1145c5169d8c data/system/fonts/Overpass-Bold.ttf
|
||||
2a13391023ce8787887331530cac35a7 data/system/fonts/BungeeInline-Regular.ttf
|
||||
17a1468e62195d0688a6f3bd12da2e92 data/system/fonts/Overpass-SemiBold.ttf
|
||||
259d4afad7edca07e727ef80f5bbce07 data/system/fonts/Bungee-Regular.ttf
|
||||
4e0441582b7b913a89176436b5122bf2 data/system/maps/huge_seattle.bin
|
||||
08d407ab1b9688eee0b83cd65e698560 data/system/maps/ballard.bin
|
||||
19ae5adf392679c4264069bbca23710c data/system/maps/downtown.bin
|
||||
2313d5a3805f07e652127d0010668c80 data/system/maps/caphill.bin
|
||||
a3b5a81b41be4c9f4b0710821c1841bb data/system/maps/lakeslice.bin
|
||||
81057642bc7981331c3fb920147faa75 data/system/maps/montlake.bin
|
||||
750b8e4f996f12d4105a771e26e83192 data/system/maps/intl_district.bin
|
||||
e27d41c916a721b330459ce85a114dbc data/system/maps/23rd.bin
|
||||
812904abcbdca8f86278205f8af26a3e data/system/maps/huge_seattle.bin
|
||||
5c0b0d1c83f43d8d71d744eabff512cb data/system/maps/ballard.bin
|
||||
6a7aead7416ee4ac45899fc6fa2905dd data/system/maps/downtown.bin
|
||||
27c24479582289a6bb47d4de4e5d0242 data/system/maps/caphill.bin
|
||||
34ce6777051eda17e54c0ea855400d11 data/system/maps/lakeslice.bin
|
||||
67712c4d404666a29178e3b7542c1269 data/system/maps/montlake.bin
|
||||
f3b48a58d5af668f02e899ed2e44ef4a data/system/maps/intl_district.bin
|
||||
d6722d5d86547f8fc963e80595d922dd data/system/maps/23rd.bin
|
||||
cc45f42cb24cad1cfdbf5ed7a0cb86d4 data/system/synthetic_maps/signal_double.json
|
||||
8b949cc34d9a27ace0bd8ecde55a9520 data/system/synthetic_maps/signal_single.json
|
||||
1cd7be125e1d992613ed3a41e8b25b6a data/system/synthetic_maps/signal_fan_in.json
|
||||
9f8ab17e0a0c1cf4a0d5964f7e36658e data/system/scenarios/ballard/weekday.bin
|
||||
70b59885920616c1b1677818f6f89d82 data/system/scenarios/intl_district/weekday.bin
|
||||
ccb9e7763427b2d8b4fb6b44b2c4e599 data/system/scenarios/23rd/weekday.bin
|
||||
160825412e11206e8e856cc20920fbf0 data/system/scenarios/lakeslice/weekday.bin
|
||||
a23157b6bc180c457f93430c0683ff69 data/system/scenarios/downtown/weekday.bin
|
||||
1ea056fc3afff56db11be283bb23b6fd data/system/scenarios/huge_seattle/weekday.bin
|
||||
1e9409a0a789de6b22157e3f28ce30bd data/system/scenarios/caphill/weekday.bin
|
||||
f180a68083c44e0e21b65e3e63be8068 data/system/scenarios/montlake/weekday.bin
|
||||
29828738af2ba2f81b1ac49dd64587b9 data/system/scenarios/ballard/weekday.bin
|
||||
23da3f12b1e98f2f531aa121a1a85c04 data/system/scenarios/intl_district/weekday.bin
|
||||
562a97a406e7502e1defcc122919a8cf data/system/scenarios/23rd/weekday.bin
|
||||
797f560c130135c6d2e3248a95748af7 data/system/scenarios/lakeslice/weekday.bin
|
||||
aad8ff309a1b38dc85a5d8a4b37f3c87 data/system/scenarios/downtown/weekday.bin
|
||||
53baae7739ada8cb7276804c0d480618 data/system/scenarios/huge_seattle/weekday.bin
|
||||
112a8e8a1f8e41f566a03ab83d14fe22 data/system/scenarios/caphill/weekday.bin
|
||||
fa8391c0e45db61fabdd466ad81b83fa data/system/scenarios/montlake/weekday.bin
|
||||
80cb748e090072b559b08bdd4bc8c30c data/system/prebaked_results/signal_single/tutorial lvl1.bin
|
||||
ec841305a2dbc37649045f31afce09bd data/system/prebaked_results/signal_single/tutorial lvl2.bin
|
||||
4e26a658e0a9e95859d82d35123b33d5 data/system/prebaked_results/montlake/car vs bike contention.bin
|
||||
25d1542a7cb3bde030a4e10e542e48df data/system/prebaked_results/montlake/weekday.bin
|
||||
2da75e16bd2620e8ed1f8db58e852538 data/system/prebaked_results/montlake/car vs bike contention.bin
|
||||
1faec374216a3afa38e48e29d1317126 data/system/prebaked_results/montlake/weekday.bin
|
||||
02ae8e1b35219ab4934969c07187842b data/system/prebaked_results/montlake/car vs bus contention.bin
|
||||
|
@ -247,7 +247,7 @@ fn describe(person: &PersonSpec, trip: &IndividTrip, home: OD) -> String {
|
||||
b.to_string()
|
||||
}
|
||||
}
|
||||
DrivingGoal::Border(i, _) => {
|
||||
DrivingGoal::Border(i, _, _) => {
|
||||
if OD::Border(*i) == home {
|
||||
"HERE".to_string()
|
||||
} else {
|
||||
@ -263,7 +263,7 @@ fn describe(person: &PersonSpec, trip: &IndividTrip, home: OD) -> String {
|
||||
b.to_string()
|
||||
}
|
||||
}
|
||||
SidewalkPOI::Border(i) => {
|
||||
SidewalkPOI::Border(i, _) => {
|
||||
if OD::Border(*i) == home {
|
||||
"HERE".to_string()
|
||||
} else {
|
||||
@ -286,7 +286,9 @@ fn describe(person: &PersonSpec, trip: &IndividTrip, home: OD) -> String {
|
||||
start.lane(),
|
||||
driving_goal(goal)
|
||||
),
|
||||
SpawnTrip::FromBorder { i, goal, is_bike } => format!(
|
||||
SpawnTrip::FromBorder {
|
||||
i, goal, is_bike, ..
|
||||
} => format!(
|
||||
"{} at {}: {} appears at {}, goes to {}",
|
||||
person.id,
|
||||
trip.depart,
|
||||
@ -333,11 +335,11 @@ fn describe(person: &PersonSpec, trip: &IndividTrip, home: OD) -> String {
|
||||
fn other_endpt(trip: &IndividTrip, home: OD, map: &Map) -> ID {
|
||||
let driving_goal = |goal: &DrivingGoal| match goal {
|
||||
DrivingGoal::ParkNear(b) => ID::Building(*b),
|
||||
DrivingGoal::Border(i, _) => ID::Intersection(*i),
|
||||
DrivingGoal::Border(i, _, _) => ID::Intersection(*i),
|
||||
};
|
||||
let sidewalk_spot = |spot: &SidewalkSpot| match &spot.connection {
|
||||
SidewalkPOI::Building(b) => ID::Building(*b),
|
||||
SidewalkPOI::Border(i) => ID::Intersection(*i),
|
||||
SidewalkPOI::Border(i, _) => ID::Intersection(*i),
|
||||
x => panic!("other_endpt for {:?}?", x),
|
||||
};
|
||||
|
||||
|
@ -104,6 +104,7 @@ impl State for AgentSpawner {
|
||||
if let Some(g) = DrivingGoal::end_at_border(
|
||||
map.get_i(to).some_incoming_road(map),
|
||||
constraints,
|
||||
None,
|
||||
map,
|
||||
) {
|
||||
g.goal_pos(constraints, map)
|
||||
@ -263,7 +264,7 @@ fn schedule_trip(
|
||||
let goal = match raw_goal {
|
||||
Goal::Building(to) => SidewalkSpot::building(to, map),
|
||||
Goal::Border(to) => {
|
||||
if let Some(goal) = SidewalkSpot::end_at_border(to, map) {
|
||||
if let Some(goal) = SidewalkSpot::end_at_border(to, None, map) {
|
||||
goal
|
||||
} else {
|
||||
return Some(format!("Can't end a walking trip at {}; no sidewalks", to));
|
||||
@ -303,6 +304,7 @@ fn schedule_trip(
|
||||
if let Some(g) = DrivingGoal::end_at_border(
|
||||
map.get_i(to).some_incoming_road(map),
|
||||
PathConstraints::Bike,
|
||||
None,
|
||||
map,
|
||||
) {
|
||||
g
|
||||
@ -334,6 +336,7 @@ fn schedule_trip(
|
||||
if let Some(g) = DrivingGoal::end_at_border(
|
||||
map.get_i(to).some_incoming_road(map),
|
||||
PathConstraints::Car,
|
||||
None,
|
||||
map,
|
||||
) {
|
||||
g
|
||||
|
@ -192,6 +192,7 @@ fn import_parcels(
|
||||
Endpoint {
|
||||
pos: pt,
|
||||
osm_building,
|
||||
parcel_id: id,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ pub struct OrigTrip {
|
||||
pub struct Endpoint {
|
||||
pub pos: LonLat,
|
||||
pub osm_building: Option<i64>,
|
||||
pub parcel_id: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
@ -1,9 +1,12 @@
|
||||
use crate::psrc::{Endpoint, Mode, OrigTrip, Parcel};
|
||||
use crate::PopDat;
|
||||
use abstutil::{prettyprint_usize, MultiMap, Timer};
|
||||
use geom::{LonLat, Pt2D};
|
||||
use geom::LonLat;
|
||||
use map_model::{BuildingID, IntersectionID, Map, PathConstraints};
|
||||
use sim::{DrivingGoal, IndividTrip, PersonID, PersonSpec, Scenario, SidewalkSpot, SpawnTrip};
|
||||
use sim::{
|
||||
DrivingGoal, IndividTrip, OffMapLocation, PersonID, PersonSpec, Scenario, SidewalkSpot,
|
||||
SpawnTrip,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -16,19 +19,18 @@ pub struct Trip {
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TripEndpt {
|
||||
Building(BuildingID),
|
||||
// The Pt2D is the original point. It'll be outside the map and likely out-of-bounds entirely,
|
||||
// maybe even negative.
|
||||
Border(IntersectionID, Pt2D),
|
||||
Border(IntersectionID, OffMapLocation),
|
||||
}
|
||||
|
||||
impl Trip {
|
||||
fn to_spawn_trip(&self, map: &Map) -> SpawnTrip {
|
||||
match self.orig.mode {
|
||||
Mode::Drive => match self.from {
|
||||
TripEndpt::Border(i, _) => SpawnTrip::FromBorder {
|
||||
TripEndpt::Border(i, ref origin) => SpawnTrip::FromBorder {
|
||||
i,
|
||||
goal: self.to.driving_goal(PathConstraints::Car, map),
|
||||
is_bike: false,
|
||||
origin: Some(origin.clone()),
|
||||
},
|
||||
TripEndpt::Building(b) => {
|
||||
SpawnTrip::UsingParkedCar(b, self.to.driving_goal(PathConstraints::Car, map))
|
||||
@ -39,10 +41,11 @@ impl Trip {
|
||||
SidewalkSpot::building(b, map),
|
||||
self.to.driving_goal(PathConstraints::Bike, map),
|
||||
),
|
||||
TripEndpt::Border(i, _) => SpawnTrip::FromBorder {
|
||||
TripEndpt::Border(i, ref origin) => SpawnTrip::FromBorder {
|
||||
i,
|
||||
goal: self.to.driving_goal(PathConstraints::Bike, map),
|
||||
is_bike: true,
|
||||
origin: Some(origin.clone()),
|
||||
},
|
||||
},
|
||||
Mode::Walk => SpawnTrip::JustWalking(
|
||||
@ -69,7 +72,6 @@ impl Trip {
|
||||
impl TripEndpt {
|
||||
fn new(
|
||||
endpt: &Endpoint,
|
||||
map: &Map,
|
||||
osm_id_to_bldg: &HashMap<i64, BuildingID>,
|
||||
borders: &Vec<(IntersectionID, LonLat)>,
|
||||
) -> Option<TripEndpt> {
|
||||
@ -82,7 +84,10 @@ impl TripEndpt {
|
||||
.map(|(id, _)| {
|
||||
TripEndpt::Border(
|
||||
*id,
|
||||
Pt2D::forcibly_from_gps(endpt.pos, map.get_gps_bounds()),
|
||||
OffMapLocation {
|
||||
gps: endpt.pos,
|
||||
parcel_id: endpt.parcel_id,
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
@ -90,24 +95,31 @@ impl TripEndpt {
|
||||
fn start_sidewalk_spot(&self, map: &Map) -> SidewalkSpot {
|
||||
match self {
|
||||
TripEndpt::Building(b) => SidewalkSpot::building(*b, map),
|
||||
TripEndpt::Border(i, _) => SidewalkSpot::start_at_border(*i, map).unwrap(),
|
||||
TripEndpt::Border(i, origin) => {
|
||||
SidewalkSpot::start_at_border(*i, Some(origin.clone()), map).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn end_sidewalk_spot(&self, map: &Map) -> SidewalkSpot {
|
||||
match self {
|
||||
TripEndpt::Building(b) => SidewalkSpot::building(*b, map),
|
||||
TripEndpt::Border(i, _) => SidewalkSpot::end_at_border(*i, map).unwrap(),
|
||||
TripEndpt::Border(i, destination) => {
|
||||
SidewalkSpot::end_at_border(*i, Some(destination.clone()), map).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn driving_goal(&self, constraints: PathConstraints, map: &Map) -> DrivingGoal {
|
||||
match self {
|
||||
TripEndpt::Building(b) => DrivingGoal::ParkNear(*b),
|
||||
TripEndpt::Border(i, _) => {
|
||||
DrivingGoal::end_at_border(map.get_i(*i).some_incoming_road(map), constraints, map)
|
||||
.unwrap()
|
||||
}
|
||||
TripEndpt::Border(i, destination) => DrivingGoal::end_at_border(
|
||||
map.get_i(*i).some_incoming_road(map),
|
||||
constraints,
|
||||
Some(destination.clone()),
|
||||
map,
|
||||
)
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,7 +180,6 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
|
||||
let maybe_results: Vec<Option<Trip>> = timer.parallelize("clip trips", popdat.trips, |orig| {
|
||||
let from = TripEndpt::new(
|
||||
&orig.from,
|
||||
map,
|
||||
&osm_id_to_bldg,
|
||||
match orig.mode {
|
||||
Mode::Walk | Mode::Transit => &incoming_borders_walking,
|
||||
@ -178,7 +189,6 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
|
||||
)?;
|
||||
let to = TripEndpt::new(
|
||||
&orig.to,
|
||||
map,
|
||||
&osm_id_to_bldg,
|
||||
match orig.mode {
|
||||
Mode::Walk | Mode::Transit => &outgoing_borders_walking,
|
||||
|
@ -14,8 +14,8 @@ pub use self::analytics::{Analytics, TripPhase};
|
||||
pub(crate) use self::events::Event;
|
||||
pub use self::events::{AlertLocation, TripPhaseType};
|
||||
pub use self::make::{
|
||||
ABTest, BorderSpawnOverTime, IndividTrip, OriginDestination, PersonSpec, Scenario,
|
||||
ScenarioGenerator, SimFlags, SpawnOverTime, SpawnTrip, TripSpawner, TripSpec,
|
||||
ABTest, BorderSpawnOverTime, IndividTrip, OffMapLocation, OriginDestination, PersonSpec,
|
||||
Scenario, ScenarioGenerator, SimFlags, SpawnOverTime, SpawnTrip, TripSpawner, TripSpec,
|
||||
};
|
||||
pub(crate) use self::mechanics::{
|
||||
DrivingSimState, IntersectionSimState, ParkingSimState, WalkingSimState,
|
||||
@ -206,13 +206,14 @@ pub struct ParkedCar {
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum DrivingGoal {
|
||||
ParkNear(BuildingID),
|
||||
Border(IntersectionID, LaneID),
|
||||
Border(IntersectionID, LaneID, Option<OffMapLocation>),
|
||||
}
|
||||
|
||||
impl DrivingGoal {
|
||||
pub fn end_at_border(
|
||||
dr: DirectedRoadID,
|
||||
constraints: PathConstraints,
|
||||
destination: Option<OffMapLocation>,
|
||||
map: &Map,
|
||||
) -> Option<DrivingGoal> {
|
||||
let lanes = dr.lanes(constraints, map);
|
||||
@ -220,7 +221,7 @@ impl DrivingGoal {
|
||||
None
|
||||
} else {
|
||||
// TODO ideally could use any
|
||||
Some(DrivingGoal::Border(dr.dst_i(map), lanes[0]))
|
||||
Some(DrivingGoal::Border(dr.dst_i(map), lanes[0], destination))
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +237,7 @@ impl DrivingGoal {
|
||||
}
|
||||
PathConstraints::Bus | PathConstraints::Pedestrian => unreachable!(),
|
||||
},
|
||||
DrivingGoal::Border(_, l) => Position::new(*l, map.get_l(*l).length()),
|
||||
DrivingGoal::Border(_, l, _) => Position::new(*l, map.get_l(*l).length()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +253,7 @@ impl DrivingGoal {
|
||||
Some(Router::park_near(path, *b))
|
||||
}
|
||||
}
|
||||
DrivingGoal::Border(i, last_lane) => Some(Router::end_at_border(
|
||||
DrivingGoal::Border(i, last_lane, _) => Some(Router::end_at_border(
|
||||
path,
|
||||
map.get_l(*last_lane).length(),
|
||||
*i,
|
||||
@ -263,7 +264,7 @@ impl DrivingGoal {
|
||||
pub fn pt(&self, map: &Map) -> Pt2D {
|
||||
match self {
|
||||
DrivingGoal::ParkNear(b) => map.get_b(*b).polygon.center(),
|
||||
DrivingGoal::Border(i, _) => map.get_i(*i).polygon.center(),
|
||||
DrivingGoal::Border(i, _, _) => map.get_i(*i).polygon.center(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -336,14 +337,18 @@ impl SidewalkSpot {
|
||||
}
|
||||
|
||||
// Recall sidewalks are bidirectional.
|
||||
pub fn start_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
|
||||
pub fn start_at_border(
|
||||
i: IntersectionID,
|
||||
origin: Option<OffMapLocation>,
|
||||
map: &Map,
|
||||
) -> Option<SidewalkSpot> {
|
||||
let lanes = map
|
||||
.get_i(i)
|
||||
.get_outgoing_lanes(map, PathConstraints::Pedestrian);
|
||||
if !lanes.is_empty() {
|
||||
return Some(SidewalkSpot {
|
||||
sidewalk_pos: Position::new(lanes[0], Distance::ZERO),
|
||||
connection: SidewalkPOI::Border(i),
|
||||
connection: SidewalkPOI::Border(i, origin),
|
||||
});
|
||||
}
|
||||
|
||||
@ -355,18 +360,22 @@ impl SidewalkSpot {
|
||||
}
|
||||
Some(SidewalkSpot {
|
||||
sidewalk_pos: Position::new(lanes[0], map.get_l(lanes[0]).length()),
|
||||
connection: SidewalkPOI::Border(i),
|
||||
connection: SidewalkPOI::Border(i, origin),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn end_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
|
||||
pub fn end_at_border(
|
||||
i: IntersectionID,
|
||||
destination: Option<OffMapLocation>,
|
||||
map: &Map,
|
||||
) -> Option<SidewalkSpot> {
|
||||
let lanes = map
|
||||
.get_i(i)
|
||||
.get_incoming_lanes(map, PathConstraints::Pedestrian);
|
||||
if !lanes.is_empty() {
|
||||
return Some(SidewalkSpot {
|
||||
sidewalk_pos: Position::new(lanes[0], map.get_l(lanes[0]).length()),
|
||||
connection: SidewalkPOI::Border(i),
|
||||
connection: SidewalkPOI::Border(i, destination),
|
||||
});
|
||||
}
|
||||
|
||||
@ -378,7 +387,7 @@ impl SidewalkSpot {
|
||||
}
|
||||
Some(SidewalkSpot {
|
||||
sidewalk_pos: Position::new(lanes[0], Distance::ZERO),
|
||||
connection: SidewalkPOI::Border(i),
|
||||
connection: SidewalkPOI::Border(i, destination),
|
||||
})
|
||||
}
|
||||
|
||||
@ -402,7 +411,7 @@ pub enum SidewalkPOI {
|
||||
DeferredParkingSpot,
|
||||
Building(BuildingID),
|
||||
BusStop(BusStopID),
|
||||
Border(IntersectionID),
|
||||
Border(IntersectionID, Option<OffMapLocation>),
|
||||
// The equivalent position on the nearest driving/bike lane
|
||||
BikeRack(Position),
|
||||
SuddenlyAppear,
|
||||
|
@ -281,7 +281,7 @@ impl BorderSpawnOverTime {
|
||||
}
|
||||
|
||||
let start = if let Some(s) =
|
||||
SidewalkSpot::start_at_border(self.start_from_border.src_i(map), map)
|
||||
SidewalkSpot::start_at_border(self.start_from_border.src_i(map), None, map)
|
||||
{
|
||||
s
|
||||
} else {
|
||||
@ -358,6 +358,7 @@ impl BorderSpawnOverTime {
|
||||
i: self.start_from_border.src_i(map),
|
||||
goal,
|
||||
is_bike: constraints == PathConstraints::Bike,
|
||||
origin: None,
|
||||
},
|
||||
}],
|
||||
});
|
||||
@ -388,7 +389,7 @@ impl OriginDestination {
|
||||
)),
|
||||
OriginDestination::GotoBldg(b) => Some(DrivingGoal::ParkNear(*b)),
|
||||
OriginDestination::EndOfRoad(dr) => {
|
||||
let goal = DrivingGoal::end_at_border(*dr, constraints, map);
|
||||
let goal = DrivingGoal::end_at_border(*dr, constraints, None, map);
|
||||
if goal.is_none() {
|
||||
timer.warn(format!(
|
||||
"Can't spawn a {:?} ending at border {}; no appropriate lanes there",
|
||||
@ -413,7 +414,7 @@ impl OriginDestination {
|
||||
map,
|
||||
)),
|
||||
OriginDestination::EndOfRoad(dr) => {
|
||||
let goal = SidewalkSpot::end_at_border(dr.dst_i(map), map);
|
||||
let goal = SidewalkSpot::end_at_border(dr.dst_i(map), None, map);
|
||||
if goal.is_none() {
|
||||
timer.warn(format!("Can't end_at_border for {} without a sidewalk", dr));
|
||||
}
|
||||
|
@ -9,5 +9,5 @@ pub use self::generator::{
|
||||
BorderSpawnOverTime, OriginDestination, ScenarioGenerator, SpawnOverTime,
|
||||
};
|
||||
pub use self::load::SimFlags;
|
||||
pub use self::scenario::{IndividTrip, PersonSpec, Scenario, SpawnTrip};
|
||||
pub use self::scenario::{IndividTrip, OffMapLocation, PersonSpec, Scenario, SpawnTrip};
|
||||
pub use self::spawner::{TripSpawner, TripSpec};
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
TripSpec, Vehicle, VehicleSpec, VehicleType, BIKE_LENGTH, MAX_CAR_LENGTH, MIN_CAR_LENGTH,
|
||||
};
|
||||
use abstutil::{prettyprint_usize, Counter, Timer};
|
||||
use geom::{Distance, Duration, Speed, Time};
|
||||
use geom::{Distance, Duration, LonLat, Speed, Time};
|
||||
use map_model::{
|
||||
BuildingID, BusRouteID, BusStopID, IntersectionID, Map, PathConstraints, Position, RoadID,
|
||||
};
|
||||
@ -38,7 +38,7 @@ pub struct IndividTrip {
|
||||
pub trip: SpawnTrip,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum SpawnTrip {
|
||||
// Only for interactive / debug trips
|
||||
VehicleAppearing {
|
||||
@ -51,6 +51,7 @@ pub enum SpawnTrip {
|
||||
goal: DrivingGoal,
|
||||
// For bikes starting at a border, use FromBorder. UsingBike implies a walk->bike trip.
|
||||
is_bike: bool,
|
||||
origin: Option<OffMapLocation>,
|
||||
},
|
||||
UsingParkedCar(BuildingID, DrivingGoal),
|
||||
UsingBike(SidewalkSpot, DrivingGoal),
|
||||
@ -58,6 +59,12 @@ pub enum SpawnTrip {
|
||||
UsingTransit(SidewalkSpot, SidewalkSpot, BusRouteID, BusStopID, BusStopID),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct OffMapLocation {
|
||||
pub parcel_id: usize,
|
||||
pub gps: LonLat,
|
||||
}
|
||||
|
||||
impl Scenario {
|
||||
// Any case where map edits could change the calls to the RNG, we have to fork.
|
||||
pub fn instantiate(&self, sim: &mut Sim, map: &Map, rng: &mut XorShiftRng, timer: &mut Timer) {
|
||||
@ -398,7 +405,7 @@ impl SpawnTrip {
|
||||
| SpawnTrip::JustWalking(ref spot, _)
|
||||
| SpawnTrip::UsingTransit(ref spot, _, _, _, _) => match spot.connection {
|
||||
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::Border(i, _) => TripEndpoint::Border(i),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
}
|
||||
@ -411,12 +418,12 @@ impl SpawnTrip {
|
||||
| SpawnTrip::UsingParkedCar(_, ref goal)
|
||||
| SpawnTrip::UsingBike(_, ref goal) => match goal {
|
||||
DrivingGoal::ParkNear(b) => TripEndpoint::Bldg(*b),
|
||||
DrivingGoal::Border(i, _) => TripEndpoint::Border(*i),
|
||||
DrivingGoal::Border(i, _, _) => TripEndpoint::Border(*i),
|
||||
},
|
||||
SpawnTrip::JustWalking(_, ref spot) | SpawnTrip::UsingTransit(_, ref spot, _, _, _) => {
|
||||
match spot.connection {
|
||||
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::Border(i, _) => TripEndpoint::Border(i),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -506,7 +513,7 @@ impl PersonSpec {
|
||||
DrivingGoal::ParkNear(b) => {
|
||||
car_locations.push((idx, Some(*b)));
|
||||
}
|
||||
DrivingGoal::Border(_, _) => {
|
||||
DrivingGoal::Border(_, _, _) => {
|
||||
car_locations.push((idx, None));
|
||||
}
|
||||
}
|
||||
@ -536,7 +543,7 @@ impl PersonSpec {
|
||||
DrivingGoal::ParkNear(b) => {
|
||||
car_locations.push((idx, Some(*b)));
|
||||
}
|
||||
DrivingGoal::Border(_, _) => {
|
||||
DrivingGoal::Border(_, _, _) => {
|
||||
car_locations.push((idx, None));
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ impl TripSpawner {
|
||||
);
|
||||
}
|
||||
match goal {
|
||||
DrivingGoal::Border(_, end_lane) => {
|
||||
DrivingGoal::Border(_, end_lane, _) => {
|
||||
if start_pos.lane() == *end_lane
|
||||
&& start_pos.dist_along() == map.get_l(*end_lane).length()
|
||||
{
|
||||
@ -241,7 +241,7 @@ impl TripSpawner {
|
||||
DrivingGoal::ParkNear(b) => {
|
||||
legs.push(TripLeg::Walk(SidewalkSpot::building(b, map)));
|
||||
}
|
||||
DrivingGoal::Border(_, _) => {}
|
||||
DrivingGoal::Border(_, _, _) => {}
|
||||
}
|
||||
trips.new_trip(
|
||||
person.id,
|
||||
@ -259,7 +259,7 @@ impl TripSpawner {
|
||||
SidewalkPOI::SuddenlyAppear => {
|
||||
TripEndpoint::Border(map.get_l(start.sidewalk_pos.lane()).src_i)
|
||||
}
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::Border(i, _) => TripEndpoint::Border(i),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
TripMode::Walk,
|
||||
@ -276,7 +276,7 @@ impl TripSpawner {
|
||||
DrivingGoal::ParkNear(b) => {
|
||||
legs.push(TripLeg::Walk(SidewalkSpot::building(b, map)));
|
||||
}
|
||||
DrivingGoal::Border(_, _) => {}
|
||||
DrivingGoal::Border(_, _, _) => {}
|
||||
};
|
||||
trips.new_trip(
|
||||
person.id,
|
||||
@ -286,7 +286,7 @@ impl TripSpawner {
|
||||
SidewalkPOI::SuddenlyAppear => {
|
||||
TripEndpoint::Border(map.get_l(start.sidewalk_pos.lane()).src_i)
|
||||
}
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::Border(i, _) => TripEndpoint::Border(i),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
TripMode::Bike,
|
||||
@ -309,7 +309,7 @@ impl TripSpawner {
|
||||
SidewalkPOI::SuddenlyAppear => {
|
||||
TripEndpoint::Border(map.get_l(start.sidewalk_pos.lane()).src_i)
|
||||
}
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::Border(i, _) => TripEndpoint::Border(i),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
TripMode::Transit,
|
||||
|
@ -161,7 +161,7 @@ impl WalkingSimState {
|
||||
self.peds.remove(&id);
|
||||
}
|
||||
}
|
||||
SidewalkPOI::Border(i) => {
|
||||
SidewalkPOI::Border(i, _) => {
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_border(
|
||||
|
@ -90,12 +90,12 @@ impl TripManager {
|
||||
let end = match legs.last() {
|
||||
Some(TripLeg::Walk(ref spot)) => match spot.connection {
|
||||
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::Border(i, _) => TripEndpoint::Border(i),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
Some(TripLeg::Drive(_, ref goal)) => match goal {
|
||||
DrivingGoal::ParkNear(b) => TripEndpoint::Bldg(*b),
|
||||
DrivingGoal::Border(i, _) => TripEndpoint::Border(*i),
|
||||
DrivingGoal::Border(i, _, _) => TripEndpoint::Border(*i),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -524,7 +524,13 @@ impl TripManager {
|
||||
.0];
|
||||
trip.total_blocked_time += blocked_time;
|
||||
|
||||
trip.assert_walking_leg(SidewalkSpot::end_at_border(i, map).unwrap());
|
||||
match trip.legs.pop_front() {
|
||||
Some(TripLeg::Walk(spot)) => match spot.connection {
|
||||
SidewalkPOI::Border(i2, _) => assert_eq!(i, i2),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert!(trip.legs.is_empty());
|
||||
assert!(!trip.finished_at.is_some());
|
||||
trip.finished_at = Some(now);
|
||||
@ -555,7 +561,7 @@ impl TripManager {
|
||||
trip.total_blocked_time += blocked_time;
|
||||
|
||||
match trip.legs.pop_front().unwrap() {
|
||||
TripLeg::Drive(c, DrivingGoal::Border(int, _)) => {
|
||||
TripLeg::Drive(c, DrivingGoal::Border(int, _, _)) => {
|
||||
assert_eq!(car, c);
|
||||
assert_eq!(i, int);
|
||||
}
|
||||
@ -987,7 +993,7 @@ impl TripManager {
|
||||
person.state,
|
||||
match start.connection {
|
||||
SidewalkPOI::Building(b) => PersonState::Inside(b),
|
||||
SidewalkPOI::Border(_) => PersonState::OffMap,
|
||||
SidewalkPOI::Border(_, _) => PersonState::OffMap,
|
||||
SidewalkPOI::SuddenlyAppear => PersonState::OffMap,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -1022,7 +1028,7 @@ impl TripManager {
|
||||
person.state,
|
||||
match start.connection {
|
||||
SidewalkPOI::Building(b) => PersonState::Inside(b),
|
||||
SidewalkPOI::Border(_) => PersonState::OffMap,
|
||||
SidewalkPOI::Border(_, _) => PersonState::OffMap,
|
||||
SidewalkPOI::SuddenlyAppear => PersonState::OffMap,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -1059,7 +1065,7 @@ impl TripManager {
|
||||
person.state,
|
||||
match start.connection {
|
||||
SidewalkPOI::Building(b) => PersonState::Inside(b),
|
||||
SidewalkPOI::Border(_) => PersonState::OffMap,
|
||||
SidewalkPOI::Border(_, _) => PersonState::OffMap,
|
||||
SidewalkPOI::SuddenlyAppear => PersonState::OffMap,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user