2013-05-13 58 views
11

Iは、ポインティングデバイスながらユーザとして角度を記録するアプリケーションがオブジェクトの中心に(好ましくは)、オブジェクトの周りに歩いている持っています。 ユーザーのコマンドで角度がリセットされるため、基準姿勢がリセットされます。オイラーの角度使用姿勢変化 - 角度と軸の問題 - クォータニオン数学

はジンバルロックを生成しますので、私は現在、このように四元数を使って角度を計算しています:

double angleFromLastPosition = acos(fromLastPositionAttitude.quaternion.w) * 2.0f; 

これは良い精度を放つと、デバイスのピッチとヨーが変わらない場合、それは完璧に動作します。言い換えれば、角度が360度を示すように、私は円の始まりと同じ場所で終わる。

問題1:デバイスのヨーとピッチの変化がわずかに(ユーザがオブジェクトの中心に直接指していない)場合、そうangleFromLastPositionを行います。 私のアングル式は3D空間内の2つのデバイス姿勢の間の角度を示しているだけなので、この部分を理解しています。

シナリオ:

  • 私は、たとえば、でデバイスの45度変更ピッチを停止回転姿勢の開始をマークし、中央に
  • を指しながら、オブジェクトの周りに円形に移動を開始それを上または下に向けることによって。それに応じて角度も変化する。
  • 私が見たいと思うのは、ピッチやヨーが変わっても、角度は45度のままです。

質問1は、クォータニオンを使用してデバイスのロールだけを計算し、他の2つの軸の変更を無視するにはどうすればよいですか?

問題2:私がちょっと回転して、デバイスを完全に凍らせても(まったく揺れることがないように)、angleFromLastPositionは約10-20秒ごとに1度の割合でドリフトします。線形であること。言い換えれば、最初は速くドリフトし、その後はかなり減速します。時には私はまったくドリフトがありません - デバイスが静止している場合、角度は堅実です。そして、これは私が何が起こっているのか理解していなくなった。

質問2、ここでは何が起こっているのですか。どのようにドリフトを処理できますか?

私はかなりの数の記事やチュートリアルを経て、および四元の数学は、現時点では私を超えている、誰かが先、リンク、または数行のコードを支援することができます願っています。

+0

は[漂流ヨー]と関連している可能性があります(http://stackoverflow.com/questions/13613239/drifting-yaw-angle-after-moving-fast?rq=1)?はいの場合、質問1の式を見つけることで両方の問題が処理されます:) –

+0

CMAttitudeを使用している場合は、fromLastPositionAttitude.rollを使用してデバイスのロールを得ることができない特別な理由はありますか?私はこれがクォータニオンプロパティを使用していないことを感謝しますが、そこに使用される! –

+0

はい、それから始まります - オイラーアングルを使用すると、ジンバルロックが生じ、自由度が失われます。デバイスがZ軸と位置合わせされていない場合、360度回転しません。少なくともこれは効果の私の理解です。 –

答えて

4

私はこれをテストしている、あなたが質問1、アンドレイに探しているものに応じて動作するようです。

最初にホームガングルを0に設定し、最初のパスの直後にwalkaroundAngleFromAttitude:fromHomeAngle:homeangleで返された角度を将来の使用のために保存します。

私のテストは、基準フレームを使用してデバイスの更新を開始含まれる:これはFinding normal vector to iOS device

からいくつかの改変および拡張コードを使用している

- (CMQuaternion) multiplyQuanternion:(CMQuaternion)left withRight:(CMQuaternion)right { 

    CMQuaternion newQ; 
    newQ.w = left.w*right.w - left.x*right.x - left.y*right.y - left.z*right.z; 
    newQ.x = left.w*right.x + left.x*right.w + left.y*right.z - left.z*right.y; 
    newQ.y = left.w*right.y + left.y*right.w + left.z*right.x - left.x*right.z; 
    newQ.z = left.w*right.z + left.z*right.w + left.x*right.y - left.y*right.x; 

    return newQ; 
} 

-(float)walkaroundRawAngleFromAttitude:(CMAttitude*)attitude { 

    CMQuaternion e = (CMQuaternion){0,0,1,1}; 
    CMQuaternion quatConj = attitude.quaternion; 
    quatConj.x *= -1; quatConj.y *= -1; quatConj.z *= -1; 
    CMQuaternion quat1 = attitude.quaternion; 
    CMQuaternion quat2 = [self multiplyQuanternion:quat1 withRight:e]; 
    CMQuaternion quat3 = [self multiplyQuanternion:quat2 withRight:quatConj]; 

    return atan2f(quat3.y, quat3.x); 
} 
-(float)walkaroundAngleFromAttitude:(CMAttitude*)attitude fromHomeAngle:(float)homeangle { 

    float rawangle = [self walkaroundRawAngleFromAttitude:attitude]; 
    if (rawangle <0) rawangle += M_PI *2; 
    if (homeangle < 0) homeangle += M_PI *2; 
    float finalangle = rawangle - homeangle; 
    if (finalangle < 0) finalangle += M_PI *2; 

    return finalangle; 
} 

[_motionManager 
startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical 
toQueue:operationQueue 
withHandler:handler]; 

をハンドラ内で呼び出され、次の方法を使用して

質問2に対処する編集&問題2:

これは解決できない場合があります。私は他のアプリ(360パノラマなど)でそれを見て、ジャイロなどで誤った読みを読んだことがあります。あなたがそれを補償しようとした場合、当然のことながら、いくつかの本物の回転運動が補償コードによって投げられたときに、あなたはびっくりするでしょう。ここ数年間私が解釈してきた限り、これはハードウェアベースの問題です。

+0

あなたの助けてくれてありがとう、いくつかの微調整で、私はあなたのコードが働いて、それは私のproblem_1を解決します。テストや微調整にもっと時間が必要ですが、私はそれを完成させるために必要なものがすべてあると確信しています。ドリフトは今や違った振る舞いをしており、数度ドリフトして停止します。角度はわずか10度のばらつきで堅実です。これは、このアプリのために完全に受け入れられます。私はそれと一緒に遊んで、私がそれが依存するものを把握するならば投稿します、それまでは、それはハードウェアの責任ボックスにあり、それは十分です:)歓声 –

+0

@AndreiG。良いこと、私はあなたに手を差し伸べることができてうれしい。また、これは私にquaternionの数学に戻るために必要な運動を与えました:)乾杯 –

+0

@TomPaceこんにちは、私はまた、これに類似した何かへの解決策を見つけようとしています、あなたはここで私の質問を見てください:リンク](http://stackoverflow.com/questions/19239482/using-quaternion-instead-of-roll-pitch-and-yaw-to-track-device-motion)。私は角度部分の変化を発見したと思うしかし、私は正しい軌道に乗っているのか分からない。私はまだ別の軸で電話の動きを追跡する方法を理解する必要があります。私の現在の進歩は[ここ](http://pastebin.com/faPWUVE2)です。前もって感謝します。 – iSeeker

関連する問題