-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Making the turn function more flexible #4789
Conversation
6b7dcf3
to
a09d6ad
Compare
bool is_link, int number_of_lanes, int highway_turn_classification, int access_turn_classification, int speed) | ||
bool is_link, int number_of_lanes, | ||
int highway_turn_classification, | ||
int access_turn_classification, int speed, bool is_incoming, |
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 you also need incoming/outgoing status for other modes. e.g for bicycle routing you also need information about car traffic
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.
Thanks! I'll target that in another issue. I'd prefer getting the changes ready and see how these changes make a difference in better ETA & route planning & extraction memory usage peak. But your comment is well noted and will not be forgotten! :)
48e71da
to
8778c86
Compare
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.
Looks good to me, but some changes are needed as PR adds information about connected roads into ExtractionTurn
and this will cause a merge conflict with splitting of EBGF and guidance code.
docs/profiles.md
Outdated
target_mode | Read | Enum | Travel mode after the turn. Defined in `include/extractor/travel_mode.hpp` | ||
Attribute | Read/write? | Type | Notes | ||
--------------------- | ------------- | --------- | ------------------------------------------------------ | ||
angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on) |
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.
Angle in ExtractionTurn
is initialized with 180. - angle: 0
is straight on, positive values for right turns, negative values for left turns, 180 is a U-turn
Feature: Turn Function Information | ||
|
||
Scenario: Turns should have correct information of source and target | ||
Given the profile file |
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.
function test_setup()
profile = functions.setup()
profile.highway_turn_classification = {
['motorway'] = 4,
['motorway_link'] = 4,
['trunk'] = 4,
['trunk_link'] = 4,
['primary'] = 4,
['primary_link'] = 4,
['secondary'] = 3,
['secondary_link'] = 3,
['tertiary'] = 2,
['tertiary_link'] = 2,
['residential'] = 1,
['living_street'] = 1,
}
profile.access_turn_classification = {
['discouraged'] = 1;
['permissive'] = 1;
['private'] = 1;
['customers'] = 1;
['dismount'] = 1;
}
return profile
end
function turn_leg_string (leg)
return 'speed: ' .. tostring(leg.speed)
.. ', is_incoming: ' .. tostring(leg.is_incoming)
.. ', is_outgoing: ' .. tostring(leg.is_outgoing)
.. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification)
.. ', access_turn_classification: ' .. tostring(leg.access_turn_classification)
end
function print_turn (profile, turn)
print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted)))
print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway)))
print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link)))
print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes)))
print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification)))
print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification)))
print ('source_speed ' .. string.format("%s", tostring(turn.source_speed)))
print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted)))
print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway)))
print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link)))
print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes)))
print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification)))
print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification)))
print ('target_speed ' .. string.format("%s", tostring(turn.target_speed)))
print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads)))
if not turn.is_u_turn then
for roadCount, road in ipairs(turn.roads_on_the_right) do
print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road))
end
for roadCount, road in ipairs(turn.roads_on_the_left) do
print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road))
end
end
end
return {
setup = test_setup,
process_way = functions.process_way,
process_node = functions.process_node,
process_turn = print_turn
}
"""
</details>
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 thanks 👍
profiles/feature/car_turnbot.lua
Outdated
@@ -0,0 +1,483 @@ | |||
-- Adjusted car profile with print output for testing |
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.
The file can be easily out of sync with the original car profile. I would suggest to load car profile functions and set testing functions directly in the feature file.
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 👍
@@ -27,6 +27,9 @@ struct NodeBasedEdgeClassification | |||
std::uint8_t startpoint : 1; // 1 | |||
std::uint8_t restricted : 1; // 1 | |||
guidance::RoadClassification road_classification; // 16 2 | |||
std::uint8_t highway_turn_classification : 4; // 4 | |||
std::uint8_t access_turn_classification : 4; // 4 | |||
std::uint8_t speed; // 8 |
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.
speed
can be moved to NodeBasedEdge
and grouped with weight
and duration
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 tried calculating speed by edge length and duration. Many calculated speeds are within 10% of the actual speed. Some are not. Here is an extract of the differences running on Berlin:
calculated speed 50.000792 real speed 56
calculated speed 41.707704 real speed 48
calculated speed 41.707704 real speed 48
calculated speed 41.707704 real speed 48
calculated speed 30.748476 real speed 40
calculated speed 30.748476 real speed 40
calculated speed 32.505609 real speed 40
calculated speed 32.505609 real speed 40
calculated speed 30.754826 real speed 48
calculated speed 30.754826 real speed 48
calculated speed 30.754826 real speed 48
calculated speed 31.699496 real speed 40
calculated speed 31.699496 real speed 40
calculated speed 19.930782 real speed 25
calculated speed 19.930782 real speed 25
calculated speed 26.538870 real speed 55
calculated speed 26.538870 real speed 55
calculated speed 26.538870 real speed 55
calculated speed 19.930782 real speed 25
in favour of using less memory, @oxidase do you think this is preferable?
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.
@chaupow both speeds values have different meaning. For example, an NBG edge from https://www.openstreetmap.org/node/5339762636 to https://www.openstreetmap.org/node/1736058469 consists of two segments:
- a part of https://www.openstreetmap.org/way/27801361 with profile speed 40 kmh (maxspeed=50)
- a part of https://www.openstreetmap.org/way/168945697 with profile speed 24 kmh (maxspeed=30)
The speed
value of the NBG edge is 40 kmh as the value of the first smaller segment.
The computed speed value is an average that also includes traffic light penalties.
In the example, the average speed is 26.44 kmh without traffic light penalty and 19.39 kmh with 2 seconds traffic light penalty.
I think average values are preferable over speed values of single segments.
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 average values are preferable over speed values of single segments.
Agreed! Done thanks 👍
@@ -405,6 +405,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti | |||
forward_classes, | |||
parsed_way.forward_travel_mode, | |||
parsed_way.is_left_hand_driving}); | |||
|
|||
std::uint8_t speed = parsed_way.forward_speed > 255 ? 255 : parsed_way.forward_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.
here can be speed = std::min(parsed_way.forward_speed, 255)
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 👍
return road.eid == turn.eid; | ||
}); | ||
|
||
// if the turn is a u turn, store all information in road_legs_on_the_right |
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.
Here can be an edge case for U-turns in left-driving countries.
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.
Do you think I should change this in left-driving countries?
I wonder whether it is important whether roads are on the left or right when you do a u turn and want to assign turn weights for u turns. Maybe it doesn't really matter 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.
agree, it should not matter, but would good to mention u-turns in the description of ExtractionTurn:roads_on_the_right
property
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.
@@ -562,7 +562,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( | |||
const auto node_based_edge_to, | |||
const auto incoming_bearing, | |||
const auto &turn, | |||
const auto entry_class_id) { | |||
const auto entry_class_id, | |||
const auto &intersection) { |
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 change conflicts with #4674 which removes guidance intersections analysis code from the edge-based-graph factory. To resolve the conflict a convertToIntersectionView
call must be included back in #4674 and intersection_view
must be used instead of intersection
.
I would suggest to move initialization of road_legs_on_the_right
and road_legs_on_the_left
vectors out of the lambda and split intersection
into two arrays after lines
osrm-backend/src/extractor/edge_based_graph_factory.cpp
Lines 860 to 865 in 8778c86
const auto turn = | |
std::find_if(intersection.begin(), | |
intersection.end(), | |
[edge = outgoing_edge.edge](const auto &road) { | |
return road.eid == 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.
profiles/lib/way_handlers.lua
Outdated
local access = way:get_value_by_key("access") | ||
|
||
if profile.highway_turn_classification[highway] then | ||
assert(profile.highway_turn_classification[highway] < 16, "highway_turn_classification must be smaller than 16") |
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.
Asserts can can be directly checked before assignments below.
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 👍
features/support/hooks.js
Outdated
@@ -50,6 +50,9 @@ module.exports = function () { | |||
.defer(mkdirp, logDir) | |||
.defer(rimraf, this.scenarioLogFile) | |||
.awaitAll(callback); | |||
// Question @review is this line nice to have here (commented, but ready to use and uncomment if needed?) | |||
// i think this is super useful and would love to have it here | |||
// console.log(" Writing logging output to " + this.scenarioLogFile) |
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.
👍
And stdout should contain "source_number_of_lanes 3" | ||
And stdout should contain "target_is_motorway false" | ||
And stdout should contain "target_is_link true" | ||
# Question @review: should number_of_lanes when untagged be 0 or 1? |
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.
👍 for using 0 number of lanes when untagged, otherwise number_of_lanes=1
would mean both untagged lanes and one lane cases.
I compared RAM peak usage during
|
… speed to the lua profile turn function
d0354d4
to
d239814
Compare
49efaeb
to
5550f76
Compare
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.
Looks good!
Issue
Targeting issue #4775
In short: The goal is to make the turn function in lua profiles more flexible and powerful by exposing more information to it.
Tasklist
Requirements / Relations
maybe none