introduce roundabout-turns into instruction set

This commit is contained in:
Moritz Kobitzsch
2016-04-18 13:41:19 +02:00
parent 8d68d4c050
commit 1544a08ea2
19 changed files with 791 additions and 141 deletions
+9 -4
View File
@@ -1,5 +1,5 @@
#ifndef OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#define OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#ifndef OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_
#define OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_
#include "extractor/guidance/turn_instruction.hpp"
#include "util/bearing.hpp"
@@ -25,9 +25,12 @@ inline bool entersRoundabout(const extractor::guidance::TurnInstruction instruct
{
return (instruction.type == extractor::guidance::TurnType::EnterRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterRotary ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
}
@@ -35,8 +38,10 @@ inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruct
{
return (instruction.type == extractor::guidance::TurnType::ExitRoundabout ||
instruction.type == extractor::guidance::TurnType::ExitRotary ||
instruction.type == extractor::guidance::TurnType::ExitRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
}
inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction)
@@ -68,4 +73,4 @@ inline double angularDeviation(const double angle, const double from)
} // namespace engine
} // namespace osrm
#endif /* OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ */
#endif /* OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_ */
+1
View File
@@ -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_ */
+3 -30
View File
@@ -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)
{
+53 -29
View File
@@ -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)
+48
View File
@@ -0,0 +1,48 @@
#ifndef OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#define OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
/* A set of tools required for guidance in both pre and post-processing */
#include "extractor/guidance/turn_instruction.hpp"
namespace osrm
{
namespace util
{
namespace guidance
{
inline double angularDeviation(const double angle, const double from)
{
const double deviation = std::abs(angle - from);
return std::min(360 - deviation, deviation);
}
inline extractor::guidance::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 extractor::guidance::DirectionModifier::SharpRight;
if (angle >= 60 && angle < 140)
return extractor::guidance::DirectionModifier::Right;
if (angle >= 140 && angle < 170)
return extractor::guidance::DirectionModifier::SlightRight;
if (angle >= 165 && angle <= 195)
return extractor::guidance::DirectionModifier::Straight;
if (angle > 190 && angle <= 220)
return extractor::guidance::DirectionModifier::SlightLeft;
if (angle > 220 && angle <= 300)
return extractor::guidance::DirectionModifier::Left;
if (angle > 300 && angle < 360)
return extractor::guidance::DirectionModifier::SharpLeft;
return extractor::guidance::DirectionModifier::UTurn;
}
} /* namespace guidance */
} /* namespace util */
} /* namespace osrm */
#endif /* OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ */