mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
plumb car properties between driving and parking sims. seems simpler...
This commit is contained in:
parent
9150ea3f6a
commit
478d12aecb
@ -88,6 +88,11 @@ around the precomputed front of the spot, used for drawing and for cars to line
|
||||
up their front in the sim. I think we need to plumb the true start of the spot
|
||||
and have a method to interpolate and pick the true front.
|
||||
|
||||
Now trying the other way -- plumbing back and forth. How do we represent this for parked cars?
|
||||
- store Vehicle in ParkedCar
|
||||
- I remember there was some reason this refactor broke last time, but let's try it again
|
||||
- and store ParkedCar's directly in ParkingLane
|
||||
|
||||
## Logging
|
||||
|
||||
Libraries will do it too -- that's fine
|
||||
|
@ -40,6 +40,7 @@ struct Car {
|
||||
on: On,
|
||||
speed: Speed,
|
||||
dist_along: Distance,
|
||||
vehicle: Vehicle,
|
||||
|
||||
parking: Option<ParkingState>,
|
||||
|
||||
@ -82,7 +83,6 @@ impl Car {
|
||||
// State transitions might be indicated
|
||||
transit_sim: &mut TransitSimState,
|
||||
intersections: &IntersectionSimState,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Result<Action, Error> {
|
||||
if self.parking.is_some() {
|
||||
// TODO right place for this check?
|
||||
@ -90,7 +90,7 @@ impl Car {
|
||||
return Ok(Action::WorkOnParking);
|
||||
}
|
||||
|
||||
let vehicle = &properties[&self.id];
|
||||
let vehicle = &self.vehicle;
|
||||
|
||||
if let Some(act) = orig_router.react_before_lookahead(
|
||||
events,
|
||||
@ -148,7 +148,7 @@ impl Car {
|
||||
if let Some(other) = view.next_car_in_front_of(current_on, current_dist_along) {
|
||||
assert!(self.id != other.id.as_car());
|
||||
assert!(current_dist_along < other.dist_along);
|
||||
let other_vehicle = &properties[&other.id.as_car()];
|
||||
let other_vehicle = other.vehicle.as_ref().unwrap();
|
||||
let dist_behind_other =
|
||||
dist_scanned_ahead + (other.dist_along - current_dist_along);
|
||||
// If our lookahead doesn't even hit the lead vehicle (plus following distance!!!), then ignore them.
|
||||
@ -350,12 +350,7 @@ impl SimQueue {
|
||||
// TODO it'd be cool to contribute tooltips (like number of cars currently here, capacity) to
|
||||
// tooltip
|
||||
|
||||
fn reset(
|
||||
&mut self,
|
||||
ids: &Vec<CarID>,
|
||||
cars: &BTreeMap<CarID, Car>,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Result<(), Error> {
|
||||
fn reset(&mut self, ids: &Vec<CarID>, cars: &BTreeMap<CarID, Car>) -> Result<(), Error> {
|
||||
let old_queue = self.cars_queue.clone();
|
||||
let new_queue: Vec<(Distance, CarID)> =
|
||||
ids.iter().map(|id| (cars[id].dist_along, *id)).collect();
|
||||
@ -375,7 +370,7 @@ impl SimQueue {
|
||||
// assert here we're not squished together too much
|
||||
for slice in self.cars_queue.windows(2) {
|
||||
let ((dist1, c1), (dist2, c2)) = (slice[0], slice[1]);
|
||||
let following_dist = properties[&c1].following_dist();
|
||||
let following_dist = cars[&c1].vehicle.following_dist();
|
||||
if dist1 - dist2 < following_dist {
|
||||
bail!(InvariantViolated::new(format!("uh oh! on {:?}, reset to {:?} broke. min following distance is {}, but we have {} at {} and {} at {}. dist btwn is just {}. prev queue was {:?}", self.id, self.cars_queue, following_dist, c1, dist1, c2, dist2, dist1 - dist2, old_queue)));
|
||||
}
|
||||
@ -389,16 +384,10 @@ impl SimQueue {
|
||||
|
||||
// TODO this starts cars with their front aligned with the end of the lane, sticking their back
|
||||
// into the intersection. :(
|
||||
fn get_draw_cars(
|
||||
&self,
|
||||
sim: &DrivingSimState,
|
||||
map: &Map,
|
||||
time: Tick,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Vec<DrawCarInput> {
|
||||
fn get_draw_cars(&self, sim: &DrivingSimState, map: &Map, time: Tick) -> Vec<DrawCarInput> {
|
||||
let mut results = Vec::new();
|
||||
for (_, id) in &self.cars_queue {
|
||||
results.push(sim.get_draw_car(*id, time, map, properties).unwrap())
|
||||
results.push(sim.get_draw_car(*id, time, map).unwrap())
|
||||
}
|
||||
results
|
||||
}
|
||||
@ -560,7 +549,6 @@ impl DrivingSimState {
|
||||
intersections: &mut IntersectionSimState,
|
||||
transit_sim: &mut TransitSimState,
|
||||
rng: &mut R,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Result<Vec<ParkedCar>, Error> {
|
||||
self.populate_view(view);
|
||||
|
||||
@ -580,7 +568,6 @@ impl DrivingSimState {
|
||||
parking_sim,
|
||||
transit_sim,
|
||||
intersections,
|
||||
properties,
|
||||
)?,
|
||||
));
|
||||
}
|
||||
@ -599,7 +586,7 @@ impl DrivingSimState {
|
||||
c.parking = Some(ParkingState {
|
||||
is_parking: true,
|
||||
started_at: time,
|
||||
tuple: ParkedCar::new(*id, *spot),
|
||||
tuple: ParkedCar::new(*id, *spot, c.vehicle.clone()),
|
||||
});
|
||||
}
|
||||
Action::WorkOnParking => {
|
||||
@ -662,16 +649,16 @@ impl DrivingSimState {
|
||||
// Reset all queues
|
||||
for l in &mut self.lanes {
|
||||
if let Some(v) = cars_per_lane.get_vec(&l.id.as_lane()) {
|
||||
l.reset(v, &self.cars, properties)?;
|
||||
l.reset(v, &self.cars)?;
|
||||
} else {
|
||||
l.reset(&Vec::new(), &self.cars, properties)?;
|
||||
l.reset(&Vec::new(), &self.cars)?;
|
||||
}
|
||||
}
|
||||
for t in self.turns.values_mut() {
|
||||
if let Some(v) = cars_per_turn.get_vec(&t.id.as_turn()) {
|
||||
t.reset(v, &self.cars, properties)?;
|
||||
t.reset(v, &self.cars)?;
|
||||
} else {
|
||||
t.reset(&Vec::new(), &self.cars, properties)?;
|
||||
t.reset(&Vec::new(), &self.cars)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,11 +672,11 @@ impl DrivingSimState {
|
||||
time: Tick,
|
||||
car: CarID,
|
||||
maybe_parked_car: Option<ParkedCar>,
|
||||
vehicle: Vehicle,
|
||||
dist_along: Distance,
|
||||
start: LaneID,
|
||||
router: Router,
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> bool {
|
||||
// If not, we have a parking lane much longer than a driving lane...
|
||||
assert!(dist_along <= map.get_l(start).length());
|
||||
@ -710,12 +697,12 @@ impl DrivingSimState {
|
||||
return false;
|
||||
}
|
||||
|
||||
let other_vehicle = &properties[&other];
|
||||
let other_vehicle = &self.cars[&other].vehicle;
|
||||
let accel_for_other_to_stop = other_vehicle
|
||||
.accel_to_follow(
|
||||
self.cars[&other].speed,
|
||||
map.get_parent(start).get_speed_limit(),
|
||||
&properties[&car],
|
||||
&vehicle,
|
||||
dist_along - other_dist,
|
||||
0.0 * si::MPS,
|
||||
).unwrap();
|
||||
@ -736,6 +723,7 @@ impl DrivingSimState {
|
||||
dist_along: dist_along,
|
||||
speed: 0.0 * si::MPS,
|
||||
on: On::Lane(start),
|
||||
vehicle,
|
||||
waiting_for: None,
|
||||
debug: false,
|
||||
is_bus: !maybe_parked_car.is_some(),
|
||||
@ -757,17 +745,10 @@ impl DrivingSimState {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn get_draw_car(
|
||||
&self,
|
||||
id: CarID,
|
||||
time: Tick,
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Option<DrawCarInput> {
|
||||
pub fn get_draw_car(&self, id: CarID, time: Tick, map: &Map) -> Option<DrawCarInput> {
|
||||
let c = self.cars.get(&id)?;
|
||||
let (base_pos, angle) = c.on.dist_along(c.dist_along, map);
|
||||
let vehicle = &properties[&id];
|
||||
let stopping_dist = vehicle.stopping_distance(c.speed);
|
||||
let stopping_dist = c.vehicle.stopping_distance(c.speed);
|
||||
|
||||
// TODO arguably, this math might belong in DrawCar.
|
||||
let pos = if let Some(ref parking) = c.parking {
|
||||
@ -787,7 +768,7 @@ impl DrivingSimState {
|
||||
|
||||
Some(DrawCarInput {
|
||||
id: c.id,
|
||||
vehicle_length: vehicle.length,
|
||||
vehicle_length: c.vehicle.length,
|
||||
waiting_for_turn: c.waiting_for.and_then(|on| on.maybe_turn()),
|
||||
front: pos,
|
||||
angle,
|
||||
@ -795,25 +776,13 @@ impl DrivingSimState {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_draw_cars_on_lane(
|
||||
&self,
|
||||
lane: LaneID,
|
||||
time: Tick,
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Vec<DrawCarInput> {
|
||||
self.lanes[lane.0].get_draw_cars(self, map, time, properties)
|
||||
pub fn get_draw_cars_on_lane(&self, lane: LaneID, time: Tick, map: &Map) -> Vec<DrawCarInput> {
|
||||
self.lanes[lane.0].get_draw_cars(self, map, time)
|
||||
}
|
||||
|
||||
pub fn get_draw_cars_on_turn(
|
||||
&self,
|
||||
turn: TurnID,
|
||||
time: Tick,
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Vec<DrawCarInput> {
|
||||
pub fn get_draw_cars_on_turn(&self, turn: TurnID, time: Tick, map: &Map) -> Vec<DrawCarInput> {
|
||||
if let Some(queue) = self.turns.get(&turn) {
|
||||
return queue.get_draw_cars(self, map, time, properties);
|
||||
return queue.get_draw_cars(self, map, time);
|
||||
}
|
||||
return Vec::new();
|
||||
}
|
||||
@ -831,6 +800,7 @@ impl DrivingSimState {
|
||||
on: c.on,
|
||||
dist_along: c.dist_along,
|
||||
speed: c.speed,
|
||||
vehicle: Some(c.vehicle.clone()),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
use intersections::Request;
|
||||
use map_model::{BuildingID, BusStopID};
|
||||
use {AgentID, CarID, On, ParkedCar, ParkingSpot, PedestrianID};
|
||||
use {AgentID, CarID, On, ParkingSpot, PedestrianID};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Event {
|
||||
// TODO CarFinishedParking
|
||||
// TODO and the pedestrian / trip associated with it?
|
||||
CarReachedParkingSpot(ParkedCar),
|
||||
CarReachedParkingSpot(CarID, ParkingSpot),
|
||||
// TODO and the car / trip?
|
||||
PedReachedParkingSpot(PedestrianID, ParkingSpot),
|
||||
// TODO CarFinishedUnparking
|
||||
|
@ -169,13 +169,8 @@ impl Sim {
|
||||
}
|
||||
|
||||
pub fn seed_parked_cars(&mut self, in_poly: Option<&Polygon>, percent: f64) {
|
||||
self.spawner.seed_parked_cars(
|
||||
percent,
|
||||
in_poly,
|
||||
&mut self.parking_state,
|
||||
&mut self.car_properties,
|
||||
&mut self.rng,
|
||||
);
|
||||
self.spawner
|
||||
.seed_parked_cars(percent, in_poly, &mut self.parking_state, &mut self.rng);
|
||||
}
|
||||
|
||||
pub fn seed_bus_route(&mut self, route: &BusRoute, map: &Map) -> Vec<CarID> {
|
||||
@ -189,18 +184,12 @@ impl Sim {
|
||||
&mut self.driving_state,
|
||||
&mut self.transit_state,
|
||||
self.time,
|
||||
&mut self.car_properties,
|
||||
)
|
||||
}
|
||||
|
||||
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.car_properties,
|
||||
&mut self.rng,
|
||||
)
|
||||
self.spawner
|
||||
.seed_specific_parked_cars(lane, spots, &mut self.parking_state, &mut self.rng)
|
||||
}
|
||||
|
||||
pub fn seed_driving_trips(&mut self, map: &Map, num_cars: usize) {
|
||||
@ -253,7 +242,8 @@ impl Sim {
|
||||
let parked = self
|
||||
.parking_state
|
||||
.lookup_car(car)
|
||||
.expect("Car isn't parked");
|
||||
.expect("Car isn't parked")
|
||||
.clone();
|
||||
let road = map.get_parent(parked.spot.lane);
|
||||
let sidewalk = road
|
||||
.find_sidewalk(parked.spot.lane)
|
||||
|
@ -35,7 +35,7 @@ const FOLLOWING_DISTANCE: Distance = si::Meter {
|
||||
// TODO unit test all of this
|
||||
// TODO handle floating point issues uniformly here
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Vehicle {
|
||||
pub id: CarID,
|
||||
|
||||
|
@ -356,11 +356,12 @@ impl ParkingSpot {
|
||||
pub struct ParkedCar {
|
||||
pub car: CarID,
|
||||
pub spot: ParkingSpot,
|
||||
pub vehicle: kinematics::Vehicle,
|
||||
}
|
||||
|
||||
impl ParkedCar {
|
||||
pub fn new(car: CarID, spot: ParkingSpot) -> ParkedCar {
|
||||
ParkedCar { car, spot }
|
||||
pub fn new(car: CarID, spot: ParkingSpot, vehicle: kinematics::Vehicle) -> ParkedCar {
|
||||
ParkedCar { car, spot, vehicle }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ use geom::{Angle, Polygon, Pt2D};
|
||||
use kinematics::Vehicle;
|
||||
use map_model;
|
||||
use map_model::{Lane, LaneID, LaneType, Map};
|
||||
use std::collections::BTreeMap;
|
||||
use std::iter;
|
||||
use {CarID, Distance, DrawCarInput, ParkedCar, ParkingSpot};
|
||||
|
||||
@ -52,8 +51,8 @@ impl ParkingSimState {
|
||||
pub fn get_all_free_spots(&self, in_poly: Option<&Polygon>) -> Vec<ParkingSpot> {
|
||||
let mut spots: Vec<ParkingSpot> = Vec::new();
|
||||
for l in &self.lanes {
|
||||
for (idx, occupant) in l.occupants.iter().enumerate() {
|
||||
if occupant.is_none() {
|
||||
for (idx, maybe_occupant) in l.occupants.iter().enumerate() {
|
||||
if maybe_occupant.is_none() {
|
||||
// Just match based on the front of the spot
|
||||
if in_poly
|
||||
.map(|p| p.contains_pt(l.spots[idx].pos))
|
||||
@ -68,43 +67,36 @@ impl ParkingSimState {
|
||||
}
|
||||
|
||||
pub fn remove_parked_car(&mut self, p: ParkedCar) {
|
||||
self.lanes[p.spot.lane.0].remove_parked_car(p.car);
|
||||
self.lanes[p.spot.lane.0].remove_parked_car(p);
|
||||
self.total_count -= 1;
|
||||
}
|
||||
|
||||
pub fn add_parked_car(&mut self, p: ParkedCar) {
|
||||
assert_eq!(self.lanes[p.spot.lane.0].occupants[p.spot.idx], None);
|
||||
self.lanes[p.spot.lane.0].occupants[p.spot.idx] = Some(p.car);
|
||||
let spot = p.spot;
|
||||
assert_eq!(self.lanes[spot.lane.0].occupants[spot.idx], None);
|
||||
self.lanes[spot.lane.0].occupants[spot.idx] = Some(p);
|
||||
self.total_count += 1;
|
||||
}
|
||||
|
||||
pub fn get_draw_cars(
|
||||
&self,
|
||||
id: LaneID,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Vec<DrawCarInput> {
|
||||
self.lanes[id.0].get_draw_cars(properties)
|
||||
pub fn get_draw_cars(&self, id: LaneID) -> Vec<DrawCarInput> {
|
||||
self.lanes[id.0].get_draw_cars()
|
||||
}
|
||||
|
||||
pub fn get_draw_car(
|
||||
&self,
|
||||
id: CarID,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Option<DrawCarInput> {
|
||||
pub fn get_draw_car(&self, id: CarID) -> Option<DrawCarInput> {
|
||||
// TODO this is so horrendously slow :D
|
||||
for l in &self.lanes {
|
||||
if l.occupants.contains(&Some(id)) {
|
||||
return l.get_draw_cars(properties).into_iter().find(|c| c.id == id);
|
||||
if l.occupants.iter().find(|x| is_car(x, id)).is_some() {
|
||||
return l.get_draw_cars().into_iter().find(|c| c.id == id);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn lookup_car(&self, id: CarID) -> Option<ParkedCar> {
|
||||
pub fn lookup_car(&self, id: CarID) -> Option<&ParkedCar> {
|
||||
// TODO this is so horrendously slow :D
|
||||
for l in &self.lanes {
|
||||
if let Some(idx) = l.occupants.iter().position(|x| *x == Some(id)) {
|
||||
return Some(ParkedCar::new(id, ParkingSpot::new(l.id, idx)));
|
||||
if let Some(p) = l.occupants.iter().find(|x| is_car(x, id)) {
|
||||
return p.as_ref();
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -113,14 +105,14 @@ impl ParkingSimState {
|
||||
pub fn get_all_parked_cars(&self, in_poly: Option<&Polygon>) -> Vec<ParkedCar> {
|
||||
let mut result = Vec::new();
|
||||
for l in &self.lanes {
|
||||
for (idx, maybe_car) in l.occupants.iter().enumerate() {
|
||||
if let Some(car) = maybe_car {
|
||||
for maybe_occupant in &l.occupants {
|
||||
if let Some(occupant) = maybe_occupant {
|
||||
// Just match based on the front of the spot
|
||||
if in_poly
|
||||
.map(|p| p.contains_pt(l.spots[idx].pos))
|
||||
.map(|p| p.contains_pt(l.spots[occupant.spot.idx].pos))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
result.push(ParkedCar::new(*car, ParkingSpot::new(l.id, idx)));
|
||||
result.push(occupant.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,7 +132,7 @@ impl ParkingSimState {
|
||||
|
||||
pub fn get_car_at_spot(&self, spot: ParkingSpot) -> Option<ParkedCar> {
|
||||
let l = &self.lanes[spot.lane.0];
|
||||
l.occupants[spot.idx].and_then(|car| Some(ParkedCar::new(car, spot)))
|
||||
l.occupants[spot.idx].clone()
|
||||
}
|
||||
|
||||
pub fn dist_along_for_car(&self, spot: ParkingSpot, vehicle: &Vehicle) -> Distance {
|
||||
@ -160,7 +152,7 @@ impl ParkingSimState {
|
||||
struct ParkingLane {
|
||||
id: LaneID,
|
||||
spots: Vec<ParkingSpotGeometry>,
|
||||
occupants: Vec<Option<CarID>>,
|
||||
occupants: Vec<Option<ParkedCar>>,
|
||||
}
|
||||
|
||||
// TODO the f64's prevent derivation
|
||||
@ -198,22 +190,25 @@ impl ParkingLane {
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_parked_car(&mut self, car: CarID) {
|
||||
let idx = self.occupants.iter().position(|x| *x == Some(car)).unwrap();
|
||||
fn remove_parked_car(&mut self, p: ParkedCar) {
|
||||
let match_against = Some(p.clone());
|
||||
let idx = self
|
||||
.occupants
|
||||
.iter()
|
||||
.position(|x| *x == match_against)
|
||||
.unwrap();
|
||||
self.occupants[idx] = None;
|
||||
}
|
||||
|
||||
fn get_draw_cars(&self, properties: &BTreeMap<CarID, Vehicle>) -> Vec<DrawCarInput> {
|
||||
fn get_draw_cars(&self) -> Vec<DrawCarInput> {
|
||||
self.occupants
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, maybe_id)| {
|
||||
maybe_id.and_then(|id| {
|
||||
let vehicle = &properties[&id];
|
||||
let (front, angle) = self.spots[idx].front_of_car(vehicle);
|
||||
.filter_map(|maybe_occupant| {
|
||||
maybe_occupant.as_ref().and_then(|p| {
|
||||
let (front, angle) = self.spots[p.spot.idx].front_of_car(&p.vehicle);
|
||||
Some(DrawCarInput {
|
||||
id: id,
|
||||
vehicle_length: vehicle.length,
|
||||
id: p.car,
|
||||
vehicle_length: p.vehicle.length,
|
||||
waiting_for_turn: None,
|
||||
front: front,
|
||||
angle: angle,
|
||||
@ -224,7 +219,7 @@ impl ParkingLane {
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
!self.occupants.iter().find(|&&x| x.is_some()).is_some()
|
||||
!self.occupants.iter().find(|x| x.is_some()).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,3 +256,10 @@ impl ParkingSpotGeometry {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_car(maybe_occupant: &&Option<ParkedCar>, car: CarID) -> bool {
|
||||
match maybe_occupant {
|
||||
Some(p) => p.car == car,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,11 @@ use driving::DrivingSimState;
|
||||
use failure::Error;
|
||||
use instrument::capture_backtrace;
|
||||
use intersections::IntersectionSimState;
|
||||
use kinematics::Vehicle;
|
||||
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
||||
use parking::ParkingSimState;
|
||||
use rand::{FromEntropy, SeedableRng, XorShiftRng};
|
||||
use spawn::Spawner;
|
||||
use std;
|
||||
use std::collections::BTreeMap;
|
||||
use std::f64;
|
||||
use std::process;
|
||||
use std::time::{Duration, Instant};
|
||||
@ -50,8 +48,6 @@ pub struct Sim {
|
||||
pub(crate) walking_state: WalkingSimState,
|
||||
pub(crate) transit_state: TransitSimState,
|
||||
pub(crate) trips_state: TripManager,
|
||||
|
||||
pub(crate) car_properties: BTreeMap<CarID, Vehicle>,
|
||||
}
|
||||
|
||||
impl Sim {
|
||||
@ -80,7 +76,6 @@ impl Sim {
|
||||
map_name: map.get_name().to_string(),
|
||||
run_name,
|
||||
savestate_every,
|
||||
car_properties: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +151,6 @@ impl Sim {
|
||||
&mut self.walking_state,
|
||||
&mut self.driving_state,
|
||||
&mut self.trips_state,
|
||||
&self.car_properties,
|
||||
);
|
||||
|
||||
for p in self.driving_state.step(
|
||||
@ -168,9 +162,8 @@ impl Sim {
|
||||
&mut self.intersection_state,
|
||||
&mut self.transit_state,
|
||||
&mut self.rng,
|
||||
&self.car_properties,
|
||||
)? {
|
||||
events.push(Event::CarReachedParkingSpot(p.clone()));
|
||||
events.push(Event::CarReachedParkingSpot(p.car, p.spot));
|
||||
capture_backtrace("CarReachedParkingSpot");
|
||||
self.parking_state.add_parked_car(p.clone());
|
||||
self.spawner.car_reached_parking_spot(
|
||||
@ -232,8 +225,8 @@ impl Sim {
|
||||
|
||||
pub fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput> {
|
||||
self.driving_state
|
||||
.get_draw_car(id, self.time, map, &self.car_properties)
|
||||
.or_else(|| self.parking_state.get_draw_car(id, &self.car_properties))
|
||||
.get_draw_car(id, self.time, map)
|
||||
.or_else(|| self.parking_state.get_draw_car(id))
|
||||
}
|
||||
|
||||
pub fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrianInput> {
|
||||
@ -243,19 +236,15 @@ impl Sim {
|
||||
// TODO maybe just DrawAgent instead? should caller care?
|
||||
pub fn get_draw_cars_on_lane(&self, l: LaneID, map: &Map) -> Vec<DrawCarInput> {
|
||||
match map.get_l(l).lane_type {
|
||||
LaneType::Driving => {
|
||||
self.driving_state
|
||||
.get_draw_cars_on_lane(l, self.time, map, &self.car_properties)
|
||||
}
|
||||
LaneType::Parking => self.parking_state.get_draw_cars(l, &self.car_properties),
|
||||
LaneType::Driving => self.driving_state.get_draw_cars_on_lane(l, self.time, map),
|
||||
LaneType::Parking => self.parking_state.get_draw_cars(l),
|
||||
LaneType::Sidewalk => Vec::new(),
|
||||
LaneType::Biking => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_draw_cars_on_turn(&self, t: TurnID, map: &Map) -> Vec<DrawCarInput> {
|
||||
self.driving_state
|
||||
.get_draw_cars_on_turn(t, self.time, map, &self.car_properties)
|
||||
self.driving_state.get_draw_cars_on_turn(t, self.time, map)
|
||||
}
|
||||
|
||||
pub fn get_draw_peds_on_lane(&self, l: LaneID, map: &Map) -> Vec<DrawPedestrianInput> {
|
||||
|
@ -5,7 +5,7 @@ use map_model::{BuildingID, BusRoute, BusStopID, LaneID, Map, Pathfinder};
|
||||
use parking::ParkingSimState;
|
||||
use rand::Rng;
|
||||
use router::Router;
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
use std::collections::VecDeque;
|
||||
use std::time::Instant;
|
||||
use transit::TransitSimState;
|
||||
use trips::{TripLeg, TripManager};
|
||||
@ -77,7 +77,6 @@ impl Spawner {
|
||||
walking_sim: &mut WalkingSimState,
|
||||
driving_sim: &mut DrivingSimState,
|
||||
trips: &mut TripManager,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) {
|
||||
let mut commands: Vec<Command> = Vec::new();
|
||||
let mut requested_paths: Vec<(LaneID, LaneID)> = Vec::new();
|
||||
@ -111,18 +110,18 @@ impl Spawner {
|
||||
// TODO this looks like it jumps when the parking and driving lanes are different lengths
|
||||
// due to diagonals
|
||||
let dist_along =
|
||||
parking_sim.dist_along_for_car(parked_car.spot, &properties[&car]);
|
||||
parking_sim.dist_along_for_car(parked_car.spot, &parked_car.vehicle);
|
||||
let start = path.pop_front().unwrap();
|
||||
if driving_sim.start_car_on_lane(
|
||||
events,
|
||||
now,
|
||||
car,
|
||||
Some(parked_car.clone()),
|
||||
parked_car.vehicle.clone(),
|
||||
dist_along,
|
||||
start,
|
||||
Router::make_router_to_park(path, goal_bldg),
|
||||
map,
|
||||
properties,
|
||||
) {
|
||||
trips.agent_starting_trip_leg(AgentID::Car(car), trip);
|
||||
parking_sim.remove_parked_car(parked_car.clone());
|
||||
@ -161,7 +160,6 @@ impl Spawner {
|
||||
driving_sim: &mut DrivingSimState,
|
||||
transit_sim: &mut TransitSimState,
|
||||
now: Tick,
|
||||
car_properties: &mut BTreeMap<CarID, Vehicle>,
|
||||
) -> Vec<CarID> {
|
||||
let route_id = transit_sim.create_empty_route(route, map);
|
||||
let mut results: Vec<CarID> = Vec::new();
|
||||
@ -179,15 +177,14 @@ impl Spawner {
|
||||
now,
|
||||
id,
|
||||
None,
|
||||
vehicle,
|
||||
start_dist_along,
|
||||
start,
|
||||
Router::make_router_for_bus(path),
|
||||
map,
|
||||
car_properties,
|
||||
) {
|
||||
transit_sim.bus_created(id, route_id, next_stop_idx);
|
||||
info!("Spawned bus {} for route {} ({})", id, route.name, route_id);
|
||||
car_properties.insert(id, vehicle);
|
||||
results.push(id);
|
||||
} else {
|
||||
warn!(
|
||||
@ -205,7 +202,6 @@ impl Spawner {
|
||||
percent_capacity_to_fill: f64,
|
||||
in_poly: Option<&Polygon>,
|
||||
parking_sim: &mut ParkingSimState,
|
||||
car_properties: &mut BTreeMap<CarID, Vehicle>,
|
||||
rng: &mut R,
|
||||
) {
|
||||
assert!(percent_capacity_to_fill >= 0.0 && percent_capacity_to_fill <= 1.0);
|
||||
@ -219,8 +215,11 @@ impl Spawner {
|
||||
let car = CarID(self.car_id_counter);
|
||||
// TODO since spawning applies during the next step, lots of stuff breaks without
|
||||
// this :(
|
||||
parking_sim.add_parked_car(ParkedCar::new(car, spot));
|
||||
car_properties.insert(car, Vehicle::generate_typical_car(car, rng));
|
||||
parking_sim.add_parked_car(ParkedCar::new(
|
||||
car,
|
||||
spot,
|
||||
Vehicle::generate_typical_car(car, rng),
|
||||
));
|
||||
self.car_id_counter += 1;
|
||||
}
|
||||
}
|
||||
@ -236,7 +235,6 @@ impl Spawner {
|
||||
lane: LaneID,
|
||||
spot_indices: Vec<usize>,
|
||||
parking_sim: &mut ParkingSimState,
|
||||
car_properties: &mut BTreeMap<CarID, Vehicle>,
|
||||
rng: &mut R,
|
||||
) -> Vec<CarID> {
|
||||
let spots = parking_sim.get_all_spots(lane);
|
||||
@ -244,9 +242,12 @@ impl Spawner {
|
||||
.into_iter()
|
||||
.map(|idx| {
|
||||
let car = CarID(self.car_id_counter);
|
||||
parking_sim.add_parked_car(ParkedCar::new(car, spots[idx]));
|
||||
parking_sim.add_parked_car(ParkedCar::new(
|
||||
car,
|
||||
spots[idx],
|
||||
Vehicle::generate_typical_car(car, rng),
|
||||
));
|
||||
self.car_id_counter += 1;
|
||||
car_properties.insert(car, Vehicle::generate_typical_car(car, rng));
|
||||
car
|
||||
}).collect()
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use driving::SimQueue;
|
||||
use kinematics::Vehicle;
|
||||
use map_model::TurnID;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use {AgentID, CarID, Distance, On, Speed};
|
||||
@ -10,6 +11,7 @@ pub struct AgentView {
|
||||
pub on: On,
|
||||
pub dist_along: Distance,
|
||||
pub speed: Speed,
|
||||
pub vehicle: Option<Vehicle>,
|
||||
}
|
||||
|
||||
pub struct WorldView {
|
||||
|
@ -556,6 +556,7 @@ impl WalkingSimState {
|
||||
} else {
|
||||
SPEED
|
||||
},
|
||||
vehicle: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ fn park_on_goal_st() {
|
||||
sim.run_until_expectations_met(
|
||||
&map,
|
||||
&control_map,
|
||||
vec![sim::Event::CarReachedParkingSpot(sim::ParkedCar::new(
|
||||
vec![sim::Event::CarReachedParkingSpot(
|
||||
car,
|
||||
sim::ParkingSpot::new(parking2, 4),
|
||||
))],
|
||||
)],
|
||||
sim::Tick::from_minutes(1),
|
||||
);
|
||||
sim.run_until_done(&map, &control_map, Box::new(|_sim| {}));
|
||||
@ -49,10 +49,10 @@ fn wander_around_for_parking() {
|
||||
sim.run_until_expectations_met(
|
||||
&map,
|
||||
&control_map,
|
||||
vec![sim::Event::CarReachedParkingSpot(sim::ParkedCar::new(
|
||||
vec![sim::Event::CarReachedParkingSpot(
|
||||
car,
|
||||
sim::ParkingSpot::new(parking1, 0),
|
||||
))],
|
||||
)],
|
||||
sim::Tick::from_minutes(2),
|
||||
);
|
||||
sim.run_until_done(&map, &control_map, Box::new(|_sim| {}));
|
||||
@ -60,7 +60,7 @@ fn wander_around_for_parking() {
|
||||
|
||||
fn setup(run_name: &str, map: map_model::Map) -> (map_model::Map, control::ControlMap, sim::Sim) {
|
||||
let rng_seed = 123;
|
||||
let control_map = control::ControlMap::new(&map, &BTreeMap::new(), &BTreeMap::new());
|
||||
let control_map = control::ControlMap::new(&map, BTreeMap::new(), BTreeMap::new());
|
||||
let sim = sim::Sim::new(&map, run_name.to_string(), Some(rng_seed), None);
|
||||
(map, control_map, sim)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user