質問

I'm currently writing a simple android application to calculate the biases of the devices imu. While doing this I've come across a problem with the value of event.timestamp

Using the code:

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

from the example at the Android Reference Guide to calculate the rotation matrix from the quaternion.

When I run the code using a Galaxy Nexus-S I get a dT of 0.06~0.07 sec between measurements but when I run the same code on a LG Nexus 4 or Nexus 7 the dT is always 0. I'm aware of the question, Android SensorEvent timestamp issue that the Nexus 7 timestamp is a unix timestamp but the difference between successive measurements shouldn't always be zero. The Nexus 4 and Nexus 7 both have the same IMU could this be a bug in how the timestamp is created from the IMU?

役に立ちましたか?

解決

Wow, ok this is surely a bug!

The timestamp of each SensorEvent is being overwritten as if it were a static variable...

When I record a string of the timestamp when the event occurs, all values are different.

The events are stored in an array unchanged.

Every SensorEvent in the array now has the same timestamp, but the values arrays are still different (i.e., they're not the same object and contain different information... EXCEPT for the timestamp).

Google/HTC, please return 3 hours of my life!

I'll go file a bug report, unless anyone can explain this behaviour. It's certainly not documented in the API.

In the meantime, try out this solution:

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;
    }
}

Then do something like this in your listener:

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

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

The refactoring should be quite easy, since SensorEvent and UnbrokenSensorEvent have the same public fields. If you need to use other SensorEvent functionality, just go ahead and chuck it into the Unbroken version.

It's hacky, but IMHO a quick hack is always better than waiting for an API to be updated!

他のヒント

Also do note the documentation on SensorEventListener's onSensorChanged -method:

NOTE: The application doesn't own the event object passed as a parameter and therefore cannot hold on to it. The object may be part of an internal pool and may be reused by the framework.

Found here: http://developer.android.com/reference/android/hardware/SensorEventListener.html#onSensorChanged%28android.hardware.SensorEvent%29

...which suggests that one should not hold references to SensorEvent -objects.

If you copied snippet from here Notice it has a bug. Need replace

private float timestamp;

to

private long timestamp;

In other case your delta time will always contain weird value

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top