I testing the accelerometer output on 2 different devices(Elocity A7 and Archos 7 Home tablet) but the sensor seems to be giving different results. I have it programmed to set to landscape mode but the x and y axis seem to be the oppisite between the 2 devices. The x axis returns 10 when held perpendicular to the ground and the Archos X axis returns 0. The Elocity tablet is android 2.2 and the Archos is 2.1. Can someone point me in the right direction as how to get orientation from the accelerometer in sync between these 2 devices?
In fact, the accelerometer axises are relative to the default orientation of the device.
Here how to deal with it:
static void canonicalOrientationToScreenOrientation(
int displayRotation, float[] canVec, float[] screenVec)
{
final int axisSwap[][] = {
{ 1, -1, 0, 1 }, // ROTATION_0
{-1, -1, 1, 0 }, // ROTATION_90
{-1, 1, 0, 1 }, // ROTATION_180
{ 1, 1, 1, 0 } }; // ROTATION_270
final int[] as = axisSwap[displayRotation];
screenVec[0] = (float)as[0] * canVec[ as[2] ];
screenVec[1] = (float)as[1] * canVec[ as[3] ];
screenVec[2] = canVec[2];
}
This solution was provided by NVidia. Check their white paper about Android Accelerometer for more details.
just wanted to add something to Hartok's answer as I couldn't understand it at first...
I've rewritten the method to be:
public static float[] adjustAccelOrientation(int displayRotation, float[] eventValues)
{
float[] adjustedValues = new float[3];
final int axisSwap[][] = {
{ 1, -1, 0, 1 }, // ROTATION_0
{-1, -1, 1, 0 }, // ROTATION_90
{-1, 1, 0, 1 }, // ROTATION_180
{ 1, 1, 1, 0 } }; // ROTATION_270
final int[] as = axisSwap[displayRotation];
adjustedValues[0] = (float)as[0] * eventValues[ as[2] ];
adjustedValues[1] = (float)as[1] * eventValues[ as[3] ];
adjustedValues[2] = eventValues[2];
return adjustedValues;
}
Exactly the same thing, just with more user friendly variable names and I recreate the float internally because I needed it like that... Simply call this function, put in the getRotation and the event.values float array, check the values of its return float array and pick whatever number you prefer...
Hope this helps someone!
As far as I know this is because of default orientation of device. F.e. new android tablets with Honeycomb have portrait orientation when held like in landscape on phones.
http://developer.android.com/reference/android/hardware/SensorEvent.html
In android documentation there is information that:
The coordinate-system is defined relative to the screen of the phone in its default orientation. The axes are not swapped when the device's screen orientation changes.
The X axis is horizontal and points to the right, the Y axis is vertical and points up and the Z axis points towards the outside of the front face of the screen. In this system, coordinates behind the screen have negative Z values.
Maybe one of this devices has also landscape as a portrait (default) orientation?
Hope it helps you somehow.
As stated before, the default screen orientation can vary from device to device. The accelerometer coordinates will always match the devices default orientation. This behavior is different for screen coordinates. As the device rotates the screen coordinates rotates as well, such that (0, 0) is always the current top left corner of the screen. On a device with a default orientation of portrait, locking the orientation to portrait will ensure that the sensor coordinates run along the same axis as the screen coordinates regardless of the rotation. On the other hand, locking the screen orientation to portrait on a device with a default landscape orientation will cause the sensor axis to run in a different direction than the screen axis.
This article: http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html explains this in greater depth as well as gives a solution for dealing with the problem.
来源:https://stackoverflow.com/questions/5877780/orientation-from-android-accelerometer