首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我的传感器监控技术怎么了?

我的传感器监控技术怎么了?
EN

Stack Overflow用户
提问于 2013-09-13 12:46:44
回答 7查看 1.9K关注 0票数 11

(请阅读最后的更新3)我正在开发一个应用程序,它不断地与设备的传感器一起工作,与AccelerometerMagnetic传感器一起工作以检索设备的方向(目的是提到这里)。换句话说,我的应用程序需要实时了解设备的定位(然而,这是不可能的,所以要尽可能快,但要和可能的一样快!)如Reto Meier在专业的Android 4应用程序开发中所提到的

加速度计每秒能更新数百次.

我不能丢失传感器报告的任何数据,我还想对这些数据执行耗时的操作(检索方向,然后进行计算.)。我决定用LinkedBlockingQueue来解决我的问题

代码语言:javascript
复制
    public void startSensors() {
            LinkedBlockingQueue<float[][]> array=new LinkedBlockingQueue();
    sensorListenerForOrientation = new SensorEventListener() {

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
                aValues = (event.values.clone());
            else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
                mValues = (event.values.clone());
            if (aValues != null && mValues != null) {
                try {
                    array.put(new float[][] { aValues, mValues });
                } catch (InterruptedException e) {
                }
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };
    Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
            sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
    Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
            sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
    sm.registerListener(sensorListenerForOrientation, aSensor,
            SensorManager.SENSOR_DELAY_FASTEST);
    sm.registerListener(sensorListenerForOrientation, mSensor,
            SensorManager.SENSOR_DELAY_FASTEST);
    executor.execute(new Runnable() {
        @Override
        public void run() {
            doCalculations();
        }
    });
}

代码语言:javascript
复制
    public void doCalculations() {
    for (;;) {
        float[][] result = null;
        try {
            result = array.take();
        } catch (InterruptedException e) {
        }
        float[] aValues, mValues;
        aValues = result[0];
        mValues = result[1];

                    int[] degrees=getOrientation(aValues,mValues);
                    Log.e("",String.valueOf(degrees[0]));

                 //other calculations...
                     }
                                }

现在我拿起我的设备,向右旋转大约90度,然后快速地返回到第一个位置(例如1.5秒),但是当我看到在设备中注册的方向时,例如:0,1,2,3,4,5.,40,39,38,37,....,0

我只想说,,我不能在我的结果中看到一个很大的学位域。基于我所做的和我研究过的,我可以确定我没有丢失任何数据,传感器报告的任何新数据都记录了

有什么办法吗?!

致以问候!

更新1:,我用我的设备做了另一个实验,得到了令人震惊的结果!如果我以90度(不到1秒)的速度旋转我的设备,我可以在我的结果中看到所有的度: 0,1,2,3,....,89,90 (例如),但是如果我将它旋转90度,然后将它旋转回它的第一个位置,结果将是0,1,2,...,36,37,36,...2,1,0(例如)...really混淆!

更新2:我更新了doCalculations()方法,以便更清楚地了解我所做的事情

更新3:我想也许我们可以用另一种方式解决这个问题!我对这段代码有明确的目的。请看一下 。我已经提到了将要发生的事情,我需要发现一个特定的动作动作。所以,也许我所选择的方法(上面的技术)并不是解决这个问题的好方法。也许通过使用其他传感器或者用其他方式使用相同的传感器来检测这个手势更好。你觉得呢?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-09-22 01:01:33

你的代码看起来很合理。一个很大的未知是传感器和传感器融合在你的设备中有多好。快速角度变化读数依赖于角加速度的积分,或者是一个带有磁性数据的物理陀螺仪来使结果与地球完全一致。磁性数据受周围环境的影响。如果你的设备有低质量的感应器,或者你的环境中有磁场干扰,那么你所看到的错误是完全有可能的。大型金属结构和磁性设备(如电动机,甚至荧光灯镇流器)可以使磁场空白或造成任意误差。对于正常的用途,一个设备只需要一个加速度计,以准确地确定哪种方式下降,所以屏幕翻转是准确的。这只需要在设备不动时才能工作,因为陀螺仪不起作用。如果你有一部带有传感器的手机或平板电脑--因此没有陀螺仪或不准确的陀螺仪--你就看到了设备的局限性。这些不稳定的值是其他证据,表明你的设备质量很低,或者你处在一个地球磁场被扭曲的位置。在外面和外面的另一个(最好是昂贵的)设备上尝试这个程序,看看你得到了什么。

票数 2
EN

Stack Overflow用户

发布于 2013-09-18 00:36:28

因此,看起来您正在为标准的“生产者-消费者”问题寻找高吞吐量、低延迟的解决方案。基本上,这个想法非常简单:减少数据处理开销,并行处理数据。建议如下:

1.使用“低延迟”库

  • javolution.org -是一个实时库,旨在使Java或类似Java的/C++应用程序更快、更容易预测。它包括Android支持。
  • 水杨酸 -是一个基于Disruptor思想的超快、无垃圾、无锁、双线程(生产者-消费者)队列.Android支持还没有定义(看起来应该有效)。
  • 干扰物 -又一个闪电般的快速库
  • 宝物 --为Java提供高速、常规的和原始的集合。

这些解决方案中的任何一个都将使您节省大量CPU周期。

2.明智地处理数据

每次你提交一份工作时都会有开销。批处理可能真的很有帮助。

连续处理数据。注意,executor.execute将消耗大量资源。几个长寿的消费者可能会有所帮助。

3.最后,使用微优化技术

例如,摆脱if-else-if而支持switch

跟踪所有的性能,以确定好的和坏的解决方案。实验。

编码愉快。

票数 7
EN

Stack Overflow用户

发布于 2013-09-18 15:00:27

我的想法是:请尝试以下几点:

代码语言:javascript
复制
public void startSensors() {
    final Stack<Runnable> mStack = new Stack<Runnable>();
    sensorListenerForOrientation = new SensorEventListener() {

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
                aValues = (event.values.clone());
            else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
                mValues = (event.values.clone());
            if (aValues != null && mValues != null) {
               mStack.push(new Calculater(new float[][] { aValues, mValues });
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };
    Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
            sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
    Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
            sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
    sm.registerListener(sensorListenerForOrientation, aSensor,
            SensorManager.SENSOR_DELAY_FASTEST);
    sm.registerListener(sensorListenerForOrientation, mSensor,
            SensorManager.SENSOR_DELAY_FASTEST);
    new Thread() { 
        public void run() {
            while(true)
            {
                try { 
                    Runnable r = mStack.pop();
                    r.run();
                } catch(Exception ex){}
            }
        }
    }.start();
}
private class Calculater implements Runnable {
    float[][] theValues;
    public Calculater(float[][] values) {
        theValues = values;
    }
    public void run() {
        int[] degrees= getOrientation(theValues[0], theValues[1]);
        Log.e("",String.valueOf(degrees[0]));
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18786694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档