如何用陀螺仪的旋转矩阵更新方位角?

时间:2013-09-02 03:13:20

标签: android android-sensors android-orientation gyroscope

假设我的当前方向为(azimuth, pitch, roll)。现在我希望用陀螺仪更新我的方向。根据{{​​3}}给出的代码,我可以获得如下所谓的deltaRotationMatrix

// Create a constant to convert nanoseconds to seconds.
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
    // (that is, EPSILON should represent your maximum allowable margin of error)
    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;
   }
}

我应该如何处理此代码段以更新我的方向?

1 个答案:

答案 0 :(得分:0)

您只需将deltaRotationMatrix乘以rotationCurrentMatrix,然后调用SensorManager.getOrientation()。您需要实现矩阵乘法。您还需要一个初始currentRotationMatrix,您可以使用加速度传感器和磁传感器与SensorManager.getRotationMatrix和SensorManager.getOrientation来获取初始currentRotationMatrix。或者,您可以使用TYPE_ROTATION_VECTOR获取初始currentRotationMatrix。

    currentRotationMatrix = matrixMultiplication(
                currentRotationMatrix,
                deltaRotationMatrix);

    SensorManager.getOrientation(currentRotationMatrix,
                gyroscopeOrientation;

不幸的是,您将会意识到,即使TYPE_GYROSCOPE传感器本应为漂移校准也不会做得很好,并且传感器会快速偏离设备旋转。令人沮丧。

我有一个GitHub仓库,所有这些已实施here Play商店中的一个有效项目here