mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 17:37:22 +03:00
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:
parent
5ea3c2ba6f
commit
2abeebc55e
@ -383,6 +383,7 @@ pub fn schedule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TripEndpoint::Border(_) => "off-map".to_string(),
|
TripEndpoint::Border(_) => "off-map".to_string(),
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => "suddenly appear".to_string(),
|
||||||
};
|
};
|
||||||
rows.push(
|
rows.push(
|
||||||
Text::from(Line(format!(
|
Text::from(Line(format!(
|
||||||
@ -412,6 +413,7 @@ pub fn schedule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TripEndpoint::Border(_) => "off-map".to_string(),
|
TripEndpoint::Border(_) => "off-map".to_string(),
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => "suddenly disappear".to_string(),
|
||||||
};
|
};
|
||||||
rows.push(
|
rows.push(
|
||||||
Text::from(Line(format!(
|
Text::from(Line(format!(
|
||||||
|
@ -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)
|
||||||
|
),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,10 +85,12 @@ impl CommuterPatterns {
|
|||||||
let block1 = match trip.start {
|
let block1 = match trip.start {
|
||||||
TripEndpoint::Bldg(b) => bldg_to_block[&b],
|
TripEndpoint::Bldg(b) => bldg_to_block[&b],
|
||||||
TripEndpoint::Border(i) => border_to_block[&i],
|
TripEndpoint::Border(i) => border_to_block[&i],
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => continue,
|
||||||
};
|
};
|
||||||
let block2 = match trip.end {
|
let block2 = match trip.end {
|
||||||
TripEndpoint::Bldg(b) => bldg_to_block[&b],
|
TripEndpoint::Bldg(b) => bldg_to_block[&b],
|
||||||
TripEndpoint::Border(i) => border_to_block[&i],
|
TripEndpoint::Border(i) => border_to_block[&i],
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => continue,
|
||||||
};
|
};
|
||||||
// Totally ignore trips within the same block
|
// Totally ignore trips within the same block
|
||||||
if block1 != block2 {
|
if block1 != block2 {
|
||||||
@ -151,6 +153,7 @@ impl CommuterPatterns {
|
|||||||
count.inc(self.border_to_block[&i]);
|
count.inc(self.border_to_block[&i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match trip.start {
|
match trip.start {
|
||||||
@ -162,6 +165,7 @@ impl CommuterPatterns {
|
|||||||
count.inc(self.border_to_block[&i]);
|
count.inc(self.border_to_block[&i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
|
|||||||
.centered_on(match trip.start {
|
.centered_on(match trip.start {
|
||||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
|
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
|
||||||
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
|
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
batch.append(
|
batch.append(
|
||||||
@ -182,6 +183,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
|
|||||||
.centered_on(match trip.end {
|
.centered_on(match trip.end {
|
||||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
|
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
|
||||||
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
|
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -433,6 +433,7 @@ impl State<App> for AgentSpawner {
|
|||||||
match endpt {
|
match endpt {
|
||||||
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
|
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
|
||||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).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 {
|
match endpt {
|
||||||
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
|
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
|
||||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).polygon.clone(),
|
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).polygon.clone(),
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if let Some(p) = poly {
|
if let Some(p) = poly {
|
||||||
@ -513,8 +515,14 @@ pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
|
|||||||
now,
|
now,
|
||||||
TripSpec::JustWalking {
|
TripSpec::JustWalking {
|
||||||
start: SidewalkSpot::suddenly_appear(
|
start: SidewalkSpot::suddenly_appear(
|
||||||
lane.id,
|
Position::new(
|
||||||
Scenario::rand_dist(&mut rng, 0.1 * lane.length(), 0.9 * lane.length()),
|
lane.id,
|
||||||
|
Scenario::rand_dist(
|
||||||
|
&mut rng,
|
||||||
|
0.1 * lane.length(),
|
||||||
|
0.9 * lane.length(),
|
||||||
|
),
|
||||||
|
),
|
||||||
map,
|
map,
|
||||||
),
|
),
|
||||||
goal: SidewalkSpot::building(
|
goal: SidewalkSpot::building(
|
||||||
|
@ -523,12 +523,12 @@ impl SidewalkSpot {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suddenly_appear(l: LaneID, dist: Distance, map: &Map) -> SidewalkSpot {
|
pub fn suddenly_appear(pos: Position, map: &Map) -> SidewalkSpot {
|
||||||
let lane = map.get_l(l);
|
let lane = map.get_l(pos.lane());
|
||||||
assert!(lane.is_walkable());
|
assert!(lane.is_walkable());
|
||||||
assert!(dist <= lane.length());
|
assert!(pos.dist_along() <= lane.length());
|
||||||
SidewalkSpot {
|
SidewalkSpot {
|
||||||
sidewalk_pos: Position::new(l, dist),
|
sidewalk_pos: pos,
|
||||||
connection: SidewalkPOI::SuddenlyAppear,
|
connection: SidewalkPOI::SuddenlyAppear,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,8 @@ impl ScenarioGenerator {
|
|||||||
(TripEndpoint::Border(_), TripEndpoint::Border(_)) => {
|
(TripEndpoint::Border(_), TripEndpoint::Border(_)) => {
|
||||||
num_trips_passthru += 1;
|
num_trips_passthru += 1;
|
||||||
}
|
}
|
||||||
|
(TripEndpoint::SuddenlyAppear(_), _) => unreachable!(),
|
||||||
|
(_, TripEndpoint::SuddenlyAppear(_)) => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
(home, work, fork_rng(rng))
|
(home, work, fork_rng(rng))
|
||||||
|
@ -511,9 +511,7 @@ impl SpawnTrip {
|
|||||||
|
|
||||||
pub fn start(&self, map: &Map) -> TripEndpoint {
|
pub fn start(&self, map: &Map) -> TripEndpoint {
|
||||||
match self {
|
match self {
|
||||||
SpawnTrip::VehicleAppearing { ref start, .. } => {
|
SpawnTrip::VehicleAppearing { start, .. } => TripEndpoint::SuddenlyAppear(*start),
|
||||||
TripEndpoint::Border(map.get_l(start.lane()).src_i)
|
|
||||||
}
|
|
||||||
SpawnTrip::FromBorder { dr, .. } => TripEndpoint::Border(dr.src_i(map)),
|
SpawnTrip::FromBorder { dr, .. } => TripEndpoint::Border(dr.src_i(map)),
|
||||||
SpawnTrip::UsingParkedCar(b, _) => TripEndpoint::Bldg(*b),
|
SpawnTrip::UsingParkedCar(b, _) => TripEndpoint::Bldg(*b),
|
||||||
SpawnTrip::UsingBike(b, _) => TripEndpoint::Bldg(*b),
|
SpawnTrip::UsingBike(b, _) => TripEndpoint::Bldg(*b),
|
||||||
@ -521,9 +519,7 @@ impl SpawnTrip {
|
|||||||
match spot.connection {
|
match spot.connection {
|
||||||
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
|
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
|
||||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||||
SidewalkPOI::SuddenlyAppear => {
|
SidewalkPOI::SuddenlyAppear => TripEndpoint::SuddenlyAppear(spot.sidewalk_pos),
|
||||||
TripEndpoint::Border(map.get_l(spot.sidewalk_pos.lane()).src_i)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,6 +561,11 @@ impl SpawnTrip {
|
|||||||
goal: to.driving_goal(PathConstraints::Car, map)?,
|
goal: to.driving_goal(PathConstraints::Car, map)?,
|
||||||
is_bike: false,
|
is_bike: false,
|
||||||
},
|
},
|
||||||
|
TripEndpoint::SuddenlyAppear(start) => SpawnTrip::VehicleAppearing {
|
||||||
|
start,
|
||||||
|
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
||||||
|
is_bike: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
TripMode::Bike => match from {
|
TripMode::Bike => match from {
|
||||||
TripEndpoint::Bldg(b) => {
|
TripEndpoint::Bldg(b) => {
|
||||||
@ -575,6 +576,11 @@ impl SpawnTrip {
|
|||||||
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
||||||
is_bike: true,
|
is_bike: true,
|
||||||
},
|
},
|
||||||
|
TripEndpoint::SuddenlyAppear(start) => SpawnTrip::VehicleAppearing {
|
||||||
|
start,
|
||||||
|
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
||||||
|
is_bike: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
TripMode::Walk => {
|
TripMode::Walk => {
|
||||||
SpawnTrip::JustWalking(from.start_sidewalk_spot(map)?, to.end_sidewalk_spot(map)?)
|
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.
|
// Once off-map, re-enter via any border node.
|
||||||
let end_bldg = match pair.0.trip.end(map) {
|
let end_bldg = match pair.0.trip.end(map) {
|
||||||
TripEndpoint::Bldg(b) => Some(b),
|
TripEndpoint::Bldg(b) => Some(b),
|
||||||
TripEndpoint::Border(_) => None,
|
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => None,
|
||||||
};
|
};
|
||||||
let start_bldg = match pair.1.trip.start(map) {
|
let start_bldg = match pair.1.trip.start(map) {
|
||||||
TripEndpoint::Bldg(b) => Some(b),
|
TripEndpoint::Bldg(b) => Some(b),
|
||||||
TripEndpoint::Border(_) => None,
|
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if end_bldg != start_bldg {
|
if end_bldg != start_bldg {
|
||||||
|
@ -150,7 +150,7 @@ impl TripManager {
|
|||||||
.push(Event::PersonEntersBuilding(trip.person, b));
|
.push(Event::PersonEntersBuilding(trip.person, b));
|
||||||
PersonState::Inside(b)
|
PersonState::Inside(b)
|
||||||
}
|
}
|
||||||
TripEndpoint::Border(_) => PersonState::OffMap,
|
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => PersonState::OffMap,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if let Some(t) = person.trips.last() {
|
if let Some(t) = person.trips.last() {
|
||||||
@ -715,20 +715,20 @@ impl TripManager {
|
|||||||
if let PersonState::Inside(b) = self.people[person.0].state {
|
if let PersonState::Inside(b) = self.people[person.0].state {
|
||||||
self.events.push(Event::PersonLeavesBuilding(person, b));
|
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) => {
|
TripEndpoint::Bldg(b) => {
|
||||||
self.events.push(Event::PersonEntersBuilding(person, b));
|
self.events.push(Event::PersonEntersBuilding(person, b));
|
||||||
|
PersonState::Inside(b)
|
||||||
}
|
}
|
||||||
TripEndpoint::Border(i) => {
|
TripEndpoint::Border(i) => {
|
||||||
self.events.push(Event::PersonLeavesMap(person, None, i));
|
self.events.push(Event::PersonLeavesMap(person, None, i));
|
||||||
|
PersonState::OffMap
|
||||||
}
|
}
|
||||||
}
|
// Can't end trips here yet
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
// Warp to the destination
|
|
||||||
self.people[person.0].state = match trip.info.end {
|
|
||||||
TripEndpoint::Bldg(b) => PersonState::Inside(b),
|
|
||||||
TripEndpoint::Border(_) => PersonState::OffMap,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't forget the car!
|
// Don't forget the car!
|
||||||
if let Some(vehicle) = abandoned_vehicle {
|
if let Some(vehicle) = abandoned_vehicle {
|
||||||
if vehicle.vehicle_type == VehicleType::Car {
|
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)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Clone)]
|
||||||
pub enum TripEndpoint {
|
pub enum TripEndpoint {
|
||||||
Bldg(BuildingID),
|
Bldg(BuildingID),
|
||||||
Border(IntersectionID),
|
Border(IntersectionID),
|
||||||
|
/// Used for interactive spawning, tests, etc. For now, only valid as a trip's start.
|
||||||
|
SuddenlyAppear(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TripEndpoint {
|
impl TripEndpoint {
|
||||||
@ -1576,6 +1579,7 @@ fn pos(endpt: TripEndpoint, mode: TripMode, from: bool, map: &Map) -> Option<Pos
|
|||||||
.map(|l| Position::start(*l))
|
.map(|l| Position::start(*l))
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
TripEndpoint::SuddenlyAppear(pos) => Some(pos),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1643,6 +1647,7 @@ impl TripEndpoint {
|
|||||||
match self {
|
match self {
|
||||||
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
|
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
|
||||||
TripEndpoint::Border(i) => SidewalkSpot::start_at_border(*i, 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 {
|
match self {
|
||||||
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
|
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
|
||||||
TripEndpoint::Border(i) => SidewalkSpot::end_at_border(*i, map),
|
TripEndpoint::Border(i) => SidewalkSpot::end_at_border(*i, map),
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1663,6 +1669,7 @@ impl TripEndpoint {
|
|||||||
TripEndpoint::Border(i) => {
|
TripEndpoint::Border(i) => {
|
||||||
DrivingGoal::end_at_border(map.get_i(*i).some_incoming_road(map)?, constraints, map)
|
DrivingGoal::end_at_border(map.get_i(*i).some_incoming_road(map)?, constraints, map)
|
||||||
}
|
}
|
||||||
|
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user