web-dev-qa-db-ja.com

3D加速度計は方向を計算します

3つの軸の加速度計の値があります(通常、重力のみに-1.0と1.0の間のデータが含まれている場合):

  float Rx;
  float Ry;
  float Rz;

いくつか計算してから、各軸の角度を取得します。

  float R =  sqrt(pow(Rx,2)+pow(Ry,2)+pow(Rz,2));
  float Arx = acos(Rx/R)*180/M_PI;
  float Ary = acos(Ry/R)*180/M_PI;
  float Arz = acos(Rz/R)*180/M_PI;

次に、openglでボックスの角度の値を設定します

rquad = Arx;
yquad = Ary;

私の箱を回転させます:

glRotatef(yquad,1.0f,0.0f,0.0f);
glRotatef(rquad,0.0f,1.0f,0.0f);

半球で動作します。全球を使用したいのですが、Arz値を使用して機能させる必要があることはわかっていますが、この回転にそれをどのように使用できるかわかりません。私たちを手伝ってくれますか?

更新:最終的な答えは私の場合です:

  rquad = -atan2(Rx/R, Rz/R)*180/M_PI;
  yquad = -atan2(Ry/R, Rz/R)*180/M_PI;
30
Roland Soós

正解は次のとおりです。

Roll = atan2(Y, Z) * 180/M_PI;
Pitch = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;

出典: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf (10ページ、式25および26)

uespの答えは間違っています。ピッチとロールの両方が45度を超えるまで、許容できる近似のように見えます。

私は別の向きの規則を想定しているかもしれませんが、軸を交換して値を反転させても、uespの計算は決して同等にはなりません。

41
matteo

Matteoの答えは正しいですが、それは完全で完全な解決策を提供しません:公式は正しいです:

Roll = atan2(Y, Z) * 180/M_PI;
Pitch = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;

ただし、ピッチが+ 90/-90度で、X軸が垂直上向き/下向きの場合、理想的な加速度計の正規化出力は次のようになります。

accX = -1  / accX = 1 
accY = 0
accZ = 0

つまり、roll angle of 0 degrees;正しい。しかし実際には、加速度計の出力にはノイズが多く、次のような結果が得られます。

accX = -1  / accX = 1 
accY = 0.003
accZ = 0.004

これは小さいように見えるかもしれませんが、ロール角度が30度以下になり、正しくありません。

明らかな本能は最後の桁を除外することですが、これは精度に影響を与えるため、常に許容できるわけではありません。

リファレンスアプリケーションノートで非常によく説明されている妥協点は、ロールの式に加速度計のX軸の読み取り値の非常に小さな割合を含めることです。

Roll  = atan2( Y,   sign* sqrt(Z*Z+ miu*X*X));
sign  = 1 if accZ>0, -1 otherwise 
miu = 0.001

この方法で導入された誤差は、前のケースよりも劇的に小さくなります。上記で説明したのと同じ条件でロールを測定すると、2〜3度になります。

18
Pandrei

私は推奨される解決策(matteo's)を試してみましたが、最初はうまく機能しているように見えましたが、ピッチが90度に近づくと(約70度から始まりますが、異なる電話間で必ずしも一定ではない)、ロールが突然急上昇します。ピッチが90の場合、0付近であるはずのロールが100を超え、180に増え続けます。ロールを+ 90/-90に制限すると、これを数学的に防止する方法を考えています。正常に動作しますが、必要な範囲が得られません(+ 180/-180):Math.atan2(y、Math.sqrt((x x)+(z z)))*( 180/Math.PI))

3
FaithNoMan

次の計算を使用して、加速度計の読み取り値をロールとピッチの値に変換します。

Roll = atan2( sqrt(Y*Y + X*X), Z) * 180/M_PI;
Pitch = atan2( sqrt(X*X + Z*Z), Y) * 180/M_PI;

加速度計の定義に応じて、X/Y/Z値を交換するか、ロール/ピッチを変換する必要がある場合があります。それらをディスプレイで使用することは簡単です:

glRotatef (Pitch, 0.0f, 0.0f, 1.0f);
glRotatef (Roll,  1.0f, 0.0f, 0.0f);
0
uesp

rollの場合、arctan(y/sqrt(X*X)+(z*z))を使用して、ロール-90/90ピッチの問題を与えない航空規格です

0
Ian Bloomfield