SensorEvent.java revision c6b7a0131e92a0bdeb268cee185404ceae9b54b7
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.hardware;
18
19/**
20 * <p>
21 * This class represents a {@link android.hardware.Sensor Sensor} event and
22 * holds informations such as the sensor's type, the time-stamp, accuracy and of
23 * course the sensor's {@link SensorEvent#values data}.
24 * </p>
25 *
26 * <p>
27 * <u>Definition of the coordinate system used by the SensorEvent API.</u>
28 * </p>
29 *
30 * <p>
31 * The coordinate-system is defined relative to the screen of the phone in its
32 * default orientation. The axes are not swapped when the device's screen
33 * orientation changes.
34 * </p>
35 *
36 * <p>
37 * The X axis is horizontal and points to the right, the Y axis is vertical and
38 * points up and the Z axis points towards the outside of the front face of the
39 * screen. In this system, coordinates behind the screen have negative Z values.
40 * </p>
41 *
42 * <p>
43 * <center><img src="../../../images/axis_device.png"
44 * alt="Sensors coordinate-system diagram." border="0" /></center>
45 * </p>
46 *
47 * <p>
48 * <b>Note:</b> This coordinate system is different from the one used in the
49 * Android 2D APIs where the origin is in the top-left corner.
50 * </p>
51 *
52 * @see SensorManager
53 * @see SensorEvent
54 * @see Sensor
55 *
56 */
57
58public class SensorEvent {
59    /**
60     * <p>
61     * The length and contents of the {@link #values values} array depends on
62     * which {@link android.hardware.Sensor sensor} type is being monitored (see
63     * also {@link SensorEvent} for a definition of the coordinate system used).
64     * </p>
65     *
66     * <h4>{@link android.hardware.Sensor#TYPE_ACCELEROMETER
67     * Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2)
68     *
69     * <ul>
70     * <p>
71     * values[0]: Acceleration minus Gx on the x-axis
72     * </p>
73     * <p>
74     * values[1]: Acceleration minus Gy on the y-axis
75     * </p>
76     * <p>
77     * values[2]: Acceleration minus Gz on the z-axis
78     * </p>
79     * </ul>
80     *
81     * <p>
82     * A sensor of this type measures the acceleration applied to the device
83     * (<b>Ad</b>). Conceptually, it does so by measuring forces applied to the
84     * sensor itself (<b>Fs</b>) using the relation:
85     * </p>
86     *
87     * <b><center>Ad = - &#8721;Fs / mass</center></b>
88     *
89     * <p>
90     * In particular, the force of gravity is always influencing the measured
91     * acceleration:
92     * </p>
93     *
94     * <b><center>Ad = -g - &#8721;F / mass</center></b>
95     *
96     * <p>
97     * For this reason, when the device is sitting on a table (and obviously not
98     * accelerating), the accelerometer reads a magnitude of <b>g</b> = 9.81
99     * m/s^2
100     * </p>
101     *
102     * <p>
103     * Similarly, when the device is in free-fall and therefore dangerously
104     * accelerating towards to ground at 9.81 m/s^2, its accelerometer reads a
105     * magnitude of 0 m/s^2.
106     * </p>
107     *
108     * <p>
109     * It should be apparent that in order to measure the real acceleration of
110     * the device, the contribution of the force of gravity must be eliminated.
111     * This can be achieved by applying a <i>high-pass</i> filter. Conversely, a
112     * <i>low-pass</i> filter can be used to isolate the force of gravity.
113     * </p>
114     *
115     * <pre class="prettyprint">
116     *
117     *     public void onSensorChanged(SensorEvent event)
118     *     {
119     *          // alpha is calculated as t / (t + dT)
120     *          // with t, the low-pass filter's time-constant
121     *          // and dT, the event delivery rate
122     *
123     *          final float alpha = 0.8;
124     *
125     *          gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
126     *          gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
127     *          gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
128     *
129     *          linear_acceleration[0] = event.values[0] - gravity[0];
130     *          linear_acceleration[1] = event.values[1] - gravity[1];
131     *          linear_acceleration[2] = event.values[2] - gravity[2];
132     *     }
133     * </pre>
134     *
135     * <p>
136     * <u>Examples</u>:
137     * <ul>
138     * <li>When the device lies flat on a table and is pushed on its left side
139     * toward the right, the x acceleration value is positive.</li>
140     *
141     * <li>When the device lies flat on a table, the acceleration value is
142     * +9.81, which correspond to the acceleration of the device (0 m/s^2) minus
143     * the force of gravity (-9.81 m/s^2).</li>
144     *
145     * <li>When the device lies flat on a table and is pushed toward the sky
146     * with an acceleration of A m/s^2, the acceleration value is equal to
147     * A+9.81 which correspond to the acceleration of the device (+A m/s^2)
148     * minus the force of gravity (-9.81 m/s^2).</li>
149     * </ul>
150     *
151     *
152     * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD
153     * Sensor.TYPE_MAGNETIC_FIELD}:</h4>
154     * All values are in micro-Tesla (uT) and measure the ambient magnetic field
155     * in the X, Y and Z axis.
156     *
157     * <h4>{@link android.hardware.Sensor#TYPE_GYROSCOPE Sensor.TYPE_GYROSCOPE}:</h4>
158     *  All values are in radians/second and measure the rate of rotation
159     *  around the X, Y and Z axis. The coordinate system is the same as is
160     *  used for the acceleration sensor.  Rotation is positive in the counter-clockwise
161     *  direction.  That is, an observer looking from some positive location on the x, y.
162     *  or z axis at a device positioned on the origin would report positive rotation
163     *  if the device appeared to be rotating counter clockwise.  Note that this is the
164     *  standard mathematical definition of positive rotation and does not agree with the
165     *  definition of roll given earlier.
166     *
167     * <ul>
168     * <p>
169     * values[0]: Angular speed around the x-axis
170     * </p>
171     * <p>
172     * values[1]: Angular speed around the y-axis
173     * </p>
174     * <p>
175     * values[2]: Angular speed around the z-axis
176     * </p>
177     * </ul>
178     * <p>
179     * Typically the output of the gyroscope is integrated over time to calculate
180     * an angle, for example:
181     * </p>
182     * <pre class="prettyprint">
183     *     private static final float NS2S = 1.0f / 1000000000.0f;
184     *     private float timestamp;
185     *     public void onSensorChanged(SensorEvent event)
186     *     {
187     *          if (timestamp != 0) {
188     *              final float dT = (event.timestamp - timestamp) * NS2S;
189     *              angle[0] += event.values[0] * dT;
190     *              angle[1] += event.values[1] * dT;
191     *              angle[2] += event.values[2] * dT;
192     *          }
193     *          timestamp = event.timestamp;
194     *     }
195     * </pre>
196     *
197     * <p>In practice, the gyroscope noise and offset will introduce some errors which need
198     * to be compensated for. This is usually done using the information from other
199     * sensors, but is beyond the scope of this document.</p>
200     *
201     * <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4>
202     * <ul>
203     * <p>
204     * values[0]: Ambient light level in SI lux units
205     * </ul>
206     *
207     * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4>
208     * <ul>
209     * <p>
210     * values[0]: Atmospheric pressure in hPa (millibar)
211     * </ul>
212     *
213     * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:
214     * </h4>
215     *
216     * <ul>
217     * <p>
218     * values[0]: Proximity sensor distance measured in centimeters
219     * </ul>
220     *
221     * <p>
222     * <b>Note:</b> Some proximity sensors only support a binary <i>near</i> or
223     * <i>far</i> measurement. In this case, the sensor should report its
224     * {@link android.hardware.Sensor#getMaximumRange() maximum range} value in
225     * the <i>far</i> state and a lesser value in the <i>near</i> state.
226     * </p>
227     *
228     *  <h4>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:</h4>
229     *  <p>A three dimensional vector indicating the direction and magnitude of gravity.  Units
230     *  are m/s^2. The coordinate system is the same as is used by the acceleration sensor.</p>
231     *  <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be identical
232     *  to that of the accelerometer.</p>
233     *
234     *  <h4>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:</h4>
235     *  A three dimensional vector indicating acceleration along each device axis, not including
236     *  gravity.  All values have units of m/s^2.  The coordinate system is the same as is used by the
237     *  acceleration sensor.
238     *  <p>The output of the accelerometer, gravity and  linear-acceleration sensors must obey the
239     *  following relation:</p>
240     *   <p><ul>acceleration = gravity + linear-acceleration</ul></p>
241     *
242     *  <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4>
243     *  <p>The rotation vector represents the orientation of the device as a combination of an <i>angle</i>
244     *  and an <i>axis</i>, in which the device has rotated through an angle &#952 around an axis
245     *  &lt;x, y, z>.</p>
246     *  <p>The three elements of the rotation vector are
247     *  &lt;x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>, such that the magnitude of the rotation
248     *  vector is equal to sin(&#952/2), and the direction of the rotation vector is equal to the
249     *  direction of the axis of rotation.</p>
250     *  </p>The three elements of the rotation vector are equal to
251     *  the last three components of a <b>unit</b> quaternion
252     *  &lt;cos(&#952/2), x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>.</p>
253     *  <p>Elements of the rotation vector are unitless.
254     *  The x,y, and z axis are defined in the same way as the acceleration
255     *  sensor.</p>
256     *  The reference coordinate system is defined as a direct orthonormal basis,
257     *  where:
258     * </p>
259     *
260     * <ul>
261     * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
262     * the ground at the device's current location and roughly points East).</li>
263     * <li>Y is tangential to the ground at the device's current location and
264     * points towards the magnetic North Pole.</li>
265     * <li>Z points towards the sky and is perpendicular to the ground.</li>
266     * </ul>
267     *
268     * <p>
269     * <center><img src="../../../images/axis_globe.png"
270     * alt="World coordinate-system diagram." border="0" /></center>
271     * </p>
272     *
273     * <ul>
274     * <p>
275     * values[0]: x*sin(&#952/2)
276     * </p>
277     * <p>
278     * values[1]: y*sin(&#952/2)
279     * </p>
280     * <p>
281     * values[2]: z*sin(&#952/2)
282     * </p>
283     * <p>
284     * values[3]: cos(&#952/2) <i>(optional: only if value.length = 4)</i>
285     * </p>
286     * </ul>
287     *
288     * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION
289     * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees.
290     *
291     * <ul>
292     * <p>
293     * values[0]: Azimuth, angle between the magnetic north direction and the
294     * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South,
295     * 270=West
296     * </p>
297     *
298     * <p>
299     * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
300     * values when the z-axis moves <b>toward</b> the y-axis.
301     * </p>
302     *
303     * <p>
304     * values[2]: Roll, rotation around y-axis (-90 to 90), with positive values
305     * when the x-axis moves <b>toward</b> the z-axis.
306     * </p>
307     * </ul>
308     *
309     * <p>
310     * <b>Note:</b> This definition is different from <b>yaw, pitch and roll</b>
311     * used in aviation where the X axis is along the long side of the plane
312     * (tail to nose).
313     * </p>
314     *
315     * <p>
316     * <b>Note:</b> This sensor type exists for legacy reasons, please use
317     * {@link android.hardware.SensorManager#getRotationMatrix
318     * getRotationMatrix()} in conjunction with
319     * {@link android.hardware.SensorManager#remapCoordinateSystem
320     * remapCoordinateSystem()} and
321     * {@link android.hardware.SensorManager#getOrientation getOrientation()} to
322     * compute these values instead.
323     * </p>
324     *
325     * <p>
326     * <b>Important note:</b> For historical reasons the roll angle is positive
327     * in the clockwise direction (mathematically speaking, it should be
328     * positive in the counter-clockwise direction).
329     * </p>
330     *
331     * <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY
332     * Sensor.TYPE_RELATIVE_HUMIDITY}:</h4>
333     * <ul>
334     * <p>
335     * values[0]: Relative ambient air humidity in percent
336     * </p>
337     * </ul>
338     * <p>
339     * When relative ambient air humidity and ambient temperature are
340     * measured, the dew point and absolute humidity can be calculated.
341     * </p>
342     * <u>Dew Point</u>
343     * <p>
344     * The dew point is the temperature to which a given parcel of air must be
345     * cooled, at constant barometric pressure, for water vapor to condense
346     * into water.
347     * </p>
348     * <center><pre>
349     *                    ln(RH/100%) + m&#183;t/(T<sub>n</sub>+t)
350     * t<sub>d</sub>(t,RH) = T<sub>n</sub> &#183; ------------------------------
351     *                 m - [ln(RH/100%) + m&#183;t/(T<sub>n</sub>+t)]
352     * </pre></center>
353     * <dl>
354     * <dt>t<sub>d</sub></dt> <dd>dew point temperature in &deg;C</dd>
355     * <dt>t</dt>             <dd>actual temperature in &deg;C</dd>
356     * <dt>RH</dt>            <dd>actual relative humidity in %</dd>
357     * <dt>m</dt>             <dd>17.62</dd>
358     * <dt>T<sub>n</sub></dt> <dd>243.12 &deg;C</dd>
359     * </dl>
360     * <p>for example:</p>
361     * <pre class="prettyprint">
362     * h = Math.log(rh / 100.0) + (17.62 * t) / (243.12 + t);
363     * td = 243.12 * h / (17.62 - h);
364     * </pre>
365     * <u>Absolute Humidity</u>
366     * <p>
367     * The absolute humidity is the mass of water vapor in a particular volume
368     * of dry air. The unit is g/m<sup>3</sup>.
369     * </p>
370     * <center><pre>
371     *                    RH/100%&#183;A&#183;exp(m&#183;t/(T<sub>n</sub>+t))
372     * d<sub>v</sub>(t,RH) = 216.7 &#183; -------------------------
373     *                           273.15 + t
374     * </pre></center>
375     * <dl>
376     * <dt>d<sub>v</sub></dt> <dd>absolute humidity in g/m<sup>3</sup></dd>
377     * <dt>t</dt>             <dd>actual temperature in &deg;C</dd>
378     * <dt>RH</dt>            <dd>actual relative humidity in %</dd>
379     * <dt>m</dt>             <dd>17.62</dd>
380     * <dt>T<sub>n</sub></dt> <dd>243.12 &deg;C</dd>
381     * <dt>A</dt>             <dd>6.112 hPa</dd>
382     * </dl>
383     * <p>for example:</p>
384     * <pre class="prettyprint">
385     * dv = 216.7 *
386     * (rh / 100.0 * 6.112 * Math.exp(17.62 * t / (243.12 + t)) / (273.15 + t));
387     * </pre>
388     *
389     * <h4>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE Sensor.TYPE_AMBIENT_TEMPERATURE}:
390     * </h4>
391     *
392     * <ul>
393     * <p>
394     * values[0]: ambient (room) temperature in degree Celsius.
395     * </ul>
396     *
397     * @see SensorEvent
398     * @see GeomagneticField
399     */
400
401    public final float[] values;
402
403    /**
404     * The sensor that generated this event. See
405     * {@link android.hardware.SensorManager SensorManager} for details.
406     */
407   public Sensor sensor;
408
409    /**
410     * The accuracy of this event. See {@link android.hardware.SensorManager
411     * SensorManager} for details.
412     */
413    public int accuracy;
414
415
416    /**
417     * The time in nanosecond at which the event happened
418     */
419    public long timestamp;
420
421
422    SensorEvent(int size) {
423        values = new float[size];
424    }
425}
426