Motorcycle profile speed section is ignored
NicholasRasi opened this issue · comments
Describe the bug
When using the suggested motorcycle profile, the resulting route duration is incorrect. In my opinion, this line { "if": "true", "multiply_by": "0.9 * car_average_speed" } produces a wrong result (the base speed is multiplied by 90% of the car_average_speed). However, the main bug is that if I change the speed section to { "if": "true", "limit_to": "car_average_speed" }, the resulting route time does not change. Meanwhile, if I append another custom_model_files with only the speed section, it works correctly.
To Reproduce
Steps to reproduce the behavior.
- checkout recent and stable version of GraphHopper v8
- pbf https://download.geofabrik.de/europe/italy/nord-ovest-latest.osm.pbf
config.yml
graphhopper:
datareader.file: "/mnt/disk/GRAPHHOPPER/nord-ovest-latest.osm.pbf"
graph.location: "/home/ubuntu/GRAPHHOPPER/graph-cache-2"
graph.vehicles: roads|transportation_mode=MOTORCYCLE|turn_costs=true,car,bike,foot
profiles:
# Moto Street
- name: motorcycle
vehicle: roads
weighting: custom
turn_costs: true
custom_model_files: [motorcycle.json]
profiles_lm:
- profile: motorcycle
graph.encoded_values: average_slope,curvature,hike_rating,max_slope,max_width,mtb_rating,surface,toll,track_type
Expected behavior
I expect that I can change the speed section of the motorcycle.json
file. It seems that the speed section of the first custom model file is ignored.
System Information
- Ubuntu 22
- Java 18
- GraphHopper v8.0
However, the main bug is that if I change the speed section to { "if": "true", "limit_to": "car_average_speed" }, the resulting route time does not change. Meanwhile, if I append another custom_model_files with only the speed section, it works correctly.
Can you explain what you did in detail to solve this?
In general the custom model for motorcycle is not yet production-ready. E.g. motorcycle access restrictions are not considered yet.
I append another custom model file (i.e. motorcycle_speed.json
) to the config file, as follow:
- name: motorcycle
vehicle: roads
weighting: custom
turn_costs: true
custom_model_files: [motorcycle.json,curvature.json,motorcycle_speed.json]
And set the speed in the motorcycle_speed.json
file
{
"speed": [
{ "if": "true", "limit_to": "car_average_speed" }
]
}
Hm, the correct way would be if the model starts with
{ "if": "true", "limit_to": "0.9 * car_average_speed" }
Here it is indeed the bug you mentioned ( multiply->limit_to ).
Can you retry without motorcycle_speed.json and you make sure that you remove the graph folder before you try again?
Yes, I already removed the cache and tried with
- name: motorcycle
vehicle: roads
weighting: custom
turn_costs: true
custom_model_files: [motorcycle.json,curvature.json]
motorcycle.json
{
"distance_influence": 90,
"priority": [
{ "if": "!car_access", "multiply_by": "0"},
{ "if": "track_type.ordinal() > 1", "multiply_by": "0" },
{ "if": "road_access == PRIVATE", "multiply_by": "0" },
{ "if": "road_class == MOTORWAY || road_class == TRUNK", "multiply_by": "0.1" }
// { "if": "urban_density != RURAL", "multiply_by": "0.3" },
],
"speed": [
{ "if": "true", "limit_to": "0.9 * car_average_speed" },
{ "if": "surface==COBBLESTONE || surface==GRASS || surface==GRAVEL || surface==SAND || surface==PAVING_STONES || surface==DIRT || >
"limit_to": "30"
}
]
}
but it does not work. It seems that the speed section of the first custom model is ignored. If I send the same json as custom model json at runtime, it works.
The traveling time is wrong.
Look, I define motorcycle.json
as
{
"distance_influence": 90,
"priority": [
{ "if": "!car_access", "multiply_by": "0"},
{ "if": "track_type.ordinal() > 1", "multiply_by": "0" },
{ "if": "road_access == PRIVATE", "multiply_by": "0" },
{ "if": "road_class == MOTORWAY || road_class == TRUNK", "multiply_by": "0.1" }
// { "if": "urban_density != RURAL", "multiply_by": "0.3" },
],
"speed": [
{ "if": "true", "limit_to": "0.9 * car_average_speed" },
{ "if": "surface==COBBLESTONE || surface==GRASS || surface==GRAVEL || surface==SAND || surface==PAVING_STONES || surface==DIRT || surface==GROUND || surface==UNPAVED || surface==COMPACTED",
"limit_to": "30"
}
]
}
Then, I make a request for this route
I get a traveling time of 8 min (that is wrong). If I send this custom model
{
"speed": [
{ "if": "true", "limit_to": "0.9 * car_average_speed" }
]
}
that is the same rule defined in motorcycle.json
I get the following:
And the traveling time is 18 min (correct).
The profile is defined as already mentioned
- name: motorcycle
vehicle: roads
weighting: custom
turn_costs: true
custom_model_files: [motorcycle.json,curvature.json]
(curvature.json does not add any speed rule)
Shouldn't it be the same?
What you see is that the (still) incorrect motorcycle.json is picked from the 8.0 jar and the limitation is basically only done from the statement if:true,limit_to:120
.
You can either use the latest master (where this is already fixed due to your request) or a correct motorcycle-fixed.json (don't forget to specify custom_models.directory: xy
) and this should no longer happen.
And yes, in general if you define a server-side custom model there is no need to send the custom model in the request and you are right that in the second case the query with "if": "true", "limit_to": "0.9 * car_average_speed"
should result in the same time, because the statement already exists on the server-side.
Please note that the statement order still can be important. So it matters if you first limit to X and multiply by Y or if you first do the multiplication and after that the limitation.
Thank you, so I suppose that if I set a motorcycle.json
in the custom_model_files
it takes the file picked from the jar, even if there exists a file with the same name in the folder specified by custom_models.directory: xy
. I didn't know that.
Maybe, it may be better to use the file defined by the user, if it is present. Or, it can be useful to write that in the documentation, but it is just a suggestion.
Yes and we should probably throw an exception to avoid the same name.
Ok, in my opinion there are two ways to solve the problem:
- throw an exception saying there is another custom model with the same name and exit
- read the user's file after the one loaded from the jar and merge them
This should be the interested code section
graphhopper/core/src/main/java/com/graphhopper/GraphHopper.java
Lines 1546 to 1570 in 3f741a7