Android get quaternion data

5.1k views Asked by At

Fast and simple. How to get the quaternion data from the sensors? basically I need:

float quaternion_x = ?
float quaternion_y = ?
float quaternion_z = ?
float quaternion_w = ?

I have something like this:

if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR)
{
    float[] values = event.values;

    float quaternion_x = values[0];
    float quaternion_y = values[1];
    float quaternion_z = values[2];
    float quaternion_w = values[3];  <----- ERROR HERE 
}

I get an index out of bound exception because values has only 3 values inside. According to this page: http://developer.android.com/guide/topics/sensors/sensors_motion.html There should be 4 values or am I understanding something wrong?

2

There are 2 answers

0
click_whir On BEST ANSWER

The SensorManager class offers a helper function to convert for you:

SensorManager.getQuaternionFromVector(Q, values);
float[] quaternion_w = Q[0];
float[] quaternion_x = Q[1];
float[] quaternion_y = Q[2];
float[] quaternion_z = Q[3];
0
José Lozano Hernández On

The android implementation of getOrientation returns the same values of getQuaterionFromVector. So, you can take those values and construct the Quaternion if you want;

float[] quaternion = new float[4];
quaternion[0] = 0;  //w
quaternion[1] = orientation[0];  //x
quaternion[2] = orientation[1];  //y
quaternion[3] = orientation[2];  //z

I checked it out with this code.

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
        mMagneticField = event.values;
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        mGravity = event.values;
    if ((mGravity == null) || (mMagneticField == null))
        return;

    float R[] = new float[9];
    float I[] = new float[9];
    boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mMagneticField);
    if (success) {
        mOrientation = new float[3];
        mQuaternion = new float[4];
        SensorManager.getOrientation(R, mOrientation);
        mAzimut = mOrientation[0]; // orientation contains: azimut, pitch and roll
        mPitch = mOrientation[1];
        mRoll = mOrientation[2];

        SensorManager.getQuaternionFromVector(mQuaternion, mOrientation);

        if(mAzimut - mQuaternion[1] == 0 && mPitch - mQuaternion[2] == 0 && mRoll - mQuaternion[3] == 0){
            Log.d("ORIENTATION", "QUATERNION IS THE SAME");
        }
        notifyObservers();
    }
}