New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add escalator reluctance parameter #5046
Add escalator reluctance parameter #5046
Conversation
We discussed this at today's dev meeting and we have come to the conclusion that we want to have a meeting to come up with a plan for further features around the StreetEdge first. @optionsome will fill you in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this issue today in a meeting and came to the conclusion that we should at least try to implement this as a EscalatorEdge instead of using the StreetEdge with escalator flag as the StreetEdge implements BikeWalkableEdge and it makes no sense in this case and the StreetEdge is already a big file so adding more logic into it is not ideal. Contrary to what I suggested in a private message a couple of weeks ago, we shouldn't create a BikeUnwalkableEdge but instead put the logic directly into EscalatorEdge.
@leonardehrenfried suggested that we should also ideally handle the other conveying tag values listed in https://wiki.openstreetmap.org/wiki/Key:conveying to handle one way escalators. conveying:reversible
and conveying:yes
should be handled both as bidirectional.
) { | ||
if (edgeIsStairs) { | ||
return pref.walk().stairsReluctance(); | ||
} else if (edgeIsEscalator) { | ||
if (traverseMode == TraverseMode.BICYCLE) return Double.POSITIVE_INFINITY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't use really high cost but instead prevent "bicycle walking" and cycling in escalators completely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I quickly tested this and it did seem to work so that only walking works. However, it also allowed traversal on wheelchairs which is wrong. The traversal permission map layer on the debug client showed the escalators as link (or maybe the edge was completely missing there). That code should be updated so it renders these edges with escalator text and maybe pink color like the stairs.
return ( | ||
"steps".equals(osmWay.getTag("highway")) && | ||
osmWay.getTag("conveying") != null && | ||
Set.of("yes", "forward", "backward", "reversible").contains(osmWay.getTag("conveying")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should set the escalator as one directional when the value is either forward
or backward
. There are probably some examples how it's done for one way streets in code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think you should have the method in the OSM way for checking if the way is an escalator (like you already have but slightly modify it).
/** | ||
* Contains the logic for extracting elevators out of OSM data | ||
*/ | ||
class EscalatorProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% sure if having an processor that goes through all the ways is the best solution or having some common top level processor for each way that then delegates the handling to separate processor based on some information. We can discuss this at a dev meeting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it makes sense not to go through all the ways for the escalators separately if it can be avoided. This could probably be done in the same function that generates the street edges as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could move the code that generates the StreetEdges into an own class (or classes) from the OsmModule and just initialize these processors in the OsmModule. I think you can iterate over the ways there and then just call either buildEscalatorEdge
or buildStreetEdge
method from one of those processor depending when is appropriate for the way.
@@ -252,7 +259,9 @@ private void buildBasicGraph() { | |||
params.banDiscouragedBiking(), | |||
issueStore | |||
); | |||
if (!OsmFilter.isWayRoutable(way) || permissions.allowsNothing()) continue; | |||
if ( | |||
!OsmFilter.isWayRoutable(way) || permissions.allowsNothing() || way.hasTag("conveying") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to use the isEscalator
method here as well from the OSMWay
class. Also, wrap the continue with {}
and put it on an own line (I know it was like this before but it shouldn't be).
src/main/java/org/opentripplanner/openstreetmap/model/OSMWay.java
Outdated
Show resolved
Hide resolved
private WalkPreferences() { | ||
this.speed = 1.33; | ||
this.reluctance = 2.0; | ||
this.boardCost = 60 * 10; | ||
this.stairsReluctance = 2.0; | ||
this.stairsTimeFactor = 3.0; | ||
this.safetyFactor = 1.0; | ||
this.escalatorReluctance = 2.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this value should be lower. Not quite sure what though. Kinda weird that the default for reluctance and stairsReluctance are the same. Maybe the stairsReluctance is added on top of the normal reluctance but I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We investigated the stairsReluctance a bit in the dev meeting and the cost comes from both the stairsReluctance and the stairsTimeFactor so the default reluctance value is probably approriate as is.
For the escalatorReluctance, maybe set this default value as 1.5.
@Override | ||
public State[] traverse(State s0) { | ||
// Only allow traversal by walking | ||
if (s0.getNonTransitMode() == TraverseMode.WALK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the getNonTransitMode WALK also when one is walking a bicycle or BICYCLE. Maybe it's just some flag set in the state data and the mode is still BICYCLE. I'm not sure. We should also block traversal on wheelchairs here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We think that the getNonTransitMode returns BICYCLE even when walking a bicycle so this code is probably right but the wheelchair should still be blocked somehow (there are probably examples in the street edge).
// Only allow traversal by walking | ||
if (s0.getNonTransitMode() == TraverseMode.WALK) { | ||
var s1 = s0.edit(this); | ||
var time = getDistanceMeters() / s0.getPreferences().walk().speed(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should consider that walk speed preference here at all? We could just have some static (maybe configurable) speed. I wonder if the speed is ever set through tagging in OSM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could try to search the internet if you can find what is usually the horizontal velocity of escalators and just use that as a static speed for the escalator instead of using the walk speed from preferences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still needs to be done.
src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java
Outdated
Show resolved
Hide resolved
@@ -778,6 +778,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa | |||
"Value should be between 0 and 1." + " If the value is set to be 0, safety is ignored." | |||
) | |||
.asDouble(dft.safetyFactor()) | |||
); | |||
) | |||
.withEscalatorReluctance(c.of("escalatorReluctance").asDouble(dft.escalatorReluctance())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a summary and also an example to https://github.com/opentripplanner/OpenTripPlanner/blob/8db191804459bdb027559361b19ef78c60cdadc4/src/test/resources/standalone/config/router-config.json#L1-L0 (which will then show up in the documentation).
import org.opentripplanner.street.search.state.State; | ||
|
||
/** Represents an escalator. An escalator edge can only be traversed by walking */ | ||
public class EscalatorEdge extends Edge { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test for this class. You can use PathwayEdgeTest
as a template.
Co-authored-by: Joel Lappalainen <lappalj8@gmail.com>
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## dev-2.x #5046 +/- ##
=============================================
- Coverage 65.60% 65.59% -0.02%
- Complexity 14656 14668 +12
=============================================
Files 1765 1767 +2
Lines 68455 68521 +66
Branches 7280 7291 +11
=============================================
+ Hits 44911 44947 +36
- Misses 21055 21078 +23
- Partials 2489 2496 +7
☔ View full report in Codecov by Sentry. |
@nurmAV I did a refactoring which will allow you to remove the |
Co-authored-by: Leonard Ehrenfried <mail@leonard.io>
Is there some command for this? I'm a bit confused by this error as when I run |
CI merges your branch and dev-2.x. It might be that that is the problem. To solve it merge dev-2.x into this branch and run |
@@ -22,6 +22,7 @@ name.ramp=Auffahrrampe | |||
name.link=Verbindung |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last request: please add a default translation for English. Then I'm happy to approve.
|
||
class EscalatorEdgeTest { | ||
|
||
Graph graph = new Graph(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Graph graph = new Graph(); |
You can remove the graph completely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this and I will approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
4d870cc
Summary
This PR adds a new parameter
escalatorReluctance
so that escalators can be treated differently than regular stairs in routing.Also disables bicycle walking in escalators.
Unit tests
Write a few words on how the new code is tested.
The changes were tested manually
Documentation
The parameter
escalatorReluctance
was added to documentation