Galaxy Nexus: частота выборки сенсора становится выше, чем больше выборок сенсоров

Я пытаюсь как можно быстрее считывать значения датчиков с Samsung Galaxy Nexus (с Android 4.0). Для этого я провел несколько экспериментов, используя разные датчики и частоты дискретизации, и выяснил очень странное поведение. Когда я использую только Acc-Sensor, частота дискретизации составляет около 50 Гц. Но когда я также использую гироскопический датчик (или датчик магнитного поля), частота дискретизации Acc-Sensor увеличивается, и оба имеют частоту дискретизации от 90 до 100 Гц. Изменение задержки датчика (например, с SENSOR_DELAY_FASTEST на SENSOR_DELAY_UI) не влияет на частоту дискретизации, и когда я добавляю также датчик магнитного поля, все три датчика имеют высокую частоту дискретизации (90-100 Гц). Еще одна странность заключается в том, что значения от трех датчиков всегда приходят с одной и той же меткой времени (иногда у одного есть разница в 1 или 2 мс, но у двух других точно такая же метка времени). Я также тестировал то же самое с Android-NDK, и там точно такое же поведение, включая то, что изменение частоты дискретизации (с использованием ASensorEventQueue_setEventRate ()) не имеет никакого эффекта.

Мой друг пробовал то же самое на HTC Desire HD (с Android 2.3 и только с датчиком и магнитным датчиком, так как у него нет гироскопа), и там частота дискретизации датчиков отличалась друг от друга, а частота дискретизации - Скорость акк-сенсора не зависела от использования магнитного сенсора (это то, что я ожидал от нормального поведения).

Почему работает акк-сенсор быстрее, если другие сенсоры используются дополнительно? Кто-нибудь придумал подобное поведение? Это ошибка? А может ошибка в моем коде?

Вот код, который я использовал для тестирования с 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++;
    }

}

}


person steckl    schedule 15.05.2012    source источник


Ответы (2)


То, что вы видите, является результатом «умного датчика» от Invensense, а не ошибкой в ​​коде уровня вашего приложения. Это ошибка в реализации программного обеспечения платформы намного ниже в недрах этого устройства.

Invensense MPU3050 в этом телефоне имеет обработку движения. Устройство в дополнение к его гироскопу MEMs. Он управляет акселерометром и магнитометром, объединяет данные, запускает объединение датчиков и отправляет данные обратно на Android, где их видит ваше приложение.

Из таблицы данных MPU3050:

Встроенный цифровой процессор движения (DMP) расположен внутри MPU-30X0 и разгружает вычисление алгоритмов обработки движения с главного процессора. DMP получает данные от акселерометров, гироскопов и дополнительных датчиков, таких как магнитометры, и обрабатывает эти данные. [..snip ...] Целью DMP является разгрузка как требований к синхронизации, так и вычислительной мощности хост-процессора.

person Rian Sanderson    schedule 17.08.2012
comment
Имеет смысл. Спасибо за Ваш ответ. - person steckl; 24.08.2012

Это странно. Я тоже столкнулся с той же проблемой. Поэтому я создал приложение для разработчика, чтобы проверить эту проблему здесь.

person user1970292    schedule 21.01.2013