mapbox / mapbox/mapbox-navigation-android

Off-route status reported incorrectly if client starts up mid-route

Open
#4,149 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

jira-sync-complete
Dominant language
Kotlin
Stars
651
Forks
321
PR merge metrics
No merged PRs in 30d

Description

If I create a route with multiple waypoints, and start navigation with the user located on the path but between two of the later waypoints, then the Navigation SDK incorrectly reports that the user is off-route.

I'm using the simple Navigation UI component, and I have intentionally disabled rerouting (as I want the user to stick to the original route).

Note that the issue does not manifest if the user is between two of the earlier waypoints ("legs" in navigation terms). It seems to only be a problem for later legs.

Android API: 30
Mapbox Navigation SDK version: 1.5.0 (also tried with 1.4.0)

Minimal code example
@Override
public void onNavigationReady(boolean isRunning) {
    if (!isRunning && navigationMapboxMap == null) {
        if (navigationView.retrieveNavigationMapboxMap() != null) {
            this.navigationMapboxMap = navigationView.retrieveNavigationMapboxMap();

            CameraPosition position = new CameraPosition.Builder()
                    .target(new LatLng(51.48296,0.01291))
                    .zoom(15)
                    .build();

            this.navigationMapboxMap.retrieveMap().setCameraPosition(position);

            List<Point> coords = new LinkedList<>();
            coords.add(Point.fromLngLat(0.012140957165058808, 51.4828513728437));
            coords.add(Point.fromLngLat(0.0014954641793281098, 51.48814394775522));
            coords.add(Point.fromLngLat(-0.002110267315146075, 51.50086499824096));
            coords.add(Point.fromLngLat(0.00870692716944177, 51.50102532496126));
            coords.add(Point.fromLngLat(0.029053554891902422, 51.493649712060034));
            coords.add(Point.fromLngLat(0.04356233162209833, 51.487235165446236));
            coords.add(Point.fromLngLat(0.07666254746163759, 51.467528739949046));
            coords.add(Point.fromLngLat(0.06953695344415678, 51.452123493940945));
            coords.add(Point.fromLngLat(0.07040974851102533, 51.43959399996976));
            coords.add(Point.fromLngLat(0.018040819204657055, 51.41936070050156));
            coords.add(Point.fromLngLat(-0.0053516712219163765, 51.42251880439164));
            coords.add(Point.fromLngLat(-0.008254568573306642, 51.42299238450883));
            coords.add(Point.fromLngLat(-0.013182751423386208, 51.421455835222844));
            coords.add(Point.fromLngLat(-0.021739522975593673, 51.420361261315065));
            coords.add(Point.fromLngLat(-0.024203614399766593, 51.42162421256282));

            MapboxDirections dir = MapboxDirections.builder()
                    .waypoints(coords)
                    .overview(DirectionsCriteria.OVERVIEW_FULL)
                    .profile("walking")
                    .bannerInstructions(true)
                    .voiceInstructions(true)
                    .steps(true)
                    .voiceUnits("metric")
                    .accessToken(getString(R.string.mapbox_access_token))
                    .build();
            dir.enqueueCall(new Callback<DirectionsResponse>() {
                @Override
                public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                    DirectionsRoute route = response.body().routes().get(0);
                    doNav(route);
                }

                @Override
                public void onFailure(Call<DirectionsResponse> call, Throwable t) {

                }
            });
        }
    }
}

private void doNav(DirectionsRoute route) {
    NavigationOptions.Builder nb = new NavigationOptions.Builder(this).isDebugLoggingEnabled(true);

    NavigationViewOptions.Builder builder = NavigationViewOptions.builder(this)
            .navigationListener(this)
            .directionsRoute(route)
            .navigationOptions(nb.build())
            .shouldSimulateRoute(false);
    NavigationViewOptions navigationViewOptions = builder.build();

    navigationView.startNavigation(navigationViewOptions);

    // Do not re-route
    navigationView.retrieveMapboxNavigation().setRerouteController(null);

    this.offRouteObserver = b -> {
        if (b) {
            System.out.println("OFF ROUTE");
        }
    };
    navigationView.retrieveMapboxNavigation().registerOffRouteObserver(this.offRouteObserver);
}
Steps to trigger behavior
  1. Start the Android simulator and set your location to lat/lng: 51.4227, -0.0055 (this is a point on the route, in one of the latter legs)
  2. Execute the sample code above, wait for navigation to begin
  3. Observe your location is on the route, as expected
  4. Change your location to ~50 metres away, which is also right on the route, at lat/lng: 51.4228, -0.0062
  5. Observe that you are now reported as being off-route, even though you're not.
Expected behavior

Routing continues as normal, without being reported as being off-route.

Actual behavior

User is reported as being off-route, with the following messages printed in the debug console:

D/MAPBOX_TELEMETRY: onOffRouteStateChanged true
I/System.out: OFF ROUTE

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal example using NavigationView.startNavigation, retrieveMapboxNavigation, setRerouteController(null), and registerOffRouteObserver. Reproduce the later-leg case at the supplied coordinates, then inspect how startup location and off-route state are handled; done means the on-route location does not trigger an off-route report when rerouting is disabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.