mapbox / mapbox-maps-android

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.
https://www.mapbox.com/mobile-maps-sdk
Other
464 stars 131 forks source link

Puck location bearing not accurate and constantly changing if device is idle #1391

Open p-agostinho opened 2 years ago

p-agostinho commented 2 years ago

Environment

Observed behavior and steps to reproduce

The location puck does not rotate when the device moves. Additionally, if the device is idle then the bearing frequently changes randomly and the location puck rotates to a direction that does not reflect the actual direction in which the device is facing.

I followed the exact instructions to include a location puck with bearing from the documentation (https://docs.mapbox.com/android/maps/guides/user-location/ and https://docs.mapbox.com/android/maps/examples/location-tracking/). This issue happens with both PuckBearingSource.HEADING and PuckBearingSource.COURSE.

Expected behavior

The location puck should accurately reflect the direction in which the device is heading. If I move the device, the bearing should change accordingly. If the device is idle, the bearing should not change and the location puck should not rotate.

Notes / preliminary analysis

This issue has been previously mentioned in #922. According to the comments, the issue as been tracked in #970, but the problem seems to have persisted.

This problem also happened in the previous v10 versions. The bearing would also not reflect the movements, but would also change randomly if the device is idle.

Additional links and references

I could include a video, but it's basically just the puck frequently rotating in random directions. And I also don't really want to reveal my exact location.

SamuelBrucksch commented 2 years ago

Not part of the mapbox team, but if you smartphone doesn't have a magnetometer it will use the bearing from GPS which is pretty inacurate while not constantly moving.

yunikkk commented 2 years ago

@Agosto44 the issue you describe usually happens when sensors (compass, magnetometer etc) are not calibrated. Could you check whether other compass apps will show correct bearing? Also - is the issue reproduced with the test app https://github.com/mapbox/mapbox-maps-android/blob/main/app/src/main/java/com/mapbox/maps/testapp/examples/LocationComponentActivity.kt ? HEADING works fine in our tests and should reflect the direction device is facing. COURSE is based on the GPS locations thus will show correct data only when it's available (will show wrong in the buildings most probably).

@SamuelBrucksch suppose Samsung A52 should have all the sensors needed

tobrun commented 2 years ago

@Agosto44

Are you using Google Play Services Location in your project? By default the Maps SDK doesn't package this dependency but when it's available in your classpath, we will make us of it:

  // By default, the Maps SDK uses the Android Location Provider to obtain raw location updates.
  // And with Android 11, the raw location updates might suffer from precision issue.

  // The Maps SDK also comes pre-compiled with support for the [Google's Fused Location Provider](https://developers.google.com/location-context/fused-location-provider)
  // if that dependency is available. This means, that if your target devices support Google Play
  // Services, [we recommend adding the Google Play Location Services dependency to your project](https://developers.google.com/android/guides/setup).
  implementation("com.google.android.gms:play-services-location:20.0.0")

Google play services location will produce better results vs raw location updates from the GPS sensor. It combines multiple streams of input data to calculate the best result.

edit: now noticing that this isn't about heading from gps data but compass. This option won't help.

tobrun commented 2 years ago

If above doesn't match what you need, you can also roll your own location provider and optimize the data yourself. There is some sample code around it in this example.

pengdev commented 2 years ago

We have introduced a calibration callback in https://github.com/mapbox/mapbox-maps-android/pull/1513 which is invoked when the compass needs to be calibrated for better heading positioning. This allows developers to notify their users that they need to re-calibrate their device.

The calibration callback is introduced in the v10.8.0-beta.1 release. @Agosto44 could you test it out?

EricGeiler commented 1 year ago

cc: @sridhar261990 as reported by drv 3341

EricGeiler commented 1 year ago

I believe this to be primary related to uncalibrated devices or devices which has "medium" or "low" calibration values as shown in third party sensors or navigation apps.

Proper re-calibrating a device appears to make this issue much less able to be reproduced on a consistent basis.

Device Affected: Sonim XP8

See attached datasheet for sensor and hardware info if required. Sonim_DataSheet_XP8_Global_Final_061520.pdf

denys-salikhov commented 1 year ago

@Agosto44 Did you find a solution? I am experiencing the same bug on Pixel6. I just migrated from Mapbox v9.6.1 to v10.8.1 and have 2 applications installed on the same device. The old one works perfectly with the bearing, while the new one clearly has the issue you described.

Haoming-Wu92 commented 1 year ago

I'm also facing this issue with 10.9.0 (same with 10.6.1) I tried my compass app and google maps none of them have this problem. It's exactly as the OP explained.

Tested on Xiaomi 9T, and Google pixel 3

@pengdev is there an example on how to use this calibration callback? I found LocationCompassCalibrationListener, but not sure where it's suppose to be attached to (unlike OnIndicatorBearingChangedListener).

also asking users to re-calibrate seems kind of odd when other apps like google maps are working as intended. Or is there a way to re-calibrate within mapbox?

RicardoN14 commented 1 year ago

HEADING works fine in our tests and should reflect the direction device is facing.

I was getting the same error when affecting directly the property like this:

mapView.location2.puckBearingSource = PuckBearingSource.HEADING

It started working when i'v change to use the updateSettings2:

mapView.location2.updateSettings2 {
       puckBearingSource = PuckBearingSource.HEADING
}
HawkItzme commented 1 year ago

Hey @p-agostinho has this issue of yours been solved? I ma facing the same issue right now in the same Samsung A52 device. I am using LocationPuck2D class to show the location pointer but my bearing image keeps on rotating even when my device is stable.

rotimidokun commented 1 year ago

I am also having this same issue as @HawkItzme above. The puck keeps rotating when my device is idle. Using a Samsung galaxy Note 9.

Edit: I used @RicardoN14 solution above

mapView.location2.updateSettings2 {
       puckBearingSource = PuckBearingSource.HEADING
}

Testing it, it doesn't rotate when idle anymore, but rotates when I rotate my phone.

Use the documentation link below to decide what type of bearing source you prefer to use. https://docs.mapbox.com/android/maps/api/10.14.1/mapbox-maps-android/com.mapbox.maps.plugin/-puck-bearing-source/