Изменение частоты дискретизации Android аппаратных датчиков на Nexus 6P
Я разрабатываю приложение для Android для исследования и читаю несколько данных датчика, таких как акселерометр, гироскоп, барометр и т. Д. Итак, у меня есть 4 устройства Nexus 6P, все с новейшей версией Factory Image и недавно настроенных, и не установлено ни одно другое приложение, кроме Стандартные, которые предварительно установлены. Итак, проблема, которая возникает сейчас, заключается в том, что один из телефонов постоянно отстает, поэтому, например, я записываю акселерометр на полчаса с частотой 105 Гц (так что максимальная возможная частота для акселерометра составляет 400 Гц), просто чтобы убедиться, что я получаю по крайней мере, о количестве сэмплов, которое я ожидал бы для 100 Гц, и результаты следующие:
Sampling в течение получаса при 100 Гц -> 180000 образцов
Sampling в течение получаса при 105 Гц -> 189000 образцов
(Теперь это только пример для акселерометра, но он одинаков для всех остальных датчиков на каждом устройстве. Таким образом, устройства 1,3,4 дают примерно те же хорошие результаты для других датчиков, в то время как устройство 2 получает такие же плохие результаты на всех других датчиках).
- Устройство 1: 180000 образцов
- Device 2: 177273 Samples <- телефон, который отстает
- Устройство 3: 181800 образцов
- Устройство 4: 179412 Образцы
Таким образом, проблема в устройстве № 2, где я пропускаю почти 3000 образцов (я знаю, что это плачет на высоком уровне), и я предполагаю, что эта проблема, вероятно, связана с аппаратным обеспечением. То, что это может быть проблема с производительностью, я, вероятно, могу исключить, поскольку не имеет значения, сколько датчиков, которые я читаю, а также читаю их на частоте 400 Гц, работает, как и ожидалось (при желании я также могу предложить образцы для этого). Я также попытался установить частоту дискретизации 400 Гц, чтобы максимально быстро, а затем сделать запись в соответствии с временной меткой, которая привела к тому же результату.
Так что на всякий случай я предоставлю, как я регистрирую Sensor Listener:
protected void onCreate(Bundle savedInstanceState){
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
unaccDataSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED);
}
....
private void Start(){
sensorManager.registerListener(unaccDataListener, unaccDataSensor, 10000);
}
Так что я хочу получить хотя бы информацию о количестве сэмплов, которые я должен ожидать, поэтому выше это не проблема, и чуть ниже также приемлемо. Так что, если у кого-то есть идея о том, что еще я могу попробовать или что может вызвать проблему, я был бы очень благодарен.
Это мой первый пост, так что если что-то не хватает или я что-то не так объяснил, то извините, и я изо всех сил стараюсь это исправить.
1 ответ
Я много работаю с датчиками Android и могу сказать, что оборудование различного качества. Я обычно использую фильтр, если мне нужно, чтобы результаты были одинаковыми для всех телефонов:
// Filter to remove readings that come too often
if (TS < LAST_TS_ACC + 100) {
//Log.d(TAG, "onSensorChanged: skipping");
return;
}
однако это означает, что вы можете настроить телефоны только на самый низкий общий знаменатель. Если это поможет, я обнаружу, что получение более 25 Гц излишне для большинства приложений, даже медицинских.
Это также может помочь убедиться, что любые операции записи в файл выполняются не в потоке, а в пакетном режиме, поскольку запись в файл является дорогостоящей операцией.
accelBuffer = new StringBuilder();
accelBuffer.append(LAST_TS_ACC + "," + event.values[0] + "," + event.values[1] + "," + event.values[2] + "\n");
if((accelBuffer.length() > 500000) && (writingAccelToFile == false) ){
writingAccelToFile = true;
AccelFile = new File(path2 +"/Acc/" + LAST_TS_ACC +"_Service.txt");
Log.d(TAG, "onSensorChanged: accelfile created at : " + AccelFile.getPath());
File parent = AccelFile.getParentFile();
if(!parent.exists() && !parent.mkdirs()){
throw new IllegalStateException("Couldn't create directory: " + parent);
}
//Try threading to take of UI thread
new Thread(new Runnable() {
@Override
public void run() {
//Log.d(TAG, "onSensorChanged: in accelbuffer");
// Log.d(TAG, "run: in runnable");
//writeToStream(accelBuffer);
writeStringBuilderToFile(AccelFile, accelBuffer);
accelBuffer.setLength(0);
writingAccelToFile = false;
}
}).start();
}
Выполнение всего вышеперечисленного принесло мне достаточно хорошие результаты, но оно никогда не будет идеальным из-за различий в оборудовании.
Удачи!