adjusting u-turn handling in lane matching to fully fix 2706
This commit is contained in:
parent
11aed6c93e
commit
9485c97738
@ -740,8 +740,8 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | name | highway | turn:lanes:forward |
|
| nodes | name | highway | turn:lanes:forward |
|
||||||
| ab | road | primary | through,right |
|
| ab | road | primary | through;right |
|
||||||
| bc | road | primary | through,right |
|
| bc | road | primary | through;right |
|
||||||
| cd | road | primary | |
|
| cd | road | primary | |
|
||||||
| xa | road | primary | |
|
| xa | road | primary | |
|
||||||
| be | turn | primary | |
|
| be | turn | primary | |
|
||||||
@ -862,3 +862,24 @@ Feature: Turn Lane Guidance
|
|||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| d,a ||||
|
| d,a ||||
|
||||||
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
|
# Note: at the moment we don't care about routes, we care about the extract process triggering assertions
|
||||||
|
|
||||||
|
@reverse @2730
|
||||||
|
Scenario: Reverse on the right
|
||||||
|
Given the node map
|
||||||
|
| a | | | c | |
|
||||||
|
| | | | b | d |
|
||||||
|
| f | | | e | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | name | turn:lanes:forward | oneway |
|
||||||
|
| ab | primary | in | left\|through\|right;reverse | yes |
|
||||||
|
| bc | primary | left | | no |
|
||||||
|
| bd | primary | through | | no |
|
||||||
|
| be | primary | right | | no |
|
||||||
|
| bf | primary | in | | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns | lanes |
|
||||||
|
| a,c | in,left,left | depart,turn left,arrive | ,left:true straight:false right;uturn:false, |
|
||||||
|
| a,d | in,through,through | depart,new name straight,arrive | ,left:false straight:true right;uturn:false, |
|
||||||
|
| a,e | in,right,right | depart,turn right,arrive | ,left:false straight:false right;uturn:true, |
|
||||||
|
@ -277,7 +277,7 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
|||||||
{
|
{
|
||||||
const double correction_factor = (intersection[1].turn.angle) / 2;
|
const double correction_factor = (intersection[1].turn.angle) / 2;
|
||||||
for (std::size_t i = 2; i < intersection.size(); ++i)
|
for (std::size_t i = 2; i < intersection.size(); ++i)
|
||||||
intersection[i].turn.angle += correction_factor;
|
intersection[i].turn.angle -= correction_factor;
|
||||||
intersection[0] = merge(intersection[0], intersection[1]);
|
intersection[0] = merge(intersection[0], intersection[1]);
|
||||||
intersection[0].turn.angle = 0;
|
intersection[0].turn.angle = 0;
|
||||||
intersection.erase(intersection.begin() + 1);
|
intersection.erase(intersection.begin() + 1);
|
||||||
|
@ -38,6 +38,28 @@ bool TurnLaneData::operator<(const TurnLaneData &other) const
|
|||||||
TurnLaneType::left,
|
TurnLaneType::left,
|
||||||
TurnLaneType::sharp_left,
|
TurnLaneType::sharp_left,
|
||||||
TurnLaneType::uturn};
|
TurnLaneType::uturn};
|
||||||
|
// U-Turns are supposed to be on the outside. So if the first lane is 0 and we are looking at a
|
||||||
|
// u-turn, it has to be on the very left. If it is equal to the number of lanes, it has to be on
|
||||||
|
// the right. These sorting function assume reverse to be on the outside always. Might need to
|
||||||
|
// be reconsidered if there are situations that offer a reverse from some middle lane (seems
|
||||||
|
// improbable)
|
||||||
|
|
||||||
|
if (tag == TurnLaneType::uturn)
|
||||||
|
{
|
||||||
|
if (from == 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.tag == TurnLaneType::uturn)
|
||||||
|
{
|
||||||
|
if (other.from == 0)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return std::find(tag_by_modifier, tag_by_modifier + 8, this->tag) <
|
return std::find(tag_by_modifier, tag_by_modifier + 8, this->tag) <
|
||||||
std::find(tag_by_modifier, tag_by_modifier + 8, other.tag);
|
std::find(tag_by_modifier, tag_by_modifier + 8, other.tag);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "extractor/guidance/turn_lane_handler.hpp"
|
|
||||||
#include "extractor/guidance/constants.hpp"
|
#include "extractor/guidance/constants.hpp"
|
||||||
#include "extractor/guidance/turn_discovery.hpp"
|
#include "extractor/guidance/turn_discovery.hpp"
|
||||||
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_handler.hpp"
|
||||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
@ -119,9 +119,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
|||||||
|
|
||||||
if (!lane_data.empty() && canMatchTrivially(intersection, lane_data) &&
|
if (!lane_data.empty() && canMatchTrivially(intersection, lane_data) &&
|
||||||
lane_data.size() !=
|
lane_data.size() !=
|
||||||
static_cast<std::size_t>(
|
static_cast<std::size_t>((
|
||||||
lane_data.back().tag != TurnLaneType::uturn && intersection[0].entry_allowed ? 1
|
!hasTag(TurnLaneType::uturn, lane_data) && intersection[0].entry_allowed ? 1 : 0)) +
|
||||||
: 0) +
|
|
||||||
possible_entries &&
|
possible_entries &&
|
||||||
intersection[0].entry_allowed && !hasTag(TurnLaneType::none, lane_data))
|
intersection[0].entry_allowed && !hasTag(TurnLaneType::none, lane_data))
|
||||||
lane_data.push_back({TurnLaneType::uturn, lane_data.back().to, lane_data.back().to});
|
lane_data.push_back({TurnLaneType::uturn, lane_data.back().to, lane_data.back().to});
|
||||||
@ -352,14 +351,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
if (lane_data.back().tag == TurnLaneType::uturn)
|
if (lane_data.back().tag == TurnLaneType::uturn)
|
||||||
return findBestMatchForReverse(lane_data[lane_data.size() - 2].tag, intersection);
|
return findBestMatchForReverse(lane_data[lane_data.size() - 2].tag, intersection);
|
||||||
|
|
||||||
// TODO(mokob): #2730 have a look please
|
BOOST_ASSERT(lane_data.front().tag == TurnLaneType::uturn);
|
||||||
// BOOST_ASSERT(lane_data.front().tag == TurnLaneType::uturn);
|
|
||||||
// return findBestMatchForReverse(lane_data[1].tag, intersection);
|
|
||||||
//
|
|
||||||
if (lane_data.front().tag == TurnLaneType::uturn)
|
|
||||||
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
||||||
|
|
||||||
return findBestMatch(data.tag, intersection);
|
|
||||||
}();
|
}();
|
||||||
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
||||||
all_simple &= (matched_indices.count(match_index) == 0);
|
all_simple &= (matched_indices.count(match_index) == 0);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
|
||||||
#include "extractor/guidance/toolkit.hpp"
|
#include "extractor/guidance/toolkit.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||||
#include "util/guidance/toolkit.hpp"
|
#include "util/guidance/toolkit.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
@ -134,17 +134,17 @@ typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask &ta
|
|||||||
// possible that it is forbidden. In addition, the best u-turn angle does not necessarily represent
|
// possible that it is forbidden. In addition, the best u-turn angle does not necessarily represent
|
||||||
// the u-turn, since it could be a sharp-left turn instead on a road with a middle island.
|
// the u-turn, since it could be a sharp-left turn instead on a road with a middle island.
|
||||||
typename Intersection::const_iterator
|
typename Intersection::const_iterator
|
||||||
findBestMatchForReverse(const TurnLaneType::Mask &leftmost_tag, const Intersection &intersection)
|
findBestMatchForReverse(const TurnLaneType::Mask &neighbor_tag, const Intersection &intersection)
|
||||||
{
|
{
|
||||||
const auto leftmost_itr = findBestMatch(leftmost_tag, intersection);
|
const auto neighbor_itr = findBestMatch(neighbor_tag, intersection);
|
||||||
if (leftmost_itr + 1 == intersection.cend())
|
if ((neighbor_itr + 1 == intersection.cend()) || (neighbor_itr == intersection.cbegin() + 1))
|
||||||
return intersection.begin();
|
return intersection.begin();
|
||||||
|
|
||||||
const constexpr double idealized_turn_angles[] = {0, 35, 90, 135, 180, 225, 270, 315};
|
const constexpr double idealized_turn_angles[] = {0, 35, 90, 135, 180, 225, 270, 315};
|
||||||
const TurnLaneType::Mask tag = TurnLaneType::uturn;
|
const TurnLaneType::Mask tag = TurnLaneType::uturn;
|
||||||
const auto idealized_angle = idealized_turn_angles[getMatchingModifier(tag)];
|
const auto idealized_angle = idealized_turn_angles[getMatchingModifier(tag)];
|
||||||
return std::min_element(
|
return std::min_element(
|
||||||
intersection.begin() + std::distance(intersection.begin(), leftmost_itr),
|
intersection.begin() + std::distance(intersection.begin(), neighbor_itr),
|
||||||
intersection.end(),
|
intersection.end(),
|
||||||
[idealized_angle, &tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
|
[idealized_angle, &tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
|
||||||
// prefer valid matches
|
// prefer valid matches
|
||||||
@ -165,6 +165,12 @@ findBestMatchForReverse(const TurnLaneType::Mask &leftmost_tag, const Intersecti
|
|||||||
bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data)
|
bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data)
|
||||||
{
|
{
|
||||||
std::size_t road_index = 1, lane = 0;
|
std::size_t road_index = 1, lane = 0;
|
||||||
|
if (!lane_data.empty() && lane_data.front().tag == TurnLaneType::uturn)
|
||||||
|
{
|
||||||
|
// the very first is a u-turn to the right
|
||||||
|
if (intersection[0].entry_allowed)
|
||||||
|
lane = 1;
|
||||||
|
}
|
||||||
for (; road_index < intersection.size() && lane < lane_data.size(); ++road_index)
|
for (; road_index < intersection.size() && lane < lane_data.size(); ++road_index)
|
||||||
{
|
{
|
||||||
if (intersection[road_index].entry_allowed)
|
if (intersection[road_index].entry_allowed)
|
||||||
@ -207,6 +213,34 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
|||||||
road.turn.lane_data_id = lane_data_id;
|
road.turn.lane_data_id = lane_data_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!lane_data.empty() && lane_data.front().tag == TurnLaneType::uturn)
|
||||||
|
{
|
||||||
|
// the very first is a u-turn to the right
|
||||||
|
if (intersection[0].entry_allowed)
|
||||||
|
{
|
||||||
|
std::size_t u_turn = 0;
|
||||||
|
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
|
||||||
|
{
|
||||||
|
if (intersection.size() <= 1 || !intersection[1].entry_allowed ||
|
||||||
|
intersection[1].turn.instruction.direction_modifier !=
|
||||||
|
DirectionModifier::SharpRight)
|
||||||
|
{
|
||||||
|
// cannot match u-turn in a valid way
|
||||||
|
return intersection;
|
||||||
|
}
|
||||||
|
u_turn = 1;
|
||||||
|
road_index = 2;
|
||||||
|
}
|
||||||
|
intersection[u_turn].entry_allowed = true;
|
||||||
|
intersection[u_turn].turn.instruction.type = TurnType::Turn;
|
||||||
|
intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn;
|
||||||
|
|
||||||
|
matchRoad(intersection[u_turn], lane_data.back());
|
||||||
|
// continue with the first lane
|
||||||
|
lane = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (; road_index < intersection.size() && lane < lane_data.size(); ++road_index)
|
for (; road_index < intersection.size() && lane < lane_data.size(); ++road_index)
|
||||||
{
|
{
|
||||||
if (intersection[road_index].entry_allowed)
|
if (intersection[road_index].entry_allowed)
|
||||||
@ -231,7 +265,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
|||||||
std::size_t u_turn = 0;
|
std::size_t u_turn = 0;
|
||||||
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
|
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
|
||||||
{
|
{
|
||||||
if (intersection.back().entry_allowed ||
|
if (!intersection.back().entry_allowed ||
|
||||||
intersection.back().turn.instruction.direction_modifier !=
|
intersection.back().turn.instruction.direction_modifier !=
|
||||||
DirectionModifier::SharpLeft)
|
DirectionModifier::SharpLeft)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user