モーション センサー

Android プラットフォームには、動きを監視できる複数のセンサーが備わっています。 できます。

センサーセンサーのタイプによって異なります。

  • 重力、直線加速度、回転ベクトル、大きな運動、ステップ 歩数計センサーはハードウェアベースか ソフトウェアベースです。
  • 加速度計とジャイロスコープのセンサーは常にハードウェアベースです。

ほとんどの Android 搭載デバイスには加速度計が搭載されており、多くのデバイスに 対応していますソフトウェアベースのセンサーの可用性は、 ハードウェア センサーを使用してデータを 分析できますデバイスによっては、これらのソフトウェアベースのセンサーが 加速度計、磁力計、ジャイロスコープからのデータを取得できます。

モーション センサーは、傾斜、シェイク、回転、 スイングできます。この動きは通常、直接のユーザー入力( ゲームで車をコントロールする、ゲームでボールをコントロールするユーザーなど)を示す画像ではなく、 デバイスが置かれている物理的な環境(運転中に一緒に移動しているなど) 。1 つ目のケースでは、デバイスの参照フレームを基準とした動きがモニタリングされます。 またはアプリの基準フレームです。2 つ目のケースでは 世界基準の枠組みになります通常、モーション センサー自体は、 地磁気センサーなどの他のセンサーと併用して、 世界の基準フレームに対するデバイスの位置を特定します(詳しくは、位置センサーをご覧ください)。 情報)が含まれます。

すべてのモーション センサーは、SensorEvent ごとにセンサー値の多次元配列を返します。たとえば 1 つのセンサー イベントが発生すると、加速度計は 加速度データを 3 つの座標軸から受け取り、ジャイロスコープが回転速度を 3 つの座標軸のデータです。このデータ値は float 配列として返されます。 (values)と他の SensorEvent あります。表 1 に、Android プラットフォームで使用可能なモーション センサーをまとめています。

表 1. Android プラットフォームでサポートされているモーション センサー。

センサー センサー イベント データ 説明 測定単位
TYPE_ACCELEROMETER SensorEvent.values[0] x 軸に沿った加速度(重力を含む)。 m/秒2
SensorEvent.values[1] y 軸に沿った加速度(重力を含む)。
SensorEvent.values[2] z 軸に沿った加速度(重力を含む)。
TYPE_ACCELEROMETER_UNCALIBRATED SensorEvent.values[0] バイアス補正なしの X 軸に沿った加速度。 m/秒2
SensorEvent.values[1] バイアス補正なしの Y 軸に沿って測定された加速度。
SensorEvent.values[2] バイアス補正なしの Z 軸に沿って測定された加速度。
SensorEvent.values[3] 推定バイアス補正を適用した場合の X 軸に沿って測定された加速度。
SensorEvent.values[4] 推定バイアス補正後の Y 軸に沿って測定された加速度。
SensorEvent.values[5] 推定バイアス補正後の Z 軸に沿って測定された加速度。
TYPE_GRAVITY SensorEvent.values[0] x 軸に沿った重力。 m/秒2
SensorEvent.values[1] y 軸に沿った重力。
SensorEvent.values[2] z 軸に沿った重力。
TYPE_GYROSCOPE SensorEvent.values[0] X 軸を中心とした回転速度。 rad/秒
SensorEvent.values[1] y 軸を中心とした回転速度。
SensorEvent.values[2] Z 軸を中心とした回転速度。
TYPE_GYROSCOPE_UNCALIBRATED SensorEvent.values[0] X 軸を中心とした回転速度(ドリフト補正なし)。 rad/秒
SensorEvent.values[1] y 軸を中心とした回転速度(ドリフト補正なし)。
SensorEvent.values[2] Z 軸を中心とした回転速度(ドリフト補正なし)。
SensorEvent.values[3] X 軸を中心とする推定ドリフト。
SensorEvent.values[4] y 軸を中心とする推定ドリフト。
SensorEvent.values[5] Z 軸を中心とする推定ドリフト。
TYPE_LINEAR_ACCELERATION SensorEvent.values[0] x 軸に沿った加速度(重力を除く)。 m/秒2
SensorEvent.values[1] y 軸に沿った加速度(重力を除く)。
SensorEvent.values[2] z 軸に沿った加速度(重力を除く)。
TYPE_ROTATION_VECTOR SensorEvent.values[0] x 軸に沿った回転ベクトル成分(x × sin(サー/2))。 単位なし
SensorEvent.values[1] y 軸に沿った回転ベクトルの成分(y * sin(q/2))。
SensorEvent.values[2] z 軸に沿った回転ベクトル成分(z × sin(z/2))。
SensorEvent.values[3] 回転ベクトルのスカラー成分((cos(q/2)))。1
TYPE_SIGNIFICANT_MOTION なし 該当なし なし
TYPE_STEP_COUNTER SensorEvent.values[0] センサーの前回の再起動以降にユーザーが行ったステップ数 が有効になりました。 手順
TYPE_STEP_DETECTOR なし 該当なし なし

1 スカラー コンポーネントは省略可能な値です。

回転ベクトル センサーと重力センサーは、モーション センサーとして最も頻繁に使用されるセンサーです。 検出とモニタリングです。回転ベクトル センサーは特に汎用性が高く、 動きに関連する幅広いタスク(ジェスチャーの検出、角度変化の監視、 画面の向きの変化をモニタリングできますたとえば、回転ベクトル センサーは、 ゲーム、拡張現実アプリ、2 次元または 3 次元のコンパスを開発しているとします。 または手ぶれ補正アプリが必要ですほとんどの場合、センサーを使用するよりも、これらのセンサーを使用する方が 方向センサーと加速度計と地磁気センサーのいずれかに 接続されます

Android オープンソース プロジェクトのセンサー

Android オープンソース プロジェクト(AOSP)は、3 つのソフトウェアベースのモーション センサーを提供しています。 直線加速度センサー、回転ベクトルセンサーの 3 種類があります。これらのセンサーの更新日時 Android 4.0 では、(他のセンサーに加えて)デバイスのジャイロスコープを使用して、安定性と 向上しますこれらのセンサーを試す場合は、getVendor() メソッドと getVersion() メソッドを使用して識別できます。 (ベンダーは Google LLC、バージョン番号は 3)。これらのセンサーをベンダー別に特定し、 Android システムはこれら 3 つのセンサーをセカンダリ センサーと見なすため、バージョン番号が必要となります。 センサー。たとえば、デバイス メーカーが独自の重力センサーを提供している場合、AOSP は 重力センサーが 2 次重力センサーとして表示されます。これら 3 つのセンサーはすべて ジャイロスコープ: デバイスにジャイロスコープがない場合、これらのセンサーは表示されず、 使用できます。

重力センサーを使用する

重力センサーは、重力センサーが 重力の方向と大きさです通常、このセンサーは、 空間におけるデバイスの相対的な向き。次のコードは、 デフォルトの重力センサーのインスタンスを取得します。

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);

単位はアクセラレーションで使用される単位と同じです。 センサー(m/s2)であり、座標系は 加速度センサー

注: デバイスが静止しているときは、重力センサーの出力は 加速度計と同じにする必要があります。

直線加速度計を使用する

直線加速度センサーは、 重力を除いた、デバイスの各軸に沿った加速度を表します。次を使用: この値を使用してジェスチャー検出を行います。この値はシステムへの入力としても 推測航法を使用する慣性ナビゲーション システム次のコードは、 デフォルトの直線加速度センサーのインスタンスを取得する方法を示します。

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);

概念的には、このセンサーは次のような加速度データを提供します。 関係:

linear acceleration = acceleration - acceleration due to gravity

通常、このセンサーは、 重力ですたとえば、このセンサーを使用して車の速度を測定できます。リニア 加速度センサーには常にオフセットがあるため、削除する必要があります。これを行う最も簡単な方法は、 を使用して、アプリケーションに調整ステップを組み込みます。キャリブレーションの際、お客様に 3 つの軸のオフセットを読み取りますその値を差し引くことで、 加速度センサーの直接読み取り値からのオフセットを 加速します。

センサーの座標 system は、加速度センサーで使用されるものと同じで、測定単位も同様 (m/s2)です。

回転ベクトル センサーを使用する

回転ベクトルは、デバイスの向きを、角度と これは、デバイスが軸(x、y、または z)を中心として角度 z だけ回転した軸です。次の デフォルトの回転ベクトル センサーのインスタンスを取得するコードは次のようになります。

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);

回転ベクトルの 3 つの要素は、次のように表現されます。

x*sin(q/2)、y*sin(q/2)、z*sin(q/2)

すなわち、回転ベクトルの大きさは sin(O/2) に等しく、 回転ベクトルは回転軸の方向と等しくなります。

図 1. 回転ベクトル センサーで使用される座標系。

回転ベクトルの 3 つの要素は、単位の最後の 3 つの要素に等しい 四元数(cos(O/2)、x*sin(O/2)、y*sin(The/2)、z*sin(O/2))。回転ベクトルの要素は、 単位なしx 軸、y 軸、z 軸は、加速度センサーと同じ方法で定義されます。リファレンス 座標系は直接直交基底として定義されます(図 1 を参照)。この座標系は、 次の特徴があります。

  • X はベクトル積 Y x Z として定義されます。接線のポイントとなる デバイスの現在地を地面にして、ほぼ東を指しています。
  • Y はデバイスの現在地における地面に対して接線の方向であり、 地磁気 北極。
  • Z は空を指しており、地表に対して垂直です。

回転ベクトル センサーの使用方法を示すサンプル アプリケーションについては、をご覧ください。 RotationVectorDemo.java

大型モーション センサーを使用する

大きなモーション センサーは、大きな動きが検知されるたびにイベントをトリガーします。 自身を無効にします。大きなモーションとは、変化を引き起こす可能性のある ユーザーの現在地(徒歩、自転車、車に乗るなど)。次のコードは、 デフォルトの重要なモーション センサーのインスタンスを取得する方法とイベントを登録する方法 リスナー:

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val mSensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION)
val triggerEventListener = object : TriggerEventListener() {
    override fun onTrigger(event: TriggerEvent?) {
        // Do work
    }
}
mSensor?.also { sensor ->
    sensorManager.requestTriggerSensor(triggerEventListener, sensor)
}

Java

private SensorManager sensorManager;
private Sensor sensor;
private TriggerEventListener triggerEventListener;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);

triggerEventListener = new TriggerEventListener() {
    @Override
    public void onTrigger(TriggerEvent event) {
        // Do work
    }
};

sensorManager.requestTriggerSensor(triggerEventListener, mSensor);

詳しくは TriggerEventListener をご覧ください。

歩数計センサーを使用する

歩数計センサーは、最後の再起動以降にユーザーが歩いた歩数を提供します センサーが有効になったとき。歩数計のレイテンシは長くなりますが(最大 10 秒)、 精度が足りないということです。

注: ACTIVITY_RECOGNITION 権限が必要になります。 Android 10(API レベル 29)以降。

次のコードは、デフォルト ステップのインスタンスを取得する方法を示しています。 カウンタ センサー:

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);

アプリを実行しているデバイスのバッテリーを節約するには、 現在の値を取得する JobScheduler クラス 一定間隔で歩数をカウントします。アプリの種類によって 必要なセンサー読み取り間隔が異なる場合は、この間隔を アプリがセンサーからのリアルタイム データを必要とする場合を除きます。

歩行検出センサーを使用する

歩数検出センサーは、ユーザーが 1 歩歩くたびにイベントをトリガーします。レイテンシは 2 秒未満と予想されます

注: ACTIVITY_RECOGNITION 権限が必要になります。 Android 10(API レベル 29)以降。

次のコードは、デフォルト ステップのインスタンスを取得する方法を示しています。 検出センサー:

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);

元データを操作する

次のセンサーは、線形と線形回帰に関する元データをアプリに提供します。 回転力が加わります。使用するには、 センサーを有効に活用するには 環境から要因を除外する必要があります 重力などを受けますトレンドに平滑化アルゴリズムを適用する必要がある場合もあります。 ノイズを低減します。

加速度計を使用する

加速度センサーは、デバイスにかかる加速度を測定します。 重力です次のコードは、デフォルトの加速度センサーのインスタンスを取得する方法を示しています。

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

Java

private SensorManager sensorManager;
private Sensor sensor;
  ...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

注: アプリが Android 12(API レベル 31)または このセンサーは レート制限される。

概念的には、加速度センサーは適用される加速度を判定します センサーに加えられる力を測定することで、デバイス(Ad)に加える (Fs)に次の関係を使用します。

A_D=-(1/質量)ΣF_S

しかし、重力は、モデルに従って測定される加速度に 次のような関係になります。

A_D=-g-(1/質量)ΣF_S

そのため、デバイスがテーブルの上に載っているとき(加速していないとき)は、 加速度計が g = 9.81 m/s2 の大きさを読み取る。同様に デバイスを 自由落下速度 9.81 m/s2 で地面に向かって急速に加速する。 加速度計が g = 0 m/s2 の大きさを読み取る。したがって デバイスの実際の加速度を測定する場合は、重力の作用を 加速度計のデータですこれは、ハイパス フィルタを適用することで実現できます。逆に、ローパス フィルタを使用して重力を分離できます次の例は、この操作を実行する方法を示しています。 これを次のように使用します。

Kotlin

override fun onSensorChanged(event: SensorEvent) {
    // In this example, alpha is calculated as t / (t + dT),
    // where t is the low-pass filter's time-constant and
    // dT is the event delivery rate.

    val alpha: Float = 0.8f

    // Isolate the force of gravity with the low-pass filter.
    gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]
    gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]
    gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]

    // Remove the gravity contribution with the high-pass filter.
    linear_acceleration[0] = event.values[0] - gravity[0]
    linear_acceleration[1] = event.values[1] - gravity[1]
    linear_acceleration[2] = event.values[2] - gravity[2]
}

Java

public void onSensorChanged(SensorEvent event){
    // In this example, alpha is calculated as t / (t + dT),
    // where t is the low-pass filter's time-constant and
    // dT is the event delivery rate.

    final float alpha = 0.8;

    // Isolate the force of gravity with the low-pass filter.
    gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
    gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
    gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

    // Remove the gravity contribution with the high-pass filter.
    linear_acceleration[0] = event.values[0] - gravity[0];
    linear_acceleration[1] = event.values[1] - gravity[1];
    linear_acceleration[2] = event.values[2] - gravity[2];
}

注: センサーデータのフィルタリングには、さまざまな手法を使用できます。 上記のコードサンプルでは、単純なフィルタ定数(alpha)を使用してローパス フィルタを作成しています。このフィルタ 定数は、時定数(t)から導出されます。時定数は、 センサーのイベントとセンサーのイベント配信率(dt)にフィルタが追加されます。コードサンプル デモ用としてアルファ値 0.8 を使用します。このフィルタリング方法を使用すると、 アルファ値を変更できます。

加速度計は標準のセンサー座標を使用します。 システム。実際には、デバイスの設置時に次の条件が適用されます。 テーブルの上に平らな状態で置くことができます。

  • デバイスを左側に押す(つまり右に動く)と、x の加速度値 肯定的です
  • デバイスを下に押す(つまり遠ざけて)押すと、y 加速度値 評価します
  • A m/s2 の加速度でデバイスを上空に押すと、 z 加速度値は A + 9.81 に等しく、デバイスの加速度(+A m/s2)から重力(-9.81 m/s2)を差し引いた値になります。
  • 静止デバイスの加速度値は +9.81 となり、これは デバイスの加速度(0 m/s2 - 重力 -9.81 を差し引いた値) m/s2)。

一般に、デバイスの動きを監視する場合は、加速度計のほうが適しています。 Android 搭載のほぼすべてのスマートフォンやタブレットに加速度計が搭載されており、約 10 回使用します。 消費電力は他のモーション センサーより少ないです。デメリットの一つは、内部 IP アドレスを ローパスフィルタとハイパスフィルタを使って重力を除去し、ノイズを低減します。

ジャイロスコープを使用する

ジャイロスコープは、デバイスの x、y、 z 軸です次のコードは、デフォルトのジャイロスコープのインスタンスを取得する方法を示しています。

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

注: アプリが Android 12(API レベル 31)または このセンサーは レート制限される。

センサーの座標系 これは加速度センサーに使用されるものと同じです。ローテーションが正の値である 反時計回りモニタリングしている人が 原点に配置されたデバイスについて、x 軸、y 軸、z 軸の正の位置からの距離を デバイスが反時計回りに回転しているように見える場合は正の回転。これが 正の回転の標準的な数学的定義であり、これは 方向センサーで使用されるロールです。

通常、ジャイロスコープの出力は、経時的に積分され、正面から見た回転を 時間ステップでの角度の変化を表します。例:

Kotlin

// Create a constant to convert nanoseconds to seconds.
private val NS2S = 1.0f / 1000000000.0f
private val deltaRotationVector = FloatArray(4) { 0f }
private var timestamp: Float = 0f

override fun onSensorChanged(event: SensorEvent?) {
    // This timestep's delta rotation to be multiplied by the current rotation
    // after computing it from the gyro sample data.
    if (timestamp != 0f && event != null) {
        val dT = (event.timestamp - timestamp) * NS2S
        // Axis of the rotation sample, not normalized yet.
        var axisX: Float = event.values[0]
        var axisY: Float = event.values[1]
        var axisZ: Float = event.values[2]

        // Calculate the angular speed of the sample
        val omegaMagnitude: Float = sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ)

        // Normalize the rotation vector if it's big enough to get the axis
        // (that is, EPSILON should represent your maximum allowable margin of error)
        if (omegaMagnitude > EPSILON) {
            axisX /= omegaMagnitude
            axisY /= omegaMagnitude
            axisZ /= omegaMagnitude
        }

        // Integrate around this axis with the angular speed by the timestep
        // in order to get a delta rotation from this sample over the timestep
        // We will convert this axis-angle representation of the delta rotation
        // into a quaternion before turning it into the rotation matrix.
        val thetaOverTwo: Float = omegaMagnitude * dT / 2.0f
        val sinThetaOverTwo: Float = sin(thetaOverTwo)
        val cosThetaOverTwo: Float = cos(thetaOverTwo)
        deltaRotationVector[0] = sinThetaOverTwo * axisX
        deltaRotationVector[1] = sinThetaOverTwo * axisY
        deltaRotationVector[2] = sinThetaOverTwo * axisZ
        deltaRotationVector[3] = cosThetaOverTwo
    }
    timestamp = event?.timestamp?.toFloat() ?: 0f
    val deltaRotationMatrix = FloatArray(9) { 0f }
    SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
    // User code should concatenate the delta rotation we computed with the current rotation
    // in order to get the updated rotation.
    // rotationCurrent = rotationCurrent * deltaRotationMatrix;
}

Java

// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;

public void onSensorChanged(SensorEvent event) {
    // This timestep's delta rotation to be multiplied by the current rotation
    // after computing it from the gyro sample data.
    if (timestamp != 0) {
      final float dT = (event.timestamp - timestamp) * NS2S;
      // Axis of the rotation sample, not normalized yet.
      float axisX = event.values[0];
      float axisY = event.values[1];
      float axisZ = event.values[2];

      // Calculate the angular speed of the sample
      float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);

      // Normalize the rotation vector if it's big enough to get the axis
      // (that is, EPSILON should represent your maximum allowable margin of error)
      if (omegaMagnitude > EPSILON) {
        axisX /= omegaMagnitude;
        axisY /= omegaMagnitude;
        axisZ /= omegaMagnitude;
      }

      // Integrate around this axis with the angular speed by the timestep
      // in order to get a delta rotation from this sample over the timestep
      // We will convert this axis-angle representation of the delta rotation
      // into a quaternion before turning it into the rotation matrix.
      float thetaOverTwo = omegaMagnitude * dT / 2.0f;
      float sinThetaOverTwo = sin(thetaOverTwo);
      float cosThetaOverTwo = cos(thetaOverTwo);
      deltaRotationVector[0] = sinThetaOverTwo * axisX;
      deltaRotationVector[1] = sinThetaOverTwo * axisY;
      deltaRotationVector[2] = sinThetaOverTwo * axisZ;
      deltaRotationVector[3] = cosThetaOverTwo;
    }
    timestamp = event.timestamp;
    float[] deltaRotationMatrix = new float[9];
    SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
    // User code should concatenate the delta rotation we computed with the current rotation
    // in order to get the updated rotation.
    // rotationCurrent = rotationCurrent * deltaRotationMatrix;
}

標準的なジャイロスコープは、ノイズやノイズ、 ドリフト(バイアス)です実際には、ジャイロスコープのノイズやドリフトによって誤差が生じます。 あります。通常、ドリフト(バイアス)とノイズを特定するには、 重力センサーや加速度計として使用しています

未調整のジャイロスコープを使用する

未調整のジャイロスコープはジャイロスコープに似ていますが、 ただし、回転速度にジャイロドリフト補正が適用されない点が異なります。工場での調整 温度補正が引き続き回転速度に適用されます。未調整の ジャイロスコープは、後処理や溶融向きのデータに便利です。一般的に gyroscope_event.values[0] の近くに加わります uncalibrated_gyroscope_event.values[0] - uncalibrated_gyroscope_event.values[3]。 つまり

calibrated_x ~= uncalibrated_x - bias_estimate_x

注: 未調整のセンサーでは、未加工の結果が多く得られるため、 バイアスはある程度含まれますが、測定値には、適用された修正からのジャンプが少なくなります。 調整します。アプリケーションによっては、未調整の結果がよりスムーズでわかりやすいものとして好まれる場合があります。 実現しますたとえば、アプリが独自のセンサー フュージョンを実行しようとしている場合、 調整を加えると 実際の結果がゆがむ可能性があります

未調整のジャイロスコープでは、回転速度に加えて、 軸を中心としたドリフトです次のコードは、デフォルトの 未調整のジャイロスコープ:

Kotlin

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);

その他のコードサンプル

BatchStepSensor サンプルで、さらに詳しく このページで説明する API の使用方法について説明します。

関連ドキュメント