fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

SensorManager#registerListener()で値の取得間隔を設定した時の実際の間隔

前回の記事の続き。

各センサの値の取得間隔を設定した時、実際にはどんな間隔でもらえるのか検証してみた。
前回と同じく、検証にはIS12Sを使った。 下記のスレッドをActivityonCreate()でスタートさせてLogcatに出てくるヒストグラムを見る。
取得間隔は1秒、継続時間は10秒。
センサはgetSensorList()で取れるもの。getDefaultSensor()の元ネタですね。

class SensorThread implements Thread {
  private SensorManager getManager() {
    return (SensorManager) self
        .getSystemService(Context.SENSOR_SERVICE);
  }

  @Override
  public void run() {
    SensorManager manager = getManager();
    List<Sensor> sensors = manager.getSensorList(Sensor.TYPE_ALL);
    Log.d(TAG, "sensor size:" + sensors.size());
    Object lock = new Object();
    for (Sensor s : sensors) {
      Log.d(TAG, "*******************");
      Log.d(TAG, "type: " + s.getType());
      Log.d(TAG, "name: " + s.getName());
      Log.d(TAG, "vendor: " + s.getVendor());
      Log.d(TAG, "min delay : " + s.getMinDelay() + " (us)");
      Log.d(TAG, "max range : " + s.getMaximumRange());
      Log.d(TAG, "resolution: " + s.getResolution());
      initHist();
      synchronized (lock) {
        startSensor(s);
        try {
          lock.wait(10100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      stopSensor();
    }
    Log.d(TAG, "* end ******************");
  }

  private void initHist() {
    hist.clear();
    post = -1;
  }

  HandlerThread handlerThread;

  private void startSensor(Sensor sensor) {
    SensorManager manager = getManager();
    handlerThread = new HandlerThread("SensorThread");
    handlerThread.start();
    Handler handler = new Handler(handlerThread.getLooper());
      manager.registerListener(sensorEventListener, sensor, (int) 1e6,
        handler);
  }

  private void stopSensor() {
    SensorManager manager = getManager();
    manager.unregisterListener(sensorEventListener);
    handlerThread = null;
    for (Integer i : hist.navigableKeySet()) {
      Log.d(TAG, i + ": " + hist.get(i));
    }
  }
}

まずは代表的なものから。ヒストグラムの各項目の単位はミリ秒。以下は加速度センサの結果。

*******************
type: 1
name: BMA250 accelerometer
vendor: Bosch Sensortec GmbH
min delay : 10000 (us)
max range : 156.96
resolution: 20.0
11: 1
12: 1
13: 2
14: 2
15: 8
16: 6
17: 12
18: 17
19: 204
20: 187
21: 12
22: 14
23: 5
24: 5
25: 3
26: 2
27: 3
28: 2
29: 2
30: 1
32: 2
33: 2
34: 1
*******************

同じ傾向だったのは、

  • Rotation Vector Sensor (Vendor: Google Inc.)
  • Gravity Sensor (Vendor: Google Inc.)
  • Linear Acceleration Sensor (Vender: Google Inc.)
  • Orientation Sensor (Vender: Google Inc.)
  • Corrected Gyroscope Sensor (Vender: Google Inc.)

これらのセンサはどれもだいたい20ミリ秒間隔でデータがとれている様子。つまり間隔の設定が無視されているということ。ちなみに20ミリ秒間隔というのはSensorManager.SENSOR_DELAY_GAMEと設定したのと同じ。ちなみに日を改めてデータを取ってみたところ70ミリ秒間隔(だいたいSensorManager.SENSOR_DELAY_UI)になっていた。別のアプリ(システム?)が使っていてこちらの設定が効かないとかそういうことなのだろうか。

続いては設定が反映されているパターン。

*******************
type: 9
name: MPL gravity
vendor: Invensense
min delay : 20000 (us)
max range : 1044.1893
resolution: 1.0
998: 1
999: 1
1000: 5
1001: 1
*******************

だいたい1秒間隔でもらえている。他にも、

  • AK8972 Magnetic Field (Vender: Asahi Kasei Corp.)
  • AK8972 Compass (Vender: Asahi Kasei Corp.)
  • MPL rotation vector (Vendor: Invensense)
  • MPL linear accel (Vendor: Invensense)
  • MPL Gyro (Vendor: Invensense)

が同じようにだいたい1秒間隔でデータをもらえていた。

いらんデータを押し付けられるのはちょっと困る、という人はgetDefaultSensor()を使ってみてください。前回の記事でもうっすら言いましたが、加速度センサ以外は取得間隔の設定が効きました。設定が効く方のセンサがもらえるというのが正しい言い方かも。

他の端末でもやってみよう。