implement basic turn handling
This commit is contained in:
parent
29fff4f51b
commit
a674028c37
@ -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;
|
||||||
|
|
||||||
|
void
|
||||||
|
handleDistinctConflict(const EdgeID via_edge, TurnCandidate &left, TurnCandidate &right) const;
|
||||||
|
|
||||||
// Type specific fallbacks
|
// 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