associating cars with an owner

This commit is contained in:
Dustin Carlino 2018-10-16 15:22:46 -07:00
parent 2c110a58f9
commit 7919b0bd8d
9 changed files with 158 additions and 63 deletions

View File

@ -167,6 +167,14 @@ Next thoughts:
- try to be close to building, random jitter to be a little far away
- if this process is somewhat stable, then should be fine. doesnt need to be perfectly stable -- removing lanes somewhere might put more pressure on another lane.
steps for this change:
= give cars an optional building as an owner, make a query for parking sim to find available cars, hook up UI debug
= initially randomly assign a building in the neighborhood
- start seeding parked cars per building instead of per spot
- make sure stability is vaguely preserved
- make peds that'll use a car pick from a house with an available car
## Traces between worlds
Alright, now how do we even compare trip progress to show it visually? This is

View File

@ -43,6 +43,13 @@ impl ID {
ID::Turn(_) => {}
ID::Building(id) => {
map.get_b(id).dump_debug();
let parked_cars = sim.get_parked_cars_by_owner(id);
println!(
"{} parked cars are owned by {}: {:?}",
parked_cars.len(),
id,
parked_cars.iter().map(|p| p.car).collect::<Vec<CarID>>()
);
}
ID::Car(id) => {
sim.debug_car(id);

View File

@ -5,7 +5,7 @@ use geom::EPSILON_DIST;
use intersections::{IntersectionSimState, Request};
use kinematics;
use kinematics::Vehicle;
use map_model::{LaneID, Map, Trace, Traversable, TurnID, LANE_THICKNESS};
use map_model::{BuildingID, LaneID, Map, Trace, Traversable, TurnID, LANE_THICKNESS};
use multimap::MultiMap;
use ordered_float::NotNaN;
use parking::ParkingSimState;
@ -38,6 +38,7 @@ struct Car {
id: CarID,
// None for buses
trip: Option<TripID>,
owner: Option<BuildingID>,
on: Traversable,
speed: Speed,
dist_along: Distance,
@ -492,7 +493,7 @@ impl DrivingSimState {
pub fn tooltip_lines(&self, id: CarID) -> Option<Vec<String>> {
if let Some(c) = self.cars.get(&id) {
Some(vec![
format!("Car {:?}, part of {:?}", id, c.trip),
format!("Car {:?}, part of {:?}, owned by {:?}", id, c.trip, c.owner),
format!(
"On {:?}, speed {:?}, dist along {:?}",
c.on, c.speed, c.dist_along
@ -591,7 +592,7 @@ impl DrivingSimState {
c.parking = Some(ParkingState {
is_parking: true,
started_at: time,
tuple: ParkedCar::new(*id, *spot, c.vehicle.clone()),
tuple: ParkedCar::new(*id, *spot, c.vehicle.clone(), c.owner),
});
}
Action::WorkOnParking => {
@ -677,29 +678,23 @@ impl DrivingSimState {
&mut self,
events: &mut Vec<Event>,
time: Tick,
car: CarID,
trip: Option<TripID>,
maybe_parked_car: Option<ParkedCar>,
vehicle: Vehicle,
dist_along: Distance,
start: LaneID,
router: Router,
map: &Map,
params: CreateCar,
) -> bool {
// If not, we have a parking lane much longer than a driving lane...
assert!(dist_along <= map.get_l(start).length());
assert!(params.dist_along <= map.get_l(params.start).length());
// Is it safe to enter the lane right now? Start scanning ahead of where we'll enter, so we
// don't hit somebody's back
if let Some(other) =
self.lanes[start.0].first_car_behind(dist_along + Vehicle::worst_case_following_dist())
if let Some(other) = self.lanes[params.start.0]
.first_car_behind(params.dist_along + Vehicle::worst_case_following_dist())
{
let other_dist = self.cars[&other].dist_along;
if other_dist >= dist_along {
if other_dist >= params.dist_along {
debug!(
"{} can't spawn, because they'd wind up too close ({}) behind {}",
car,
other_dist - dist_along,
params.car,
other_dist - params.dist_along,
other
);
return false;
@ -709,13 +704,13 @@ impl DrivingSimState {
let accel_for_other_to_stop = other_vehicle
.accel_to_follow(
self.cars[&other].speed,
map.get_parent(start).get_speed_limit(),
&vehicle,
dist_along - other_dist,
map.get_parent(params.start).get_speed_limit(),
&params.vehicle,
params.dist_along - other_dist,
0.0 * si::MPS,
).unwrap();
if accel_for_other_to_stop <= other_vehicle.max_deaccel {
debug!("{} can't spawn {} in front of {}, because {} would have to do {} to not hit {}", car, dist_along - other_dist, other, other, accel_for_other_to_stop, car);
debug!("{} can't spawn {} in front of {}, because {} would have to do {} to not hit {}", params.car, params.dist_along - other_dist, other, other, accel_for_other_to_stop, params.car);
return false;
}
@ -725,18 +720,19 @@ impl DrivingSimState {
}
self.cars.insert(
car,
params.car,
Car {
id: car,
trip,
dist_along: dist_along,
id: params.car,
trip: params.trip,
owner: params.owner,
on: Traversable::Lane(params.start),
dist_along: params.dist_along,
speed: 0.0 * si::MPS,
on: Traversable::Lane(start),
vehicle,
vehicle: params.vehicle,
waiting_for: None,
debug: false,
is_bus: !maybe_parked_car.is_some(),
parking: maybe_parked_car.and_then(|parked_car| {
is_bus: !params.maybe_parked_car.is_some(),
parking: params.maybe_parked_car.and_then(|parked_car| {
Some(ParkingState {
is_parking: false,
started_at: time,
@ -745,11 +741,11 @@ impl DrivingSimState {
}),
},
);
self.routers.insert(car, router);
self.lanes[start.0].insert_at(car, dist_along);
self.routers.insert(params.car, params.router);
self.lanes[params.start.0].insert_at(params.car, params.dist_along);
events.push(Event::AgentEntersTraversable(
AgentID::Car(car),
Traversable::Lane(start),
AgentID::Car(params.car),
Traversable::Lane(params.start),
));
true
}
@ -823,3 +819,14 @@ impl DrivingSimState {
Some(r.trace_route(c.on, c.dist_along, map, dist_ahead))
}
}
pub struct CreateCar {
pub car: CarID,
pub trip: Option<TripID>,
pub owner: Option<BuildingID>,
pub maybe_parked_car: Option<ParkedCar>,
pub vehicle: Vehicle,
pub start: LaneID,
pub dist_along: Distance,
pub router: Router,
}

View File

@ -143,7 +143,11 @@ impl Sim {
// Spawning helpers
impl Sim {
pub fn small_spawn(&mut self, map: &Map) {
self.seed_parked_cars(map.all_lanes().iter().map(|l| l.id).collect(), 0.5);
self.seed_parked_cars(
map.all_lanes().iter().map(|l| l.id).collect(),
&map.all_buildings().iter().map(|b| b.id).collect(),
0.5,
);
self.seed_walking_trips(&map, 100);
self.seed_driving_trips(&map, 100);
@ -162,14 +166,28 @@ impl Sim {
);*/ }
pub fn big_spawn(&mut self, map: &Map) {
self.seed_parked_cars(map.all_lanes().iter().map(|l| l.id).collect(), 0.95);
self.seed_parked_cars(
map.all_lanes().iter().map(|l| l.id).collect(),
&map.all_buildings().iter().map(|b| b.id).collect(),
0.95,
);
self.seed_walking_trips(&map, 1000);
self.seed_driving_trips(&map, 1000);
}
pub fn seed_parked_cars(&mut self, in_lanes: Vec<LaneID>, percent: f64) {
self.spawner
.seed_parked_cars(percent, in_lanes, &mut self.parking_state, &mut self.rng);
pub fn seed_parked_cars(
&mut self,
in_lanes: Vec<LaneID>,
owner_buildins: &Vec<BuildingID>,
percent: f64,
) {
self.spawner.seed_parked_cars(
percent,
in_lanes,
owner_buildins,
&mut self.parking_state,
&mut self.rng,
);
}
pub fn seed_bus_route(&mut self, route: &BusRoute, map: &Map) -> Vec<CarID> {
@ -186,9 +204,19 @@ impl Sim {
)
}
pub fn seed_specific_parked_cars(&mut self, lane: LaneID, spots: Vec<usize>) -> Vec<CarID> {
self.spawner
.seed_specific_parked_cars(lane, spots, &mut self.parking_state, &mut self.rng)
pub fn seed_specific_parked_cars(
&mut self,
lane: LaneID,
owner: BuildingID,
spots: Vec<usize>,
) -> Vec<CarID> {
self.spawner.seed_specific_parked_cars(
lane,
owner,
spots,
&mut self.parking_state,
&mut self.rng,
)
}
pub fn seed_driving_trips(&mut self, map: &Map, num_cars: usize) {

View File

@ -58,7 +58,7 @@ pub use events::Event;
use geom::{Angle, Pt2D};
pub use helpers::{load, SimFlags};
pub use instrument::save_backtraces;
use map_model::{LaneID, Trace, TurnID};
use map_model::{BuildingID, LaneID, Trace, TurnID};
use rand::{RngCore, SeedableRng, XorShiftRng};
pub use scenario::{Neighborhood, Scenario, SeedParkedCars, SpawnOverTime};
pub use sim::{Benchmark, Sim};
@ -293,11 +293,22 @@ pub struct ParkedCar {
pub car: CarID,
pub spot: ParkingSpot,
pub vehicle: kinematics::Vehicle,
pub owner: Option<BuildingID>,
}
impl ParkedCar {
pub fn new(car: CarID, spot: ParkingSpot, vehicle: kinematics::Vehicle) -> ParkedCar {
ParkedCar { car, spot, vehicle }
pub fn new(
car: CarID,
spot: ParkingSpot,
vehicle: kinematics::Vehicle,
owner: Option<BuildingID>,
) -> ParkedCar {
ParkedCar {
car,
spot,
vehicle,
owner,
}
}
}

View File

@ -1,7 +1,7 @@
use geom::{Angle, Polygon, Pt2D};
use kinematics::Vehicle;
use map_model;
use map_model::{Lane, LaneID, LaneType, Map};
use map_model::{BuildingID, Lane, LaneID, LaneType, Map};
use std::iter;
use {CarID, Distance, DrawCarInput, ParkedCar, ParkingSpot};
@ -138,6 +138,25 @@ impl ParkingSimState {
fn get_spot(&self, spot: ParkingSpot) -> &ParkingSpotGeometry {
&self.lanes[spot.lane.0].spots[spot.idx]
}
pub fn tooltip_lines(&self, id: CarID) -> Vec<String> {
let c = self.lookup_car(id).unwrap();
vec![format!("{} is parked, owned by {:?}", c.car, c.owner)]
}
pub fn get_parked_cars_by_owner(&self, id: BuildingID) -> Vec<&ParkedCar> {
let mut result: Vec<&ParkedCar> = Vec::new();
for l in &self.lanes {
for maybe_occupant in &l.occupants {
if let Some(o) = maybe_occupant {
if o.owner == Some(id) {
result.push(maybe_occupant.as_ref().unwrap());
}
}
}
}
result
}
}
#[derive(Serialize, Deserialize)]

View File

@ -97,6 +97,7 @@ impl Scenario {
for s in &self.seed_parked_cars {
sim.seed_parked_cars(
neighborhoods[&s.neighborhood].find_matching_lanes(map),
&bldgs_per_neighborhood[&s.neighborhood],
s.percent_to_fill,
);
}

View File

@ -8,7 +8,7 @@ use driving::DrivingSimState;
use geom::Pt2D;
use instrument::capture_backtrace;
use intersections::IntersectionSimState;
use map_model::{IntersectionID, LaneID, LaneType, Map, Trace, Turn, TurnID};
use map_model::{BuildingID, IntersectionID, LaneID, LaneType, Map, Trace, Turn, TurnID};
use parking::ParkingSimState;
use rand::{FromEntropy, SeedableRng, XorShiftRng};
use spawn::Spawner;
@ -21,8 +21,8 @@ use trips::TripManager;
use view::WorldView;
use walking::WalkingSimState;
use {
AgentID, CarID, CarState, Distance, DrawCarInput, DrawPedestrianInput, Event, PedestrianID,
ScoreSummary, Tick, TripID, TIMESTEP,
AgentID, CarID, CarState, Distance, DrawCarInput, DrawPedestrianInput, Event, ParkedCar,
PedestrianID, ScoreSummary, Tick, TripID, TIMESTEP,
};
#[derive(Serialize, Deserialize, Derivative)]
@ -280,7 +280,7 @@ impl Sim {
pub fn car_tooltip(&self, car: CarID) -> Vec<String> {
self.driving_state
.tooltip_lines(car)
.unwrap_or(vec![format!("{} is parked", car)])
.unwrap_or(self.parking_state.tooltip_lines(car))
}
pub fn debug_car(&mut self, id: CarID) {
@ -395,6 +395,10 @@ impl Sim {
None => None,
}
}
pub fn get_parked_cars_by_owner(&self, id: BuildingID) -> Vec<&ParkedCar> {
self.parking_state.get_parked_cars_by_owner(id)
}
}
pub struct Benchmark {

View File

@ -1,5 +1,5 @@
use abstutil::elapsed_seconds;
use driving::DrivingSimState;
use driving::{CreateCar, DrivingSimState};
use kinematics::Vehicle;
use map_model::{BuildingID, BusRoute, BusStopID, LaneID, Map, Pathfinder};
use parking::ParkingSimState;
@ -117,14 +117,17 @@ impl Spawner {
if driving_sim.start_car_on_lane(
events,
now,
car,
Some(trip),
Some(parked_car.clone()),
parked_car.vehicle.clone(),
dist_along,
start,
Router::make_router_to_park(path, goal_bldg),
map,
CreateCar {
car,
trip: Some(trip),
owner: parked_car.owner,
maybe_parked_car: Some(parked_car.clone()),
vehicle: parked_car.vehicle.clone(),
start,
dist_along,
router: Router::make_router_to_park(path, goal_bldg),
},
) {
trips.agent_starting_trip_leg(AgentID::Car(car), trip);
parking_sim.remove_parked_car(parked_car.clone());
@ -178,14 +181,17 @@ impl Spawner {
if driving_sim.start_car_on_lane(
events,
now,
id,
None,
None,
vehicle,
start_dist_along,
start,
Router::make_router_for_bus(path),
map,
CreateCar {
car: id,
trip: None,
owner: None,
maybe_parked_car: None,
vehicle,
start,
dist_along: start_dist_along,
router: Router::make_router_for_bus(path),
},
) {
transit_sim.bus_created(id, route_id, next_stop_idx);
info!("Spawned bus {} for route {} ({})", id, route.name, route_id);
@ -205,6 +211,7 @@ impl Spawner {
&mut self,
percent_capacity_to_fill: f64,
in_lanes: Vec<LaneID>,
owner_buildings: &Vec<BuildingID>,
parking_sim: &mut ParkingSimState,
base_rng: &mut XorShiftRng,
) {
@ -228,6 +235,7 @@ impl Spawner {
car,
spot,
Vehicle::generate_typical_car(car, &mut rng),
Some(*rng.choose(owner_buildings).unwrap()),
));
self.car_id_counter += 1;
}
@ -242,6 +250,7 @@ impl Spawner {
pub fn seed_specific_parked_cars(
&mut self,
lane: LaneID,
owner: BuildingID,
spot_indices: Vec<usize>,
parking_sim: &mut ParkingSimState,
rng: &mut XorShiftRng,
@ -255,6 +264,7 @@ impl Spawner {
car,
spots[idx],
Vehicle::generate_typical_car(car, rng),
Some(owner),
));
self.car_id_counter += 1;
car