Search code examples
javac#androidmathandroid-sensors

Android Device Physical Rotation readings


I'm trying to read out the physical orientation of the android device in comparison to a specific start-rotation, but I cannot seem to get a proper rotation out of it, no matter what Sensor I use. I initialize the sensor like this:

mySensorManager.GetDefaultSensor(SensorType.RotationVector);

I have tried reading the 'Values' of the SensorChanged event out as X, Y, Z on index 0, 1 and 2. This did give some numbers that changed as I rotated the device, however I can't seem to figure out how I can get the rotational value around a specific axis

I'm developing on a Tablet in Portrait mode. This should still work, even though tablets are generally in Landscape mode. That's why I'm led to believe this is why the readings it reports are not a simple 0,0,0 but more likely something like 90,0,0.

It's not an easy problem to explain (partially because I'm not sure I even understand it completely), and as such an even more difficult problem to solve. So basically I'm making this question in hopes that someone out there has encountered a similar scenario, and may be able to help me.

Or perhaps just a 3D vector math genius looking to spend a few minutes on a random question.

Note:

If the values reported by the device indeed DOES report different values, depending on whether it's a phone or tablet device, I'd really appreciate a solution that handles this, and outputs a value that's equal across all devices. Though any input is appreciated of course.


Solution

  • So after a lot of digging around, and some porting of Java code, I managed to get it working using code from this blogpost: Using orientation sensors: Simple Compass sample

    Here's how my SensorChanged method ended up looking:

        private float[] mGravity;
        private float[] mGeomagnetic;
        public void OnSensorChanged(SensorEvent e)
        {
            if (e.Sensor.Type == SensorType.Accelerometer)
                this.mGravity = e.Values.ToArray();
            if (e.Sensor.Type == SensorType.MagneticField)
                this.mGeomagnetic = e.Values.ToArray();
            if (this.mGravity != null && this.mGeomagnetic != null)
            {
                float[] R = new float[9];
                float[] I = new float[9];
                bool success = SensorManager.GetRotationMatrix(R, I, this.mGravity, this.mGeomagnetic);
                if (success)
                {
                    var orientation = new float[3];
                    SensorManager.GetOrientation(R, orientation);
    
                    var rotation = new Vector3(orientation[0], orientation[1], orientation[2]);
                    this.ReadingReceived?.Invoke(this, rotation);
                }
            }
        }