1 page.title=Motion Sensors 2 page.tags="sensorevent","accelerometer","gyroscope","gravity","rotation" 3 @jd:body 4 5 <div id="qv-wrapper"> 6 <div id="qv"> 7 <h2>In this document</h2> 8 <ol> 9 <li><a href="#sensors-motion-accel">Using the Accelerometer</a></li> 10 <li><a href="#sensors-motion-grav">Using the Gravity Sensor</a></li> 11 <li><a href="#sensors-motion-gyro">Using the Gyroscope</a></li> 12 <li><a href="#sensors-motion-linear">Using the Linear Accelerometer</a></li> 13 <li><a href="#sensors-motion-rotate">Using the Rotation Vector Sensor</a></li> 14 </ol> 15 <h2>Key classes and interfaces</h2> 16 <ol> 17 <li>{@link android.hardware.Sensor}</li> 18 <li>{@link android.hardware.SensorEvent}</li> 19 <li>{@link android.hardware.SensorManager}</li> 20 <li>{@link android.hardware.SensorEventListener}</li> 21 </ol> 22 <h2>Related samples</h2> 23 <ol> 24 <li><a href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer 25 Play</a></li> 26 <li><a 27 href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html"> 28 API Demos (OS - RotationVectorDemo)</a></li> 29 <li><a 30 href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html" 31 >API Demos (OS - Sensors)</a></li> 32 </ol> 33 <h2>See also</h2> 34 <ol> 35 <li><a href="{@docRoot}guide/topics/sensors/index.html">Sensors</a></li> 36 <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li> 37 <li><a href="{@docRoot}guide/topics/sensors/sensors_position.html">Position Sensors</a></li> 38 <li><a href="{@docRoot}guide/topics/sensors/sensors_environment.html">Environment 39 Sensors</a></li> 40 </ol> 41 </div> 42 </div> 43 44 <p>The Android platform provides several sensors that let you monitor the motion of a device. Two of 45 these sensors are always hardware-based (the accelerometer and gyroscope), and three of these 46 sensors can be either hardware-based or software-based (the gravity, linear acceleration, and 47 rotation vector sensors). For example, on some devices the software-based sensors derive their data 48 from the accelerometer and magnetometer, but on other devices they may also use the gyroscope to 49 derive their data. Most Android-powered devices have an accelerometer, and many now 50 include a gyroscope. The availability of the softare-based sensors is more variable because they 51 often rely on one or more hardware sensors to derive their data.</p> 52 53 <p>Motion sensors are useful for monitoring device movement, such as tilt, shake, rotation, or 54 swing. The movement is usually a reflection of direct user input (for example, a user steering a 55 car in a game or a user controlling a ball in a game), but it can also be a reflection of the 56 physical environment in which the device is sitting (for example, moving with you while you drive 57 your car). In the first case, you are monitoring motion relative to the device's frame of reference 58 or your application's frame of reference; in the second case you are monitoring motion relative to 59 the world's frame of reference. Motion sensors by themselves are not typically used to monitor 60 device position, but they can be used with other sensors, such as the geomagnetic field sensor, to 61 determine a device's position relative to the world's frame of reference (see <a 62 href="{@docRoot}guide/topics/sensors/sensors_position.html">Position Sensors</a> for more 63 information).</p> 64 65 <p>All of the motion sensors return multi-dimensional arrays of sensor values for each {@link 66 android.hardware.SensorEvent}. For example, during a single sensor event the accelerometer returns 67 acceleration force data for the three coordinate axes, and the gyroscope returns rate of rotation 68 data for the three coordinate axes. These data values are returned in a <code>float</code> array 69 ({@link android.hardware.SensorEvent#values}) along with other {@link android.hardware.SensorEvent} 70 parameters. Table 1 summarizes the motion sensors that are available on the Android platform.</p> 71 72 <p class="table-caption" id="table1"> 73 <strong>Table 1.</strong> Motion sensors that are supported on the Android platform.</p> 74 <table> 75 <tr> 76 <th scope="col" style="white-space:nowrap">Sensor</th> 77 <th scope="col" style="white-space:nowrap">Sensor event data</th> 78 <th scope="col" style="white-space:nowrap">Description</th> 79 <th scope="col" style="white-space:nowrap">Units of measure</th> 80 </tr> 81 <tr> 82 <td rowspan="3">{@link android.hardware.Sensor#TYPE_ACCELEROMETER}</td> 83 <td><code>SensorEvent.values[0]</code></td> 84 <td>Acceleration force along the x axis (including gravity).</td> 85 <td rowspan="3">m/s<sup>2</sup></td> 86 </tr> 87 <tr> 88 <td><code>SensorEvent.values[1]</code></td> 89 <td>Acceleration force along the y axis (including gravity).</td> 90 </tr> 91 <tr> 92 <td><code>SensorEvent.values[2]</code></td> 93 <td>Acceleration force along the z axis (including gravity).</td> 94 </tr> 95 <tr> 96 <td rowspan="3">{@link android.hardware.Sensor#TYPE_GRAVITY}</td> 97 <td><code>SensorEvent.values[0]</code></td> 98 <td>Force of gravity along the x axis.</td> 99 <td rowspan="3">m/s<sup>2</sup></td> 100 </tr> 101 <tr> 102 <td><code>SensorEvent.values[1]</code></td> 103 <td>Force of gravity along the y axis.</td> 104 </tr> 105 <tr> 106 <td><code>SensorEvent.values[2]</code></td> 107 <td>Force of gravity along the z axis.</td> 108 </tr> 109 <tr> 110 <td rowspan="3">{@link android.hardware.Sensor#TYPE_GYROSCOPE}</td> 111 <td><code>SensorEvent.values[0]</code></td> 112 <td>Rate of rotation around the x axis.</td> 113 <td rowspan="3">rad/s</td> 114 </tr> 115 <tr> 116 <td><code>SensorEvent.values[1]</code></td> 117 <td>Rate of rotation around the y axis.</td> 118 </tr> 119 <tr> 120 <td><code>SensorEvent.values[2]</code></td> 121 <td>Rate of rotation around the z axis.</td> 122 </tr> 123 <tr> 124 <td rowspan="3">{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td> 125 <td><code>SensorEvent.values[0]</code></td> 126 <td>Acceleration force along the x axis (excluding gravity).</td> 127 <td rowspan="3">m/s<sup>2</sup></td> 128 </tr> 129 <tr> 130 <td><code>SensorEvent.values[1]</code></td> 131 <td>Acceleration force along the y axis (excluding gravity).</td> 132 </tr> 133 <tr> 134 <td><code>SensorEvent.values[2]</code></td> 135 <td>Acceleration force along the z axis (excluding gravity).</td> 136 </tr> 137 <tr> 138 <td rowspan="4">{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}</td> 139 <td><code>SensorEvent.values[0]</code></td> 140 <td>Rotation vector component along the x axis (x * sin(/2)).</td> 141 <td rowspan="4">Unitless</td> 142 </tr> 143 <tr> 144 <td><code>SensorEvent.values[1]</code></td> 145 <td>Rotation vector component along the y axis (y * sin(/2)).</td> 146 </tr> 147 <tr> 148 <td><code>SensorEvent.values[2]</code></td> 149 <td>Rotation vector component along the z axis (z * sin(/2)).</td> 150 </tr> 151 <tr> 152 <td><code>SensorEvent.values[3]</code></td> 153 <td>Scalar component of the rotation vector ((cos(/2)).<sup>1</sup></td> 154 </tr> 155 </table> 156 157 <p class="note"><strong><sup>1</sup></strong> The scalar component is an optional value.</p> 158 159 <p>The rotation vector sensor and the gravity sensor are the most frequently used sensors for motion 160 detection and monitoring. The rotational vector sensor is particularly versatile and can be used for 161 a wide range of motion-related tasks, such as detecting gestures, monitoring angular change, and 162 monitoring relative orientation changes. For example, the rotational vector sensor is ideal if you 163 are developing a game, an augmented reality application, a 2-dimensional or 3-dimensional compass, 164 or a camera stabilization app. In most cases, using these sensors is a better choice than using 165 the accelerometer and geomagnetic field sensor or the orientation sensor.</p> 166 167 <h3>Android Open Source Project Sensors</h3> 168 169 <p>The Android Open Source Project (AOSP) provides three software-based motion sensors: a gravity 170 sensor, a linear acceleration sensor, and a rotation vector sensor. These sensors were updated in 171 Android 4.0 and now use a device's gyroscope (in addition to other sensors) to improve stability and 172 performance. If you want to try these sensors, you can identify them by using the {@link 173 android.hardware.Sensor#getVendor} method and the {@link android.hardware.Sensor#getVersion} method 174 (the vendor is Google Inc.; the version number is 3). Identifying these sensors by vendor and 175 version number is necessary because the Android system considers these three sensors to be secondary 176 sensors. For example, if a device manufacturer provides their own gravity sensor, then the AOSP 177 gravity sensor shows up as a secondary gravity sensor. All three of these sensors rely on a 178 gyroscope: if a device does not have a gyroscope, these sensors do not show up and are not 179 available for use.</p> 180 181 <h2 id="sensors-motion-accel">Using the Accelerometer</h2> 182 183 <p>An acceleration sensor measures the acceleration applied to the device, including the force of 184 gravity. The following code shows you how to get an instance of the default acceleration sensor:</p> 185 186 <pre> 187 private SensorManager mSensorManager; 188 private Sensor mSensor; 189 ... 190 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 191 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 192 </pre> 193 194 <p>Conceptually, an acceleration sensor determines the acceleration that is applied 195 to a device (A<sub>d</sub>) by measuring the forces that are applied to the sensor 196 itself (F<sub>s</sub>) using the following relationship:</p> 197 198 <pre class="no-pretty-print classic"> 199 A<sub>d</sub> = - F<sub>s</sub> / mass 200 </pre> 201 202 <p>However, the force of gravity is always influencing the measured acceleration according to 203 the following relationship:</p> 204 205 <pre class="no-pretty-print classic"> 206 A<sub>d</sub> = -g - F / mass 207 </pre> 208 209 <p>For this reason, when the device is sitting on a table (and not accelerating), the 210 accelerometer reads a magnitude of g = 9.81 m/s<sup>2</sup>. Similarly, when the device is in 211 free fall and therefore rapidly accelerating toward the ground at 9.81 m/s<sup>2</sup>, its 212 accelerometer reads a magnitude of g = 0 m/s<sup>2</sup>. Therefore, to measure 213 the real acceleration of the device, the contribution of the force of gravity must be removed from 214 the accelerometer data. This can be achieved by applying a high-pass filter. Conversely, a low-pass 215 filter can be used to isolate the force of gravity. The following example shows how you can do 216 this:</p> 217 218 <pre> 219 public void onSensorChanged(SensorEvent event){ 220 // In this example, alpha is calculated as t / (t + dT), 221 // where t is the low-pass filter's time-constant and 222 // dT is the event delivery rate. 223 224 final float alpha = 0.8; 225 226 // Isolate the force of gravity with the low-pass filter. 227 gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]; 228 gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]; 229 gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]; 230 231 // Remove the gravity contribution with the high-pass filter. 232 linear_acceleration[0] = event.values[0] - gravity[0]; 233 linear_acceleration[1] = event.values[1] - gravity[1]; 234 linear_acceleration[2] = event.values[2] - gravity[2]; 235 } 236 </pre> 237 238 <p class="note"><strong>Note:</strong> You can use many different techniques to filter sensor data. 239 The code sample above uses a simple filter constant (alpha) to create a low-pass filter. This filter 240 constant is derived from a time constant (t), which is a rough representation of the latency that 241 the filter adds to the sensor events, and the sensor's event delivery rate (dt). The code sample 242 uses an alpha value of 0.8 for demonstration purposes. If you use this filtering method you may need 243 to choose a different alpha value.</p> 244 245 <p>Accelerometers use the standard sensor <a 246 href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">coordinate 247 system</a>. In practice, this means that the following conditions apply when a device is laying 248 flat on a table in its natural orientation:</p> 249 250 <ul> 251 <li>If you push the device on the left side (so it moves to the right), the x acceleration value 252 is positive.</li> 253 <li>If you push the device on the bottom (so it moves away from you), the y acceleration value is 254 positive.</li> 255 <li>If you push the device toward the sky with an acceleration of A m/s<sup>2</sup>, the 256 z acceleration value is equal to A + 9.81, which corresponds to the acceleration of the device (+A 257 m/s<sup>2</sup>) minus the force of gravity (-9.81 m/s<sup>2</sup>).</li> 258 <li>The stationary device will have an acceleration value of +9.81, which corresponds to the 259 acceleration of the device (0 m/s<sup>2</sup> minus the force of gravity, which is -9.81 260 m/s<sup>2</sup>).</li> 261 </ul> 262 263 <p>In general, the accelerometer is a good sensor to use if you are monitoring device motion. 264 Almost every Android-powered handset and tablet has an accelerometer, and it uses about 10 times 265 less power than the other motion sensors. One drawback is that you might have to implement 266 low-pass and high-pass filters to eliminate gravitational forces and reduce noise.</p> 267 268 <p>The Android SDK provides a sample application that shows how to use the acceleration sensor (<a 269 href="{@docRoot}resources/samples/AccelerometerPlay/index.html">Accelerometer Play</a>).</p> 270 271 <h2 id="sensors-motion-grav">Using the Gravity Sensor</h2> 272 273 <p>The gravity sensor provides a three dimensional vector indicating the direction and magnitude of 274 gravity. The following code shows you how to get an instance of the default gravity sensor:</p> 275 276 <pre> 277 private SensorManager mSensorManager; 278 private Sensor mSensor; 279 ... 280 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 281 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); 282 </pre> 283 284 <p>The units are the same as those used by the acceleration 285 sensor (m/s<sup>2</sup>), and the coordinate system is the same as the one used by the 286 acceleration sensor.</p> 287 288 <p class="note"><strong>Note:</strong> When a device is at rest, the output of the gravity sensor 289 should be identical to that of the accelerometer.</p> 290 291 <h2 id="sensors-motion-gyro">Using the Gyroscope</h2> 292 <p>The gyroscope measures the rate or rotation in rad/s around a device's x, y, 293 and z axis. The following code shows you how to get an instance of the default gyroscope:</p> 294 295 <pre> 296 private SensorManager mSensorManager; 297 private Sensor mSensor; 298 ... 299 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 300 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); 301 </pre> 302 303 <p>The sensor's <a 304 href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">coordinate system</a> 305 is the same as the one used for the acceleration sensor. Rotation is positive in the 306 counter-clockwise direction; that is, an observer looking 307 from some positive location on the x, y or z axis at a device positioned on the origin would report 308 positive rotation if the device appeared to be rotating counter clockwise. This is the 309 standard mathematical definition of positive rotation and is not the same as the definition for 310 roll that is used by the orientation sensor.</p> 311 312 <p>Usually, the output of the gyroscope is integrated over time to calculate a rotation describing 313 the change of angles over the timestep. For example:</p> 314 315 <pre> 316 // Create a constant to convert nanoseconds to seconds. 317 private static final float NS2S = 1.0f / 1000000000.0f; 318 private final float[] deltaRotationVector = new float[4](); 319 private float timestamp; 320 321 public void onSensorChanged(SensorEvent event) { 322 // This timestep's delta rotation to be multiplied by the current rotation 323 // after computing it from the gyro sample data. 324 if (timestamp != 0) { 325 final float dT = (event.timestamp - timestamp) * NS2S; 326 // Axis of the rotation sample, not normalized yet. 327 float axisX = event.values[0]; 328 float axisY = event.values[1]; 329 float axisZ = event.values[2]; 330 331 // Calculate the angular speed of the sample 332 float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ); 333 334 // Normalize the rotation vector if it's big enough to get the axis 335 // (that is, EPSILON should represent your maximum allowable margin of error) 336 if (omegaMagnitude > EPSILON) { 337 axisX /= omegaMagnitude; 338 axisY /= omegaMagnitude; 339 axisZ /= omegaMagnitude; 340 } 341 342 // Integrate around this axis with the angular speed by the timestep 343 // in order to get a delta rotation from this sample over the timestep 344 // We will convert this axis-angle representation of the delta rotation 345 // into a quaternion before turning it into the rotation matrix. 346 float thetaOverTwo = omegaMagnitude * dT / 2.0f; 347 float sinThetaOverTwo = sin(thetaOverTwo); 348 float cosThetaOverTwo = cos(thetaOverTwo); 349 deltaRotationVector[0] = sinThetaOverTwo * axisX; 350 deltaRotationVector[1] = sinThetaOverTwo * axisY; 351 deltaRotationVector[2] = sinThetaOverTwo * axisZ; 352 deltaRotationVector[3] = cosThetaOverTwo; 353 } 354 timestamp = event.timestamp; 355 float[] deltaRotationMatrix = new float[9]; 356 SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector); 357 // User code should concatenate the delta rotation we computed with the current rotation 358 // in order to get the updated rotation. 359 // rotationCurrent = rotationCurrent * deltaRotationMatrix; 360 } 361 } 362 </pre> 363 364 <p>Standard gyroscopes provide raw rotational data without any filtering or correction for noise and 365 drift (bias). In practice, gyroscope noise and drift will introduce errors that need to be 366 compensated for. You usually determine the drift (bias) and noise by monitoring other sensors, such 367 as the gravity sensor or accelerometer.</p> 368 369 <h2 id="sensors-motion-linear">Using the Linear Accelerometer</h2> 370 371 <p>The linear acceleration sensor provides you with a three-dimensional vector representing 372 acceleration along each device axis, excluding gravity. The following code shows you how to get an 373 instance of the default linear acceleration sensor:</p> 374 375 <pre> 376 private SensorManager mSensorManager; 377 private Sensor mSensor; 378 ... 379 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 380 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); 381 </pre> 382 383 <p>Conceptually, this sensor provides you with acceleration data according to the following 384 relationship:</p> 385 386 <pre class="no-pretty-print classic"> 387 linear acceleration = acceleration - acceleration due to gravity 388 </pre> 389 390 <p>You typically use this sensor when you want to obtain acceleration data without the influence of 391 gravity. For example, you could use this sensor to see how fast your car is going. The linear 392 acceleration sensor always has an offset, which you need to remove. The simplest way to do this is 393 to build a calibration step into your application. During calibration you can ask the user to set 394 the device on a table, and then read the offsets for all three axes. You can then subtract that 395 offset from the acceleration sensor's direct readings to get the actual linear 396 acceleration.</p> 397 398 <p>The sensor <a 399 href="{@docRoot}guide/topics/sensors/sensors_overview.html#sensors-coords">coordinate 400 system</a> is the same as the one used by the acceleration sensor, as are the units of measure 401 (m/s<sup>2</sup>). 402 403 <h2 id="sensors-motion-rotate">Using the Rotation Vector Sensor</h2> 404 405 <p>The rotation vector represents the orientation of the device as a combination of an angle and an 406 axis, in which the device has rotated through an angle around an axis (x, y, or z). The following 407 code shows you how to get an instance of the default rotation vector sensor:</p> 408 409 <pre> 410 private SensorManager mSensorManager; 411 private Sensor mSensor; 412 ... 413 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 414 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); 415 </pre> 416 417 <p>The three elements of the rotation vector are expressed as follows:</p> 418 419 <pre class="no-pretty-print classic"> 420 x*sin(/2) 421 y*sin(/2) 422 z*sin(/2) 423 </pre> 424 425 <p>Where the magnitude of the rotation vector is equal to sin(/2), and the direction of the 426 rotation vector is equal to the direction of the axis of rotation.</p> 427 428 <div class="figure" style="width:246px"> 429 <img src="{@docRoot}images/axis_globe.png" alt="" height="235" /> 430 <p class="img-caption"> 431 <strong>Figure 1.</strong> Coordinate system used by the rotation vector sensor. 432 </p> 433 </div> 434 435 <p>The three elements of the rotation vector are equal to the last three components of a unit 436 quaternion (cos(/2), x*sin(/2), y*sin(/2), z*sin(/2)). Elements of the rotation vector are 437 unitless. The x, y, and z axes are defined in the same way as the acceleration sensor. The reference 438 coordinate system is defined as a direct orthonormal basis (see figure 1). This coordinate system 439 has the following characteristics:</p> 440 441 <ul> 442 <li>X is defined as the vector product Y x Z. It is tangential to the 443 ground at the device's current location and points approximately East.</li> 444 <li>Y is tangential to the ground at the device's current location and points toward the 445 geomagnetic 446 North Pole.</li> 447 <li>Z points toward the sky and is perpendicular to the ground plane.</li> 448 </ul> 449 450 <p>The Android SDK provides a sample application that shows how to use the rotation vector sensor. 451 The sample application is located in the API Demos code (<a 452 href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html"> 453 OS - RotationVectorDemo</a>).</p>