mapbox / mapbox-navigation-android

Mapbox Navigation SDK for Android
https://docs.mapbox.com/android/navigation/overview/
Other
622 stars 319 forks source link

Navigation SDK 1.5 breaks off-route detection and voice instructions for first leg with >2 waypoints #4150

Open samcrawford opened 3 years ago

samcrawford commented 3 years ago

I've just upgraded my app from Navigation SDK 1.4.0 to 1.5.0 and have observed an issue.

If I create a route with >2 waypoints, and start navigation with the user located right at the first waypoint, then the navigation SDK reports that the user is off-route. I also noticed that the voice instructions that are read out are for the first step of the second leg (not the first leg).

The issue does not occur if:

  1. I downgrade to 1.4.0
  2. I use only two waypoints.

I can reliably reproduce this on 1.5.0 on both the simulator and a real phone. And it reliably does not appear on 1.4.0.

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). Enabling re-routing does not make a difference - the user is still reported as being off-route (but then it re-routes them quite quickly afterwards).

Android API: 30 Mapbox Navigation SDK version: 1.5.0 (issue does NOT occur 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));

            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 current location to match the first waypoint (0.012140957165058808, 51.4828513728437)
  2. Execute the sample code above, wait for navigation to begin
  3. Observe that you're immediately reported off route. Also observe that the voice instruction that's read out is "Walk north east for 900 feet". This is the first voice instruction for leg=1, not leg=0

Expected behavior

Routing should not report the user is off-route, and should read out the correct voice instruction.

Actual behavior

User is reported as being off-route, and the incorrect voice instruction is read out.

mskurydin commented 3 years ago

@samcrawford trying to reproduce it on both 1.4 and 1.5 and not seeing an immediate re-route.

I'm setting a puck position via the console (geo fix 0.012140957165058808 51.4828513728437) and run the test off the snippet you have provided (no off-route happens). Could you clarify how you do it on your end?

Sharing a history recording with us may speed things up too. Could you start the history recording after the navigation start? This will help us see the events that come to the core (including the locations and results).

    private fun doNav(route: DirectionsRoute) {
        val nb = NavigationOptions.Builder(this).isDebugLoggingEnabled(true)
        val builder = NavigationViewOptions.builder(this)
            .navigationListener(this)
            .directionsRoute(route)
            .navigationOptions(nb.build())
            .shouldSimulateRoute(false)
        val navigationViewOptions = builder.build()
        navigationView.startNavigation(navigationViewOptions)

        nav = navigationView.retrieveMapboxNavigation()!!
        nav.toggleHistory(true);
        // ....
}

override fun onDestroy() {
    super.onDestroy()
    val history = nav.retrieveHistory()
    // copy the history JSON into the file in a debugger or print it
    navigationView.onDestroy()
}

Please remove any tokens from the history file before sharing (if there are any).

mskurydin commented 3 years ago

Btw, here are the instructions I get for the whole route (always seeing exactly the first one from leg 0). History will also have the route you receive, so it should remove any uncertainty.

Leg 0

0 - 0 - 0 - 0 --> Walk west on Humber Road for 900 feet.
0 - 0 - 0 - 1 --> In 300 feet, Turn right onto Vanburgh Hill.
0 - 0 - 0 - 2 --> Turn right onto Vanburgh Hill.
0 - 0 - 1 - 0 --> In 300 feet, Turn left onto the walkway.
0 - 0 - 1 - 1 --> Turn left onto the walkway.
0 - 0 - 2 - 0 --> In 60 feet, Continue on Woodlands Park Road.
0 - 0 - 2 - 1 --> Continue on Woodlands Park Road.
0 - 0 - 3 - 0 --> In 90 feet, Turn right onto Colomb Street.
0 - 0 - 3 - 1 --> Turn right onto Colomb Street.
0 - 0 - 4 - 0 --> Continue for a quarter mile.
0 - 0 - 4 - 1 --> In 300 feet, Bear left onto Pelton Road.
0 - 0 - 4 - 2 --> Bear left onto Pelton Road.
0 - 0 - 5 - 0 --> Continue for 400 feet.
0 - 0 - 5 - 1 --> In 300 feet, Turn right onto Christchurch Way.
0 - 0 - 5 - 2 --> Turn right onto Christchurch Way.
0 - 0 - 6 - 0 --> Continue for 600 feet.
0 - 0 - 6 - 1 --> In 300 feet, Turn left.
0 - 0 - 6 - 2 --> Turn left.
0 - 0 - 7 - 0 --> In 200 feet, Turn left onto Banning Street.
0 - 0 - 7 - 1 --> Turn left onto Banning Street. Then Turn right.
0 - 0 - 8 - 0 --> Turn right.
0 - 0 - 9 - 0 --> Continue for 400 feet.
0 - 0 - 9 - 1 --> In 300 feet, Turn left.
0 - 0 - 9 - 2 --> Turn left.
0 - 0 - 10 - 0 --> In 60 feet, Your destination will be on the right.
0 - 0 - 10 - 1 --> Your destination is on the right.

Leg 1

0 - 1 - 0 - 0 --> Walk northeast for a half mile.
0 - 1 - 0 - 1 --> In 300 feet, Turn left.
0 - 1 - 0 - 2 --> Turn left.
0 - 1 - 1 - 0 --> Continue for a quarter mile.
0 - 1 - 1 - 1 --> In 300 feet, Turn left.
0 - 1 - 1 - 2 --> Turn left.
0 - 1 - 2 - 0 --> Continue for a quarter mile.
0 - 1 - 2 - 1 --> In 300 feet, Your destination will be on the right.
0 - 1 - 2 - 2 --> Your destination is on the right.
samcrawford commented 3 years ago

Thanks for the feedback. I've tried it again today and have reproduced it on a real device. I have taken logs, as instructed.

Log from Mapbox Navigation 1.4.0, which does not immediately re-route: https://gist.github.com/samcrawford/781f2c06300c40953ec94a48e6511039

Log from Mapbox Navigation 1.5.0, which immediately re-routes: https://gist.github.com/samcrawford/49ec6f77182fd6aa35d39051f363b630

The 1.5.0 log seems to show that a getStatusMonotonic event is fired with a (0,0) position right at the start, whilst this is not seen on the 1.4.0 log. It looks like this could be causing the immediate re-route.

samcrawford commented 3 years ago

I'm still seeing this with the latest stable release, 1.6.1. Again, 1.4.0 works perfectly fine for me.

I guess I'll try with the new 2.x betas soon.

samcrawford commented 3 years ago

Whilst this issue still plagues me, I think I've tracked it down to something relating to Mapbox's location engine. Enabling the Google Play Location Services with Mapbox Navigation 1.6.1 resolves the issue. For anyone else experiencing this in the future, I just added the following to build.gradle:

implementation 'com.google.android.gms:play-services-location:18.0.0'
abhishek1508 commented 2 years ago

Thanks for using the Mapbox Navigation SDK for Android and being a valued customer.

Mapbox will be soon deprecating any support for v0 and v1 versions of the SDK. To facilitate this transition we’re launching a new drop-in UI component into v2, equivalent to the existing NavigationView v1 in its design goals, however with a more modern and customizable API.

We plan to launch this new drop-in UI component as a Developer Preview feature in April, as part of the v2.5 series. Since you are using NavigationView with v1, we’d love to hear your feedback so that we can incorporate it ahead of a GA release.

If you’re interested in having early access to the upcoming drop-in UI for v2 and its documentation, drop a comment on this ticket or send an email to abhishek.kejriwal@mapbox.com

/cc @zugaldia @AhmerKhan1