Galaxy Nexus:采样更多传感器时,传感器采样率变得更快

时间:2012-05-15 19:00:23

标签: android performance android-sensors

我正试图从三星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++;
    }

}

}

2 个答案:

答案 0 :(得分:2)

您所看到的是Invensense的“智能传感器”的结果,绝对不是您的应用程序级代码中的错误。这是平台软件实现中的一个错误,远低于此设备的内容。

除了MEMs陀螺仪外,Invensense MPU3050 chip on this phone还有一个运动处理单元。它控制加速度计和磁力计,合并数据,运行sensor fusionsends the data back up to Android,您的应用可以在其中看到它。

来自MPU3050 datasheet

  

嵌入式数字运动处理器(DMP)位于MPU-30X0内并卸载计算   来自主处理器的运动处理算法。 DMP   从加速度计,陀螺仪和其他传感器获取数据   例如磁力计,并处理数据。 [..snip ...] DMP的目的是卸载   来自主处理器的时序要求和处理能力

答案 1 :(得分:1)

这很奇怪。我也遇到了同样的问题。所以我为开发人员创建了一个App来检查这个问题here