Calculation of proper Rotation Values from Gyroscope Sensor in Android

Arun AC picture Arun AC · Dec 16, 2011 · Viewed 8.4k times · Source

I am working on rotating the rectangle using the orientation values from gyroscope sensors in Android 3.1 device.

I have to rotate my device very fast to get values 1.0 and more.

Here is the code

final float currentRotVector[] =  { 1, 0, 0, 0 };
if (timestamp != 0)
{
    final float dT = (event.timestamp - timestamp) * NS2S;
    // Axis of the rotation sample, not normalized yet.

    // Calculate the angular speed of the sample
    float omegaMagnitude = (float) Math.sqrt(X * X + Y * Y + Z * Z);

    // Normalize the rotation vector if it's big enough to get the axis
    if (omegaMagnitude > EPSILON)
    {
    X /= omegaMagnitude;
    Y /= omegaMagnitude;
    Z /= omegaMagnitude;
    }

    // Integrate around this axis with the angular speed by the timestep
    // in order to get a delta rotation from this sample over the timestep
    // We will convert this axis-angle representation of the delta rotation
    // into a quaternion before turning it into the rotation matrix.
    float thetaOverTwo = dT * omegaMagnitude / 2.0f;
    float sinThetaOverTwo = (float) Math.sin(thetaOverTwo);
    float cosThetaOverTwo = (float) Math.cos(thetaOverTwo);
    deltaRotationVector[0] = cosThetaOverTwo;
    deltaRotationVector[1] = sinThetaOverTwo * X;
    deltaRotationVector[2] = sinThetaOverTwo * Y;
    deltaRotationVector[3] = sinThetaOverTwo * Z;

    /* quaternion multiplication 
        Reference: http://www.cprogramming.com/tutorial/3d/quaternions.html
    */

    currentRotVector[0] = deltaRotationVector[0] * currentRotVector[0] - 
                          deltaRotationVector[1] * currentRotVector[1] - 
                          deltaRotationVector[2] * currentRotVector[2] - 
                          deltaRotationVector[3] * currentRotVector[3];

    currentRotVector[1] = deltaRotationVector[0] * currentRotVector[1] + 
                          deltaRotationVector[1] * currentRotVector[0] + 
                          deltaRotationVector[2] * currentRotVector[3] - 
                          deltaRotationVector[3] * currentRotVector[2];

    currentRotVector[2] = deltaRotationVector[0] * currentRotVector[2] - 
                          deltaRotationVector[1] * currentRotVector[3] + 
                          deltaRotationVector[2] * currentRotVector[0] + 
                          deltaRotationVector[3] * currentRotVector[1];

    currentRotVector[3] = deltaRotationVector[0] * currentRotVector[3] + 
                          deltaRotationVector[1] * currentRotVector[2] - 
                          deltaRotationVector[2] * currentRotVector[1] + 
                          deltaRotationVector[3] * currentRotVector[0];
    final float rad2deg = (float) (180.0f / Math.PI);
    RotAngle = currentRotVector[0] * rad2deg;
    axisX = currentRotVector[1];
    axisY = currentRotVector[2];
    axisZ = currentRotVector[3];

    Log.i("Sensor Orientation GyroScope", "axisX: " + axisX + //
        " axisY: " + axisY + //
                    " axisZ: " + axisZ + //
        " RotAngle: " + RotAngle);
}

timestamp = event.timestamp;

I am getting some outputs like axisX: 0.69363713 axisY: 0.18359372 axisZ: 0.0228636 RotAngle: 36.7191 And because of the axis values, the output rectangle looked tweaked when the device is lay down on the table.

Is there any problem in the above code?

Answer

jap1968 picture jap1968 · Dec 16, 2011

The values are measeured in rad/s. This has been standarized starting from Android 2.3

To get values of about 1.0 you have to turn at a speed of almost 60 deg/s

Some devices having previous Android versions return (returned) values in degrees/s, but these are just a few. As an example, the LG Optimus Black (P970) with android 2.2 is one of these devices returning deg/s, but this is not the common case.