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); |     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}; |     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) | 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) |     if (!isBasic(instruction.type) || instruction.direction_modifier == DirectionModifier::UTurn) | ||||||
|         return 1.0; |         return 1.0; | ||||||
| 
 | 
 | ||||||
|     const double deviations[] = {0, 45, 50, 35, 10, 35, 50, 45}; |     const double deviations[] = {0, 45, 50, 30, 20, 30, 50, 45}; | ||||||
|     const double difference = getAngularPenalty(angle, instruction); |     const double difference = getAngularPenalty(angle, instruction.direction_modifier); | ||||||
|     const double max_deviation = deviations[static_cast<int>(instruction.direction_modifier)]; |     const double max_deviation = deviations[static_cast<int>(instruction.direction_modifier)]; | ||||||
|     return 1.0 - (difference / max_deviation) * (difference / max_deviation); |     return 1.0 - (difference / max_deviation) * (difference / max_deviation); | ||||||
| } | } | ||||||
| @ -281,7 +282,7 @@ inline DirectionModifier getTurnDirection(const double angle) | |||||||
|         return DirectionModifier::Right; |         return DirectionModifier::Right; | ||||||
|     if (angle >= 140 && angle < 170) |     if (angle >= 140 && angle < 170) | ||||||
|         return DirectionModifier::SlightRight; |         return DirectionModifier::SlightRight; | ||||||
|     if (angle >= 170 && angle <= 190) |     if (angle >= 165 && angle <= 195) | ||||||
|         return DirectionModifier::Straight; |         return DirectionModifier::Straight; | ||||||
|     if (angle > 190 && angle <= 220) |     if (angle > 190 && angle <= 220) | ||||||
|         return DirectionModifier::SlightLeft; |         return DirectionModifier::SlightLeft; | ||||||
| @ -295,10 +296,14 @@ inline DirectionModifier getTurnDirection(const double angle) | |||||||
| // swaps left <-> right modifier types
 | // swaps left <-> right modifier types
 | ||||||
| inline DirectionModifier mirrorDirectionModifier(const DirectionModifier modifier) | inline DirectionModifier mirrorDirectionModifier(const DirectionModifier modifier) | ||||||
| { | { | ||||||
|     const constexpr DirectionModifier results[] = { |     const constexpr DirectionModifier results[] = {DirectionModifier::UTurn, | ||||||
|         DirectionModifier::UTurn,      DirectionModifier::SharpLeft, DirectionModifier::Left, |                                                    DirectionModifier::SharpLeft, | ||||||
|         DirectionModifier::SlightLeft, DirectionModifier::Straight,  DirectionModifier::SlightRight, |                                                    DirectionModifier::Left, | ||||||
|         DirectionModifier::Right,      DirectionModifier::SharpRight}; |                                                    DirectionModifier::SlightLeft, | ||||||
|  |                                                    DirectionModifier::Straight, | ||||||
|  |                                                    DirectionModifier::SlightRight, | ||||||
|  |                                                    DirectionModifier::Right, | ||||||
|  |                                                    DirectionModifier::SharpRight}; | ||||||
|     return results[modifier]; |     return results[modifier]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -315,6 +320,17 @@ inline bool isLowPriorityRoadClass(const FunctionalRoadClass road_class) | |||||||
|            road_class == FunctionalRoadClass::SERVICE; |            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 guidance
 | ||||||
| } // namespace extractor
 | } // namespace extractor
 | ||||||
| } // namespace osrm
 | } // namespace osrm
 | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ | |||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <memory> | #include <memory> | ||||||
|  | #include <utility> | ||||||
| #include <unordered_set> | #include <unordered_set> | ||||||
| 
 | 
 | ||||||
| namespace osrm | namespace osrm | ||||||
| @ -149,11 +150,13 @@ class TurnAnalysis | |||||||
|     std::vector<TurnCandidate> handleMotorwayJunction( |     std::vector<TurnCandidate> handleMotorwayJunction( | ||||||
|         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; |         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; | ||||||
| 
 | 
 | ||||||
|     std::vector<TurnCandidate> handleFromMotorway( |     std::vector<TurnCandidate> handleFromMotorway(const NodeID from, | ||||||
|         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; |                                                   const EdgeID via_edge, | ||||||
|  |                                                   std::vector<TurnCandidate> turn_candidates) const; | ||||||
| 
 | 
 | ||||||
|     std::vector<TurnCandidate> handleMotorwayRamp( |     std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from, | ||||||
|         const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const; |                                                   const EdgeID via_edge, | ||||||
|  |                                                   std::vector<TurnCandidate> turn_candidates) const; | ||||||
| 
 | 
 | ||||||
|     // Utility function, setting basic turn types. Prepares for normal turn handling.
 |     // Utility function, setting basic turn types. Prepares for normal turn handling.
 | ||||||
|     std::vector<TurnCandidate> setTurnTypes(const NodeID from, |     std::vector<TurnCandidate> setTurnTypes(const NodeID from, | ||||||
| @ -165,20 +168,6 @@ class TurnAnalysis | |||||||
|                                                const EdgeID via_edge, |                                                const EdgeID via_edge, | ||||||
|                                                std::vector<TurnCandidate> turn_candidates) const; |                                                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
 |     // node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
 | ||||||
|     TurnInstruction AnalyzeTurn(const NodeID node_u, |     TurnInstruction AnalyzeTurn(const NodeID node_u, | ||||||
|                                 const EdgeID edge1, |                                 const EdgeID edge1, | ||||||
| @ -194,10 +183,20 @@ class TurnAnalysis | |||||||
|                     TurnCandidate ¢er, |                     TurnCandidate ¢er, | ||||||
|                     TurnCandidate &right) const; |                     TurnCandidate &right) const; | ||||||
| 
 | 
 | ||||||
|     //Type specific fallbacks
 |     void | ||||||
|  |     handleDistinctConflict(const EdgeID via_edge, TurnCandidate &left, TurnCandidate &right) const; | ||||||
|  | 
 | ||||||
|  |     // Type specific fallbacks
 | ||||||
|     std::vector<TurnCandidate> |     std::vector<TurnCandidate> | ||||||
|     fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates) const; |     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
 | }; // class TurnAnalysis
 | ||||||
| 
 | 
 | ||||||
| } // namespace guidance
 | } // 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
 |     NewName,                // no turn, but name changes
 | ||||||
|     Continue,               // remain on a street
 |     Continue,               // remain on a street
 | ||||||
|     Turn,                   // basic turn
 |     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
 |     Merge,                  // merge onto a street
 | ||||||
|     Ramp,                   // special turn (highway ramp exits)
 |     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
 |     Fork,                   // fork road splitting up
 | ||||||
|     EndOfRoad,              // T intersection
 |     EndOfRoad,              // T intersection
 | ||||||
|     EnterRoundabout,        // Entering a small Roundabout
 |     EnterRoundabout,        // Entering a small Roundabout
 | ||||||
|  | |||||||
| @ -28,23 +28,17 @@ namespace json | |||||||
| namespace detail | namespace detail | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| const constexpr char *modifier_names[] = {"uturn", | const constexpr char *modifier_names[] = {"uturn",    "sharp right", "right", "slight right", | ||||||
|                                           "sharp right", |                                           "straight", "slight left", "left",  "sharp left"}; | ||||||
|                                           "right", |  | ||||||
|                                           "slight right", |  | ||||||
|                                           "straight", |  | ||||||
|                                           "slight left", |  | ||||||
|                                           "left", |  | ||||||
|                                           "sharp left"}; |  | ||||||
| 
 | 
 | ||||||
| // translations of TurnTypes. Not all types are exposed to the outside world.
 | // translations of TurnTypes. Not all types are exposed to the outside world.
 | ||||||
| // invalid types should never be returned as part of the API
 | // invalid types should never be returned as part of the API
 | ||||||
| const constexpr char *turn_type_names[] = { | const constexpr char *turn_type_names[] = { | ||||||
|     "invalid",    "no turn",     "invalid",        "new name",    "continue",       "turn", |     "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", |     "roundabout", "invalid",     "traffic circle", "invalid",     "traffic circle", "invalid", | ||||||
|     "invalid",    "restriction", "notification"}; |     "invalid",    "restriction", "notification"}; | ||||||
| 
 |  | ||||||
| const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"}; | const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"}; | ||||||
| 
 | 
 | ||||||
| // Check whether to include a modifier in the result of the API
 | // 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; |     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) | std::string instructionTypeToString(const TurnType type) | ||||||
| { | { | ||||||
|     return turn_type_names[static_cast<std::size_t>(type)]; |     return turn_type_names[static_cast<std::size_t>(type)]; | ||||||
| @ -141,6 +152,8 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver) | |||||||
|     else |     else | ||||||
|         step_maneuver.values["type"] = detail::waypointTypeToString(maneuver.waypoint_type); |         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)) |     if (detail::isValidModifier(maneuver)) | ||||||
|         step_maneuver.values["modifier"] = |         step_maneuver.values["modifier"] = | ||||||
|             detail::instructionModifierToString(maneuver.instruction.direction_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