give commands to spawn peds, but don't do anything with them yet

This commit is contained in:
Dustin Carlino 2019-02-23 11:24:49 -08:00
parent 5bd840d296
commit b6eb62aa62
6 changed files with 221 additions and 69 deletions

View File

@ -4,7 +4,9 @@ use crate::plugins::{BlockingPlugin, PluginCtx};
use crate::render::MIN_ZOOM_FOR_DETAIL;
use ezgui::{EventLoopMode, GfxCtx, Key};
use geom::{Distance, Duration, Speed};
use map_model::{BuildingID, LaneID, LaneType, Map, Traversable};
use map_model::{
BuildingID, LaneID, LaneType, Map, PathRequest, Pathfinder, Position, Traversable,
};
use rand::seq::SliceRandom;
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;
@ -132,7 +134,8 @@ fn populate_sim(start: LaneID, map: &Map) -> new_des_model::Sim {
}
}
let mut counter = 0;
let mut car_counter = 0;
let mut ped_counter = 0;
let mut rng = XorShiftRng::from_seed([42; 16]);
for source in sources {
let len = map.get_l(source).length();
@ -142,12 +145,14 @@ fn populate_sim(start: LaneID, map: &Map) -> new_des_model::Sim {
}
for _ in 0..10 {
if spawn_car(&mut sim, &mut rng, map, counter, source) {
counter += 1;
if spawn_car(&mut sim, &mut rng, map, car_counter, source) {
car_counter += 1;
}
}
seed_parked_cars_near(source, &mut rng, &mut sim, map, &mut counter);
seed_parked_cars_near(source, &mut rng, &mut sim, map, &mut car_counter);
random_ped_near(source, &mut sim, map, &mut rng, &mut ped_counter);
}
sim
@ -156,17 +161,20 @@ fn populate_sim(start: LaneID, map: &Map) -> new_des_model::Sim {
fn densely_populate_sim(map: &Map) -> new_des_model::Sim {
let mut sim = new_des_model::Sim::new(map);
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut counter = 0;
let mut car_counter = 0;
let mut ped_counter = 0;
for l in map.all_lanes() {
let len = l.length();
if l.is_driving() && len >= new_des_model::MAX_VEHICLE_LENGTH {
for _ in 0..rng.gen_range(0, 5) {
if spawn_car(&mut sim, &mut rng, map, counter, l.id) {
counter += 1;
if spawn_car(&mut sim, &mut rng, map, car_counter, l.id) {
car_counter += 1;
}
}
seed_parked_cars_near(l.id, &mut rng, &mut sim, map, &mut counter);
seed_parked_cars_near(l.id, &mut rng, &mut sim, map, &mut car_counter);
random_ped_near(l.id, &mut sim, map, &mut rng, &mut ped_counter);
}
}
@ -290,3 +298,47 @@ fn rand_vehicle(rng: &mut XorShiftRng, id: usize) -> new_des_model::Vehicle {
max_speed,
}
}
fn random_ped_near(
start_near: LaneID,
sim: &mut new_des_model::Sim,
map: &Map,
rng: &mut XorShiftRng,
counter: &mut usize,
) {
let end_near = random_path(start_near, rng, map).last().unwrap().as_lane();
let (start, end) = match (
map.find_closest_lane(start_near, vec![LaneType::Sidewalk]),
map.find_closest_lane(end_near, vec![LaneType::Sidewalk]),
) {
(Ok(l1), Ok(l2)) => (l1, l2),
_ => {
return;
}
};
let pos1 = Position::new(start, map.get_l(start).length() / 2.0);
let pos2 = Position::new(end, map.get_l(end).length() / 2.0);
let path = match Pathfinder::shortest_distance(
map,
PathRequest {
start: pos1,
end: pos2,
can_use_bike_lanes: false,
can_use_bus_lanes: false,
},
) {
Some(p) => p,
None => {
return;
}
};
sim.spawn_ped(
PedestrianID::tmp_new(*counter),
new_des_model::SidewalkSpot::bike_rack(pos1, map),
new_des_model::SidewalkSpot::bike_rack(pos2, map),
path,
);
*counter += 1
}

View File

@ -1,4 +1,6 @@
use crate::plugins::sim::new_des_model::{ParkingSpot, Router, Vehicle};
use crate::plugins::sim::new_des_model::{
DistanceInterval, ParkingSpot, Router, TimeInterval, Vehicle,
};
use geom::{Distance, Duration, PolyLine};
use map_model::{Map, Traversable, LANE_THICKNESS};
use sim::DrawCarInput;
@ -135,52 +137,3 @@ pub enum CarState {
Unparking(Distance, TimeInterval),
Parking(Distance, ParkingSpot, TimeInterval),
}
// TODO Walking will use these too -- lift up
#[derive(Debug)]
pub struct TimeInterval {
// TODO Private fields
pub start: Duration,
pub end: Duration,
}
impl TimeInterval {
pub fn new(start: Duration, end: Duration) -> TimeInterval {
if end < start {
panic!("Bad TimeInterval {} .. {}", start, end);
}
TimeInterval { start, end }
}
pub fn percent(&self, t: Duration) -> f64 {
if self.start == self.end {
return 1.0;
}
let x = (t - self.start) / (self.end - self.start);
assert!(x >= 0.0 && x <= 1.0);
x
}
}
#[derive(Debug)]
pub struct DistanceInterval {
// TODO Private fields
pub start: Distance,
pub end: Distance,
}
impl DistanceInterval {
fn new(start: Distance, end: Distance) -> DistanceInterval {
if end < start {
panic!("Bad DistanceInterval {} .. {}", start, end);
}
DistanceInterval { start, end }
}
pub fn lerp(&self, x: f64) -> Distance {
assert!(x >= 0.0 && x <= 1.0);
self.start + x * (self.end - self.start)
}
}

View File

@ -6,7 +6,7 @@ mod queue;
mod router;
mod sim;
pub use self::car::{Car, CarState, TimeInterval};
pub use self::car::{Car, CarState};
pub use self::driving::DrivingSimState;
pub use self::intersection::IntersectionController;
pub use self::parking::ParkingSimState;
@ -14,8 +14,8 @@ pub use self::queue::Queue;
pub use self::router::{ActionAtEnd, Router};
pub use self::sim::Sim;
use ::sim::{CarID, VehicleType};
use geom::{Distance, Speed};
use map_model::{BuildingID, LaneID};
use geom::{Distance, Duration, Speed};
use map_model::{BuildingID, BusStopID, IntersectionID, LaneID, LaneType, Map, Position};
use serde_derive::{Deserialize, Serialize};
pub const MIN_VEHICLE_LENGTH: Distance = Distance::const_meters(2.0);
@ -60,3 +60,134 @@ impl ParkedCar {
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
pub struct SidewalkSpot {
connection: SidewalkPOI,
pub sidewalk_pos: Position,
}
impl SidewalkSpot {
#[allow(dead_code)]
pub fn parking_spot(
spot: ParkingSpot,
map: &Map,
parking_sim: &ParkingSimState,
) -> SidewalkSpot {
let sidewalk = map
.find_closest_lane(spot.lane, vec![LaneType::Sidewalk])
.unwrap();
SidewalkSpot {
connection: SidewalkPOI::ParkingSpot(spot),
sidewalk_pos: parking_sim.spot_to_sidewalk_pos(spot, sidewalk, map),
}
}
#[allow(dead_code)]
pub fn building(bldg: BuildingID, map: &Map) -> SidewalkSpot {
let front_path = &map.get_b(bldg).front_path;
SidewalkSpot {
connection: SidewalkPOI::Building(bldg),
sidewalk_pos: front_path.sidewalk,
}
}
pub fn bike_rack(sidewalk_pos: Position, map: &Map) -> SidewalkSpot {
assert!(map.get_l(sidewalk_pos.lane()).is_sidewalk());
SidewalkSpot {
connection: SidewalkPOI::BikeRack,
sidewalk_pos,
}
}
#[allow(dead_code)]
pub fn bus_stop(stop: BusStopID, map: &Map) -> SidewalkSpot {
SidewalkSpot {
sidewalk_pos: map.get_bs(stop).sidewalk_pos,
connection: SidewalkPOI::BusStop(stop),
}
}
#[allow(dead_code)]
pub fn start_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
let lanes = map.get_i(i).get_outgoing_lanes(map, LaneType::Sidewalk);
if lanes.is_empty() {
None
} else {
Some(SidewalkSpot {
sidewalk_pos: Position::new(lanes[0], Distance::ZERO),
connection: SidewalkPOI::Border(i),
})
}
}
#[allow(dead_code)]
pub fn end_at_border(i: IntersectionID, map: &Map) -> Option<SidewalkSpot> {
let lanes = map.get_i(i).get_incoming_lanes(map, LaneType::Sidewalk);
if lanes.is_empty() {
None
} else {
Some(SidewalkSpot {
sidewalk_pos: Position::new(lanes[0], map.get_l(lanes[0]).length()),
connection: SidewalkPOI::Border(i),
})
}
}
}
// Point of interest, that is
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
enum SidewalkPOI {
ParkingSpot(ParkingSpot),
Building(BuildingID),
BusStop(BusStopID),
Border(IntersectionID),
BikeRack,
}
#[derive(Debug)]
pub struct TimeInterval {
// TODO Private fields
pub start: Duration,
pub end: Duration,
}
impl TimeInterval {
pub fn new(start: Duration, end: Duration) -> TimeInterval {
if end < start {
panic!("Bad TimeInterval {} .. {}", start, end);
}
TimeInterval { start, end }
}
pub fn percent(&self, t: Duration) -> f64 {
if self.start == self.end {
return 1.0;
}
let x = (t - self.start) / (self.end - self.start);
assert!(x >= 0.0 && x <= 1.0);
x
}
}
#[derive(Debug)]
pub struct DistanceInterval {
// TODO Private fields
pub start: Distance,
pub end: Distance,
}
impl DistanceInterval {
fn new(start: Distance, end: Distance) -> DistanceInterval {
if end < start {
panic!("Bad DistanceInterval {} .. {}", start, end);
}
DistanceInterval { start, end }
}
pub fn lerp(&self, x: f64) -> Distance {
assert!(x >= 0.0 && x <= 1.0);
self.start + x * (self.end - self.start)
}
}

View File

@ -162,9 +162,9 @@ impl ParkingSimState {
.equiv_pos(driving_lane, map)
}
/*pub fn spot_to_sidewalk_pos(&self, spot: ParkingSpot, sidewalk: LaneID, map: &Map) -> Position {
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]
@ -264,10 +264,10 @@ struct ParkingSpotGeometry {
}
impl ParkingSpotGeometry {
/*fn dist_along_for_ped(&self) -> Distance {
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

View File

@ -1,10 +1,10 @@
use crate::plugins::sim::new_des_model::{
DrivingSimState, ParkedCar, ParkingSimState, Router, Vehicle,
DrivingSimState, ParkedCar, ParkingSimState, Router, SidewalkSpot, Vehicle,
};
use ezgui::GfxCtx;
use geom::{Distance, Duration};
use map_model::{Map, Traversable};
use sim::DrawCarInput;
use map_model::{Map, Path, Traversable};
use sim::{DrawCarInput, PedestrianID};
pub struct Sim {
driving: DrivingSimState,
@ -64,6 +64,16 @@ impl Sim {
);
}
pub fn spawn_ped(
&mut self,
id: PedestrianID,
start: SidewalkSpot,
goal: SidewalkSpot,
path: Path,
) {
// TODO Assert valid
}
pub fn step_if_needed(&mut self, time: Duration, map: &Map) {
self.driving.step_if_needed(time, map, &mut self.parking);
}

View File

@ -65,6 +65,12 @@ impl fmt::Display for CarID {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct PedestrianID(pub usize);
impl PedestrianID {
pub fn tmp_new(idx: usize) -> PedestrianID {
PedestrianID(idx)
}
}
impl fmt::Display for PedestrianID {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PedestrianID({0})", self.0)