Take stop signs into account during routing

This commit is contained in:
Siarhei Fedartsou 2022-10-28 22:59:46 +02:00
parent 4432756de1
commit 350862d177
15 changed files with 104 additions and 19 deletions

View File

@ -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 |

View File

@ -71,6 +71,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const std::vector<util::Coordinate> &coordinates,
const NameTable &name_table,
const std::unordered_set<EdgeID> &segregated_edges,
@ -138,6 +139,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &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;

View File

@ -40,7 +40,7 @@ class ExtractionContainers
ReferencedWays IdentifyManeuverOverrideWays();
ReferencedTrafficFlowControlNodes IdentifyTrafficFlowControlNodes(
const std::vector<InputTrafficFlowControlNode> &external_stop_signs);
const std::vector<InputTrafficFlowControlNode> &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<InputTrafficFlowControlNode> external_give_ways;
TrafficFlowControlNodes internal_give_ways;
TrafficFlowControlNodes internal_give_way_signs;
std::vector<NodeBasedEdge> used_edges;

View File

@ -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<ExtractionTurnLeg> &roads_on_the_right,
const std::vector<ExtractionTurnLeg> &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

View File

@ -68,6 +68,7 @@ class Extractor
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
TrafficFlowControlNodes traffic_signals;
TrafficFlowControlNodes stop_signs;
TrafficFlowControlNodes give_way_signs;
std::unordered_set<NodeID> barriers;
std::vector<util::Coordinate> osm_coordinates;
extractor::PackedOSMIDs osm_node_ids;
@ -89,6 +90,7 @@ class Extractor
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const RestrictionGraph &restriction_graph,
const std::unordered_set<EdgeID> &segregated_edges,
const NameTable &name_table,

View File

@ -28,6 +28,7 @@ class GraphCompressor
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,

View File

@ -43,7 +43,7 @@ class NodeBasedGraphFactory
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
std::unordered_set<NodeID> &&barriers,
std::vector<util::Coordinate> &&coordinates,
extractor::PackedOSMIDs &&osm_node_ids,
@ -76,7 +76,8 @@ class NodeBasedGraphFactory
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &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

View File

@ -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

View File

@ -61,6 +61,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const std::vector<util::Coordinate> &coordinates,
const NameTable &name_table,
const std::unordered_set<EdgeID> &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

View File

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

View File

@ -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<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
const RestrictionGraph &restriction_graph,
const std::unordered_set<EdgeID> &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,

View File

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

View File

@ -24,6 +24,7 @@ static constexpr int SECOND_TO_DECISECOND = 10;
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
@ -223,11 +224,25 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &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<NodeID> &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<NodeID> &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

View File

@ -22,6 +22,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficFlowControlNodes &traffic_signals,
const TrafficFlowControlNodes &stop_signs,
const TrafficFlowControlNodes &give_way_signs,
std::unordered_set<NodeID> &&barriers,
std::vector<util::Coordinate> &&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<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &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,

View File

@ -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