From 7badd2c402f9e8e9fd13f6915ad2e32301f9f305 Mon Sep 17 00:00:00 2001
From: Mathias Agopian
Date: Mon, 22 Nov 2010 15:48:10 -0800
Subject: allow rotation-vector to have 4 components
- upadte documentation for rotation vector
- update method dealing with rotation vector to deal with 4 components
- virtual rotation-vector sensor reports all four components
- improve SensorManager documentation layout
Whent he 4-th component of the rotation-vector is present, we can save
a square-root when computing the quaternion or rotation matrix from it.
Change-Id: Ia84d278dd5f0909fab1c5ba050f8df2679e2c7c8
---
core/java/android/hardware/SensorEvent.java | 48 ++++++++++++++++++-------
core/java/android/hardware/SensorManager.java | 21 +++++++----
services/sensorservice/RotationVectorSensor.cpp | 1 +
3 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 32ff3b3d9791..8c55bf33788b 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -220,25 +220,47 @@ public class SensorEvent {
*
*
* {@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:
- * A three dimensional vector indicating the direction and magnitude of gravity. Units
- * are m/s^2. The coordinate system is the same as is used by the acceleration sensor.
+ * A three dimensional vector indicating the direction and magnitude of gravity. Units
+ * are m/s^2. The coordinate system is the same as is used by the acceleration sensor.
+ * Note: When the device is at rest, the output of the gravity sensor should be identical
+ * to that of the accelerometer.
*
* {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:
* A three dimensional vector indicating acceleration along each device axis, not including
* gravity. All values have units of m/s^2. The coordinate system is the same as is used by the
- * acceleration sensor.
+ * acceleration sensor.
+ * The output of the accelerometer, gravity and linear-acceleration sensors must obey the
+ * following relation:
+ * acceleration = gravity + linear-acceleration
*
* {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:
- * The rotation vector represents the orientation of the device as a combination of an angle
- * and an axis, in which the device has rotated through an angle theta around an axis
- * <x, y, z>. The three elements of the rotation vector are
- * <x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>, such that the magnitude of the rotation
- * vector is equal to sin(theta/2), and the direction of the rotation vector is equal to the
- * direction of the axis of rotation. The three elements of the rotation vector are equal to
- * the last three components of a unit quaternion
- * <cos(theta/2), x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>. Elements of the rotation
- * vector are unitless. The x,y, and z axis are defined in the same way as the acceleration
- * sensor.
+ * The rotation vector represents the orientation of the device as a combination of an angle
+ * and an axis, in which the device has rotated through an angle θ around an axis
+ * <x, y, z>.
+ * The three elements of the rotation vector are
+ * <x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)>, such that the magnitude of the rotation
+ * vector is equal to sin(θ/2), and the direction of the rotation vector is equal to the
+ * direction of the axis of rotation.
+ * The three elements of the rotation vector are equal to
+ * the last three components of a unit quaternion
+ * <cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)>.
+ * Elements of the rotation vector are unitless.
+ * The x,y, and z axis are defined in the same way as the acceleration
+ * sensor.
+ *
+ *
+ * values[0]: x*sin(θ/2)
+ *
+ *
+ * values[1]: y*sin(θ/2)
+ *
+ *
+ * values[2]: z*sin(θ/2)
+ *
+ *
+ * values[3]: cos(θ/2) (optional: only if value.length = 4)
+ *
+ *
*
* {@link android.hardware.Sensor#TYPE_ORIENTATION
* Sensor.TYPE_ORIENTATION}:
All values are angles in degrees.
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index c178aee3d548..1b799aed857f 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1938,13 +1938,18 @@ public class SensorManager
* @param R an array of floats in which to store the rotation matrix
*/
public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) {
- float q0 = (float)Math.sqrt(1 - rotationVector[0]*rotationVector[0] -
- rotationVector[1]*rotationVector[1] -
- rotationVector[2]*rotationVector[2]);
+
+ float q0;
float q1 = rotationVector[0];
float q2 = rotationVector[1];
float q3 = rotationVector[2];
+ if (rotationVector.length == 4) {
+ q0 = rotationVector[3];
+ } else {
+ q0 = (float)Math.sqrt(1 - q1*q1 - q2*q2 - q3*q3);
+ }
+
float sq_q1 = 2 * q1 * q1;
float sq_q2 = 2 * q2 * q2;
float sq_q3 = 2 * q3 * q3;
@@ -1995,10 +2000,12 @@ public class SensorManager
* @param Q an array of floats in which to store the computed quaternion
*/
public static void getQuaternionFromVector(float[] Q, float[] rv) {
- float w = (float)Math.sqrt(1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]);
- //In this case, the w component of the quaternion is known to be a positive number
-
- Q[0] = w;
+ if (rv.length == 4) {
+ Q[0] = rv[3];
+ } else {
+ //In this case, the w component of the quaternion is known to be a positive number
+ Q[0] = (float)Math.sqrt(1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]);
+ }
Q[1] = rv[0];
Q[2] = rv[1];
Q[3] = rv[2];
diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp
index eecf260a7724..50cd6beac37b 100644
--- a/services/sensorservice/RotationVectorSensor.cpp
+++ b/services/sensorservice/RotationVectorSensor.cpp
@@ -125,6 +125,7 @@ bool RotationVectorSensor::process(sensors_event_t* outEvent,
outEvent->data[0] = qx;
outEvent->data[1] = qy;
outEvent->data[2] = qz;
+ outEvent->data[3] = qw;
outEvent->sensor = '_rov';
outEvent->type = SENSOR_TYPE_ROTATION_VECTOR;
return true;
--
cgit v1.2.3-59-g8ed1b