opentripplanner / OpenTripPlanner

An open source multi-modal trip planner
http://www.opentripplanner.org
Other
2.15k stars 1.01k forks source link

U-turns not prevented at split edges #5955

Open hbruch opened 1 month ago

hbruch commented 1 month ago

Is your feature request related to a problem? Please describe. As a driver, I usually don't want to perform a U-turn. OTP's SimpleIntersectionTraversalCalculator currently provides costs for safe and accrossTraffic turns, but not for U-turns.

EDIT: U-turns are currently usually prevented by an isReverse check in StreetEdge.doTraverse() and state dominance checks. However, this fails under some very special conditions, e.g. when an edge is split by a linked transit stop and the dominance check allows visiting a vertex multiple times because the vertex is close to the request origin/destination. Splitting currently introduces two distinct split nodes so the isReverse check does not recognize the split forward/backward edges as reversed (see comment below).

Goal / high level use-case Preventing U-turns.

Describe the solution you'd like I suggest to add costs for U-turns (e.g. between 170 and 190 degrees) in SimpleIntersectionTraversalCalculator. I suggest to use the same split vertex for forward and backward edge.

Describe alternatives you've considered

Additional context The city of Aachen, Germany wants to inform their citizen about upcoming super block turn restrictions. For this use case, a custom OSM extract was generated, which contains these restrictions. Evaluating these restrictions, OTP's routing circumvents some of them suggesting U-turns:

grafik
hbruch commented 1 month ago

As discussed in todays developer meeting, the above routing behavior looks like a bug that should already be addressed in https://github.com/opentripplanner/OpenTripPlanner/blob/20fc8cea3723eb1aeac4a1df5470c70cca3aa6f2/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java#L1069-L1078

However, this apparently seems not to work in case of split edges, where forwardEdge and backwardEdge are split by different splitNodes:

image