mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
making car length vary, and adjusting parking model in response
This commit is contained in:
parent
917c3c3ed5
commit
7f29e5d285
@ -546,6 +546,7 @@ Some first tests to write:
|
||||
- car stops for departing car (winds up following it)
|
||||
- departing car waits for other car (winds up following it)
|
||||
- a line of cars moving through a stop sign looks jittery right now. correct or not?
|
||||
- following distances for cars of different lengths
|
||||
|
||||
Unclear how to nicely let the test inspect stuff every tick.
|
||||
|
||||
@ -556,3 +557,8 @@ Need to associate car length between driving and parking sims.
|
||||
---> could store this in master Sim; after all, there will be some more permanentish stuff like agent/building/trip/owned car soon
|
||||
- but soon need to bundle things together and pass less params everywhere
|
||||
- or stash in parking sim, transfer to driving, and back later
|
||||
|
||||
Wait, length of car affects parking pretty critically. A bunch of things plumb
|
||||
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.
|
||||
|
@ -4,17 +4,12 @@ use dimensioned::si;
|
||||
use ezgui::GfxCtx;
|
||||
use geom::{Angle, Polygon, Pt2D};
|
||||
use graphics;
|
||||
use kinematics::Vehicle;
|
||||
use map_model::{geometry, Map, TurnID};
|
||||
use std;
|
||||
use {CarID, Distance};
|
||||
|
||||
const CAR_WIDTH: f64 = 2.0;
|
||||
|
||||
pub const CAR_LENGTH: Distance = si::Meter {
|
||||
value_unsafe: 4.5,
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
// TODO should this live in editor/render?
|
||||
pub struct DrawCar {
|
||||
pub id: CarID,
|
||||
@ -32,6 +27,7 @@ pub struct DrawCar {
|
||||
impl DrawCar {
|
||||
pub fn new(
|
||||
id: CarID,
|
||||
vehicle: &Vehicle,
|
||||
waiting_for_turn: Option<TurnID>,
|
||||
map: &Map,
|
||||
front: Pt2D,
|
||||
@ -40,7 +36,7 @@ impl DrawCar {
|
||||
) -> DrawCar {
|
||||
let turn_arrow = if let Some(t) = waiting_for_turn {
|
||||
let angle = map.get_t(t).line.angle();
|
||||
let arrow_pt = front.project_away(CAR_LENGTH.value_unsafe / 2.0, angle.opposite());
|
||||
let arrow_pt = front.project_away(vehicle.length.value_unsafe / 2.0, angle.opposite());
|
||||
Some([arrow_pt.x(), arrow_pt.y(), front.x(), front.y()])
|
||||
} else {
|
||||
None
|
||||
@ -62,7 +58,7 @@ impl DrawCar {
|
||||
// TODO the rounded corners from graphics::Line::new_round look kind of cool though
|
||||
body_polygon: geometry::thick_line_from_angle(
|
||||
CAR_WIDTH,
|
||||
CAR_LENGTH.value_unsafe,
|
||||
vehicle.length.value_unsafe,
|
||||
front,
|
||||
// find the back of the car relative to the front
|
||||
angle.opposite(),
|
||||
@ -83,7 +79,7 @@ impl DrawCar {
|
||||
front_window_thickness * 0.8,
|
||||
CAR_WIDTH - 2.0 * front_window_length_gap,
|
||||
front
|
||||
.project_away(CAR_LENGTH.value_unsafe - 1.0, angle.opposite())
|
||||
.project_away(vehicle.length.value_unsafe - 1.0, angle.opposite())
|
||||
.project_away(
|
||||
CAR_WIDTH / 2.0 - front_window_length_gap,
|
||||
angle.rotate_degs(-90.0),
|
||||
|
@ -11,9 +11,9 @@ use map_model::{LaneID, Map, TurnID};
|
||||
use models::{choose_turn, FOLLOWING_DISTANCE};
|
||||
use multimap::MultiMap;
|
||||
use ordered_float::NotNaN;
|
||||
use parking::ParkingSimState;
|
||||
use parking::{ParkingSimState, ParkingSpot};
|
||||
use rand::Rng;
|
||||
use sim::{CarParking, ParkingSpot};
|
||||
use sim::CarParking;
|
||||
use std;
|
||||
use std::collections::{BTreeMap, HashMap, VecDeque};
|
||||
use {Acceleration, AgentID, CarID, CarState, Distance, InvariantViolated, On, Speed, Tick, Time};
|
||||
@ -93,24 +93,24 @@ impl Car {
|
||||
return Action::WorkOnParking;
|
||||
}
|
||||
|
||||
let vehicle = &properties[&self.id];
|
||||
|
||||
if self.path.is_empty() && self.speed <= kinematics::EPSILON_SPEED {
|
||||
if let Some(spot) =
|
||||
self.find_parking_spot(self.on.as_lane(), self.dist_along, map, parking_sim)
|
||||
{
|
||||
if spot.dist_along == self.dist_along {
|
||||
if spot.dist_along_for_car(vehicle) == self.dist_along {
|
||||
return Action::StartParking(spot);
|
||||
}
|
||||
// This seems to never happen; TODO make it an InvariantViolated
|
||||
println!(
|
||||
"uh oh, {} is stopped {} before their parking spot. keep going I guess.",
|
||||
self.id,
|
||||
spot.dist_along - self.dist_along
|
||||
spot.dist_along_for_car(vehicle) - self.dist_along
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let vehicle = &properties[&self.id];
|
||||
|
||||
// TODO could wrap this state up
|
||||
let mut current_speed_limit = self.on.speed_limit(map);
|
||||
// Of course we have to include FOLLOWING_DISTANCE
|
||||
@ -176,7 +176,7 @@ impl Car {
|
||||
if let Some(spot) =
|
||||
self.find_parking_spot(id, current_dist_along, map, parking_sim)
|
||||
{
|
||||
spot.dist_along
|
||||
spot.dist_along_for_car(vehicle)
|
||||
} else {
|
||||
need_parking = true;
|
||||
current_on.length(map)
|
||||
@ -661,8 +661,11 @@ impl DrivingSimState {
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> bool {
|
||||
let vehicle = &properties[&car];
|
||||
let start = path.pop_front().unwrap();
|
||||
let dist_along = parking.spot.dist_along;
|
||||
// TODO this looks like it jumps when the parking and driving lanes are different lengths
|
||||
// due to diagonals
|
||||
let dist_along = parking.spot.dist_along_for_car(vehicle);
|
||||
// If not, we have a parking lane much longer than a driving lane...
|
||||
assert!(dist_along <= map.get_l(start).length());
|
||||
|
||||
@ -682,7 +685,6 @@ impl DrivingSimState {
|
||||
return false;
|
||||
}
|
||||
|
||||
let vehicle = &properties[&car];
|
||||
let accel_for_other_to_stop = vehicle.accel_to_follow(
|
||||
self.cars[&other].speed,
|
||||
map.get_parent(start).get_speed_limit(),
|
||||
@ -734,7 +736,8 @@ impl DrivingSimState {
|
||||
) -> Option<DrawCar> {
|
||||
let c = self.cars.get(&id)?;
|
||||
let (base_pos, angle) = c.on.dist_along(c.dist_along, map);
|
||||
let stopping_dist = properties[&id].stopping_distance(c.speed);
|
||||
let vehicle = &properties[&id];
|
||||
let stopping_dist = vehicle.stopping_distance(c.speed);
|
||||
|
||||
// TODO arguably, this math might belong in DrawCar.
|
||||
let pos = if let Some(ref parking) = c.parking {
|
||||
@ -754,6 +757,7 @@ impl DrivingSimState {
|
||||
|
||||
Some(DrawCar::new(
|
||||
c.id,
|
||||
vehicle,
|
||||
c.waiting_for.and_then(|on| on.maybe_turn()),
|
||||
map,
|
||||
pos,
|
||||
|
@ -10,6 +10,12 @@ pub const EPSILON_SPEED: Speed = si::MeterPerSecond {
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
// This must be < PARKING_SPOT_LENGTH
|
||||
pub const MAX_CAR_LENGTH: Distance = si::Meter {
|
||||
value_unsafe: 6.5,
|
||||
_marker: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
// TODO unit test all of this
|
||||
// TODO handle floating point issues uniformly here
|
||||
|
||||
@ -21,6 +27,8 @@ pub struct Vehicle {
|
||||
max_accel: Acceleration,
|
||||
// < 0
|
||||
pub max_deaccel: Acceleration,
|
||||
|
||||
pub length: Distance,
|
||||
}
|
||||
|
||||
// TODO this is used for verifying sim state determinism, so it should actually check everything.
|
||||
@ -38,6 +46,8 @@ impl Vehicle {
|
||||
id,
|
||||
max_accel: rng.gen_range(2.4, 2.8) * si::MPS2,
|
||||
max_deaccel: rng.gen_range(-2.8, -2.4) * si::MPS2,
|
||||
// TODO more realistic to have a few preset lengths and choose between them
|
||||
length: rng.gen_range(4.5, MAX_CAR_LENGTH.value_unsafe) * si::M,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,14 +206,15 @@ impl SimQueue {
|
||||
}
|
||||
|
||||
// TODO base this on actual speed and each vehicle ;)
|
||||
let stopping_dist =
|
||||
properties[&self.cars_queue[0]].stopping_distance(self.id.speed_limit(map));
|
||||
let vehicle = &properties[&self.cars_queue[0]];
|
||||
let stopping_dist = vehicle.stopping_distance(self.id.speed_limit(map));
|
||||
|
||||
let mut results = Vec::new();
|
||||
let (pos1, angle1, dist_along1) =
|
||||
sim.cars[&self.cars_queue[0]].get_best_case_pos(time, map);
|
||||
results.push(DrawCar::new(
|
||||
self.cars_queue[0],
|
||||
vehicle,
|
||||
sim.cars[&self.cars_queue[0]]
|
||||
.waiting_for
|
||||
.and_then(|on| on.maybe_turn()),
|
||||
@ -229,6 +230,7 @@ impl SimQueue {
|
||||
if dist_along_bound - FOLLOWING_DISTANCE > dist_along {
|
||||
results.push(DrawCar::new(
|
||||
*id,
|
||||
vehicle,
|
||||
sim.cars[id].waiting_for.and_then(|on| on.maybe_turn()),
|
||||
map,
|
||||
pos,
|
||||
@ -243,6 +245,7 @@ impl SimQueue {
|
||||
let (pt, angle) = self.id.dist_along(dist_along_bound, map);
|
||||
results.push(DrawCar::new(
|
||||
*id,
|
||||
vehicle,
|
||||
sim.cars[id].waiting_for.and_then(|on| on.maybe_turn()),
|
||||
map,
|
||||
pt,
|
||||
|
@ -1,10 +1,11 @@
|
||||
use dimensioned::si;
|
||||
use draw_car;
|
||||
use draw_car::DrawCar;
|
||||
use geom::{Angle, Pt2D};
|
||||
use kinematics::Vehicle;
|
||||
use map_model;
|
||||
use map_model::{Lane, LaneID, LaneType, Map};
|
||||
use sim::{CarParking, ParkingSpot};
|
||||
use sim::CarParking;
|
||||
use std::collections::BTreeMap;
|
||||
use std::iter;
|
||||
use {CarID, Distance};
|
||||
|
||||
@ -31,7 +32,7 @@ impl ParkingSimState {
|
||||
self.lanes[id.0] = ParkingLane {
|
||||
id: id,
|
||||
spots: Vec::new(),
|
||||
spot_fronts: Vec::new(),
|
||||
occupants: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -44,27 +45,15 @@ impl ParkingSimState {
|
||||
}
|
||||
|
||||
pub fn get_all_spots(&self, lane: LaneID) -> Vec<ParkingSpot> {
|
||||
let mut spots: Vec<ParkingSpot> = Vec::new();
|
||||
for (idx, front) in self.lanes[lane.0].spot_fronts.iter().enumerate() {
|
||||
spots.push(ParkingSpot {
|
||||
parking_lane: lane,
|
||||
spot_idx: idx,
|
||||
dist_along: front.0,
|
||||
});
|
||||
}
|
||||
spots
|
||||
self.lanes[lane.0].spots.clone()
|
||||
}
|
||||
|
||||
pub fn get_all_free_spots(&self) -> Vec<ParkingSpot> {
|
||||
let mut spots: Vec<ParkingSpot> = Vec::new();
|
||||
for l in &self.lanes {
|
||||
for (idx, (occupant, front)) in l.spots.iter().zip(l.spot_fronts.iter()).enumerate() {
|
||||
for (spot, occupant) in l.spots.iter().zip(l.occupants.iter()) {
|
||||
if occupant.is_none() {
|
||||
spots.push(ParkingSpot {
|
||||
parking_lane: l.id,
|
||||
spot_idx: idx,
|
||||
dist_along: front.0,
|
||||
});
|
||||
spots.push(spot.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,22 +67,34 @@ impl ParkingSimState {
|
||||
|
||||
pub fn add_parked_car(&mut self, p: CarParking) {
|
||||
assert_eq!(
|
||||
self.lanes[p.spot.parking_lane.0].spots[p.spot.spot_idx],
|
||||
self.lanes[p.spot.parking_lane.0].occupants[p.spot.spot_idx],
|
||||
None
|
||||
);
|
||||
self.lanes[p.spot.parking_lane.0].spots[p.spot.spot_idx] = Some(p.car);
|
||||
self.lanes[p.spot.parking_lane.0].occupants[p.spot.spot_idx] = Some(p.car);
|
||||
self.total_count += 1;
|
||||
}
|
||||
|
||||
pub fn get_draw_cars(&self, id: LaneID, map: &Map) -> Vec<DrawCar> {
|
||||
self.lanes[id.0].get_draw_cars(map)
|
||||
pub fn get_draw_cars(
|
||||
&self,
|
||||
id: LaneID,
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Vec<DrawCar> {
|
||||
self.lanes[id.0].get_draw_cars(map, properties)
|
||||
}
|
||||
|
||||
pub fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCar> {
|
||||
pub fn get_draw_car(
|
||||
&self,
|
||||
id: CarID,
|
||||
map: &Map,
|
||||
properties: &BTreeMap<CarID, Vehicle>,
|
||||
) -> Option<DrawCar> {
|
||||
// TODO this is so horrendously slow :D
|
||||
for l in &self.lanes {
|
||||
if l.spots.contains(&Some(id)) {
|
||||
return l.get_draw_cars(map).into_iter().find(|c| c.id == id);
|
||||
if l.occupants.contains(&Some(id)) {
|
||||
return l.get_draw_cars(map, properties)
|
||||
.into_iter()
|
||||
.find(|c| c.id == id);
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -102,7 +103,7 @@ impl ParkingSimState {
|
||||
pub fn lane_of_car(&self, id: CarID) -> Option<LaneID> {
|
||||
// TODO this is so horrendously slow :D
|
||||
for l in &self.lanes {
|
||||
if l.spots.contains(&Some(id)) {
|
||||
if l.occupants.contains(&Some(id)) {
|
||||
return Some(l.id);
|
||||
}
|
||||
}
|
||||
@ -112,21 +113,17 @@ impl ParkingSimState {
|
||||
// Of the front of the car
|
||||
pub fn get_spot_of_car(&self, c: CarID, l: LaneID) -> ParkingSpot {
|
||||
let idx = self.lanes[l.0]
|
||||
.spots
|
||||
.occupants
|
||||
.iter()
|
||||
.position(|x| *x == Some(c))
|
||||
.unwrap();
|
||||
ParkingSpot {
|
||||
parking_lane: l,
|
||||
spot_idx: idx,
|
||||
dist_along: self.lanes[l.0].spot_fronts[idx].0,
|
||||
}
|
||||
self.lanes[l.0].spots[idx].clone()
|
||||
}
|
||||
|
||||
pub fn get_all_cars(&self) -> Vec<(CarID, LaneID)> {
|
||||
let mut result = Vec::new();
|
||||
for l in &self.lanes {
|
||||
for maybe_car in &l.spots {
|
||||
for maybe_car in &l.occupants {
|
||||
if let Some(car) = maybe_car {
|
||||
result.push((*car, l.id));
|
||||
}
|
||||
@ -137,29 +134,26 @@ impl ParkingSimState {
|
||||
|
||||
pub fn get_first_free_spot(&self, lane: LaneID, dist_along: Distance) -> Option<ParkingSpot> {
|
||||
let l = &self.lanes[lane.0];
|
||||
let idx = l.spots
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(idx, x)| x.is_none() && l.spot_fronts[idx].0 >= dist_along)?;
|
||||
Some(ParkingSpot {
|
||||
parking_lane: lane,
|
||||
spot_idx: idx,
|
||||
dist_along: l.spot_fronts[idx].0,
|
||||
})
|
||||
// Just require the car to currently be behind the end of the spot length, so we don't have
|
||||
// to worry about where in the spot they need to line up.
|
||||
let idx = l.occupants.iter().enumerate().position(|(idx, x)| {
|
||||
x.is_none() && l.spots[idx].dist_along + map_model::PARKING_SPOT_LENGTH >= dist_along
|
||||
})?;
|
||||
Some(l.spots[idx].clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct ParkingLane {
|
||||
id: LaneID,
|
||||
spots: Vec<Option<CarID>>,
|
||||
spot_fronts: Vec<(Distance, Pt2D, Angle)>,
|
||||
spots: Vec<ParkingSpot>,
|
||||
occupants: Vec<Option<CarID>>,
|
||||
}
|
||||
|
||||
// TODO the f64's prevent derivation
|
||||
impl PartialEq for ParkingLane {
|
||||
fn eq(&self, other: &ParkingLane) -> bool {
|
||||
self.id == other.id && self.spots == other.spots
|
||||
self.id == other.id && self.occupants == other.occupants
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,44 +165,88 @@ impl ParkingLane {
|
||||
return ParkingLane {
|
||||
id: l.id,
|
||||
spots: Vec::new(),
|
||||
spot_fronts: Vec::new(),
|
||||
occupants: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
ParkingLane {
|
||||
id: l.id,
|
||||
spots: iter::repeat(None).take(l.number_parking_spots()).collect(),
|
||||
spot_fronts: (0..l.number_parking_spots())
|
||||
occupants: iter::repeat(None).take(l.number_parking_spots()).collect(),
|
||||
spots: (0..l.number_parking_spots())
|
||||
.map(|idx| {
|
||||
let spot_start = map_model::PARKING_SPOT_LENGTH * (2.0 + idx as f64);
|
||||
let dist_along =
|
||||
spot_start - (map_model::PARKING_SPOT_LENGTH - draw_car::CAR_LENGTH) / 2.0;
|
||||
let (pos, angle) = l.dist_along(dist_along);
|
||||
(dist_along, pos, angle)
|
||||
let (pos, angle) = l.dist_along(spot_start);
|
||||
ParkingSpot {
|
||||
parking_lane: l.id,
|
||||
spot_idx: idx,
|
||||
dist_along: spot_start,
|
||||
pos,
|
||||
angle,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_parked_car(&mut self, car: CarID) {
|
||||
let idx = self.spots.iter().position(|x| *x == Some(car)).unwrap();
|
||||
self.spots[idx] = None;
|
||||
let idx = self.occupants.iter().position(|x| *x == Some(car)).unwrap();
|
||||
self.occupants[idx] = None;
|
||||
}
|
||||
|
||||
fn get_draw_cars(&self, map: &Map) -> Vec<DrawCar> {
|
||||
self.spots
|
||||
fn get_draw_cars(&self, map: &Map, properties: &BTreeMap<CarID, Vehicle>) -> Vec<DrawCar> {
|
||||
self.occupants
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, maybe_id)| {
|
||||
maybe_id.and_then(|id| {
|
||||
let (_, front, angle) = self.spot_fronts[idx];
|
||||
Some(DrawCar::new(id, None, map, front, angle, 0.0 * si::M))
|
||||
let vehicle = &properties[&id];
|
||||
let (front, angle) = self.spots[idx].front_of_car(vehicle);
|
||||
Some(DrawCar::new(
|
||||
id,
|
||||
vehicle,
|
||||
None,
|
||||
map,
|
||||
front,
|
||||
angle,
|
||||
0.0 * si::M,
|
||||
))
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
!self.spots.iter().find(|&&x| x.is_some()).is_some()
|
||||
!self.occupants.iter().find(|&&x| x.is_some()).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derivative(PartialEq, Eq)]
|
||||
pub struct ParkingSpot {
|
||||
pub parking_lane: LaneID,
|
||||
pub spot_idx: usize,
|
||||
// These 3 are of the front of the parking spot
|
||||
#[derivative(PartialEq = "ignore")]
|
||||
dist_along: Distance,
|
||||
pos: Pt2D,
|
||||
#[derivative(PartialEq = "ignore")]
|
||||
angle: Angle,
|
||||
}
|
||||
|
||||
impl ParkingSpot {
|
||||
pub fn dist_along_for_car(&self, vehicle: &Vehicle) -> Distance {
|
||||
// Find the offset to center this particular car in the parking spot
|
||||
let offset = (map_model::PARKING_SPOT_LENGTH - vehicle.length) / 2.0;
|
||||
self.dist_along - offset
|
||||
}
|
||||
|
||||
fn front_of_car(&self, vehicle: &Vehicle) -> (Pt2D, Angle) {
|
||||
// Find the offset to center this particular car in the parking spot
|
||||
let offset = (map_model::PARKING_SPOT_LENGTH - vehicle.length) / 2.0;
|
||||
(
|
||||
self.pos
|
||||
.project_away(offset.value_unsafe, self.angle.opposite()),
|
||||
self.angle,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -9,14 +9,14 @@ use intersections::{AgentInfo, IntersectionSimState};
|
||||
use kinematics::Vehicle;
|
||||
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
||||
use parametric_driving;
|
||||
use parking::ParkingSimState;
|
||||
use parking::{ParkingSimState, ParkingSpot};
|
||||
use rand::{FromEntropy, Rng, SeedableRng, XorShiftRng};
|
||||
use spawn::Spawner;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
||||
use std::f64;
|
||||
use std::time::{Duration, Instant};
|
||||
use walking::WalkingSimState;
|
||||
use {CarID, CarState, Distance, InvariantViolated, PedestrianID, Tick, TIMESTEP};
|
||||
use {CarID, CarState, InvariantViolated, PedestrianID, Tick, TIMESTEP};
|
||||
|
||||
#[derive(Serialize, Deserialize, Derivative, PartialEq, Eq)]
|
||||
pub enum DrivingModel {
|
||||
@ -317,7 +317,10 @@ impl Sim {
|
||||
pub fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCar> {
|
||||
self.driving_state
|
||||
.get_draw_car(id, self.time, map, &self.car_properties)
|
||||
.or_else(|| self.parking_state.get_draw_car(id, map))
|
||||
.or_else(|| {
|
||||
self.parking_state
|
||||
.get_draw_car(id, map, &self.car_properties)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrian> {
|
||||
@ -331,7 +334,8 @@ impl Sim {
|
||||
self.driving_state
|
||||
.get_draw_cars_on_lane(l, self.time, map, &self.car_properties)
|
||||
}
|
||||
LaneType::Parking => self.parking_state.get_draw_cars(l, map),
|
||||
LaneType::Parking => self.parking_state
|
||||
.get_draw_cars(l, map, &self.car_properties),
|
||||
LaneType::Sidewalk => Vec::new(),
|
||||
LaneType::Biking => Vec::new(),
|
||||
}
|
||||
@ -419,16 +423,6 @@ impl Benchmark {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Derivative)]
|
||||
#[derivative(PartialEq, Eq)]
|
||||
pub struct ParkingSpot {
|
||||
pub parking_lane: LaneID,
|
||||
pub spot_idx: usize,
|
||||
// Of the front of the car
|
||||
#[derivative(PartialEq = "ignore")]
|
||||
pub dist_along: Distance,
|
||||
}
|
||||
|
||||
// TODO better name?
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct CarParking {
|
||||
|
Loading…
Reference in New Issue
Block a user