I'm trying to read out sensor values as fast as possible from a Samsung Galaxy Nexus (with Android 4.0). For this I did a few experiments using different sensors and sampling rates and figured out a very weird behaviour. When I use only the Acc-Sensor the sampling-rate is about 50Hz. But when I also use the Gyro-Sensor (or magnetic-field-sensor) the sample-rate of the Acc-Sensor increases and both have a sample-rate of between 90 and 100 Hz. A change of the sensor-delay (e.g. from SENSOR_DELAY_FASTEST to SENSOR_DELAY_UI) has no effect on the sampling rate and when I add also the magnetic-field-sensor all three sensors have a high sampling-rate (90-100Hz). Another strange thing is that the values from the three sensors arrive always with the same timestamp (sometimes one has 1 or 2 ms difference, but the other two have exactly the same timestamp). I also tested the same with Android-NDK and there is exactly the same behaviour including that a change of the sampling-rate (using ASensorEventQueue_setEventRate()) has no effect.
A friend of mine tried the same things on a HTC Desire HD (with Android 2.3 and only acc- and magnetic-sensor, since he has no gyro) and there the sampling-rate of the sensors was different from each other and the sampling-rate of the acc-sensor was independent on the use of the magnetic sensor (that's what I would expect as normal behaviour).
Why becomes the acc-sensor faster if other sensors are used additionally? Did someone figure out a similar behaviour? Is this a bug? Or maybe a bug with my code?
Here is the code I used for testing with Android-SDK (I calculate the time it takes for doing 1000 measures on each of the sensors):
package de.tum.sdktest;
import java.util.ArrayList;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class TestSDKActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccSensor;
private Sensor mGyroSensor;
private Sensor mMagSensor;
private int accCounter = 0;
private long lastAccTime = 0;
private int gyroCounter = 0;
private long lastGyroTime = 0;
private int magCounter = 0;
private long lastMagTime = 0;
private int measuresPerInterval = 1000;
private ArrayList<Float> accValues;
private ArrayList<Float> gyroValues;
private ArrayList<Float> magValues;
private static final String TAG = "TestSDKActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
accValues = new ArrayList<Float>();
gyroValues = new ArrayList<Float>();
magValues = new ArrayList<Float>();
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
mMagSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
TextView tv = new TextView(this);
tv.setText("Hello World!!!");
setContentView(tv);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccSensor, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mGyroSensor, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mMagSensor, SensorManager.SENSOR_DELAY_UI);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
public synchronized void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
if(accCounter == 0 || accCounter == measuresPerInterval)
{
String s = String.valueOf("acc: "+(event.timestamp-lastAccTime)/1000000000.0);
lastAccTime = event.timestamp;
Log.i(TAG, s);
accCounter = 0;
accValues.clear();
}
accValues.add(event.values[0]);
accCounter++;
}
else if(event.sensor.getType() == Sensor.TYPE_GYROSCOPE)
{
if(gyroCounter == 0 || gyroCounter == measuresPerInterval)
{
String s = String.valueOf("gyro: "+(event.timestamp-lastGyroTime)/1000000000.0);
lastGyroTime = event.timestamp;
Log.i(TAG, s);
gyroCounter = 0;
}
gyroValues.add(event.values[0]);
gyroCounter++;
}
else if(event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
{
if(magCounter == 0 || magCounter == measuresPerInterval)
{
String s = String.valueOf("mag: "+(event.timestamp-lastMagTime)/1000000000.0);
lastMagTime = event.timestamp;
Log.i(TAG, s);
magCounter = 0;
}
magValues.add(event.values[0]);
magCounter++;
}
}
}