mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 19:27:11 +03:00
bring in parking code and some structures needed for it. dont use it yet. switch to Vehicle.
This commit is contained in:
parent
ff8ddc94b5
commit
6673807422
@ -197,9 +197,12 @@ fn spawn_car(
|
||||
let spawn_time = Duration::seconds(0.2) * (id % 5) as f64;
|
||||
|
||||
sim.spawn_car(
|
||||
CarID::tmp_new(id, VehicleType::Car),
|
||||
vehicle_len,
|
||||
new_des_model::Vehicle {
|
||||
id: CarID::tmp_new(id, VehicleType::Car),
|
||||
vehicle_type: VehicleType::Car,
|
||||
length: vehicle_len,
|
||||
max_speed,
|
||||
},
|
||||
path,
|
||||
spawn_time,
|
||||
start_dist,
|
||||
|
@ -1,20 +1,19 @@
|
||||
use geom::{Distance, Duration, PolyLine, Speed};
|
||||
use crate::plugins::sim::new_des_model::Vehicle;
|
||||
use geom::{Distance, Duration, PolyLine};
|
||||
use map_model::{Map, Traversable};
|
||||
use sim::{CarID, DrawCarInput};
|
||||
use sim::DrawCarInput;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Car {
|
||||
pub id: CarID,
|
||||
pub vehicle_len: Distance,
|
||||
pub max_speed: Option<Speed>,
|
||||
pub vehicle: Vehicle,
|
||||
// Front is always the current step
|
||||
pub path: VecDeque<Traversable>,
|
||||
pub end_dist: Distance,
|
||||
pub state: CarState,
|
||||
|
||||
// In reverse order -- most recently left is first. The sum length of these must be >=
|
||||
// vehicle_len.
|
||||
// vehicle.length.
|
||||
pub last_steps: VecDeque<Traversable>,
|
||||
}
|
||||
|
||||
@ -36,7 +35,7 @@ impl Car {
|
||||
);
|
||||
|
||||
let mut speed = on.speed_limit(map);
|
||||
if let Some(s) = self.max_speed {
|
||||
if let Some(s) = self.vehicle.max_speed {
|
||||
speed = speed.min(s);
|
||||
}
|
||||
let dt = (dist_int.end - dist_int.start) / speed;
|
||||
@ -49,7 +48,7 @@ impl Car {
|
||||
for on in self.last_steps.drain(..) {
|
||||
len += on.length(map);
|
||||
keep.push_back(on);
|
||||
if len >= self.vehicle_len {
|
||||
if len >= self.vehicle.length {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -58,9 +57,9 @@ impl Car {
|
||||
|
||||
pub fn get_draw_car(&self, front: Distance, map: &Map) -> DrawCarInput {
|
||||
assert!(front >= Distance::ZERO);
|
||||
let body = if front >= self.vehicle_len {
|
||||
let body = if front >= self.vehicle.length {
|
||||
self.path[0]
|
||||
.slice(front - self.vehicle_len, front, map)
|
||||
.slice(front - self.vehicle.length, front, map)
|
||||
.unwrap()
|
||||
.0
|
||||
} else {
|
||||
@ -69,11 +68,11 @@ impl Car {
|
||||
.slice(Distance::ZERO, front, map)
|
||||
.map(|(pl, _)| pl.points().clone())
|
||||
.unwrap_or_else(Vec::new);
|
||||
let mut leftover = self.vehicle_len - front;
|
||||
let mut leftover = self.vehicle.length - front;
|
||||
let mut i = 0;
|
||||
while leftover > Distance::ZERO {
|
||||
if i == self.last_steps.len() {
|
||||
panic!("{} spawned too close to short stuff", self.id);
|
||||
panic!("{} spawned too close to short stuff", self.vehicle.id);
|
||||
}
|
||||
let len = self.last_steps[i].length(map);
|
||||
let start = (len - leftover).max(Distance::ZERO);
|
||||
@ -90,7 +89,7 @@ impl Car {
|
||||
};
|
||||
|
||||
DrawCarInput {
|
||||
id: self.id,
|
||||
id: self.vehicle.id,
|
||||
waiting_for_turn: None,
|
||||
stopping_trace: None,
|
||||
state: match self.state {
|
||||
@ -98,7 +97,7 @@ impl Car {
|
||||
CarState::Queued => sim::CarState::Stuck,
|
||||
CarState::Crossing(_, _) => sim::CarState::Moving,
|
||||
},
|
||||
vehicle_type: self.id.tmp_get_vehicle_type(),
|
||||
vehicle_type: self.vehicle.vehicle_type,
|
||||
on: self.path[0],
|
||||
body,
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::plugins::sim::new_des_model::{
|
||||
Car, CarState, IntersectionController, Queue, FOLLOWING_DISTANCE, MAX_VEHICLE_LENGTH,
|
||||
Car, CarState, IntersectionController, Queue, Vehicle, FOLLOWING_DISTANCE, MAX_VEHICLE_LENGTH,
|
||||
};
|
||||
use ezgui::{Color, GfxCtx};
|
||||
use geom::{Distance, Duration, Speed};
|
||||
use geom::{Distance, Duration};
|
||||
use map_model::{IntersectionID, Map, Traversable, LANE_THICKNESS};
|
||||
use sim::{CarID, DrawCarInput};
|
||||
use sim::DrawCarInput;
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
|
||||
const FREEFLOW: Color = Color::CYAN;
|
||||
@ -14,15 +14,7 @@ pub struct DrivingSimState {
|
||||
queues: BTreeMap<Traversable, Queue>,
|
||||
intersections: BTreeMap<IntersectionID, IntersectionController>,
|
||||
|
||||
spawn_later: Vec<(
|
||||
CarID,
|
||||
Distance,
|
||||
Option<Speed>,
|
||||
Vec<Traversable>,
|
||||
Duration,
|
||||
Distance,
|
||||
Distance,
|
||||
)>,
|
||||
spawn_later: Vec<(Vehicle, Vec<Traversable>, Duration, Distance, Distance)>,
|
||||
}
|
||||
|
||||
impl DrivingSimState {
|
||||
@ -136,16 +128,14 @@ impl DrivingSimState {
|
||||
|
||||
pub fn spawn_car(
|
||||
&mut self,
|
||||
id: CarID,
|
||||
vehicle_len: Distance,
|
||||
max_speed: Option<Speed>,
|
||||
vehicle: Vehicle,
|
||||
path: Vec<Traversable>,
|
||||
start_time: Duration,
|
||||
start_dist: Distance,
|
||||
end_dist: Distance,
|
||||
map: &Map,
|
||||
) {
|
||||
if start_dist < vehicle_len {
|
||||
if start_dist < vehicle.length {
|
||||
panic!(
|
||||
"Can't spawn a car at {}; too close to the start",
|
||||
start_dist
|
||||
@ -171,15 +161,8 @@ impl DrivingSimState {
|
||||
);
|
||||
}
|
||||
|
||||
self.spawn_later.push((
|
||||
id,
|
||||
vehicle_len,
|
||||
max_speed,
|
||||
path,
|
||||
start_time,
|
||||
start_dist,
|
||||
end_dist,
|
||||
));
|
||||
self.spawn_later
|
||||
.push((vehicle, path, start_time, start_dist, end_dist));
|
||||
}
|
||||
|
||||
pub fn step_if_needed(&mut self, time: Duration, map: &Map) {
|
||||
@ -219,7 +202,7 @@ impl DrivingSimState {
|
||||
|
||||
// Carry out the transitions.
|
||||
for from in head_cars_ready_to_advance {
|
||||
let car_id = self.queues[&from].cars[0].id;
|
||||
let car_id = self.queues[&from].cars[0].vehicle.id;
|
||||
let goto = self.queues[&from].cars[0].path[1];
|
||||
|
||||
// Always need to do this check.
|
||||
@ -254,7 +237,7 @@ impl DrivingSimState {
|
||||
CarState::Queued => {
|
||||
follower.state = follower.crossing_state(
|
||||
// Since the follower was Queued, this must be where they are
|
||||
from.length(map) - car.vehicle_len - FOLLOWING_DISTANCE,
|
||||
from.length(map) - car.vehicle.length - FOLLOWING_DISTANCE,
|
||||
time,
|
||||
from,
|
||||
map,
|
||||
@ -271,13 +254,13 @@ impl DrivingSimState {
|
||||
car.state = car.crossing_state(Distance::ZERO, time, goto, map);
|
||||
|
||||
if goto.maybe_lane().is_some() {
|
||||
// TODO Actually, don't call turn_finished until the car is at least vehicle_len +
|
||||
// FOLLOWING_DISTANCE into the next lane. This'll be hard to predict when we're
|
||||
// TODO Actually, don't call turn_finished until the car is at least vehicle.length
|
||||
// + FOLLOWING_DISTANCE into the next lane. This'll be hard to predict when we're
|
||||
// event-based, so hold off on this bit of realism.
|
||||
self.intersections
|
||||
.get_mut(&last_step.as_turn().parent)
|
||||
.unwrap()
|
||||
.turn_finished(car.id, last_step.as_turn());
|
||||
.turn_finished(car.vehicle.id, last_step.as_turn());
|
||||
}
|
||||
|
||||
self.queues.get_mut(&goto).unwrap().cars.push_back(car);
|
||||
@ -285,9 +268,7 @@ impl DrivingSimState {
|
||||
|
||||
// Spawn cars at the end, so we can see the correct state of everything else at this time.
|
||||
let mut retain_spawn = Vec::new();
|
||||
for (id, vehicle_len, max_speed, path, start_time, start_dist, end_dist) in
|
||||
self.spawn_later.drain(..)
|
||||
{
|
||||
for (vehicle, path, start_time, start_dist, end_dist) in self.spawn_later.drain(..) {
|
||||
let mut spawned = false;
|
||||
let first_lane = path[0].as_lane();
|
||||
|
||||
@ -296,12 +277,10 @@ impl DrivingSimState {
|
||||
.nobody_headed_towards(first_lane)
|
||||
{
|
||||
if let Some(idx) = self.queues[&Traversable::Lane(first_lane)]
|
||||
.get_idx_to_insert_car(start_dist, vehicle_len, time)
|
||||
.get_idx_to_insert_car(start_dist, vehicle.length, time)
|
||||
{
|
||||
let mut car = Car {
|
||||
id,
|
||||
vehicle_len,
|
||||
max_speed,
|
||||
vehicle: vehicle.clone(),
|
||||
path: VecDeque::from(path.clone()),
|
||||
end_dist,
|
||||
state: CarState::Queued,
|
||||
@ -315,19 +294,11 @@ impl DrivingSimState {
|
||||
.cars
|
||||
.insert(idx, car);
|
||||
spawned = true;
|
||||
//println!("{} spawned at {}", id, time);
|
||||
//println!("{} spawned at {}", vehicle.id, time);
|
||||
}
|
||||
}
|
||||
if !spawned {
|
||||
retain_spawn.push((
|
||||
id,
|
||||
vehicle_len,
|
||||
max_speed,
|
||||
path,
|
||||
start_time,
|
||||
start_dist,
|
||||
end_dist,
|
||||
));
|
||||
retain_spawn.push((vehicle, path, start_time, start_dist, end_dist));
|
||||
}
|
||||
}
|
||||
self.spawn_later = retain_spawn;
|
||||
|
@ -1,14 +1,64 @@
|
||||
mod car;
|
||||
mod driving;
|
||||
mod intersection;
|
||||
mod parking;
|
||||
mod queue;
|
||||
|
||||
pub use self::car::{Car, CarState};
|
||||
pub use self::driving::DrivingSimState;
|
||||
pub use self::intersection::IntersectionController;
|
||||
pub use self::queue::Queue;
|
||||
use geom::Distance;
|
||||
use geom::{Distance, Speed};
|
||||
use map_model::{BuildingID, LaneID};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sim::{CarID, VehicleType};
|
||||
|
||||
pub const MIN_VEHICLE_LENGTH: Distance = Distance::const_meters(2.0);
|
||||
pub const MAX_VEHICLE_LENGTH: Distance = Distance::const_meters(7.0);
|
||||
pub const FOLLOWING_DISTANCE: Distance = Distance::const_meters(1.0);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
pub struct Vehicle {
|
||||
pub id: CarID,
|
||||
pub vehicle_type: VehicleType,
|
||||
|
||||
pub length: Distance,
|
||||
pub max_speed: Option<Speed>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ParkingSpot {
|
||||
pub lane: LaneID,
|
||||
pub idx: usize,
|
||||
}
|
||||
|
||||
impl ParkingSpot {
|
||||
pub fn new(lane: LaneID, idx: usize) -> ParkingSpot {
|
||||
ParkingSpot { lane, idx }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct ParkedCar {
|
||||
pub car: CarID,
|
||||
pub spot: ParkingSpot,
|
||||
pub vehicle: Vehicle,
|
||||
pub owner: Option<BuildingID>,
|
||||
}
|
||||
|
||||
impl ParkedCar {
|
||||
pub fn new(
|
||||
car: CarID,
|
||||
spot: ParkingSpot,
|
||||
vehicle: Vehicle,
|
||||
owner: Option<BuildingID>,
|
||||
) -> ParkedCar {
|
||||
assert_eq!(vehicle.vehicle_type, VehicleType::Car);
|
||||
ParkedCar {
|
||||
car,
|
||||
spot,
|
||||
vehicle,
|
||||
owner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
258
editor/src/plugins/sim/new_des_model/parking.rs
Normal file
258
editor/src/plugins/sim/new_des_model/parking.rs
Normal file
@ -0,0 +1,258 @@
|
||||
use crate::plugins::sim::new_des_model::{ParkedCar, ParkingSpot, Vehicle};
|
||||
use abstutil::{deserialize_btreemap, serialize_btreemap};
|
||||
use geom::{Angle, Distance, Pt2D};
|
||||
use map_model;
|
||||
use map_model::{BuildingID, Lane, LaneID, LaneType, Map, Position, Traversable};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sim::{CarID, CarState, DrawCarInput, VehicleType};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::iter;
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq)]
|
||||
pub struct ParkingSimState {
|
||||
#[serde(
|
||||
serialize_with = "serialize_btreemap",
|
||||
deserialize_with = "deserialize_btreemap"
|
||||
)]
|
||||
cars: BTreeMap<CarID, ParkedCar>,
|
||||
// TODO hacky, but other types of lanes just mark 0 spots. :\
|
||||
lanes: Vec<ParkingLane>,
|
||||
}
|
||||
|
||||
impl ParkingSimState {
|
||||
pub fn new(map: &Map) -> ParkingSimState {
|
||||
ParkingSimState {
|
||||
cars: BTreeMap::new(),
|
||||
lanes: map
|
||||
.all_lanes()
|
||||
.iter()
|
||||
.map(|l| ParkingLane::new(l))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edit_remove_lane(&mut self, id: LaneID) {
|
||||
assert!(self.lanes[id.0].is_empty());
|
||||
self.lanes[id.0] = ParkingLane {
|
||||
id,
|
||||
spots: Vec::new(),
|
||||
occupants: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn edit_add_lane(&mut self, l: &Lane) {
|
||||
self.lanes[l.id.0] = ParkingLane::new(l);
|
||||
}
|
||||
|
||||
// TODO bad name
|
||||
pub fn total_count(&self) -> usize {
|
||||
self.cars.len()
|
||||
}
|
||||
|
||||
pub fn get_free_spots(&self, lane: LaneID) -> Vec<ParkingSpot> {
|
||||
let l = &self.lanes[lane.0];
|
||||
let mut spots: Vec<ParkingSpot> = Vec::new();
|
||||
for (idx, maybe_occupant) in l.occupants.iter().enumerate() {
|
||||
if maybe_occupant.is_none() {
|
||||
spots.push(ParkingSpot::new(l.id, idx));
|
||||
}
|
||||
}
|
||||
spots
|
||||
}
|
||||
|
||||
pub fn remove_parked_car(&mut self, p: ParkedCar) {
|
||||
self.cars.remove(&p.car);
|
||||
self.lanes[p.spot.lane.0].remove_parked_car(p.car);
|
||||
}
|
||||
|
||||
pub fn add_parked_car(&mut self, p: ParkedCar) {
|
||||
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.car);
|
||||
self.cars.insert(p.car, p);
|
||||
}
|
||||
|
||||
pub fn get_draw_cars(&self, id: LaneID, map: &Map) -> Vec<DrawCarInput> {
|
||||
self.lanes[id.0]
|
||||
.occupants
|
||||
.iter()
|
||||
.filter_map(|maybe_occupant| {
|
||||
if let Some(car) = maybe_occupant {
|
||||
Some(self.get_draw_car(*car, map).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput> {
|
||||
let p = self.cars.get(&id)?;
|
||||
let lane = p.spot.lane;
|
||||
|
||||
let front_dist = self.lanes[lane.0].spots[p.spot.idx].dist_along_for_car(&p.vehicle);
|
||||
Some(DrawCarInput {
|
||||
id: p.car,
|
||||
waiting_for_turn: None,
|
||||
stopping_trace: None,
|
||||
state: CarState::Parked,
|
||||
vehicle_type: VehicleType::Car,
|
||||
on: Traversable::Lane(lane),
|
||||
|
||||
body: map
|
||||
.get_l(lane)
|
||||
.lane_center_pts
|
||||
.slice(front_dist - p.vehicle.length, front_dist)
|
||||
.unwrap()
|
||||
.0,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_all_draw_cars(&self, map: &Map) -> Vec<DrawCarInput> {
|
||||
self.cars
|
||||
.keys()
|
||||
.map(|id| self.get_draw_car(*id, map).unwrap())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn lookup_car(&self, id: CarID) -> Option<&ParkedCar> {
|
||||
self.cars.get(&id)
|
||||
}
|
||||
|
||||
pub fn get_first_free_spot(
|
||||
&self,
|
||||
parking_pos: Position,
|
||||
vehicle: &Vehicle,
|
||||
) -> Option<ParkingSpot> {
|
||||
let l = &self.lanes[parking_pos.lane().0];
|
||||
let idx = l.occupants.iter().enumerate().position(|(idx, x)| {
|
||||
x.is_none() && parking_pos.dist_along() <= l.spots[idx].dist_along_for_car(vehicle)
|
||||
})?;
|
||||
Some(ParkingSpot::new(parking_pos.lane(), idx))
|
||||
}
|
||||
|
||||
pub fn get_car_at_spot(&self, spot: ParkingSpot) -> Option<ParkedCar> {
|
||||
let car = self.lanes[spot.lane.0].occupants[spot.idx]?;
|
||||
Some(self.cars[&car].clone())
|
||||
}
|
||||
|
||||
pub fn spot_to_driving_pos(
|
||||
&self,
|
||||
spot: ParkingSpot,
|
||||
vehicle: &Vehicle,
|
||||
driving_lane: LaneID,
|
||||
map: &Map,
|
||||
) -> Position {
|
||||
Position::new(spot.lane, self.get_spot(spot).dist_along_for_car(vehicle))
|
||||
.equiv_pos(driving_lane, map)
|
||||
}
|
||||
|
||||
pub fn spot_to_sidewalk_pos(&self, spot: ParkingSpot, sidewalk: LaneID, map: &Map) -> Position {
|
||||
Position::new(spot.lane, self.get_spot(spot).dist_along_for_ped()).equiv_pos(sidewalk, map)
|
||||
}
|
||||
|
||||
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 p in self.cars.values() {
|
||||
if p.owner == Some(id) {
|
||||
result.push(p);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn get_owner_of_car(&self, id: CarID) -> Option<BuildingID> {
|
||||
self.lookup_car(id).and_then(|p| p.owner)
|
||||
}
|
||||
|
||||
pub fn count(&self, lanes: &HashSet<LaneID>) -> (usize, usize) {
|
||||
// TODO self.cars.len() works for cars_parked; we could maintain the other value easily too
|
||||
let mut cars_parked = 0;
|
||||
let mut open_parking_spots = 0;
|
||||
|
||||
for id in lanes {
|
||||
for maybe_car in &self.lanes[id.0].occupants {
|
||||
if maybe_car.is_some() {
|
||||
cars_parked += 1;
|
||||
} else {
|
||||
open_parking_spots += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(cars_parked, open_parking_spots)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq)]
|
||||
struct ParkingLane {
|
||||
id: LaneID,
|
||||
spots: Vec<ParkingSpotGeometry>,
|
||||
occupants: Vec<Option<CarID>>,
|
||||
}
|
||||
|
||||
impl ParkingLane {
|
||||
fn new(l: &Lane) -> ParkingLane {
|
||||
if l.lane_type != LaneType::Parking {
|
||||
return ParkingLane {
|
||||
id: l.id,
|
||||
spots: Vec::new(),
|
||||
occupants: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
ParkingLane {
|
||||
id: l.id,
|
||||
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 (pos, angle) = l.dist_along(spot_start);
|
||||
ParkingSpotGeometry {
|
||||
dist_along: spot_start,
|
||||
pos,
|
||||
angle,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_parked_car(&mut self, car: CarID) {
|
||||
let idx = self.occupants.iter().position(|x| *x == Some(car)).unwrap();
|
||||
self.occupants[idx] = None;
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
!self.occupants.iter().any(|x| x.is_some())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
struct ParkingSpotGeometry {
|
||||
// These 3 are of the front of the parking spot (farthest along)
|
||||
dist_along: Distance,
|
||||
pos: Pt2D,
|
||||
angle: Angle,
|
||||
}
|
||||
|
||||
impl ParkingSpotGeometry {
|
||||
fn dist_along_for_ped(&self) -> Distance {
|
||||
// Always centered in the entire parking spot
|
||||
self.dist_along - (map_model::PARKING_SPOT_LENGTH / 2.0)
|
||||
}
|
||||
|
||||
fn dist_along_for_car(&self, vehicle: &Vehicle) -> Distance {
|
||||
// Find the offset to center this particular car in the parking spot
|
||||
self.dist_along - (map_model::PARKING_SPOT_LENGTH - vehicle.length) / 2.0
|
||||
}
|
||||
}
|
@ -33,7 +33,9 @@ impl Queue {
|
||||
|
||||
for car in &self.cars {
|
||||
let bound = match result.last() {
|
||||
Some((leader, last_dist)) => *last_dist - leader.vehicle_len - FOLLOWING_DISTANCE,
|
||||
Some((leader, last_dist)) => {
|
||||
*last_dist - leader.vehicle.length - FOLLOWING_DISTANCE
|
||||
}
|
||||
None => self.geom_len,
|
||||
};
|
||||
|
||||
@ -42,7 +44,7 @@ impl Queue {
|
||||
dump_cars(&result, self.id, time);
|
||||
panic!(
|
||||
"Queue has spillover on {:?} at {} -- can't draw {}, bound is {}",
|
||||
self.id, time, car.id, bound
|
||||
self.id, time, car.vehicle.id, bound
|
||||
);
|
||||
}
|
||||
|
||||
@ -80,7 +82,7 @@ impl Queue {
|
||||
|
||||
// Are we too close to the leader?
|
||||
if idx != 0
|
||||
&& dists[idx - 1].1 - dists[idx - 1].0.vehicle_len - FOLLOWING_DISTANCE < start_dist
|
||||
&& dists[idx - 1].1 - dists[idx - 1].0.vehicle.length - FOLLOWING_DISTANCE < start_dist
|
||||
{
|
||||
return None;
|
||||
}
|
||||
@ -96,7 +98,7 @@ impl Queue {
|
||||
// This could also be implemented by calling get_idx_to_insert_car with start_dist =
|
||||
// self.geom_len
|
||||
match self.get_car_positions(time).last() {
|
||||
Some((car, front)) => *front >= car.vehicle_len + FOLLOWING_DISTANCE,
|
||||
Some((car, front)) => *front >= car.vehicle.length + FOLLOWING_DISTANCE,
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
@ -108,7 +110,7 @@ fn validate_positions(
|
||||
id: Traversable,
|
||||
) -> Vec<(&Car, Distance)> {
|
||||
for pair in cars.windows(2) {
|
||||
if pair[0].1 - pair[0].0.vehicle_len - FOLLOWING_DISTANCE < pair[1].1 {
|
||||
if pair[0].1 - pair[0].0.vehicle.length - FOLLOWING_DISTANCE < pair[1].1 {
|
||||
dump_cars(&cars, id, time);
|
||||
panic!(
|
||||
"get_car_positions wound up with bad positioning: {} then {}\n{:?}",
|
||||
@ -122,7 +124,10 @@ fn validate_positions(
|
||||
fn dump_cars(cars: &Vec<(&Car, Distance)>, id: Traversable, time: Duration) {
|
||||
println!("\nOn {:?} at {}...", id, time);
|
||||
for (car, dist) in cars {
|
||||
println!("- {} @ {} (length {})", car.id, dist, car.vehicle_len);
|
||||
println!(
|
||||
"- {} @ {} (length {})",
|
||||
car.vehicle.id, dist, car.vehicle.length
|
||||
);
|
||||
match car.state {
|
||||
CarState::Crossing(ref time_int, ref dist_int) => {
|
||||
println!(
|
||||
|
@ -45,11 +45,6 @@ impl CarID {
|
||||
pub fn tmp_new(idx: usize, vt: VehicleType) -> CarID {
|
||||
CarID(idx, vt)
|
||||
}
|
||||
|
||||
// TODO Not sure if the new DES model should do this
|
||||
pub fn tmp_get_vehicle_type(self) -> VehicleType {
|
||||
self.1
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CarID {
|
||||
|
Loading…
Reference in New Issue
Block a user