Android SensorEvent Постоянная метка времени

В настоящее время я пишу простое приложение для Android, чтобы рассчитать смещения устройств IMU. При этом я столкнулся с проблемой со значением event.timestamp

Используя код:

float dT = (event.timestamp-accel_timestamp)*NS2S;

из примера в Справочном руководстве по Android, чтобы вычислить матрицу вращения из кватерниона.

Когда я запускаю код с помощью Galaxy Nexus-S, я получаю dT 0,06~0,07 сек между измерениями, но когда я запускаю один и тот же код на LG Nexus 4 или Nexus 7, dT всегда равен 0. Я знаю вопрос Временная метка Android SensorEvent указывает на то, что временная метка Nexus 7 является временной меткой Unix, но разница между последовательными измерениями не всегда должна быть равна нулю. Как Nexus 4, так и Nexus 7 имеют одинаковый IMU, может ли это быть ошибкой при создании временной метки из IMU?

3 ответа

Решение

Вау, хорошо, это, безусловно, ошибка!

Временная метка каждого SensorEvent перезаписывается, как если бы это была статическая переменная...

Когда я записываю строку метки времени, когда происходит событие, все значения разные.

События хранятся в массиве без изменений.

Каждый SensorEvent в массиве теперь имеет одну и ту же временную метку, но массивы значений по-прежнему различны (т. Е. Они не являются одним и тем же объектом и содержат разную информацию... ЗА ИСКЛЮЧЕНИЕМ для временной метки).

Google / HTC, верните, пожалуйста, 3 часа моей жизни!

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

А пока попробуйте это решение:

import android.hardware.Sensor;
import android.hardware.SensorEvent;

public class UnbrokenSensorEvent {
    public long timestamp;
    public float[] values;
    public Sensor sensor;

    public UnbrokenSensorEvent(SensorEvent event){
        this.timestamp = event.timestamp;
        this.values = event.values;
        this.sensor = event.sensor;
    }
}

Затем сделайте что-то вроде этого в вашем слушателе:

ArrayList<UnbrokenSensorEvent> results = new ArrayList<UnbrokenSensorEvent>();

public void onSensorChanged(SensorEvent event) {
    results.add(new UnbrokenSensorEvent(event));
}

Рефакторинг должен быть довольно простым, поскольку SensorEvent и UnbrokenSensorEvent имеют одинаковые открытые поля. Если вам нужно использовать другие функциональные возможности SensorEvent, просто включите его в версию Unbroken.

Это взломано, но IMHO быстрый взлом всегда лучше, чем ждать обновления API!

Также обратите внимание на документацию по SensorSventListener onSensorChanged -method:

ПРИМЕЧАНИЕ. Приложению не принадлежит объект события, переданный в качестве параметра, и, следовательно, он не может его удерживать. Объект может быть частью внутреннего пула и может быть повторно использован платформой.

Найдено здесь: http://developer.android.com/reference/android/hardware/SensorEventListener.html

... что говорит о том, что не следует хранить ссылки на объекты SensorEvent.

Если вы скопировали фрагмент отсюда, обратите внимание, что в нем есть ошибка. Нужно заменить

private float timestamp;

в

private long timestamp;

В другом случае ваше дельта время всегда будет содержать странные значения

Другие вопросы по тегам