Skip to content

Commit 6ea9f9f

Browse files
daniel-j-hTheMarex
authored andcommitted
Consider number of lanes to cross, resolves #3025.
Lane Anticipation currently triggers on quick steps with lanes. This changeset makes the "quick" part more dynamic by taking lanes left and right of the turn into account. The reasoning for this is as follows. The user can drive on the leftmost or rightmost lane and has to cross all lanes left or right of the turn, respecitvely. We scale our threshold appropriately, which now means the threshold describes the duration the user needs for crossing _a single lane_. Note: this is a heuristic and assumes the worst case. Which in my opinion is fine to do since triggering Lane Anticipation in complex scenarios is desirable.
1 parent 434a3a6 commit 6ea9f9f

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

features/guidance/anticipate-lanes.feature

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,3 +783,38 @@ Feature: Turn Lane Guidance
783783
| waypoints | route | turns | lanes |
784784
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,turn right,arrive | ,left:false left:true none:false none:false,left:false left:true none:false none:false,left:false left:true none:false none:false,left:false left:false right:true, |
785785
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,turn left,arrive | ,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true right:false, |
786+
787+
@anticipate
788+
Scenario: Complex lane scenarios scale threshold for triggering Lane Anticipation
789+
Given the node map
790+
"""
791+
a – b – x
792+
|
793+
|
794+
|
795+
|
796+
|
797+
|
798+
|
799+
|
800+
|
801+
|
802+
c
803+
|
804+
e – d – y
805+
"""
806+
# With a grid size of 20m the duration is ~20s but our default threshold for Lane Anticipation is 15s.
807+
# The additional lanes left and right of the turn scale the threshold up so that Lane Anticipation still triggers.
808+
809+
And the ways
810+
| nodes | turn:lanes:forward | name |
811+
| ab | through\|through\|right\|right | MySt |
812+
| bx | | XSt |
813+
| bc | | MySt |
814+
| cd | left\|right | MySt |
815+
| de | | MySt |
816+
| dy | | YSt |
817+
818+
When I route I should get
819+
| waypoints | route | turns | lanes |
820+
| a,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight:false straight:false right:false right:true,left:false right:true, |

src/engine/guidance/lane_processing.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "extractor/guidance/turn_instruction.hpp"
55
#include "engine/guidance/post_processing.hpp"
66

7+
#include <algorithm>
78
#include <iterator>
89
#include <unordered_set>
910
#include <utility>
@@ -27,9 +28,26 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
2728
{
2829
// Lane anticipation works on contiguous ranges of quick steps that have lane information
2930
const auto is_quick_has_lanes = [&](const RouteStep &step) {
30-
const auto is_quick = step.duration < min_duration_needed_for_lane_change;
3131
const auto has_lanes = step.intersections.front().lanes.lanes_in_turn > 0;
32-
return has_lanes && is_quick;
32+
33+
if (!has_lanes)
34+
return false;
35+
36+
// The more unused lanes to the left and right of the turn there are, the higher
37+
// the chance the user is driving on one of those and has to cross lanes.
38+
// Scale threshold for these cases to be adaptive to the situation's complexity.
39+
//
40+
// Note: what we could do instead: do Lane Anticipation on all step pairs and then scale
41+
// the threshold based on the lanes we're constraining the user to. Would need a re-write
42+
// since at the moment we first group-by and only then do Lane Anticipation selectively.
43+
//
44+
// We do not have a source-target lane mapping, assume worst case for lanes to cross.
45+
const auto to_cross = std::max(step.NumLanesToTheRight(), step.NumLanesToTheLeft());
46+
const auto scale = 1 + to_cross;
47+
const auto threshold = scale * min_duration_needed_for_lane_change;
48+
49+
const auto is_quick = step.duration < threshold;
50+
return is_quick;
3351
};
3452

3553
using StepIter = decltype(steps)::iterator;

0 commit comments

Comments
 (0)