make roundabout maneuvers continuous with respect to lane changes
This commit is contained in:
parent
86241a2793
commit
396add1e9d
@ -8,6 +8,7 @@
|
|||||||
- Guidance
|
- Guidance
|
||||||
- Improved detection of obvious turns
|
- Improved detection of obvious turns
|
||||||
- Improved turn lane detection
|
- Improved turn lane detection
|
||||||
|
- Improved lane anticipation for roundabouts
|
||||||
- Bugfixes
|
- Bugfixes
|
||||||
- Fix bug that didn't chose minimal weights on overlapping edges
|
- Fix bug that didn't chose minimal weights on overlapping edges
|
||||||
|
|
||||||
|
@ -365,6 +365,62 @@ Feature: Turn Lane Guidance
|
|||||||
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||||
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||||
|
|
||||||
|
@anticipate
|
||||||
|
Scenario: Departing or arriving inside a roundabout does not yet anticipate lanes (BIG version)
|
||||||
|
Given the node map
|
||||||
|
| | | a | | |
|
||||||
|
| x | b | | d | y |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | c | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | turn:lanes:forward | highway | junction | name |
|
||||||
|
| xb | slight_right\|slight_right | primary | | xb |
|
||||||
|
| dy | | primary | | dy |
|
||||||
|
| ab | | primary | roundabout | roundabout |
|
||||||
|
| bc | | primary | roundabout | roundabout |
|
||||||
|
| cd | left\|slight_right | primary | roundabout | roundabout |
|
||||||
|
| da | | primary | roundabout | roundabout |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns | lanes |
|
||||||
|
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
|
||||||
|
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||||
|
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Anticipate Lanes for turns before and / or after roundabout
|
Scenario: Anticipate Lanes for turns before and / or after roundabout
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -15,7 +15,10 @@ namespace guidance
|
|||||||
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
||||||
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
||||||
// we anticipate lane changes emitting only matching lanes early on.
|
// we anticipate lane changes emitting only matching lanes early on.
|
||||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
|
// the second parameter describes the duration that we feel two segments need to be apart to count
|
||||||
|
// as separate maneuvers.
|
||||||
|
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||||
|
const double min_duration_needed_for_lane_change = 15);
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "util/debug.hpp"
|
||||||
#include "util/for_each_pair.hpp"
|
#include "util/for_each_pair.hpp"
|
||||||
#include "util/group_by.hpp"
|
#include "util/group_by.hpp"
|
||||||
#include "util/guidance/toolkit.hpp"
|
#include "util/guidance/toolkit.hpp"
|
||||||
@ -20,18 +21,17 @@ namespace engine
|
|||||||
namespace guidance
|
namespace guidance
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps)
|
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||||
|
const double min_duration_needed_for_lane_change)
|
||||||
{
|
{
|
||||||
const constexpr auto MIN_DURATION_NEEDED_FOR_LANE_CHANGE = 15.;
|
|
||||||
|
|
||||||
// Postprocessing does not strictly guarantee for only turns
|
// Postprocessing does not strictly guarantee for only turns
|
||||||
const auto is_turn = [](const RouteStep &step) {
|
const auto is_turn = [](const RouteStep &step) {
|
||||||
return step.maneuver.instruction.type != TurnType::NewName &&
|
return step.maneuver.instruction.type != TurnType::NewName &&
|
||||||
step.maneuver.instruction.type != TurnType::Notification;
|
step.maneuver.instruction.type != TurnType::Notification;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto is_quick = [MIN_DURATION_NEEDED_FOR_LANE_CHANGE](const RouteStep &step) {
|
const auto is_quick = [min_duration_needed_for_lane_change](const RouteStep &step) {
|
||||||
return step.duration < MIN_DURATION_NEEDED_FOR_LANE_CHANGE;
|
return step.duration < min_duration_needed_for_lane_change;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto is_quick_turn = [&](const RouteStep &step) {
|
const auto is_quick_turn = [&](const RouteStep &step) {
|
||||||
|
@ -524,7 +524,10 @@ std::vector<RouteStep> anticipateLaneChangeForRoundabouts(std::vector<RouteStep>
|
|||||||
enter.maneuver.instruction.direction_modifier =
|
enter.maneuver.instruction.direction_modifier =
|
||||||
mirrorDirectionModifier(enter_direction);
|
mirrorDirectionModifier(enter_direction);
|
||||||
|
|
||||||
auto enterAndLeave = anticipateLaneChange({enter, leave});
|
// a roundabout is a continuous maneuver. We don't switch lanes within a roundabout, as long
|
||||||
|
// as it can be avoided.
|
||||||
|
auto enterAndLeave =
|
||||||
|
anticipateLaneChange({enter, leave}, std::numeric_limits<double>::max());
|
||||||
|
|
||||||
// Undo flipping direction on a right turn in a right-sided counter-clockwise roundabout.
|
// Undo flipping direction on a right turn in a right-sided counter-clockwise roundabout.
|
||||||
// FIXME: assumes right-side driving (counter-clockwise roundabout flow)
|
// FIXME: assumes right-side driving (counter-clockwise roundabout flow)
|
||||||
|
Loading…
Reference in New Issue
Block a user