Increasing speeds doesn't have the expected effect on duration

I’m trying to create custom routes for emergency vehicles.

I create a new FlagEncoder by copying the car flag encoder https://github.com/graphhopper/graphhopper/blob/master/core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java and modifying the speeds like so

double emergencyCarSpeedIncrease = 2;
// autobahn
defaultSpeedMap.put("motorway", (int) emergencyCarSpeedIncrease * 100);
defaultSpeedMap.put("motorway_link", (int) emergencyCarSpeedIncrease * 70);
...
maxPossibleSpeed = (int) emergencyCarSpeedIncrease * 140;
...

( I provided some additional implementation details here: Flexible / Configurable Weighting Update)

I would expect this to reduce the duration of trips by a bit less than half (I’m doubling the speeds but the turn costs are still the same) however the duration decreases less than expected:

Shorter trip: 2.7 minutes with car profile; 1.6 minutes with custom profile (59%)
Medium trip: 23 minutes with car profile; 21 minutes with custom profile (91%)
Longer trip: 129 minutes with car profile; 132 minutes with custom profile (102%)

Could you help point me in the right direction for how to get the desired result? Are there any resources or examples for how to do what I’m attempting? Any other files (or other places in the FlagEncoder file) that I should be adjusting?

Thanks in advance for any assistance!

For debugging it might help to enable ‘Local MVT’ from the layer menu (layer icon at the top right of your map). It should show the graphhopper route network and you can hover single streets to check if e.g. car.average_speed is what you expect it to be (you need to make the MVTResource return the path details for car.average_speed, the easiest you can do is replace the pathDetails list there with a list containing the string “car.average_speed”.

The ‘turn costs’ are only ‘turn restrictions’ (either you can do a turn or not so GH might return another route but it does not affect the travel time of a given route).

If you are doubling the speeds of all edges I would expect the durations to be exactly 50%. However, you might be running into accuracy issues when blindly doubling the speeds in defaultSpeedMap, because GH is trying to store the speeds with a minimal amount of memory (see speedBits/Factor in FlagEncoder).

1 Like

Another factor might be because we reduce the speed according to the allowed max speed on the road.

@easbar Thank you very much for your answer! I’m able to view the route network and see street properties when I hover over them after enabling ‘Local MVT’. I can see:

  • name: North Croatan Highway, US 158
  • road_environment: road
  • max_speed: 80
  • road_class: primary

Could you clarify what you mean by the comment below? Specifically, where “car.average_speed” should be placed; I see pathDetails in this file:https://github.com/graphhopper/graphhopper/blob/dfdd92cf5e0d7f2c6c2289b98b646dfb6cfd36c1/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java#L61 but I’m not sure how I should be modifying it (or if it the right file to modify).

Thanks!

Is there another place where I need to override this other than here: https://github.com/graphhopper/graphhopper/blob/master/core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java#L140?

Yeah honestly I had the same problem, but then I just added some code like this in MVTResource.java:

pathDetails = Arrays.asList("car.average_speed", "max_speed");

and if you use a debugger you can check what (other) encoded values are available in encodingManager#encodedValueMap.

@karussell is there a way to control this via the web UI? This would be pretty useful and the /mvt endpoint already supports it?

There is currently no way in the UI and would be nice to add it

@karussell and @easbar Thanks again for your help with this.

Summary:

Details:
Using the Local MVT in the web UI I was able to determine that:

  1. The duration works as expected (takes half the time with custom Emergency Vehicle profile) on roads where max_speed: infinity
  2. The duration does not work as expected (takes more than half the time with custom Emergency Vehicle profile) on roads where max_speed is set to a numeric value

so @karussell 's comment that, “Another factor might be because we reduce the speed according to the allowed max speed on the road.” seems to be the cause.

Any advice on how to address this? Here’s what I’ve tried:

I’ve looked through the code in graphhopper/core/src/main/java/com/graphhopper/routing/ for a way to override the max_speed field but didn’t find a way to fix the issue there. I tried changing this line, https://github.com/graphhopper/graphhopper/blob/d44bf427a66eaeda95101409d80382030dce5328/core/src/main/java/com/graphhopper/routing/weighting/custom/SpeedCalculator.java#L157 to just return speed rather than Math.min(speed, maxSpeed) but the maxSpeed there is actually the maxPossibleSpeed set in the ...FlagEncoder.java file and the speed is already set to be the OSM max_speed if that is lower than what we want based on the FlagEncoder.

UPDATE: I was able to override the max_speed from OSM and make all of them infinity by changing this https://github.com/graphhopper/graphhopper/blob/b15256635e179355563945d068fce87a6c58cd2d/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMaxSpeedParser.java#L57 to be -1. I’m able to check this with the Local MVT and it does in fact set max_speed to infinity. But the route times still aren’t as expected (for example longer routes, 1hr plus, are very close with standard car and emergency car profiles).

But did you not say above that “The duration works as expected (takes half the time with custom Emergency Vehicle profile) on roads where max_speed: infinity”? You mean now the MVT view says that max_speed is infinity but the duration is still not affected?

Powered by Discourse