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

Improve Turn Angles #2779

Merged
merged 1 commit into from
Oct 20, 2016
Merged

Improve Turn Angles #2779

merged 1 commit into from
Oct 20, 2016

Conversation

MoKob
Copy link

@MoKob MoKob commented Aug 17, 2016

This PR addresses the improvement of turn angles raised in #2778.

resolves in #2778
resolves #2937

TODO

Right now I see multiple strategies that I will update the PR with to report on my findings:
- [ ] Average Turn Angle among multiple coordinates

  • Offset Roads: Jump ahead road width (number of lanes * average lane width), consider the next n meters for the turn (see here)
    • implement
      • straight offsets
      • short curved offsets
    • tune
    • analysis
  • Linear Regression: Use Linear Regression to find turn angles offsetting the road for non turning roads
    • implement
    • analysis
  • detect noise at beginnings of roads
    • implement
    • analysis
  • detect curved turns
    • implement
    • analysis
  • make implementation independent of calling side (right now the incoming edge (due to the lanes) can influence the resulting bearing class. the computed bearing can vary. This needs to be the same for all calling directions to ensure consistency.
    In addition:
  • we need Angle Computation in EdgeExpandedGraph/Assemble Steps doesn't match up #2937 fixed to make it work correctly.
  • better detect curves in turns
  • clean-up
    • remove case checking structures
    • remove old reference implementation
  • review
  • adjust for comments

@MoKob MoKob added the Guidance label Aug 17, 2016
@MoKob MoKob self-assigned this Aug 17, 2016
@MoKob
Copy link
Author

MoKob commented Aug 17, 2016

I've implemented a first crack at resolving #2778 . The change results in updated turn angles on Berlin in many cases. If only printing changes of at least 20 degrees, we see changes reflected in the following list:

Changed Angle from 75.6269169146 to 97.6369878691 at: 52.537318 13.360354
Changed Angle from 289.518196384 to 309.945525292 at: 52.522206 13.587492
Changed Angle from 129.710002289 to 153.400320439 at: 52.475872 13.535999
Changed Angle from 247.51201648 to 225.000686656 at: 52.452798 13.560956
Changed Angle from 307.748912795 to 335.563286793 at: 52.450324 13.51931
Changed Angle from 308.98626688 to 287.008468757 at: 52.512135 13.390056
Changed Angle from 235.577935454 to 256.583428702 at: 52.482608 13.349332
Changed Angle from 200.673838407 to 180 at: 52.472489 13.384549

I am verifying this list to see whether these changes can be considered reasonable or not.

Edit: I've reduced the list to a set of problematic cases I've seen. Further verification is ongoing.

@MoKob MoKob mentioned this pull request Aug 17, 2016
@MoKob
Copy link
Author

MoKob commented Aug 17, 2016

From what I've seen in the changes: the most angles affected very strongly are turn-lanes in between two ways representing the same road, roads splitting into two ways and turning roads/traffic circles.

The affected angles for splitting roads are most times alright, but can offer too strong variations in my view. I have to check more items to see the effect in a global scenario.

Any curve in a road is usually difficult to begin with. The angles seem a bit off to me. Will need to investigate this further.

@MoKob
Copy link
Author

MoKob commented Aug 29, 2016

screen shot 2016-08-29 at 16 03 03

local request

should be turn-left (requires angle adjustment in collapsing)

@MoKob
Copy link
Author

MoKob commented Aug 29, 2016

Local requests broken at link road:
here
here, and here

@MoKob
Copy link
Author

MoKob commented Aug 30, 2016

After thorough investigation of changed turns on the Berlin network, the following list of situations has to be investigated

@MoKob MoKob added this to the 5.4.0 milestone Sep 2, 2016
@MoKob MoKob changed the title [wip] fix #2778 fix #2778 Sep 2, 2016
@MoKob MoKob modified the milestones: 5.5.0, 5.4.0 Sep 6, 2016
@MoKob MoKob force-pushed the guidance/2778 branch 2 times, most recently from 3b89d51 to 7c15d0b Compare September 7, 2016 13:07
@MoKob
Copy link
Author

MoKob commented Sep 21, 2016

#2937 is somewhat standing in our way.

@MoKob MoKob changed the title fix #2778 Improve Turn Angles Sep 27, 2016
@MoKob
Copy link
Author

MoKob commented Sep 28, 2016

Apparently one of the tests only succeeded due to a sliproad detection. This detection has changed. The test needs investigation to make it pass again.

@MoKob
Copy link
Author

MoKob commented Oct 4, 2016

  • First Coordinate Far Away - Use the first, since the turn cannot be simply an offset

    screen shot 2016-10-04 at 09 46 10 screen shot 2016-10-04 at 09 43 27
  • Straight Line Heuristic - Turn is straight, any coordinate would be fine for the turn angle

    screen shot 2016-10-04 at 09 48 29 screen shot 2016-10-04 at 09 50 22
  • Starts of without turn - Road takes a turn within the first 30 meters, but the start is straight

    screen shot 2016-10-04 at 09 52 22 screen shot 2016-10-04 at 09 53 40
  • Regression Line - The road itself does not deviate far from a straight line, but enough to consider it. We choose between:

    • First Coordinate

      screen shot 2016-10-04 at 09 57 44 screen shot 2016-10-04 at 09 59 26 - And offsetting (moving the straight line to the intersection for the angle) none on Berlin
  • Offset Coordinates - A short initial segment, bridging lanes usually

    screen shot 2016-10-04 at 10 04 59 screen shot 2016-10-04 at 10 07 09
  • The initial offset can happen in a tiny curve as well

    screen shot 2016-10-04 at 10 09 18 screen shot 2016-10-04 at 10 10 37
  • Curves usually are described best by their very first index:

    screen shot 2016-10-04 at 10 12 28 screen shot 2016-10-04 at 10 13 36

@MoKob
Copy link
Author

MoKob commented Oct 4, 2016

Circle Offsets are currently offering strange results. Needs further investigation.

@MoKob
Copy link
Author

MoKob commented Oct 4, 2016

Example Picture of how angle computation can change

screen shot 2016-10-04 at 15 07 22

screen shot 2016-10-04 at 15 07 23

@daniel-j-h
Copy link
Member

@MoKob care to elaborate on these images? Color reflects angle?

@MoKob
Copy link
Author

MoKob commented Oct 4, 2016

Greenish colours are coordinates of the connected roads. Blue are the three coordinates chosen to calculate the turn angle. On the satellite image you can see that the angles better describe the actual turn here.

@MoKob
Copy link
Author

MoKob commented Oct 6, 2016

screen shot 2016-10-06 at 16 58 39

another example: now 260 degree turn, previous 220 degree turn

return this.extractInstructionList(instructions, s => s.maneuver.bearing_before + '->' + s.maneuver.bearing_after);
return this.extractInstructionList(instructions, s => ('in' in s.intersections[0] ? this.reverseBearing(s.intersections[0].bearings[s.intersections[0].in]) : 0)
+ '->' +
('out' in s.intersections[0] ? s.intersections[0].bearings[s.intersections[0].out] : 0));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change uses the bearing array instead of the parameters we want to deprecate anyhow.

INVALID_ENTRY_CLASSID,
datasource_vector[segment_idx],
util::guidance::TurnBearing(0),
util::guidance::TurnBearing(0)});
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rest of this part was not aligned properly. The addition of the turn-bearings is the only change here.

unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += (edge_data.distance - total_weight);
unpacked_path.back().pre_turn_bearing = facade.PreTurnBearing(edge_data.id);
unpacked_path.back().post_turn_bearing = facade.PostTurnBearing(edge_data.id);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and here

@@ -34,7 +34,7 @@ const int constexpr MAX_SLIPROAD_THRESHOLD = 250;
// Road priorities give an idea of how obvious a turn is. If two priorities differ greatly (e.g.
// service road over a primary road, the better priority can be seen as obvious due to its road
// category).
const double constexpr PRIORITY_DISTINCTION_FACTOR = 2.0;
const double constexpr PRIORITY_DISTINCTION_FACTOR = 1.75;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turned out the obvious detection was a bit to restrictive here

Copy link
Member

@daniel-j-h daniel-j-h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trophy for best ASCII Cucumber scenarios! More seriously, wow those are detailed and describe their OSM link - thanks for that!

Most of the (i, i+-1) code could benefit from some stdlib algorithms (check algorithms and numeric header).

I think the two major issues are possible iterator invalidation and the accumulate with int.

| de | | bot | primary | yes |
| dr | | off | primary | yes |
| gj | | bot | primary | yes |
| jk | | bot | primary | yes |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing!

| waypoints | route | turns |
| k,j | on,ferry,,ferry,off,off | depart,notification straight,continue uturn,turn straight,notification straight,arrive |
| waypoints | route | turns |
| k,j | on,ferry,road,road,ferry,off,off | depart,notification straight,notification straight,continue uturn,turn straight,notification straight,arrive |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in route and turns here is not only related to only ga being a ferry now?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the change is including ab as non-ferry. The problem we were trying to check here was having mode-changes (notifications) visible. This was not the case without the change anymore.

|
|
|
d
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ~7 meter here is compensated by abc having 4 lanes, right?

|
|
|
d
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. and no longer here since it's still 4 lanes but more like 20 meters?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. Lanes influence how a road is seen. If the modelled road takes a turn right after it reaches the border of the road, the turn itself is most likely describing a typical phenomenon in osm which i modelled in #2778 (comment).

When I route I should get
| waypoints | route | turns |
| a,b | road,road | depart,arrive |
| a,i | road,road,road | depart,continue uturn,arrive |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm is there a limit on the uturn's road length? I can see how this is a uturn with this small of a grid size, what about larger ones?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. There is a limit on how long this road can become.

const auto slope = dividend / divisor;
const auto intercept = (sum_lat - slope * sum_lon) / coordinates.size();

const auto GetLatatLon =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At

}
}
else
{
if (angularDeviation(left.turn.angle, 270) > angularDeviation(right.turn.angle, 270))
if (angularDeviation(left.turn.angle, 265) >= angularDeviation(right.turn.angle, 265))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh? Can you explain the changes for the lines above?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

essentially gives a little bit of wiggle room. 270 is perfectly left.

&guidance::RoadClassification::SetClass)
.property("num_lanes",
&guidance::RoadClassification::GetNumberOfLanes,
&guidance::RoadClassification::SetNumberOfLanes),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are road width tags (e.g. http://taginfo.openstreetmap.org/keys/width#combinations) - do you think it could make sense to use those for shortcutting the width calculation via lanes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to #3055

static_cast<double>(toFloating(first_coordinate.lon)) *
static_cast<double>(toFloating(third_coordinate.lat)) +
static_cast<double>(toFloating(second_coordinate.lon)) *
static_cast<double>(toFloating(third_coordinate.lat)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. Maybe make some tmp. vars for the calculation, this is somewhat hard to read.

@@ -188,6 +188,8 @@
{"key": "highway", "value": "default"},
{"key": "width", "description": "Penalties for narrow streets"},
{"key": "lanes", "description": "Penalties for shared single lane streets"},
{"key": "lanes:forward", "description": "Lanes in forward direction"},
{"key": "lanes:back", "description": "Lanes in backward direction"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I can't see those getting used, also it should be backward I suppose?

@MoKob MoKob force-pushed the guidance/2778 branch 2 times, most recently from d3bfae5 to bee0614 Compare October 17, 2016 06:59
@MoKob
Copy link
Author

MoKob commented Oct 19, 2016

@daniel-j-h what about the changes? Would love to get this off my plate

@daniel-j-h
Copy link
Member

Thank you for the adjustments.

This PR adds more advanced coordinate extraction, analysing the road
to detect offsets due to OSM way modelling.

In addition it improves the handling of bearings. Right now OSM reports
bearings simply based on the very first coordinate along a way.
With this PR, we store the bearings for a turn correctly, making the
bearings for turns correct.
@MoKob MoKob merged commit 5e167b8 into master Oct 20, 2016
@MoKob MoKob deleted the guidance/2778 branch October 20, 2016 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Angle Computation in EdgeExpandedGraph/Assemble Steps doesn't match up
2 participants