We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2156

Summary: Android: Accelerometer values fed to joystick driver are inverted for the X axis and wrong for Z
Product: SDL Reporter: Denis Bernard <denis>
Component: joystickAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: denis
Version: HG 2.0   
Hardware: All   
OS: Android (All)   

Description Denis Bernard 2013-10-15 18:04:05 UTC
Background information: http://developer.android.com/reference/android/hardware/SensorEvent.html#values

Steps to reproduce: compile testjoystick.c as an android app (change screen size according to your device). While running the app, also run:

adb logcat -c; adb logcat -s 'SDL:*' 'SDL/APP:*'

When tilting the device left/right, the joystick moves in the opposite direction of what one would expect. Or at least, the behaviour is not consistent with the Y axis.

Also when the device sits on a table (obviously not moving), the Z axis value oscillates between -32000 and +32000 (by overflow):

I/SDL/APP ( 1994): Joystick 0 axis 2 value: 32511
I/SDL/APP ( 1994): Joystick 0 axis 2 value: 32575
I/SDL/APP ( 1994): Joystick 0 axis 2 value: 32383
I/SDL/APP ( 1994): Joystick 0 axis 2 value: -32386
I/SDL/APP ( 1994): Joystick 0 axis 2 value: -32450
I/SDL/APP ( 1994): Joystick 0 axis 2 value: -32578

This is caused by the accelerometer yielding a constant value around 9.81 for Z and feeding something like 0.9 to 1.1 to the joystick driver, resulting in the overflow. 

Proposed fix in SDLActivity.java (swap X and subtract G from Z reading):

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        SDLActivity.onNativeAccel(-event.values[0] / SensorManager.GRAVITY_EARTH,
                                  event.values[1] / SensorManager.GRAVITY_EARTH,
                                  event.values[2] / SensorManager.GRAVITY_EARTH - 1);
    }
}

Id'd suggest applying this on top of Bug 2155.
Comment 1 Sam Lantinga 2013-10-18 06:47:25 UTC
Can you double check this relative to your latest patch?

The code now looks like this:
            float x, y;
            switch (mDisplay.getRotation()) {
                case Surface.ROTATION_90:
                    x = -event.values[1];
                    y = event.values[0];
                    break;
                case Surface.ROTATION_270:
                    x = event.values[1];
                    y = -event.values[0];
                    break;
                case Surface.ROTATION_180:
                    x = -event.values[1];
                    y = -event.values[0];
                    break;
                default:
                    x = event.values[0];
                    y = event.values[1];
                    break;
            }
            SDLActivity.onNativeAccel(x / SensorManager.GRAVITY_EARTH,
                                      y / SensorManager.GRAVITY_EARTH,
                                      event.values[2] / SensorManager.GRAVITY_EARTH);
Comment 2 Denis Bernard 2013-10-18 11:24:25 UTC
(In reply to Sam Lantinga from comment #1)
> Can you double check this relative to your latest patch?

>             SDLActivity.onNativeAccel(x / SensorManager.GRAVITY_EARTH,
>                                       y / SensorManager.GRAVITY_EARTH,
>                                       event.values[2] /
> SensorManager.GRAVITY_EARTH);

Yes, this still stands. I didn't want to double patch ;) I'll provide a patch on top of 2155 this evening. In the meantime I'd appreciate if someone else could confirm this (wrong?) behaviour on other devices.

Also worth noting, I stumbled upon this bug when playing around with the Accelerometer iOS Demo where the value of the joystick's Y axis is negated:

float ax = SDL_JoystickGetAxis(accelerometer, 0);
float ay = -SDL_JoystickGetAxis(accelerometer, 1);

Is X or Y flipped as well on iOS?
Comment 3 Sam Lantinga 2013-10-21 06:53:07 UTC
Fixed!
http://hg.libsdl.org/SDL/rev/fdada7e3b3e7

iOS did indeed have an inverted Y axis, which is now also fixed.

Thanks!
Comment 4 Sam Lantinga 2013-10-21 06:53:24 UTC
Closing this bug.