mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
add a 4th turn priority... can completely ban turns. make pathfinding
pay attention to this.
This commit is contained in:
parent
956ebc04e6
commit
3198ade5d1
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user