1

I am trying to capture Accel, Gyro, Mag data at 100hz which is a sampling rate every 10 milliseconds, the usual rates do not fit this pattern GAME is 20ms, and NORMAL is 200ms then you have FASTEST which is 0ms.

I can see that Android introduced Sensor direct channels and sensor reporting mode contiuous which can be set using sampling_period_ns. However i cannot see any documentation or examples anywhere on how to fully implement this. Can anyone who has experience please let me know. at the moment i am using the onChange callback with is unsuitable:

    private void registerListener() {
        SensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
        SensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_GAME);
        SensorManager.registerListener(this, pressure, SensorManager.SENSOR_DELAY_GAME);
        SensorManager.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_GAME);
    }

Then I handle the events in onSensorChanged, however this is 20ms not the required 10

HTBuild
  • 53
  • 6

2 Answers2

0

According to the document on registerListener method you can specify the rate in ms. For the third parameter samplingPeriodUs the document states

int: The rate sensor events are delivered at. This is only a hint to the system. Events may be received faster or slower than the specified rate. Usually events are received faster. The value must be one of SENSOR_DELAY_NORMAL, SENSOR_DELAY_UI, SENSOR_DELAY_GAME, or SENSOR_DELAY_FASTEST or, the desired delay between events in microseconds. Specifying the delay in microseconds only works from Android 2.3 (API level 9) onwards. For earlier releases, you must use one of the SENSOR_DELAY_* constants

Thus you can try a sampling period of 10 ms. If it is slower then you can do nothing about it. But if is faster then you can try Thread.sleep for a few ms or for kotlin use delay with runBlocking.

Hoan Nguyen
  • 18,033
  • 3
  • 50
  • 54
0

You can't. While you can give a hint to the system about your desired acquisition rate, it might still pick a different rate or even deviate from the rate it has chosen (especially if the sensor is used for other tasks in parallel). Also, since it simply hands the data over to your listener, there is no way you can delay the acquisition.

I have not yet tried SensorDirectChannel myself, but it does not seem to solve your problem. Here the documentation states for all selectable frequency presets that

the actual rate is expected to be between 55% to 220% of nominal rate.

Your best bet is to simply request a rate that is high enough for your needs (or maybe SENSOR_DELAY_FASTEST) and discard the events that arrive too soon. Depending on your use case, it might be sufficient to simply discard anything arriving before 10ms have elapsed (simply compare to last non-discarded timestamp) or to actually interpolate between values to get something that matches exactly your desired timestamps.

Also note, that the sensors you listed typically have very different maximum sampling rates. While accelerometer and gyroscope almost always at least reach 100 Hz (i.e. 10ms period), there are many magnetometers that will not go beyond 50 Hz. You can check out the statistics from several thousand users running their sensors at SENSOR_DELAY_FASTEST as well as individual devices here.

  • Thank you. I couldn't find enough information on the Sensor Direct Channel and was not convinced it would solve my issue. I followed your advice and collected samples at a higher rate and polled the results at the 10 ms i needed. – HTBuild Jun 17 '20 at 17:20