start of four way turns
This commit is contained in:
		
							parent
							
								
									a1f1da4c16
								
							
						
					
					
						commit
						92b4f14db6
					
				| @ -111,10 +111,11 @@ bool isMotorwayJunction(const NodeID from, | ||||
|                         const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); | ||||
| 
 | ||||
| // Decide whether a turn is a turn or a ramp access
 | ||||
| TurnType turnOrRamp(const NodeID from, | ||||
|                     const EdgeID via_edge, | ||||
|                     const TurnCandidate &candidate, | ||||
|                     const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); | ||||
| TurnType | ||||
| findBasicTurnType(const NodeID from, | ||||
|                   const EdgeID via_edge, | ||||
|                   const TurnCandidate &candidate, | ||||
|                   const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); | ||||
| 
 | ||||
| // Get the Instruction for an obvious turn
 | ||||
| // Instruction will be a silent instruction
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ | ||||
| 
 | ||||
| #include <cstddef> | ||||
| #include <limits> | ||||
| #include <iomanip> | ||||
| 
 | ||||
| namespace osrm | ||||
| { | ||||
| @ -23,6 +24,7 @@ const double constexpr STRAIGHT_ANGLE = 180.; | ||||
| const double constexpr MAXIMAL_ALLOWED_NO_TURN_DEVIATION = 2.; | ||||
| // angle that lies between two nearly indistinguishable roads
 | ||||
| const double constexpr NARROW_TURN_ANGLE = 35.; | ||||
| const double constexpr WELL_DISTINCT_ANGLE = 50; | ||||
| // angle difference that can be classified as straight, if its the only narrow turn
 | ||||
| const double constexpr FUZZY_ANGLE_DIFFERENCE = 15.; | ||||
| const double constexpr DISTINCTION_RATIO = 2; | ||||
| @ -105,37 +107,35 @@ getTurns(const NodeID from, | ||||
|     } | ||||
| 
 | ||||
|     if (detail::isBasicJunction(from, via_edge, turn_candidates, node_based_graph) && | ||||
|         turn_candidates.size() <= 3) // TODO change when larger junctions are handled
 | ||||
|         turn_candidates.size() <= 4) // TODO change when larger junctions are handled
 | ||||
|     { | ||||
|         if (turn_candidates.size() == 1) | ||||
|         { | ||||
|             return detail::handleOneWayTurn(from, via_edge, std::move(turn_candidates), | ||||
|                                             node_based_graph); | ||||
|             turn_candidates = detail::handleOneWayTurn(from, via_edge, std::move(turn_candidates), | ||||
|                                                        node_based_graph); | ||||
|         } | ||||
|         if (turn_candidates.size() == 2) | ||||
|         { | ||||
|             return detail::handleTwoWayTurn(from, via_edge, std::move(turn_candidates), | ||||
|                                             node_based_graph); | ||||
|             turn_candidates = detail::handleTwoWayTurn(from, via_edge, std::move(turn_candidates), | ||||
|                                                        node_based_graph); | ||||
|         } | ||||
|         if (turn_candidates.size() == 3) | ||||
|         { | ||||
|             return detail::handleConflicts( | ||||
|                 from, via_edge, detail::handleThreeWayTurn( | ||||
|                                     from, via_edge, std::move(turn_candidates), node_based_graph), | ||||
|                 node_based_graph); | ||||
|             detail::handleThreeWayTurn(from, via_edge, std::move(turn_candidates), | ||||
|                                        node_based_graph); | ||||
|         } | ||||
|         if (turn_candidates.size() == 4) | ||||
|         { | ||||
|             return detail::handleConflicts( | ||||
|                 from, via_edge, detail::handleFourWayTurn( | ||||
|                                     from, via_edge, std::move(turn_candidates), node_based_graph), | ||||
|                 node_based_graph); | ||||
|             detail::handleFourWayTurn(from, via_edge, std::move(turn_candidates), node_based_graph); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             turn_candidates = detail::handleComplexTurn(from, via_edge, std::move(turn_candidates), | ||||
|                                                         node_based_graph); | ||||
|         } | ||||
|         // complex intersection, potentially requires conflict resolution
 | ||||
|         return detail::handleConflicts( | ||||
|             from, via_edge, | ||||
|             detail::handleComplexTurn(from, via_edge, std::move(turn_candidates), node_based_graph), | ||||
|             node_based_graph); | ||||
|         return detail::handleConflicts(from, via_edge, std::move(turn_candidates), | ||||
|                                        node_based_graph); | ||||
|     } | ||||
| 
 | ||||
| #if PRINT_DEBUG_CANDIDATES | ||||
| @ -413,9 +413,10 @@ handleFromMotorway(const NodeID from, | ||||
|             // FALLBACK, this should hopefully never be reached
 | ||||
|             auto coord = localizer(node_based_graph->GetTarget(via_edge)); | ||||
|             util::SimpleLogger().Write(logWARNING) | ||||
|                 << "Fallback reached from motorway at " << toFloating(coord.lat) << " " | ||||
|                 << toFloating(coord.lon) << ", no continue angle, " << turn_candidates.size() | ||||
|                 << " candidates, " << countValid(turn_candidates) << " valid ones."; | ||||
|                 << "Fallback reached from motorway at " << std::setprecision(12) | ||||
|                 << toFloating(coord.lat) << " " << toFloating(coord.lon) << ", no continue angle, " | ||||
|                 << turn_candidates.size() << " candidates, " << countValid(turn_candidates) | ||||
|                 << " valid ones."; | ||||
|             fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph); | ||||
|         } | ||||
|     } | ||||
| @ -554,8 +555,8 @@ handleFromMotorway(const NodeID from, | ||||
|                 auto coord = localizer(node_based_graph->GetTarget(via_edge)); | ||||
|                 util::SimpleLogger().Write(logWARNING) | ||||
|                     << "Found motorway junction with more than " | ||||
|                        "2 exiting motorways or additional ramps at " << toFloating(coord.lat) << " " | ||||
|                     << toFloating(coord.lon); | ||||
|                        "2 exiting motorways or additional ramps at " << std::setprecision(12) | ||||
|                     << toFloating(coord.lat) << " " << toFloating(coord.lon); | ||||
|                 fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph); | ||||
|             } | ||||
|         } // done for more than one highway exit
 | ||||
| @ -652,8 +653,7 @@ handleMotorwayRamp(const NodeID from, | ||||
|             if (isMotorwayClass(turn_candidates[1].eid, node_based_graph) && | ||||
|                 isMotorwayClass(turn_candidates[2].eid, node_based_graph)) | ||||
|             { | ||||
|                 assignFork(via_edge, turn_candidates[2], turn_candidates[1], | ||||
|                            node_based_graph); | ||||
|                 assignFork(via_edge, turn_candidates[2], turn_candidates[1], node_based_graph); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @ -818,18 +818,28 @@ bool isMotorwayJunction(const NodeID from, | ||||
|            in_data.road_classification.road_class == FunctionalRoadClass::TRUNK; | ||||
| } | ||||
| 
 | ||||
| TurnType turnOrRamp(const NodeID from, | ||||
|                     const EdgeID via_edge, | ||||
|                     const TurnCandidate &candidate, | ||||
|                     const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) | ||||
| TurnType | ||||
| findBasicTurnType(const NodeID from, | ||||
|                   const EdgeID via_edge, | ||||
|                   const TurnCandidate &candidate, | ||||
|                   const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) | ||||
| { | ||||
|     bool on_ramp = | ||||
|         isRampClass(node_based_graph->GetEdgeData(via_edge).road_classification.road_class); | ||||
|     const auto &in_data = node_based_graph->GetEdgeData(via_edge); | ||||
|     const auto &out_data = node_based_graph->GetEdgeData(candidate.eid); | ||||
| 
 | ||||
|     bool onto_ramp = | ||||
|         isRampClass(node_based_graph->GetEdgeData(candidate.eid).road_classification.road_class); | ||||
|     bool on_ramp = isRampClass(in_data.road_classification.road_class); | ||||
| 
 | ||||
|     return (!on_ramp && onto_ramp) ? TurnType::Ramp : TurnType::Turn; | ||||
|     bool onto_ramp = isRampClass(out_data.road_classification.road_class); | ||||
| 
 | ||||
|     if (!onto_ramp && onto_ramp) | ||||
|         return TurnType::Ramp; | ||||
| 
 | ||||
|     if (in_data.name_id == out_data.name_id && in_data.name_id != INVALID_NAME_ID) | ||||
|     { | ||||
|         return TurnType::Continue; | ||||
|     } | ||||
| 
 | ||||
|     return TurnType::Turn; | ||||
| } | ||||
| 
 | ||||
| TurnInstruction | ||||
| @ -862,7 +872,7 @@ getInstructionForObvious(const NodeID from, | ||||
|                          const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) | ||||
| { | ||||
| 
 | ||||
|     if (turnOrRamp(from, via_edge, candidate, node_based_graph) == TurnType::Turn) | ||||
|     if (findBasicTurnType(from, via_edge, candidate, node_based_graph) == TurnType::Turn) | ||||
|     { | ||||
|         return noTurnOrNewName(from, via_edge, candidate, node_based_graph); | ||||
|     } | ||||
| @ -943,7 +953,8 @@ handleThreeWayTurn(const NodeID from, | ||||
|     { | ||||
|         if (turn_candidates[1].valid && turn_candidates[2].valid) | ||||
|         { | ||||
|             if (TurnType::Turn == turnOrRamp(from, via_edge, turn_candidates[1], node_based_graph)) | ||||
|             if (TurnType::Turn == | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[1], node_based_graph)) | ||||
|             { | ||||
|                 if (angularDeviation(turn_candidates[1].angle, STRAIGHT_ANGLE) < | ||||
|                     MAXIMAL_ALLOWED_NO_TURN_DEVIATION) | ||||
| @ -961,7 +972,8 @@ handleThreeWayTurn(const NodeID from, | ||||
|             else | ||||
|                 turn_candidates[1].instruction = {TurnType::Ramp, DirectionModifier::SlightRight}; | ||||
| 
 | ||||
|             if (TurnType::Turn == turnOrRamp(from, via_edge, turn_candidates[2], node_based_graph)) | ||||
|             if (TurnType::Turn == | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[2], node_based_graph)) | ||||
|             { | ||||
|                 if (angularDeviation(turn_candidates[2].angle, STRAIGHT_ANGLE) < | ||||
|                     MAXIMAL_ALLOWED_NO_TURN_DEVIATION) | ||||
| @ -1003,14 +1015,16 @@ handleThreeWayTurn(const NodeID from, | ||||
|     { | ||||
|         if (turn_candidates[1].valid) | ||||
|         { | ||||
|             if (TurnType::Turn == turnOrRamp(from, via_edge, turn_candidates[1], node_based_graph)) | ||||
|             if (TurnType::Ramp != | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[1], node_based_graph)) | ||||
|                 turn_candidates[1].instruction = {TurnType::EndOfRoad, DirectionModifier::Right}; | ||||
|             else | ||||
|                 turn_candidates[1].instruction = {TurnType::Ramp, DirectionModifier::Right}; | ||||
|         } | ||||
|         if (turn_candidates[2].valid) | ||||
|         { | ||||
|             if (TurnType::Turn == turnOrRamp(from, via_edge, turn_candidates[2], node_based_graph)) | ||||
|             if (TurnType::Ramp != | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[2], node_based_graph)) | ||||
|                 turn_candidates[2].instruction = {TurnType::EndOfRoad, DirectionModifier::Left}; | ||||
|             else | ||||
|                 turn_candidates[2].instruction = {TurnType::Ramp, DirectionModifier::Left}; | ||||
| @ -1028,7 +1042,8 @@ handleThreeWayTurn(const NodeID from, | ||||
|     { | ||||
|         if (turn_candidates[1].valid) | ||||
|         { | ||||
|             if (turnOrRamp(from, via_edge, turn_candidates[1], node_based_graph) == TurnType::Turn) | ||||
|             if (TurnType::Ramp != | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[1], node_based_graph)) | ||||
|                 turn_candidates[1].instruction = | ||||
|                     getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph); | ||||
|             else | ||||
| @ -1037,7 +1052,7 @@ handleThreeWayTurn(const NodeID from, | ||||
|         if (turn_candidates[2].valid) | ||||
|         { | ||||
|             turn_candidates[2].instruction = { | ||||
|                 turnOrRamp(from, via_edge, turn_candidates[2], node_based_graph), | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[2], node_based_graph), | ||||
|                 DirectionModifier::Left}; | ||||
|         } | ||||
|     } | ||||
| @ -1057,7 +1072,7 @@ handleThreeWayTurn(const NodeID from, | ||||
|                 getInstructionForObvious(from, via_edge, turn_candidates[2], node_based_graph); | ||||
|         if (turn_candidates[1].valid) | ||||
|             turn_candidates[1].instruction = { | ||||
|                 turnOrRamp(from, via_edge, turn_candidates[1], node_based_graph), | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[1], node_based_graph), | ||||
|                 DirectionModifier::Right}; | ||||
|     } | ||||
|     // merge onto a through street
 | ||||
| @ -1166,7 +1181,82 @@ handleFourWayTurn(const NodeID from, | ||||
|                   std::vector<TurnCandidate> turn_candidates, | ||||
|                   const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) | ||||
| { | ||||
| 
 | ||||
|     static int fallback_count = 0; | ||||
|     // basic turn, or slightly rotated basic turn, has straight ANGLE
 | ||||
|     if (angularDeviation(turn_candidates[2].angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE && | ||||
|         angularDeviation(turn_candidates[0].angle, turn_candidates[1].angle) > NARROW_TURN_ANGLE && | ||||
|         angularDeviation(turn_candidates[1].angle, turn_candidates[2].angle) > NARROW_TURN_ANGLE && | ||||
|         angularDeviation(turn_candidates[2].angle, turn_candidates[3].angle) > NARROW_TURN_ANGLE && | ||||
|         angularDeviation(turn_candidates[3].angle, turn_candidates[0].angle) > NARROW_TURN_ANGLE) | ||||
|     { | ||||
|         { // Right
 | ||||
|             const auto type = | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[1], node_based_graph); | ||||
|             turn_candidates[1].instruction = {type, DirectionModifier::Right}; | ||||
|         } | ||||
|         { // Straight
 | ||||
|             turn_candidates[2].instruction = | ||||
|                 getInstructionForObvious(from, via_edge, turn_candidates[2], node_based_graph); | ||||
|         } | ||||
|         { // Left
 | ||||
|             const auto type = | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[3], node_based_graph); | ||||
|             turn_candidates[3].instruction = {type, DirectionModifier::Left}; | ||||
|         } | ||||
|     } | ||||
|     // well differentiated turns
 | ||||
|     else if (angularDeviation(turn_candidates[1].angle, turn_candidates[2].angle) > | ||||
|                  WELL_DISTINCT_ANGLE && | ||||
|              angularDeviation(turn_candidates[2].angle, turn_candidates[3].angle) > | ||||
|                  WELL_DISTINCT_ANGLE) | ||||
|     { | ||||
|         for (std::size_t i = 1; i < turn_candidates.size(); ++i) | ||||
|         { | ||||
|             const auto type = | ||||
|                 findBasicTurnType(from, via_edge, turn_candidates[i], node_based_graph); | ||||
|             turn_candidates[i].instruction = {type, getTurnDirection(turn_candidates[i].angle)}; | ||||
|         } | ||||
|     } | ||||
|     //  *     *
 | ||||
|     //  *   *
 | ||||
|     //  * *
 | ||||
|     //  * *
 | ||||
|     //  *   *
 | ||||
|     //  *     *
 | ||||
|     // Two roads at the right side of a street
 | ||||
|     else if ( false && angularDeviation(turn_candidates[3].angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE) | ||||
|     { | ||||
|         //currently unhandled
 | ||||
|     } | ||||
|     //  *     *
 | ||||
|     //    *   *
 | ||||
|     //      * *
 | ||||
|     //      * *
 | ||||
|     //    *   *
 | ||||
|     //  *     *
 | ||||
|     // Two roads at the left side of a street
 | ||||
|     else if ( false && angularDeviation(turn_candidates[1].angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE) | ||||
|     { | ||||
|         //currently unhandled
 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (fallback_count++ < 10) | ||||
|         { | ||||
|             const auto coord = localizer(node_based_graph->GetTarget(via_edge)); | ||||
|             util::SimpleLogger().Write(logWARNING) | ||||
|                 << "Resolved to keep fallback on four way turn assignment at " | ||||
|                 << std::setprecision(12) << toFloating(coord.lat) << " " << toFloating(coord.lon); | ||||
|             for (const auto &candidate : turn_candidates) | ||||
|             { | ||||
|                 const auto &out_data = node_based_graph->GetEdgeData(candidate.eid); | ||||
|                 util::SimpleLogger().Write(logWARNING) | ||||
|                     << "Candidate: " << candidate.toString() << " Name: " << out_data.name_id | ||||
|                     << " Road Class: " << (int)out_data.road_classification.road_class | ||||
|                     << " At: " << localizer(node_based_graph->GetTarget(candidate.eid)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| #if PRINT_DEBUG_CANDIDATES | ||||
|     std::cout << "Basic Turn Candidates:\n"; | ||||
|     for (auto tc : turn_candidates) | ||||
| @ -1319,8 +1409,8 @@ optimizeCandidates(const EdgeID via_eid, | ||||
|         { | ||||
|             util::SimpleLogger().Write(logWARNING) | ||||
|                 << "[warning] conflicting turn angles, identical road duplicated? " | ||||
|                 << node_info_list[node_based_graph->GetTarget(via_eid)].lat << " " | ||||
|                 << node_info_list[node_based_graph->GetTarget(via_eid)].lon << std::endl; | ||||
|                 << std::setprecision(12) << node_info_list[node_based_graph->GetTarget(via_eid)].lat | ||||
|                 << " " << node_info_list[node_based_graph->GetTarget(via_eid)].lon << std::endl; | ||||
|         } | ||||
|         if (isConflict(turn.instruction, left.instruction)) | ||||
|         { | ||||
| @ -1972,7 +2062,7 @@ void assignFork(const EdgeID via_edge, | ||||
|     const auto &in_data = node_based_graph->GetEdgeData(via_edge); | ||||
|     { // left fork
 | ||||
|         const auto &out_data = node_based_graph->GetEdgeData(left.eid); | ||||
|         if (angularDeviation(left.angle, 180) < FUZZY_ANGLE_DIFFERENCE) | ||||
|         if (angularDeviation(left.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) | ||||
|         { | ||||
|             if (requiresAnnouncedment(in_data, out_data)) | ||||
|             { | ||||
| @ -1990,7 +2080,7 @@ void assignFork(const EdgeID via_edge, | ||||
|     } | ||||
|     { // right fork
 | ||||
|         const auto &out_data = node_based_graph->GetEdgeData(right.eid); | ||||
|         if (angularDeviation(right.angle, 180) < FUZZY_ANGLE_DIFFERENCE) | ||||
|         if (angularDeviation(right.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) | ||||
|         { | ||||
|             if (requiresAnnouncedment(in_data, out_data)) | ||||
|             { | ||||
| @ -2015,7 +2105,7 @@ void assignFork(const EdgeID via_edge, | ||||
|                 const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) | ||||
| { | ||||
|     left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; | ||||
|     if (angularDeviation(center.angle, 180) < FUZZY_ANGLE_DIFFERENCE) | ||||
|     if (angularDeviation(center.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) | ||||
|     { | ||||
|         const auto &in_data = node_based_graph->GetEdgeData(via_edge); | ||||
|         const auto &out_data = node_based_graph->GetEdgeData(center.eid); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user