加速度计记录器:在经历帧之间偶尔长时间延迟 [英] Accelerometer logger: experiencing occasional long delays between frames

查看:211
本文介绍了加速度计记录器:在经历帧之间偶尔长时间延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个应用程序,登录手机的加速度每40毫秒(在25Hz的)。这帧速率可以保持在平均水平,但有时我遇到的5'000ms延迟 - 时间周期之间50'000ms。我想知道为什么会这样。

I am writing an app that logs the accelerations of the mobile phone every 40ms (at 25Hz). This frame rate can be held on average, but sometimes I am experiencing delays of 5'000ms - 50'000ms between timeframes. I am wondering why this happens.

在这里,你有延迟的图,你可以看到他们出现相当频繁:

Here you have a graph of the delays where you can see that they occur quite often:

下面是我在做什么(这可能是坏的):

Here's what I am doing (which might be bad):

  • 在活动指向一个加速计记录器类(单,纯java,没有安卓类的扩展)。
  • 加速计记录单继续记录在后台。
  • 加速计记录每个日志直接保存到sqlite的分贝。
  • 在我还登录后台GPS数据。
  • 的DAO(数据访问对象)分配每个登录到的LinkedBlockingQueue,并将它们保存在单独的线程。

下面是我想可能是这个问题:

Here's what I think might be the problem:

  • 也许我要实现进一步的生命周期方法,或延长特定的机器人类,从而使accererometer记录的收益优先级(或只是设置优先级的地方)。
  • 我可能会使用 event.timestamp ,而不是 System.currentTimeMills的()。 (我想preFER不这样做,因为一些传感器具有不同的时区,这就是为什么我使用 System.currentTimeMillis的(),但如有必要,我会切换。 )
  • Maybe i have to implement further lifecycle methods, or extend a specific android class, so that the accererometer logger gains priority (or just set the priority somewhere).
  • I might use the event.timestamp instead of System.currentTimeMills(). (I would prefer not to do this, as some sensors have different timezones, thats why i use System.currentTimeMillis(), but if necessary I'd switch.)

你有这个或建议的任何经验,哪里出了问题很可能在哪里?

Do you have any experience with this or suggestions where the problem could probably lie?

下面是我的code:

@SuppressLint("NewApi")
public class AccelerometerLogger implements SensorEventListener {

    private static AccelerometerLogger singleton = new AccelerometerLogger();

    private LoggerDao loggerDao;

    private SensorManager sensorManager;

    private Sensor accelerometer;

    private double acceleorometerRate = 25; // Hz

    int accelerometerDelayMicroseconds = (int) (Math.round(((1/this.acceleorometerRate)*1000000.0)));

    private AccelerometerLogger()
    {
        this.loggerDao = LoggerDao.getInstance();
    }

    public static AccelerometerLogger getInstance()
    {
        return singleton;
    }

    public void start(Context context)
    {
        this.sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        this.accelerometer = this.sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        int accelerometerMinDelay = this.accelerometer.getMinDelay();

        //Log.d("lggr-r", "desired delay: "+this.accelerometerDelayMicroseconds+" microseconds");
        //Log.d("lggr-r", "provided min delay: "+accelerometerMinDelay+" microseconds");

        if(accelerometerMinDelay < this.accelerometerDelayMicroseconds)
        {
            this.sensorManager.registerListener(this, this.accelerometer, this.accelerometerDelayMicroseconds);
            //Log.d("lggr-r", "listener registered for desired rate: "+this.acceleorometerRate+"Hz (delay of "+this.accelerometerDelayMicroseconds+" microseconds).");
        } 
        else if(accelerometerMinDelay==0)
        {           
            this.sensorManager.registerListener(this, this.accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
            // Log.d("lggr-r", "listener registered for streaming api. only changes will be notified (interrupt).");
        }
        else
        {
            int providedRate = (int) Math.round(1 / (accelerometerMinDelay / 1000000.0));
            this.sensorManager.registerListener(this, this.accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
            // Log.d("lggr-r", "can't read at the desired rate ("+this.acceleorometerRate+"Hz), app will read at "+providedRate+"Hz instead (delay of "+accelerometerMinDelay+" microseconds).");
        }
    }

    public void stop()
    {
        this.sensorManager.unregisterListener(this);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy)
    {
        // String name = sensor.getName();
        // Log.d("lggr", "the accurracy of "+name+" changed to "+accuracy+".");
    }

    @Override
    public void onSensorChanged(SensorEvent event)
    {
        // lazy load loggerDao (TODO: fix all of those)
        if(this.loggerDao == null)
        {
            this.loggerDao = LoggerDao.getInstance();
        }


        String values = "";
        for(float value : event.values) values += value+",";
        values = values.substring(0,values.length()-2);

        // long timestamp = System.currentTimeMillis();
        // Log.d("lggr", "acc = {time:"+timestamp+", data: ["+values+"]}");

        AccelerometerSample accelerometerSample = new AccelerometerSample();
        accelerometerSample.setTimestamp(System.currentTimeMillis());
        accelerometerSample.setValues(event.values);

        this.loggerDao.save(accelerometerSample);
    }

}

显然,问题只发生在三星Galaxy SIII的迷你。我有一个三星Galaxy SII(自定义ROM)的测试,并延迟总是约0.04秒(范围0.005〜0.12S之间 - 要好得多)。

Apparently the problem only happens on the Samsung Galaxy SIII mini. I've tested it with a Samsung Galaxy SII (custom ROM) and the delays were always about 0.04s (ranging between 0.005 and 0.12s - much better).

你有什么建议,为什么发生这种情况在三星Galaxy SIII迷你?

Do you have any suggestions why this happens on the Samsung Galaxy SIII mini?

更新:

本·福格茨答案,意为显著使用 event.timestamp 改善了延迟。不过,我遇到有时会出现一些更长的延迟。你知道我怎么能进一步提高他们?

Ben Voigts answer which purposed to use the event.timestamp has improved the delays significantly. Still, i am experiencing sometimes some longer delays. Do you know how I can further improve them?

推荐答案

您绝对应该使用 event.timestamp 。如果你想要本地时间,计算之间的 event.timestamp System.currentTimeMills()调整系数上的第一个事件,并应用相同的调整到后续样品

You absolutely should be using event.timestamp. If you want local time, calculate the adjustment factor between event.timestamp and System.currentTimeMills() on the first event, and apply the same adjustment to subsequent samples.

连接到采样硬件提供时间戳的全部意义在于,它不是搞砸由线程调度延迟。

The whole point of a hardware-provided timestamp attached to the sample is that it isn't messed up by thread scheduling delays.

这篇关于加速度计记录器:在经历帧之间偶尔长时间延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆