From 8ff4bc09acf93ec124c14b1be49adb3886f92347 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Wed, 26 Oct 2016 18:53:16 +0200 Subject: [PATCH] fix breaking the sorting order by node adjustments --- CHANGELOG.md | 1 + features/guidance/perception.feature | 28 ++++++++++++ .../guidance/intersection_generator.cpp | 45 ++++++++++++++----- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c0279e77..8c8db863a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - Bugfixes - #3032 Fixed a bug that could result in emitting `invalid` as an instruction type on sliproads with mode changes - #3085 Fixed an outdated assertion that could throw without a cause for concern + - #3179 Fixed a bug that could trigger an assertion in TurnInstruciton generation # 5.4.1 - Changes from 5.4.0 diff --git a/features/guidance/perception.feature b/features/guidance/perception.feature index b4edb7585..facf81558 100644 --- a/features/guidance/perception.feature +++ b/features/guidance/perception.feature @@ -162,3 +162,31 @@ Feature: Simple Turns | a,f | depart,continue left,continue right,arrive | place,place,place,place | | d,f | depart,turn right,continue right,arrive | bottom,place,place,place | | d,h | depart,turn right,continue left,turn right,arrive | bottom,place,place,top,top | + + @bug @not-sorted @3179 + Scenario: Adjusting road angles to not be sorted + Given the node map + """ + g + | + | + | + _e - - - - - - - - - f + / + a - - - - -b < + i \ _ + h c - - - - - - - - - d + + """ + + And the ways + | nodes | name | oneway | + | ab | road | no | + | febcd | road | yes | + | ge | in | yes | + | eh | right | yes | + | ei | left | yes | + + When I route I should get + | waypoints | route | + | g,a | in,road,road | diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index e4fe8280e..c74250389 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -578,17 +578,38 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i if (range.size() <= 1) continue; + // the order does not matter + const auto get_offset = [](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { + return 0.5 * angularDeviation(lhs.turn.angle, rhs.turn.angle); + }; + + // When offsetting angles in our turns, we don't want to get past the next turn. This + // function simply limits an offset to be at most half the distance to the next turn in the + // offfset direction + const auto get_corrected_offset = [](const double offset, + const ConnectedRoad &road, + const ConnectedRoad &next_road_in_offset_direction) { + const auto offset_limit = + angularDeviation(road.turn.angle, next_road_in_offset_direction.turn.angle); + // limit the offset with an additional buffer + return (offset + MAXIMAL_ALLOWED_NO_TURN_DEVIATION > offset_limit) ? 0.5 * offset_limit + : offset; + }; + // check if the u-turn edge at the next intersection could be merged to the left/right. If // this is the case and the road is not far away (see previous distance check), if // influences the perceived angle. if (CanMerge(node_at_next_intersection, next_intersection_along_road, 0, 1)) { - const auto offset = 0.5 * angularDeviation(next_intersection_along_road[0].turn.angle, - next_intersection_along_road[1].turn.angle); + const auto offset = + get_offset(next_intersection_along_road[0], next_intersection_along_road[1]); + + const auto corrected_offset = + get_corrected_offset(offset, road, intersection[(index + 1) % intersection.size()]); // at the target intersection, we merge to the right, so we need to shift the current // angle to the left - road.turn.angle = adjustAngle(road.turn.angle, offset); - road.turn.bearing = adjustAngle(road.turn.bearing, offset); + road.turn.angle = adjustAngle(road.turn.angle, corrected_offset); + road.turn.bearing = adjustAngle(road.turn.bearing, corrected_offset); } else if (CanMerge(node_at_next_intersection, next_intersection_along_road, @@ -596,14 +617,15 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i next_intersection_along_road.size() - 1)) { const auto offset = - 0.5 * angularDeviation( - next_intersection_along_road[0].turn.angle, - next_intersection_along_road[next_intersection_along_road.size() - 1] - .turn.angle); + get_offset(next_intersection_along_road[0], + next_intersection_along_road[next_intersection_along_road.size() - 1]); + + const auto corrected_offset = + get_corrected_offset(offset, road, intersection[index - 1]); // at the target intersection, we merge to the left, so we need to shift the current // angle to the right - road.turn.angle = adjustAngle(road.turn.angle, -offset); - road.turn.bearing = adjustAngle(road.turn.bearing, -offset); + road.turn.angle = adjustAngle(road.turn.angle, -corrected_offset); + road.turn.bearing = adjustAngle(road.turn.bearing, -corrected_offset); } } return intersection; @@ -652,8 +674,7 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node, return result; } -const CoordinateExtractor& -IntersectionGenerator::GetCoordinateExtractor() const +const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const { return coordinate_extractor; }