HoLoGram
HoLoGram

Reputation: 169

Orientation Heading Inaccuracy

I'm working on an Android application that requires accurate orientation heading updates using the FusedOrientationProviderClient and a custom DeviceOrientationListener. However, I'm experiencing issues with orientation accuracy and incorrect heading values, especially when the device is flat on a surface.

Here's the class I am using for orientation updates:

class LocationOrientationRepo(context: Context) {

    private var deviceOrientationListener: DeviceOrientationListenerImpl? = null
    private val fusedOrientationProviderClient: FusedOrientationProviderClient =
        LocationServices.getFusedOrientationProviderClient(context)
    private val handler = Handler(Looper.getMainLooper())
    private val refreshRunnable = object : Runnable {
        override fun run() {
            checkOrientationListener()
            handler.postDelayed(this, REFRESH_INTERVAL_MS)
        }
    }

    private var lastAzimuth: Float? = null
    private val threshold = 0.0f // Set your threshold value (in degrees)

    fun startListening(onOrientationChanged: (Float) -> Unit) {
        if (deviceOrientationListener == null) {
            deviceOrientationListener = DeviceOrientationListenerImpl { azimuth ->
                if (shouldNotify(azimuth)) {
                    lastAzimuth = azimuth
                    onOrientationChanged(azimuth)
                }
            }
            val request = DeviceOrientationRequest.Builder(DeviceOrientationRequest.OUTPUT_PERIOD_DEFAULT).build()
            val executor: ExecutorService = Executors.newSingleThreadExecutor()

            fusedOrientationProviderClient.requestOrientationUpdates(request, executor, deviceOrientationListener!!)
                .addOnSuccessListener {
                    Log.i(TAG, "Successfully added new orientation listener")
                    handler.post(refreshRunnable)
                }
                .addOnFailureListener { e ->
                    Log.e(TAG, "Failed to add new orientation listener", e)
                }
        }
    }

    fun stopListening() {
        if (deviceOrientationListener != null) {
            Log.i(TAG, "Removing active orientation listener")
            fusedOrientationProviderClient.removeOrientationUpdates(deviceOrientationListener!!)
            deviceOrientationListener = null
            handler.removeCallbacks(refreshRunnable)
        }
    }

    private fun checkOrientationListener() {
        if (deviceOrientationListener == null) {
            Log.i(TAG, "Orientation listener not active. Restarting.")
            startListening { azimuth ->
                Log.d(TAG, "Orientation callback with azimuth: $azimuth")
            }
        }
    }

    private fun shouldNotify(newAzimuth: Float): Boolean {
        // If lastAzimuth is null, initialize it
        if (lastAzimuth == null) {
            lastAzimuth = newAzimuth
            return true
        }

        // Calculate the difference
        val diff = Math.abs(newAzimuth - (lastAzimuth ?: newAzimuth))
        return diff >= threshold
    }

    private inner class DeviceOrientationListenerImpl(private val onOrientationChanged: (Float) -> Unit) :
        DeviceOrientationListener {

        override fun onDeviceOrientationChanged(deviceOrientation: DeviceOrientation) {
            val azimuth = deviceOrientation.headingDegrees
            Log.d(TAG, "Device Orientation Changed - Heading: $azimuth")  // Debug log for azimuth
            onOrientationChanged(azimuth)
        }
    }

    companion object {
        private const val TAG = "LocationOrientationRepo"
        private const val REFRESH_INTERVAL_MS = 10000L // 10 seconds
    }
}

Issue:

The heading direction provided by DeviceOrientationListener is not always accurate. When the device is flat, the heading direction seems incorrect and does not update properly.

Using sensor events directly also yields inaccurate and erratic results, especially when rotating the device.

What I've Tried: I’ve tried using sensors events but they produce unstable and incorrect values when the device is rotated. Questions:

Any guidance or suggestions on how to fix these issues would be greatly appreciated. Thank you !

Upvotes: 0

Views: 39

Answers (0)

Related Questions