Home | History | Annotate | Download | only in hardware
      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 
     17 package 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 
     58 public 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.data[0];
    126      *          gravity[1] = alpha * gravity[1] + (1 - alpha) * event.data[1];
    127      *          gravity[2] = alpha * gravity[2] + (1 - alpha) * event.data[2];
    128      *
    129      *          linear_acceleration[0] = event.data[0] - gravity[0];
    130      *          linear_acceleration[1] = event.data[1] - gravity[1];
    131      *          linear_acceleration[2] = event.data[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.data[0] * dT;
    190      *              angle[1] += event.data[1] * dT;
    191      *              angle[2] += event.data[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_PROXIMITY Sensor.TYPE_PROXIMITY}:
    208      * </h4>
    209      *
    210      * <ul>
    211      * <p>
    212      * values[0]: Proximity sensor distance measured in centimeters
    213      * </ul>
    214      *
    215      * <p>
    216      * <b>Note:</b> Some proximity sensors only support a binary <i>near</i> or
    217      * <i>far</i> measurement. In this case, the sensor should report its
    218      * {@link android.hardware.Sensor#getMaximumRange() maximum range} value in
    219      * the <i>far</i> state and a lesser value in the <i>near</i> state.
    220      * </p>
    221      *
    222      *  <h4>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:</h4>
    223      *  <p>A three dimensional vector indicating the direction and magnitude of gravity.  Units
    224      *  are m/s^2. The coordinate system is the same as is used by the acceleration sensor.</p>
    225      *  <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be identical
    226      *  to that of the accelerometer.</p>
    227      *
    228      *  <h4>{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:</h4>
    229      *  A three dimensional vector indicating acceleration along each device axis, not including
    230      *  gravity.  All values have units of m/s^2.  The coordinate system is the same as is used by the
    231      *  acceleration sensor.
    232      *  <p>The output of the accelerometer, gravity and  linear-acceleration sensors must obey the
    233      *  following relation:</p>
    234      *   <p><ul>acceleration = gravity + linear-acceleration</ul></p>
    235      *
    236      *  <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4>
    237      *  <p>The rotation vector represents the orientation of the device as a combination of an <i>angle</i>
    238      *  and an <i>axis</i>, in which the device has rotated through an angle &#952 around an axis
    239      *  &lt;x, y, z>.</p>
    240      *  <p>The three elements of the rotation vector are
    241      *  &lt;x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>, such that the magnitude of the rotation
    242      *  vector is equal to sin(&#952/2), and the direction of the rotation vector is equal to the
    243      *  direction of the axis of rotation.</p>
    244      *  </p>The three elements of the rotation vector are equal to
    245      *  the last three components of a <b>unit</b> quaternion
    246      *  &lt;cos(&#952/2), x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>.</p>
    247      *  <p>Elements of the rotation vector are unitless.
    248      *  The x,y, and z axis are defined in the same way as the acceleration
    249      *  sensor.</p>
    250      * <ul>
    251      * <p>
    252      * values[0]: x*sin(&#952/2)
    253      * </p>
    254      * <p>
    255      * values[1]: y*sin(&#952/2)
    256      * </p>
    257      * <p>
    258      * values[2]: z*sin(&#952/2)
    259      * </p>
    260      * <p>
    261      * values[3]: cos(&#952/2) <i>(optional: only if value.length = 4)</i>
    262      * </p>
    263      * </ul>
    264      *
    265      * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION
    266      * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees.
    267      *
    268      * <ul>
    269      * <p>
    270      * values[0]: Azimuth, angle between the magnetic north direction and the
    271      * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South,
    272      * 270=West
    273      * </p>
    274      *
    275      * <p>
    276      * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
    277      * values when the z-axis moves <b>toward</b> the y-axis.
    278      * </p>
    279      *
    280      * <p>
    281      * values[2]: Roll, rotation around y-axis (-90 to 90), with positive values
    282      * when the x-axis moves <b>toward</b> the z-axis.
    283      * </p>
    284      * </ul>
    285      *
    286      * <p>
    287      * <b>Note:</b> This definition is different from <b>yaw, pitch and roll</b>
    288      * used in aviation where the X axis is along the long side of the plane
    289      * (tail to nose).
    290      * </p>
    291      *
    292      * <p>
    293      * <b>Note:</b> This sensor type exists for legacy reasons, please use
    294      * {@link android.hardware.SensorManager#getRotationMatrix
    295      * getRotationMatrix()} in conjunction with
    296      * {@link android.hardware.SensorManager#remapCoordinateSystem
    297      * remapCoordinateSystem()} and
    298      * {@link android.hardware.SensorManager#getOrientation getOrientation()} to
    299      * compute these values instead.
    300      * </p>
    301      *
    302      * <p>
    303      * <b>Important note:</b> For historical reasons the roll angle is positive
    304      * in the clockwise direction (mathematically speaking, it should be
    305      * positive in the counter-clockwise direction).
    306      * </p>
    307      *
    308      * @see SensorEvent
    309      * @see GeomagneticField
    310      */
    311 
    312     public final float[] values;
    313 
    314     /**
    315      * The sensor that generated this event. See
    316      * {@link android.hardware.SensorManager SensorManager} for details.
    317      */
    318    public Sensor sensor;
    319 
    320     /**
    321      * The accuracy of this event. See {@link android.hardware.SensorManager
    322      * SensorManager} for details.
    323      */
    324     public int accuracy;
    325 
    326 
    327     /**
    328      * The time in nanosecond at which the event happened
    329      */
    330     public long timestamp;
    331 
    332 
    333     SensorEvent(int size) {
    334         values = new float[size];
    335     }
    336 }
    337