moving on->traversable, in the map model directly

This commit is contained in:
Dustin Carlino 2018-10-09 13:00:10 -07:00
parent d7a36889b2
commit d3e5fdb7c4
8 changed files with 123 additions and 112 deletions

View File

@ -30,6 +30,7 @@ mod pathfind;
pub mod raw_data;
mod road;
mod trace;
mod traversable;
mod turn;
pub use area::{Area, AreaID, AreaType};
@ -43,6 +44,7 @@ pub use parcel::{Parcel, ParcelID};
pub use pathfind::Pathfinder;
pub use road::{Road, RoadID};
pub use trace::Trace;
pub use traversable::Traversable;
pub use turn::{Turn, TurnID};
pub const LANE_THICKNESS: f64 = 2.5;

View 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(),
}
}
}

View File

@ -6,7 +6,7 @@ use geom::EPSILON_DIST;
use intersections::{IntersectionSimState, Request};
use kinematics;
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 ordered_float::NotNaN;
use parking::ParkingSimState;
@ -17,7 +17,7 @@ use std::collections::BTreeMap;
use transit::TransitSimState;
use view::{AgentView, WorldView};
use {
Acceleration, AgentID, CarID, CarState, Distance, DrawCarInput, Event, InvariantViolated, On,
Acceleration, AgentID, CarID, CarState, Distance, DrawCarInput, Event, InvariantViolated,
ParkedCar, ParkingSpot, Speed, Tick, Time,
};
@ -37,7 +37,7 @@ struct ParkingState {
#[derive(Clone, Debug, Serialize, Deserialize)]
struct Car {
id: CarID,
on: On,
on: Traversable,
speed: Speed,
dist_along: Distance,
vehicle: Vehicle,
@ -45,7 +45,7 @@ struct Car {
parking: Option<ParkingState>,
// TODO should this only be turns?
waiting_for: Option<On>,
waiting_for: Option<Traversable>,
debug: bool,
// TODO ew? :\
@ -177,7 +177,7 @@ impl Car {
}
// 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(
current_on,
current_dist_along,
@ -226,11 +226,11 @@ impl Car {
break;
}
current_on = match current_on {
On::Turn(t) => {
Traversable::Turn(t) => {
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;
dist_scanned_ahead += dist_this_step;
@ -285,11 +285,11 @@ impl Car {
break;
}
let next_on = match self.on {
On::Turn(t) => On::Lane(map.get_t(t).dst),
On::Lane(l) => On::Turn(router.choose_turn(l, map)),
Traversable::Turn(t) => Traversable::Lane(map.get_t(t).dst),
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));
router.advance_to(t.dst);
}
@ -303,7 +303,7 @@ impl Car {
));
self.waiting_for = None;
self.on = next_on;
if let On::Turn(t) = self.on {
if let Traversable::Turn(t) = self.on {
intersections
.on_enter(Request::for_car(self.id, t))
.context(format!(
@ -319,7 +319,7 @@ impl Car {
#[derive(Serialize, Deserialize, Clone)]
pub struct SimQueue {
id: On,
id: Traversable,
// First element is farthest along the queue; they have the greatest dist_along.
// Caching the current dist_along vastly simplifies the API of SimQueue.
cars_queue: Vec<(Distance, CarID)>,
@ -338,7 +338,7 @@ impl PartialEq for SimQueue {
impl Eq for SimQueue {}
impl SimQueue {
fn new(id: On, map: &Map) -> SimQueue {
fn new(id: Traversable, map: &Map) -> SimQueue {
SimQueue {
id,
cars_queue: Vec::new(),
@ -444,14 +444,15 @@ impl DrivingSimState {
lanes: map
.all_lanes()
.iter()
.map(|l| SimQueue::new(On::Lane(l.id), map))
.map(|l| SimQueue::new(Traversable::Lane(l.id), map))
.collect(),
turns: BTreeMap::new(),
debug: None,
};
for t in map.all_turns().values() {
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
@ -534,7 +535,8 @@ impl DrivingSimState {
}
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
@ -621,8 +623,10 @@ impl DrivingSimState {
// 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
// leader vehicle...
if On::Lane(req.turn.src) == c.on && c.speed <= kinematics::EPSILON_SPEED {
c.waiting_for = Some(On::Turn(req.turn));
if Traversable::Lane(req.turn.src) == c.on
&& 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
// 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_turn = MultiMap::new();
for c in self.cars.values() {
match c.on {
On::Lane(id) => cars_per_lane.insert(id, c.id),
On::Turn(id) => cars_per_turn.insert(id, c.id),
Traversable::Lane(id) => cars_per_lane.insert(id, c.id),
Traversable::Turn(id) => cars_per_turn.insert(id, c.id),
};
}
@ -722,7 +726,7 @@ impl DrivingSimState {
id: car,
dist_along: dist_along,
speed: 0.0 * si::MPS,
on: On::Lane(start),
on: Traversable::Lane(start),
vehicle,
waiting_for: None,
debug: false,
@ -740,7 +744,7 @@ impl DrivingSimState {
self.lanes[start.0].insert_at(car, dist_along);
events.push(Event::AgentEntersTraversable(
AgentID::Car(car),
On::Lane(start),
Traversable::Lane(start),
));
true
}

View File

@ -1,6 +1,6 @@
use intersections::Request;
use map_model::{BuildingID, BusStopID};
use {AgentID, CarID, On, ParkingSpot, PedestrianID};
use map_model::{BuildingID, BusStopID, Traversable};
use {AgentID, CarID, ParkingSpot, PedestrianID};
#[derive(Debug, PartialEq, Eq)]
pub enum Event {
@ -19,8 +19,8 @@ pub enum Event {
PedLeavesBus(PedestrianID, CarID),
// TODO split up into cases or not?
AgentEntersTraversable(AgentID, On),
AgentLeavesTraversable(AgentID, On),
AgentEntersTraversable(AgentID, Traversable),
AgentLeavesTraversable(AgentID, Traversable),
// TODO maybe AgentRequestsTurn?
IntersectionAcceptsRequest(Request),

View File

@ -60,7 +60,7 @@ pub use events::Event;
use geom::{Angle, Pt2D};
pub use helpers::{load, SimFlags};
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 sim::{Benchmark, Sim};
use std::fmt;
@ -254,57 +254,6 @@ fn time_parsing() {
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 {
Moving,
Stuck,

View File

@ -2,13 +2,13 @@ use dimensioned::si;
use driving::Action;
use kinematics;
use kinematics::Vehicle;
use map_model::{BuildingID, LaneID, Map, TurnID};
use map_model::{BuildingID, LaneID, Map, Traversable, TurnID};
use parking::ParkingSimState;
use rand::Rng;
use std::collections::VecDeque;
use transit::TransitSimState;
use view::AgentView;
use {Distance, Event, On, ParkingSpot, Tick};
use {Distance, Event, ParkingSpot, Tick};
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
enum Goal {
@ -95,7 +95,7 @@ impl Router {
pub fn stop_early_at_dist(
&self,
// TODO urgh, we cant reuse AgentView here, because lookahead doesn't advance the view :(
on: On,
on: Traversable,
dist_along: Distance,
vehicle: &Vehicle,
map: &Map,

View File

@ -1,14 +1,14 @@
use driving::SimQueue;
use kinematics::Vehicle;
use map_model::TurnID;
use map_model::{Traversable, TurnID};
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.
pub struct AgentView {
pub id: AgentID,
pub debug: bool,
pub on: On,
pub on: Traversable,
pub dist_along: Distance,
pub speed: Speed,
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 {
On::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::Lane(id) => self.lanes[id.0].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)])
}

View File

@ -5,7 +5,9 @@ use failure::Error;
use geom::{Line, Pt2D};
use instrument::capture_backtrace;
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 parking::ParkingSimState;
use std;
@ -13,8 +15,8 @@ use std::collections::{BTreeMap, VecDeque};
use trips::TripManager;
use view::{AgentView, WorldView};
use {
AgentID, Distance, DrawPedestrianInput, Event, InvariantViolated, On, ParkingSpot,
PedestrianID, Speed, Tick, Time, TIMESTEP,
AgentID, Distance, DrawPedestrianInput, Event, InvariantViolated, ParkingSpot, PedestrianID,
Speed, Tick, Time, TIMESTEP,
};
// TODO tune these!
@ -91,22 +93,22 @@ enum Action {
StartCrossingPath(BuildingID),
KeepCrossingPath,
Continue,
Goto(On),
WaitFor(On),
Goto(Traversable),
WaitFor(Traversable),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Pedestrian {
id: PedestrianID,
on: On,
on: Traversable,
dist_along: Distance,
// Traveling along the lane/turn in its original direction or not?
contraflow: bool,
// Head is the next lane
path: VecDeque<LaneID>,
waiting_for: Option<On>,
waiting_for: Option<Traversable>,
front_path: Option<CrossingFrontPath>,
goal: SidewalkSpot,
@ -153,7 +155,7 @@ impl Pedestrian {
return Action::Continue;
}
let desired_on: On = {
let desired_on: Traversable = {
if let Some(on) = self.waiting_for {
on
} else {
@ -164,12 +166,12 @@ impl Pedestrian {
}
match self.on {
On::Lane(id) => {
Traversable::Lane(id) => {
let l = map.get_l(id);
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?
let intersection_req_granted = match desired_on {
// Already doing a turn, finish it!
On::Lane(_) => true,
On::Turn(id) => intersections.request_granted(Request::for_ped(self.id, id)),
Traversable::Lane(_) => true,
Traversable::Turn(id) => intersections.request_granted(Request::for_ped(self.id, id)),
};
if intersection_req_granted {
Action::Goto(desired_on)
@ -247,12 +249,12 @@ impl Pedestrian {
fn step_goto(
&mut self,
events: &mut Vec<Event>,
on: On,
on: Traversable,
map: &Map,
intersections: &mut IntersectionSimState,
) -> Result<(), Error> {
// 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 pt1 = if self.contraflow {
l.first_pt()
@ -270,7 +272,7 @@ impl Pedestrian {
}
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));
assert_eq!(self.path[0], map.get_t(t).dst);
self.path.pop_front();
@ -288,10 +290,10 @@ impl Pedestrian {
self.dist_along = 0.0 * si::M;
self.contraflow = false;
match self.on {
On::Turn(t) => {
Traversable::Turn(t) => {
intersections.on_enter(Request::for_ped(self.id, t))?;
}
On::Lane(l) => {
Traversable::Lane(l) => {
// Which end of the sidewalk are we entering?
let turn = map.get_t(old_on.as_turn());
let lane = map.get_l(l);
@ -427,7 +429,7 @@ impl WalkingSimState {
}
Action::WaitFor(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.
intersections.submit_request(Request::for_ped(*id, t))?;
}
@ -440,8 +442,8 @@ impl WalkingSimState {
self.peds_per_turn.clear();
for p in self.peds.values() {
match p.on {
On::Lane(id) => self.peds_per_sidewalk.insert(id, p.id),
On::Turn(id) => self.peds_per_turn.insert(id, p.id),
Traversable::Lane(id) => self.peds_per_sidewalk.insert(id, p.id),
Traversable::Turn(id) => self.peds_per_turn.insert(id, p.id),
};
}
@ -526,7 +528,7 @@ impl WalkingSimState {
id,
path,
contraflow,
on: On::Lane(start_lane),
on: Traversable::Lane(start_lane),
dist_along: start.dist_along,
waiting_for: None,
front_path,
@ -537,7 +539,7 @@ impl WalkingSimState {
self.peds_per_sidewalk.insert(start_lane, id);
events.push(Event::AgentEntersTraversable(
AgentID::Pedestrian(id),
On::Lane(start_lane),
Traversable::Lane(start_lane),
));
}