How can I get the pitch, yaw, and roll of an Android device from 0 - 360 degrees?

September 11, 2019, at 11:50 AM

So this is apparently quite a simple question but I haven't been able to find a 100% working solution despite my research and googling over the last few months. Basically, I just want to obtain the pitch, yaw and roll from an Android device represented from 0 to 360 degrees.

Most functionality I have seen that accomplishes this seems to boil down to code that looks like the following:

  private fun updateOrientation(rotationVector: FloatArray) {
        val rotationMatrix = FloatArray(9)
        SensorManager.getRotationMatrixFromVector(rotationMatrix, rotationVector)
        val (worldAxisForDeviceAxisX, worldAxisForDeviceAxisY) = when (mWindowManager.defaultDisplay.rotation) {
            Surface.ROTATION_0 -> Pair(SensorManager.AXIS_X, SensorManager.AXIS_Z)
            Surface.ROTATION_90 -> Pair(SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_X)
            Surface.ROTATION_180 -> Pair(SensorManager.AXIS_MINUS_X, SensorManager.AXIS_MINUS_Z)
            Surface.ROTATION_270 -> Pair(SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X)
            else -> Pair(SensorManager.AXIS_X, SensorManager.AXIS_Z)
        val adjustedRotationMatrix = FloatArray(9)
        SensorManager.remapCoordinateSystem(rotationMatrix, worldAxisForDeviceAxisX,
                worldAxisForDeviceAxisY, adjustedRotationMatrix)
        // Transform rotation matrix into azimuth/pitch/roll
        val orientation = FloatArray(3)
        SensorManager.getOrientation(adjustedRotationMatrix, orientation)
        // Convert radians to degrees
        val pitch = orientation[1] * -57
        val roll = orientation[2] * -57
        println("pitch is $pitch")
        println("roll is $roll")

        mListener?.onOrientationChanged(pitch, roll)

However, when I run this on my physical device, and I roll the device from side to side (that is, put the device on approximately 45 degree angle either way), when I roll to the left I get readings like 95 degrees, and when I roll to the right I get readings like -95. If I roll the phone and then leave it, the roll angle (while the phone is flat on the desk) goes between 140 and 160 before finally stabilising at ~144-145 degrees.

Pitch behaves in a more reasonable manner (starts at -90, goes to -74 if I tilt the phone up and down).

I would expect that the roll of the device would start at 0 or 180, as the phone is flat on the desk. If I tilted the device 45 degrees to the left, I would get a reading of 135. If I tilted it 45 degrees to the right, I would get readings like 225.

I'm starting to think that I could critically misunderstand the accelerometer/gyroscope functionality in android and physical devices and what I want to accomplish is physically impossible. I am trying to get this data so I can set up a "safe range" of angles for my app (if the phone is at less than a certain angle, or more than a certain angle for a certain amount of time, it sounds an alert).

How can I get the pitch, yaw, and roll of the device from 0 - 360 degrees on an Android device?

How to fix 'Failed to apply plugin [id ''] Malformed \uxxxx encoding.' error in react native

How to fix 'Failed to apply plugin [id ''] Malformed \uxxxx encoding.' error in react native

I want to run my react native project on android using react-native run-androidand I found this error when I run this project on windows

How can I make email sent from android java?

How can I make email sent from android java?

I have an POS app and I want to send my e-receipt to customers via email

FirebaseAuth: RemoteException when sending failure result

FirebaseAuth: RemoteException when sending failure result

I have an issue when I woking with firebase auth