Can anybody help me getting a smooth-er stream of sensor-events?
I'm trying to use the accelerometer data of a Sony Smart Watch 2 to animate a flag waving on the screen of an android device. Using Sony's sensors-control example code as a starting point i'm getting a nicely working setup. BUT only for about 5-6 seconds! then the sensor data starts coming in in clumps, messing up my animation. Trying to locate the culprit, i've cut-down my smartwatch code to bare essential:
The listener simply logs the number of milliseconds since the last sensorevent:
private final AccessorySensorEventListener timeListener = new AccessorySensorEventListener() {
long lastTime = 0;
@Override
public void onSensorEvent(AccessorySensorEvent event) {
Log.i(TAG, "SmartWatch - onSensorEvent: " + (System.currentTimeMillis()-lastTime));
lastTime = System.currentTimeMillis();
}
};
And the registration of this listener
SW2SensorsControl(final String hostAppPackageName, final Context context) {
super(context, hostAppPackageName);
AccessorySensorManager manager = new AccessorySensorManager(context, hostAppPackageName);
if (DeviceInfoHelper.isSensorSupported(context, hostAppPackageName, SensorTypeValue.ACCELEROMETER)) {
accelerometer = manager.getSensor(SensorTypeValue.ACCELEROMETER);
}
if(accelerometer!=null) {
try {
accelerometer.registerFixedRateListener(timeListener, com.sonyericsson.extras.liveware.aef.sensor.Sensor.SensorRates.SENSOR_DELAY_NORMAL);
} catch (AccessorySensorException e) {
Log.d(TAG, "Failed to register listener", e);
}
}
}
Running the code, i see the sensorevents streaming-in fine between 10 and 70 milliseconds apart. But after about 6 seconds, i start seeing hiccups: 200 milliseconds, and then they try to "catch-up" and i get 5 readings a few ms apart. After this, it runs fine for a couple of seconds, and then i see another hiccup: 500~100 ms, and again some quick "catch-up" events. - this scheme repeats and gets more frequent, until after a few more seconds, the stream gets completely bogged down. I've tested on both A Samsung galaxy S5, a Nexus-4 and a Nexus-5, so it's not device-specific, although on the SG5 the logcat is turbo-spammed by something called "ServiceKeeper" apparently some system-process. Here's an example of a hiccup of 450 ms, followed by the short "catch-ups":
06-30 11:47:23.208: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 450
06-30 11:47:23.208: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.208: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.218: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.218: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.218: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 9
06-30 11:47:23.218: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.218: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.228: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.228: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.228: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 9
06-30 11:47:23.228: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.228: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.228: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.228: I/SW2SensorsControl(5173): SmartWatch - onSensorEvent: 3
06-30 11:47:23.228: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.238: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.238: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
06-30 11:47:23.238: I/ServiceKeeper(857): In getappinfo pid = 857 pkgName = android appinfo = null
06-30 11:47:23.238: I/ServiceKeeper(857): In getseinfo pid = 857 uid = 1000 seinfo= system
As you can see, the listener here is not doing any work - aside from logging the time - but when animating my flag, the hiccups starts coming in even quicker (because there's more going on). It is like the sensor event thread is being preemted, and the events queue up behind the scene, or perhaps it's the bluetooth recieve buffer that aren't read. When i use the alternative
accelerometer.registerInterruptListener(timeListener);
The events stream in even faster, and the hiccups gets even worse! Can anybody tell me if this can be solved? Is it my code, is it Android or Sony?
Regards
Edit:
The timestamps in the sensor events themselves don't show the "catch-up" behavior, but continues at the steady rate of 39-41ms (the timestamps are in nano-seconds irl - why?). There's still the odd hiccup - usually 401 or 402ms. This would be much more useful to me when doing animation based on the accelerometer. But the listener doesn't receive them at anything nearly regular rates; sometimes several seconds pass before the next "clump" comes in...
Edit-2:
Tested on a Samsung Galaxy S-3 today. On that the data are coming in at a much smoother rate than on either the Nexus-4 or the SG S-5 (worst). Both Samsungs are spamming the logcat output, On the S5 it's a system process with no useful information, but on the S3 it says "BluetoothSocket.cpp; readNative" I suspect the clumping behaviour of the sensor readings might be caused by the bluetooth system: an input buffer maybe? Does anybody know if it's possible to alter the reading rate of the bluetooth inputbuffer?