13

iOS プロトタイプでは、CMDeviceMotion.deviceMotion.yaw と CLHeading.trueHeading の組み合わせを使用して、応答性が高く正確な安定したコンパス ヘディングを作成します。これは、iPhone が平らに保持されている場合にうまく機能し、安定したコンパスの方向を指すグラフィカルな矢印が表示されます。

この問題は、iPhone をポートレート モードで垂直に保持すると発生します。UIDeviceOrientation は、UIDeviceOrientationFaceDown から UIDeviceOrientationFaceUp に、またその逆に常に変化します。これにより、ピッチの小さな変化に基づいてヨー値が前後に +/-180 度スキップします。安定したヨー値を与える 1 つの方向にデバイスをロックしたり、グリッチなしで変化を予測したり、他の方法でジャイロ ヨー (またはこの方向でロール) を計算したりすることは可能ですか?

この哀れな男も同じ問題を抱えていますが、答えはありません。ダブルポイント可能者!:) https://stackoverflow.com/questions/10470938/euler-angle-yaw-not-working-when-iphone-orientation-changes

4

3 に答える 3

16

私はちょうどこの問題に対する答えを探していました。あなたが 1 年以上前にこれを投稿したことを知って少し胸が痛みましたが、あなたや他の誰かがこの解決策から利益を得ることができると思いました.

問題はジンバルロックです。ピッチが約 90 度になると、ヨーとロールが一致し、ジャイロの自由度が失われます。クォータニオンはジンバル ロックを回避する 1 つの方法ですが、正直なところ、それについて頭を悩ませているとは思いませんでした。代わりに、ヨーとロールが実際に一致し、単純に合計して問題を解決できることに気付きました (ヨーのみを気にする場合)。

解決:

    float yawDegrees = currentAttitude.yaw * (180.0 / M_PI);
    float pitchDegrees = currentAttitude.pitch  * (180.0 / M_PI);
    float rollDegrees = currentAttitude.roll * (180.0 / M_PI);

    double rotationDegrees;
    if(rollDegrees < 0 && yawDegrees < 0) // This is the condition where simply
                                          // summing yawDegrees with rollDegrees
                                          // wouldn't work.
                                          // Suppose yaw = -177 and pitch = -165. 
                                          // rotationDegrees would then be -342, 
                                          // making your rotation angle jump all
                                          // the way around the circle.
    {
        rotationDegrees = 360 - (-1 * (yawDegrees + rollDegrees));
    }
    else
    {
        rotationDegrees = yawDegrees + rollDegrees;
    }

    // Use rotationDegrees with range 0 - 360 to do whatever you want.

これが他の誰かに役立つことを願っています!

于 2013-07-29T18:27:46.127 に答える
2

誰かが iOS Swift での実装に興味がある場合は、コードを以下に示します。

    let queue = NSOperationQueue()
    motionManager.startDeviceMotionUpdatesToQueue(queue) {
        [weak self] (data: CMDeviceMotion!, error: NSError!) in
    var yawDegrees: Double = self!.motionManager.deviceMotion.attitude.yaw * (180.0 / M_PI)
        var pitchDegrees: Double = self!.motionManager.deviceMotion.attitude.pitch * (180.0 / M_PI)
        var rollDegrees: Double = self!.motionManager.deviceMotion.attitude.roll * (180.0 / M_PI)


        if(rollDegrees < 0 && yawDegrees < 0){
            self!.rotationDegrees = 360 - (-1 * (yawDegrees + rollDegrees))
        }
        else {
            self!.rotationDegrees = yawDegrees + rollDegrees
        }
   }

しかし、私はいくつかの問題を抱えています.@ blkhp19がこれを手伝ってくれることを願っています.

于 2015-05-22T08:39:26.357 に答える