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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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