使用'onSensorChanged'加速度计采样率抖动

时间:2014-04-11 10:18:26

标签: android accelerometer android-sensors sampling

我正在使用三星galaxy ace3来加速加速。 getMinDelay()给了我10000μs。当我将该周期的加速度记录到csv文件时,我会在正确的周期内出现延迟,并且随机抖动有时很大(超过0.5秒)。

有人知道如何改善这个吗?

以下是我得到的样本之间的延迟。

Delays vs time Delays vs time (Zoom)

public class MainActivity extends Activity implements SensorEventListener {    
private SensorManager mSensorManager;
private Sensor mSensor;
private int cpt = 0;
private boolean start;
private List<String> records = new ArrayList<String>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

}


public final File dir = new File("/mnt/extSdCard/test/");
public FileOutputStream afos = null;
public OutputStream stream = null;

public void startButton(View view) {
    start = true;
    cpt = 0;
    mSensorManager.registerListener((SensorEventListener) this, mSensor, 10000); // 10000 µs -> 10 ms
    openCsvFiles(dir, "data.csv");
    stream = new BufferedOutputStream(afos);
}

public void stopButton(View view) {

    for (String record: records) {
        try {
            stream.write(record.getBytes());
        } catch (IOException e) {

        }
    }

    try {
        stream.flush();
        stream.close();
        afos.close();
        start = false;
    } catch (IOException e) {
        Toast.makeText(MainActivity.this, "exception: " + e.getMessage(), Toast.LENGTH_SHORT).show();
    }
    Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_SHORT).show();
}

@Override
public final void onSensorChanged(SensorEvent event) {
    float ax, ay, az;
    String axs, ays, azs, ts, line;
    if (start) {
        cpt++;

        ax = event.values[0];
        ay = event.values[1];
        az = event.values[2];

        ts = String.valueOf(event.timestamp);

        long ns = android.os.SystemClock.elapsedRealtimeNanos();

        line = ns+", "+ cpt+", "+ ts + "," + ax + "," + ay + "," + az + "\n";

        records.add(line);

    }
  }
}

2 个答案:

答案 0 :(得分:0)

mSensorManager.registerListener((SensorEventListener) this, mSensor, 10000);

使用 SensorManager.SENSOR_DELAY_FASTEST

而不是硬编码值10000
mSensorManager.registerListener((SensorEventListener) this, mSensor, SensorManager.SENSOR_DELAY_FASTEST);

答案 1 :(得分:0)

onSensorChanged的文档说你不应该在方法中做很多处理,因为它会阻止进一步的样本。它在这个页面上说:

http://developer.android.com/guide/topics/sensors/sensors_overview.html

在这里,您将从数据创建一个字符串并将其添加到ArrayList。创建字符串需要一定的时间,通常会将其快速添加到ArrayList中,但有时需要增长ArrayList以容纳下一个对象,在这种情况下需要很长时间,因为它需要在内部分配一个新的(更大的)数组,并将旧数组中的引用复制到新数组。

考虑将SensorEvent添加到方法中的FIFO(例如ArrayDeque)中,然后在另一个线程中处理这些。它应该改善抖动。

我认为Android系统不能保证抖动永远不会很大,但这应该会有所帮助。