Skip to content

Commit 691be97

Browse files
Jean-Baptiste QueruAndroid Code Review
authored andcommitted
Merge "add new sensor types for handling gyro data and device orientation more efficiently."
2 parents 32f510e + f35fd95 commit 691be97

File tree

4 files changed

+312
-3
lines changed

4 files changed

+312
-3
lines changed

api/current.xml

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73532,6 +73532,17 @@
7353273532
visibility="public"
7353373533
>
7353473534
</field>
73535+
<field name="TYPE_GRAVITY"
73536+
type="int"
73537+
transient="false"
73538+
volatile="false"
73539+
value="9"
73540+
static="true"
73541+
final="true"
73542+
deprecated="not deprecated"
73543+
visibility="public"
73544+
>
73545+
</field>
7353573546
<field name="TYPE_GYROSCOPE"
7353673547
type="int"
7353773548
transient="false"
@@ -73554,6 +73565,17 @@
7355473565
visibility="public"
7355573566
>
7355673567
</field>
73568+
<field name="TYPE_LINEAR_ACCELERATION"
73569+
type="int"
73570+
transient="false"
73571+
volatile="false"
73572+
value="10"
73573+
static="true"
73574+
final="true"
73575+
deprecated="not deprecated"
73576+
visibility="public"
73577+
>
73578+
</field>
7355773579
<field name="TYPE_MAGNETIC_FIELD"
7355873580
type="int"
7355973581
transient="false"
@@ -73598,6 +73620,17 @@
7359873620
visibility="public"
7359973621
>
7360073622
</field>
73623+
<field name="TYPE_ROTATION_VECTOR"
73624+
type="int"
73625+
transient="false"
73626+
volatile="false"
73627+
value="11"
73628+
static="true"
73629+
final="true"
73630+
deprecated="not deprecated"
73631+
visibility="public"
73632+
>
73633+
</field>
7360173634
<field name="TYPE_TEMPERATURE"
7360273635
type="int"
7360373636
transient="false"
@@ -73742,6 +73775,23 @@
7374273775
deprecated="not deprecated"
7374373776
visibility="public"
7374473777
>
73778+
<method name="getAngleChange"
73779+
return="void"
73780+
abstract="false"
73781+
native="false"
73782+
synchronized="false"
73783+
static="true"
73784+
final="false"
73785+
deprecated="not deprecated"
73786+
visibility="public"
73787+
>
73788+
<parameter name="angleChange" type="float[]">
73789+
</parameter>
73790+
<parameter name="R" type="float[]">
73791+
</parameter>
73792+
<parameter name="prevR" type="float[]">
73793+
</parameter>
73794+
</method>
7374573795
<method name="getDefaultSensor"
7374673796
return="android.hardware.Sensor"
7374773797
abstract="false"
@@ -73783,6 +73833,21 @@
7378373833
<parameter name="values" type="float[]">
7378473834
</parameter>
7378573835
</method>
73836+
<method name="getQuaternionFromVector"
73837+
return="void"
73838+
abstract="false"
73839+
native="false"
73840+
synchronized="false"
73841+
static="true"
73842+
final="false"
73843+
deprecated="not deprecated"
73844+
visibility="public"
73845+
>
73846+
<parameter name="Q" type="float[]">
73847+
</parameter>
73848+
<parameter name="rv" type="float[]">
73849+
</parameter>
73850+
</method>
7378673851
<method name="getRotationMatrix"
7378773852
return="boolean"
7378873853
abstract="false"
@@ -73802,6 +73867,21 @@
7380273867
<parameter name="geomagnetic" type="float[]">
7380373868
</parameter>
7380473869
</method>
73870+
<method name="getRotationMatrixFromVector"
73871+
return="void"
73872+
abstract="false"
73873+
native="false"
73874+
synchronized="false"
73875+
static="true"
73876+
final="false"
73877+
deprecated="not deprecated"
73878+
visibility="public"
73879+
>
73880+
<parameter name="R" type="float[]">
73881+
</parameter>
73882+
<parameter name="rotationVector" type="float[]">
73883+
</parameter>
73884+
</method>
7380573885
<method name="getSensorList"
7380673886
return="java.util.List&lt;android.hardware.Sensor&gt;"
7380773887
abstract="false"
@@ -237873,7 +237953,7 @@
237873237953
<method name="availableProcessors"
237874237954
return="int"
237875237955
abstract="false"
237876-
native="false"
237956+
native="true"
237877237957
synchronized="false"
237878237958
static="false"
237879237959
final="false"

core/java/android/hardware/Sensor.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,27 @@ public class Sensor {
6969
*/
7070
public static final int TYPE_PROXIMITY = 8;
7171

72-
72+
/**
73+
* A constant describing a gravity sensor type.
74+
* See {@link android.hardware.SensorEvent SensorEvent}
75+
* for more details.
76+
*/
77+
public static final int TYPE_GRAVITY = 9;
78+
79+
/**
80+
* A constant describing a linear acceleration sensor type.
81+
* See {@link android.hardware.SensorEvent SensorEvent}
82+
* for more details.
83+
*/
84+
public static final int TYPE_LINEAR_ACCELERATION = 10;
85+
86+
/**
87+
* A constant describing a rotation vector sensor type.
88+
* See {@link android.hardware.SensorEvent SensorEvent}
89+
* for more details.
90+
*/
91+
public static final int TYPE_ROTATION_VECTOR = 11;
92+
7393
/**
7494
* A constant describing all sensor types.
7595
*/

core/java/android/hardware/SensorEvent.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ public class SensorEvent {
119119
* All values are in micro-Tesla (uT) and measure the ambient magnetic
120120
* field in the X, Y and Z axis.
121121
*
122+
* <p>{@link android.hardware.Sensor#TYPE_GYROSCOPE Sensor.TYPE_GYROSCOPE}:<p>
123+
* All values are in radians/second and measure the rate of rotation
124+
* around the X, Y and Z axis. The coordinate system is the same as is
125+
* used for the acceleration sensor. Rotation is positive in the counter-clockwise
126+
* direction. That is, an observer looking from some positive location on the x, y.
127+
* or z axis at a device positioned on the origin would report positive rotation
128+
* if the device appeared to be rotating counter clockwise. Note that this is the
129+
* standard mathematical definition of positive rotation and does not agree with the
130+
* definition of roll given earlier.
131+
*
122132
* <p>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:<p>
123133
*
124134
* <p>values[0]: Ambient light level in SI lux units
@@ -130,7 +140,29 @@ public class SensorEvent {
130140
* <p> Note that some proximity sensors only support a binary "close" or "far" measurement.
131141
* In this case, the sensor should report its maxRange value in the "far" state and a value
132142
* less than maxRange in the "near" state.
143+
*
144+
* <p>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:<p>
145+
* A three dimensional vector indicating the direction and magnitude of gravity. Units
146+
* are m/s^2. The coordinate system is the same as is used by the acceleration sensor.
147+
*
148+
* <p>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:<p>
149+
* A three dimensional vector indicating acceleration along each device axis, not including
150+
* gravity. All values have units of m/s^2. The coordinate system is the same as is used by the
151+
* acceleration sensor.
152+
*
153+
* <p>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:<p>
154+
* The rotation vector represents the orientation of the device as a combination of an angle
155+
* and an axis, in which the device has rotated through an angle theta around an axis
156+
* <x, y, z>. The three elements of the rotation vector are
157+
* <x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>, such that the magnitude of the rotation
158+
* vector is equal to sin(theta/2), and the direction of the rotation vector is equal to the
159+
* direction of the axis of rotation. The three elements of the rotation vector are equal to
160+
* the last three components of a unit quaternion
161+
* <cos(theta/2), x*sin(theta/2), y*sin(theta/2), z*sin(theta/2)>. Elements of the rotation
162+
* vector are unitless. The x,y, and z axis are defined in the same way as the acceleration
163+
* sensor.
133164
*/
165+
134166
public final float[] values;
135167

136168
/**

core/java/android/hardware/SensorManager.java

Lines changed: 178 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1555,7 +1555,184 @@ public float filter(long time, float in) {
15551555
}
15561556
}
15571557

1558-
1558+
1559+
/** Helper function to compute the angle change between two rotation matrices.
1560+
* Given a current rotation matrix (R) and a previous rotation matrix
1561+
* (prevR) computes the rotation around the x,y, and z axes which
1562+
* transforms prevR to R.
1563+
* outputs a 3 element vector containing the x,y, and z angle
1564+
* change at indexes 0, 1, and 2 respectively.
1565+
* <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix
1566+
* depending on the length of the passed array:
1567+
* <p>If the array length is 9, then the array elements represent this matrix
1568+
* <pre>
1569+
* / R[ 0] R[ 1] R[ 2] \
1570+
* | R[ 3] R[ 4] R[ 5] |
1571+
* \ R[ 6] R[ 7] R[ 8] /
1572+
*</pre>
1573+
* <p>If the array length is 16, then the array elements represent this matrix
1574+
* <pre>
1575+
* / R[ 0] R[ 1] R[ 2] R[ 3] \
1576+
* | R[ 4] R[ 5] R[ 6] R[ 7] |
1577+
* | R[ 8] R[ 9] R[10] R[11] |
1578+
* \ R[12] R[13] R[14] R[15] /
1579+
*</pre>
1580+
* @param R current rotation matrix see {@link android.hardware.Sensor#TYPE_ROTATION_MATRIX}.
1581+
* @param prevR previous rotation matrix
1582+
* @param angleChange an array of floats in which the angle change is stored
1583+
*/
1584+
1585+
public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
1586+
float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0;
1587+
float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0;
1588+
float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0;
1589+
int i, j, k;
1590+
1591+
if(R.length == 9) {
1592+
ri0 = R[0];
1593+
ri1 = R[1];
1594+
ri2 = R[2];
1595+
ri3 = R[3];
1596+
ri4 = R[4];
1597+
ri5 = R[5];
1598+
ri6 = R[6];
1599+
ri7 = R[7];
1600+
ri8 = R[8];
1601+
} else if(R.length == 16) {
1602+
ri0 = R[0];
1603+
ri1 = R[1];
1604+
ri2 = R[2];
1605+
ri3 = R[4];
1606+
ri4 = R[5];
1607+
ri5 = R[6];
1608+
ri6 = R[8];
1609+
ri7 = R[9];
1610+
ri8 = R[10];
1611+
}
1612+
1613+
if(prevR.length == 9) {
1614+
pri0 = R[0];
1615+
pri1 = R[1];
1616+
pri2 = R[2];
1617+
pri3 = R[3];
1618+
pri4 = R[4];
1619+
pri5 = R[5];
1620+
pri6 = R[6];
1621+
pri7 = R[7];
1622+
pri8 = R[8];
1623+
} else if(prevR.length == 16) {
1624+
pri0 = R[0];
1625+
pri1 = R[1];
1626+
pri2 = R[2];
1627+
pri3 = R[4];
1628+
pri4 = R[5];
1629+
pri5 = R[6];
1630+
pri6 = R[8];
1631+
pri7 = R[9];
1632+
pri8 = R[10];
1633+
}
1634+
1635+
// calculate the parts of the rotation difference matrix we need
1636+
// rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j];
1637+
1638+
rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1]
1639+
rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1]
1640+
rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0]
1641+
rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1]
1642+
rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2]
1643+
1644+
angleChange[0] = (float)Math.atan2(rd1, rd4);
1645+
angleChange[1] = (float)Math.asin(-rd7);
1646+
angleChange[2] = (float)Math.atan2(-rd6, rd8);
1647+
1648+
}
1649+
1650+
/** Helper function to convert a rotation vector to a rotation matrix.
1651+
* Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a
1652+
* 9 or 16 element rotation matrix in the array R. R must have length 9 or 16.
1653+
* If R.length == 9, the following matrix is returned:
1654+
* <pre>
1655+
* / R[ 0] R[ 1] R[ 2] \
1656+
* | R[ 3] R[ 4] R[ 5] |
1657+
* \ R[ 6] R[ 7] R[ 8] /
1658+
*</pre>
1659+
* If R.length == 16, the following matrix is returned:
1660+
* <pre>
1661+
* / R[ 0] R[ 1] R[ 2] 0 \
1662+
* | R[ 4] R[ 5] R[ 6] 0 |
1663+
* | R[ 8] R[ 9] R[10] 0 |
1664+
* \ 0 0 0 1 /
1665+
*</pre>
1666+
* @param rotationVector the rotation vector to convert
1667+
* @param R an array of floats in which to store the rotation matrix
1668+
*/
1669+
public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) {
1670+
float q0 = (float)Math.sqrt(1 - rotationVector[0]*rotationVector[0] -
1671+
rotationVector[1]*rotationVector[1] -
1672+
rotationVector[2]*rotationVector[2]);
1673+
float q1 = rotationVector[0];
1674+
float q2 = rotationVector[1];
1675+
float q3 = rotationVector[2];
1676+
1677+
float sq_q1 = 2 * q1 * q1;
1678+
float sq_q2 = 2 * q2 * q2;
1679+
float sq_q3 = 2 * q3 * q3;
1680+
float q1_q2 = 2 * q1 * q2;
1681+
float q3_q0 = 2 * q3 * q0;
1682+
float q1_q3 = 2 * q1 * q3;
1683+
float q2_q0 = 2 * q2 * q0;
1684+
float q2_q3 = 2 * q2 * q3;
1685+
float q1_q0 = 2 * q1 * q0;
1686+
1687+
if(R.length == 9) {
1688+
R[0] = 1 - sq_q2 - sq_q3;
1689+
R[1] = q1_q2 - q3_q0;
1690+
R[2] = q1_q3 + q2_q0;
1691+
1692+
R[3] = q1_q2 + q3_q0;
1693+
R[4] = 1 - sq_q1 - sq_q3;
1694+
R[5] = q2_q3 - q1_q0;
1695+
1696+
R[6] = q1_q3 - q2_q0;
1697+
R[7] = q2_q3 + q1_q0;
1698+
R[8] = 1 - sq_q1 - sq_q2;
1699+
} else if (R.length == 16) {
1700+
R[0] = 1 - sq_q2 - sq_q3;
1701+
R[1] = q1_q2 - q3_q0;
1702+
R[2] = q1_q3 + q2_q0;
1703+
R[3] = 0.0f;
1704+
1705+
R[4] = q1_q2 + q3_q0;
1706+
R[5] = 1 - sq_q1 - sq_q3;
1707+
R[6] = q2_q3 - q1_q0;
1708+
R[7] = 0.0f;
1709+
1710+
R[8] = q1_q3 - q2_q0;
1711+
R[9] = q2_q3 + q1_q0;
1712+
R[10] = 1 - sq_q1 - sq_q2;
1713+
R[11] = 0.0f;
1714+
1715+
R[12] = R[13] = R[14] = 0.0f;
1716+
R[15] = 1.0f;
1717+
}
1718+
}
1719+
1720+
/** Helper function to convert a rotation vector to a normalized quaternion.
1721+
* Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized
1722+
* quaternion in the array Q. The quaternion is stored as [w, x, y, z]
1723+
* @param rv the rotation vector to convert
1724+
* @param Q an array of floats in which to store the computed quaternion
1725+
*/
1726+
public static void getQuaternionFromVector(float[] Q, float[] rv) {
1727+
float w = (float)Math.sqrt(1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]);
1728+
//In this case, the w component of the quaternion is known to be a positive number
1729+
1730+
Q[0] = w;
1731+
Q[1] = rv[0];
1732+
Q[2] = rv[1];
1733+
Q[3] = rv[2];
1734+
}
1735+
15591736
private static native void nativeClassInit();
15601737

15611738
private static native int sensors_module_init();

0 commit comments

Comments
 (0)