Closed Fabi755 closed 1 year ago
Thanks a lot for looking into this.
Could you maybe check the formatting of your change, it uses a different indentation than the rest of the code. I know that the exciting formatting is a huge mess, we should probably reformat the whole source code in one go, but we should probably do this without any other changes mixed in. So it would be nice if you could reformat the code to have a similar indentation.
A quick thing that I spotted was the change from RingBuffer to List. Any reason to do this? The nice thing about RingBuffer was that it was capped at 3 entries, with a list, we could end up storing millions of records for no reason if a user is offroute for a long time.
Thanks for your fast response!
I know that the exciting formatting is a huge mess, we should probably reformat the whole source code in one go, but we should probably do this without any other changes mixed in.
Make sense! I will force the IDE keeping the current format.
A quick thing that I spotted was the change from RingBuffer to List. Any reason to do this? The nice thing about RingBuffer was that it was capped at 3 entries, with a list, we could end up storing millions of records for no reason if a user is offroute for a long time.
I have copied this, form the iOS solution, that was the origin for the Android code of Mapbox site (I read this on some Mapbox issue). The problem with the RingBuffer is, when we calculate distance by first & last position, the first position may already replaced by newer one. Often updated positions will be always below our minimum of 50 meters threshold.
We need the first position to calculate our traveled distance. My first attempt was to use the current distance to maneuver, but this can be initial more then our threshold of 50 meters. So the first location is our point zero for comparing.
I will have a look if I find some cleaner solution for tracking our direction and first distance point without generating a full location history.
To prevent using a list with all historical positions, we always need to store the first position, and the last two positions.
My current ideas are:
ArrayDeque
for this.I'm not happy with all of them. Maybe you know a pattern or have some more ideas that would be more cleaner?
How about we do a check like this, and add after the pop:
if (distancesAwayFromManeuver.size >= 3) {
// We replace the first one, in order to keep the history with the last one
distancesAwayFromManeuver.pop()
}
Ahh, right! I have thinking all the time with the wrong calculation. While check our current position with the last one, we don't need the second value for comparing.
Thank you!
Sorry for the delay! I will try to review this PR in the next days. As this is a very critical part of the navigation, I would like to give this proper testing and debugging.
I'm currently run some final tests.. please wait a little bit with merging :-)
I found two more things that maybe can improved.
OffRouteDetector
get calles by NavigationRouteProcessor
. This is only happening when we use the internal one. Some idea why this not an interface function that always is called?While I use my own OffRoute
engine this part is missing and leads to wrong off route results. Maybe I can build this by myself, but it would be easier if this is already supported by default.
ToleranceUtils
the radius for off route detection is calculated. If we are near a maneuver the radius is smaller. So far so good. By default the maneuver radius is 40 and the off distance is 50. On near maneuver the distance is 25 (min reroute / 2).
In short: If we are in a maneuver zone (40 meters radius) the off route distance is calculated with 25 meters. If the next step will be more then 25m we get an off route event.I see the problem here in the default values and the calculation of minimumDistanceBeforeRerouting / 2
. My idea would be to create a new navigation option that can be used to control this value and changing the default values to work each other. If we want to force a right usage, we need to check the values and be sure that the zone radius is not smaller than the new near-maneuver-re-route-threshold option.
Any ideas or discussions before I start to resolve them? :-)
The internal OffRouteDetector get calles by NavigationRouteProcessor. This is only happening when we use the internal one. Some idea why this not an interface function that always is called?
I am not sure if I can follow you here. You can set the OffRouteDetector using MapboxNavigation#setOffRouteEngine
. You should extend OffRouteDetector
then it should work fine. Or is there something else missing?
In short: If we are in a maneuver zone (40 meters radius) the off route distance is calculated with 25 meters. If the next step will be more then 25m we get an off route event.
I am not sure if I can follow you here. Isn't this code checking if we are close to an intersection (these are points where we can leave the route), distanceToNextIntersection <= navigationOptions.maneuverZoneRadius()
. If yes, then we are extra sensible about moving away from the route, because we are using navigationOptions.minimumDistanceBeforeRerouting() / 2
. This would mean the distance before rerouting is reduced, if we are close to an intersection and would trigger a rerouting a lot easier. I think this approach is not too unreasonable?
This PR looks good to me @Fabi755. Do you want to merge this soon or do you want to add something else here as well?
I think we can merge this now. If some users have similar problems or I detect something more I will create a new pull request.
This will fix the problems described in #58.
Following things are done
movingAwayFromManeuver
logic.maximumDistanceOffRoute
as deprecatedInstead of removing
maximumDistanceOffRoute
directly, I marked the option as deprecated, while some projects may already use this in their code.Let me know if I can adjust something more or you find some problem in my code.