ElevationWeighting implementation and bike2

I started implementing a new elevation weighting prototype as I came the conclusion that the bike2 profile is not flexible enough. One, but not the only reason, was the findings for issue 330. Basically I just moved the speed calculation of bike2:applyWayTags to calcWeight of the new weighting. The weigthing can be dynamically influenced with the following ‘ascendAvoidance’ parameter:

// ascendAvoidance: 0 = don't include elevation to the weighting at all
// 1.0 avoid ascends by choosing long de-tours 
// -1.0 search for ascends

A value of 1.0 mimics the ‘bike2’ profile. The approach automatically provides elevation based weighting influence for all vehicle types. It comes with the drawback of slightly increased performance requirements and it currently only works in the flexibility mode.
What currently is also missing an adaptation of calcMillis to take the modified speed into regard. Here I probably might need some help, as this seems to be totally new and eventually requires bigger changes.

My question now is what the chances are that this gets merged if I prepare a PR later on.

As I haven’t used and understood the CH mode much. I also wanted to ask if there are chances somehow to completely get rid of the ‘bike2’ profile long term and using the described approach with a hard-coded value of ascendAvoidance=1. I believe that the answer to this question slightly influences how the slider for the ascendAvoidance should be best integrated into the web GUI.

Something like this will happen with the flexibility work in the near future. But it is very important that only a few parameters are influencing the weighting due to the critical performance

drawback of slightly increased performance requirements

how much and why :slight_smile: ?

Here I probably might need some help, as this seems to be totally new and eventually requires bigger changes.

Yes, also this will come. See [393][https://github.com/graphhopper/graphhopper/issues/393]

As I haven’t used and understood the CH mode much.

You are able to freeze one mode and use a lot faster routing.

using the described approach with a hard-coded value of ascendAvoidance=1.

That is the plan, yes. But even more dynamic. All vehicles will move into weightings and more values will be available without calculation in the flagencoder to make dynamic profile changes possible. And CH profiles will refer to one fixed parameter config.

Thank you for the explanation about the plan for the flexibility enhancements.

drawback of slightly increased performance requirements - how much and why :smile: ?

The performance requirements are higher because the calculation for the incline/decline of an edge is performed at calculation time and not already during graph preparation time. But I haven’t made any measurements. And the calculation is not complex, so it can’t be much. At least I didn’t notice any difference during my tests. But if I understood your answers about the CH mode correctly, then this seems to be true only for the flexibility mode, and not for the CH mode.

That is the plan, yes. But even more dynamic. All vehicles will move into weightings and more values will be available without calculation in the flagencoder to make dynamic profile changes possible. And CH profiles will refer to one fixed parameter config.

As it looks that the intended behavior will get included nearly automatically with the planned flexibility enhancements, I will not improve the prototype into a pull request and rather wait instead.

Thanks! The effort will be important once I have implemented a basic prototype of what I have in mind. This will happen hopefully within November.

At least I didn’t notice any difference during my tests.

you can easily test and compare via ./graphhopper.sh measurement your.pbf

But if I understood your answers about the CH mode correctly, then this seems to be true
only for the flexibility mode, and not for the CH mode.

In CH mode we currently have shortcuts and edges. And for shortcuts indeed a precalculated weight is used, but not so for the (rare) edges used while routing. But we could precalculate a weight here too, this would just increase the RAM usage per profile further. Not sure.

Best thing would be if these flexibility changes have only a slight performance impact on with and without routing (<10% slower).

you can easily test and compare via ./graphhopper.sh measurement your.pbf

I tried now. It does not work as it obviously is designed for car with 2D only. It is the problem described in issue 285. After makeing some code changes in the srcipt and tools I gave up. This is what I get now:

perform measurement via jar=> tools/target/graphhopper-tools-0.6-SNAPSHOT-jar-with-dependencies.jar and ARGS=> config=config.properties graph.location=/mnt/hgfs/osmdata/austria.osm-gh osmreader.osm=/mnt/hgfs/osmdata/austria.osm.pbf prepare.chWeighting=elevation graph.flagEncoders=bike Exception in thread "main" java.lang.IllegalStateException: Configured graph.chWeightings: [fastest|bike] is not equal to loaded []

Yes, this is not possible with other vehicles out of the box but should be easy to change.

I cannot see how this is related to 285 but we should make it a no-brainer maybe add this to 492

Finnaly I got the measurments running. I increased measurement.count to 50000. This is the original result for a fastest weighting run over austria.osm.obf:

routing.mean=522.1300511392

This is the value for dynamic elevation weighting: It is about factor 2 (100%) slower:

routing.mean=1082.2037116832

The relevant code can be found here: https://github.com/ratrun/graphhopper/blob/bike2improve/core/src/main/java/com/graphhopper/routing/util/EleWeighting.java

One possibility to increase the performance would be to pre-calculate a reverse and none reverse elevation weighting factor during graph generation and store it as part of the edge, such that this factor can get dynamically multiplied with ascendAvoidance during runtime. Or is there any better option?

It should go a lot faster without the fetchWayGeometry as the implementation does not use the pillar nodes. Just use graph.getNodeAccess with the adjNode and baseNode of the edge.

For the future we would need of course a more precise ele increase and decrease stored in the edge via preprocessing.

Thank you for this valueable hint. Just for my excuse: The fetchWayGeometry and pointlist code originated from bike2, so the performance could be improved there as well. With the proposed change I measured following result: routing.mean=653.4052024796, which is now only about 25% slower.

so the performance could be improved there as well.

sure, but on import other things are more critical and it would not improve much :wink:

which is now only about 25% slower.

nice, but I didn’t expect it that high, hmmh

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.