mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
moving on->traversable, in the map model directly
This commit is contained in:
parent
d7a36889b2
commit
d3e5fdb7c4
@ -30,6 +30,7 @@ mod pathfind;
|
|||||||
pub mod raw_data;
|
pub mod raw_data;
|
||||||
mod road;
|
mod road;
|
||||||
mod trace;
|
mod trace;
|
||||||
|
mod traversable;
|
||||||
mod turn;
|
mod turn;
|
||||||
|
|
||||||
pub use area::{Area, AreaID, AreaType};
|
pub use area::{Area, AreaID, AreaType};
|
||||||
@ -43,6 +44,7 @@ pub use parcel::{Parcel, ParcelID};
|
|||||||
pub use pathfind::Pathfinder;
|
pub use pathfind::Pathfinder;
|
||||||
pub use road::{Road, RoadID};
|
pub use road::{Road, RoadID};
|
||||||
pub use trace::Trace;
|
pub use trace::Trace;
|
||||||
|
pub use traversable::Traversable;
|
||||||
pub use turn::{Turn, TurnID};
|
pub use turn::{Turn, TurnID};
|
||||||
|
|
||||||
pub const LANE_THICKNESS: f64 = 2.5;
|
pub const LANE_THICKNESS: f64 = 2.5;
|
||||||
|
54
map_model/src/traversable.rs
Normal file
54
map_model/src/traversable.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use dimensioned::si;
|
||||||
|
use geom::{Angle, Pt2D};
|
||||||
|
use {LaneID, Map, TurnID};
|
||||||
|
|
||||||
|
// TODO also building paths?
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum Traversable {
|
||||||
|
Lane(LaneID),
|
||||||
|
Turn(TurnID),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Traversable {
|
||||||
|
pub fn as_lane(&self) -> LaneID {
|
||||||
|
match self {
|
||||||
|
&Traversable::Lane(id) => id,
|
||||||
|
&Traversable::Turn(_) => panic!("not a lane"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_turn(&self) -> TurnID {
|
||||||
|
match self {
|
||||||
|
&Traversable::Turn(id) => id,
|
||||||
|
&Traversable::Lane(_) => panic!("not a turn"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_turn(&self) -> Option<TurnID> {
|
||||||
|
match self {
|
||||||
|
&Traversable::Turn(id) => Some(id),
|
||||||
|
&Traversable::Lane(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn length(&self, map: &Map) -> si::Meter<f64> {
|
||||||
|
match self {
|
||||||
|
&Traversable::Lane(id) => map.get_l(id).length(),
|
||||||
|
&Traversable::Turn(id) => map.get_t(id).length(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dist_along(&self, dist: si::Meter<f64>, map: &Map) -> (Pt2D, Angle) {
|
||||||
|
match self {
|
||||||
|
&Traversable::Lane(id) => map.get_l(id).dist_along(dist),
|
||||||
|
&Traversable::Turn(id) => map.get_t(id).dist_along(dist),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn speed_limit(&self, map: &Map) -> si::MeterPerSecond<f64> {
|
||||||
|
match self {
|
||||||
|
&Traversable::Lane(id) => map.get_parent(id).get_speed_limit(),
|
||||||
|
&Traversable::Turn(id) => map.get_parent(id.dst).get_speed_limit(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ use geom::EPSILON_DIST;
|
|||||||
use intersections::{IntersectionSimState, Request};
|
use intersections::{IntersectionSimState, Request};
|
||||||
use kinematics;
|
use kinematics;
|
||||||
use kinematics::Vehicle;
|
use kinematics::Vehicle;
|
||||||
use map_model::{LaneID, Map, Trace, TurnID, LANE_THICKNESS};
|
use map_model::{LaneID, Map, Trace, Traversable, TurnID, LANE_THICKNESS};
|
||||||
use multimap::MultiMap;
|
use multimap::MultiMap;
|
||||||
use ordered_float::NotNaN;
|
use ordered_float::NotNaN;
|
||||||
use parking::ParkingSimState;
|
use parking::ParkingSimState;
|
||||||
@ -17,7 +17,7 @@ use std::collections::BTreeMap;
|
|||||||
use transit::TransitSimState;
|
use transit::TransitSimState;
|
||||||
use view::{AgentView, WorldView};
|
use view::{AgentView, WorldView};
|
||||||
use {
|
use {
|
||||||
Acceleration, AgentID, CarID, CarState, Distance, DrawCarInput, Event, InvariantViolated, On,
|
Acceleration, AgentID, CarID, CarState, Distance, DrawCarInput, Event, InvariantViolated,
|
||||||
ParkedCar, ParkingSpot, Speed, Tick, Time,
|
ParkedCar, ParkingSpot, Speed, Tick, Time,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ struct ParkingState {
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
struct Car {
|
struct Car {
|
||||||
id: CarID,
|
id: CarID,
|
||||||
on: On,
|
on: Traversable,
|
||||||
speed: Speed,
|
speed: Speed,
|
||||||
dist_along: Distance,
|
dist_along: Distance,
|
||||||
vehicle: Vehicle,
|
vehicle: Vehicle,
|
||||||
@ -45,7 +45,7 @@ struct Car {
|
|||||||
parking: Option<ParkingState>,
|
parking: Option<ParkingState>,
|
||||||
|
|
||||||
// TODO should this only be turns?
|
// TODO should this only be turns?
|
||||||
waiting_for: Option<On>,
|
waiting_for: Option<Traversable>,
|
||||||
|
|
||||||
debug: bool,
|
debug: bool,
|
||||||
// TODO ew? :\
|
// TODO ew? :\
|
||||||
@ -177,7 +177,7 @@ impl Car {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop for something?
|
// Stop for something?
|
||||||
if let On::Lane(id) = current_on {
|
if let Traversable::Lane(id) = current_on {
|
||||||
let maybe_stop_early = current_router.stop_early_at_dist(
|
let maybe_stop_early = current_router.stop_early_at_dist(
|
||||||
current_on,
|
current_on,
|
||||||
current_dist_along,
|
current_dist_along,
|
||||||
@ -226,11 +226,11 @@ impl Car {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
current_on = match current_on {
|
current_on = match current_on {
|
||||||
On::Turn(t) => {
|
Traversable::Turn(t) => {
|
||||||
current_router.advance_to(t.dst);
|
current_router.advance_to(t.dst);
|
||||||
On::Lane(t.dst)
|
Traversable::Lane(t.dst)
|
||||||
}
|
}
|
||||||
On::Lane(l) => On::Turn(current_router.choose_turn(l, map)),
|
Traversable::Lane(l) => Traversable::Turn(current_router.choose_turn(l, map)),
|
||||||
};
|
};
|
||||||
current_dist_along = 0.0 * si::M;
|
current_dist_along = 0.0 * si::M;
|
||||||
dist_scanned_ahead += dist_this_step;
|
dist_scanned_ahead += dist_this_step;
|
||||||
@ -285,11 +285,11 @@ impl Car {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let next_on = match self.on {
|
let next_on = match self.on {
|
||||||
On::Turn(t) => On::Lane(map.get_t(t).dst),
|
Traversable::Turn(t) => Traversable::Lane(map.get_t(t).dst),
|
||||||
On::Lane(l) => On::Turn(router.choose_turn(l, map)),
|
Traversable::Lane(l) => Traversable::Turn(router.choose_turn(l, map)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let On::Turn(t) = self.on {
|
if let Traversable::Turn(t) = self.on {
|
||||||
intersections.on_exit(Request::for_car(self.id, t));
|
intersections.on_exit(Request::for_car(self.id, t));
|
||||||
router.advance_to(t.dst);
|
router.advance_to(t.dst);
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ impl Car {
|
|||||||
));
|
));
|
||||||
self.waiting_for = None;
|
self.waiting_for = None;
|
||||||
self.on = next_on;
|
self.on = next_on;
|
||||||
if let On::Turn(t) = self.on {
|
if let Traversable::Turn(t) = self.on {
|
||||||
intersections
|
intersections
|
||||||
.on_enter(Request::for_car(self.id, t))
|
.on_enter(Request::for_car(self.id, t))
|
||||||
.context(format!(
|
.context(format!(
|
||||||
@ -319,7 +319,7 @@ impl Car {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct SimQueue {
|
pub struct SimQueue {
|
||||||
id: On,
|
id: Traversable,
|
||||||
// First element is farthest along the queue; they have the greatest dist_along.
|
// First element is farthest along the queue; they have the greatest dist_along.
|
||||||
// Caching the current dist_along vastly simplifies the API of SimQueue.
|
// Caching the current dist_along vastly simplifies the API of SimQueue.
|
||||||
cars_queue: Vec<(Distance, CarID)>,
|
cars_queue: Vec<(Distance, CarID)>,
|
||||||
@ -338,7 +338,7 @@ impl PartialEq for SimQueue {
|
|||||||
impl Eq for SimQueue {}
|
impl Eq for SimQueue {}
|
||||||
|
|
||||||
impl SimQueue {
|
impl SimQueue {
|
||||||
fn new(id: On, map: &Map) -> SimQueue {
|
fn new(id: Traversable, map: &Map) -> SimQueue {
|
||||||
SimQueue {
|
SimQueue {
|
||||||
id,
|
id,
|
||||||
cars_queue: Vec::new(),
|
cars_queue: Vec::new(),
|
||||||
@ -444,14 +444,15 @@ impl DrivingSimState {
|
|||||||
lanes: map
|
lanes: map
|
||||||
.all_lanes()
|
.all_lanes()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| SimQueue::new(On::Lane(l.id), map))
|
.map(|l| SimQueue::new(Traversable::Lane(l.id), map))
|
||||||
.collect(),
|
.collect(),
|
||||||
turns: BTreeMap::new(),
|
turns: BTreeMap::new(),
|
||||||
debug: None,
|
debug: None,
|
||||||
};
|
};
|
||||||
for t in map.all_turns().values() {
|
for t in map.all_turns().values() {
|
||||||
if !t.between_sidewalks {
|
if !t.between_sidewalks {
|
||||||
s.turns.insert(t.id, SimQueue::new(On::Turn(t.id), map));
|
s.turns
|
||||||
|
.insert(t.id, SimQueue::new(Traversable::Turn(t.id), map));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
@ -534,7 +535,8 @@ impl DrivingSimState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_add_turn(&mut self, id: TurnID, map: &Map) {
|
pub fn edit_add_turn(&mut self, id: TurnID, map: &Map) {
|
||||||
self.turns.insert(id, SimQueue::new(On::Turn(id), map));
|
self.turns
|
||||||
|
.insert(id, SimQueue::new(Traversable::Turn(id), map));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this populates the view BEFORE the step is applied
|
// Note that this populates the view BEFORE the step is applied
|
||||||
@ -621,8 +623,10 @@ impl DrivingSimState {
|
|||||||
// TODO kind of a weird way to figure out when to fill this out...
|
// TODO kind of a weird way to figure out when to fill this out...
|
||||||
// duplicated with stop sign's check, also. should check that they're a
|
// duplicated with stop sign's check, also. should check that they're a
|
||||||
// leader vehicle...
|
// leader vehicle...
|
||||||
if On::Lane(req.turn.src) == c.on && c.speed <= kinematics::EPSILON_SPEED {
|
if Traversable::Lane(req.turn.src) == c.on
|
||||||
c.waiting_for = Some(On::Turn(req.turn));
|
&& c.speed <= kinematics::EPSILON_SPEED
|
||||||
|
{
|
||||||
|
c.waiting_for = Some(Traversable::Turn(req.turn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,13 +640,13 @@ impl DrivingSimState {
|
|||||||
// TODO could simplify this by only adjusting the SimQueues we need above
|
// TODO could simplify this by only adjusting the SimQueues we need above
|
||||||
|
|
||||||
// Group cars by lane and turn
|
// Group cars by lane and turn
|
||||||
// TODO ideally, just hash On
|
// TODO ideally, just hash Traversable
|
||||||
let mut cars_per_lane = MultiMap::new();
|
let mut cars_per_lane = MultiMap::new();
|
||||||
let mut cars_per_turn = MultiMap::new();
|
let mut cars_per_turn = MultiMap::new();
|
||||||
for c in self.cars.values() {
|
for c in self.cars.values() {
|
||||||
match c.on {
|
match c.on {
|
||||||
On::Lane(id) => cars_per_lane.insert(id, c.id),
|
Traversable::Lane(id) => cars_per_lane.insert(id, c.id),
|
||||||
On::Turn(id) => cars_per_turn.insert(id, c.id),
|
Traversable::Turn(id) => cars_per_turn.insert(id, c.id),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,7 +726,7 @@ impl DrivingSimState {
|
|||||||
id: car,
|
id: car,
|
||||||
dist_along: dist_along,
|
dist_along: dist_along,
|
||||||
speed: 0.0 * si::MPS,
|
speed: 0.0 * si::MPS,
|
||||||
on: On::Lane(start),
|
on: Traversable::Lane(start),
|
||||||
vehicle,
|
vehicle,
|
||||||
waiting_for: None,
|
waiting_for: None,
|
||||||
debug: false,
|
debug: false,
|
||||||
@ -740,7 +744,7 @@ impl DrivingSimState {
|
|||||||
self.lanes[start.0].insert_at(car, dist_along);
|
self.lanes[start.0].insert_at(car, dist_along);
|
||||||
events.push(Event::AgentEntersTraversable(
|
events.push(Event::AgentEntersTraversable(
|
||||||
AgentID::Car(car),
|
AgentID::Car(car),
|
||||||
On::Lane(start),
|
Traversable::Lane(start),
|
||||||
));
|
));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use intersections::Request;
|
use intersections::Request;
|
||||||
use map_model::{BuildingID, BusStopID};
|
use map_model::{BuildingID, BusStopID, Traversable};
|
||||||
use {AgentID, CarID, On, ParkingSpot, PedestrianID};
|
use {AgentID, CarID, ParkingSpot, PedestrianID};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
@ -19,8 +19,8 @@ pub enum Event {
|
|||||||
PedLeavesBus(PedestrianID, CarID),
|
PedLeavesBus(PedestrianID, CarID),
|
||||||
|
|
||||||
// TODO split up into cases or not?
|
// TODO split up into cases or not?
|
||||||
AgentEntersTraversable(AgentID, On),
|
AgentEntersTraversable(AgentID, Traversable),
|
||||||
AgentLeavesTraversable(AgentID, On),
|
AgentLeavesTraversable(AgentID, Traversable),
|
||||||
|
|
||||||
// TODO maybe AgentRequestsTurn?
|
// TODO maybe AgentRequestsTurn?
|
||||||
IntersectionAcceptsRequest(Request),
|
IntersectionAcceptsRequest(Request),
|
||||||
|
@ -60,7 +60,7 @@ pub use events::Event;
|
|||||||
use geom::{Angle, Pt2D};
|
use geom::{Angle, Pt2D};
|
||||||
pub use helpers::{load, SimFlags};
|
pub use helpers::{load, SimFlags};
|
||||||
pub use instrument::save_backtraces;
|
pub use instrument::save_backtraces;
|
||||||
use map_model::{LaneID, Map, Trace, TurnID};
|
use map_model::{LaneID, Trace, TurnID};
|
||||||
pub use scenario::{Neighborhood, Scenario, SeedParkedCars, SpawnOverTime};
|
pub use scenario::{Neighborhood, Scenario, SeedParkedCars, SpawnOverTime};
|
||||||
pub use sim::{Benchmark, Sim};
|
pub use sim::{Benchmark, Sim};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -254,57 +254,6 @@ fn time_parsing() {
|
|||||||
assert_eq!(Tick::parse("01:02:03.5"), Some(Tick(35 + 1200 + 36000)));
|
assert_eq!(Tick::parse("01:02:03.5"), Some(Tick(35 + 1200 + 36000)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this name isn't quite right :)
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub enum On {
|
|
||||||
Lane(LaneID),
|
|
||||||
Turn(TurnID),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl On {
|
|
||||||
pub fn as_lane(&self) -> LaneID {
|
|
||||||
match self {
|
|
||||||
&On::Lane(id) => id,
|
|
||||||
&On::Turn(_) => panic!("not a lane"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_turn(&self) -> TurnID {
|
|
||||||
match self {
|
|
||||||
&On::Turn(id) => id,
|
|
||||||
&On::Lane(_) => panic!("not a turn"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe_turn(&self) -> Option<TurnID> {
|
|
||||||
match self {
|
|
||||||
&On::Turn(id) => Some(id),
|
|
||||||
&On::Lane(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn length(&self, map: &Map) -> Distance {
|
|
||||||
match self {
|
|
||||||
&On::Lane(id) => map.get_l(id).length(),
|
|
||||||
&On::Turn(id) => map.get_t(id).length(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dist_along(&self, dist: Distance, map: &Map) -> (Pt2D, Angle) {
|
|
||||||
match self {
|
|
||||||
&On::Lane(id) => map.get_l(id).dist_along(dist),
|
|
||||||
&On::Turn(id) => map.get_t(id).dist_along(dist),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn speed_limit(&self, map: &Map) -> Speed {
|
|
||||||
match self {
|
|
||||||
&On::Lane(id) => map.get_parent(id).get_speed_limit(),
|
|
||||||
&On::Turn(id) => map.get_parent(id.dst).get_speed_limit(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum CarState {
|
pub enum CarState {
|
||||||
Moving,
|
Moving,
|
||||||
Stuck,
|
Stuck,
|
||||||
|
@ -2,13 +2,13 @@ use dimensioned::si;
|
|||||||
use driving::Action;
|
use driving::Action;
|
||||||
use kinematics;
|
use kinematics;
|
||||||
use kinematics::Vehicle;
|
use kinematics::Vehicle;
|
||||||
use map_model::{BuildingID, LaneID, Map, TurnID};
|
use map_model::{BuildingID, LaneID, Map, Traversable, TurnID};
|
||||||
use parking::ParkingSimState;
|
use parking::ParkingSimState;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use transit::TransitSimState;
|
use transit::TransitSimState;
|
||||||
use view::AgentView;
|
use view::AgentView;
|
||||||
use {Distance, Event, On, ParkingSpot, Tick};
|
use {Distance, Event, ParkingSpot, Tick};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
enum Goal {
|
enum Goal {
|
||||||
@ -95,7 +95,7 @@ impl Router {
|
|||||||
pub fn stop_early_at_dist(
|
pub fn stop_early_at_dist(
|
||||||
&self,
|
&self,
|
||||||
// TODO urgh, we cant reuse AgentView here, because lookahead doesn't advance the view :(
|
// TODO urgh, we cant reuse AgentView here, because lookahead doesn't advance the view :(
|
||||||
on: On,
|
on: Traversable,
|
||||||
dist_along: Distance,
|
dist_along: Distance,
|
||||||
vehicle: &Vehicle,
|
vehicle: &Vehicle,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use driving::SimQueue;
|
use driving::SimQueue;
|
||||||
use kinematics::Vehicle;
|
use kinematics::Vehicle;
|
||||||
use map_model::TurnID;
|
use map_model::{Traversable, TurnID};
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use {AgentID, CarID, Distance, On, Speed};
|
use {AgentID, CarID, Distance, Speed};
|
||||||
|
|
||||||
// An immutable view that agents and intersection controllers see of agents.
|
// An immutable view that agents and intersection controllers see of agents.
|
||||||
pub struct AgentView {
|
pub struct AgentView {
|
||||||
pub id: AgentID,
|
pub id: AgentID,
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
pub on: On,
|
pub on: Traversable,
|
||||||
pub dist_along: Distance,
|
pub dist_along: Distance,
|
||||||
pub speed: Speed,
|
pub speed: Speed,
|
||||||
pub vehicle: Option<Vehicle>,
|
pub vehicle: Option<Vehicle>,
|
||||||
@ -38,10 +38,10 @@ impl WorldView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_car_in_front_of(&self, on: On, dist: Distance) -> Option<&AgentView> {
|
pub fn next_car_in_front_of(&self, on: Traversable, dist: Distance) -> Option<&AgentView> {
|
||||||
let maybe_id = match on {
|
let maybe_id = match on {
|
||||||
On::Lane(id) => self.lanes[id.0].next_car_in_front_of(dist),
|
Traversable::Lane(id) => self.lanes[id.0].next_car_in_front_of(dist),
|
||||||
On::Turn(id) => self.turns[&id].next_car_in_front_of(dist),
|
Traversable::Turn(id) => self.turns[&id].next_car_in_front_of(dist),
|
||||||
};
|
};
|
||||||
maybe_id.map(|id| &self.agents[&AgentID::Car(id)])
|
maybe_id.map(|id| &self.agents[&AgentID::Car(id)])
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@ use failure::Error;
|
|||||||
use geom::{Line, Pt2D};
|
use geom::{Line, Pt2D};
|
||||||
use instrument::capture_backtrace;
|
use instrument::capture_backtrace;
|
||||||
use intersections::{IntersectionSimState, Request};
|
use intersections::{IntersectionSimState, Request};
|
||||||
use map_model::{BuildingID, BusStopID, IntersectionID, Lane, LaneID, Map, Turn, TurnID};
|
use map_model::{
|
||||||
|
BuildingID, BusStopID, IntersectionID, Lane, LaneID, Map, Traversable, Turn, TurnID,
|
||||||
|
};
|
||||||
use multimap::MultiMap;
|
use multimap::MultiMap;
|
||||||
use parking::ParkingSimState;
|
use parking::ParkingSimState;
|
||||||
use std;
|
use std;
|
||||||
@ -13,8 +15,8 @@ use std::collections::{BTreeMap, VecDeque};
|
|||||||
use trips::TripManager;
|
use trips::TripManager;
|
||||||
use view::{AgentView, WorldView};
|
use view::{AgentView, WorldView};
|
||||||
use {
|
use {
|
||||||
AgentID, Distance, DrawPedestrianInput, Event, InvariantViolated, On, ParkingSpot,
|
AgentID, Distance, DrawPedestrianInput, Event, InvariantViolated, ParkingSpot, PedestrianID,
|
||||||
PedestrianID, Speed, Tick, Time, TIMESTEP,
|
Speed, Tick, Time, TIMESTEP,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO tune these!
|
// TODO tune these!
|
||||||
@ -91,22 +93,22 @@ enum Action {
|
|||||||
StartCrossingPath(BuildingID),
|
StartCrossingPath(BuildingID),
|
||||||
KeepCrossingPath,
|
KeepCrossingPath,
|
||||||
Continue,
|
Continue,
|
||||||
Goto(On),
|
Goto(Traversable),
|
||||||
WaitFor(On),
|
WaitFor(Traversable),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
struct Pedestrian {
|
struct Pedestrian {
|
||||||
id: PedestrianID,
|
id: PedestrianID,
|
||||||
|
|
||||||
on: On,
|
on: Traversable,
|
||||||
dist_along: Distance,
|
dist_along: Distance,
|
||||||
// Traveling along the lane/turn in its original direction or not?
|
// Traveling along the lane/turn in its original direction or not?
|
||||||
contraflow: bool,
|
contraflow: bool,
|
||||||
|
|
||||||
// Head is the next lane
|
// Head is the next lane
|
||||||
path: VecDeque<LaneID>,
|
path: VecDeque<LaneID>,
|
||||||
waiting_for: Option<On>,
|
waiting_for: Option<Traversable>,
|
||||||
|
|
||||||
front_path: Option<CrossingFrontPath>,
|
front_path: Option<CrossingFrontPath>,
|
||||||
goal: SidewalkSpot,
|
goal: SidewalkSpot,
|
||||||
@ -153,7 +155,7 @@ impl Pedestrian {
|
|||||||
return Action::Continue;
|
return Action::Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let desired_on: On = {
|
let desired_on: Traversable = {
|
||||||
if let Some(on) = self.waiting_for {
|
if let Some(on) = self.waiting_for {
|
||||||
on
|
on
|
||||||
} else {
|
} else {
|
||||||
@ -164,12 +166,12 @@ impl Pedestrian {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.on {
|
match self.on {
|
||||||
On::Lane(id) => {
|
Traversable::Lane(id) => {
|
||||||
let l = map.get_l(id);
|
let l = map.get_l(id);
|
||||||
let at = if self.contraflow { l.src_i } else { l.dst_i };
|
let at = if self.contraflow { l.src_i } else { l.dst_i };
|
||||||
On::Turn(self.choose_turn(id, at, map))
|
Traversable::Turn(self.choose_turn(id, at, map))
|
||||||
}
|
}
|
||||||
On::Turn(id) => On::Lane(map.get_t(id).dst),
|
Traversable::Turn(id) => Traversable::Lane(map.get_t(id).dst),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -177,8 +179,8 @@ impl Pedestrian {
|
|||||||
// Can we actually go there right now?
|
// Can we actually go there right now?
|
||||||
let intersection_req_granted = match desired_on {
|
let intersection_req_granted = match desired_on {
|
||||||
// Already doing a turn, finish it!
|
// Already doing a turn, finish it!
|
||||||
On::Lane(_) => true,
|
Traversable::Lane(_) => true,
|
||||||
On::Turn(id) => intersections.request_granted(Request::for_ped(self.id, id)),
|
Traversable::Turn(id) => intersections.request_granted(Request::for_ped(self.id, id)),
|
||||||
};
|
};
|
||||||
if intersection_req_granted {
|
if intersection_req_granted {
|
||||||
Action::Goto(desired_on)
|
Action::Goto(desired_on)
|
||||||
@ -247,12 +249,12 @@ impl Pedestrian {
|
|||||||
fn step_goto(
|
fn step_goto(
|
||||||
&mut self,
|
&mut self,
|
||||||
events: &mut Vec<Event>,
|
events: &mut Vec<Event>,
|
||||||
on: On,
|
on: Traversable,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
intersections: &mut IntersectionSimState,
|
intersections: &mut IntersectionSimState,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Detect if the ped just warped. Bidirectional sidewalks are confusing. :)
|
// Detect if the ped just warped. Bidirectional sidewalks are confusing. :)
|
||||||
if let On::Lane(l) = self.on {
|
if let Traversable::Lane(l) = self.on {
|
||||||
let l = map.get_l(l);
|
let l = map.get_l(l);
|
||||||
let pt1 = if self.contraflow {
|
let pt1 = if self.contraflow {
|
||||||
l.first_pt()
|
l.first_pt()
|
||||||
@ -270,7 +272,7 @@ impl Pedestrian {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let old_on = self.on.clone();
|
let old_on = self.on.clone();
|
||||||
if let On::Turn(t) = self.on {
|
if let Traversable::Turn(t) = self.on {
|
||||||
intersections.on_exit(Request::for_ped(self.id, t));
|
intersections.on_exit(Request::for_ped(self.id, t));
|
||||||
assert_eq!(self.path[0], map.get_t(t).dst);
|
assert_eq!(self.path[0], map.get_t(t).dst);
|
||||||
self.path.pop_front();
|
self.path.pop_front();
|
||||||
@ -288,10 +290,10 @@ impl Pedestrian {
|
|||||||
self.dist_along = 0.0 * si::M;
|
self.dist_along = 0.0 * si::M;
|
||||||
self.contraflow = false;
|
self.contraflow = false;
|
||||||
match self.on {
|
match self.on {
|
||||||
On::Turn(t) => {
|
Traversable::Turn(t) => {
|
||||||
intersections.on_enter(Request::for_ped(self.id, t))?;
|
intersections.on_enter(Request::for_ped(self.id, t))?;
|
||||||
}
|
}
|
||||||
On::Lane(l) => {
|
Traversable::Lane(l) => {
|
||||||
// Which end of the sidewalk are we entering?
|
// Which end of the sidewalk are we entering?
|
||||||
let turn = map.get_t(old_on.as_turn());
|
let turn = map.get_t(old_on.as_turn());
|
||||||
let lane = map.get_l(l);
|
let lane = map.get_l(l);
|
||||||
@ -427,7 +429,7 @@ impl WalkingSimState {
|
|||||||
}
|
}
|
||||||
Action::WaitFor(on) => {
|
Action::WaitFor(on) => {
|
||||||
self.peds.get_mut(&id).unwrap().waiting_for = Some(on);
|
self.peds.get_mut(&id).unwrap().waiting_for = Some(on);
|
||||||
if let On::Turn(t) = on {
|
if let Traversable::Turn(t) = on {
|
||||||
// Note this is idempotent and does NOT grant the request.
|
// Note this is idempotent and does NOT grant the request.
|
||||||
intersections.submit_request(Request::for_ped(*id, t))?;
|
intersections.submit_request(Request::for_ped(*id, t))?;
|
||||||
}
|
}
|
||||||
@ -440,8 +442,8 @@ impl WalkingSimState {
|
|||||||
self.peds_per_turn.clear();
|
self.peds_per_turn.clear();
|
||||||
for p in self.peds.values() {
|
for p in self.peds.values() {
|
||||||
match p.on {
|
match p.on {
|
||||||
On::Lane(id) => self.peds_per_sidewalk.insert(id, p.id),
|
Traversable::Lane(id) => self.peds_per_sidewalk.insert(id, p.id),
|
||||||
On::Turn(id) => self.peds_per_turn.insert(id, p.id),
|
Traversable::Turn(id) => self.peds_per_turn.insert(id, p.id),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +528,7 @@ impl WalkingSimState {
|
|||||||
id,
|
id,
|
||||||
path,
|
path,
|
||||||
contraflow,
|
contraflow,
|
||||||
on: On::Lane(start_lane),
|
on: Traversable::Lane(start_lane),
|
||||||
dist_along: start.dist_along,
|
dist_along: start.dist_along,
|
||||||
waiting_for: None,
|
waiting_for: None,
|
||||||
front_path,
|
front_path,
|
||||||
@ -537,7 +539,7 @@ impl WalkingSimState {
|
|||||||
self.peds_per_sidewalk.insert(start_lane, id);
|
self.peds_per_sidewalk.insert(start_lane, id);
|
||||||
events.push(Event::AgentEntersTraversable(
|
events.push(Event::AgentEntersTraversable(
|
||||||
AgentID::Pedestrian(id),
|
AgentID::Pedestrian(id),
|
||||||
On::Lane(start_lane),
|
Traversable::Lane(start_lane),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user