安卓指南针似乎不可靠

时间:2011-06-06 18:15:22

标签: android compass-geolocation sensor android-sensors

过去几天我一直在研究小型指南针应用程序,并且已经启动并运行了代码,但似乎指南针读数不准确。在校准了两部手机之后,我第一次测试了我发现这个,我只是把手机靠在平面上,看着读数然后水平翻转并将它放在同一平面上(180转)并且值得做不改变180 *它接近240 *。

然后,我测试了读数与指南针,有时读数似乎很接近,但在其他时候,读数超过50 *。我甚至试图将我的手机和指南针放在地板上以保持指南针远离任何磁干扰同样的结果(注意我也保持指南针和手机分开,通过排列书的边缘使它们保持在同一方向)

然后我将示例应用程序放在另一部手机上(首先是nexus S,第二个是Motorola droid 1)。在两部手机之间,差异的范围在某些点相等,但最多点在50到15度之间。

我查看了文档并查看了许多不同的论坛帖子,但我没有看到任何人有相同的结果。我的代码中可能存在一些小错误,导致我的读数错误地出现,或者一些我没有看到的记录错误。

非常感谢任何见解或建议!!

我的传感器改变了我的SensorEventListener类中的代码

public void onSensorChanged(SensorEvent event)
    {
        // If the sensor data is unreliable return
        if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        {
            Toast.makeText(main.this, "Sensor Status Unreliable",Toast.LENGTH_SHORT).show();
        }





        // Gets the value of the sensor that has been changed
        switch (event.sensor.getType())
        {
        case Sensor.TYPE_ACCELEROMETER:
            m_vfgravity = event.values.clone();
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            m_vfgeomag = event.values.clone();
            break;
        }

        if (m_vfgravity != null && m_vfgeomag != null)
        {
            if(SensorManager.getRotationMatrix(m_vfinR, m_vfI, m_vfgravity, m_vfgeomag))
            {
                SensorManager.getOrientation(m_vfinR, m_vforientVals);

                m_fCompBearing = (float) Math.round((Math.toDegrees(m_vforientVals[0])) *2)/2;

                //convert to 0-360 from -180-180
                if(m_fCompBearing < 0.0)
                {
                    m_fCompBearing = 360 + m_fCompBearing;
                }


                mCompHead.setText("" + (int)m_fCompBearing);
            }

            calcOffset();   
            rotateCmp();
        }
    }

并创建我的活动代码

    mSMngr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mSListener = new cSensorListener();

    mSMngr.registerListener(mSListener,
            mSMngr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
            SensorManager.SENSOR_DELAY_UI);
    mSMngr.registerListener(mSListener,
            mSMngr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_UI);

提前致谢!

编辑:还尝试使用droid X但结果最差...当手机滚动45度左右(绕z轴旋转一个计算机坐标系)时,返回的罗盘标题可以改变超过180度,实际上当以相同方向旋转时,标题值与其他电话的方向相反。即使在设置中校准后,这也是唯一产生此结果的手机。他们是一个指南针动态壁纸我测试反对,没有相同的问题。所以我认为我可以在软件中做些什么来避免这种情况。

3 个答案:

答案 0 :(得分:33)

尽管作者回答了他自己的问题,但我还是要在这里加入,以加强Android平台上几乎完全无用的任何指南针功能。

我得出的结论是,任何依赖Android指南针应用程序的人都会遇到麻烦,它们都不能可靠地工作,这不是开发人员的错。

谷歌和制造商根本没有提供从这些设备获得可靠准确度的方法,甚至没有提供确定准确性是否可靠的方法甚至更糟,因为有时他们是,而且很多时候他们不是,如果有人信任这些设备对于真正的定向运动,上帝帮助他们。

作者可能认为他获得更好结果的原因是他们在弃用的方向传感器上使用了一个非常好的噪声滤波器(为什么他们不能在新的方法上做到这一点超出我的要求)以及对单个测试的有限测试校准后的设备似乎可行,但在使用许多设备的现场,我发现在大多数情况下,可靠性始终存在问题。

首先,磁性和方向传感器产生的噪音非常可怕,是的,这可以通过适当的DSP技术克服,而使用2.3和陀螺仪的手机,整体效果会更好,但谷歌和Mfg的耻辱是如此浪费开发人员的时间与粗略的硬件和软件输出实现。

其次,我已经测试了至少18部具有适当DSP过滤功能的手机,虽然这样可以清除噪音,但对于精确度没有帮助,即使同一型号的手机也有不同的输出(尽管有些型号看起来比其他型号好)

第三,你几乎没有办法确定传感器是否经过校准,即使做痉挛的数字8运动可能会或可能不会校准手机,用户也不会真正知道它是否正常工作,除非你有指南针验证,哪种失败点不是吗?

注意:您可以将磁传感器相互乘以和求和,并取该sqrt的平方根(x * x + y * y + z * z),并确保它在25到65左右,这是你可以使用一个指示器来检测异常场,但它不是完全可靠的,比我想的更好。

第四,许多手机完全不可靠,无法校准或不校准,不仅限于型号类型,但可能是制造商的劣质QA,我真的不知道为什么,但我可以说3 HTC ARIA的产品疯狂生产不同的结果(一个30度关闭,另一个50度,第三个几乎点亮)与令人难以置信的连接等同样的事情。

我测试了18部手机,其中许多非常接近准确如果您可以正确校准,但其中许多需要2-10次尝试(我们在每次校准尝试后使用高精度指南针进行验证)并且他们会进行多次测试根本不校准。

注意:您必须考虑真正的北偏移的偏角,如果您可以访问当前的GPS坐标,高度,一天中的时间等,您可以使用Android中的API来解决问题。问题不是赤纬,如果你正在与一个不是问题的指南针进行比较,因为它也会受到局部磁场的影响。

Fith,冷启动总是需要在我们测试的每部手机上进行校准,包括X,不可思议,Aria,Nexus和Thunderbolt。换句话说,第一次启动传感器监听95%的时间它需要一个校准步骤(即使每天两次破坏时钟也是如此)所以如果你坚持添加这个功能,我会告诉你的用户在每个监听器事件的开始。

如果您让传感器继续运行(对电池不利),那么您可能需要或可能不需要重新校准,具体取决于遇到的字段)上述方法可以正常工作。

最重要的是,当他们工作时,他们看起来很酷,但你现在无法确定方位角的准确性,这使得它们对任何实际工作都非常不可靠和无用。

就个人而言,我会在移动时使用GPS轴承,然后使用旋转矢量方法,如果可能的话,它可能不是很完美,但它比你在当前的手机系列中的功能要好得多。方位角。

对于冗长的回复感到抱歉,但是我已经浪费了差不多一个月的时间,试图在专家DSP工程师的帮助下使用它,我们已经写了很多关于Android平台的文章在这方面很有用。

A“有时这种方法有效,有时候它不会,你永远无法确定,除非你有一个真正的指南针”在我看来,应该在每个指南针应用程序中放置免责声明。

答案 1 :(得分:3)

经过多次测试和调试。我得出的结论是,有些人提到了我的机器人1和Nexus S纯粹的硬件差异和磁干扰的区别。

然而Droid X是一个不同的问题,无论我尝试什么,我都无法通过getRotationMatrix和getOrientation以推荐的方式获得正确的读数,即使添加了重新映射坐标功能。因此,经过一些修补,没有成功,我认为id给方向传感器方式一个镜头。

Google表示这种方式已被弃用,他们建议按照我开始的方式进行,但是我尝试了所有类型的组合,但没有成功。所以我继续前进,忽略了他们的警告,并使用了方向传感器......它起作用了。为什么?我不知道,机器人x是比我的机器人1更新的操作系统所以它不应该与使用遗留代码。然而,当我的应用程序执行“推荐方式”无效时,为什么指南针应用程序写入目标1.6会有效。

如果有人有更好的方法可以让我知道,或者如果你知道一种方法可以使它与getRotationMatrix和getOrientation一起使用也可以告诉我。

否则,对于那些像我一样努力打击这个砖墙的人来说,最终会为我工作的代码。

我的传感器已更改

        switch (event.sensor.getType())
        {
        case Sensor.TYPE_ORIENTATION:
            m_vforientVals = event.values.clone();
            break;
        }

        if(m_vforientVals != null)
        {
            m_fCompBearing = m_vforientVals[0];             


            mCompHead.setText("" + (int)m_fCompBearing);

            calcOffset();   
            rotateCmp();
        }

并初始化传感器监听器

    mSMngr.registerListener(mSListener,mSMngr.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                            SensorManager.SENSOR_DELAY_NORMAL);

答案 2 :(得分:2)

您的代码对我来说很好,如果您的代码中存在错误,我很确定这两种设备都会受到影响。我认为这是导致差异的设备中的硬件。 您是否通过将手机移动到八字形状中来“校准”两个指南针?许多指南针应用程序建议,包括Symbian设备附带的地图软件。那可能有用