implement basic turn handling
This commit is contained in:
		
							parent
							
								
									4f1503c4a1
								
							
						
					
					
						commit
						b63f3cc247
					
				| @ -249,10 +249,11 @@ inline double angularDeviation(const double angle, const double from) | ||||
|     return std::min(360 - deviation, deviation); | ||||
| } | ||||
| 
 | ||||
| inline double getAngularPenalty(const double angle, TurnInstruction instruction) | ||||
| inline double getAngularPenalty(const double angle, DirectionModifier modifier) | ||||
| { | ||||
|     // these are not aligned with getTurnDirection but represent an ideal center
 | ||||
|     const double center[] = {0, 45, 90, 135, 180, 225, 270, 315}; | ||||
|     return angularDeviation(center[static_cast<int>(instruction.direction_modifier)], angle); | ||||
|     return angularDeviation(center[static_cast<int>(modifier)], angle); | ||||
| } | ||||
| 
 | ||||
| inline double getTurnConfidence(const double angle, TurnInstruction instruction) | ||||
| @ -262,8 +263,8 @@ inline double getTurnConfidence(const double angle, TurnInstruction instruction) | ||||
|     if (!isBasic(instruction.type) || instruction.direction_modifier == DirectionModifier::UTurn) | ||||
|         return 1.0; | ||||
| 
 | ||||
|     const double deviations[] = {0, 45, 50, 35, 10, 35, 50, 45}; | ||||
|     const double difference = getAngularPenalty(angle, instruction); | ||||
|     const double deviations[] = {0, 45, 50, 30, 20, 30, 50, 45}; | ||||
|     const double difference = getAngularPenalty(angle, instruction.direction_modifier); | ||||
|     const double max_deviation = deviations[static_cast<int>(instruction.direction_modifier)]; | ||||
|     return 1.0 - (difference / max_deviation) * (difference / max_deviation); | ||||
| } | ||||
| @ -281,7 +282,7 @@ inline DirectionModifier getTurnDirection(const double angle) | ||||
|         return DirectionModifier::Right; | ||||
|     if (angle >= 140 && angle < 170) | ||||
|         return DirectionModifier::SlightRight; | ||||
|     if (angle >= 170 && angle <= 190) | ||||
|     if (angle >= 165 && angle <= 195) | ||||
|         return DirectionModifier::Straight; | ||||
|     if (angle > 190 && angle <= 220) | ||||
|         return DirectionModifier::SlightLeft; | ||||
| @ -295,10 +296,14 @@ inline DirectionModifier getTurnDirection(const double angle) | ||||
| // swaps left <-> right modifier types
 | ||||
| inline DirectionModifier mirrorDirectionModifier(const DirectionModifier modifier) | ||||
| { | ||||
|     const constexpr DirectionModifier results[] = { | ||||
|         DirectionModifier::UTurn,      DirectionModifier::SharpLeft, DirectionModifier::Left, | ||||
|         DirectionModifier::SlightLeft, DirectionModifier::Straight,  DirectionModifier::SlightRight, | ||||
|         DirectionModifier::Right,      DirectionModifier::SharpRight}; | ||||
|     const constexpr DirectionModifier results[] = {DirectionModifier::UTurn, | ||||
|                                                    DirectionModifier::SharpLeft, | ||||
|                                                    DirectionModifier::Left, | ||||
|                                                    DirectionModifier::SlightLeft, | ||||
|                                                    DirectionModifier::Straight, | ||||
|                                                    DirectionModifier::SlightRight, | ||||
|                                                    DirectionModifier::Right, | ||||
|                                                    DirectionModifier::SharpRight}; | ||||
|     return results[modifier]; | ||||
| } | ||||
| 
 | ||||
| @ -315,6 +320,17 @@ inline bool isLowPriorityRoadClass(const FunctionalRoadClass road_class) | ||||
|            road_class == FunctionalRoadClass::SERVICE; | ||||
| } | ||||
| 
 | ||||
| inline bool isDistinct(const DirectionModifier first, const DirectionModifier second) | ||||
| { | ||||
|     if ((first + 1) % detail::num_direction_modifiers == second) | ||||
|         return false; | ||||
| 
 | ||||
|     if ((second + 1) % detail::num_direction_modifiers == first) | ||||
|         return false; | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| } // namespace guidance
 | ||||
| } // namespace extractor
 | ||||
| } // namespace osrm
 | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
| #include <unordered_set> | ||||
| 
 | ||||
| namespace osrm | ||||
| @ -149,11 +150,13 @@ class TurnAnalysis | ||||
|     std::vector<TurnCandidate> handleMotorwayJunction( | ||||
|         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     std::vector<TurnCandidate> handleFromMotorway( | ||||
|         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; | ||||
|     std::vector<TurnCandidate> handleFromMotorway(const NodeID from, | ||||
|                                                   const EdgeID via_edge, | ||||
|                                                   std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     std::vector<TurnCandidate> handleMotorwayRamp( | ||||
|         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; | ||||
|     std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from, | ||||
|                                                   const EdgeID via_edge, | ||||
|                                                   std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     // Utility function, setting basic turn types. Prepares for normal turn handling.
 | ||||
|     std::vector<TurnCandidate> setTurnTypes(const NodeID from, | ||||
| @ -165,20 +168,6 @@ class TurnAnalysis | ||||
|                                                const EdgeID via_edge, | ||||
|                                                std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     // Old fallbacks, to be removed
 | ||||
|     std::vector<TurnCandidate> optimizeRamps(const EdgeID via_edge, | ||||
|                                              std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     std::vector<TurnCandidate> optimizeCandidates(const EdgeID via_eid, | ||||
|                                                   std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     bool isObviousChoice(const EdgeID via_eid, | ||||
|                          const std::size_t turn_index, | ||||
|                          const std::vector<TurnCandidate> &turn_candidates) const; | ||||
| 
 | ||||
|     std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid, | ||||
|                                              std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     // node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
 | ||||
|     TurnInstruction AnalyzeTurn(const NodeID node_u, | ||||
|                                 const EdgeID edge1, | ||||
| @ -194,10 +183,20 @@ class TurnAnalysis | ||||
|                     TurnCandidate ¢er, | ||||
|                     TurnCandidate &right) const; | ||||
| 
 | ||||
|     //Type specific fallbacks
 | ||||
|     void | ||||
|     handleDistinctConflict(const EdgeID via_edge, TurnCandidate &left, TurnCandidate &right) const; | ||||
| 
 | ||||
|     // Type specific fallbacks
 | ||||
|     std::vector<TurnCandidate> | ||||
|     fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates) const; | ||||
| 
 | ||||
|     //Classification
 | ||||
|     std::size_t findObviousTurn( const EdgeID via_edge, const std::vector<TurnCandidate> &turn_candidates) const; | ||||
|     std::pair<std::size_t,std::size_t> findFork( const EdgeID via_edge, const std::vector<TurnCandidate> &turn_candidates) const; | ||||
| 
 | ||||
|     std::vector<TurnCandidate> assignLeftTurns( const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates, const std::size_t starting_at ) const; | ||||
|     std::vector<TurnCandidate> assignRightTurns( const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates, const std::size_t up_to ) const; | ||||
| 
 | ||||
| }; // class TurnAnalysis
 | ||||
| 
 | ||||
| } // namespace guidance
 | ||||
|  | ||||
| @ -42,8 +42,16 @@ enum TurnType // at the moment we can support 32 turn types, without increasing | ||||
|     NewName,                // no turn, but name changes
 | ||||
|     Continue,               // remain on a street
 | ||||
|     Turn,                   // basic turn
 | ||||
|     FirstTurn,              // First of x turns
 | ||||
|     SecondTurn,             // Second of x turns
 | ||||
|     ThirdTurn,              // Third of x turns
 | ||||
|     FourthTurn,             // Fourth of x turns
 | ||||
|     Merge,                  // merge onto a street
 | ||||
|     Ramp,                   // special turn (highway ramp exits)
 | ||||
|     FirstRamp,              // first turn onto a ramp
 | ||||
|     SecondRamp,             // second turn onto a ramp
 | ||||
|     ThirdRamp,              // third turn onto a ramp
 | ||||
|     FourthRamp,             // fourth turn onto a ramp
 | ||||
|     Fork,                   // fork road splitting up
 | ||||
|     EndOfRoad,              // T intersection
 | ||||
|     EnterRoundabout,        // Entering a small Roundabout
 | ||||
|  | ||||
| @ -28,23 +28,17 @@ namespace json | ||||
| namespace detail | ||||
| { | ||||
| 
 | ||||
| const constexpr char *modifier_names[] = {"uturn", | ||||
|                                           "sharp right", | ||||
|                                           "right", | ||||
|                                           "slight right", | ||||
|                                           "straight", | ||||
|                                           "slight left", | ||||
|                                           "left", | ||||
|                                           "sharp left"}; | ||||
| const constexpr char *modifier_names[] = {"uturn",    "sharp right", "right", "slight right", | ||||
|                                           "straight", "slight left", "left",  "sharp left"}; | ||||
| 
 | ||||
| // translations of TurnTypes. Not all types are exposed to the outside world.
 | ||||
| // invalid types should never be returned as part of the API
 | ||||
| const constexpr char *turn_type_names[] = { | ||||
|     "invalid",    "no turn",     "invalid",        "new name",    "continue",       "turn", | ||||
|     "merge",      "ramp",        "fork",           "end of road", "roundabout",     "invalid", | ||||
|     "turn",       "turn",        "turn",           "merge",       "ramp",           "ramp", | ||||
|     "ramp",       "ramp",        "fork",           "end of road", "roundabout",     "invalid", | ||||
|     "roundabout", "invalid",     "traffic circle", "invalid",     "traffic circle", "invalid", | ||||
|     "invalid",    "restriction", "notification"}; | ||||
| 
 | ||||
| const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"}; | ||||
| 
 | ||||
| // Check whether to include a modifier in the result of the API
 | ||||
| @ -56,6 +50,23 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver) | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| inline bool isMultiTurn(const TurnType type) | ||||
| { | ||||
|     return (type == TurnType::FirstTurn || type == TurnType::SecondTurn || | ||||
|             type == TurnType::ThirdTurn); | ||||
| } | ||||
| 
 | ||||
| inline std::string getCount(const TurnType type) | ||||
| { | ||||
|     if (type == TurnType::FirstTurn) | ||||
|         return "1"; | ||||
|     if (type == TurnType::SecondTurn) | ||||
|         return "2"; | ||||
|     if (type == TurnType::ThirdTurn) | ||||
|         return "3"; | ||||
|     return "0"; | ||||
| } | ||||
| 
 | ||||
| std::string instructionTypeToString(const TurnType type) | ||||
| { | ||||
|     return turn_type_names[static_cast<std::size_t>(type)]; | ||||
| @ -141,6 +152,8 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver) | ||||
|     else | ||||
|         step_maneuver.values["type"] = detail::waypointTypeToString(maneuver.waypoint_type); | ||||
| 
 | ||||
|     if (detail::isMultiTurn(maneuver.instruction.type)) | ||||
|         step_maneuver.values["count"] = detail::getCount(maneuver.instruction.type); | ||||
|     if (detail::isValidModifier(maneuver)) | ||||
|         step_maneuver.values["modifier"] = | ||||
|             detail::instructionModifierToString(maneuver.instruction.direction_modifier); | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user