Take stop signs into account during routing
This commit is contained in:
parent
4432756de1
commit
350862d177
39
features/car/give_way_sign_penalties.feature
Normal file
39
features/car/give_way_sign_penalties.feature
Normal 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 |
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user