M.A.
M.A.

Reputation: 169

Synchronizing "SensorEvent.timestamp" with "System.nanoTime()" or "SystemClock.elapsedRealtimeNanos()"

The problem:

I need to synchronize some data set time-stamped using System.nanoTime() with another one time-stamped using SensorEvent.timestamp.

Description:

I am working on System Identification of a quadcopter. Data acquisition is done using Android API. The input to my system is the pulse width modulation (PWM) which are time-stamped using System.nanoTime() with a frequency of 200 Hz.

The output of the system is Androids's sensors measurements which are time-stamped using SensorEvent.timestamp.

I've checked many online resources but unfortunately didn't help. Can I access SensorEvent.timestamp whenever I want so I time-stamp the inputs using this clock?

Upvotes: 0

Views: 1095

Answers (1)

drdawud
drdawud

Reputation: 83

I'm afraid this problem is a bit complicated. SensorEvent.timestamp switched from being System.nanoTime() to SystemClock.elapsedRealtimeNanos() at some point, but it is unclear when that happened in terms of devices and API levels. In fact, it appears to be completely manufacturer-dependent: https://code.google.com/p/android/issues/detail?id=56561

Furthermore, these clocks count relative to different events or points in time, and nanoTime() does not necessarily continue counting in deep sleep mode; Android: time intervals with deep sleep (System.nanoTime(), System.currentTimeMillis(), SystemClock.elapsedRealtimeNanos())

The only way we found to solve the problem is to periodically record System.currentTimeMillis(), System.nanoTime() and SystemClock.elapsedRealtimeNanos() as atomically as possible, and use the offset between SensorEvent.timestamp and both System.nanoTime() and SystemClock.elapsedRealtimeNanos() to figure out which one the sensor is using. Once you have that you can get an absolute timestamp for each sensor event adding the delta between your SensorEvent.timestamp and System.nanoTime() or SystemClock.elapsedRealtimeNanos() (respectively) to your System.currentTimeMillis(). It's not perfect, and could be off by as much as a few millisecond, but it's as good as we could get it.

Hope that helps!

Upvotes: 3

Related Questions