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