29

次のように、自分がどちらを向いているかを示す位置矢印を含む地図アプリを作成しています。

青い矢印の地図

SensorManager.getOrientation()最初に返された値である azimuth を使用して、から方向を直接取得します。画面が水平線の上を指すように携帯電話を保持し、縦向きにすると、矢印は正常に機能します。でも:

  • 画面が水平線の下を向くように携帯電話を持っている場合、矢印はユーザーが向いている方向から 180 度離れた方向を指します。
  • 画面の向きが水平線と同じ高さになるように携帯電話を持っていると、矢印はどちらを向いているのかわかりません。Azimuth は意味のある結果をまったく返しません。
  • 電話を左または右に傾ける (またはランドスケープ モードで保持する) と、矢印は左または右に傾きます。

以下の慎重に構築された科学的な画像は、私が何を意味するかを示しています (青はユーザーが向いている方向、赤は矢印の方向、画面はほぼユーザーの顔を向いています。Google マップはまさに私が望んでいることを実行します):

何が起こるか対私が望むことのグラフ

(Google マップでは、自動回転がオフになっている場合、リストの最後の 2 つのアクションを正常に実行できないことに注意してください。しかし、私はまだその段階ではありません。一度に 1 つずつ。)

ここに示すように、単に Y 軸のポインティング方向を使用しているように見えます: http://developer.android.com/reference/android/hardware/SensorEvent.html、Z 軸のポインティング方向の逆を使用する場合、ほとんどの場合、電話が平らな場合は Y です。ただし、返される値を考えると、getOrientation()いくつかの問題を修正するために複雑なケースを作成する必要があり、電話に面した地平線のユース ケースは解決できません。もっと簡単な方法があると確信しています。

これが私のコードです(lastAccelerationとlastMagneticFieldの両方が内部センサーからのものです):

float[] rotationMatrix = new float[9];
if(SensorManager.getRotationMatrix(rotationMatrix, null, lastAcceleration, lastMagneticField)){
    float[] orientMatrix = new float[3];
    SensorManager.getOrientation(rotationMatrix, orientMatrix);

    orientation = orientMat[0]*180/(float)Math.PI;
}

私は何を間違っていますか?これを行う簡単な方法はありますか?

編集: 明確にするために、ユーザーがデバイスを目の前に持っていて、画面がユーザーの方を向いていると仮定しています。それを超えて、そのうちの1つだけが回転するかどうかは明らかにわかりません. また、ユーザーが動いているときのモーションを使用していますが、これは静止しているときのものです。

4

5 に答える 5

6

remapCoordinateSystem を呼び出しましたか? それ以外の場合は、電話を垂直に保持したときにのみ正しい向きの値が得られます。ケースの場合 画面の向きが水平線と同じ高さになるように電話を持っている場合、ユーザーの向きを取得する方法はありません。向きを取得するには、センサーの読み取り値の z 値をワールド座標の xy 平面に投影する必要があり、デバイスが水平に保持されている場合はゼロになるためです。

より正確には、電話を正面に向けたい場合は、電話を水平から少なくとも約 25 度傾ける必要があり、remapCoordinateSystem を呼び出す必要があります。次のコードは、上の最後の 2 つの画像に必要なものを提供します。
コード

float[] rotationMatrix = new float[9];  

if(SensorManager.getRotationMatrix(rotationMatrix, null, lastAcceleration, lastMagneticField)){
    float[] orientMatrix = new float[3];
    float remapMatrix = new float[9];
    SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapMatrix);
    SensorManager.getOrientation(remapMatrix, orientMatrix);

    orientation = orientMat[0]*180/(float)Math.PI;
}  

getOrientation は、電話が平らに置かれていると仮定して、正しい値を提供します。したがって、電話機が垂直に保持されている場合は、座標を再マッピングして平らな位置を取得する必要があります。幾何学的には、電話の -z 軸を世界の xy 平面に投影し、この投影ベクトルと世界の y 軸の間の角度を計算します。

于 2012-05-18T10:08:01.260 に答える
0

これはかなりトリッキーに見えます。私はAndroid用のPNSを開発していますが、まだ光が必要な、なんとなく似たような問題に直面しています。加速度計の軸と動きベクトルの間の回転を取得するにはどうすればよいですか?

ユーザーが動いていない場合、ユーザーが(デバイスではなく)どの方向を向いているかを見つけることは絶対に不可能に見えます。つまり、人間の体にはセンサーがないので、デバイスがまったく同じ位置にとどまっているが、ユーザーが90°回転した場合はどうなるでしょうか。これを見つける方法がわかりません。

私が提案できること(そしてそれは実際に私の問題に当てはまります)は、ユーザーの動きを使用してユーザーの見出しを決定できることです(コードで実際に何をしているのかわかりません)。説明させてください。最初の位置がAであるとします。ユーザーはBに移動します。次に、ABベクトルを作成し、ユーザーがBで停止したときに、ユーザーの見出しを取得できます。次に、コードをユーザーが向いている方向に制限する必要があります。目的地に到着。

私はこれがグーグルマップが得るものほど良くないことを知っています、しかしあなたはグーグルがこれのために何を使うか知っていますか?つまり、加速度センサーと磁場センサーのみを使用しているのでしょうか。

于 2012-04-20T07:46:07.793 に答える