jonasb jonasb - 3 months ago 10
Android Question

How to convert between sensor quaternion and 3d camera quaternion?

I get a quaternion from Android's Sensor.TYPE_ROTATION_VECTOR fused sensor using getQuaternionFromVector(). I want to use that quaternion to control the camera of my Rajawali app.

The values (w, x, y, z) I get from the sensor are (phone in landscape, looking straight ahead):


  • North: (0.5, 0.5, -0.5, 0.5)

  • East: (0.71, 0, -0.71, 0)

  • South: (0.5, -0.5, -0.5, -0.5)

  • West: (0, 0.71, 0, 0.71)



I need to transform this values to these correct values:


  • North: (1.0, 0, 0, 0)

  • East: (0.71, 0, 0.71, 0)

  • South: (0, 0, 1, 0)

  • West: (-0.71, 0, 0.71, 0)



Through some trial and error I've approached a solution, but I'm still some ways off. If I first rotate 90 deg against Y axis, and -90 deg against the X axis:

Quaternion a = new Quaternion(Vector3.Y, 90);
a.multiply(q);
Quaternion b = new Quaternion(Vector3.X, -90);
b.multiply(a);


The values I get are:


  • North: (1, 0, 0, 0)

  • East: (0.71, -0.71, 0, 0)

  • South: (0, -1, 0, 0)

  • West: (0.71, 0.71, 0, 0)



The result is that north is correct, east is up, west is down and south is upside down. I notice that the bearing is mixed up with pitch (I change the pitch of the device and the bearing of the camera changes, and the resevers).

Any suggestions for how to modify the sensor quaternion to match the expected quaternion value? How can I change it so that sensor bearing changes the camera bearing and not the pitch?

Thanks in advance!

Answer

Managed to sort it out.

public static Quaternion transform(Quaternion q) {
    Quaternion a = new Quaternion(Vector3.Y, 90).multiply(q);
    Quaternion b = new Quaternion(a.w, a.y, -a.x, -a.z);
    return b.multiply(new Quaternion(Vector3.Y, 90));
}