From 8a4af59838d30c5856682c5879b45b9482853626 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 27 Oct 2022 21:13:57 +0200 Subject: [PATCH 01/18] wip --- features/car/stop_sign_penalties.feature | 39 +++++ features/support/hooks.js | 2 +- .../extractor/edge_based_graph_factory.hpp | 3 + include/extractor/extraction_containers.hpp | 16 ++ include/extractor/extraction_node.hpp | 8 + include/extractor/extraction_turn.hpp | 4 +- include/extractor/extractor.hpp | 2 + include/extractor/graph_compressor.hpp | 1 + .../extractor/node_based_graph_factory.hpp | 5 +- include/extractor/stop_sign_class.hpp | 0 include/extractor/traffic_lights.hpp | 31 ++++ include/extractor/traffic_signals.hpp | 11 +- profiles/car.lua | 11 ++ profiles/lib/give_way.lua | 23 +++ profiles/lib/stop_sign.lua | 21 +++ src/extractor/edge_based_graph_factory.cpp | 6 +- src/extractor/extraction_containers.cpp | 140 ++++++++++++++++++ src/extractor/extractor.cpp | 6 + src/extractor/extractor_callbacks.cpp | 9 ++ src/extractor/graph_compressor.cpp | 19 ++- src/extractor/node_based_graph_factory.cpp | 8 +- src/extractor/scripting_environment_lua.cpp | 49 +++++- taginfo.json | 1 + 23 files changed, 401 insertions(+), 14 deletions(-) create mode 100644 features/car/stop_sign_penalties.feature create mode 100644 include/extractor/stop_sign_class.hpp create mode 100644 profiles/lib/give_way.lua create mode 100644 profiles/lib/stop_sign.lua diff --git a/features/car/stop_sign_penalties.feature b/features/car/stop_sign_penalties.feature new file mode 100644 index 00000000000..1cccc30d805 --- /dev/null +++ b/features/car/stop_sign_penalties.feature @@ -0,0 +1,39 @@ +@routing @car @stop_sign +Feature: Car - Handle stop signs + + Background: + Given the profile "car" + + Scenario: Car - Encounters a stop sign + Given the node map + """ + a-1-b-2-c + + d-3-e-4-f + + g-h-i k-l-m + | | + j n + + """ + + And the ways + | nodes | highway | + | abc | primary | + | def | primary | + | ghi | primary | + | klm | primary | + | hj | primary | + | ln | primary | + + And the nodes + | node | highway | + | e | stop | + | l | stop | + + When I route I should get + | from | to | time | # | + | 1 | 2 | 11.1s | no turn with no stop sign | + | 3 | 4 | 13.1s | no turn with stop sign | + | g | j | 18.7s | turn with no stop sign | + | k | n | 20.7s | turn with stop sign | \ No newline at end of file diff --git a/features/support/hooks.js b/features/support/hooks.js index 01c2e6e8921..4a035554502 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -51,7 +51,7 @@ module.exports = function () { .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); // uncomment to get path to logfile - // console.log(' Writing logging output to ' + this.scenarioLogFile); + console.log(' Writing logging output to ' + this.scenarioLogFile); }); this.After((scenario, callback) => { diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index 9dc0cadf215..0ad5b16be2b 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -70,6 +70,7 @@ class EdgeBasedGraphFactory const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, const std::vector &coordinates, const NameTable &name_table, const std::unordered_set &segregated_edges, @@ -136,6 +137,8 @@ class EdgeBasedGraphFactory const std::unordered_set &m_barrier_nodes; const TrafficSignals &m_traffic_signals; + const StopSigns &m_stop_signs; + const CompressedEdgeContainer &m_compressed_edge_container; const NameTable &name_table; diff --git a/include/extractor/extraction_containers.hpp b/include/extractor/extraction_containers.hpp index 6f643aed009..03f24bec64a 100644 --- a/include/extractor/extraction_containers.hpp +++ b/include/extractor/extraction_containers.hpp @@ -30,17 +30,24 @@ class ExtractionContainers using ReferencedWays = std::unordered_map; using ReferencedTrafficSignals = std::pair, std::unordered_multimap>; + using ReferencedStopSigns = + std::pair, std::unordered_multimap>; + // The relationship between way and nodes is lost during node preparation. // We identify the ways and nodes relevant to restrictions/overrides/signals prior to // node processing so that they can be referenced in the preparation phase. ReferencedWays IdentifyRestrictionWays(); ReferencedWays IdentifyManeuverOverrideWays(); ReferencedTrafficSignals IdentifyTrafficSignals(); + ReferencedStopSigns IdentifyStopSigns(); + void PrepareNodes(); void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways); void PrepareRestrictions(const ReferencedWays &restriction_ways); void PrepareTrafficSignals(const ReferencedTrafficSignals &referenced_traffic_signals); + void PrepareStopSigns(const ReferencedStopSigns &referenced_stop_signs); + void PrepareEdges(ScriptingEnvironment &scripting_environment); void WriteCharData(const std::string &file_name); @@ -55,6 +62,8 @@ class ExtractionContainers using WayIDVector = std::vector; using WayNodeIDOffsets = std::vector; using InputTrafficSignal = std::pair; + using InputStopSign = std::pair; + using InputGiveWay = std::pair; std::vector barrier_nodes; NodeIDVector used_node_id_list; @@ -72,6 +81,13 @@ class ExtractionContainers std::vector external_traffic_signals; TrafficSignals internal_traffic_signals; + + std::vector external_stop_signs; + StopSigns internal_stop_signs; + + std::vector external_give_ways; + GiveWaySigns internal_give_ways; + std::vector used_edges; // List of restrictions (conditional and unconditional) before we transform them into the diff --git a/include/extractor/extraction_node.hpp b/include/extractor/extraction_node.hpp index 9a146d4d3cc..8872605dbe4 100644 --- a/include/extractor/extraction_node.hpp +++ b/include/extractor/extraction_node.hpp @@ -2,22 +2,30 @@ #define EXTRACTION_NODE_HPP #include "traffic_lights.hpp" +#include namespace osrm { namespace extractor { + struct ExtractionNode { ExtractionNode() : traffic_lights(TrafficLightClass::NONE), barrier(false) {} void clear() { traffic_lights = TrafficLightClass::NONE; + stop_sign = StopSign::Direction::NONE; + give_way = GiveWay::Direction::NONE; barrier = false; } TrafficLightClass::Direction traffic_lights; bool barrier; + + + StopSign::Direction stop_sign; + GiveWay::Direction give_way; }; } // namespace extractor } // namespace osrm diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 9e32712d349..9dfe163f80c 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -51,6 +51,7 @@ struct ExtractionTurn int number_of_roads, bool is_u_turn, bool has_traffic_light, + bool has_stop_sign, bool is_left_hand_driving, bool source_restricted, TravelMode source_mode, @@ -75,7 +76,7 @@ struct ExtractionTurn const std::vector &roads_on_the_right, const std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving), + has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), source_mode(source_mode), source_is_motorway(source_is_motorway), source_is_link(source_is_link), @@ -100,6 +101,7 @@ struct ExtractionTurn const int number_of_roads; const bool is_u_turn; const bool has_traffic_light; + const bool has_stop_sign; const bool is_left_hand_driving; // source info diff --git a/include/extractor/extractor.hpp b/include/extractor/extractor.hpp index fb32af8a096..a2fc2d05c91 100644 --- a/include/extractor/extractor.hpp +++ b/include/extractor/extractor.hpp @@ -67,6 +67,7 @@ class Extractor std::vector turn_restrictions; std::vector unresolved_maneuver_overrides; TrafficSignals traffic_signals; + StopSigns stop_signs; std::unordered_set barriers; std::vector osm_coordinates; extractor::PackedOSMIDs osm_node_ids; @@ -87,6 +88,7 @@ class Extractor const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, const RestrictionGraph &restriction_graph, const std::unordered_set &segregated_edges, const NameTable &name_table, diff --git a/include/extractor/graph_compressor.hpp b/include/extractor/graph_compressor.hpp index 1b6d8159a3e..3196cabfd69 100644 --- a/include/extractor/graph_compressor.hpp +++ b/include/extractor/graph_compressor.hpp @@ -27,6 +27,7 @@ class GraphCompressor public: void Compress(const std::unordered_set &barrier_nodes, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index 7c0a70f2e92..aca2aaa114c 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -42,6 +42,8 @@ class NodeBasedGraphFactory std::vector &turn_restrictions, std::vector &maneuver_overrides, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, + std::unordered_set &&barriers, std::vector &&coordinates, extractor::PackedOSMIDs &&osm_node_ids, @@ -73,7 +75,8 @@ class NodeBasedGraphFactory void Compress(ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, - const TrafficSignals &traffic_signals); + const TrafficSignals &traffic_signals, + const StopSigns &stop_signs); // Most ways are bidirectional, making the geometry in forward and backward direction the same, // except for reversal. We make use of this fact by keeping only one representation of the diff --git a/include/extractor/stop_sign_class.hpp b/include/extractor/stop_sign_class.hpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/include/extractor/traffic_lights.hpp b/include/extractor/traffic_lights.hpp index 0c8aa6d001e..cf78509e96f 100644 --- a/include/extractor/traffic_lights.hpp +++ b/include/extractor/traffic_lights.hpp @@ -1,6 +1,7 @@ #ifndef OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_ #define OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_ +#include namespace osrm { namespace extractor @@ -19,6 +20,36 @@ enum Direction }; } // namespace TrafficLightClass +// Stop Signs tagged on nodes can be present or not. In addition Stop Signs have +// an optional way direction they apply to. If the direction is unknown from the +// data we have to compute by checking the distance to the next intersection. +// +// Impl. detail: namespace + enum instead of enum class to make Luabind happy +namespace StopSign +{ +enum Direction : std::uint8_t +{ + NONE = 0, + DIRECTION_ALL = 1, + DIRECTION_FORWARD = 2, + DIRECTION_REVERSE = 3 +}; +} + +// Give Way is the complement to priority roads. Tagging is the same as Stop Signs. +// See explanation above. +namespace GiveWay +{ +enum Direction : std::uint8_t +{ + NONE = 0, + DIRECTION_ALL = 1, + DIRECTION_FORWARD = 2, + DIRECTION_REVERSE = 3 +}; +} + + } // namespace extractor } // namespace osrm diff --git a/include/extractor/traffic_signals.hpp b/include/extractor/traffic_signals.hpp index 36913092c3d..5e303ccb9ae 100644 --- a/include/extractor/traffic_signals.hpp +++ b/include/extractor/traffic_signals.hpp @@ -11,7 +11,8 @@ namespace osrm namespace extractor { -struct TrafficSignals +// TODO: better naming +struct RoadObjects { std::unordered_set bidirectional_nodes; std::unordered_set, boost::hash>> @@ -22,6 +23,14 @@ struct TrafficSignals return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0; } }; + +struct TrafficSignals final : public RoadObjects {}; + +// TODO: better naming ? +struct StopSigns final : public RoadObjects {}; +struct GiveWaySigns final : public RoadObjects {}; + + } // namespace extractor } // namespace osrm diff --git a/profiles/car.lua b/profiles/car.lua index 770805962d5..37f131807af 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -7,6 +7,8 @@ Sequence = require('lib/sequence') Handlers = require("lib/way_handlers") Relations = require("lib/relations") TrafficSignal = require("lib/traffic_signal") +StopSign = require("lib/stop_sign") +GiveWay = require("lib/give_way") find_access_tag = require("lib/access").find_access_tag limit = require("lib/maxspeed").limit Utils = require("lib/utils") @@ -362,6 +364,12 @@ function process_node(profile, node, result, relations) -- check if node is a traffic light result.traffic_lights = TrafficSignal.get_value(node) + + -- check if node is stop sign + result.stop_sign = StopSign.get_value(node) + + -- check if node is a give way sign + result.give_way = GiveWay.get_value(node) end function process_way(profile, way, result, relations) @@ -472,6 +480,9 @@ function process_turn(profile, turn) if turn.has_traffic_light then turn.duration = profile.properties.traffic_light_penalty + elseif turn.has_stop_sign then + -- TODO: use another constant + turn.duration = profile.properties.traffic_light_penalty end if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then diff --git a/profiles/lib/give_way.lua b/profiles/lib/give_way.lua new file mode 100644 index 00000000000..d8bb9863d99 --- /dev/null +++ b/profiles/lib/give_way.lua @@ -0,0 +1,23 @@ +local GiveWay = {} + +function GiveWay.get_value(node) + local tag = node:get_value_by_key("highway") + if "give_way" == tag then + local direction = node:get_value_by_key("direction") + if direction then + if "forward" == direction then + return give_way.direction_forward + end + if "backward" == direction then + return give_way.direction_reverse + end + end + -- return give_way.direction_all + return true + end + -- return give_way.none + return false +end + +return GiveWay + diff --git a/profiles/lib/stop_sign.lua b/profiles/lib/stop_sign.lua new file mode 100644 index 00000000000..e805c5a39e3 --- /dev/null +++ b/profiles/lib/stop_sign.lua @@ -0,0 +1,21 @@ +local StopSign = {} + +function StopSign.get_value(node) + local tag = node:get_value_by_key("highway") + if "stop" == tag then + local direction = node:get_value_by_key("direction") + if direction then + if "forward" == direction then + return stop_sign.direction_forward + end + if "backward" == direction then + return stop_sign.direction_reverse + end + end + return stop_sign.direction_all + end + return stop_sign.none +end + +return StopSign + diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index a0a8561b73d..862466a11ae 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -60,6 +60,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, const std::vector &coordinates, const NameTable &name_table, const std::unordered_set &segregated_edges, @@ -67,7 +68,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( : m_edge_based_node_container(node_data_container), m_connectivity_checksum(0), m_number_of_edge_based_nodes(0), m_coordinates(coordinates), m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes), - m_traffic_signals(traffic_signals), m_compressed_edge_container(compressed_edge_container), + m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), m_compressed_edge_container(compressed_edge_container), name_table(name_table), segregated_edges(segregated_edges), lane_description_map(lane_description_map) { @@ -643,6 +644,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // the traffic signal direction was potentially ambiguously annotated on the junction // node But we'll check anyway. const auto is_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node); + const auto is_stop_sign = m_stop_signs.HasSignal(from_node, intersection_node); + std::cerr << "IS STOP SIGN " << is_stop_sign << std::endl; const auto is_uturn = guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn; @@ -652,6 +655,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - is_uturn, is_uturn, is_traffic_light, + is_stop_sign, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) .is_left_hand_driving, // source info diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 553968d6f18..1738ecfb920 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -413,11 +413,14 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme const auto restriction_ways = IdentifyRestrictionWays(); const auto maneuver_override_ways = IdentifyManeuverOverrideWays(); const auto traffic_signals = IdentifyTrafficSignals(); + const auto stop_signs = IdentifyStopSigns(); PrepareNodes(); PrepareEdges(scripting_environment); PrepareTrafficSignals(traffic_signals); + PrepareStopSigns(stop_signs); + PrepareManeuverOverrides(maneuver_override_ways); PrepareRestrictions(restriction_ways); WriteCharData(name_file_name); @@ -979,6 +982,54 @@ void ExtractionContainers::PrepareTrafficSignals( log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s"; } +// TODO: copy-paste +void ExtractionContainers::PrepareStopSigns(const ReferencedStopSigns &referenced_stop_signs) { + const auto &bidirectional_signal_nodes = referenced_stop_signs.first; + const auto &unidirectional_signal_segments = referenced_stop_signs.second; + + util::UnbufferedLog log; + log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size() + << " bidirectional, " << unidirectional_signal_segments.size() + << " unidirectional nodes ..."; + TIMER_START(prepare_traffic_signals); + + std::unordered_set bidirectional; + std::unordered_set, boost::hash>> + unidirectional; + + for (const auto &osm_node : bidirectional_signal_nodes) + { + const auto node_id = mapExternalToInternalNodeID( + used_node_id_list.begin(), used_node_id_list.end(), osm_node); + if (node_id != SPECIAL_NODEID) + { + bidirectional.insert(node_id); + } + } + for (const auto &to_from : unidirectional_signal_segments) + { + const auto to_node_id = mapExternalToInternalNodeID( + used_node_id_list.begin(), used_node_id_list.end(), to_from.first); + const auto from_node_id = mapExternalToInternalNodeID( + used_node_id_list.begin(), used_node_id_list.end(), to_from.second); + if (from_node_id != SPECIAL_NODEID && to_node_id != SPECIAL_NODEID) + { + unidirectional.insert({from_node_id, to_node_id}); + } + } + + internal_stop_signs.bidirectional_nodes = std::move(bidirectional); + internal_stop_signs.unidirectional_segments = std::move(unidirectional); + + TIMER_STOP(prepare_traffic_signals); + log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s"; +} + +// void ExtractionContainers::PrepareGiveWays(const ReferencedGiveWays &referenced_give_ways) { + +// } + + void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways) { auto const osm_node_to_internal_nbn = [&](auto const osm_node) { @@ -1159,6 +1210,95 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa return restriction_ways; } +// TODO: copy-paste +ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSigns() +{ + util::UnbufferedLog log; + log << "Collecting traffic signal information on " << external_stop_signs.size() + << " signals..."; + TIMER_START(identify_traffic_signals); + + // Temporary store for nodes containing a unidirectional signal. + std::unordered_map unidirectional_signals; + + // For each node that has a unidirectional traffic signal, we store the node(s) + // that lead up to the signal. + std::unordered_multimap signal_segments; + + std::unordered_set bidirectional_signals; + + const auto mark_signals = [&](auto const &traffic_signal) { + if (traffic_signal.second == StopSign::DIRECTION_FORWARD || + traffic_signal.second == StopSign::DIRECTION_REVERSE) + { + unidirectional_signals.insert({traffic_signal.first, traffic_signal.second}); + } + else + { + BOOST_ASSERT(traffic_signal.second == StopSign::DIRECTION_ALL); + bidirectional_signals.insert(traffic_signal.first); + } + }; + std::for_each(external_stop_signs.begin(), external_stop_signs.end(), mark_signals); + + // Extract all the segments that lead up to unidirectional traffic signals. + const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) { + const auto node_start_offset = + used_node_id_list.begin() + way_node_id_offsets[way_list_idx]; + const auto node_end_offset = + used_node_id_list.begin() + way_node_id_offsets[way_list_idx + 1]; + + for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++) + { + const auto sig = unidirectional_signals.find(*node_it); + if (sig != unidirectional_signals.end()) + { + if (sig->second == StopSign::DIRECTION_FORWARD) + { + if (node_it != node_start_offset) + { + // Previous node leads to signal + signal_segments.insert({*node_it, *(node_it - 1)}); + } + } + else + { + BOOST_ASSERT(sig->second == StopSign::DIRECTION_REVERSE); + if (node_it + 1 != node_end_offset) + { + // Next node leads to signal + signal_segments.insert({*node_it, *(node_it + 1)}); + } + } + } + } + }; + util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments); + + util::for_each_pair( + signal_segments, [](const auto pair_a, const auto pair_b) { + if (pair_a.first == pair_b.first) + { + // If a node is appearing multiple times in this map, then it's ambiguous. + // The node is an intersection and the traffic direction is being use for multiple + // ways. We can't be certain of the original intent. See: + // https://wiki.openstreetmap.org/wiki/Key:traffic_signals:direction + + // OSRM will include the signal for all intersecting ways in the specified + // direction, but let's flag this as a concern. + util::Log(logWARNING) + << "OSM node " << pair_a.first + << " has a unidirectional traffic signal ambiguously applied to multiple ways"; + } + }); + + TIMER_STOP(identify_traffic_signals); + log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s"; + + return {std::move(bidirectional_signals), std::move(signal_segments)}; +} + + ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTrafficSignals() { util::UnbufferedLog log; diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 687b35b5352..14764dd2f98 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -226,6 +226,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) parsed_osm_data.turn_restrictions, parsed_osm_data.unresolved_maneuver_overrides, parsed_osm_data.traffic_signals, + parsed_osm_data.stop_signs, + std::move(parsed_osm_data.barriers), std::move(parsed_osm_data.osm_coordinates), std::move(parsed_osm_data.osm_node_ids), @@ -283,6 +285,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) node_based_graph_factory.GetCompressedEdges(), barrier_nodes, parsed_osm_data.traffic_signals, + parsed_osm_data.stop_signs, restriction_graph, segregated_edges, name_table, @@ -649,6 +652,7 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting std::move(extraction_containers.turn_restrictions), std::move(extraction_containers.internal_maneuver_overrides), std::move(extraction_containers.internal_traffic_signals), + std::move(extraction_containers.internal_stop_signs), std::move(extraction_containers.used_barrier_nodes), std::move(osm_coordinates), std::move(osm_node_ids), @@ -725,6 +729,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph( const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, const RestrictionGraph &restriction_graph, const std::unordered_set &segregated_edges, const NameTable &name_table, @@ -746,6 +751,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph( compressed_edge_container, barrier_nodes, traffic_signals, + stop_signs, coordinates, name_table, segregated_edges, diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 7cecd763e2b..c6a0269b66d 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -82,6 +82,15 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, { external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights}); } + // if (result_node.give_way != GiveWay::Direction::NONE) + // { + // external_memory.external_give_ways.push_back({id, result_node.give_way}); + // } + if (result_node.stop_sign != StopSign::Direction::NONE) + { + std::cerr << "FOUND STOP SIGN\n"; + external_memory.external_stop_signs.push_back({id, result_node.stop_sign}); + } } void ExtractorCallbacks::ProcessRestriction(const InputTurnRestriction &restriction) diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 517d3e8d794..e1ebbe317fc 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -23,6 +23,7 @@ static constexpr int SECOND_TO_DECISECOND = 10; void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, @@ -212,11 +213,15 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, const bool has_forward_signal = traffic_signals.HasSignal(node_u, node_v); const bool has_reverse_signal = traffic_signals.HasSignal(node_w, node_v); + const bool has_forward_stop_sign = stop_signs.HasSignal(node_u, node_v); + const bool has_reverse_stop_sign = stop_signs.HasSignal(node_w, node_v); + + // TODO: can we have a case when we have both traffic signal and stop sign? how should we handle it? EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT; EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT; - if (has_forward_signal || has_reverse_signal) + if (has_forward_signal || has_reverse_signal || has_forward_stop_sign || has_reverse_stop_sign) { // we cannot handle this as node penalty, if it depends on turn direction if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted) @@ -228,7 +233,8 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, ExtractionTurn extraction_turn(0, 2, false, - true, + has_forward_signal || has_reverse_signal, + has_forward_stop_sign || has_reverse_stop_sign, false, false, TRAVEL_MODE_DRIVING, @@ -258,8 +264,11 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, EdgeWeight &weight_penalty) { if (signal) { + std::cerr << "DUR = " << extraction_turn.duration << " WEIGHT = " << extraction_turn.weight << std::endl; duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND; weight_penalty = extraction_turn.weight * weight_multiplier; + + std::cerr << "DUR = " << duration_penalty << " WEIGHT = " << weight_penalty << std::endl; } }; @@ -269,6 +278,12 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, update_direction_penalty(has_reverse_signal, reverse_node_duration_penalty, reverse_node_weight_penalty); + update_direction_penalty(has_forward_stop_sign, + forward_node_duration_penalty, + forward_node_weight_penalty); + update_direction_penalty(has_reverse_stop_sign, + reverse_node_duration_penalty, + reverse_node_weight_penalty); } // Get weights before graph is modified diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 5edc447154f..42a4dfebabe 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -1,6 +1,7 @@ #include "extractor/node_based_graph_factory.hpp" #include "extractor/files.hpp" #include "extractor/graph_compressor.hpp" +#include "extractor/traffic_signals.hpp" #include "storage/io.hpp" #include "util/log.hpp" @@ -20,6 +21,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( std::vector &turn_restrictions, std::vector &maneuver_overrides, const TrafficSignals &traffic_signals, + const StopSigns &stop_signs, std::unordered_set &&barriers, std::vector &&coordinates, extractor::PackedOSMIDs &&osm_node_ids, @@ -29,7 +31,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids)) { BuildCompressedOutputGraph(edge_list); - Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals); + Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs); CompressGeometry(); CompressAnnotationData(); } @@ -74,11 +76,13 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector &turn_restrictions, std::vector &maneuver_overrides, - const TrafficSignals &traffic_signals) + const TrafficSignals &traffic_signals, + const StopSigns &stop_signs) { GraphCompressor graph_compressor; graph_compressor.Compress(barriers, traffic_signals, + stop_signs, scripting_environment, turn_restrictions, maneuver_overrides, diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index dca80fc447f..d598ca1d56d 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -294,6 +294,24 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) extractor::TrafficLightClass::DIRECTION_FORWARD, "direction_reverse", extractor::TrafficLightClass::DIRECTION_REVERSE); + context.state.new_enum("stop_sign", + "none", + extractor::StopSign::NONE, + "direction_all", + extractor::StopSign::DIRECTION_ALL, + "direction_forward", + extractor::StopSign::DIRECTION_FORWARD, + "direction_reverse", + extractor::StopSign::DIRECTION_REVERSE); + context.state.new_enum("give_way", + "none", + extractor::GiveWay::NONE, + "direction_all", + extractor::GiveWay::DIRECTION_ALL, + "direction_forward", + extractor::GiveWay::DIRECTION_FORWARD, + "direction_reverse", + extractor::GiveWay::DIRECTION_REVERSE); context.state.new_usertype( "ResultNode", @@ -318,6 +336,18 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) node.traffic_lights = val; } }), + "stop_sign", + sol::property([](const ExtractionNode &node) { return node.stop_sign; }, + [](ExtractionNode &node, const sol::object &obj) { + BOOST_ASSERT(obj.is()); + node.stop_sign = obj.as(); + }), + "give_way", + sol::property([](const ExtractionNode &node) { return node.give_way; }, + [](ExtractionNode &node, const sol::object &obj) { + BOOST_ASSERT(obj.is()); + node.give_way = obj.as(); + }), "barrier", &ExtractionNode::barrier); @@ -640,6 +670,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) }), "has_traffic_light", &ExtractionTurn::has_traffic_light, + "has_stop_sign", + &ExtractionTurn::has_stop_sign, "weight", &ExtractionTurn::weight, "duration", @@ -765,7 +797,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::has_traffic_light, "is_left_hand_driving", &ExtractionTurn::is_left_hand_driving, - "source_restricted", &ExtractionTurn::source_restricted, "source_mode", @@ -1125,15 +1156,23 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) case 2: if (context.has_turn_penalty_function) { + std::cerr << "GOT TURN " << turn.has_stop_sign << " " << turn.has_traffic_light << std::endl; + context.turn_function(context.profile_table, std::ref(turn)); // Turn weight falls back to the duration value in deciseconds // or uses the extracted unit-less weight value - if (context.properties.fallback_to_duration) + if (context.properties.fallback_to_duration) { + std::cerr << "FALLBACK\n"; turn.weight = turn.duration; - else - // cap turn weight to max turn weight, which depend on weight precision + } + + else { + // cap turn weight to max turn weight, which depend on weight precision turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight()); + std::cerr << "NO FALLBACK " << turn.weight << std::endl; + } + } break; @@ -1171,7 +1210,7 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) } // Add traffic light penalty, back-compatibility of api_version=0 - if (turn.has_traffic_light) + if (turn.has_traffic_light || turn.has_stop_sign) turn.duration += context.properties.GetTrafficSignalPenalty(); // Turn weight falls back to the duration value in deciseconds diff --git a/taginfo.json b/taginfo.json index 358845d80c9..3107a5c61c0 100644 --- a/taginfo.json +++ b/taginfo.json @@ -125,6 +125,7 @@ {"key": "side_road", "value": "rotary", "description": "gets speed penalty"}, {"key": "route", "object_types": ["way"]}, {"key": "highway", "value": "traffic_signals", "object_types": ["node"]}, + {"key": "highway", "value": "stop", "object_types": ["node"]}, {"key": "highway", "value": "crossing", "object_types": ["node"]}, {"key": "access", "value": "yes"}, {"key": "access", "value": "motorcar"}, From 7f635f2ed6e61720436a92fd7726824f2bfbc87e Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 27 Oct 2022 21:39:21 +0200 Subject: [PATCH 02/18] Take stop signs into account during routing --- profiles/car.lua | 1 + src/extractor/scripting_environment_lua.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/profiles/car.lua b/profiles/car.lua index 37f131807af..4910a1fa7c4 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -485,6 +485,7 @@ function process_turn(profile, turn) turn.duration = profile.properties.traffic_light_penalty end + if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then if turn.angle >= 0 then turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias))) diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index d598ca1d56d..43884efa556 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -670,8 +670,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) }), "has_traffic_light", &ExtractionTurn::has_traffic_light, - "has_stop_sign", - &ExtractionTurn::has_stop_sign, "weight", &ExtractionTurn::weight, "duration", @@ -795,6 +793,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::is_u_turn, "has_traffic_light", &ExtractionTurn::has_traffic_light, + "has_stop_sign", + &ExtractionTurn::has_stop_sign, "is_left_hand_driving", &ExtractionTurn::is_left_hand_driving, "source_restricted", From 72ea34f3b7adf7da5203e04c60ad6210c90d741b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 28 Oct 2022 09:47:43 +0200 Subject: [PATCH 03/18] Take stop signs into account during routing --- features/options/extract/turn_function.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index eecb2960492..b9cf792f669 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -1,7 +1,7 @@ @routing @testbot @turn_function Feature: Turn Function Information - + // TODO Background: Given the profile file """ From 36f3a5eec83678711526f28605c2fa326f4b2dba Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 28 Oct 2022 22:04:02 +0200 Subject: [PATCH 04/18] Take stop signs into account during routing --- .../extractor/edge_based_graph_factory.hpp | 8 +-- include/extractor/extraction_containers.hpp | 33 +++++------ include/extractor/extraction_node.hpp | 16 +++--- include/extractor/extractor.hpp | 8 +-- include/extractor/extractor_callbacks.hpp | 2 + include/extractor/graph_compressor.hpp | 4 +- .../extractor/node_based_graph_factory.hpp | 8 +-- include/extractor/traffic_lights.hpp | 56 ------------------- include/extractor/traffic_signals.hpp | 30 ++++++---- profiles/lib/give_way.lua | 10 ++-- profiles/lib/stop_sign.lua | 8 +-- src/extractor/edge_based_graph_factory.cpp | 8 +-- src/extractor/extraction_containers.cpp | 32 +++++------ src/extractor/extractor.cpp | 4 +- src/extractor/extractor_callbacks.cpp | 4 +- src/extractor/graph_compressor.cpp | 14 +++-- src/extractor/node_based_graph_factory.cpp | 8 +-- src/extractor/scripting_environment_lua.cpp | 52 ++++++++--------- unit_tests/extractor/graph_compressor.cpp | 10 ++-- .../extractor/intersection_analysis_tests.cpp | 6 +- 20 files changed, 132 insertions(+), 189 deletions(-) delete mode 100644 include/extractor/traffic_lights.hpp diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index 0ad5b16be2b..5d0a6898852 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -69,8 +69,8 @@ class EdgeBasedGraphFactory EdgeBasedNodeDataContainer &node_data_container, const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, const std::vector &coordinates, const NameTable &name_table, const std::unordered_set &segregated_edges, @@ -136,8 +136,8 @@ class EdgeBasedGraphFactory const util::NodeBasedDynamicGraph &m_node_based_graph; const std::unordered_set &m_barrier_nodes; - const TrafficSignals &m_traffic_signals; - const StopSigns &m_stop_signs; + const TrafficFlowControlNodes &m_traffic_signals; + const TrafficFlowControlNodes &m_stop_signs; const CompressedEdgeContainer &m_compressed_edge_container; diff --git a/include/extractor/extraction_containers.hpp b/include/extractor/extraction_containers.hpp index 03f24bec64a..3b44125480f 100644 --- a/include/extractor/extraction_containers.hpp +++ b/include/extractor/extraction_containers.hpp @@ -8,7 +8,6 @@ #include "extractor/scripting_environment.hpp" #include "storage/tar_fwd.hpp" -#include "traffic_lights.hpp" #include "traffic_signals.hpp" #include @@ -28,25 +27,22 @@ namespace extractor class ExtractionContainers { using ReferencedWays = std::unordered_map; - using ReferencedTrafficSignals = + using ReferencedTrafficFlowControlNodes = std::pair, std::unordered_multimap>; - using ReferencedStopSigns = - std::pair, std::unordered_multimap>; - // The relationship between way and nodes is lost during node preparation. // We identify the ways and nodes relevant to restrictions/overrides/signals prior to // node processing so that they can be referenced in the preparation phase. ReferencedWays IdentifyRestrictionWays(); ReferencedWays IdentifyManeuverOverrideWays(); - ReferencedTrafficSignals IdentifyTrafficSignals(); - ReferencedStopSigns IdentifyStopSigns(); + ReferencedTrafficFlowControlNodes IdentifyTrafficSignals(); + ReferencedTrafficFlowControlNodes IdentifyStopSigns(); void PrepareNodes(); void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways); void PrepareRestrictions(const ReferencedWays &restriction_ways); - void PrepareTrafficSignals(const ReferencedTrafficSignals &referenced_traffic_signals); - void PrepareStopSigns(const ReferencedStopSigns &referenced_stop_signs); + void PrepareTrafficSignals(const ReferencedTrafficFlowControlNodes &referenced_traffic_signals); + void PrepareStopSigns(const ReferencedTrafficFlowControlNodes &referenced_stop_signs); void PrepareEdges(ScriptingEnvironment &scripting_environment); @@ -61,10 +57,10 @@ class ExtractionContainers using NameOffsets = std::vector; using WayIDVector = std::vector; using WayNodeIDOffsets = std::vector; - using InputTrafficSignal = std::pair; - using InputStopSign = std::pair; - using InputGiveWay = std::pair; + using InputTrafficFlowControlNode = std::pair; + + std::vector barrier_nodes; NodeIDVector used_node_id_list; NodeVector all_nodes_list; @@ -78,15 +74,14 @@ class ExtractionContainers unsigned max_internal_node_id; - std::vector external_traffic_signals; - TrafficSignals internal_traffic_signals; - + std::vector external_traffic_signals; + TrafficFlowControlNodes internal_traffic_signals; - std::vector external_stop_signs; - StopSigns internal_stop_signs; + std::vector external_stop_signs; + TrafficFlowControlNodes internal_stop_signs; - std::vector external_give_ways; - GiveWaySigns internal_give_ways; + std::vector external_give_ways; + TrafficFlowControlNodes internal_give_ways; std::vector used_edges; diff --git a/include/extractor/extraction_node.hpp b/include/extractor/extraction_node.hpp index 8872605dbe4..f5418bf30c1 100644 --- a/include/extractor/extraction_node.hpp +++ b/include/extractor/extraction_node.hpp @@ -1,7 +1,7 @@ #ifndef EXTRACTION_NODE_HPP #define EXTRACTION_NODE_HPP -#include "traffic_lights.hpp" +#include "traffic_signals.hpp" #include namespace osrm @@ -12,20 +12,20 @@ namespace extractor struct ExtractionNode { - ExtractionNode() : traffic_lights(TrafficLightClass::NONE), barrier(false) {} + ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {} void clear() { - traffic_lights = TrafficLightClass::NONE; - stop_sign = StopSign::Direction::NONE; - give_way = GiveWay::Direction::NONE; + traffic_lights = TrafficFlowControlNodeDirection::NONE; + stop_sign = TrafficFlowControlNodeDirection::NONE; + give_way = TrafficFlowControlNodeDirection::NONE; barrier = false; } - TrafficLightClass::Direction traffic_lights; + TrafficFlowControlNodeDirection traffic_lights; bool barrier; - StopSign::Direction stop_sign; - GiveWay::Direction give_way; + TrafficFlowControlNodeDirection stop_sign; + TrafficFlowControlNodeDirection give_way; }; } // namespace extractor } // namespace osrm diff --git a/include/extractor/extractor.hpp b/include/extractor/extractor.hpp index a2fc2d05c91..13c149171e4 100644 --- a/include/extractor/extractor.hpp +++ b/include/extractor/extractor.hpp @@ -66,8 +66,8 @@ class Extractor LaneDescriptionMap turn_lane_map; std::vector turn_restrictions; std::vector unresolved_maneuver_overrides; - TrafficSignals traffic_signals; - StopSigns stop_signs; + TrafficFlowControlNodes traffic_signals; + TrafficFlowControlNodes stop_signs; std::unordered_set barriers; std::vector osm_coordinates; extractor::PackedOSMIDs osm_node_ids; @@ -87,8 +87,8 @@ class Extractor const std::vector &coordinates, const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, const RestrictionGraph &restriction_graph, const std::unordered_set &segregated_edges, const NameTable &name_table, diff --git a/include/extractor/extractor_callbacks.hpp b/include/extractor/extractor_callbacks.hpp index 9939a49631c..87bb0abcd38 100644 --- a/include/extractor/extractor_callbacks.hpp +++ b/include/extractor/extractor_callbacks.hpp @@ -10,6 +10,7 @@ #include #include +#include namespace osmium { @@ -72,6 +73,7 @@ class ExtractorCallbacks bool fallback_to_duration; bool force_split_edges; + public: using ClassesMap = std::unordered_map; diff --git a/include/extractor/graph_compressor.hpp b/include/extractor/graph_compressor.hpp index 3196cabfd69..2d33c8adcb1 100644 --- a/include/extractor/graph_compressor.hpp +++ b/include/extractor/graph_compressor.hpp @@ -26,8 +26,8 @@ class GraphCompressor public: void Compress(const std::unordered_set &barrier_nodes, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index aca2aaa114c..e5821df35fa 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -41,8 +41,8 @@ class NodeBasedGraphFactory NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, std::unordered_set &&barriers, std::vector &&coordinates, @@ -75,8 +75,8 @@ class NodeBasedGraphFactory void Compress(ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs); + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs); // Most ways are bidirectional, making the geometry in forward and backward direction the same, // except for reversal. We make use of this fact by keeping only one representation of the diff --git a/include/extractor/traffic_lights.hpp b/include/extractor/traffic_lights.hpp deleted file mode 100644 index cf78509e96f..00000000000 --- a/include/extractor/traffic_lights.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_ -#define OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_ - -#include -namespace osrm -{ -namespace extractor -{ - -namespace TrafficLightClass -{ -// The traffic light annotation is extracted from node tags. -// The directions in which the traffic light applies are relative to the way containing the node. -enum Direction -{ - NONE = 0, - DIRECTION_ALL = 1, - DIRECTION_FORWARD = 2, - DIRECTION_REVERSE = 3 -}; -} // namespace TrafficLightClass - -// Stop Signs tagged on nodes can be present or not. In addition Stop Signs have -// an optional way direction they apply to. If the direction is unknown from the -// data we have to compute by checking the distance to the next intersection. -// -// Impl. detail: namespace + enum instead of enum class to make Luabind happy -namespace StopSign -{ -enum Direction : std::uint8_t -{ - NONE = 0, - DIRECTION_ALL = 1, - DIRECTION_FORWARD = 2, - DIRECTION_REVERSE = 3 -}; -} - -// Give Way is the complement to priority roads. Tagging is the same as Stop Signs. -// See explanation above. -namespace GiveWay -{ -enum Direction : std::uint8_t -{ - NONE = 0, - DIRECTION_ALL = 1, - DIRECTION_FORWARD = 2, - DIRECTION_REVERSE = 3 -}; -} - - -} // namespace extractor -} // namespace osrm - -#endif // OSRM_EXTRACTOR_TRAFFIC_LIGHTS_DATA_HPP_ diff --git a/include/extractor/traffic_signals.hpp b/include/extractor/traffic_signals.hpp index 5e303ccb9ae..2753a35d084 100644 --- a/include/extractor/traffic_signals.hpp +++ b/include/extractor/traffic_signals.hpp @@ -11,26 +11,36 @@ namespace osrm namespace extractor { -// TODO: better naming -struct RoadObjects +// Stop Signs tagged on nodes can be present or not. In addition Stop Signs have +// an optional way direction they apply to. If the direction is unknown from the +// data we have to compute by checking the distance to the next intersection. +// +// Impl. detail: namespace + enum instead of enum class to make Luabind happy + + +// The traffic light annotation is extracted from node tags. +// The directions in which the traffic light applies are relative to the way containing the node. +enum class TrafficFlowControlNodeDirection : std::uint8_t +{ + NONE = 0, + ALL = 1, + FORWARD = 2, + REVERSE = 3 +}; + +// represents traffic lights, stop signs, give way signs, etc. +struct TrafficFlowControlNodes { std::unordered_set bidirectional_nodes; std::unordered_set, boost::hash>> unidirectional_segments; - inline bool HasSignal(NodeID from, NodeID to) const + inline bool Has(NodeID from, NodeID to) const { return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0; } }; -struct TrafficSignals final : public RoadObjects {}; - -// TODO: better naming ? -struct StopSigns final : public RoadObjects {}; -struct GiveWaySigns final : public RoadObjects {}; - - } // namespace extractor } // namespace osrm diff --git a/profiles/lib/give_way.lua b/profiles/lib/give_way.lua index d8bb9863d99..527092ced88 100644 --- a/profiles/lib/give_way.lua +++ b/profiles/lib/give_way.lua @@ -6,17 +6,15 @@ function GiveWay.get_value(node) local direction = node:get_value_by_key("direction") if direction then if "forward" == direction then - return give_way.direction_forward + return traffic_flow_control_direction.direction_forward end if "backward" == direction then - return give_way.direction_reverse + return traffic_flow_control_direction.direction_reverse end end - -- return give_way.direction_all - return true + return traffic_flow_control_direction.direction_all end - -- return give_way.none - return false + return traffic_flow_control_direction.none end return GiveWay diff --git a/profiles/lib/stop_sign.lua b/profiles/lib/stop_sign.lua index e805c5a39e3..368dfb98adf 100644 --- a/profiles/lib/stop_sign.lua +++ b/profiles/lib/stop_sign.lua @@ -6,15 +6,15 @@ function StopSign.get_value(node) local direction = node:get_value_by_key("direction") if direction then if "forward" == direction then - return stop_sign.direction_forward + return traffic_flow_control_direction.direction_forward end if "backward" == direction then - return stop_sign.direction_reverse + return traffic_flow_control_direction.direction_reverse end end - return stop_sign.direction_all + return traffic_flow_control_direction.direction_all end - return stop_sign.none + return traffic_flow_control_direction.none end return StopSign diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 862466a11ae..d53d16372bf 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -59,8 +59,8 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( EdgeBasedNodeDataContainer &node_data_container, const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, const std::vector &coordinates, const NameTable &name_table, const std::unordered_set &segregated_edges, @@ -643,8 +643,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // In theory we shouldn't get a directed traffic light on a turn, as it indicates that // the traffic signal direction was potentially ambiguously annotated on the junction // node But we'll check anyway. - const auto is_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node); - const auto is_stop_sign = m_stop_signs.HasSignal(from_node, intersection_node); + const auto is_traffic_light = m_traffic_signals.Has(from_node, intersection_node); + const auto is_stop_sign = m_stop_signs.Has(from_node, intersection_node); std::cerr << "IS STOP SIGN " << is_stop_sign << std::endl; const auto is_uturn = guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn; diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 1738ecfb920..24e7785b5aa 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -939,7 +939,7 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr } void ExtractionContainers::PrepareTrafficSignals( - const ExtractionContainers::ReferencedTrafficSignals &referenced_traffic_signals) + const ReferencedTrafficFlowControlNodes &referenced_traffic_signals) { const auto &bidirectional_signal_nodes = referenced_traffic_signals.first; const auto &unidirectional_signal_segments = referenced_traffic_signals.second; @@ -983,7 +983,7 @@ void ExtractionContainers::PrepareTrafficSignals( } // TODO: copy-paste -void ExtractionContainers::PrepareStopSigns(const ReferencedStopSigns &referenced_stop_signs) { +void ExtractionContainers::PrepareStopSigns(const ReferencedTrafficFlowControlNodes &referenced_stop_signs) { const auto &bidirectional_signal_nodes = referenced_stop_signs.first; const auto &unidirectional_signal_segments = referenced_stop_signs.second; @@ -1211,7 +1211,7 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa } // TODO: copy-paste -ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSigns() +ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::IdentifyStopSigns() { util::UnbufferedLog log; log << "Collecting traffic signal information on " << external_stop_signs.size() @@ -1219,7 +1219,7 @@ ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSign TIMER_START(identify_traffic_signals); // Temporary store for nodes containing a unidirectional signal. - std::unordered_map unidirectional_signals; + std::unordered_map unidirectional_signals; // For each node that has a unidirectional traffic signal, we store the node(s) // that lead up to the signal. @@ -1228,14 +1228,14 @@ ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSign std::unordered_set bidirectional_signals; const auto mark_signals = [&](auto const &traffic_signal) { - if (traffic_signal.second == StopSign::DIRECTION_FORWARD || - traffic_signal.second == StopSign::DIRECTION_REVERSE) + if (traffic_signal.second == TrafficFlowControlNodeDirection::FORWARD || + traffic_signal.second == TrafficFlowControlNodeDirection::REVERSE) { unidirectional_signals.insert({traffic_signal.first, traffic_signal.second}); } else { - BOOST_ASSERT(traffic_signal.second == StopSign::DIRECTION_ALL); + BOOST_ASSERT(traffic_signal.second == TrafficFlowControlNodeDirection::ALL); bidirectional_signals.insert(traffic_signal.first); } }; @@ -1253,7 +1253,7 @@ ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSign const auto sig = unidirectional_signals.find(*node_it); if (sig != unidirectional_signals.end()) { - if (sig->second == StopSign::DIRECTION_FORWARD) + if (sig->second == TrafficFlowControlNodeDirection::FORWARD) { if (node_it != node_start_offset) { @@ -1263,7 +1263,7 @@ ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSign } else { - BOOST_ASSERT(sig->second == StopSign::DIRECTION_REVERSE); + BOOST_ASSERT(sig->second == TrafficFlowControlNodeDirection::REVERSE); if (node_it + 1 != node_end_offset) { // Next node leads to signal @@ -1299,7 +1299,7 @@ ExtractionContainers::ReferencedStopSigns ExtractionContainers::IdentifyStopSign } -ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTrafficSignals() +ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::IdentifyTrafficSignals() { util::UnbufferedLog log; log << "Collecting traffic signal information on " << external_traffic_signals.size() @@ -1307,7 +1307,7 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra TIMER_START(identify_traffic_signals); // Temporary store for nodes containing a unidirectional signal. - std::unordered_map unidirectional_signals; + std::unordered_map unidirectional_signals; // For each node that has a unidirectional traffic signal, we store the node(s) // that lead up to the signal. @@ -1316,14 +1316,14 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra std::unordered_set bidirectional_signals; const auto mark_signals = [&](auto const &traffic_signal) { - if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD || - traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE) + if (traffic_signal.second == TrafficFlowControlNodeDirection::FORWARD || + traffic_signal.second == TrafficFlowControlNodeDirection::REVERSE) { unidirectional_signals.insert({traffic_signal.first, traffic_signal.second}); } else { - BOOST_ASSERT(traffic_signal.second == TrafficLightClass::DIRECTION_ALL); + BOOST_ASSERT(traffic_signal.second == TrafficFlowControlNodeDirection::ALL); bidirectional_signals.insert(traffic_signal.first); } }; @@ -1341,7 +1341,7 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra const auto sig = unidirectional_signals.find(*node_it); if (sig != unidirectional_signals.end()) { - if (sig->second == TrafficLightClass::DIRECTION_FORWARD) + if (sig->second == TrafficFlowControlNodeDirection::FORWARD) { if (node_it != node_start_offset) { @@ -1351,7 +1351,7 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra } else { - BOOST_ASSERT(sig->second == TrafficLightClass::DIRECTION_REVERSE); + BOOST_ASSERT(sig->second == TrafficFlowControlNodeDirection::REVERSE); if (node_it + 1 != node_end_offset) { // Next node leads to signal diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 14764dd2f98..733bc3b4902 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -728,8 +728,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph( const std::vector &coordinates, const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, const RestrictionGraph &restriction_graph, const std::unordered_set &segregated_edges, const NameTable &name_table, diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index c6a0269b66d..8fe07198b4a 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -78,7 +78,7 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, { external_memory.barrier_nodes.push_back(id); } - if (result_node.traffic_lights != TrafficLightClass::NONE) + if (result_node.traffic_lights != TrafficFlowControlNodeDirection::NONE) { external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights}); } @@ -86,7 +86,7 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, // { // external_memory.external_give_ways.push_back({id, result_node.give_way}); // } - if (result_node.stop_sign != StopSign::Direction::NONE) + if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE) { std::cerr << "FOUND STOP SIGN\n"; external_memory.external_stop_signs.push_back({id, result_node.stop_sign}); diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index e1ebbe317fc..1b1d2cd2335 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -22,8 +22,8 @@ namespace extractor static constexpr int SECOND_TO_DECISECOND = 10; void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, @@ -210,11 +210,11 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, rev_edge_data2.annotation_data, rev_edge_data1.annotation_data); // Add node penalty when compress edge crosses a traffic signal - const bool has_forward_signal = traffic_signals.HasSignal(node_u, node_v); - const bool has_reverse_signal = traffic_signals.HasSignal(node_w, node_v); + const bool has_forward_signal = traffic_signals.Has(node_u, node_v); + const bool has_reverse_signal = traffic_signals.Has(node_w, node_v); - const bool has_forward_stop_sign = stop_signs.HasSignal(node_u, node_v); - const bool has_reverse_stop_sign = stop_signs.HasSignal(node_w, node_v); + const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); + const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); // TODO: can we have a case when we have both traffic signal and stop sign? how should we handle it? EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; @@ -258,6 +258,8 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, roads_on_the_left); scripting_environment.ProcessTurn(extraction_turn); + std::cerr << "HAS STOP SIGN = " << extraction_turn.has_stop_sign << " " << extraction_turn.duration << std::endl; + auto update_direction_penalty = [&extraction_turn, weight_multiplier](bool signal, EdgeDuration &duration_penalty, diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 42a4dfebabe..b00173b7870 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -20,8 +20,8 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs, + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs, std::unordered_set &&barriers, std::vector &&coordinates, extractor::PackedOSMIDs &&osm_node_ids, @@ -76,8 +76,8 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector &turn_restrictions, std::vector &maneuver_overrides, - const TrafficSignals &traffic_signals, - const StopSigns &stop_signs) + const TrafficFlowControlNodes &traffic_signals, + const TrafficFlowControlNodes &stop_signs) { GraphCompressor graph_compressor; graph_compressor.Compress(barriers, diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 43884efa556..1670d948b57 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -284,35 +284,26 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) [&context, &get_location_tag](const osmium::Node &node, const char *key) { return get_location_tag(context, node.location(), key); }); - + // just for backward compatibility + // TODO: remove in v6 context.state.new_enum("traffic_lights", "none", - extractor::TrafficLightClass::NONE, + extractor::TrafficFlowControlNodeDirection::NONE, "direction_all", - extractor::TrafficLightClass::DIRECTION_ALL, + extractor::TrafficFlowControlNodeDirection::ALL, "direction_forward", - extractor::TrafficLightClass::DIRECTION_FORWARD, + extractor::TrafficFlowControlNodeDirection::FORWARD, "direction_reverse", - extractor::TrafficLightClass::DIRECTION_REVERSE); - context.state.new_enum("stop_sign", + extractor::TrafficFlowControlNodeDirection::REVERSE); + context.state.new_enum("traffic_flow_control_direction", "none", - extractor::StopSign::NONE, + extractor::TrafficFlowControlNodeDirection::NONE, "direction_all", - extractor::StopSign::DIRECTION_ALL, + extractor::TrafficFlowControlNodeDirection::ALL, "direction_forward", - extractor::StopSign::DIRECTION_FORWARD, + extractor::TrafficFlowControlNodeDirection::FORWARD, "direction_reverse", - extractor::StopSign::DIRECTION_REVERSE); - context.state.new_enum("give_way", - "none", - extractor::GiveWay::NONE, - "direction_all", - extractor::GiveWay::DIRECTION_ALL, - "direction_forward", - extractor::GiveWay::DIRECTION_FORWARD, - "direction_reverse", - extractor::GiveWay::DIRECTION_REVERSE); - + extractor::TrafficFlowControlNodeDirection::REVERSE); context.state.new_usertype( "ResultNode", "traffic_lights", @@ -324,29 +315,29 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) // state to the node is converted to the class enum // TODO: Make a breaking API change and remove this option. bool val = obj.as(); - node.traffic_lights = (val) ? TrafficLightClass::DIRECTION_ALL - : TrafficLightClass::NONE; + node.traffic_lights = (val) ? TrafficFlowControlNodeDirection::ALL + : TrafficFlowControlNodeDirection::NONE; return; } - BOOST_ASSERT(obj.is()); + BOOST_ASSERT(obj.is()); { - TrafficLightClass::Direction val = - obj.as(); + TrafficFlowControlNodeDirection val = + obj.as(); node.traffic_lights = val; } }), "stop_sign", sol::property([](const ExtractionNode &node) { return node.stop_sign; }, [](ExtractionNode &node, const sol::object &obj) { - BOOST_ASSERT(obj.is()); - node.stop_sign = obj.as(); + BOOST_ASSERT(obj.is()); + node.stop_sign = obj.as(); }), "give_way", sol::property([](const ExtractionNode &node) { return node.give_way; }, [](ExtractionNode &node, const sol::object &obj) { - BOOST_ASSERT(obj.is()); - node.give_way = obj.as(); + BOOST_ASSERT(obj.is()); + node.give_way = obj.as(); }), "barrier", &ExtractionNode::barrier); @@ -1170,7 +1161,8 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) else { // cap turn weight to max turn weight, which depend on weight precision turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight()); - std::cerr << "NO FALLBACK " << turn.weight << std::endl; + std::cerr << "NO FALLBACK " << turn.weight << " " << turn.duration << std::endl; + } } diff --git a/unit_tests/extractor/graph_compressor.cpp b/unit_tests/extractor/graph_compressor.cpp index 559bde7d60a..b57792da38e 100644 --- a/unit_tests/extractor/graph_compressor.cpp +++ b/unit_tests/extractor/graph_compressor.cpp @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(long_road_test) GraphCompressor compressor; std::unordered_set barrier_nodes; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector restrictions; std::vector annotations(1); CompressedEdgeContainer container; @@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(loop_test) GraphCompressor compressor; std::unordered_set barrier_nodes; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector restrictions; CompressedEdgeContainer container; std::vector annotations(1); @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(t_intersection) GraphCompressor compressor; std::unordered_set barrier_nodes; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector annotations(1); std::vector restrictions; CompressedEdgeContainer container; @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(street_name_changes) GraphCompressor compressor; std::unordered_set barrier_nodes; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector annotations(2); std::vector restrictions; CompressedEdgeContainer container; @@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(direction_changes) GraphCompressor compressor; std::unordered_set barrier_nodes; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector annotations(1); std::vector restrictions; CompressedEdgeContainer container; diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index 40cdece819b..b1ee0dc9582 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -19,7 +19,7 @@ using Graph = util::NodeBasedDynamicGraph; BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) { std::unordered_set barrier_nodes{6}; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector annotations{ {EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}, {EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}}; @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) { std::unordered_set barrier_nodes; - TrafficSignals traffic_lights; + TrafficFlowControlNodes traffic_lights; std::vector annotations; std::vector restrictions; CompressedEdgeContainer container; @@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) { std::unordered_set barrier_nodes{1}; - TrafficSignals traffic_lights = {{2}, {}}; + TrafficFlowControlNodes traffic_lights = {{2}, {}}; std::vector annotations(1); std::vector restrictions; CompressedEdgeContainer container; From 3558ec9db46284e3a16a35cfaf87394e07f121f7 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 28 Oct 2022 22:16:00 +0200 Subject: [PATCH 05/18] Take stop signs into account during routing --- .../extractor/edge_based_graph_factory.hpp | 2 +- include/extractor/extraction_containers.hpp | 22 +- include/extractor/extraction_node.hpp | 2 - include/extractor/extraction_turn.hpp | 3 +- include/extractor/extractor_callbacks.hpp | 1 - .../extractor/node_based_graph_factory.hpp | 2 +- include/extractor/traffic_signals.hpp | 1 - src/extractor/edge_based_graph_factory.cpp | 6 +- src/extractor/extraction_containers.cpp | 216 ++++-------------- src/extractor/extractor.cpp | 2 +- src/extractor/graph_compressor.cpp | 17 +- src/extractor/node_based_graph_factory.cpp | 3 +- src/extractor/scripting_environment_lua.cpp | 15 +- 13 files changed, 82 insertions(+), 210 deletions(-) diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index 5d0a6898852..9e0a77b66b2 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -138,7 +138,7 @@ class EdgeBasedGraphFactory const std::unordered_set &m_barrier_nodes; const TrafficFlowControlNodes &m_traffic_signals; const TrafficFlowControlNodes &m_stop_signs; - + const CompressedEdgeContainer &m_compressed_edge_container; const NameTable &name_table; diff --git a/include/extractor/extraction_containers.hpp b/include/extractor/extraction_containers.hpp index 3b44125480f..45eb2a270a7 100644 --- a/include/extractor/extraction_containers.hpp +++ b/include/extractor/extraction_containers.hpp @@ -26,6 +26,10 @@ namespace extractor */ class ExtractionContainers { + public: + using InputTrafficFlowControlNode = std::pair; + + private: using ReferencedWays = std::unordered_map; using ReferencedTrafficFlowControlNodes = std::pair, std::unordered_multimap>; @@ -34,15 +38,16 @@ class ExtractionContainers // node processing so that they can be referenced in the preparation phase. ReferencedWays IdentifyRestrictionWays(); ReferencedWays IdentifyManeuverOverrideWays(); - ReferencedTrafficFlowControlNodes IdentifyTrafficSignals(); - ReferencedTrafficFlowControlNodes IdentifyStopSigns(); - + + ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes( + const std::vector &external_stop_signs); void PrepareNodes(); void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways); void PrepareRestrictions(const ReferencedWays &restriction_ways); - void PrepareTrafficSignals(const ReferencedTrafficFlowControlNodes &referenced_traffic_signals); - void PrepareStopSigns(const ReferencedTrafficFlowControlNodes &referenced_stop_signs); + void PrepareTrafficFlowControlNodes( + const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes, + TrafficFlowControlNodes &internal_traffic_control_nodes); void PrepareEdges(ScriptingEnvironment &scripting_environment); @@ -57,10 +62,7 @@ class ExtractionContainers using NameOffsets = std::vector; using WayIDVector = std::vector; using WayNodeIDOffsets = std::vector; - using InputTrafficFlowControlNode = std::pair; - - std::vector barrier_nodes; NodeIDVector used_node_id_list; NodeVector all_nodes_list; @@ -79,10 +81,10 @@ class ExtractionContainers std::vector external_stop_signs; TrafficFlowControlNodes internal_stop_signs; - + std::vector external_give_ways; TrafficFlowControlNodes internal_give_ways; - + std::vector used_edges; // List of restrictions (conditional and unconditional) before we transform them into the diff --git a/include/extractor/extraction_node.hpp b/include/extractor/extraction_node.hpp index f5418bf30c1..2a8d4fa2a13 100644 --- a/include/extractor/extraction_node.hpp +++ b/include/extractor/extraction_node.hpp @@ -9,7 +9,6 @@ namespace osrm namespace extractor { - struct ExtractionNode { ExtractionNode() : traffic_lights(TrafficFlowControlNodeDirection::NONE), barrier(false) {} @@ -23,7 +22,6 @@ struct ExtractionNode TrafficFlowControlNodeDirection traffic_lights; bool barrier; - TrafficFlowControlNodeDirection stop_sign; TrafficFlowControlNodeDirection give_way; }; diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 9dfe163f80c..41b7224b344 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -76,7 +76,8 @@ struct ExtractionTurn const std::vector &roads_on_the_right, const std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), is_left_hand_driving(is_left_hand_driving), + has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), + is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), source_mode(source_mode), source_is_motorway(source_is_motorway), source_is_link(source_is_link), diff --git a/include/extractor/extractor_callbacks.hpp b/include/extractor/extractor_callbacks.hpp index 87bb0abcd38..d556b29ba1c 100644 --- a/include/extractor/extractor_callbacks.hpp +++ b/include/extractor/extractor_callbacks.hpp @@ -73,7 +73,6 @@ class ExtractorCallbacks bool fallback_to_duration; bool force_split_edges; - public: using ClassesMap = std::unordered_map; diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index e5821df35fa..5308b31ca20 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -43,7 +43,7 @@ class NodeBasedGraphFactory std::vector &maneuver_overrides, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, - + std::unordered_set &&barriers, std::vector &&coordinates, extractor::PackedOSMIDs &&osm_node_ids, diff --git a/include/extractor/traffic_signals.hpp b/include/extractor/traffic_signals.hpp index 2753a35d084..5a797ceb89a 100644 --- a/include/extractor/traffic_signals.hpp +++ b/include/extractor/traffic_signals.hpp @@ -17,7 +17,6 @@ namespace extractor // // Impl. detail: namespace + enum instead of enum class to make Luabind happy - // The traffic light annotation is extracted from node tags. // The directions in which the traffic light applies are relative to the way containing the node. enum class TrafficFlowControlNodeDirection : std::uint8_t diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index d53d16372bf..0232c991048 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -68,9 +68,9 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( : m_edge_based_node_container(node_data_container), m_connectivity_checksum(0), m_number_of_edge_based_nodes(0), m_coordinates(coordinates), m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes), - m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), m_compressed_edge_container(compressed_edge_container), - name_table(name_table), segregated_edges(segregated_edges), - lane_description_map(lane_description_map) + m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), + m_compressed_edge_container(compressed_edge_container), name_table(name_table), + segregated_edges(segregated_edges), lane_description_map(lane_description_map) { } diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 24e7785b5aa..93dc56ea50e 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -5,6 +5,7 @@ #include "extractor/name_table.hpp" #include "extractor/restriction.hpp" #include "extractor/serialization.hpp" +#include "extractor/traffic_signals.hpp" #include "util/coordinate_calculation.hpp" #include "util/integer_range.hpp" @@ -412,15 +413,15 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme { const auto restriction_ways = IdentifyRestrictionWays(); const auto maneuver_override_ways = IdentifyManeuverOverrideWays(); - const auto traffic_signals = IdentifyTrafficSignals(); - const auto stop_signs = IdentifyStopSigns(); + const auto traffic_signals = IdentifyTrafficFlowControlNodes(external_traffic_signals); + const auto stop_signs = IdentifyTrafficFlowControlNodes(external_stop_signs); PrepareNodes(); PrepareEdges(scripting_environment); - PrepareTrafficSignals(traffic_signals); - PrepareStopSigns(stop_signs); - + PrepareTrafficFlowControlNodes(traffic_signals, internal_traffic_signals); + PrepareTrafficFlowControlNodes(stop_signs, internal_stop_signs); + PrepareManeuverOverrides(maneuver_override_ways); PrepareRestrictions(restriction_ways); WriteCharData(name_file_name); @@ -938,23 +939,23 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr return maneuver_override_ways; } -void ExtractionContainers::PrepareTrafficSignals( - const ReferencedTrafficFlowControlNodes &referenced_traffic_signals) +void ExtractionContainers::PrepareTrafficFlowControlNodes( + const ReferencedTrafficFlowControlNodes &referenced_traffic_control_nodes, + TrafficFlowControlNodes &internal_traffic_control_nodes) { - const auto &bidirectional_signal_nodes = referenced_traffic_signals.first; - const auto &unidirectional_signal_segments = referenced_traffic_signals.second; + const auto &bidirectional_traffic_control_nodes = referenced_traffic_control_nodes.first; + const auto &unidirectional_node_segments = referenced_traffic_control_nodes.second; util::UnbufferedLog log; - log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size() - << " bidirectional, " << unidirectional_signal_segments.size() - << " unidirectional nodes ..."; + log << "Preparing traffic control nodes for " << bidirectional_traffic_control_nodes.size() + << " bidirectional, " << unidirectional_node_segments.size() << " unidirectional nodes ..."; TIMER_START(prepare_traffic_signals); std::unordered_set bidirectional; std::unordered_set, boost::hash>> unidirectional; - for (const auto &osm_node : bidirectional_signal_nodes) + for (const auto &osm_node : bidirectional_traffic_control_nodes) { const auto node_id = mapExternalToInternalNodeID( used_node_id_list.begin(), used_node_id_list.end(), osm_node); @@ -963,7 +964,7 @@ void ExtractionContainers::PrepareTrafficSignals( bidirectional.insert(node_id); } } - for (const auto &to_from : unidirectional_signal_segments) + for (const auto &to_from : unidirectional_node_segments) { const auto to_node_id = mapExternalToInternalNodeID( used_node_id_list.begin(), used_node_id_list.end(), to_from.first); @@ -975,61 +976,13 @@ void ExtractionContainers::PrepareTrafficSignals( } } - internal_traffic_signals.bidirectional_nodes = std::move(bidirectional); - internal_traffic_signals.unidirectional_segments = std::move(unidirectional); + internal_traffic_control_nodes.bidirectional_nodes = std::move(bidirectional); + internal_traffic_control_nodes.unidirectional_segments = std::move(unidirectional); TIMER_STOP(prepare_traffic_signals); log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s"; } -// TODO: copy-paste -void ExtractionContainers::PrepareStopSigns(const ReferencedTrafficFlowControlNodes &referenced_stop_signs) { - const auto &bidirectional_signal_nodes = referenced_stop_signs.first; - const auto &unidirectional_signal_segments = referenced_stop_signs.second; - - util::UnbufferedLog log; - log << "Preparing traffic light signals for " << bidirectional_signal_nodes.size() - << " bidirectional, " << unidirectional_signal_segments.size() - << " unidirectional nodes ..."; - TIMER_START(prepare_traffic_signals); - - std::unordered_set bidirectional; - std::unordered_set, boost::hash>> - unidirectional; - - for (const auto &osm_node : bidirectional_signal_nodes) - { - const auto node_id = mapExternalToInternalNodeID( - used_node_id_list.begin(), used_node_id_list.end(), osm_node); - if (node_id != SPECIAL_NODEID) - { - bidirectional.insert(node_id); - } - } - for (const auto &to_from : unidirectional_signal_segments) - { - const auto to_node_id = mapExternalToInternalNodeID( - used_node_id_list.begin(), used_node_id_list.end(), to_from.first); - const auto from_node_id = mapExternalToInternalNodeID( - used_node_id_list.begin(), used_node_id_list.end(), to_from.second); - if (from_node_id != SPECIAL_NODEID && to_node_id != SPECIAL_NODEID) - { - unidirectional.insert({from_node_id, to_node_id}); - } - } - - internal_stop_signs.bidirectional_nodes = std::move(bidirectional); - internal_stop_signs.unidirectional_segments = std::move(unidirectional); - - TIMER_STOP(prepare_traffic_signals); - log << "ok, after " << TIMER_SEC(prepare_traffic_signals) << "s"; -} - -// void ExtractionContainers::PrepareGiveWays(const ReferencedGiveWays &referenced_give_ways) { - -// } - - void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways) { auto const osm_node_to_internal_nbn = [&](auto const osm_node) { @@ -1210,124 +1163,37 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa return restriction_ways; } -// TODO: copy-paste -ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::IdentifyStopSigns() -{ - util::UnbufferedLog log; - log << "Collecting traffic signal information on " << external_stop_signs.size() - << " signals..."; - TIMER_START(identify_traffic_signals); - - // Temporary store for nodes containing a unidirectional signal. - std::unordered_map unidirectional_signals; - - // For each node that has a unidirectional traffic signal, we store the node(s) - // that lead up to the signal. - std::unordered_multimap signal_segments; - - std::unordered_set bidirectional_signals; - - const auto mark_signals = [&](auto const &traffic_signal) { - if (traffic_signal.second == TrafficFlowControlNodeDirection::FORWARD || - traffic_signal.second == TrafficFlowControlNodeDirection::REVERSE) - { - unidirectional_signals.insert({traffic_signal.first, traffic_signal.second}); - } - else - { - BOOST_ASSERT(traffic_signal.second == TrafficFlowControlNodeDirection::ALL); - bidirectional_signals.insert(traffic_signal.first); - } - }; - std::for_each(external_stop_signs.begin(), external_stop_signs.end(), mark_signals); - - // Extract all the segments that lead up to unidirectional traffic signals. - const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) { - const auto node_start_offset = - used_node_id_list.begin() + way_node_id_offsets[way_list_idx]; - const auto node_end_offset = - used_node_id_list.begin() + way_node_id_offsets[way_list_idx + 1]; - - for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++) - { - const auto sig = unidirectional_signals.find(*node_it); - if (sig != unidirectional_signals.end()) - { - if (sig->second == TrafficFlowControlNodeDirection::FORWARD) - { - if (node_it != node_start_offset) - { - // Previous node leads to signal - signal_segments.insert({*node_it, *(node_it - 1)}); - } - } - else - { - BOOST_ASSERT(sig->second == TrafficFlowControlNodeDirection::REVERSE); - if (node_it + 1 != node_end_offset) - { - // Next node leads to signal - signal_segments.insert({*node_it, *(node_it + 1)}); - } - } - } - } - }; - util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments); - - util::for_each_pair( - signal_segments, [](const auto pair_a, const auto pair_b) { - if (pair_a.first == pair_b.first) - { - // If a node is appearing multiple times in this map, then it's ambiguous. - // The node is an intersection and the traffic direction is being use for multiple - // ways. We can't be certain of the original intent. See: - // https://wiki.openstreetmap.org/wiki/Key:traffic_signals:direction - - // OSRM will include the signal for all intersecting ways in the specified - // direction, but let's flag this as a concern. - util::Log(logWARNING) - << "OSM node " << pair_a.first - << " has a unidirectional traffic signal ambiguously applied to multiple ways"; - } - }); - - TIMER_STOP(identify_traffic_signals); - log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s"; - - return {std::move(bidirectional_signals), std::move(signal_segments)}; -} - - -ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::IdentifyTrafficSignals() +ExtractionContainers::ReferencedTrafficFlowControlNodes +ExtractionContainers::IdentifyTrafficFlowControlNodes( + const std::vector &external_nodes) { util::UnbufferedLog log; - log << "Collecting traffic signal information on " << external_traffic_signals.size() - << " signals..."; - TIMER_START(identify_traffic_signals); + log << "Collecting traffic nodes information on " << external_nodes.size() << " nodes..."; + TIMER_START(identify_traffic_flow_control_nodes); // Temporary store for nodes containing a unidirectional signal. - std::unordered_map unidirectional_signals; + std::unordered_map unidirectional_traffic_nodes; // For each node that has a unidirectional traffic signal, we store the node(s) // that lead up to the signal. - std::unordered_multimap signal_segments; + std::unordered_multimap node_segments; - std::unordered_set bidirectional_signals; + std::unordered_set bidirectional_traffic_nodes; - const auto mark_signals = [&](auto const &traffic_signal) { - if (traffic_signal.second == TrafficFlowControlNodeDirection::FORWARD || - traffic_signal.second == TrafficFlowControlNodeDirection::REVERSE) + const auto mark_traffic_nodes = [&](auto const &traffic_control_node) { + if (traffic_control_node.second == TrafficFlowControlNodeDirection::FORWARD || + traffic_control_node.second == TrafficFlowControlNodeDirection::REVERSE) { - unidirectional_signals.insert({traffic_signal.first, traffic_signal.second}); + unidirectional_traffic_nodes.insert( + {traffic_control_node.first, traffic_control_node.second}); } else { - BOOST_ASSERT(traffic_signal.second == TrafficFlowControlNodeDirection::ALL); - bidirectional_signals.insert(traffic_signal.first); + BOOST_ASSERT(traffic_control_node.second == TrafficFlowControlNodeDirection::ALL); + bidirectional_traffic_nodes.insert(traffic_control_node.first); } }; - std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals); + std::for_each(external_nodes.begin(), external_nodes.end(), mark_traffic_nodes); // Extract all the segments that lead up to unidirectional traffic signals. const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) { @@ -1338,15 +1204,15 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id for (auto node_it = node_start_offset; node_it < node_end_offset; node_it++) { - const auto sig = unidirectional_signals.find(*node_it); - if (sig != unidirectional_signals.end()) + const auto sig = unidirectional_traffic_nodes.find(*node_it); + if (sig != unidirectional_traffic_nodes.end()) { if (sig->second == TrafficFlowControlNodeDirection::FORWARD) { if (node_it != node_start_offset) { // Previous node leads to signal - signal_segments.insert({*node_it, *(node_it - 1)}); + node_segments.insert({*node_it, *(node_it - 1)}); } } else @@ -1355,7 +1221,7 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id if (node_it + 1 != node_end_offset) { // Next node leads to signal - signal_segments.insert({*node_it, *(node_it + 1)}); + node_segments.insert({*node_it, *(node_it + 1)}); } } } @@ -1364,7 +1230,7 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments); util::for_each_pair( - signal_segments, [](const auto pair_a, const auto pair_b) { + node_segments, [](const auto pair_a, const auto pair_b) { if (pair_a.first == pair_b.first) { // If a node is appearing multiple times in this map, then it's ambiguous. @@ -1380,10 +1246,10 @@ ExtractionContainers::ReferencedTrafficFlowControlNodes ExtractionContainers::Id } }); - TIMER_STOP(identify_traffic_signals); - log << "ok, after " << TIMER_SEC(identify_traffic_signals) << "s"; + TIMER_STOP(identify_traffic_flow_control_nodes); + log << "ok, after " << TIMER_SEC(identify_traffic_flow_control_nodes) << "s"; - return {std::move(bidirectional_signals), std::move(signal_segments)}; + return {std::move(bidirectional_traffic_nodes), std::move(node_segments)}; } void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways) diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 733bc3b4902..88149f87a7d 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -227,7 +227,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) parsed_osm_data.unresolved_maneuver_overrides, parsed_osm_data.traffic_signals, parsed_osm_data.stop_signs, - + std::move(parsed_osm_data.barriers), std::move(parsed_osm_data.osm_coordinates), std::move(parsed_osm_data.osm_node_ids), diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 1b1d2cd2335..f4896d3bc88 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -215,13 +215,15 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); - - // TODO: can we have a case when we have both traffic signal and stop sign? how should we handle it? + + // TODO: can we have a case when we have both traffic signal and stop sign? how + // should we handle it? EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT; EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT; - if (has_forward_signal || has_reverse_signal || has_forward_stop_sign || has_reverse_stop_sign) + if (has_forward_signal || has_reverse_signal || has_forward_stop_sign || + has_reverse_stop_sign) { // we cannot handle this as node penalty, if it depends on turn direction if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted) @@ -258,7 +260,8 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, roads_on_the_left); scripting_environment.ProcessTurn(extraction_turn); - std::cerr << "HAS STOP SIGN = " << extraction_turn.has_stop_sign << " " << extraction_turn.duration << std::endl; + std::cerr << "HAS STOP SIGN = " << extraction_turn.has_stop_sign << " " + << extraction_turn.duration << std::endl; auto update_direction_penalty = [&extraction_turn, weight_multiplier](bool signal, @@ -266,11 +269,13 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, EdgeWeight &weight_penalty) { if (signal) { - std::cerr << "DUR = " << extraction_turn.duration << " WEIGHT = " << extraction_turn.weight << std::endl; + std::cerr << "DUR = " << extraction_turn.duration + << " WEIGHT = " << extraction_turn.weight << std::endl; duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND; weight_penalty = extraction_turn.weight * weight_multiplier; - std::cerr << "DUR = " << duration_penalty << " WEIGHT = " << weight_penalty << std::endl; + std::cerr << "DUR = " << duration_penalty + << " WEIGHT = " << weight_penalty << std::endl; } }; diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index b00173b7870..c150bce7911 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -31,7 +31,8 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids)) { BuildCompressedOutputGraph(edge_list); - Compress(scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs); + Compress( + scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs); CompressGeometry(); CompressAnnotationData(); } diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 1670d948b57..3b9ee5e3469 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -1147,24 +1147,25 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) case 2: if (context.has_turn_penalty_function) { - std::cerr << "GOT TURN " << turn.has_stop_sign << " " << turn.has_traffic_light << std::endl; + std::cerr << "GOT TURN " << turn.has_stop_sign << " " << turn.has_traffic_light + << std::endl; context.turn_function(context.profile_table, std::ref(turn)); // Turn weight falls back to the duration value in deciseconds // or uses the extracted unit-less weight value - if (context.properties.fallback_to_duration) { + if (context.properties.fallback_to_duration) + { std::cerr << "FALLBACK\n"; turn.weight = turn.duration; } - - else { - // cap turn weight to max turn weight, which depend on weight precision + + else + { + // cap turn weight to max turn weight, which depend on weight precision turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight()); std::cerr << "NO FALLBACK " << turn.weight << " " << turn.duration << std::endl; - } - } break; From 4432756de129a3e602aec1377159c20953142f2b Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 28 Oct 2022 22:30:50 +0200 Subject: [PATCH 06/18] Take stop signs into account during routing --- profiles/car.lua | 4 +-- profiles/lib/traffic_signal.lua | 4 +-- src/extractor/graph_compressor.cpp | 33 +++++++++++---------- src/extractor/scripting_environment_lua.cpp | 5 ---- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/profiles/car.lua b/profiles/car.lua index 4910a1fa7c4..03ff1946819 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -30,6 +30,7 @@ function setup() use_turn_restrictions = true, left_hand_driving = false, traffic_light_penalty = 2, + stop_sign_penalty = 2 }, default_mode = mode.driving, @@ -481,8 +482,7 @@ function process_turn(profile, turn) if turn.has_traffic_light then turn.duration = profile.properties.traffic_light_penalty elseif turn.has_stop_sign then - -- TODO: use another constant - turn.duration = profile.properties.traffic_light_penalty + turn.duration = profile.properties.stop_sign_penalty end diff --git a/profiles/lib/traffic_signal.lua b/profiles/lib/traffic_signal.lua index 8356e3500a4..fdfb23f3366 100644 --- a/profiles/lib/traffic_signal.lua +++ b/profiles/lib/traffic_signal.lua @@ -9,10 +9,10 @@ function TrafficSignal.get_value(node) local direction = node:get_value_by_key("traffic_signals:direction") if direction then if "forward" == direction then - return traffic_lights.direction_forward + return traffic_flow_control_direction.direction_forward end if "backward" == direction then - return traffic_lights.direction_reverse + return traffic_flow_control_direction.direction_reverse end end -- return traffic_lights.direction_all diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index f4896d3bc88..7a8dd9f5dc7 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -209,15 +209,26 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, graph.GetEdgeData(reverse_e2).annotation_data = selectAnnotation( rev_edge_data2.annotation_data, rev_edge_data1.annotation_data); - // Add node penalty when compress edge crosses a traffic signal + // Add node penalty when compress edge crosses a traffic signal/stop sign/give way const bool has_forward_signal = traffic_signals.Has(node_u, node_v); const bool has_reverse_signal = traffic_signals.Has(node_w, node_v); - const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); - const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); + bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); + bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); + + // we apply penalty for only one of the control flow nodes + if (has_forward_stop_sign && has_forward_signal) { + has_forward_stop_sign = false; + util::Log(logWARNING) << "Node " << node_v + << " has both a traffic signal and a stop sign"; + } + if (has_reverse_stop_sign && has_reverse_signal) { + has_forward_stop_sign = false; + util::Log(logWARNING) << "Node " << node_v + << " has both a traffic signal and a stop sign"; + } + - // TODO: can we have a case when we have both traffic signal and stop sign? how - // should we handle it? EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT; EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION; @@ -260,22 +271,14 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, roads_on_the_left); scripting_environment.ProcessTurn(extraction_turn); - std::cerr << "HAS STOP SIGN = " << extraction_turn.has_stop_sign << " " - << extraction_turn.duration << std::endl; - auto update_direction_penalty = - [&extraction_turn, weight_multiplier](bool signal, + [&extraction_turn, weight_multiplier](bool has_traffic_control_node, EdgeDuration &duration_penalty, EdgeWeight &weight_penalty) { - if (signal) + if (has_traffic_control_node) { - std::cerr << "DUR = " << extraction_turn.duration - << " WEIGHT = " << extraction_turn.weight << std::endl; duration_penalty = extraction_turn.duration * SECOND_TO_DECISECOND; weight_penalty = extraction_turn.weight * weight_multiplier; - - std::cerr << "DUR = " << duration_penalty - << " WEIGHT = " << weight_penalty << std::endl; } }; diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 3b9ee5e3469..347c696844b 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -1147,16 +1147,12 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) case 2: if (context.has_turn_penalty_function) { - std::cerr << "GOT TURN " << turn.has_stop_sign << " " << turn.has_traffic_light - << std::endl; - context.turn_function(context.profile_table, std::ref(turn)); // Turn weight falls back to the duration value in deciseconds // or uses the extracted unit-less weight value if (context.properties.fallback_to_duration) { - std::cerr << "FALLBACK\n"; turn.weight = turn.duration; } @@ -1164,7 +1160,6 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) { // cap turn weight to max turn weight, which depend on weight precision turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight()); - std::cerr << "NO FALLBACK " << turn.weight << " " << turn.duration << std::endl; } } From 350862d1774f4cf014d9a2107e14a1b00c11385e Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 28 Oct 2022 22:59:46 +0200 Subject: [PATCH 07/18] Take stop signs into account during routing --- features/car/give_way_sign_penalties.feature | 39 +++++++++++++++++++ .../extractor/edge_based_graph_factory.hpp | 2 + include/extractor/extraction_containers.hpp | 4 +- include/extractor/extraction_turn.hpp | 4 +- include/extractor/extractor.hpp | 2 + include/extractor/graph_compressor.hpp | 1 + .../extractor/node_based_graph_factory.hpp | 5 ++- profiles/car.lua | 7 +++- src/extractor/edge_based_graph_factory.cpp | 7 +++- src/extractor/extraction_containers.cpp | 2 + src/extractor/extractor.cpp | 6 ++- src/extractor/extractor_callbacks.cpp | 9 ++--- src/extractor/graph_compressor.cpp | 24 +++++++++++- src/extractor/node_based_graph_factory.cpp | 7 +++- src/extractor/scripting_environment_lua.cpp | 4 +- 15 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 features/car/give_way_sign_penalties.feature diff --git a/features/car/give_way_sign_penalties.feature b/features/car/give_way_sign_penalties.feature new file mode 100644 index 00000000000..4e7e28fe886 --- /dev/null +++ b/features/car/give_way_sign_penalties.feature @@ -0,0 +1,39 @@ +@routing @car @give_way_sign +Feature: Car - Handle give way signs + + Background: + Given the profile "car" + + Scenario: Car - Encounters a give way sign + Given the node map + """ + a-1-b-2-c + + d-3-e-4-f + + g-h-i k-l-m + | | + j n + + """ + + And the ways + | nodes | highway | + | abc | primary | + | def | primary | + | ghi | primary | + | klm | primary | + | hj | primary | + | ln | primary | + + And the nodes + | node | highway | + | e | give_way | + | l | give_way | + + When I route I should get + | from | to | time | # | + | 1 | 2 | 11.1s | no turn with no stop sign | + | 3 | 4 | 13.1s | no turn with stop sign | + | g | j | 18.7s | turn with no stop sign | + | k | n | 20.7s | turn with stop sign | \ No newline at end of file diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index 9e0a77b66b2..b6b3b137f8f 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -71,6 +71,7 @@ class EdgeBasedGraphFactory const std::unordered_set &barrier_nodes, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, const std::vector &coordinates, const NameTable &name_table, const std::unordered_set &segregated_edges, @@ -138,6 +139,7 @@ class EdgeBasedGraphFactory const std::unordered_set &m_barrier_nodes; const TrafficFlowControlNodes &m_traffic_signals; const TrafficFlowControlNodes &m_stop_signs; + const TrafficFlowControlNodes &m_give_way_signs; const CompressedEdgeContainer &m_compressed_edge_container; diff --git a/include/extractor/extraction_containers.hpp b/include/extractor/extraction_containers.hpp index 45eb2a270a7..b2325e26541 100644 --- a/include/extractor/extraction_containers.hpp +++ b/include/extractor/extraction_containers.hpp @@ -40,7 +40,7 @@ class ExtractionContainers ReferencedWays IdentifyManeuverOverrideWays(); ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes( - const std::vector &external_stop_signs); + const std::vector &external_traffic_control_nodes); void PrepareNodes(); void PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways); @@ -83,7 +83,7 @@ class ExtractionContainers TrafficFlowControlNodes internal_stop_signs; std::vector external_give_ways; - TrafficFlowControlNodes internal_give_ways; + TrafficFlowControlNodes internal_give_way_signs; std::vector used_edges; diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 41b7224b344..d0873738a60 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -52,6 +52,7 @@ struct ExtractionTurn bool is_u_turn, bool has_traffic_light, bool has_stop_sign, + bool has_give_way_sign, bool is_left_hand_driving, bool source_restricted, TravelMode source_mode, @@ -76,7 +77,7 @@ struct ExtractionTurn const std::vector &roads_on_the_right, const std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), + has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), has_give_way_sign(has_give_way_sign), is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), source_mode(source_mode), @@ -103,6 +104,7 @@ struct ExtractionTurn const bool is_u_turn; const bool has_traffic_light; const bool has_stop_sign; + const bool has_give_way_sign; const bool is_left_hand_driving; // source info diff --git a/include/extractor/extractor.hpp b/include/extractor/extractor.hpp index 13c149171e4..d2626f526a9 100644 --- a/include/extractor/extractor.hpp +++ b/include/extractor/extractor.hpp @@ -68,6 +68,7 @@ class Extractor std::vector unresolved_maneuver_overrides; TrafficFlowControlNodes traffic_signals; TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::unordered_set barriers; std::vector osm_coordinates; extractor::PackedOSMIDs osm_node_ids; @@ -89,6 +90,7 @@ class Extractor const std::unordered_set &barrier_nodes, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, const RestrictionGraph &restriction_graph, const std::unordered_set &segregated_edges, const NameTable &name_table, diff --git a/include/extractor/graph_compressor.hpp b/include/extractor/graph_compressor.hpp index 2d33c8adcb1..b41e438e996 100644 --- a/include/extractor/graph_compressor.hpp +++ b/include/extractor/graph_compressor.hpp @@ -28,6 +28,7 @@ class GraphCompressor void Compress(const std::unordered_set &barrier_nodes, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index 5308b31ca20..deaa1fd24e2 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -43,7 +43,7 @@ class NodeBasedGraphFactory std::vector &maneuver_overrides, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, - + const TrafficFlowControlNodes &give_way_signs, std::unordered_set &&barriers, std::vector &&coordinates, extractor::PackedOSMIDs &&osm_node_ids, @@ -76,7 +76,8 @@ class NodeBasedGraphFactory std::vector &turn_restrictions, std::vector &maneuver_overrides, const TrafficFlowControlNodes &traffic_signals, - const TrafficFlowControlNodes &stop_signs); + const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs); // Most ways are bidirectional, making the geometry in forward and backward direction the same, // except for reversal. We make use of this fact by keeping only one representation of the diff --git a/profiles/car.lua b/profiles/car.lua index 03ff1946819..ddae81de820 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -30,7 +30,8 @@ function setup() use_turn_restrictions = true, left_hand_driving = false, traffic_light_penalty = 2, - stop_sign_penalty = 2 + stop_sign_penalty = 2, + give_way_sign_penalty = 2 }, default_mode = mode.driving, @@ -480,9 +481,11 @@ function process_turn(profile, turn) local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias if turn.has_traffic_light then - turn.duration = profile.properties.traffic_light_penalty + turn.duration = profile.properties.traffic_light_penalty elseif turn.has_stop_sign then turn.duration = profile.properties.stop_sign_penalty + elseif turn.has_give_way_sign then + turn.duration = profile.properties.give_way_sign_penalty end diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 0232c991048..f9e37735c97 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -61,6 +61,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( const std::unordered_set &barrier_nodes, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, const std::vector &coordinates, const NameTable &name_table, const std::unordered_set &segregated_edges, @@ -68,7 +69,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( : m_edge_based_node_container(node_data_container), m_connectivity_checksum(0), m_number_of_edge_based_nodes(0), m_coordinates(coordinates), m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes), - m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), + m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), m_give_way_signs(give_way_signs), m_compressed_edge_container(compressed_edge_container), name_table(name_table), segregated_edges(segregated_edges), lane_description_map(lane_description_map) { @@ -645,7 +646,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // node But we'll check anyway. const auto is_traffic_light = m_traffic_signals.Has(from_node, intersection_node); const auto is_stop_sign = m_stop_signs.Has(from_node, intersection_node); - std::cerr << "IS STOP SIGN " << is_stop_sign << std::endl; + const auto is_give_way_sign = m_give_way_signs.Has(from_node, intersection_node); + const auto is_uturn = guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn; @@ -656,6 +658,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( is_uturn, is_traffic_light, is_stop_sign, + is_give_way_sign, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) .is_left_hand_driving, // source info diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 93dc56ea50e..ea8755048e9 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -415,12 +415,14 @@ void ExtractionContainers::PrepareData(ScriptingEnvironment &scripting_environme const auto maneuver_override_ways = IdentifyManeuverOverrideWays(); const auto traffic_signals = IdentifyTrafficFlowControlNodes(external_traffic_signals); const auto stop_signs = IdentifyTrafficFlowControlNodes(external_stop_signs); + const auto give_ways = IdentifyTrafficFlowControlNodes(external_give_ways); PrepareNodes(); PrepareEdges(scripting_environment); PrepareTrafficFlowControlNodes(traffic_signals, internal_traffic_signals); PrepareTrafficFlowControlNodes(stop_signs, internal_stop_signs); + PrepareTrafficFlowControlNodes(give_ways, internal_give_way_signs); PrepareManeuverOverrides(maneuver_override_ways); PrepareRestrictions(restriction_ways); diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 88149f87a7d..bb3b7fbbaa0 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -227,7 +227,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) parsed_osm_data.unresolved_maneuver_overrides, parsed_osm_data.traffic_signals, parsed_osm_data.stop_signs, - + parsed_osm_data.give_way_signs, std::move(parsed_osm_data.barriers), std::move(parsed_osm_data.osm_coordinates), std::move(parsed_osm_data.osm_node_ids), @@ -286,6 +286,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) barrier_nodes, parsed_osm_data.traffic_signals, parsed_osm_data.stop_signs, + parsed_osm_data.give_way_signs, restriction_graph, segregated_edges, name_table, @@ -653,6 +654,7 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting std::move(extraction_containers.internal_maneuver_overrides), std::move(extraction_containers.internal_traffic_signals), std::move(extraction_containers.internal_stop_signs), + std::move(extraction_containers.internal_give_way_signs), std::move(extraction_containers.used_barrier_nodes), std::move(osm_coordinates), std::move(osm_node_ids), @@ -730,6 +732,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph( const std::unordered_set &barrier_nodes, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, const RestrictionGraph &restriction_graph, const std::unordered_set &segregated_edges, const NameTable &name_table, @@ -752,6 +755,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph( barrier_nodes, traffic_signals, stop_signs, + give_way_signs, coordinates, name_table, segregated_edges, diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 8fe07198b4a..200c3681b41 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -82,13 +82,12 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, { external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights}); } - // if (result_node.give_way != GiveWay::Direction::NONE) - // { - // external_memory.external_give_ways.push_back({id, result_node.give_way}); - // } + if (result_node.give_way != TrafficFlowControlNodeDirection::NONE) + { + external_memory.external_give_ways.push_back({id, result_node.give_way}); + } if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE) { - std::cerr << "FOUND STOP SIGN\n"; external_memory.external_stop_signs.push_back({id, result_node.stop_sign}); } } diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 7a8dd9f5dc7..0b3a5e1c1ae 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -24,6 +24,7 @@ static constexpr int SECOND_TO_DECISECOND = 10; void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, ScriptingEnvironment &scripting_environment, std::vector &turn_restrictions, std::vector &maneuver_overrides, @@ -223,11 +224,25 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, << " has both a traffic signal and a stop sign"; } if (has_reverse_stop_sign && has_reverse_signal) { - has_forward_stop_sign = false; + has_reverse_stop_sign = false; util::Log(logWARNING) << "Node " << node_v << " has both a traffic signal and a stop sign"; } + bool has_forward_give_way_sign = give_way_signs.Has(node_u, node_v); + bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v); + // we apply penalty for only one of the control flow nodes + if (has_forward_give_way_sign && (has_forward_signal || has_forward_stop_sign)) { + has_forward_give_way_sign = false; + util::Log(logWARNING) << "Node " << node_v + << " has both a give way sign and a stop sign or traffic signal"; + } + if (has_reverse_stop_sign && (has_reverse_signal || has_reverse_stop_sign)) { + has_reverse_give_way_sign = false; + util::Log(logWARNING) << "Node " << node_v + << " has both a give way sign and a stop sign or traffic signal"; + } + EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT; @@ -248,6 +263,7 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, false, has_forward_signal || has_reverse_signal, has_forward_stop_sign || has_reverse_stop_sign, + has_forward_give_way_sign || has_reverse_give_way_sign, false, false, TRAVEL_MODE_DRIVING, @@ -294,6 +310,12 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, update_direction_penalty(has_reverse_stop_sign, reverse_node_duration_penalty, reverse_node_weight_penalty); + update_direction_penalty(has_forward_give_way_sign, + forward_node_duration_penalty, + forward_node_weight_penalty); + update_direction_penalty(has_reverse_give_way_sign, + reverse_node_duration_penalty, + reverse_node_weight_penalty); } // Get weights before graph is modified diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index c150bce7911..708c69ca315 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -22,6 +22,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( std::vector &maneuver_overrides, const TrafficFlowControlNodes &traffic_signals, const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs, std::unordered_set &&barriers, std::vector &&coordinates, extractor::PackedOSMIDs &&osm_node_ids, @@ -32,7 +33,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( { BuildCompressedOutputGraph(edge_list); Compress( - scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs); + scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs, give_way_signs); CompressGeometry(); CompressAnnotationData(); } @@ -78,12 +79,14 @@ void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment std::vector &turn_restrictions, std::vector &maneuver_overrides, const TrafficFlowControlNodes &traffic_signals, - const TrafficFlowControlNodes &stop_signs) + const TrafficFlowControlNodes &stop_signs, + const TrafficFlowControlNodes &give_way_signs) { GraphCompressor graph_compressor; graph_compressor.Compress(barriers, traffic_signals, stop_signs, + give_way_signs, scripting_environment, turn_restrictions, maneuver_overrides, diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 347c696844b..20b1aa04514 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -786,6 +786,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::has_traffic_light, "has_stop_sign", &ExtractionTurn::has_stop_sign, + "has_give_way_sign", + &ExtractionTurn::has_give_way_sign, "is_left_hand_driving", &ExtractionTurn::is_left_hand_driving, "source_restricted", @@ -1198,7 +1200,7 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) } // Add traffic light penalty, back-compatibility of api_version=0 - if (turn.has_traffic_light || turn.has_stop_sign) + if (turn.has_traffic_light) turn.duration += context.properties.GetTrafficSignalPenalty(); // Turn weight falls back to the duration value in deciseconds From 97883178fab6f0be9d625f7753332c42164bd110 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Fri, 28 Oct 2022 23:03:51 +0200 Subject: [PATCH 08/18] Take stop signs into account during routing --- include/extractor/edge_based_graph_factory.hpp | 2 +- include/extractor/extraction_containers.hpp | 2 +- include/extractor/extraction_node.hpp | 2 +- include/extractor/extractor.hpp | 2 +- include/extractor/graph_compressor.hpp | 2 +- include/extractor/node_based_graph_factory.hpp | 2 +- include/extractor/stop_sign_class.hpp | 0 .../{traffic_signals.hpp => traffic_flow_control_nodes.hpp} | 0 src/extractor/extraction_containers.cpp | 2 +- src/extractor/node_based_graph_factory.cpp | 2 +- 10 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 include/extractor/stop_sign_class.hpp rename include/extractor/{traffic_signals.hpp => traffic_flow_control_nodes.hpp} (100%) diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index b6b3b137f8f..b8c87192f34 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -23,7 +23,7 @@ #include "util/typedefs.hpp" #include "storage/io.hpp" -#include "traffic_signals.hpp" +#include "traffic_flow_control_nodes.hpp" #include #include diff --git a/include/extractor/extraction_containers.hpp b/include/extractor/extraction_containers.hpp index b2325e26541..1d426cd721d 100644 --- a/include/extractor/extraction_containers.hpp +++ b/include/extractor/extraction_containers.hpp @@ -8,7 +8,7 @@ #include "extractor/scripting_environment.hpp" #include "storage/tar_fwd.hpp" -#include "traffic_signals.hpp" +#include "traffic_flow_control_nodes.hpp" #include #include diff --git a/include/extractor/extraction_node.hpp b/include/extractor/extraction_node.hpp index 2a8d4fa2a13..158d5476036 100644 --- a/include/extractor/extraction_node.hpp +++ b/include/extractor/extraction_node.hpp @@ -1,7 +1,7 @@ #ifndef EXTRACTION_NODE_HPP #define EXTRACTION_NODE_HPP -#include "traffic_signals.hpp" +#include "traffic_flow_control_nodes.hpp" #include namespace osrm diff --git a/include/extractor/extractor.hpp b/include/extractor/extractor.hpp index d2626f526a9..0fe4ac47cb2 100644 --- a/include/extractor/extractor.hpp +++ b/include/extractor/extractor.hpp @@ -43,7 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "util/guidance/turn_lanes.hpp" #include "restriction_graph.hpp" -#include "traffic_signals.hpp" +#include "traffic_flow_control_nodes.hpp" #include "util/typedefs.hpp" namespace osrm diff --git a/include/extractor/graph_compressor.hpp b/include/extractor/graph_compressor.hpp index b41e438e996..3ba13ea9cb0 100644 --- a/include/extractor/graph_compressor.hpp +++ b/include/extractor/graph_compressor.hpp @@ -4,7 +4,7 @@ #include "extractor/scripting_environment.hpp" #include "util/typedefs.hpp" -#include "traffic_signals.hpp" +#include "traffic_flow_control_nodes.hpp" #include "util/node_based_graph.hpp" #include diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index deaa1fd24e2..c9324fa378e 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -8,7 +8,7 @@ #include "extractor/packed_osm_ids.hpp" #include "extractor/scripting_environment.hpp" -#include "traffic_signals.hpp" +#include "traffic_flow_control_nodes.hpp" #include "util/coordinate.hpp" #include "util/node_based_graph.hpp" diff --git a/include/extractor/stop_sign_class.hpp b/include/extractor/stop_sign_class.hpp deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/include/extractor/traffic_signals.hpp b/include/extractor/traffic_flow_control_nodes.hpp similarity index 100% rename from include/extractor/traffic_signals.hpp rename to include/extractor/traffic_flow_control_nodes.hpp diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index ea8755048e9..43dc38938fb 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -5,7 +5,7 @@ #include "extractor/name_table.hpp" #include "extractor/restriction.hpp" #include "extractor/serialization.hpp" -#include "extractor/traffic_signals.hpp" +#include "extractor/traffic_flow_control_nodes.hpp" #include "util/coordinate_calculation.hpp" #include "util/integer_range.hpp" diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 708c69ca315..e4a6bbfef57 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -1,7 +1,7 @@ #include "extractor/node_based_graph_factory.hpp" #include "extractor/files.hpp" #include "extractor/graph_compressor.hpp" -#include "extractor/traffic_signals.hpp" +#include "extractor/traffic_flow_control_nodes.hpp" #include "storage/io.hpp" #include "util/log.hpp" From c28a6832d73d42bd9ddd8a3933119dfd4298ad79 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Sun, 30 Oct 2022 11:59:33 +0100 Subject: [PATCH 09/18] Take stop signs into account during routing --- src/extractor/graph_compressor.cpp | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 0b3a5e1c1ae..6041f861b10 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -217,31 +217,9 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); - // we apply penalty for only one of the control flow nodes - if (has_forward_stop_sign && has_forward_signal) { - has_forward_stop_sign = false; - util::Log(logWARNING) << "Node " << node_v - << " has both a traffic signal and a stop sign"; - } - if (has_reverse_stop_sign && has_reverse_signal) { - has_reverse_stop_sign = false; - util::Log(logWARNING) << "Node " << node_v - << " has both a traffic signal and a stop sign"; - } - bool has_forward_give_way_sign = give_way_signs.Has(node_u, node_v); bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v); - // we apply penalty for only one of the control flow nodes - if (has_forward_give_way_sign && (has_forward_signal || has_forward_stop_sign)) { - has_forward_give_way_sign = false; - util::Log(logWARNING) << "Node " << node_v - << " has both a give way sign and a stop sign or traffic signal"; - } - if (has_reverse_stop_sign && (has_reverse_signal || has_reverse_stop_sign)) { - has_reverse_give_way_sign = false; - util::Log(logWARNING) << "Node " << node_v - << " has both a give way sign and a stop sign or traffic signal"; - } + EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; @@ -249,7 +227,7 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight reverse_node_weight_penalty = INVALID_EDGE_WEIGHT; if (has_forward_signal || has_reverse_signal || has_forward_stop_sign || - has_reverse_stop_sign) + has_reverse_stop_sign || has_forward_give_way_sign || has_reverse_give_way_sign) { // we cannot handle this as node penalty, if it depends on turn direction if (fwd_edge_data1.flags.restricted != fwd_edge_data2.flags.restricted) From 62298cf409bbaa9baeccbe19e1973d3fbd884d49 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 17:30:15 +0100 Subject: [PATCH 10/18] Take stop signs into account during routing --- src/extractor/graph_compressor.cpp | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 6041f861b10..8fae0c985c4 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -214,11 +214,11 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, const bool has_forward_signal = traffic_signals.Has(node_u, node_v); const bool has_reverse_signal = traffic_signals.Has(node_w, node_v); - bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); - bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); + const bool has_forward_stop_sign = stop_signs.Has(node_u, node_v); + const bool has_reverse_stop_sign = stop_signs.Has(node_w, node_v); - bool has_forward_give_way_sign = give_way_signs.Has(node_u, node_v); - bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v); + const bool has_forward_give_way_sign = give_way_signs.Has(node_u, node_v); + const bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v); @@ -276,22 +276,10 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, } }; - update_direction_penalty(has_forward_signal, + update_direction_penalty(has_forward_signal || has_forward_stop_sign || has_forward_give_way_sign, forward_node_duration_penalty, forward_node_weight_penalty); - update_direction_penalty(has_reverse_signal, - reverse_node_duration_penalty, - reverse_node_weight_penalty); - update_direction_penalty(has_forward_stop_sign, - forward_node_duration_penalty, - forward_node_weight_penalty); - update_direction_penalty(has_reverse_stop_sign, - reverse_node_duration_penalty, - reverse_node_weight_penalty); - update_direction_penalty(has_forward_give_way_sign, - forward_node_duration_penalty, - forward_node_weight_penalty); - update_direction_penalty(has_reverse_give_way_sign, + update_direction_penalty(has_reverse_signal || has_reverse_stop_sign || has_reverse_give_way_sign, reverse_node_duration_penalty, reverse_node_weight_penalty); } From be1b86657c07a5a0461cf6f22c7892ef6030981f Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 21:36:08 +0100 Subject: [PATCH 11/18] Take stop signs into account during routing --- features/car/give_way_sign_penalties.feature | 46 ++++++++++++++++++-- features/car/stop_sign_penalties.feature | 39 ++++++++++++++++- src/extractor/extraction_containers.cpp | 2 +- taginfo.json | 1 + 4 files changed, 82 insertions(+), 6 deletions(-) diff --git a/features/car/give_way_sign_penalties.feature b/features/car/give_way_sign_penalties.feature index 4e7e28fe886..ed84ab92254 100644 --- a/features/car/give_way_sign_penalties.feature +++ b/features/car/give_way_sign_penalties.feature @@ -33,7 +33,45 @@ Feature: Car - Handle give way signs When I route I should get | from | to | time | # | - | 1 | 2 | 11.1s | no turn with no stop sign | - | 3 | 4 | 13.1s | no turn with stop sign | - | g | j | 18.7s | turn with no stop sign | - | k | n | 20.7s | turn with stop sign | \ No newline at end of file + | 1 | 2 | 11.1s | no turn with no give way | + | 3 | 4 | 13.1s | no turn with give way | + | g | j | 18.7s | turn with no give way | + | k | n | 20.7s | turn with give way | + + + Scenario: Car - Give way direction + Given the node map + """ + a-1-b-2-c + + d-3-e-4-f + + g-5-h-6-i + + j-7-k-8-l + + """ + + And the ways + | nodes | highway | + | abc | primary | + | def | primary | + | ghi | primary | + | jkl | primary | + + And the nodes + | node | highway | direction | + | e | give_way | | + | h | give_way | forward | + | k | give_way | backward | + + When I route I should get + | from | to | time | weight | # | + | 1 | 2 | 11.1s | 11.1 | no turn with no give way | + | 2 | 1 | 11.1s | 11.1 | no turn with no give way | + | 3 | 4 | 13.1s | 13.1 | no turn with give way | + | 4 | 3 | 13.1s | 13.1 | no turn with give way | + | 5 | 6 | 13.1s | 13.1 | no turn with give way | + | 6 | 5 | 11.1s | 11.1 | no turn with no give way | + | 7 | 8 | 11.1s | 11.1 | no turn with no give way | + | 8 | 7 | 13.1s | 13.1 | no turn with give way | diff --git a/features/car/stop_sign_penalties.feature b/features/car/stop_sign_penalties.feature index 1cccc30d805..8ae42263ab1 100644 --- a/features/car/stop_sign_penalties.feature +++ b/features/car/stop_sign_penalties.feature @@ -36,4 +36,41 @@ Feature: Car - Handle stop signs | 1 | 2 | 11.1s | no turn with no stop sign | | 3 | 4 | 13.1s | no turn with stop sign | | g | j | 18.7s | turn with no stop sign | - | k | n | 20.7s | turn with stop sign | \ No newline at end of file + | k | n | 20.7s | turn with stop sign | + + Scenario: Car - Stop sign direction + Given the node map + """ + a-1-b-2-c + + d-3-e-4-f + + g-5-h-6-i + + j-7-k-8-l + + """ + + And the ways + | nodes | highway | + | abc | primary | + | def | primary | + | ghi | primary | + | jkl | primary | + + And the nodes + | node | highway | direction | + | e | stop | | + | h | stop | forward | + | k | stop | backward | + + When I route I should get + | from | to | time | weight | # | + | 1 | 2 | 11.1s | 11.1 | no turn with no stop sign | + | 2 | 1 | 11.1s | 11.1 | no turn with no stop sign | + | 3 | 4 | 13.1s | 13.1 | no turn with stop sign | + | 4 | 3 | 13.1s | 13.1 | no turn with stop sign | + | 5 | 6 | 13.1s | 13.1 | no turn with stop sign | + | 6 | 5 | 11.1s | 11.1 | no turn with no stop sign | + | 7 | 8 | 11.1s | 11.1 | no turn with no stop sign | + | 8 | 7 | 13.1s | 13.1 | no turn with stop sign | diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 43dc38938fb..1fab34db580 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -1197,7 +1197,7 @@ ExtractionContainers::IdentifyTrafficFlowControlNodes( }; std::for_each(external_nodes.begin(), external_nodes.end(), mark_traffic_nodes); - // Extract all the segments that lead up to unidirectional traffic signals. + // Extract all the segments that lead up to unidirectional traffic flow control nodes. const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) { const auto node_start_offset = used_node_id_list.begin() + way_node_id_offsets[way_list_idx]; diff --git a/taginfo.json b/taginfo.json index 3107a5c61c0..536564efff4 100644 --- a/taginfo.json +++ b/taginfo.json @@ -126,6 +126,7 @@ {"key": "route", "object_types": ["way"]}, {"key": "highway", "value": "traffic_signals", "object_types": ["node"]}, {"key": "highway", "value": "stop", "object_types": ["node"]}, + {"key": "highway", "value": "give_way", "object_types": ["node"]}, {"key": "highway", "value": "crossing", "object_types": ["node"]}, {"key": "access", "value": "yes"}, {"key": "access", "value": "motorcar"}, From b887e72d0b63f5d7b9c5a0ecdb5c8a82142a5f54 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 21:45:20 +0100 Subject: [PATCH 12/18] Take stop signs into account during routing --- .../options/extract/turn_function.feature | 1 - .../extractor/traffic_flow_control_nodes.hpp | 10 ++------- profiles/lib/give_way.lua | 18 +++------------- profiles/lib/stop_sign.lua | 17 +++------------ profiles/lib/traffic_flow_control_node.lua | 21 +++++++++++++++++++ 5 files changed, 29 insertions(+), 38 deletions(-) create mode 100644 profiles/lib/traffic_flow_control_node.lua diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index b9cf792f669..76335416525 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -1,7 +1,6 @@ @routing @testbot @turn_function Feature: Turn Function Information - // TODO Background: Given the profile file """ diff --git a/include/extractor/traffic_flow_control_nodes.hpp b/include/extractor/traffic_flow_control_nodes.hpp index 5a797ceb89a..259fdcdb75b 100644 --- a/include/extractor/traffic_flow_control_nodes.hpp +++ b/include/extractor/traffic_flow_control_nodes.hpp @@ -11,14 +11,8 @@ namespace osrm namespace extractor { -// Stop Signs tagged on nodes can be present or not. In addition Stop Signs have -// an optional way direction they apply to. If the direction is unknown from the -// data we have to compute by checking the distance to the next intersection. -// -// Impl. detail: namespace + enum instead of enum class to make Luabind happy - -// The traffic light annotation is extracted from node tags. -// The directions in which the traffic light applies are relative to the way containing the node. +// The direction annotation is extracted from node tags. +// The directions in which traffic flow object applies are relative to the way containing the node. enum class TrafficFlowControlNodeDirection : std::uint8_t { NONE = 0, diff --git a/profiles/lib/give_way.lua b/profiles/lib/give_way.lua index 527092ced88..2bf53574f0c 100644 --- a/profiles/lib/give_way.lua +++ b/profiles/lib/give_way.lua @@ -1,21 +1,9 @@ local GiveWay = {} +TrafficFlowControlNode = require("lib/traffic_flow_control_node") + function GiveWay.get_value(node) - local tag = node:get_value_by_key("highway") - if "give_way" == tag then - local direction = node:get_value_by_key("direction") - if direction then - if "forward" == direction then - return traffic_flow_control_direction.direction_forward - end - if "backward" == direction then - return traffic_flow_control_direction.direction_reverse - end - end - return traffic_flow_control_direction.direction_all - end - return traffic_flow_control_direction.none + return TrafficFlowControlNode.get_value(node, "give_way") end return GiveWay - diff --git a/profiles/lib/stop_sign.lua b/profiles/lib/stop_sign.lua index 368dfb98adf..a31c4deca16 100644 --- a/profiles/lib/stop_sign.lua +++ b/profiles/lib/stop_sign.lua @@ -1,20 +1,9 @@ local StopSign = {} +TrafficFlowControlNode = require("lib/traffic_flow_control_node") + function StopSign.get_value(node) - local tag = node:get_value_by_key("highway") - if "stop" == tag then - local direction = node:get_value_by_key("direction") - if direction then - if "forward" == direction then - return traffic_flow_control_direction.direction_forward - end - if "backward" == direction then - return traffic_flow_control_direction.direction_reverse - end - end - return traffic_flow_control_direction.direction_all - end - return traffic_flow_control_direction.none + return TrafficFlowControlNode.get_value(node, "stop") end return StopSign diff --git a/profiles/lib/traffic_flow_control_node.lua b/profiles/lib/traffic_flow_control_node.lua new file mode 100644 index 00000000000..ef20aebcdaa --- /dev/null +++ b/profiles/lib/traffic_flow_control_node.lua @@ -0,0 +1,21 @@ +local TrafficFlowControlNode = {} + +function TrafficFlowControlNode.get_value(node, tag_name) + local tag = node:get_value_by_key("highway") + if tag_name == tag then + local direction = node:get_value_by_key("direction") + if direction then + if "forward" == direction then + return traffic_flow_control_direction.direction_forward + end + if "backward" == direction then + return traffic_flow_control_direction.direction_reverse + end + end + return traffic_flow_control_direction.direction_all + end + return traffic_flow_control_direction.none +end + +return TrafficFlowControlNode + From a7142ee737a38fda111e8618fcddfe63859c6c64 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 21:47:48 +0100 Subject: [PATCH 13/18] Take stop signs into account during routing --- include/extractor/extraction_turn.hpp | 4 +-- src/extractor/edge_based_graph_factory.cpp | 9 +++--- src/extractor/graph_compressor.cpp | 35 ++++++++++++---------- src/extractor/node_based_graph_factory.cpp | 8 +++-- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index d0873738a60..61cdf8d6a92 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -77,8 +77,8 @@ struct ExtractionTurn const std::vector &roads_on_the_right, const std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), has_give_way_sign(has_give_way_sign), - is_left_hand_driving(is_left_hand_driving), + has_traffic_light(has_traffic_light), has_stop_sign(has_stop_sign), + has_give_way_sign(has_give_way_sign), is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), source_mode(source_mode), source_is_motorway(source_is_motorway), source_is_link(source_is_link), diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 1e5e9e4f87a..aebfab689d3 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -55,9 +55,10 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( : m_edge_based_node_container(node_data_container), m_connectivity_checksum(0), m_number_of_edge_based_nodes(0), m_coordinates(coordinates), m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes), - m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), m_give_way_signs(give_way_signs), - m_compressed_edge_container(compressed_edge_container), name_table(name_table), - segregated_edges(segregated_edges), lane_description_map(lane_description_map) + m_traffic_signals(traffic_signals), m_stop_signs(stop_signs), + m_give_way_signs(give_way_signs), m_compressed_edge_container(compressed_edge_container), + name_table(name_table), segregated_edges(segregated_edges), + lane_description_map(lane_description_map) { } @@ -634,7 +635,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto is_traffic_light = m_traffic_signals.Has(from_node, intersection_node); const auto is_stop_sign = m_stop_signs.Has(from_node, intersection_node); const auto is_give_way_sign = m_give_way_signs.Has(from_node, intersection_node); - + const auto is_uturn = guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn; diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 2d3e85c9aed..b547b234874 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -220,8 +220,6 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, const bool has_forward_give_way_sign = give_way_signs.Has(node_u, node_v); const bool has_reverse_give_way_sign = give_way_signs.Has(node_w, node_v); - - EdgeDuration forward_node_duration_penalty = MAXIMAL_EDGE_DURATION; EdgeWeight forward_node_weight_penalty = INVALID_EDGE_WEIGHT; EdgeDuration reverse_node_duration_penalty = MAXIMAL_EDGE_DURATION; @@ -241,7 +239,8 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, false, has_forward_signal || has_reverse_signal, has_forward_stop_sign || has_reverse_stop_sign, - has_forward_give_way_sign || has_reverse_give_way_sign, + has_forward_give_way_sign || + has_reverse_give_way_sign, false, false, TRAVEL_MODE_DRIVING, @@ -265,21 +264,25 @@ void GraphCompressor::Compress(const std::unordered_set &barrier_nodes, roads_on_the_left); scripting_environment.ProcessTurn(extraction_turn); - auto update_direction_penalty = - [&extraction_turn, weight_multiplier](bool has_traffic_control_node, - EdgeDuration &duration_penalty, - EdgeWeight &weight_penalty) { - if (has_traffic_control_node) - { - duration_penalty = to_alias(extraction_turn.duration * SECOND_TO_DECISECOND); - weight_penalty = to_alias(extraction_turn.weight * weight_multiplier); - } - }; - - update_direction_penalty(has_forward_signal || has_forward_stop_sign || has_forward_give_way_sign, + auto update_direction_penalty = [&extraction_turn, weight_multiplier]( + bool has_traffic_control_node, + EdgeDuration &duration_penalty, + EdgeWeight &weight_penalty) { + if (has_traffic_control_node) + { + duration_penalty = to_alias(extraction_turn.duration * + SECOND_TO_DECISECOND); + weight_penalty = + to_alias(extraction_turn.weight * weight_multiplier); + } + }; + + update_direction_penalty(has_forward_signal || has_forward_stop_sign || + has_forward_give_way_sign, forward_node_duration_penalty, forward_node_weight_penalty); - update_direction_penalty(has_reverse_signal || has_reverse_stop_sign || has_reverse_give_way_sign, + update_direction_penalty(has_reverse_signal || has_reverse_stop_sign || + has_reverse_give_way_sign, reverse_node_duration_penalty, reverse_node_weight_penalty); } diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index e4a6bbfef57..018b54f18ec 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -32,8 +32,12 @@ NodeBasedGraphFactory::NodeBasedGraphFactory( coordinates(std::move(coordinates)), osm_node_ids(std::move(osm_node_ids)) { BuildCompressedOutputGraph(edge_list); - Compress( - scripting_environment, turn_restrictions, maneuver_overrides, traffic_signals, stop_signs, give_way_signs); + Compress(scripting_environment, + turn_restrictions, + maneuver_overrides, + traffic_signals, + stop_signs, + give_way_signs); CompressGeometry(); CompressAnnotationData(); } From 3080be59ed57cbe6491f6d66d5e3d4bd3497839c Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 21:58:18 +0100 Subject: [PATCH 14/18] Take stop signs into account during routing --- features/car/give_way_sign_penalties.feature | 10 +++++----- features/car/stop_sign_penalties.feature | 9 +++++---- src/extractor/extractor_callbacks.cpp | 6 ++++-- unit_tests/extractor/graph_compressor.cpp | 20 +++++++++++++++++++ .../extractor/intersection_analysis_tests.cpp | 13 ++++++++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/features/car/give_way_sign_penalties.feature b/features/car/give_way_sign_penalties.feature index ed84ab92254..4f9b45debba 100644 --- a/features/car/give_way_sign_penalties.feature +++ b/features/car/give_way_sign_penalties.feature @@ -31,12 +31,13 @@ Feature: Car - Handle give way signs | e | give_way | | l | give_way | + # TODO: give way signs with no direction has no any impact on routing at the moment When I route I should get | from | to | time | # | | 1 | 2 | 11.1s | no turn with no give way | - | 3 | 4 | 13.1s | no turn with give way | + | 3 | 4 | 11.1s | no turn with give way | | g | j | 18.7s | turn with no give way | - | k | n | 20.7s | turn with give way | + | k | n | 18.7s | turn with give way | Scenario: Car - Give way direction @@ -64,13 +65,12 @@ Feature: Car - Handle give way signs | e | give_way | | | h | give_way | forward | | k | give_way | backward | - When I route I should get | from | to | time | weight | # | | 1 | 2 | 11.1s | 11.1 | no turn with no give way | | 2 | 1 | 11.1s | 11.1 | no turn with no give way | - | 3 | 4 | 13.1s | 13.1 | no turn with give way | - | 4 | 3 | 13.1s | 13.1 | no turn with give way | + | 3 | 4 | 11.1s | 11.1 | no turn with give way | + | 4 | 3 | 11.1s | 11.1 | no turn with give way | | 5 | 6 | 13.1s | 13.1 | no turn with give way | | 6 | 5 | 11.1s | 11.1 | no turn with no give way | | 7 | 8 | 11.1s | 11.1 | no turn with no give way | diff --git a/features/car/stop_sign_penalties.feature b/features/car/stop_sign_penalties.feature index 8ae42263ab1..35c15540abc 100644 --- a/features/car/stop_sign_penalties.feature +++ b/features/car/stop_sign_penalties.feature @@ -31,12 +31,13 @@ Feature: Car - Handle stop signs | e | stop | | l | stop | + # TODO: stop signs with no direction has no any impact on routing at the moment When I route I should get | from | to | time | # | | 1 | 2 | 11.1s | no turn with no stop sign | - | 3 | 4 | 13.1s | no turn with stop sign | + | 3 | 4 | 11.1s | no turn with stop sign | | g | j | 18.7s | turn with no stop sign | - | k | n | 20.7s | turn with stop sign | + | k | n | 18.7s | turn with stop sign | Scenario: Car - Stop sign direction Given the node map @@ -68,8 +69,8 @@ Feature: Car - Handle stop signs | from | to | time | weight | # | | 1 | 2 | 11.1s | 11.1 | no turn with no stop sign | | 2 | 1 | 11.1s | 11.1 | no turn with no stop sign | - | 3 | 4 | 13.1s | 13.1 | no turn with stop sign | - | 4 | 3 | 13.1s | 13.1 | no turn with stop sign | + | 3 | 4 | 11.1s | 11.1 | no turn with stop sign | + | 4 | 3 | 11.1s | 11.1 | no turn with stop sign | | 5 | 6 | 13.1s | 13.1 | no turn with stop sign | | 6 | 5 | 11.1s | 11.1 | no turn with no stop sign | | 7 | 8 | 11.1s | 11.1 | no turn with no stop sign | diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index f40507a8856..76369f2cfa4 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -82,11 +82,13 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, { external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights}); } - if (result_node.give_way != TrafficFlowControlNodeDirection::NONE) + // TODO: we ignore `ALL` for both stop signs and give way signs, because we cannot understand direction of the way they should be applied yet + // see: https://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop#Direction + if (result_node.give_way != TrafficFlowControlNodeDirection::NONE && result_node.give_way != TrafficFlowControlNodeDirection::ALL) { external_memory.external_give_ways.push_back({id, result_node.give_way}); } - if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE) + if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE && result_node.stop_sign != TrafficFlowControlNodeDirection::ALL) { external_memory.external_stop_signs.push_back({id, result_node.stop_sign}); } diff --git a/unit_tests/extractor/graph_compressor.cpp b/unit_tests/extractor/graph_compressor.cpp index 128ed8e5261..f20a1fb14d1 100644 --- a/unit_tests/extractor/graph_compressor.cpp +++ b/unit_tests/extractor/graph_compressor.cpp @@ -66,6 +66,8 @@ BOOST_AUTO_TEST_CASE(long_road_test) std::unordered_set barrier_nodes; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::vector restrictions; std::vector annotations(1); CompressedEdgeContainer container; @@ -88,6 +90,8 @@ BOOST_AUTO_TEST_CASE(long_road_test) compressor.Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, @@ -112,6 +116,8 @@ BOOST_AUTO_TEST_CASE(loop_test) std::unordered_set barrier_nodes; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::vector restrictions; CompressedEdgeContainer container; std::vector annotations(1); @@ -148,6 +154,8 @@ BOOST_AUTO_TEST_CASE(loop_test) compressor.Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, @@ -175,6 +183,8 @@ BOOST_AUTO_TEST_CASE(t_intersection) std::unordered_set barrier_nodes; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::vector annotations(1); std::vector restrictions; CompressedEdgeContainer container; @@ -197,6 +207,8 @@ BOOST_AUTO_TEST_CASE(t_intersection) compressor.Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, @@ -218,6 +230,8 @@ BOOST_AUTO_TEST_CASE(street_name_changes) std::unordered_set barrier_nodes; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::vector annotations(2); std::vector restrictions; CompressedEdgeContainer container; @@ -236,6 +250,8 @@ BOOST_AUTO_TEST_CASE(street_name_changes) compressor.Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, @@ -256,6 +272,8 @@ BOOST_AUTO_TEST_CASE(direction_changes) std::unordered_set barrier_nodes; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::vector annotations(1); std::vector restrictions; CompressedEdgeContainer container; @@ -270,6 +288,8 @@ BOOST_AUTO_TEST_CASE(direction_changes) Graph graph(5, edges); compressor.Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index eb35730e1fb..6bf39570ca5 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -20,6 +20,9 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) { std::unordered_set barrier_nodes{6}; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; + std::vector annotations{ {EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}, {EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}}; @@ -87,6 +90,8 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) GraphCompressor().Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, @@ -153,6 +158,8 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) { std::unordered_set barrier_nodes; TrafficFlowControlNodes traffic_lights; + TrafficFlowControlNodes stop_signs; + TrafficFlowControlNodes give_way_signs; std::vector annotations; std::vector restrictions; CompressedEdgeContainer container; @@ -210,6 +217,8 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) GraphCompressor().Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, @@ -260,6 +269,8 @@ BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) { std::unordered_set barrier_nodes{1}; TrafficFlowControlNodes traffic_lights = {{2}, {}}; + TrafficFlowControlNodes stop_signs = {}; + TrafficFlowControlNodes give_way_signs = {}; std::vector annotations(1); std::vector restrictions; CompressedEdgeContainer container; @@ -309,6 +320,8 @@ BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) GraphCompressor().Compress(barrier_nodes, traffic_lights, + stop_signs, + give_way_signs, scripting_environment, restrictions, maneuver_overrides, From ee008e75e59046657e14a89f8c582551aa02feea Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 21:58:36 +0100 Subject: [PATCH 15/18] Take stop signs into account during routing --- src/extractor/extractor_callbacks.cpp | 11 +++++++---- unit_tests/extractor/intersection_analysis_tests.cpp | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 76369f2cfa4..8c0c1c47bb7 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -82,13 +82,16 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, { external_memory.external_traffic_signals.push_back({id, result_node.traffic_lights}); } - // TODO: we ignore `ALL` for both stop signs and give way signs, because we cannot understand direction of the way they should be applied yet - // see: https://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop#Direction - if (result_node.give_way != TrafficFlowControlNodeDirection::NONE && result_node.give_way != TrafficFlowControlNodeDirection::ALL) + // TODO: we ignore `ALL` for both stop signs and give way signs, because we cannot understand + // direction of the way they should be applied yet see: + // https://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop#Direction + if (result_node.give_way != TrafficFlowControlNodeDirection::NONE && + result_node.give_way != TrafficFlowControlNodeDirection::ALL) { external_memory.external_give_ways.push_back({id, result_node.give_way}); } - if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE && result_node.stop_sign != TrafficFlowControlNodeDirection::ALL) + if (result_node.stop_sign != TrafficFlowControlNodeDirection::NONE && + result_node.stop_sign != TrafficFlowControlNodeDirection::ALL) { external_memory.external_stop_signs.push_back({id, result_node.stop_sign}); } diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index 6bf39570ca5..fba37685c68 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) TrafficFlowControlNodes traffic_lights; TrafficFlowControlNodes stop_signs; TrafficFlowControlNodes give_way_signs; - + std::vector annotations{ {EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}, {EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}}; From 750826215f0f4a0ce90ee36671e7c8c84fe32d1a Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 22:00:24 +0100 Subject: [PATCH 16/18] Take stop signs into account during routing --- features/car/give_way_sign_penalties.feature | 4 ++-- profiles/car.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/car/give_way_sign_penalties.feature b/features/car/give_way_sign_penalties.feature index 4f9b45debba..c204de6a8e2 100644 --- a/features/car/give_way_sign_penalties.feature +++ b/features/car/give_way_sign_penalties.feature @@ -71,7 +71,7 @@ Feature: Car - Handle give way signs | 2 | 1 | 11.1s | 11.1 | no turn with no give way | | 3 | 4 | 11.1s | 11.1 | no turn with give way | | 4 | 3 | 11.1s | 11.1 | no turn with give way | - | 5 | 6 | 13.1s | 13.1 | no turn with give way | + | 5 | 6 | 12.6s | 12.6 | no turn with give way | | 6 | 5 | 11.1s | 11.1 | no turn with no give way | | 7 | 8 | 11.1s | 11.1 | no turn with no give way | - | 8 | 7 | 13.1s | 13.1 | no turn with give way | + | 8 | 7 | 12.6s | 12.6 | no turn with give way | diff --git a/profiles/car.lua b/profiles/car.lua index ddae81de820..1d415862658 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -31,7 +31,7 @@ function setup() left_hand_driving = false, traffic_light_penalty = 2, stop_sign_penalty = 2, - give_way_sign_penalty = 2 + give_way_sign_penalty = 1.5 }, default_mode = mode.driving, From 3f7a629db80e974374af936a233e1ec34dc5fe4a Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 22:22:40 +0100 Subject: [PATCH 17/18] Take stop signs into account during routing --- features/support/hooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/support/hooks.js b/features/support/hooks.js index 4a035554502..01c2e6e8921 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -51,7 +51,7 @@ module.exports = function () { .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); // uncomment to get path to logfile - console.log(' Writing logging output to ' + this.scenarioLogFile); + // console.log(' Writing logging output to ' + this.scenarioLogFile); }); this.After((scenario, callback) => { From 04ee126297e9eae749a71d49c198211f6ea05c83 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 31 Oct 2022 22:24:22 +0100 Subject: [PATCH 18/18] Take stop signs into account during routing --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf1c10381fd..b14dbba63fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - CHANGED: Make edge metrics strongly typed [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420) - FIXED: Typo in file name src/util/timed_historgram.cpp -> src/util/timed_histogram.cpp [#6428](https://github.com/Project-OSRM/osrm-backend/issues/6428) - Routing: + - ADDED: Stop and give way signs are now taken into account in car profile. [#6426](https://github.com/Project-OSRM/osrm-backend/pull/6426) - FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419) # 5.27.1 - Changes from 5.27.0