2
\$\begingroup\$

So using LibGDX accelerometer methods, I'm able to get the rotation of the device in the X and Z axes in degrees with this code:

 @Override
public void render(float delta) { 
    float accX = Gdx.input.getAccelerometerX(),
            accY = Gdx.input.getAccelerometerY(),
            accZ = Gdx.input.getAccelerometerZ();

    float moduleValue = (float) Math.sqrt(accX * accX + accY * accY + accZ * accZ);

    //Here I do the gravity compensation
    accX /= moduleValue;
    accY /= moduleValue;
    accZ /= moduleValue;

    float xRotation = (float) Math.atan2(accY, accZ) * MathUtils.radiansToDegrees,
            zRotation = (float) Math.atan2(accY, accX) * MathUtils.radiansToDegrees;}

However, get the rotation in the Y axis is not that easy to obtain, and if I try to get it by this way, it returns erroneus values.

\$\endgroup\$
3
  • \$\begingroup\$ Hmm, what values for Y-rotation do you get and what values do you expect? As it is, this code does not produce any values at all. \$\endgroup\$
    – Trilarion
    Aug 30 '16 at 8:30
  • \$\begingroup\$ @Trilarion I use this code in the render method. \$\endgroup\$
    – Alex Pi
    Aug 30 '16 at 21:31
  • \$\begingroup\$ See also this previous question on finding yaw from a 9DOF sensor. Note that accelerometers on their own are not able to detect rotation about the axis of gravity, so you need to apply sensor-fusion with a second sensor like a gyroscope to get this information. Note also that the code above labeled "gravity compensation" doesn't actually compensate for gravity, it just normalizes the acceleration vector, which could still contain a mix of gravity and motion signals. \$\endgroup\$
    – DMGregory
    Nov 13 '17 at 16:35
1
\$\begingroup\$

I'm not sure what your gravity compensations are doing, but you may not be taking units into account. The docs for Input.getAccelerometerY() say

The rate of rotation around the y axis. (rad/s)

To convert this to degrees, you have to convert from rad/s to rad then to degrees

float accY = Gdx.input.getAccelerometerY();
float degrees = accY * deltaTime * MathUtils.RadiansToDegrees;

Then degrees is how much the phone rotated on the Y axis this frame. Note that both the X and the Z axes also return in (rad/s).

Update:

Thanks to DMGregory for his comment to get to the root of this issue. The docs are indeed mixed up. The getGyroscope functions are the ones that give rotation in rad/s. The getAccelerometer functions give acceleration in m/s^2

If you look at the source for the Android implementation of the Input interface all it does it sets up a SensorEventListener and then copy the values of each Sensor.TYPE_ACCELEROMETER event into an accelerometerValues[3] array and returns one of its members on a call to getAccelerometer. The same occurs for Sensor.TYPE_GYROSCOPE and the getGyroscope functions.

For reference on what these android specific values mean, one can look here

TLDR;

The docs are wrong. For rotation, use getGyroscope. It is the function that will give you rotation around the phone's local axis in rad/s

\$\endgroup\$
2
  • 1
    \$\begingroup\$ That quote from the docs looks a bit fishy. Usually an accelerometer would be measuring acceleration in Gs. Radians per second of rotation would normally come from the rate gyroscope instead. I notice that the docs here are blank for the getGyroscope methods which might suggest there was an error in creating the document, where the gyroscope entries accidentally got placed in the accelerometer section. \$\endgroup\$
    – DMGregory
    Mar 16 '17 at 12:27
  • \$\begingroup\$ Good catch. The docs are wrong. I updated my answer \$\endgroup\$ Mar 16 '17 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.