mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
clean up dupe logic in popdat for figuring out path from a trip. instead just repeat the main path used in simulation layer
This commit is contained in:
parent
8ed42e9fb6
commit
f73e0c15af
@ -29,9 +29,14 @@ impl TripsVisualizer {
|
||||
let trips = ctx.loading_screen("load trip data", |_, mut timer| {
|
||||
let (all_trips, _) = clip_trips(&ui.primary.map, &mut timer);
|
||||
let map = &ui.primary.map;
|
||||
let sim = &ui.primary.sim;
|
||||
let flags = &ui.primary.current_flags.sim_flags;
|
||||
let maybe_trips =
|
||||
timer.parallelize("calculate paths with geometry", all_trips, |trip| {
|
||||
if let Some(req) = trip.path_req(map) {
|
||||
if let Some(spawn_trip) = trip.to_spawn_trip(map) {
|
||||
let mut rng = flags.make_rng();
|
||||
let (_, spec) = spawn_trip.to_trip_spec(&mut rng);
|
||||
let req = sim.trip_spec_to_path_req(&spec, map);
|
||||
if let Some(route) = map
|
||||
.pathfind(req.clone())
|
||||
.and_then(|path| path.trace(map, req.start.dist_along(), None))
|
||||
|
@ -2,9 +2,7 @@ use crate::psrc::{Endpoint, Mode, Parcel, Purpose};
|
||||
use crate::PopDat;
|
||||
use abstutil::Timer;
|
||||
use geom::{Distance, Duration, LonLat, Polygon, Pt2D};
|
||||
use map_model::{
|
||||
BuildingID, IntersectionID, LaneType, Map, PathConstraints, PathRequest, Position,
|
||||
};
|
||||
use map_model::{BuildingID, IntersectionID, LaneType, Map, PathConstraints, Position};
|
||||
use sim::{DrivingGoal, Scenario, SidewalkSpot, SpawnTrip, TripSpec};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
@ -33,48 +31,86 @@ impl Trip {
|
||||
self.depart_at + self.trip_time
|
||||
}
|
||||
|
||||
pub fn path_req(&self, map: &Map) -> Option<PathRequest> {
|
||||
Some(match self.mode {
|
||||
Mode::Walk => PathRequest {
|
||||
start: self.from.start_sidewalk_spot(map).sidewalk_pos,
|
||||
end: self.from.end_sidewalk_spot(map).sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
},
|
||||
Mode::Bike => PathRequest {
|
||||
start: self.from.start_pos_driving(map)?,
|
||||
end: self
|
||||
.to
|
||||
.driving_goal(PathConstraints::Bike, map)
|
||||
.goal_pos(map),
|
||||
constraints: PathConstraints::Bike,
|
||||
},
|
||||
Mode::Drive => PathRequest {
|
||||
start: self.from.start_pos_driving(map)?,
|
||||
end: self
|
||||
.to
|
||||
.driving_goal(PathConstraints::Car, map)
|
||||
.goal_pos(map),
|
||||
constraints: PathConstraints::Car,
|
||||
},
|
||||
Mode::Transit => {
|
||||
let start = self.from.start_sidewalk_spot(map).sidewalk_pos;
|
||||
let end = self.to.end_sidewalk_spot(map).sidewalk_pos;
|
||||
if let Some((stop1, _, _)) = map.should_use_transit(start, end) {
|
||||
PathRequest {
|
||||
start,
|
||||
end: SidewalkSpot::bus_stop(stop1, map).sidewalk_pos,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
}
|
||||
} else {
|
||||
// Just fall back to walking. :\
|
||||
PathRequest {
|
||||
start,
|
||||
end,
|
||||
constraints: PathConstraints::Pedestrian,
|
||||
pub fn to_spawn_trip(&self, map: &Map) -> Option<SpawnTrip> {
|
||||
match self.mode {
|
||||
Mode::Drive => match self.from {
|
||||
TripEndpt::Border(i, _) => {
|
||||
if let Some(start) = TripSpec::spawn_car_at(
|
||||
Position::new(
|
||||
map.get_i(i).get_outgoing_lanes(map, LaneType::Driving)[0],
|
||||
Distance::ZERO,
|
||||
),
|
||||
map,
|
||||
) {
|
||||
Some(SpawnTrip::CarAppearing {
|
||||
depart: self.depart_at,
|
||||
start,
|
||||
goal: self.to.driving_goal(PathConstraints::Car, map),
|
||||
is_bike: false,
|
||||
})
|
||||
} else {
|
||||
// TODO need to be able to emit warnings from parallelize
|
||||
//timer.warn(format!("No room for car to appear at {:?}", self.from));
|
||||
None
|
||||
}
|
||||
}
|
||||
TripEndpt::Building(b) => Some(SpawnTrip::MaybeUsingParkedCar(
|
||||
self.depart_at,
|
||||
b,
|
||||
self.to.driving_goal(PathConstraints::Car, map),
|
||||
)),
|
||||
},
|
||||
Mode::Bike => match self.from {
|
||||
TripEndpt::Building(b) => Some(SpawnTrip::UsingBike(
|
||||
self.depart_at,
|
||||
SidewalkSpot::building(b, map),
|
||||
self.to.driving_goal(PathConstraints::Bike, map),
|
||||
)),
|
||||
TripEndpt::Border(i, _) => {
|
||||
if let Some(start) = TripSpec::spawn_car_at(
|
||||
Position::new(
|
||||
map.get_i(i).get_outgoing_lanes(map, LaneType::Driving)[0],
|
||||
Distance::ZERO,
|
||||
),
|
||||
map,
|
||||
) {
|
||||
Some(SpawnTrip::CarAppearing {
|
||||
depart: self.depart_at,
|
||||
start,
|
||||
goal: self.to.driving_goal(PathConstraints::Bike, map),
|
||||
is_bike: true,
|
||||
})
|
||||
} else {
|
||||
//timer.warn(format!("No room for bike to appear at {:?}", self.from));
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
Mode::Walk => Some(SpawnTrip::JustWalking(
|
||||
self.depart_at,
|
||||
self.from.start_sidewalk_spot(map),
|
||||
self.to.end_sidewalk_spot(map),
|
||||
)),
|
||||
Mode::Transit => {
|
||||
let start = self.from.start_sidewalk_spot(map);
|
||||
let goal = self.to.end_sidewalk_spot(map);
|
||||
if let Some((stop1, stop2, route)) =
|
||||
map.should_use_transit(start.sidewalk_pos, goal.sidewalk_pos)
|
||||
{
|
||||
Some(SpawnTrip::UsingTransit(
|
||||
self.depart_at,
|
||||
start,
|
||||
goal,
|
||||
route,
|
||||
stop1,
|
||||
stop2,
|
||||
))
|
||||
} else {
|
||||
//timer.warn(format!("{:?} not actually using transit, because pathfinding didn't find any useful route", trip));
|
||||
Some(SpawnTrip::JustWalking(self.depart_at, start, goal))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,19 +149,6 @@ impl TripEndpt {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO or biking
|
||||
// TODO bldg_via_driving needs to do find_driving_lane_near_building sometimes
|
||||
// Doesn't adjust for starting length yet.
|
||||
fn start_pos_driving(&self, map: &Map) -> Option<Position> {
|
||||
match self {
|
||||
TripEndpt::Building(b) => Position::bldg_via_driving(*b, map),
|
||||
TripEndpt::Border(i, _) => Some(Position::new(
|
||||
map.get_i(*i).get_outgoing_lanes(map, LaneType::Driving)[0],
|
||||
Distance::ZERO,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn driving_goal(&self, constraints: PathConstraints, map: &Map) -> DrivingGoal {
|
||||
match self {
|
||||
TripEndpt::Building(b) => DrivingGoal::ParkNear(*b),
|
||||
@ -199,7 +222,7 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
|
||||
},
|
||||
)?;
|
||||
|
||||
let mut trip = Trip {
|
||||
let trip = Trip {
|
||||
from,
|
||||
to,
|
||||
depart_at: trip.depart_at,
|
||||
@ -217,27 +240,8 @@ pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingI
|
||||
// Fix depart_at, trip_time, and trip_dist for border cases. Assume constant speed
|
||||
// through the trip.
|
||||
// TODO Disabled because slow and nonsensical distance ratios. :(
|
||||
(TripEndpt::Border(_, _), TripEndpt::Building(_)) => {
|
||||
if false {
|
||||
// TODO Figure out why some paths fail.
|
||||
// TODO Since we're doing the work anyway, store the result?
|
||||
let dist = map.pathfind(trip.path_req(map)?)?.total_length();
|
||||
// TODO This is failing all over the place, why?
|
||||
assert!(dist <= trip.trip_dist);
|
||||
let trip_time = (dist / trip.trip_dist) * trip.trip_time;
|
||||
trip.depart_at += trip.trip_time - trip_time;
|
||||
trip.trip_time = trip_time;
|
||||
trip.trip_dist = dist;
|
||||
}
|
||||
}
|
||||
(TripEndpt::Building(_), TripEndpt::Border(_, _)) => {
|
||||
if false {
|
||||
let dist = map.pathfind(trip.path_req(map)?)?.total_length();
|
||||
assert!(dist <= trip.trip_dist);
|
||||
trip.trip_time = (dist / trip.trip_dist) * trip.trip_time;
|
||||
trip.trip_dist = dist;
|
||||
}
|
||||
}
|
||||
(TripEndpt::Border(_, _), TripEndpt::Building(_)) => {}
|
||||
(TripEndpt::Building(_), TripEndpt::Border(_, _)) => {}
|
||||
(TripEndpt::Building(_), TripEndpt::Building(_)) => {}
|
||||
}
|
||||
|
||||
@ -259,85 +263,7 @@ pub fn trips_to_scenario(map: &Map, timer: &mut Timer) -> Scenario {
|
||||
// TODO Don't clone trips for parallelize
|
||||
let individ_trips = timer
|
||||
.parallelize("turn PSRC trips into SpawnTrips", trips.clone(), |trip| {
|
||||
match trip.mode {
|
||||
Mode::Drive => match trip.from {
|
||||
TripEndpt::Border(i, _) => {
|
||||
if let Some(start) = TripSpec::spawn_car_at(
|
||||
Position::new(
|
||||
map.get_i(i).get_outgoing_lanes(map, LaneType::Driving)[0],
|
||||
Distance::ZERO,
|
||||
),
|
||||
map,
|
||||
) {
|
||||
Some(SpawnTrip::CarAppearing {
|
||||
depart: trip.depart_at,
|
||||
start,
|
||||
goal: trip.to.driving_goal(PathConstraints::Car, map),
|
||||
is_bike: false,
|
||||
})
|
||||
} else {
|
||||
// TODO need to be able to emit warnings from parallelize
|
||||
//timer.warn(format!("No room for car to appear at {:?}", trip.from));
|
||||
None
|
||||
}
|
||||
}
|
||||
TripEndpt::Building(b) => Some(SpawnTrip::MaybeUsingParkedCar(
|
||||
trip.depart_at,
|
||||
b,
|
||||
trip.to.driving_goal(PathConstraints::Car, map),
|
||||
)),
|
||||
},
|
||||
Mode::Bike => match trip.from {
|
||||
TripEndpt::Building(b) => Some(SpawnTrip::UsingBike(
|
||||
trip.depart_at,
|
||||
SidewalkSpot::building(b, map),
|
||||
trip.to.driving_goal(PathConstraints::Bike, map),
|
||||
)),
|
||||
TripEndpt::Border(i, _) => {
|
||||
if let Some(start) = TripSpec::spawn_car_at(
|
||||
Position::new(
|
||||
map.get_i(i).get_outgoing_lanes(map, LaneType::Driving)[0],
|
||||
Distance::ZERO,
|
||||
),
|
||||
map,
|
||||
) {
|
||||
Some(SpawnTrip::CarAppearing {
|
||||
depart: trip.depart_at,
|
||||
start,
|
||||
goal: trip.to.driving_goal(PathConstraints::Bike, map),
|
||||
is_bike: true,
|
||||
})
|
||||
} else {
|
||||
//timer.warn(format!("No room for bike to appear at {:?}", trip.from));
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
Mode::Walk => Some(SpawnTrip::JustWalking(
|
||||
trip.depart_at,
|
||||
trip.from.start_sidewalk_spot(map),
|
||||
trip.to.end_sidewalk_spot(map),
|
||||
)),
|
||||
Mode::Transit => {
|
||||
let start = trip.from.start_sidewalk_spot(map);
|
||||
let goal = trip.to.end_sidewalk_spot(map);
|
||||
if let Some((stop1, stop2, route)) =
|
||||
map.should_use_transit(start.sidewalk_pos, goal.sidewalk_pos)
|
||||
{
|
||||
Some(SpawnTrip::UsingTransit(
|
||||
trip.depart_at,
|
||||
start,
|
||||
goal,
|
||||
route,
|
||||
stop1,
|
||||
stop2,
|
||||
))
|
||||
} else {
|
||||
//timer.warn(format!("{:?} not actually using transit, because pathfinding didn't find any useful route", trip));
|
||||
Some(SpawnTrip::JustWalking(trip.depart_at, start, goal))
|
||||
}
|
||||
}
|
||||
}
|
||||
trip.to_spawn_trip(map)
|
||||
})
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
@ -151,79 +151,9 @@ impl Scenario {
|
||||
|
||||
timer.start_iter("SpawnTrip", self.individ_trips.len());
|
||||
for t in &self.individ_trips {
|
||||
match t.clone() {
|
||||
SpawnTrip::CarAppearing {
|
||||
depart,
|
||||
start,
|
||||
goal,
|
||||
is_bike,
|
||||
..
|
||||
} => {
|
||||
sim.schedule_trip(
|
||||
depart,
|
||||
TripSpec::CarAppearing {
|
||||
start_pos: start,
|
||||
goal,
|
||||
vehicle_spec: if is_bike {
|
||||
Scenario::rand_bike(rng)
|
||||
} else {
|
||||
Scenario::rand_car(rng)
|
||||
},
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
map,
|
||||
);
|
||||
}
|
||||
SpawnTrip::MaybeUsingParkedCar(depart, start_bldg, goal) => {
|
||||
sim.schedule_trip(
|
||||
depart,
|
||||
TripSpec::MaybeUsingParkedCar {
|
||||
start_bldg,
|
||||
goal,
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
map,
|
||||
);
|
||||
}
|
||||
SpawnTrip::UsingBike(depart, start, goal) => {
|
||||
sim.schedule_trip(
|
||||
depart,
|
||||
TripSpec::UsingBike {
|
||||
start,
|
||||
goal,
|
||||
vehicle: Scenario::rand_bike(rng),
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
map,
|
||||
);
|
||||
}
|
||||
SpawnTrip::JustWalking(depart, start, goal) => {
|
||||
sim.schedule_trip(
|
||||
depart,
|
||||
TripSpec::JustWalking {
|
||||
start,
|
||||
goal,
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
map,
|
||||
);
|
||||
}
|
||||
SpawnTrip::UsingTransit(depart, start, goal, route, stop1, stop2) => {
|
||||
sim.schedule_trip(
|
||||
depart,
|
||||
TripSpec::UsingTransit {
|
||||
start,
|
||||
goal,
|
||||
route,
|
||||
stop1,
|
||||
stop2,
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
map,
|
||||
);
|
||||
}
|
||||
}
|
||||
timer.next();
|
||||
let (depart, spec) = t.clone().to_trip_spec(rng);
|
||||
sim.schedule_trip(depart, spec, map);
|
||||
}
|
||||
|
||||
sim.spawn_all_trips(map, timer, true);
|
||||
@ -900,3 +830,66 @@ pub enum SpawnTrip {
|
||||
BusStopID,
|
||||
),
|
||||
}
|
||||
|
||||
impl SpawnTrip {
|
||||
// (departure time, spec)
|
||||
pub fn to_trip_spec(self, rng: &mut XorShiftRng) -> (Duration, TripSpec) {
|
||||
match self {
|
||||
SpawnTrip::CarAppearing {
|
||||
depart,
|
||||
start,
|
||||
goal,
|
||||
is_bike,
|
||||
..
|
||||
} => (
|
||||
depart,
|
||||
TripSpec::CarAppearing {
|
||||
start_pos: start,
|
||||
goal,
|
||||
vehicle_spec: if is_bike {
|
||||
Scenario::rand_bike(rng)
|
||||
} else {
|
||||
Scenario::rand_car(rng)
|
||||
},
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
),
|
||||
SpawnTrip::MaybeUsingParkedCar(depart, start_bldg, goal) => (
|
||||
depart,
|
||||
TripSpec::MaybeUsingParkedCar {
|
||||
start_bldg,
|
||||
goal,
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
),
|
||||
SpawnTrip::UsingBike(depart, start, goal) => (
|
||||
depart,
|
||||
TripSpec::UsingBike {
|
||||
start,
|
||||
goal,
|
||||
vehicle: Scenario::rand_bike(rng),
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
),
|
||||
SpawnTrip::JustWalking(depart, start, goal) => (
|
||||
depart,
|
||||
TripSpec::JustWalking {
|
||||
start,
|
||||
goal,
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
),
|
||||
SpawnTrip::UsingTransit(depart, start, goal, route, stop1, stop2) => (
|
||||
depart,
|
||||
TripSpec::UsingTransit {
|
||||
start,
|
||||
goal,
|
||||
route,
|
||||
stop1,
|
||||
stop2,
|
||||
ped_speed: Scenario::rand_ped_speed(rng),
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -464,7 +464,11 @@ impl TripSpec {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_pathfinding_request(&self, map: &Map, parking: &ParkingSimState) -> PathRequest {
|
||||
pub(crate) fn get_pathfinding_request(
|
||||
&self,
|
||||
map: &Map,
|
||||
parking: &ParkingSimState,
|
||||
) -> PathRequest {
|
||||
match self {
|
||||
TripSpec::CarAppearing {
|
||||
start_pos,
|
||||
|
@ -952,6 +952,10 @@ impl Sim {
|
||||
self.driving
|
||||
.find_blockage_front(car, map, &self.intersections)
|
||||
}
|
||||
|
||||
pub fn trip_spec_to_path_req(&self, spec: &TripSpec, map: &Map) -> PathRequest {
|
||||
spec.get_pathfinding_request(map, &self.parking)
|
||||
}
|
||||
}
|
||||
|
||||
// Invasive debugging
|
||||
|
Loading…
Reference in New Issue
Block a user