Skip to content
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

Merged
merged 37 commits into from
Jan 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9792493
init commit
Jan 11, 2018
9450f13
prevent breaking API change
Jan 11, 2018
6775d86
set and store highway and access classification for the turn function
chaupow Jan 15, 2018
2a29c64
expose highway turn classification and access turn classification and…
chaupow Jan 15, 2018
329187c
expose whether connection road at turn is incoming or outgoing
chaupow Jan 15, 2018
2fd9442
small cleanup
chaupow Jan 17, 2018
76224ef
add lua tests for exposed information to turn function
chaupow Jan 17, 2018
096f86d
clang-format
chaupow Jan 17, 2018
9208fd7
remove mode in connected roads
chaupow Jan 17, 2018
69758c7
check lane numbers in tests
chaupow Jan 17, 2018
5767da9
update docs about attributes in process_turn
chaupow Jan 17, 2018
ac2846d
add turn_classification info to docs
chaupow Jan 17, 2018
3651f6b
small nitpicks and cleanup
chaupow Jan 17, 2018
0ad7169
review adjustments
chaupow Jan 18, 2018
09ff6ef
remove speed from node based edge and calculate from edge length and …
chaupow Jan 18, 2018
73c72ff
calculate speed by edge length and duration
chaupow Jan 18, 2018
62c089e
split roads on the left and roads on the right before running generat…
chaupow Jan 18, 2018
d1f3146
comment on u turns and empty roads_on_the_left
chaupow Jan 18, 2018
013d951
move profile to background
chaupow Jan 19, 2018
0611e55
move impl or setting info for connected edges
chaupow Jan 19, 2018
e51abc8
clang-format
chaupow Jan 19, 2018
3ee0d22
dirty commit! checking failing assertion
chaupow Jan 19, 2018
d339178
remove assertions for edge cases
chaupow Jan 19, 2018
430859c
less assertions
chaupow Jan 19, 2018
edc30b0
strange clang-format glitch
chaupow Jan 19, 2018
7898ccb
adding warning if uturn and intersection dont match
chaupow Jan 19, 2018
56754ea
handle u turns that do not turn into intersection[0]
chaupow Jan 19, 2018
939ac0f
attempt to make travis happy
chaupow Jan 22, 2018
989f633
try again
chaupow Jan 22, 2018
106874d
fix mismatch of arguments
chaupow Jan 22, 2018
98ca829
add changelog
chaupow Jan 19, 2018
271915e
add changelog
chaupow Jan 19, 2018
12629cd
fix changelog
chaupow Jan 23, 2018
dd61ce8
clang-format
chaupow Jan 23, 2018
a3de95c
fix typo and used std::transform instead of loop
chaupow Jan 24, 2018
9eb80ca
split OSM link generation in an accessible coordinate function
chaupow Jan 24, 2018
5550f76
guard transform when begin iterator is bigger than end iterator
chaupow Jan 24, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- Changes from 5.15.0:
- Profile:
- FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping.
- ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775)

# 5.15.0
- Changes from 5.14.3:
Expand Down Expand Up @@ -701,4 +702,4 @@
- `properties.traffic_signal_penalty`
- `properties.use_turn_restrictions`
- `properties.u_turn_penalty`
- `properties.allow_u_turn_at_via`
- `properties.allow_u_turn_at_via`
107 changes: 94 additions & 13 deletions docs/profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,100 @@ The `process_turn` function is called for every possible turn in the network. Ba

The following attributes can be read and set on the result in `process_turn`:

Attribute | Read/write? | Type | Notes
---------------------|-------------|---------|------------------------------------------------------
angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on)
number_of_roads | Read | Integer | Number of ways at the intersection of the turn
is_u_turn | Read | Boolean | Is the turn a u-turn?
has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `process_way`)
is_left_hand_driving | Read | Boolean | Is left-hand traffic?
weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
source_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
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 (`[-179, 180]`: `0`=straight, `180`=u turn, `+x`=x degrees to the right, `-x`= x degrees to the left)
number_of_roads | Read | Integer | Number of ways at the intersection of the turn
is_u_turn | Read | Boolean | Is the turn a u-turn?
has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
is_left_hand_driving | Read | Boolean | Is left-hand traffic?
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
source_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
source_is_motorway | Read | Boolean | Is the source road a motorway?
source_is_link | Read | Boolean | Is the source road a link?
source_number_of_lanes | Read | Integer | How many lanes does the source road have? (default when not tagged: 0)
source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
source_speed | Read | Integer | Speed on this source road in km/h
target_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
target_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
target_is_motorway | Read | Boolean | Is the target road a motorway?
target_is_link | Read | Boolean | Is the target road a link?
target_number_of_lanes | Read | Integer | How many lanes does the target road have? (default when not tagged: 0)
target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
target_speed | Read | Integer | Speed on this target road in km/h
roads_on_the_right | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the right of the turn that are also connected at the intersection
roads_on_the_left | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the left of the turn that are also connected at the intersection. If turn is a u turn, this is empty.
weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)

#### `roads_on_the_right` and `roads_on_the_left`

The information of `roads_on_the_right` and `roads_on_the_left` that can be read are as follows:

Attribute | Read/write? | Type | Notes
--------------------- | ------------- | --------- | ------------------------------------------------------
is_restricted | Read | Boolean | Is it a restricted access road? (See definition in `process_way`)
mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
is_motorway | Read | Boolean | Is the road a motorway?
is_link | Read | Boolean | Is the road a link?
number_of_lanes | Read | Integer | How many lanes does the road have? (default when not tagged: 0)
highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)
access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)
speed | Read | Integer | Speed on this road in km/h
is_incoming | Read | Boolean | Is the road an incoming road of the intersection
is_outgoing | Read | Boolean | Is the road an outgoing road of the intersection

The order of the roads in `roads_on_the_right` and `roads_on_the_left` are *counter clockwise*. If the turn is a u turn, all other connected roads will be in `roads_on_the_right`.

**Example**

```
c e
| /
| /
a ---- x ---- b
/|
/ |
f d


```
When turning from `a` to `b` via `x`,
* `roads_on_the_right[1]` is the road `xf`
* `roads_on_the_right[2]` is the road `xd`
* `roads_on_the_left[1]` is the road `xe`
* `roads_on_the_left[2]` is the road `xc`

Note that indices of arrays in lua are 1-based.

#### `highway_turn_classification` and `access_turn_classification`
When setting appropriate turn weights and duration, information about the highway and access tags of roads that are involved in the turn are necessary. The lua turn function `process_turn` does not have access to the original osrm tags anymore. However, `highway_turn_classification` and `access_turn_classification` can be set during setup. The classification set during setup can be later used in `process_turn`.

**Example**

In the following example we use `highway_turn_classification` to set the turn weight to `10` if the turn is on a highway and to `5` if the turn is on a primary.

```
function setup()
return {
highway_turn_classification = {
['motorway'] = 2,
['primary'] = 1
}
}
end

function process_turn(profile, turn) {
if turn.source_highway_turn_classification == 2 and turn.target_highway_turn_classification == 2 then
turn.weight = 10
end
if turn.source_highway_turn_classification == 1 and turn.target_highway_turn_classification == 1 then
turn.weight = 5
end
}
```

## Guidance
The guidance parameters in profiles are currently a work in progress. They can and will change.
Expand Down
176 changes: 176 additions & 0 deletions features/options/extract/turn_function.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
@routing @testbot @turn_function
Feature: Turn Function Information


Background:
Given the profile file
"""
functions = require('car')

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
}
"""

Scenario: Turns should have correct information of source and target
Given the node map
"""

a b c

"""
And the ways
| nodes | highway |
| ab | motorway |
| bc | motorway |
And the data has been saved to disk

When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "source_is_motorway true"
And stdout should contain "target_is_motorway true"
And stdout should contain "source_is_link false"
And stdout should contain "target_is_motorway true"
And stdout should contain "target_is_link false"


Scenario: Turns should detect when turn is leaving highway
Given the node map
"""

a b c

"""
And the ways
| nodes | highway | lanes |
| ab | motorway | 3 |
| bc | motorway_link | |

And the data has been saved to disk

When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "source_is_motorway true"
And stdout should contain "source_is_link false"
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"
And stdout should contain "target_number_of_lanes 0"
And stdout should contain "number_of_roads 2"

Scenario: Turns should have correct information of other roads at intersection I
Given the node map
"""
d
^
|
a->b->c
"""
And the ways
| nodes | highway | oneway |
| ab | primary | yes |
| bc | motorway | yes |
| bd | residential | yes |
And the data has been saved to disk

When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "number_of_roads 3"
# turning abd, give information about bc
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 4, access_turn_classification: 0/
# turning abc, give information about bd
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 1, access_turn_classification: 0/

Scenario: Turns should have correct information of other roads at intersection II
Given the node map
"""
d
|
v
a->b->c
"""
And the ways
| nodes | highway | oneway | access |
| ab | secondary | yes | |
| bc | motorway | yes | |
| db | unclassified | yes | discouraged |
And the data has been saved to disk

When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
And stdout should contain "number_of_roads 3"
# turning dbc, give information about about ab
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/
# turning abc, give information about about db
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/




2 changes: 2 additions & 0 deletions features/support/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ module.exports = function () {
.defer(mkdirp, logDir)
.defer(rimraf, this.scenarioLogFile)
.awaitAll(callback);
// uncomment to get path to logfile
// console.log(" Writing logging output to " + this.scenarioLogFile)
});

this.After((scenario, callback) => {
Expand Down
Loading