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