-
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
Support manual instruction type override relations #4676
Conversation
} | ||
}; | ||
|
||
const auto string_to_turn_direction = [](const std::string &direction_string) { |
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 here we will also need to pass in the turn_string
to be able to set a uturn
direction modifier
72220ed
to
1be89bb
Compare
@danpat Do you have some unpushed additions to the IO operations for reading/writing maneuver overrides? Locally and on every travis build I'm seeing a
error, where it looks like we're missing the |
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.
Also see the comment about the missing overrides io methods!
# Testing disconnected via ways (first turn is only modified if you end up | ||
# on a particular way) | ||
# | h,a | J Street,C Street,A Street,A Street | depart,turn left,turn left,arrive | | ||
# | h,e | J Street,C Street,B Street,B Street | depart,turn sharp left,turn left,arrive | |
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.
Should these tests pass? Should we add a test that makes sure the first turn is not modified when the ending street is not in the maneuver? e.g. j -> e
should return depart,turn right,arrive
include/engine/api/route_api.hpp
Outdated
@@ -101,6 +104,27 @@ class RouteAPI : public BaseAPI | |||
const std::vector<bool> &source_traversed_in_reverse, | |||
const std::vector<bool> &target_traversed_in_reverse) const | |||
{ | |||
for (const auto &a : unpacked_path_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.
Should this logging be wrapped into debug output only?
include/engine/api/route_api.hpp
Outdated
++route_iter; | ||
continue; | ||
} | ||
// Skip over duplicated EBNs in the step array |
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.
When would the EBNs in the step array be duplicated?
include/engine/api/route_api.hpp
Outdated
const auto via_node_coords = BaseAPI::facade.GetCoordinateOfNode( | ||
maneuver_relation.instruction_node); | ||
// Find the step that has the instruction_node at the intersection point | ||
auto step_to_update = std::find_if( |
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.
Thought: could we also store the offset of the instruction_node in the override from the first part of the sequence, and just count forward that many steps in the route sequence? If the current route steps sequence actually matches the override, it should be 1:1 right? The coordinate comparison should be an assert or a second check then.
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 is a good idea and would definitely speed things up. We're also being wasteful here by checking every coordinate - only intersection coordinates should get checked.
// Copy all the overrides into the results array. | ||
// m_maneuver_overrides is sorted by node_sequence.front(), | ||
// so we can stop searching after we get to a node > edge_based_node_id | ||
for (const auto & override : m_maneuver_overrides) |
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.
Would it be any faster to do a std::equal_range
search for the edge_based_node_id
and just write all of those results?
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.
Good catch - yeah, it would be faster, std::equal_range
has sub-linear performance if the thing being searched is random-access (as opposed to just forward iterable).
The way we're comparing a member variable (override.start_node
) doesn't fit with the std::equal_range
pattern though, I'll see if I can re-jigger it to work.
// id of via node of the turn | ||
// from edge-based-node id | ||
NodeID from_edge_based_node; | ||
// the internal OSRM id of the OSM node id that is the via node of the turn |
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 comment is so sad and great at the same time
// check if all parts of the restriction reference an actual node | ||
bool Valid() const | ||
{ | ||
return turn_sequence.size() >= 2 || std::none_of(turn_sequence.begin(), |
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 would expect that all of these ||
are &&
's. Isn't an override only valid if it has at least 2 turns, none of the nodes are SPECIAL_NODEID, and the direction and override types are valid?
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.
@danpat I'm still unclear on whether or not this check is the right one. Should the logic here be inverted?
class ScriptingEnvironment; | ||
|
||
/** | ||
* Parses the relations that represents turn restrictions. |
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 these comments need to be updated a bit for the maneuver relations
}; | ||
|
||
// wrapper function to handle distinction between conditional and unconditional turn | ||
// restrictions |
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.
Is this comment unrelated?
0c15d5d
to
7944351
Compare
7944351
to
df1ef2f
Compare
5a3dcd7
to
8320f25
Compare
56dbaae
to
6f1aa4e
Compare
f2757e5
to
4577f29
Compare
8ba682d
to
fe994f6
Compare
50807b4
to
3d9d1aa
Compare
fe994f6
to
dc43288
Compare
3d9d1aa
to
68a500f
Compare
dc43288
to
edb6478
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! Just small cleanup remarks before merging.
guidance::TurnType::Invalid, | ||
guidance::DirectionModifier::MaxDirectionModifier}; | ||
|
||
std::clog << " ****** EXTERNAL WAY SEQUENCE " << std::endl; |
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.
could it be removed?
include/engine/api/route_api.hpp
Outdated
@@ -140,6 +168,156 @@ class RouteAPI : public BaseAPI | |||
reversed_source, | |||
reversed_target); | |||
|
|||
// Find overrides that match, and apply them |
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.
would it make sense to move the code block into a guidance handler function guidance::handleManeuverOverride
?
@@ -78,6 +79,7 @@ struct RouteStep | |||
std::size_t geometry_end; | |||
std::vector<IntermediateIntersection> intersections; | |||
bool is_left_hand_driving; | |||
bool is_overridden; |
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.
is_overridden
is only set but never used, can it be removed?
src/storage/storage.cpp
Outdated
@@ -1074,6 +1086,22 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr) | |||
" in " + config.GetPath(".osrm.edges").string()); | |||
} | |||
} | |||
|
|||
// load turn duration penalties |
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.
// load maneuver overrides
?
9bf892f
to
2dc70a3
Compare
edb6478
to
5b4c4d1
Compare
67d5bb6
to
54fe4be
Compare
54fe4be
to
2ea559e
Compare
- Changes from 5.15.2: - Guidance - ADDED Project-OSRM#4676: Support for maneuver override relation, allowing data-driven overrides for turn-by-turn instructions [Project-OSRM#4676](Project-OSRM#4676) - CHANGED Project-OSRM#4830: Announce reference change if names are empty - CHANGED Project-OSRM#4835: MAXIMAL_ALLOWED_SEPARATION_WIDTH increased to 12 meters - CHANGED Project-OSRM#4842: Lower priority links from a motorway now are used as motorway links [Project-OSRM#4842](Project-OSRM#4842) - CHANGED Project-OSRM#4895: Use ramp bifurcations as fork intersections [Project-OSRM#4895](Project-OSRM#4895) - CHANGED Project-OSRM#4893: Handle motorway forks with links as normal motorway intersections[Project-OSRM#4893](Project-OSRM#4893) - FIXED Project-OSRM#4905: Check required tags of `maneuver` relations [Project-OSRM#4905](Project-OSRM#4905) - Profile: - FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping. - ADDED Project-OSRM#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 [Project-OSRM#4775](Project-OSRM#4775) - FIXED Project-OSRM#4763: Add support for non-numerical units in car profile for maxheight [Project-OSRM#4763](Project-OSRM#4763) - ADDED Project-OSRM#4872: Handling of `barrier=height_restrictor` nodes [Project-OSRM#4872](Project-OSRM#4872)
This is an experimental PR to tinker with the idea of data-driven instruction generation.
Rationale: sometimes, you want a specific instruction at a particular location, and the heuristics we're using just aren't fancy enough to make the right decision, or the OSM tagging scheme is incomplete for the structure of the map at that location and doesn't supply enough information to make a good decision about which instruction to issue.
This PR adds support for a new, totally made up relation we're calling a
maneuver relation
. They look like this:The basic process is that after a route is found, we scan along the path and find
maneuver
relations that match (they pass throughfrom
,via
, andto
in that order). If a match is found, thetype
value for thevia
point is replaced with the value from the relation (same for thedirection
).We will come up with a rough mapping of reasonable-looking
type
values to OSRM turn types - the intent is for the OSM data to be relatively routing-engine agnostic. The intent of this relation type is to be a hint to the navigation engine in locations where heuristics have trouble.TODO:
RestrictionCompressor
work so that it also updates the ManeuverOverride from/to IDs @karenzsheaManeuverOverride
list at the end of extraction @danpatfacade.GetOverridesThatStartAt
methodMulti-via-way support
** Do this bit after we have directly-connected overrides working
/cc @karenzshea
Tasklist