mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 19:27:11 +03:00
give commands to spawn peds, but don't do anything with them yet
This commit is contained in:
parent
5bd840d296
commit
b6eb62aa62
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user