我正在尝试从 Samsung Galaxy Nexus(带 Android 4.0)尽快读取传感器值。为此,我使用不同的传感器和采样率做了一些实验,并发现了一个非常奇怪的行为。当我只使用 Acc-Sensor 时,采样率约为 50Hz。但是,当我还使用陀螺仪传感器(或磁场传感器)时,加速传感器的采样率会增加,并且两者的采样率都在 90 到 100 Hz 之间。传感器延迟的变化(例如从 SENSOR_DELAY_FASTEST 到 SENSOR_DELAY_UI)对采样率没有影响,当我添加磁场传感器时,所有三个传感器都具有高采样率(90-100Hz)。
另一个奇怪的事情是,来自三个传感器的值始终具有相同的时间戳(有时一个传感器有 1 或 2 毫秒的差异,但其他两个具有完全相同的时间戳)。
我还使用 Android-NDK 进行了相同的测试,并且存在完全相同的行为,包括采样率的更改(使用 ASensorEventQueue_setEventRate())没有效果。
我的一个朋友在 HTC Desire HD 上尝试了同样的事情(使用 Android 2.3,只有加速度传感器和磁传感器,因为他没有陀螺仪),传感器的采样率彼此不同,并且采样率不同。 acc-传感器的速率独立于磁传感器的使用(这是我所期望的正常行为)。
如果另外使用其他传感器,为什么 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++;
}
}
}