mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
WIP storing per-car properties like accel somewhere
This commit is contained in:
parent
e2ee2ecc84
commit
917c3c3ed5
@ -548,3 +548,11 @@ Some first tests to write:
|
|||||||
- a line of cars moving through a stop sign looks jittery right now. correct or not?
|
- a line of cars moving through a stop sign looks jittery right now. correct or not?
|
||||||
|
|
||||||
Unclear how to nicely let the test inspect stuff every tick.
|
Unclear how to nicely let the test inspect stuff every tick.
|
||||||
|
|
||||||
|
## Per-car properties
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -85,6 +85,7 @@ impl Car {
|
|||||||
sim: &DrivingSimState,
|
sim: &DrivingSimState,
|
||||||
parking_sim: &ParkingSimState,
|
parking_sim: &ParkingSimState,
|
||||||
intersections: &IntersectionSimState,
|
intersections: &IntersectionSimState,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
) -> Action {
|
) -> Action {
|
||||||
if self.parking.is_some() {
|
if self.parking.is_some() {
|
||||||
// TODO right place for this check?
|
// TODO right place for this check?
|
||||||
@ -108,7 +109,7 @@ impl Car {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let vehicle = Vehicle::typical_car();
|
let vehicle = &properties[&self.id];
|
||||||
|
|
||||||
// TODO could wrap this state up
|
// TODO could wrap this state up
|
||||||
let mut current_speed_limit = self.on.speed_limit(map);
|
let mut current_speed_limit = self.on.speed_limit(map);
|
||||||
@ -153,7 +154,7 @@ impl Car {
|
|||||||
let accel = vehicle.accel_to_follow(
|
let accel = vehicle.accel_to_follow(
|
||||||
self.speed,
|
self.speed,
|
||||||
current_speed_limit,
|
current_speed_limit,
|
||||||
&vehicle,
|
&properties[&other.id],
|
||||||
dist_behind_other,
|
dist_behind_other,
|
||||||
other.speed,
|
other.speed,
|
||||||
);
|
);
|
||||||
@ -380,10 +381,16 @@ 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(&self, sim: &DrivingSimState, map: &Map, time: Tick) -> Vec<DrawCar> {
|
fn get_draw_cars(
|
||||||
|
&self,
|
||||||
|
sim: &DrivingSimState,
|
||||||
|
map: &Map,
|
||||||
|
time: Tick,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Vec<DrawCar> {
|
||||||
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).unwrap())
|
results.push(sim.get_draw_car(*id, time, map, properties).unwrap())
|
||||||
}
|
}
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
@ -542,11 +549,15 @@ impl DrivingSimState {
|
|||||||
parking_sim: &ParkingSimState,
|
parking_sim: &ParkingSimState,
|
||||||
intersections: &mut IntersectionSimState,
|
intersections: &mut IntersectionSimState,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
) -> Result<Vec<CarParking>, InvariantViolated> {
|
) -> Result<Vec<CarParking>, InvariantViolated> {
|
||||||
// Could be concurrent, since this is deterministic.
|
// Could be concurrent, since this is deterministic.
|
||||||
let mut requested_moves: Vec<(CarID, Action)> = Vec::new();
|
let mut requested_moves: Vec<(CarID, Action)> = Vec::new();
|
||||||
for c in self.cars.values() {
|
for c in self.cars.values() {
|
||||||
requested_moves.push((c.id, c.react(map, time, self, parking_sim, intersections)));
|
requested_moves.push((
|
||||||
|
c.id,
|
||||||
|
c.react(map, time, self, parking_sim, intersections, properties),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// In AORTA, there was a split here -- react vs step phase. We're still following the same
|
// In AORTA, there was a split here -- react vs step phase. We're still following the same
|
||||||
@ -648,6 +659,7 @@ impl DrivingSimState {
|
|||||||
parking: CarParking,
|
parking: CarParking,
|
||||||
mut path: VecDeque<LaneID>,
|
mut path: VecDeque<LaneID>,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let start = path.pop_front().unwrap();
|
let start = path.pop_front().unwrap();
|
||||||
let dist_along = parking.spot.dist_along;
|
let dist_along = parking.spot.dist_along;
|
||||||
@ -670,11 +682,11 @@ impl DrivingSimState {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let vehicle = Vehicle::typical_car();
|
let vehicle = &properties[&car];
|
||||||
let accel_for_other_to_stop = vehicle.accel_to_follow(
|
let accel_for_other_to_stop = vehicle.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(),
|
||||||
&vehicle,
|
&properties[&other],
|
||||||
dist_along - other_dist,
|
dist_along - other_dist,
|
||||||
0.0 * si::MPS,
|
0.0 * si::MPS,
|
||||||
);
|
);
|
||||||
@ -713,10 +725,16 @@ impl DrivingSimState {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_car(&self, id: CarID, time: Tick, map: &Map) -> Option<DrawCar> {
|
pub fn get_draw_car(
|
||||||
|
&self,
|
||||||
|
id: CarID,
|
||||||
|
time: Tick,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Option<DrawCar> {
|
||||||
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 stopping_dist = Vehicle::typical_car().stopping_distance(c.speed);
|
let stopping_dist = properties[&id].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 {
|
||||||
@ -744,13 +762,25 @@ impl DrivingSimState {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_cars_on_lane(&self, lane: LaneID, time: Tick, map: &Map) -> Vec<DrawCar> {
|
pub fn get_draw_cars_on_lane(
|
||||||
self.lanes[lane.0].get_draw_cars(self, map, time)
|
&self,
|
||||||
|
lane: LaneID,
|
||||||
|
time: Tick,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Vec<DrawCar> {
|
||||||
|
self.lanes[lane.0].get_draw_cars(self, map, time, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_cars_on_turn(&self, turn: TurnID, time: Tick, map: &Map) -> Vec<DrawCar> {
|
pub fn get_draw_cars_on_turn(
|
||||||
|
&self,
|
||||||
|
turn: TurnID,
|
||||||
|
time: Tick,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Vec<DrawCar> {
|
||||||
if let Some(queue) = self.turns.get(&turn) {
|
if let Some(queue) = self.turns.get(&turn) {
|
||||||
return queue.get_draw_cars(self, map, time);
|
return queue.get_draw_cars(self, map, time, properties);
|
||||||
}
|
}
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use dimensioned::si;
|
use dimensioned::si;
|
||||||
use geom::EPSILON_DIST;
|
use geom::EPSILON_DIST;
|
||||||
use models::FOLLOWING_DISTANCE;
|
use models::FOLLOWING_DISTANCE;
|
||||||
|
use rand::Rng;
|
||||||
use std;
|
use std;
|
||||||
use {Acceleration, Distance, Speed, Time, TIMESTEP};
|
use {Acceleration, CarID, Distance, Speed, Time, TIMESTEP};
|
||||||
|
|
||||||
pub const EPSILON_SPEED: Speed = si::MeterPerSecond {
|
pub const EPSILON_SPEED: Speed = si::MeterPerSecond {
|
||||||
value_unsafe: 0.00000001,
|
value_unsafe: 0.00000001,
|
||||||
@ -12,18 +13,31 @@ pub const EPSILON_SPEED: Speed = si::MeterPerSecond {
|
|||||||
// 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)]
|
||||||
pub struct Vehicle {
|
pub struct Vehicle {
|
||||||
|
pub id: CarID,
|
||||||
|
|
||||||
// > 0
|
// > 0
|
||||||
max_accel: Acceleration,
|
max_accel: Acceleration,
|
||||||
// < 0
|
// < 0
|
||||||
pub max_deaccel: Acceleration,
|
pub max_deaccel: Acceleration,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this is used for verifying sim state determinism, so it should actually check everything.
|
||||||
|
// the f64 prevents this from being derived.
|
||||||
|
impl PartialEq for Vehicle {
|
||||||
|
fn eq(&self, other: &Vehicle) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Eq for Vehicle {}
|
||||||
|
|
||||||
impl Vehicle {
|
impl Vehicle {
|
||||||
pub fn typical_car() -> Vehicle {
|
pub fn generate_typical_car<R: Rng + ?Sized>(id: CarID, rng: &mut R) -> Vehicle {
|
||||||
Vehicle {
|
Vehicle {
|
||||||
max_accel: 2.7 * si::MPS2,
|
id,
|
||||||
max_deaccel: -2.7 * si::MPS2,
|
max_accel: rng.gen_range(2.4, 2.8) * si::MPS2,
|
||||||
|
max_deaccel: rng.gen_range(-2.8, -2.4) * si::MPS2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,13 +194,20 @@ 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(&self, time: Tick, sim: &DrivingSimState, map: &Map) -> Vec<DrawCar> {
|
fn get_draw_cars(
|
||||||
|
&self,
|
||||||
|
time: Tick,
|
||||||
|
sim: &DrivingSimState,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Vec<DrawCar> {
|
||||||
if self.cars_queue.is_empty() {
|
if self.cars_queue.is_empty() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO base this on actual speed ;)
|
// TODO base this on actual speed and each vehicle ;)
|
||||||
let stopping_dist = Vehicle::typical_car().stopping_distance(self.id.speed_limit(map));
|
let stopping_dist =
|
||||||
|
properties[&self.cars_queue[0]].stopping_distance(self.id.speed_limit(map));
|
||||||
|
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
let (pos1, angle1, dist_along1) =
|
let (pos1, angle1, dist_along1) =
|
||||||
@ -372,6 +379,7 @@ impl DrivingSimState {
|
|||||||
_parking_sim: &ParkingSimState,
|
_parking_sim: &ParkingSimState,
|
||||||
intersections: &mut IntersectionSimState,
|
intersections: &mut IntersectionSimState,
|
||||||
_rng: &mut R,
|
_rng: &mut R,
|
||||||
|
_properties: &BTreeMap<CarID, Vehicle>,
|
||||||
) -> Result<Vec<CarParking>, InvariantViolated> {
|
) -> Result<Vec<CarParking>, InvariantViolated> {
|
||||||
// Could be concurrent, since this is deterministic.
|
// Could be concurrent, since this is deterministic.
|
||||||
let mut requested_moves: Vec<(CarID, Action)> = Vec::new();
|
let mut requested_moves: Vec<(CarID, Action)> = Vec::new();
|
||||||
@ -467,6 +475,7 @@ impl DrivingSimState {
|
|||||||
_parking: CarParking,
|
_parking: CarParking,
|
||||||
mut path: VecDeque<LaneID>,
|
mut path: VecDeque<LaneID>,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
|
_properties: &BTreeMap<CarID, Vehicle>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let start = path.pop_front().unwrap();
|
let start = path.pop_front().unwrap();
|
||||||
|
|
||||||
@ -491,21 +500,39 @@ impl DrivingSimState {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_car(&self, id: CarID, time: Tick, map: &Map) -> Option<DrawCar> {
|
pub fn get_draw_car(
|
||||||
|
&self,
|
||||||
|
id: CarID,
|
||||||
|
time: Tick,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Option<DrawCar> {
|
||||||
let all = match self.cars.get(&id)?.on {
|
let all = match self.cars.get(&id)?.on {
|
||||||
On::Lane(l) => self.get_draw_cars_on_lane(l, time, map),
|
On::Lane(l) => self.get_draw_cars_on_lane(l, time, map, properties),
|
||||||
On::Turn(t) => self.get_draw_cars_on_turn(t, time, map),
|
On::Turn(t) => self.get_draw_cars_on_turn(t, time, map, properties),
|
||||||
};
|
};
|
||||||
all.into_iter().find(|c| c.id == id)
|
all.into_iter().find(|c| c.id == id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_cars_on_lane(&self, lane: LaneID, time: Tick, map: &Map) -> Vec<DrawCar> {
|
pub fn get_draw_cars_on_lane(
|
||||||
self.lanes[lane.0].get_draw_cars(time, self, map)
|
&self,
|
||||||
|
lane: LaneID,
|
||||||
|
time: Tick,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Vec<DrawCar> {
|
||||||
|
self.lanes[lane.0].get_draw_cars(time, self, map, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_cars_on_turn(&self, turn: TurnID, time: Tick, map: &Map) -> Vec<DrawCar> {
|
pub fn get_draw_cars_on_turn(
|
||||||
|
&self,
|
||||||
|
turn: TurnID,
|
||||||
|
time: Tick,
|
||||||
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
|
) -> Vec<DrawCar> {
|
||||||
if let Some(queue) = self.turns.get(&turn) {
|
if let Some(queue) = self.turns.get(&turn) {
|
||||||
return queue.get_draw_cars(time, self, map);
|
return queue.get_draw_cars(time, self, map, properties);
|
||||||
}
|
}
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,13 @@ use draw_car::DrawCar;
|
|||||||
use draw_ped::DrawPedestrian;
|
use draw_ped::DrawPedestrian;
|
||||||
use driving;
|
use driving;
|
||||||
use intersections::{AgentInfo, IntersectionSimState};
|
use intersections::{AgentInfo, IntersectionSimState};
|
||||||
|
use kinematics::Vehicle;
|
||||||
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
||||||
use parametric_driving;
|
use parametric_driving;
|
||||||
use parking::ParkingSimState;
|
use parking::ParkingSimState;
|
||||||
use rand::{FromEntropy, Rng, SeedableRng, XorShiftRng};
|
use rand::{FromEntropy, Rng, SeedableRng, XorShiftRng};
|
||||||
use spawn::Spawner;
|
use spawn::Spawner;
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use walking::WalkingSimState;
|
use walking::WalkingSimState;
|
||||||
@ -106,18 +107,19 @@ impl DrivingModel {
|
|||||||
delegate!(fn edit_add_lane(&mut self, id: LaneID));
|
delegate!(fn edit_add_lane(&mut self, id: LaneID));
|
||||||
delegate!(fn edit_remove_turn(&mut self, id: TurnID));
|
delegate!(fn edit_remove_turn(&mut self, id: TurnID));
|
||||||
delegate!(fn edit_add_turn(&mut self, id: TurnID, map: &Map));
|
delegate!(fn edit_add_turn(&mut self, id: TurnID, map: &Map));
|
||||||
delegate!(fn step<R: Rng + ?Sized>(&mut self, time: Tick, map: &Map, parking: &ParkingSimState, intersections: &mut IntersectionSimState, rng: &mut R) -> Result<Vec<CarParking>, InvariantViolated>);
|
delegate!(fn step<R: Rng + ?Sized>(&mut self, time: Tick, map: &Map, parking: &ParkingSimState, intersections: &mut IntersectionSimState, rng: &mut R, properties: &BTreeMap<CarID, Vehicle>) -> Result<Vec<CarParking>, InvariantViolated>);
|
||||||
delegate!(pub fn start_car_on_lane(
|
delegate!(pub fn start_car_on_lane(
|
||||||
&mut self,
|
&mut self,
|
||||||
time: Tick,
|
time: Tick,
|
||||||
car: CarID,
|
car: CarID,
|
||||||
parking: CarParking,
|
parking: CarParking,
|
||||||
path: VecDeque<LaneID>,
|
path: VecDeque<LaneID>,
|
||||||
map: &Map
|
map: &Map,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>
|
||||||
) -> bool);
|
) -> bool);
|
||||||
delegate!(fn get_draw_car(&self, id: CarID, time: Tick, map: &Map) -> Option<DrawCar>);
|
delegate!(fn get_draw_car(&self, id: CarID, time: Tick, map: &Map, properties: &BTreeMap<CarID, Vehicle>) -> Option<DrawCar>);
|
||||||
delegate!(fn get_draw_cars_on_lane(&self, lane: LaneID, time: Tick, map: &Map) -> Vec<DrawCar>);
|
delegate!(fn get_draw_cars_on_lane(&self, lane: LaneID, time: Tick, map: &Map, properties: &BTreeMap<CarID, Vehicle>) -> Vec<DrawCar>);
|
||||||
delegate!(fn get_draw_cars_on_turn(&self, turn: TurnID, time: Tick, map: &Map) -> Vec<DrawCar>);
|
delegate!(fn get_draw_cars_on_turn(&self, turn: TurnID, time: Tick, map: &Map, properties: &BTreeMap<CarID, Vehicle>) -> Vec<DrawCar>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Derivative)]
|
#[derive(Serialize, Deserialize, Derivative)]
|
||||||
@ -134,6 +136,8 @@ pub struct Sim {
|
|||||||
driving_state: DrivingModel,
|
driving_state: DrivingModel,
|
||||||
parking_state: ParkingSimState,
|
parking_state: ParkingSimState,
|
||||||
walking_state: WalkingSimState,
|
walking_state: WalkingSimState,
|
||||||
|
|
||||||
|
car_properties: BTreeMap<CarID, Vehicle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sim {
|
impl Sim {
|
||||||
@ -157,6 +161,7 @@ impl Sim {
|
|||||||
parking_state: ParkingSimState::new(map),
|
parking_state: ParkingSimState::new(map),
|
||||||
walking_state: WalkingSimState::new(),
|
walking_state: WalkingSimState::new(),
|
||||||
time: Tick::zero(),
|
time: Tick::zero(),
|
||||||
|
car_properties: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,13 +198,24 @@ impl Sim {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn seed_parked_cars(&mut self, percent: f64) {
|
pub fn seed_parked_cars(&mut self, percent: f64) {
|
||||||
self.spawner
|
for v in self.spawner
|
||||||
.seed_parked_cars(percent, &mut self.parking_state, &mut self.rng);
|
.seed_parked_cars(percent, &mut self.parking_state, &mut self.rng)
|
||||||
|
.into_iter()
|
||||||
|
{
|
||||||
|
self.car_properties.insert(v.id, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
let mut ids = Vec::new();
|
||||||
.seed_specific_parked_cars(lane, spots, &mut self.parking_state)
|
for v in self.spawner
|
||||||
|
.seed_specific_parked_cars(lane, spots, &mut self.parking_state, &mut self.rng)
|
||||||
|
.into_iter()
|
||||||
|
{
|
||||||
|
ids.push(v.id);
|
||||||
|
self.car_properties.insert(v.id, v);
|
||||||
|
}
|
||||||
|
ids
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_many_parked_cars(&mut self, map: &Map, num_cars: usize) {
|
pub fn start_many_parked_cars(&mut self, map: &Map, num_cars: usize) {
|
||||||
@ -252,6 +268,7 @@ impl Sim {
|
|||||||
&mut self.parking_state,
|
&mut self.parking_state,
|
||||||
&mut self.walking_state,
|
&mut self.walking_state,
|
||||||
&mut self.driving_state,
|
&mut self.driving_state,
|
||||||
|
&self.car_properties,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cars_parked_this_step: Vec<CarParking> = Vec::new();
|
let mut cars_parked_this_step: Vec<CarParking> = Vec::new();
|
||||||
@ -261,6 +278,7 @@ impl Sim {
|
|||||||
&self.parking_state,
|
&self.parking_state,
|
||||||
&mut self.intersection_state,
|
&mut self.intersection_state,
|
||||||
&mut self.rng,
|
&mut self.rng,
|
||||||
|
&self.car_properties,
|
||||||
) {
|
) {
|
||||||
Ok(parked_cars) => for p in parked_cars {
|
Ok(parked_cars) => for p in parked_cars {
|
||||||
cars_parked_this_step.push(p.clone());
|
cars_parked_this_step.push(p.clone());
|
||||||
@ -298,7 +316,7 @@ impl Sim {
|
|||||||
|
|
||||||
pub fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCar> {
|
pub fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCar> {
|
||||||
self.driving_state
|
self.driving_state
|
||||||
.get_draw_car(id, self.time, map)
|
.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))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +327,10 @@ 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<DrawCar> {
|
pub fn get_draw_cars_on_lane(&self, l: LaneID, map: &Map) -> Vec<DrawCar> {
|
||||||
match map.get_l(l).lane_type {
|
match map.get_l(l).lane_type {
|
||||||
LaneType::Driving => self.driving_state.get_draw_cars_on_lane(l, self.time, map),
|
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, map),
|
LaneType::Parking => self.parking_state.get_draw_cars(l, map),
|
||||||
LaneType::Sidewalk => Vec::new(),
|
LaneType::Sidewalk => Vec::new(),
|
||||||
LaneType::Biking => Vec::new(),
|
LaneType::Biking => Vec::new(),
|
||||||
@ -317,7 +338,8 @@ impl Sim {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_draw_cars_on_turn(&self, t: TurnID, map: &Map) -> Vec<DrawCar> {
|
pub fn get_draw_cars_on_turn(&self, t: TurnID, map: &Map) -> Vec<DrawCar> {
|
||||||
self.driving_state.get_draw_cars_on_turn(t, self.time, map)
|
self.driving_state
|
||||||
|
.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<DrawPedestrian> {
|
pub fn get_draw_peds_on_lane(&self, l: LaneID, map: &Map) -> Vec<DrawPedestrian> {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
use kinematics::Vehicle;
|
||||||
use map_model;
|
use map_model;
|
||||||
use map_model::{LaneID, Map};
|
use map_model::{LaneID, Map};
|
||||||
use parking::ParkingSimState;
|
use parking::ParkingSimState;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use sim::{CarParking, DrivingModel};
|
use sim::{CarParking, DrivingModel};
|
||||||
use std::collections::VecDeque;
|
use std::collections::{BTreeMap, VecDeque};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use walking::WalkingSimState;
|
use walking::WalkingSimState;
|
||||||
use {AgentID, CarID, PedestrianID, Tick};
|
use {AgentID, CarID, PedestrianID, Tick};
|
||||||
@ -47,6 +48,7 @@ impl Spawner {
|
|||||||
parking_sim: &mut ParkingSimState,
|
parking_sim: &mut ParkingSimState,
|
||||||
walking_sim: &mut WalkingSimState,
|
walking_sim: &mut WalkingSimState,
|
||||||
driving_sim: &mut DrivingModel,
|
driving_sim: &mut DrivingModel,
|
||||||
|
properties: &BTreeMap<CarID, Vehicle>,
|
||||||
) {
|
) {
|
||||||
for p in self.spawn_parked_cars.drain(0..) {
|
for p in self.spawn_parked_cars.drain(0..) {
|
||||||
parking_sim.add_parked_car(p);
|
parking_sim.add_parked_car(p);
|
||||||
@ -95,6 +97,7 @@ impl Spawner {
|
|||||||
CarParking::new(*car, spot),
|
CarParking::new(*car, spot),
|
||||||
VecDeque::from(path),
|
VecDeque::from(path),
|
||||||
map,
|
map,
|
||||||
|
properties,
|
||||||
) {
|
) {
|
||||||
parking_sim.remove_parked_car(parking_lane, *car);
|
parking_sim.remove_parked_car(parking_lane, *car);
|
||||||
spawned_agents += 1;
|
spawned_agents += 1;
|
||||||
@ -134,36 +137,40 @@ impl Spawner {
|
|||||||
percent_capacity_to_fill: f64,
|
percent_capacity_to_fill: f64,
|
||||||
parking_sim: &mut ParkingSimState,
|
parking_sim: &mut ParkingSimState,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
) {
|
) -> Vec<Vehicle> {
|
||||||
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);
|
||||||
assert!(self.spawn_parked_cars.is_empty());
|
assert!(self.spawn_parked_cars.is_empty());
|
||||||
|
|
||||||
let mut total_capacity = 0;
|
let mut total_capacity = 0;
|
||||||
let mut new_cars = 0;
|
let mut new_cars: Vec<Vehicle> = Vec::new();
|
||||||
for spot in parking_sim.get_all_free_spots() {
|
for spot in parking_sim.get_all_free_spots() {
|
||||||
total_capacity += 1;
|
total_capacity += 1;
|
||||||
if rng.gen_bool(percent_capacity_to_fill) {
|
if rng.gen_bool(percent_capacity_to_fill) {
|
||||||
new_cars += 1;
|
let id = 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(CarParking::new(CarID(self.car_id_counter), spot));
|
parking_sim.add_parked_car(CarParking::new(id, spot));
|
||||||
//self.spawn_parked_cars.push(CarParking::new(CarID(self.car_id_counter), spot));
|
//self.spawn_parked_cars.push(CarParking::new(CarID(self.car_id_counter), spot));
|
||||||
|
new_cars.push(Vehicle::generate_typical_car(id, rng));
|
||||||
self.car_id_counter += 1;
|
self.car_id_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Seeded {} of {} parking spots with cars",
|
"Seeded {} of {} parking spots with cars",
|
||||||
new_cars, total_capacity
|
new_cars.len(),
|
||||||
|
total_capacity
|
||||||
);
|
);
|
||||||
|
new_cars
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seed_specific_parked_cars(
|
pub fn seed_specific_parked_cars<R: Rng + ?Sized>(
|
||||||
&mut self,
|
&mut self,
|
||||||
lane: LaneID,
|
lane: LaneID,
|
||||||
spot_indices: Vec<usize>,
|
spot_indices: Vec<usize>,
|
||||||
parking_sim: &mut ParkingSimState,
|
parking_sim: &mut ParkingSimState,
|
||||||
) -> Vec<CarID> {
|
rng: &mut R,
|
||||||
|
) -> Vec<Vehicle> {
|
||||||
assert!(self.spawn_parked_cars.is_empty());
|
assert!(self.spawn_parked_cars.is_empty());
|
||||||
let spots = parking_sim.get_all_spots(lane);
|
let spots = parking_sim.get_all_spots(lane);
|
||||||
spot_indices
|
spot_indices
|
||||||
@ -173,7 +180,7 @@ impl Spawner {
|
|||||||
parking_sim.add_parked_car(CarParking::new(id, spots[idx].clone()));
|
parking_sim.add_parked_car(CarParking::new(id, spots[idx].clone()));
|
||||||
// TODO push onto spawn_parked_cars?
|
// TODO push onto spawn_parked_cars?
|
||||||
self.car_id_counter += 1;
|
self.car_id_counter += 1;
|
||||||
id
|
Vehicle::generate_typical_car(id, rng)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user