Device pose android emulator rotation values to App

13 Views Asked by At

I am attempting to replicate the absolute rotation values provided by the Device Pose Emulator in Android Studio. Despite trying various sensors and calculation methods, I have been unable to achieve the exact same values.

Specifically, I am looking to obtain the same azimuth, pitch, and roll values as displayed in the Device Pose Emulator. I have experimented with different sensors, including the accelerometer, gyroscope, game rotation vector, and geomagnetic rotation vector, but none have produced the desired results.

Could someone provide guidance on the sensor types or calculation techniques necessary to accurately replicate the absolute rotation values seen in the Device Pose Emulator?

Thank you in advance for any assistance provided.

package com.example.myapplication

import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Bundle
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private lateinit var ivDroid: ImageView
    private lateinit var tvX: TextView
    private lateinit var tvY: TextView
    private lateinit var tvZ: TextView
    private var brightness = 0.5f // Initial brightness

    private var mAccelerometerData = FloatArray(3)
    private var mMagnetometerData = FloatArray(3)
    private var mRotationMatrix = FloatArray(9)
    private var mOrientationAngles = FloatArray(3)

    private lateinit var tvGameRotationVector: TextView
    private lateinit var tvGeomagneticRotationVector: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ivDroid = findViewById(R.id.ivDroid)
        tvX = findViewById(R.id.tvX)
        tvY = findViewById(R.id.tvY)
        tvZ = findViewById(R.id.tvZ)
        // Initialize labels
        tvGameRotationVector = findViewById(R.id.tvGameRotationVector)
        tvGeomagneticRotationVector = findViewById(R.id.tvGeomagneticRotationVector)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also { accelerometer ->
            sensorManager.registerListener(
                this,
                accelerometer,
                SensorManager.SENSOR_DELAY_NORMAL
            )
        }

        sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also { magneticField ->
            sensorManager.registerListener(
                this,
                magneticField,
                SensorManager.SENSOR_DELAY_NORMAL
            )
        }
    }

    override fun onResume() {
        super.onResume()
        sensorManager.registerListener(
            this,
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_NORMAL
        )
        sensorManager.registerListener(
            this,
            sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
            SensorManager.SENSOR_DELAY_NORMAL
        )
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        // Not relevant for this example
    }

    private var lastPitch: Float = 0.0f // Variable to store the last pitch angle

    override fun onSensorChanged(event: SensorEvent?) {

        if (event?.sensor?.type == Sensor.TYPE_ACCELEROMETER) {
            mAccelerometerData = event.values.clone()
        } else if (event?.sensor?.type == Sensor.TYPE_MAGNETIC_FIELD) {
            mMagnetometerData = event.values.clone()
        }

        // Calculate the rotation matrix
        val success = SensorManager.getRotationMatrix(
            mRotationMatrix,
            null,
            mAccelerometerData,
            mMagnetometerData
        )

        if (success) {
            // Get the absolute orientation angles
            SensorManager.getOrientation(mRotationMatrix, mOrientationAngles)

            // Convert angles from radians to degrees
            val azimuth = Math.toDegrees(mOrientationAngles[0].toDouble()).toInt()
            val pitch = Math.toDegrees(mOrientationAngles[1].toDouble()).toInt()
            val roll = Math.toDegrees(mOrientationAngles[2].toDouble()).toInt()

            // Update labels with absolute angles
            runOnUiThread {
                tvX.text = "$azimuth"
                tvY.text = "$pitch"
                tvZ.text = "$roll"
            }
        }
    }
}
0

There are 0 best solutions below