Я пытаюсь как можно быстрее считывать значения датчиков с Samsung Galaxy Nexus (с Android 4.0). Для этого я провел несколько экспериментов, используя разные датчики и частоты дискретизации, и выяснил очень странное поведение. Когда я использую только Acc-Sensor, частота дискретизации составляет около 50 Гц. Но когда я также использую гироскопический датчик (или датчик магнитного поля), частота дискретизации Acc-Sensor увеличивается, и оба имеют частоту дискретизации от 90 до 100 Гц. Изменение задержки датчика (например, с SENSOR_DELAY_FASTEST на SENSOR_DELAY_UI) не влияет на частоту дискретизации, и когда я добавляю также датчик магнитного поля, все три датчика имеют высокую частоту дискретизации (90-100 Гц). Еще одна странность заключается в том, что значения от трех датчиков всегда приходят с одной и той же меткой времени (иногда у одного есть разница в 1 или 2 мс, но у двух других точно такая же метка времени). Я также тестировал то же самое с Android-NDK, и там точно такое же поведение, включая то, что изменение частоты дискретизации (с использованием ASensorEventQueue_setEventRate ()) не имеет никакого эффекта.
Мой друг пробовал то же самое на HTC Desire HD (с Android 2.3 и только с датчиком и магнитным датчиком, так как у него нет гироскопа), и там частота дискретизации датчиков отличалась друг от друга, а частота дискретизации - Скорость акк-сенсора не зависела от использования магнитного сенсора (это то, что я ожидал от нормального поведения).
Почему работает акк-сенсор быстрее, если другие сенсоры используются дополнительно? Кто-нибудь придумал подобное поведение? Это ошибка? А может ошибка в моем коде?
Вот код, который я использовал для тестирования с Android-SDK (я рассчитываю время, необходимое для выполнения 1000 измерений на каждом из датчиков):
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++;
}
}
}