【问题标题】:Galaxy Nexus: Sensor Sampling Rate becomes faster when sampling more SensorsGalaxy Nexus:采样更多传感器时,传感器采样率变得更快
【发布时间】:2012-05-15 19:00:22
【问题描述】:

我正在尝试尽快从三星 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 传感器的采样率与磁性传感器的使用无关(这是我所期望的正常行为)。

如果额外使用其他传感器,为什么 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++;
    }

}

}

【问题讨论】:

    标签: android performance android-sensors


    【解决方案1】:

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

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

    来自MPU3050 datasheet

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

    【讨论】:

    • 有意义。谢谢你的回答。
    【解决方案2】:

    这很奇怪。我也遇到了同样的问题。所以我为开发者创建了一个应用程序来检查这个问题here

    【讨论】:

      猜你喜欢
      • 2019-03-06
      • 2012-10-05
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多