使用CMDeviceMotion和CMAttitude隔离垂直或水平加速度

时间:2014-01-13 17:33:12

标签: ios

假设设备方向可能不断变化,我试图隔离垂直或水平加速度分量。

在拥有陀螺仪数据和CMAttitude之前,这是不可能的,因为我们只有加速度数据。既然我们通过CMAttitude同时加速了userAcceleration和方向,那么似乎应该可以通过姿态数据调整加速度数据,以便隔离特定的加速度绝对方向。这与使用参考帧略有不同,因为我期望设备方向不断变化。想念臂章等......就我而言,

无论设备方向如何变化,我都希望能够捕获严格垂直或严格水平的加速度值。这个的几何形状有点超出我的意见,我很欣赏一些建议。

2 个答案:

答案 0 :(得分:4)

我不熟悉iOS API,但我可以给出数学答案。

  1. 使用陀螺仪+加速计传感器融合确定方向。我希望iOS有一个API,因为它相对复杂(如果不是让我们知道,我会详细说明)。这似乎就是你所说的CMAttitude。方向应表示为四元数或矩阵,它表示固定参考框架(最可能是东北向下,但它取决于API)与附加到设备的本地参考框架之间的旋转。
  2. 从加速度计读取的矢量(在本地参考系中),并以与您的方向相反的旋转旋转它。旋转的反面是四元数共轭或矩阵转置。通过四元数乘法或矩阵乘法来旋转矢量。这为您提供了固定参考系中的加速度矢量。
  3. 固定参考系中加速度的Z分量是垂直加速度。 XY分量的范数(sqrt(x ^ 2 + y ^ 2))是水平加速度。不要忘记从垂直加速度中减去重力。这又假设了一个东北向下的参考系,但大多数其他固定参考系只需要你适当地交换X,Y,Z。
  4. 如果iOS具有正确的API,则实现应该是微不足道的。如果你有选择偏好四元数而不是矩阵,因为实现运行得更快。让我们知道它是怎么回事。

答案 1 :(得分:1)

我刚刚实施了 marcv81 回答。

-(void)isolateHorizontalMotionFromMotionData:(CMDeviceMotino *)newMotion
{
    //Quaternion Conjugation
    CMQuaternion quaternion = newMotion.attitude.quaternion;
    GLKQuaternion original_quaternion = GLKQuaternionMake(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
    GLKQuaternion conjugated_quaternion = GLKQuaternionConjugate(original_quaternion);

    //Rotation of Accelerometer vector with quanternion
    GLKVector3 acceleromationVector = GLKVector3Make(newMotion.userAcceleration.x, newMotion.userAcceleration.y, newMotion.userAcceleration.z);

    GLKVector3 accelerometionVector_toReferenceFrame = GLKQuaternionRotateVector3(conjugated_quaternion, acceleromationVector);

    //Horizontal Acceleration
    float horizontalAcceleration = sqrtf(powf(accelerometionVector_toReferenceFrame.x,2)+powf(accelerometionVector_toReferenceFrame.y,2));
}