introduce roundabout-turns into instruction set
This commit is contained in:
@@ -22,6 +22,7 @@ const double constexpr FUZZY_ANGLE_DIFFERENCE = 20.;
|
||||
const double constexpr DISTINCTION_RATIO = 2;
|
||||
const unsigned constexpr INVALID_NAME_ID = 0;
|
||||
|
||||
const double constexpr MAX_ROUNDABOUT_INTERSECTION_RADIUS = 5;
|
||||
const double constexpr MAX_ROUNDABOUT_RADIUS = 15; // 30 m diameter as final distinction
|
||||
const double constexpr INCREASES_BY_FOURTY_PERCENT = 1.4;
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_ROUNDABOUT_HANDLER_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_ROUNDABOUT_HANDLER_HPP_
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/guidance/roundabout_type.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -37,7 +40,8 @@ class RoundaboutHandler : public IntersectionHandler
|
||||
public:
|
||||
RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table);
|
||||
const util::NameTable &name_table,
|
||||
const CompressedEdgeContainer &compressed_edge_container);
|
||||
|
||||
~RoundaboutHandler() override final;
|
||||
|
||||
@@ -61,17 +65,21 @@ class RoundaboutHandler : public IntersectionHandler
|
||||
Intersection &intersection) const;
|
||||
|
||||
// decide whether we lookk at a roundabout or a rotary
|
||||
bool isRotary(const NodeID nid) const;
|
||||
RoundaboutType getRoundaboutType(const NodeID nid) const;
|
||||
|
||||
// TODO handle bike/walk cases that allow crossing a roundabout!
|
||||
// Processing of roundabouts
|
||||
// Produces instructions to enter/exit a roundabout or to stay on it.
|
||||
// Performs the distinction between roundabout and rotaries.
|
||||
Intersection handleRoundabouts(const bool is_rotary,
|
||||
Intersection handleRoundabouts(const RoundaboutType roundabout_type,
|
||||
const EdgeID via_edge,
|
||||
const bool on_roundabout,
|
||||
const bool can_exit_roundabout,
|
||||
Intersection intersection) const;
|
||||
|
||||
bool qualifiesAsRoundaboutIntersection(const std::set<NodeID> &roundabout_nodes) const;
|
||||
|
||||
const CompressedEdgeContainer &compressed_edge_container;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_ROUNDABOUT_TYPES_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_ROUNDABOUT_TYPES_HPP_
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
enum class RoundaboutType
|
||||
{
|
||||
None, // not a roundabout
|
||||
Roundabout, // standard roundabout
|
||||
Rotary, // traffic circle (large roundabout) with dedicated name
|
||||
RoundaboutIntersection // small roundabout with distinct turns, handled as intersection
|
||||
};
|
||||
} /* namespace guidance */
|
||||
} /* namespace extractor */
|
||||
} /* namespace osrm */
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_ROUNDABOUT_TYPES_HPP_ */
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "util/bearing.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@@ -26,6 +27,8 @@ namespace extractor
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
using util::guidance::angularDeviation;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
const constexpr double DESIRED_SEGMENT_LENGTH = 10.0;
|
||||
@@ -246,12 +249,6 @@ inline double angleFromDiscreteAngle(const DiscreteAngle angle)
|
||||
return static_cast<double>(angle) * detail::discrete_angle_step_size;
|
||||
}
|
||||
|
||||
inline double angularDeviation(const double angle, const double from)
|
||||
{
|
||||
const double deviation = std::abs(angle - from);
|
||||
return std::min(360 - deviation, deviation);
|
||||
}
|
||||
|
||||
inline double getAngularPenalty(const double angle, DirectionModifier modifier)
|
||||
{
|
||||
// these are not aligned with getTurnDirection but represent an ideal center
|
||||
@@ -272,30 +269,6 @@ inline double getTurnConfidence(const double angle, TurnInstruction instruction)
|
||||
return 1.0 - (difference / max_deviation) * (difference / max_deviation);
|
||||
}
|
||||
|
||||
// Translates between angles and their human-friendly directional representation
|
||||
inline DirectionModifier getTurnDirection(const double angle)
|
||||
{
|
||||
// An angle of zero is a u-turn
|
||||
// 180 goes perfectly straight
|
||||
// 0-180 are right turns
|
||||
// 180-360 are left turns
|
||||
if (angle > 0 && angle < 60)
|
||||
return DirectionModifier::SharpRight;
|
||||
if (angle >= 60 && angle < 140)
|
||||
return DirectionModifier::Right;
|
||||
if (angle >= 140 && angle < 170)
|
||||
return DirectionModifier::SlightRight;
|
||||
if (angle >= 165 && angle <= 195)
|
||||
return DirectionModifier::Straight;
|
||||
if (angle > 190 && angle <= 220)
|
||||
return DirectionModifier::SlightLeft;
|
||||
if (angle > 220 && angle <= 300)
|
||||
return DirectionModifier::Left;
|
||||
if (angle > 300 && angle < 360)
|
||||
return DirectionModifier::SharpLeft;
|
||||
return DirectionModifier::UTurn;
|
||||
}
|
||||
|
||||
// swaps left <-> right modifier types
|
||||
inline DirectionModifier mirrorDirectionModifier(const DirectionModifier modifier)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include "extractor/guidance/roundabout_type.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -36,26 +38,30 @@ enum DirectionModifier
|
||||
// enum class TurnType : unsigned char
|
||||
enum TurnType // at the moment we can support 32 turn types, without increasing memory consumption
|
||||
{
|
||||
Invalid, // no valid turn instruction
|
||||
NoTurn, // end of segment without turn/middle of a segment
|
||||
Suppressed, // location that suppresses a turn
|
||||
NewName, // no turn, but name changes
|
||||
Continue, // remain on a street
|
||||
Turn, // basic turn
|
||||
Merge, // merge onto a street
|
||||
Ramp, // special turn (highway ramp exits)
|
||||
Fork, // fork road splitting up
|
||||
EndOfRoad, // T intersection
|
||||
EnterRoundabout, // Entering a small Roundabout
|
||||
EnterRoundaboutAtExit, // Entering a small Roundabout at a countable exit
|
||||
EnterAndExitRoundabout, // Touching a roundabout
|
||||
ExitRoundabout, // Exiting a small Roundabout
|
||||
EnterRotary, // Enter a rotary
|
||||
EnterRotaryAtExit, // Enter A Rotary at a countable exit
|
||||
EnterAndExitRotary, // Touching a rotary
|
||||
ExitRotary, // Exit a rotary
|
||||
StayOnRoundabout, // Continue on Either a small or a large Roundabout
|
||||
Notification // Travel Mode Changes`
|
||||
Invalid, // no valid turn instruction
|
||||
NewName, // no turn, but name changes
|
||||
Continue, // remain on a street
|
||||
Turn, // basic turn
|
||||
Merge, // merge onto a street
|
||||
Ramp, // special turn (highway ramp exits)
|
||||
Fork, // fork road splitting up
|
||||
EndOfRoad, // T intersection
|
||||
Notification, // Travel Mode Changes, Restrictions apply...
|
||||
EnterRoundabout, // Entering a small Roundabout
|
||||
EnterAndExitRoundabout, // Touching a roundabout
|
||||
EnterRotary, // Enter a rotary
|
||||
EnterAndExitRotary, // Touching a rotary
|
||||
EnterRoundaboutIntersection, // Entering a small Roundabout
|
||||
EnterAndExitRoundaboutIntersection, // Touching a roundabout
|
||||
NoTurn, // end of segment without turn/middle of a segment
|
||||
Suppressed, // location that suppresses a turn
|
||||
EnterRoundaboutAtExit, // Entering a small Roundabout at a countable exit
|
||||
ExitRoundabout, // Exiting a small Roundabout
|
||||
EnterRotaryAtExit, // Enter A Rotary at a countable exit
|
||||
ExitRotary, // Exit a rotary
|
||||
EnterRoundaboutIntersectionAtExit, // Entering a small Roundabout at a countable exit
|
||||
ExitRoundaboutIntersection, // Exiting a small Roundabout
|
||||
StayOnRoundabout // Continue on Either a small or a large Roundabout
|
||||
};
|
||||
|
||||
// turn angle in 1.40625 degree -> 128 == 180 degree
|
||||
@@ -80,27 +86,45 @@ struct TurnInstruction
|
||||
return TurnInstruction(TurnType::NoTurn, DirectionModifier::UTurn);
|
||||
}
|
||||
|
||||
static TurnInstruction REMAIN_ROUNDABOUT(bool is_rotary, const DirectionModifier modifier)
|
||||
static TurnInstruction REMAIN_ROUNDABOUT(const RoundaboutType, const DirectionModifier modifier)
|
||||
{
|
||||
(void)is_rotary; // staying does not require a different instruction at the moment
|
||||
return TurnInstruction(TurnType::StayOnRoundabout, modifier);
|
||||
}
|
||||
|
||||
static TurnInstruction ENTER_ROUNDABOUT(bool is_rotary, const DirectionModifier modifier)
|
||||
static TurnInstruction ENTER_ROUNDABOUT(const RoundaboutType roundabout_type,
|
||||
const DirectionModifier modifier)
|
||||
{
|
||||
return {is_rotary ? TurnType::EnterRotary : TurnType::EnterRoundabout, modifier};
|
||||
const constexpr TurnType enter_instruction[] = {
|
||||
TurnType::Invalid, TurnType::EnterRoundabout, TurnType::EnterRotary,
|
||||
TurnType::EnterRoundaboutIntersection};
|
||||
return {enter_instruction[static_cast<int>(roundabout_type)], modifier};
|
||||
}
|
||||
|
||||
static TurnInstruction EXIT_ROUNDABOUT(bool is_rotary, const DirectionModifier modifier)
|
||||
static TurnInstruction EXIT_ROUNDABOUT(const RoundaboutType roundabout_type,
|
||||
const DirectionModifier modifier)
|
||||
{
|
||||
return {is_rotary ? TurnType::ExitRotary : TurnType::ExitRoundabout, modifier};
|
||||
const constexpr TurnType exit_instruction[] = {TurnType::Invalid, TurnType::ExitRoundabout,
|
||||
TurnType::ExitRotary,
|
||||
TurnType::ExitRoundaboutIntersection};
|
||||
return {exit_instruction[static_cast<int>(roundabout_type)], modifier};
|
||||
}
|
||||
|
||||
static TurnInstruction ENTER_AND_EXIT_ROUNDABOUT(bool is_rotary,
|
||||
static TurnInstruction ENTER_AND_EXIT_ROUNDABOUT(const RoundaboutType roundabout_type,
|
||||
const DirectionModifier modifier)
|
||||
{
|
||||
return {is_rotary ? TurnType::EnterAndExitRotary : TurnType::EnterAndExitRoundabout,
|
||||
modifier};
|
||||
const constexpr TurnType exit_instruction[] = {
|
||||
TurnType::Invalid, TurnType::EnterAndExitRoundabout, TurnType::EnterAndExitRotary,
|
||||
TurnType::EnterAndExitRoundaboutIntersection};
|
||||
return {exit_instruction[static_cast<int>(roundabout_type)], modifier};
|
||||
}
|
||||
|
||||
static TurnInstruction ENTER_ROUNDABOUT_AT_EXIT(const RoundaboutType roundabout_type,
|
||||
const DirectionModifier modifier)
|
||||
{
|
||||
const constexpr TurnType enter_instruction[] = {
|
||||
TurnType::Invalid, TurnType::EnterRoundaboutAtExit, TurnType::EnterRotaryAtExit,
|
||||
TurnType::EnterRoundaboutIntersectionAtExit};
|
||||
return {enter_instruction[static_cast<int>(roundabout_type)], modifier};
|
||||
}
|
||||
|
||||
static TurnInstruction SUPPRESSED(const DirectionModifier modifier)
|
||||
|
||||
Reference in New Issue
Block a user