Samsung Galaxy Nexus (Android 4.0) からできるだけ速くセンサー値を読み取ろうとしています。このために、さまざまなセンサーとサンプリング レートを使用していくつかの実験を行い、非常に奇妙な動作を見つけました。Acc-Sensor のみを使用した場合、サンプリング レートは約 50Hz です。しかし、ジャイロ センサー (または磁場センサー) も使用すると、Acc センサーのサンプル レートが増加し、どちらも 90 ~ 100 Hz のサンプル レートになります。センサー遅延の変更 (たとえば、SENSOR_DELAY_FASTEST から SENSOR_DELAY_UI へ) はサンプリング レートに影響を与えず、磁場センサーも追加すると、3 つのセンサーすべてのサンプリング レートが高くなります (90-100Hz)。もう 1 つの奇妙な点は、3 つのセンサーからの値が常に同じタイムスタンプで到着することです (1 つまたは 2 ミリ秒の違いがある場合があります。他の 2 つのタイムスタンプはまったく同じです)。Android-NDKでも同じことをテストしましたが、サンプリングレートの変更(ASensorEventQueue_setEventRate()を使用)が効果がないことを含め、まったく同じ動作があります。
私の友人は、HTC Desire HD で同じことを試しました (Android 2.3 で、ジャイロを持っていないため、加速度センサーと磁気センサーのみ)。 acc-sensor の速度は、磁気センサーの使用とは無関係でした (これは、通常の動作として期待されることです)。
他のセンサーを追加で使用すると、acc-sensor が高速になるのはなぜですか? 誰かが同様の動作を理解しましたか? これはバグですか?それとも私のコードのバグですか?
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++;
}
}
}