Android下陀螺仪、加速度和磁场传感器数据定义

摘自Android SensorEvent.java代码注释


Sensor.TYPE_ACCELEROMETER(加速度传感器类型)

All values are in SI units (m/s^2)

values[0]: Acceleration minus Gx on the x-axis
values[1]: Acceleration minus Gy on the y-axis
values[2]: Acceleration minus Gz on the z-axis

A sensor of this type measures the acceleration applied to the device (Ad). Conceptually, it does so by measuring forces applied to the sensor itself (Fs) using the relation:
Ad = - ∑Fs / mass

In particular, the force of gravity is always influencing the measured acceleration:
Ad = -g - ∑F / mass

For this reason, when the device is sitting on a table (and obviously not accelerating), the accelerometer reads a magnitude of g = 9.81 m/s^2

Similarly, when the device is in free-fall and therefore dangerously accelerating towards to ground at 9.81 m/s^2, its accelerometer reads a magnitude of 0 m/s^2.

It should be apparent that in order to measure the real acceleration of the device, the contribution of the force of gravity must be eliminated. This can be achieved by applying a high-pass filter. Conversely, a low-pass filter can be used to isolate the force of gravity.

public void onSensorChanged(SensorEvent event)
{
     // alpha is calculated as t / (t + dT)
     // with t, the low-pass filter's time-constant
     // and dT, the event delivery rate

     final float alpha = 0.8;

     gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
     gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
     gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

     linear_acceleration[0] = event.values[0] - gravity[0];
     linear_acceleration[1] = event.values[1] - gravity[1];
     linear_acceleration[2] = event.values[2] - gravity[2];
}

Examples:

When the device lies flat on a table and is pushed on its left side toward the right, the x acceleration value is positive.

When the device lies flat on a table, the acceleration value is +9.81, which correspond to the acceleration of the device (0 m/s^2) minus the force of gravity (-9.81 m/s^2).

Sensor.TYPE_MAGNETIC_FIELD(磁场传感器类型)

All values are in micro-Tesla (uT) and measure the ambient magnetic field in the X, Y and Z axis.


Sensor.TYPE_GYROSCOPE(陀螺仪传感器)

All values are in radians/second and measure the rate of rotation around the device’s local X, Y and Z axis. The coordinate system is the same as is used for the acceleration sensor. Rotation is positive in the counter-clockwise direction. That is, an observer looking from some positive location on the x, y or z axis at a device positioned on the origin would report positive rotation if the device appeared to be rotating counter clockwise. Note that this is the standard mathematical definition of positive rotation and does not agree with the definition of roll given earlier.

values[0]: Angular speed around the x-axis
values[1]: Angular speed around the y-axis
values[2]: Angular speed around the z-axis

Typically the output of the gyroscope is integrated over time to calculate a rotation describing the change of angles over the timestep, for example:

private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;

public void onSensorChanged(SensorEvent event) {
     // This timestep's delta rotation to be multiplied by the current rotation
     // after computing it from the gyro sample data.
     if (timestamp != 0) {
         final float dT = (event.timestamp - timestamp) * NS2S;
         // Axis of the rotation sample, not normalized yet.
         float axisX = event.values[0];
         float axisY = event.values[1];
         float axisZ = event.values[2];

         // Calculate the angular speed of the sample
         float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);

         // Normalize the rotation vector if it's big enough to get the axis
         if (omegaMagnitude > EPSILON) {
             axisX /= omegaMagnitude;
             axisY /= omegaMagnitude;
             axisZ /= omegaMagnitude;
         }

         // Integrate around this axis with the angular speed by the timestep
         // in order to get a delta rotation from this sample over the timestep
         // We will convert this axis-angle representation of the delta rotation
         // into a quaternion before turning it into the rotation matrix.
         float thetaOverTwo = omegaMagnitude * dT / 2.0f;
         float sinThetaOverTwo = sin(thetaOverTwo);
         float cosThetaOverTwo = cos(thetaOverTwo);
         deltaRotationVector[0] = sinThetaOverTwo * axisX;
         deltaRotationVector[1] = sinThetaOverTwo * axisY;
         deltaRotationVector[2] = sinThetaOverTwo * axisZ;
         deltaRotationVector[3] = cosThetaOverTwo;
     }
     timestamp = event.timestamp;
     float[] deltaRotationMatrix = new float[9];
     SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
     // User code should concatenate the delta rotation we computed with the current rotation
     // in order to get the updated rotation.
     // rotationCurrent = rotationCurrent * deltaRotationMatrix;
}

In practice, the gyroscope noise and offset will introduce some errors which need to be compensated for. This is usually done using the information from other sensors, but is beyond the scope of this document.


文章目录
  1. 1. Sensor.TYPE_ACCELEROMETER(加速度传感器类型)
  2. 2. Sensor.TYPE_MAGNETIC_FIELD(磁场传感器类型)
  3. 3. Sensor.TYPE_GYROSCOPE(陀螺仪传感器)