Skip to content

Commit

Permalink
Explicitly model U-turns. Sometimes they're legal, often they get
Browse files Browse the repository at this point in the history
generated incorrectly, but regardless, calling them TurnType::Left is
just confusing.

For the moment, always filter out U-turns from merged intersections.
When connections across merged one-ways are handled properly, we won't
need this, but in the meantime, it moves forward. #114

Not regenerating just yet, but will bundle it with the next commit.
  • Loading branch information
dabreegster committed Dec 30, 2020
1 parent de4b026 commit 9bc761f
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 12 deletions.
2 changes: 1 addition & 1 deletion map_gui/src/render/car.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl DrawCar {

if let Some(t) = input.waiting_for_turn {
match map.get_t(t).turn_type {
TurnType::Left => {
TurnType::Left | TurnType::UTurn => {
let (pos, angle) = input
.body
.must_dist_along(input.body.length() - Distance::meters(2.5));
Expand Down
6 changes: 6 additions & 0 deletions map_gui/src/tools/turn_explorer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ impl TurnExplorer {
TurnExplorer::color_turn_type(TurnType::Left),
"left turn",
));
col.push(ColorLegend::row(
ctx,
TurnExplorer::color_turn_type(TurnType::UTurn),
"U-turn",
));
}
} else {
let (lt, lc, slow_lane) = turns[idx - 1].penalty(app.map());
Expand Down Expand Up @@ -194,6 +199,7 @@ impl TurnExplorer {
TurnType::Straight => Color::BLUE,
TurnType::Right => Color::GREEN,
TurnType::Left => Color::RED,
TurnType::UTurn => Color::PURPLE,
}
}
}
Expand Down
23 changes: 13 additions & 10 deletions map_model/src/make/merge_intersections.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use crate::raw::{OriginalRoad, RawMap};
use std::collections::BTreeSet;

use crate::osm::NodeID;
use crate::raw::RawMap;

/// Merge tiny "roads" that're actually just part of a complicated intersection. Returns all
/// surviving intersections adjacent to one of these merged roads.
pub fn merge_short_roads(map: &mut RawMap) -> BTreeSet<NodeID> {
let mut merged = BTreeSet::new();

/// Experimentally try to merge tiny "roads" that're actually just part of a complicated
/// intersection.
pub fn merge_short_roads(map: &mut RawMap) {
// An expensive fixed-point approach. When we merge one road, the IDs of some other roads might
// change, so it's simplest just to start over.
// TODO But since merge_short_road tells us what road IDs were deleted and created, it wouldn't
Expand All @@ -11,13 +16,9 @@ pub fn merge_short_roads(map: &mut RawMap) {
let mut changes = false;
for (id, road) in &map.roads {
// See https://wiki.openstreetmap.org/wiki/Proposed_features/junction%3Dintersection
// Hardcoding some Montlake intersections to test
if road.osm_tags.is("junction", "intersection")
|| *id == OriginalRoad::new(459084309, (4550007325, 4550007326))
|| *id == OriginalRoad::new(332060258, (3391701875, 1635790583))
{
if road.osm_tags.is("junction", "intersection") {
let id = *id;
map.merge_short_road(id).unwrap();
merged.insert(map.merge_short_road(id).unwrap().0);
changes = true;
break;
}
Expand All @@ -26,4 +27,6 @@ pub fn merge_short_roads(map: &mut RawMap) {
break;
}
}

merged
}
3 changes: 2 additions & 1 deletion map_model/src/make/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Map {
// Better to defer this and see RawMaps with more debug info in map_editor
remove_disconnected::remove_disconnected_roads(&mut raw, timer);

merge_intersections::merge_short_roads(&mut raw);
let merged_intersections = merge_intersections::merge_short_roads(&mut raw);

timer.start("raw_map to InitialMap");
let gps_bounds = raw.gps_bounds.clone();
Expand Down Expand Up @@ -88,6 +88,7 @@ impl Map {
incoming_lanes: Vec::new(),
outgoing_lanes: Vec::new(),
roads: i.roads.iter().map(|id| road_id_mapping[id]).collect(),
merged: merged_intersections.contains(&i.id),
});
intersection_id_mapping.insert(i.id, id);
}
Expand Down
16 changes: 16 additions & 0 deletions map_model/src/make/turns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,20 @@ pub fn make_all_turns(map: &Map, i: &Intersection, timer: &mut Timer) -> Vec<Tur
final_turns = remove_merging_turns(map, final_turns, TurnType::Right);
final_turns = remove_merging_turns(map, final_turns, TurnType::Left);

if i.merged {
final_turns.retain(|turn| {
if turn.turn_type == TurnType::UTurn {
timer.warn(format!(
"Removing u-turn from merged intersection: {}",
turn.id
));
false
} else {
true
}
});
}

let mut outgoing_missing: HashSet<LaneID> = HashSet::new();
for l in &i.outgoing_lanes {
if map.get_l(*l).lane_type.supports_any_movement() {
Expand Down Expand Up @@ -373,6 +387,8 @@ fn turn_type_from_angles(from: Angle, to: Angle) -> TurnType {
// some observed cases.
if diff.abs() < 30.0 {
TurnType::Straight
} else if diff.abs() > 135.0 {
TurnType::UTurn
} else if diff < 0.0 {
// Clockwise rotation
TurnType::Right
Expand Down
3 changes: 3 additions & 0 deletions map_model/src/objects/intersection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ pub struct Intersection {

// TODO Maybe DirectedRoadIDs
pub roads: BTreeSet<RoadID>,

/// Was a short road adjacent to this intersection merged?
pub merged: bool,
}

impl Intersection {
Expand Down
1 change: 1 addition & 0 deletions map_model/src/objects/turn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum TurnType {
Straight,
Right,
Left,
UTurn,
}

// TODO This concept may be dated, now that Movements exist. Within a movement, the lane-changing
Expand Down

0 comments on commit 9bc761f

Please sign in to comment.