add a 4th turn priority... can completely ban turns. make pathfinding

pay attention to this.
This commit is contained in:
Dustin Carlino 2018-12-05 09:27:08 -08:00
parent 956ebc04e6
commit 3198ade5d1
8 changed files with 52 additions and 20 deletions

View File

@ -84,6 +84,7 @@ impl Plugin for StopSignEditor {
sign.set_priority(id, TurnPriority::Yield, map);
}
}
_ => {}
};
map.edit_stop_sign(sign);
@ -113,6 +114,7 @@ impl Plugin for StopSignEditor {
}
TurnPriority::Yield => Some(ctx.cs.get("yield stop sign turn", Color::YELLOW)),
TurnPriority::Stop => Some(ctx.cs.get("stop turn", Color::RED)),
TurnPriority::Banned => Some(ctx.cs.get("banned turn", Color::PURPLE)),
}
}
_ => None,

View File

@ -129,7 +129,7 @@ impl Plugin for TrafficSignalEditor {
let cycle = &mut signal.cycles[*current_cycle];
// Just one key to toggle between the 3 states
let next_priority = match cycle.get_priority(id) {
TurnPriority::Stop => {
TurnPriority::Banned => {
if ctx.primary.map.get_t(id).turn_type == TurnType::Crosswalk {
if cycle.could_be_priority_turn(id, &ctx.primary.map) {
Some(TurnPriority::Priority)
@ -144,10 +144,13 @@ impl Plugin for TrafficSignalEditor {
if cycle.could_be_priority_turn(id, &ctx.primary.map) {
Some(TurnPriority::Priority)
} else {
Some(TurnPriority::Stop)
Some(TurnPriority::Banned)
}
}
TurnPriority::Priority => Some(TurnPriority::Stop),
TurnPriority::Priority => Some(TurnPriority::Banned),
TurnPriority::Stop => {
panic!("Can't have TurnPriority::Stop in a traffic signal");
}
};
if let Some(pri) = next_priority {
if input.key_pressed(Key::Space, &format!("make {:?} {:?}", id, pri)) {
@ -358,9 +361,12 @@ impl Plugin for TrafficSignalEditor {
TurnPriority::Yield => ctx
.cs
.get("yield turn in current cycle", Color::rgb(255, 105, 180)),
TurnPriority::Stop => ctx
TurnPriority::Banned => ctx
.cs
.get("turn conflicts with current cycle", Color::BLACK),
TurnPriority::Stop => {
panic!("Can't have TurnPriority::Stop in a traffic signal")
}
})
}
_ => None,

View File

@ -9,8 +9,8 @@ use std::fmt;
use {BuildingID, BusStopID, IntersectionID, RoadID};
pub const PARKING_SPOT_LENGTH: si::Meter<f64> = si::Meter {
// TODO look up a real value
value_unsafe: 10.0,
// Bit longer than the longest car.
value_unsafe: 8.0,
_marker: std::marker::PhantomData,
};

View File

@ -12,7 +12,7 @@ use std::path;
use {
Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop, BusStopID, ControlStopSign,
ControlTrafficSignal, Intersection, IntersectionID, IntersectionType, Lane, LaneID, LaneType,
Parcel, ParcelID, Road, RoadID, Turn, TurnID, LANE_THICKNESS,
Parcel, ParcelID, Road, RoadID, Turn, TurnID, TurnPriority, LANE_THICKNESS,
};
#[derive(Serialize, Deserialize, Debug)]
@ -349,7 +349,8 @@ impl Map {
}
}
pub fn edit_stop_sign(&mut self, sign: ControlStopSign) {
pub fn edit_stop_sign(&mut self, mut sign: ControlStopSign) {
sign.changed = true;
self.edits.stop_signs.insert(sign.id, sign.clone());
self.stop_signs.insert(sign.id, sign);
}
@ -661,6 +662,20 @@ impl Map {
}
panic!("No parking lane has label {}", label);
}
pub(crate) fn is_turn_allowed(&self, t: TurnID) -> bool {
if let Some(ss) = self.stop_signs.get(&t.parent) {
ss.get_priority(t) != TurnPriority::Banned
} else if let Some(ts) = self.traffic_signals.get(&t.parent) {
ts.cycles
.iter()
.find(|c| c.get_priority(t) != TurnPriority::Banned)
.is_some()
} else {
// Border nodes have no turns...
panic!("{}'s intersection isn't a stop sign or traffic signal", t);
}
}
}
fn is_border(intersection: &Intersection, map: &Map) -> bool {

View File

@ -318,7 +318,9 @@ impl Pathfinder {
map.get_l(l).src_i
};
for (turn, next) in map.get_next_turns_and_lanes(l, endpoint).into_iter() {
if !self.can_use_bike_lanes && next.lane_type == LaneType::Biking {
if !map.is_turn_allowed(turn.id) {
// Skip
} else if !self.can_use_bike_lanes && next.lane_type == LaneType::Biking {
// Skip
} else if !self.can_use_bus_lanes && next.lane_type == LaneType::Bus {
// Skip
@ -345,7 +347,9 @@ impl Pathfinder {
// Don't forget multiple turns in a row.
for (turn, next) in map.get_next_turns_and_lanes(dst.id, t.parent).into_iter() {
if !self.can_use_bike_lanes && next.lane_type == LaneType::Biking {
if !map.is_turn_allowed(turn.id) {
// Skip
} else if !self.can_use_bike_lanes && next.lane_type == LaneType::Biking {
// Skip
} else if !self.can_use_bus_lanes && next.lane_type == LaneType::Bus {
// Skip

View File

@ -5,13 +5,13 @@ use {IntersectionID, LaneID, Map, TurnID, TurnPriority, TurnType};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ControlStopSign {
pub id: IntersectionID,
// Turns may be present here as Banned.
#[serde(
serialize_with = "serialize_btreemap",
deserialize_with = "deserialize_btreemap"
)]
turns: BTreeMap<TurnID, TurnPriority>,
// TODO
changed: bool,
pub(crate) changed: bool,
}
impl ControlStopSign {
@ -26,11 +26,11 @@ impl ControlStopSign {
}
pub fn set_priority(&mut self, turn: TurnID, priority: TurnPriority, map: &Map) {
assert_ne!(self.turns[&turn], priority);
if priority == TurnPriority::Priority {
assert!(self.could_be_priority_turn(turn, map));
}
self.turns.insert(turn, priority);
self.changed = true;
}
pub fn could_be_priority_turn(&self, id: TurnID, map: &Map) -> bool {
@ -43,15 +43,15 @@ impl ControlStopSign {
}
pub fn is_changed(&self) -> bool {
// TODO detect edits that've been undone, equivalent to original
self.changed
}
// Only Yield and Priority
pub fn is_priority_lane(&self, lane: LaneID) -> bool {
self.turns
.iter()
.find(|(turn, pri)| turn.src == lane && **pri > TurnPriority::Stop)
.is_some()
.find(|(turn, pri)| turn.src == lane && **pri <= TurnPriority::Stop)
.is_none()
}
fn validate(&self, map: &Map) -> Result<(), Error> {

View File

@ -335,7 +335,7 @@ impl Cycle {
} else if self.yield_turns.contains(&t) {
TurnPriority::Yield
} else {
TurnPriority::Stop
TurnPriority::Banned
}
}
@ -354,7 +354,7 @@ impl Cycle {
assert_ne!(pri, TurnPriority::Yield);
self.yield_turns.remove(&t);
} else {
assert_ne!(pri, TurnPriority::Stop);
assert_ne!(pri, TurnPriority::Banned);
}
// Now add to the new set
@ -370,7 +370,10 @@ impl Cycle {
assert_ne!(turn.turn_type, TurnType::Crosswalk);
self.yield_turns.insert(t);
}
TurnPriority::Stop => {}
TurnPriority::Stop => {
panic!("Can't set a cycle's TurnPriority to Stop");
}
TurnPriority::Banned => {}
}
}

View File

@ -49,8 +49,10 @@ impl TurnType {
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy, PartialOrd)]
pub enum TurnPriority {
// Can't do this turn at all!
Banned,
// For stop signs: cars have to stop before doing this turn, and are accepted with the lowest priority.
// For traffic signals: can't do this turn at all.
// For traffic signals: this priority doesn't make sense; can't be used.
Stop,
// Cars can do this immediately if there are no previously accepted conflicting turns.
Yield,