私の目標は、自転車に乗っている間に道路の品質を測定する Android モバイル アプリ (SDK16+) を作成することです。
Android 用のセンサー フュージョン デモを見つけました。これですべての測定が行われると思います。
電話が特定の方向に固定されていない場合、垂直方向の動きだけを取得するにはどうすればよいですか?
私の目標は、自転車に乗っている間に道路の品質を測定する Android モバイル アプリ (SDK16+) を作成することです。
Android 用のセンサー フュージョン デモを見つけました。これですべての測定が行われると思います。
電話が特定の方向に固定されていない場合、垂直方向の動きだけを取得するにはどうすればよいですか?
問題
ここでの問題は、デバイスの dx、dy、dz と、周囲の世界の wX、wY、wZ という 2 つの座標系があることです。デバイスを動かすと、2 つの変化の関係が変化します。
質問を定式化する別の方法は、次のように言うことです。
センサーの読み取り値 [dx, dy, dz] が与えられた場合、wZ に平行な読み取り値の成分を見つけるにはどうすればよいですか?
解決策
幸いなことに、方向センサー (Android 独自のROTATION_VECTOR
センサーなど) は、これら 2 つの座標系間の変換のためのツールを提供します。
たとえば、ROTATION_VECTOR
センサーの出力は、ワールド フレームで固定された特定の「ベース」回転からデバイスが持っている回転の軸角度表現の形式で提供されます (クォータニオンも参照してください)。
Android は、SensorManager#getRotationMatrixFromVector(float[] R, float[] rotationVector)
センサーから軸角度表現を取得し、それを回転行列に変換する メソッドを提供します。回転行列は、ある参照フレームで指定されたベクトルを別の参照フレームに変換するために使用されます (この場合は [ World -> Device ])。
ここで、デバイス フレームの測定値をワールド フレームに変換しますか? 問題ない。回転行列の気の利いた特徴の 1 つは、回転行列の逆行列が反対の変換 (この場合は [デバイス -> 世界]) の回転行列であることです。もう 1 つのさらに気の利いたことは、回転行列の逆行列は単純に転置であることです。
したがって、コードは次の行に従うことができます。
public void findVerticalComponentOfSensorValue() {
float[] rotationVectorOutput = ... // Get latest value from ROTATION_VECTOR sensor
float[] accelerometerValue = ... // Get latest value from ACCELEROMETER sensor
float[] rotationMatrix = new float[9]; // Both 9 and 16 works, depending on what you're doing with it
SensorManager.getRotationMatrixFromVector(rotationMatrix, rotationVectorOutput);
float[] accelerationInWorldFrame = matrixMult(
matrixTranspose(rotationMatrix),
accelerometerValue);
// Make your own methods for the matrix operations or find an existing library
accelerationInWorldFrame[2] // This is your vertical acceleration
}
これが最善の解決策であると言っているわけではありませんが、あなたが求めていることを実行する必要があります.
免責事項
磁力計を含むセンサーフュージョンを使用するデバイスを金属フレームにストラップすると、一貫性のない結果が生じる場合があります。ここではコンパスの方位は問題にならないので、磁力計を使用しないセンサー フュージョン方式を使用することをお勧めします。