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 = - ∑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 - ∑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 θ around an axis 245 * <x, y, z>.</p> 246 * <p>The three elements of the rotation vector are 247 * <x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)>, such that the magnitude of the rotation 248 * vector is equal to sin(θ/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 * <cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/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(θ/2) 276 * </p> 277 * <p> 278 * values[1]: y*sin(θ/2) 279 * </p> 280 * <p> 281 * values[2]: z*sin(θ/2) 282 * </p> 283 * <p> 284 * values[3]: cos(θ/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·t/(T<sub>n</sub>+t) 350 * t<sub>d</sub>(t,RH) = T<sub>n</sub> · ------------------------------ 351 * m - [ln(RH/100%) + m·t/(T<sub>n</sub>+t)] 352 * </pre></center> 353 * <dl> 354 * <dt>t<sub>d</sub></dt> <dd>dew point temperature in °C</dd> 355 * <dt>t</dt> <dd>actual temperature in °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 °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%·A·exp(m·t/(T<sub>n</sub>+t)) 372 * d<sub>v</sub>(t,RH) = 216.7 · ------------------------- 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 °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 °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