我正试图从三星Galaxy Nexus(使用Android 4.0)尽快读出传感器值。为此,我做了一些使用不同传感器和采样率的实验,并发现了一个非常奇怪的行为。当我只使用Acc-Sensor时,采样率约为50Hz。但是,当我还使用陀螺仪传感器(或磁场传感器)时,Acc传感器的采样率会增加,并且两者的采样率都在90到100 Hz之间。传感器延迟的改变(例如从SENSOR_DELAY_FASTEST到SENSOR_DELAY_UI)对采样率没有影响,当我还添加磁场传感器时,所有三个传感器都具有高采样率(90-100Hz)。 另一个奇怪的事情是来自三个传感器的值总是以相同的时间戳到达(有时一个有1或2 ms的差异,但其他两个具有完全相同的时间戳)。 我也用Android-NDK对它进行了相同的测试,结果完全相同,包括更改采样率(使用ASensorEventQueue_setEventRate())无效。
我的一位朋友在HTC Desire HD上尝试过相同的东西(Android 2.3和只有acc和磁传感器,因为他没有陀螺仪),传感器的采样率彼此不同, acc传感器的采样率与磁传感器的使用无关(这是我所期望的正常行为)。
如果另外使用其他传感器,为什么会使传感器更快?有人想出类似的行为吗?这是一个错误吗?或者我的代码可能有错误?
以下是我用于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++;
}
}
}
答案 0 :(得分:2)
您所看到的是Invensense的“智能传感器”的结果,绝对不是您的应用程序级代码中的错误。这是平台软件实现中的一个错误,远低于此设备的内容。
除了MEMs陀螺仪外,Invensense MPU3050 chip on this phone还有一个运动处理单元。它控制加速度计和磁力计,合并数据,运行sensor fusion和sends the data back up to Android,您的应用可以在其中看到它。
嵌入式数字运动处理器(DMP)位于MPU-30X0内并卸载计算 来自主处理器的运动处理算法。 DMP 从加速度计,陀螺仪和其他传感器获取数据 例如磁力计,并处理数据。 [..snip ...] DMP的目的是卸载 来自主处理器的时序要求和处理能力
答案 1 :(得分:1)
这很奇怪。我也遇到了同样的问题。所以我为开发人员创建了一个App来检查这个问题here。