Add a third TripEndpoint case to appear at an exact Position (lane + distance). This is a necessary step before simplifying Scenario's IndividTrip to use TripEndpoints and mode instead of SpawnTrip. #258

This commit is contained in:
Dustin Carlino 2020-11-17 10:50:42 -08:00
parent 5ea3c2ba6f
commit 2abeebc55e
9 changed files with 61 additions and 22 deletions

View File

@ -383,6 +383,7 @@ pub fn schedule(
}
}
TripEndpoint::Border(_) => "off-map".to_string(),
TripEndpoint::SuddenlyAppear(_) => "suddenly appear".to_string(),
};
rows.push(
Text::from(Line(format!(
@ -412,6 +413,7 @@ pub fn schedule(
}
}
TripEndpoint::Border(_) => "off-map".to_string(),
TripEndpoint::SuddenlyAppear(_) => "suddenly disappear".to_string(),
};
rows.push(
Text::from(Line(format!(

View File

@ -899,5 +899,13 @@ fn endpoint(endpt: &TripEndpoint, app: &App) -> (ID, Pt2D, String) {
),
)
}
TripEndpoint::SuddenlyAppear(pos) => (
ID::Lane(pos.lane()),
pos.pt(&app.primary.map),
format!(
"suddenly appear {} along",
pos.dist_along().to_string(&app.opts.units)
),
),
}
}

View File

@ -85,10 +85,12 @@ impl CommuterPatterns {
let block1 = match trip.start {
TripEndpoint::Bldg(b) => bldg_to_block[&b],
TripEndpoint::Border(i) => border_to_block[&i],
TripEndpoint::SuddenlyAppear(_) => continue,
};
let block2 = match trip.end {
TripEndpoint::Bldg(b) => bldg_to_block[&b],
TripEndpoint::Border(i) => border_to_block[&i],
TripEndpoint::SuddenlyAppear(_) => continue,
};
// Totally ignore trips within the same block
if block1 != block2 {
@ -151,6 +153,7 @@ impl CommuterPatterns {
count.inc(self.border_to_block[&i]);
}
}
TripEndpoint::SuddenlyAppear(_) => {}
}
} else {
match trip.start {
@ -162,6 +165,7 @@ impl CommuterPatterns {
count.inc(self.border_to_block[&i]);
}
}
TripEndpoint::SuddenlyAppear(_) => {}
}
}
}

View File

@ -169,6 +169,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
.centered_on(match trip.start {
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
}),
);
batch.append(
@ -182,6 +183,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
.centered_on(match trip.end {
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
}),
);

View File

@ -433,6 +433,7 @@ impl State<App> for AgentSpawner {
match endpt {
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).polygon.clone(),
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
},
);
}
@ -442,6 +443,7 @@ impl State<App> for AgentSpawner {
match endpt {
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).polygon.clone(),
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
},
);
if let Some(p) = poly {
@ -513,8 +515,14 @@ pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
now,
TripSpec::JustWalking {
start: SidewalkSpot::suddenly_appear(
lane.id,
Scenario::rand_dist(&mut rng, 0.1 * lane.length(), 0.9 * lane.length()),
Position::new(
lane.id,
Scenario::rand_dist(
&mut rng,
0.1 * lane.length(),
0.9 * lane.length(),
),
),
map,
),
goal: SidewalkSpot::building(

View File

@ -523,12 +523,12 @@ impl SidewalkSpot {
})
}
pub fn suddenly_appear(l: LaneID, dist: Distance, map: &Map) -> SidewalkSpot {
let lane = map.get_l(l);
pub fn suddenly_appear(pos: Position, map: &Map) -> SidewalkSpot {
let lane = map.get_l(pos.lane());
assert!(lane.is_walkable());
assert!(dist <= lane.length());
assert!(pos.dist_along() <= lane.length());
SidewalkSpot {
sidewalk_pos: Position::new(l, dist),
sidewalk_pos: pos,
connection: SidewalkPOI::SuddenlyAppear,
}
}

View File

@ -159,6 +159,8 @@ impl ScenarioGenerator {
(TripEndpoint::Border(_), TripEndpoint::Border(_)) => {
num_trips_passthru += 1;
}
(TripEndpoint::SuddenlyAppear(_), _) => unreachable!(),
(_, TripEndpoint::SuddenlyAppear(_)) => unreachable!(),
};
(home, work, fork_rng(rng))

View File

@ -511,9 +511,7 @@ impl SpawnTrip {
pub fn start(&self, map: &Map) -> TripEndpoint {
match self {
SpawnTrip::VehicleAppearing { ref start, .. } => {
TripEndpoint::Border(map.get_l(start.lane()).src_i)
}
SpawnTrip::VehicleAppearing { start, .. } => TripEndpoint::SuddenlyAppear(*start),
SpawnTrip::FromBorder { dr, .. } => TripEndpoint::Border(dr.src_i(map)),
SpawnTrip::UsingParkedCar(b, _) => TripEndpoint::Bldg(*b),
SpawnTrip::UsingBike(b, _) => TripEndpoint::Bldg(*b),
@ -521,9 +519,7 @@ impl SpawnTrip {
match spot.connection {
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
SidewalkPOI::SuddenlyAppear => {
TripEndpoint::Border(map.get_l(spot.sidewalk_pos.lane()).src_i)
}
SidewalkPOI::SuddenlyAppear => TripEndpoint::SuddenlyAppear(spot.sidewalk_pos),
_ => unreachable!(),
}
}
@ -565,6 +561,11 @@ impl SpawnTrip {
goal: to.driving_goal(PathConstraints::Car, map)?,
is_bike: false,
},
TripEndpoint::SuddenlyAppear(start) => SpawnTrip::VehicleAppearing {
start,
goal: to.driving_goal(PathConstraints::Bike, map)?,
is_bike: false,
},
},
TripMode::Bike => match from {
TripEndpoint::Bldg(b) => {
@ -575,6 +576,11 @@ impl SpawnTrip {
goal: to.driving_goal(PathConstraints::Bike, map)?,
is_bike: true,
},
TripEndpoint::SuddenlyAppear(start) => SpawnTrip::VehicleAppearing {
start,
goal: to.driving_goal(PathConstraints::Bike, map)?,
is_bike: true,
},
},
TripMode::Walk => {
SpawnTrip::JustWalking(from.start_sidewalk_spot(map)?, to.end_sidewalk_spot(map)?)
@ -610,11 +616,11 @@ impl PersonSpec {
// Once off-map, re-enter via any border node.
let end_bldg = match pair.0.trip.end(map) {
TripEndpoint::Bldg(b) => Some(b),
TripEndpoint::Border(_) => None,
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => None,
};
let start_bldg = match pair.1.trip.start(map) {
TripEndpoint::Bldg(b) => Some(b),
TripEndpoint::Border(_) => None,
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => None,
};
if end_bldg != start_bldg {

View File

@ -150,7 +150,7 @@ impl TripManager {
.push(Event::PersonEntersBuilding(trip.person, b));
PersonState::Inside(b)
}
TripEndpoint::Border(_) => PersonState::OffMap,
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => PersonState::OffMap,
};
}
if let Some(t) = person.trips.last() {
@ -715,20 +715,20 @@ impl TripManager {
if let PersonState::Inside(b) = self.people[person.0].state {
self.events.push(Event::PersonLeavesBuilding(person, b));
}
match trip.info.end {
// Warp to the destination
self.people[person.0].state = match trip.info.end {
TripEndpoint::Bldg(b) => {
self.events.push(Event::PersonEntersBuilding(person, b));
PersonState::Inside(b)
}
TripEndpoint::Border(i) => {
self.events.push(Event::PersonLeavesMap(person, None, i));
PersonState::OffMap
}
}
// Warp to the destination
self.people[person.0].state = match trip.info.end {
TripEndpoint::Bldg(b) => PersonState::Inside(b),
TripEndpoint::Border(_) => PersonState::OffMap,
// Can't end trips here yet
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
};
// Don't forget the car!
if let Some(vehicle) = abandoned_vehicle {
if vehicle.vehicle_type == VehicleType::Car {
@ -1515,10 +1515,13 @@ impl TripMode {
}
}
/// Specifies where a trip begins or ends.
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Clone)]
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 {
@ -1576,6 +1579,7 @@ fn pos(endpt: TripEndpoint, mode: TripMode, from: bool, map: &Map) -> Option<Pos
.map(|l| Position::start(*l))
}),
},
TripEndpoint::SuddenlyAppear(pos) => Some(pos),
}
}
@ -1643,6 +1647,7 @@ impl TripEndpoint {
match self {
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
TripEndpoint::Border(i) => SidewalkSpot::start_at_border(*i, map),
TripEndpoint::SuddenlyAppear(pos) => Some(SidewalkSpot::suddenly_appear(*pos, map)),
}
}
@ -1650,6 +1655,7 @@ impl TripEndpoint {
match self {
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
TripEndpoint::Border(i) => SidewalkSpot::end_at_border(*i, map),
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
}
}
@ -1663,6 +1669,7 @@ impl TripEndpoint {
TripEndpoint::Border(i) => {
DrivingGoal::end_at_border(map.get_i(*i).some_incoming_road(map)?, constraints, map)
}
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
}
}
}