2017-06-12 3 views
5

人がこのコンパスを使用していて、90度から時計回りまたは反時計回りに回転を開始したとします。彼らが完了した完全な360度回転の回数をカウントする最良の方法は何ですか?時計回りにのみ回転するか、反時計回りに回転すると仮定します。コンパス - 完全な360度回転のトラック番号

最初のベアリングが90度の場合、センサデータが変更されたときに次のベアリングをチェックし続け、一貫して一方向に動いていれば、回転していることが分かります。そして、その方向に回転し続けて90度に戻すと、それは1回転としてカウントされます。私のやり方は非常に畳み込まれていて非効率的で、私はより良い方法を思いつくのに苦労しています。

このシナリオでは、複数のフルローテーションが予想されます。

ご協力いただきありがとうございます。ありがとうございました!

私はthisという回答を見つけました。そのためのコードサンプルをまとめようとしています。誰かがすでに何か似たようなことをしているなら、投稿してください!

@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    switch(event.sensor.getType()) 
    { 
     case Sensor.TYPE_GRAVITY: 
     { 
      mValuesAccelerometer = lowPass(event.values.clone(), mValuesAccelerometer); 
      break; 
     } 
     case Sensor.TYPE_MAGNETIC_FIELD: 
     { 
      mValuesMagneticField = lowPass(event.values.clone(), mValuesMagneticField); 
      break; 
     } 
    } 

    boolean success = SensorManager.getRotationMatrix(
      mMatrixR, 
      mMatrixI, 
      mValuesAccelerometer, 
      mValuesMagneticField); 

    if (success) 
    { 
     SensorManager.getOrientation(mMatrixR, mMatrixValues); 

     float azimuth = toDegrees(mMatrixValues[0]); 
     float pitch = toDegrees(mMatrixValues[1]); 
     float roll = toDegrees(mMatrixValues[2]); 

     if (azimuth < 0.0d) 
     { 
      //The bearing in degrees 
      azimuth += 360.0d; 
     } 
    } 
} 

答えて

1

あなたのコードを最適化するために、彼らは唯一の1方向に移動することがありますことを確認している場合は、代わりに、彼らはまだ、右方向に移動している場合は、連続的監視の程度のためのチェックポイントを持つことができます。

ここ

//You noted 90 degree as starting point 
// checkpoint 1 will be 180 keep it as a boolean 
// now you've reached 180 if the meter gets to 180 before going to next checkpoint 
// which is 270 then make 180 false. it means they turned back. 
// if they make it to 270 then wait for 0 degrees and do the same. 
// if they make it back to 90 like that. You got a rotation and hopefully 
// a bit of complexity is reduced as you're just checking for 4 checkpoints 

私は現時点では便利な任意のコードを持っていないことを行うにはラフアルゴです。

0

私はあなたがonSensorChangedイベントを処理する方法を知っているが、基本的には、whileループ内の構文については申し訳ありません

while (currentDegrees + 90 < 360) 
{ 
    if (currentDegrees + 90 == 0) 
    { 
     if (previousDegrees == 359) 
     { 
      rotationCount = rotationCount + 1 
     } 
    } 
    else if (currentDegrees + 90 == 359) 
    { 
     if (previousDegrees == 0) 
     { 
      rotationCount = rotationCount - 1 
     } 
    } 
    previousDegrees = currentDegrees + 90 
} 

、これをチェックを行ういけないので、3つの整数

int rotationCount=0 
int currentDegrees=0 
int previousDegrees=89 

ないJavaプログラマを作成します。これを行う方法の一例に過ぎません。

0

これはオーバーフローした読みに伴うトラッキングの問題です。あなたは最後の読みを追跡する必要があり、ユーザが各読みの間に半分以上回転しないようにする必要があります....(ナイキストの定理のため)

ここには基本的な疑似コードがあります。

var totalChange = 0; 
var lastAzimuth = -1000; 

function CountTurns(az) 
{ 
    if (az > 180) az -= 360; // do this if your azimuth is always positive i.e. 0-360. 

    if (lastAzimuth == -1000) 
    { 
    lastAzimuth = az; 
    } 

    diff = az - lastAzimuth; 
    if (diff > 180) 
    diff -= 360; 
    if (diff < -180) 
    diff += 360; 

    lastAzimuth = az; 
    totalChange += diff; 
    return totalChange/360; 
} 
0

私が言うことを視覚化すれば、間違いなくあなたの目標を打ち破ることができます。 あなたは完全な360度を考える必要はありませんが、その半分を取って、あなたの利点にサインの違いを使用することができます。

はこの数字を見てみましょう: 360 Rotation

我々は2つの側面(左右)に分割された円を持っています。

左側がマイナス180度になります。 (西側)。

右側が正の180度になります。 (東側)。

現在のポジショニングは、常に(北)として0、(南)として正の180になります。

コンパスが正になるのIF(意味が右方向に行く)

次に、各ターンに1を追加します。

IFコンパスが負になる(意味は左方向に向いています)。コンパスがヒットOR 0の場合

次に引く-1それぞれには

を回し、それは現在の位置(NORTH)です。

コンパスのヒットORが90の場合は、(東)です。

コンパスヒットIF OR 180であるが、コンパスがヒットOR -90であれば、それは(南)

だ、それは(西)です。

東に行くたびに、カウンターは+1に+1してからプラスに変化し、0になるまで-1回ずつ減じます。完全な360回転になります。

関連する問題