From ca09d8cf8c7bd0ad58f667941e888002dfc4b8da Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Thu, 21 May 2015 18:06:06 -0700 Subject: [PATCH] Bug fix and documentation clarification Clarify definition of rotation angles used in SensorManager.getOrientation and SensorManager.getAngleChange. Clarify the condition of a free-fall in SensorManager.getRotation, and added code to guard against such condition. Fix a typo that causes confusion in the definition of TYPE_ORIENTATION data in SensorEvent. Change-Id: I614d981ec7b1b52c5ec59d5b40b84cd600df65e7 See: b/21337218, b/21337552, b/21337606. --- core/java/android/hardware/SensorEvent.java | 4 +- core/java/android/hardware/SensorManager.java | 59 +++++++++++-------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java index 2bc0f9bbde663..906c2a1941d59 100644 --- a/core/java/android/hardware/SensorEvent.java +++ b/core/java/android/hardware/SensorEvent.java @@ -312,7 +312,7 @@ public class SensorEvent { *

* *

- * values[2]: Roll, rotation around the x-axis (-90 to 90) + * values[2]: Roll, rotation around the y-axis (-90 to 90) * increasing as the device moves clockwise. *

* @@ -325,6 +325,8 @@ public class SensorEvent { * *

* Note: This sensor type exists for legacy reasons, please use + * {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR + * rotation vector sensor type} and * {@link android.hardware.SensorManager#getRotationMatrix * getRotationMatrix()} in conjunction with * {@link android.hardware.SensorManager#remapCoordinateSystem diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index 861969e773b41..fda889f0f4152 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -967,8 +967,9 @@ public abstract class SensorManager { * TYPE_MAGNETIC_FIELD}. * * @return true on success, false on failure (for - * instance, if the device is in free fall). On failure the output - * matrices are not modified. + * instance, if the device is in free fall). Free fall is defined as + * condition when the magnitude of the gravity is less than 1/10 of + * the nominal value. On failure the output matrices are not modified. * * @see #getInclination(float[]) * @see #getOrientation(float[], float[]) @@ -981,6 +982,15 @@ public abstract class SensorManager { float Ax = gravity[0]; float Ay = gravity[1]; float Az = gravity[2]; + + final float normsqA = (Ax*Ax + Ay*Ay + Az*Az); + final float g = 9.81f; + final float freeFallGravitySquared = 0.01f * g * g; + if (normsqA < freeFallGravitySquared) { + // gravity less than 10% of normal value + return false; + } + final float Ex = geomagnetic[0]; final float Ey = geomagnetic[1]; final float Ez = geomagnetic[2]; @@ -988,6 +998,7 @@ public abstract class SensorManager { float Hy = Ez*Ax - Ex*Az; float Hz = Ex*Ay - Ey*Ax; final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); + if (normH < 0.1f) { // device is close to free fall (or in space?), or close to // magnetic north pole. Typical values are > 100. @@ -1117,12 +1128,12 @@ public abstract class SensorManager { * returned by {@link #getRotationMatrix}. * * @param X - * defines on which world axis and direction the X axis of the device - * is mapped. + * defines the axis of the new cooridinate system that coincide with the X axis of the + * original coordinate system. * * @param Y - * defines on which world axis and direction the Y axis of the device - * is mapped. + * defines the axis of the new cooridinate system that coincide with the Y axis of the + * original coordinate system. * * @param outR * the transformed rotation matrix. inR and outR should not be the same @@ -1219,27 +1230,18 @@ public abstract class SensorManager { *

* When it returns, the array values is filled with the result: *

- *

The reference coordinate-system used is different from the world - * coordinate-system defined for the rotation matrix:

- * - * - *

- *

Inverted world coordinate-system diagram.
- *

*

+ * Applying these three intrinsic rotations in azimuth, pitch and roll order transforms + * identity matrix to the rotation matrix given in input R. * All three angles above are in radians and positive in the - * counter-clockwise direction. + * counter-clockwise direction. Range of output is: azimuth from -π to π, + * pitch from -π/2 to π/2 and roll from -π to π. * * @param R * rotation matrix see {@link #getRotationMatrix}. @@ -1275,6 +1277,7 @@ public abstract class SensorManager { values[1] = (float)Math.asin(-R[9]); values[2] = (float)Math.atan2(-R[8], R[10]); } + return values; } @@ -1314,9 +1317,9 @@ public abstract class SensorManager { /** Helper function to compute the angle change between two rotation matrices. * Given a current rotation matrix (R) and a previous rotation matrix - * (prevR) computes the rotation around the z,x, and y axes which + * (prevR) computes the intrinsic rotation around the z, x, and y axes which * transforms prevR to R. - * outputs a 3 element vector containing the z,x, and y angle + * outputs a 3 element vector containing the z, x, and y angle * change at indexes 0, 1, and 2 respectively. *

Each input matrix is either as a 3x3 or 4x4 row-major matrix * depending on the length of the passed array: @@ -1333,9 +1336,13 @@ public abstract class SensorManager { * | R[ 8] R[ 9] R[10] R[11] | * \ R[12] R[13] R[14] R[15] / * + * + * See {@link #getOrientation} for more detailed definition of the output. + * * @param R current rotation matrix * @param prevR previous rotation matrix - * @param angleChange an an array of floats (z, x, and y) in which the angle change is stored + * @param angleChange an an array of floats (z, x, and y) in which the angle change + * (in radians) is stored */ public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {