5

私の現在のプロジェクトでは、Core Motion の CMAttitude によって提供される四元数に関する問題に遭遇しました。iPhone 5 (iOS 6.0.1) を明確な開始位置に置きました。次に、ペースの速いゲームのように、デバイスをすばやく動かし始めます。10 ~ 30 秒後に開始位置に戻ると、報告されたヨー角度は開始位置と 10 ~ 20 度異なります (ほとんどの場合、約 11°)。

効果を検証するために、古い (そして残念ながらもう利用できない) Core Motion Teapot サンプルを使用しました。ロギングのオイラー角は、CMAttitude から直接読み取られます。

開始位置 15秒後の同じ場所

        NSLog(@"pitch: %f, roll: %f, yaw: %f",  attitude.pitch * 180 / M_PI, attitude.roll * 180 / M_PI, attitude.yaw * 180 / M_PI);

これは、異なる工場で異なる時期に製造された 2 つの異なる iPhone 5 デバイスで見つかりました。しかし、本当に奇妙なのは、iOS 5.1.1 を実行している私の iPhone 4 が期待どおりに動作していることです。私には iOS のバグのように思えて、私はすでにバグ レポートを提出しましたが、その一方で、まだ誰もそれに遭遇していないとはほとんど想像できません。再設計された Core Motion API に関係していると思われます。バージョン 5 からは、磁力計 (コンパス) もセンサー フュージョンで考慮されます。コンソールは、場所からのバイアス推定が CoreMotion に提供されることを示しています。

locationd[41] <Notice>: GYTT inserted: bias,-0.196419,1.749323,-1.828088,variance,0.002644,0.004651,0.002527,temperature,31.554688

私の質問: Device Motion を使用しているときに磁力計の読み取りをブロックする可能性はありますか? 位置情報サービスを無効にしてみましたが、Core Motion には影響しません。不可能な場合、加速度計に基づく重力推定の代替/回避策は何ですか?

PS: クォータニオン ベースのモデルを扱っているため、これはジンバル ロックとは関係ありません。

編集: さらにいくつかの測定を行った後、ヨーだけが影響を受けていることが明らかです。ヨーが開始位置に関係なくドリフトしている間、ピッチとロールは許容範囲内 (<= 1°) の偏差を示します。CMDeviceMotion.gravityもきれいに見えます。

編集 (2): 最近の XCode バージョンに添付されている MotionGraphs サンプルで問題を再現できました。ヨーグラフは、原点から再現可能にドリフトしています。

4

2 に答える 2

4

決定的な解決策ではありませんが、少なくとも私自身の質問に対する回避策です (あなたを招待するために未回答のままにしておきます)。DeviceMotion.gravity少なくともバグの影響を受けていないことが判明しました。そこで、モーション検出のこの非常に単純な部分を再設計しarcsin (gravity.x/||gravity||)、デバイスを傾けたときにメイン プレイヤー キャラクターを横に移動するために使用することにしました。

これは、クォータニオンに含まれる完全な回転ステータスに関する情報を破壊するため、間違いなく 2 番目に優れたソリューションです。戦略的な考慮事項として、そのように決定しました。

  1. CMAttitude.quaternionほとんどの開発者は、ほとんどの人がクォータニオンの計算にそれほど興味を示さないというよりも、むしろ重力ベクトルを使用して傾斜モーション検出を行っていると思います;-) したがって、重力ベクトルに関連する将来のバグは、ベータ段階で修正される可能性があります。ユーザー。
  2. それがソフトウェアのバグであり、ハードウェアの問題に関連していない場合、私が推測することであり、バグができるだけ早く修正される場合、何らかの理由で更新されない可能性のあるデバイスがまだ多数あります. したがって、潜在的な将来の顧客がトラブルに遭遇するリスクは小さいですが、0 より大きくなります。
于 2012-11-29T20:57:23.207 に答える
1

自分のコードで同様のことを行ったところ、同じ z 軸の回転ドリフト (ヨー) が見つかりました。バランスフィルターをかけました。Motion Manager の各時間間隔で、現在のクォータニオン (z コンポーネント) を取得し、計算後にそれを oldZ として保存して、次の一連の計算で使用します。私のフィルターは、新しい z 値とその直前の z 値のバランスを取り、動きが速すぎるのを防ぎます。ハードウェアとプログラムの正確な許容範囲によっては、この方法でドリフトをうまく管理できます。ジャイロのドリフトがわずかに見られますが、フィルターが作用し続けると修正され始めます。私のフィルターは次のようになり、0.5 度以上の「迷い」を防ぎます。

filtZ = 0.65 * oldZ + 0.35 * z;

0.65 と 0.35 の値は実験的に決定されたものであり、時間があるときに試してみることをお勧めします。出力は引き続き 0 ~ 1 にスケーリングされ、これまでと同じ方法で利用できます (または、全体で 4 つの次元すべてを保持する必要がある場合は、クォータニオンに再度導入します)。

于 2013-01-30T18:37:13.987 に答える