2011-06-06 42 views
10

过去几天我一直在研究一个小罗盘应用程序,并且已经开始运行代码,但是看起来罗盘阅读并不准确。在对两部手机进行校准之后,我的第一个测试是,我发现了这一点,我只是拿着手机对着它,平坦的表面看着读数,然后水平翻转并将它放在同一平面上(180 *转),数值没有改变180 *它接近240 *。安卓罗盘看起来不可靠

然后我测试了读数与指南针,有时读数似乎很接近,但在其他地方它超过50 * off。我甚至试图把我的手机和指南针放在地板上,使圆规远离任何磁性干扰,并得到相同的结果(请注意,我还要保持指南针和手机分开,通过排列书本边缘来保持它们在同一个方向) 。

然后我把示例应用程序放在另一个手机上(第一个是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度,在事实上,当朝相同方向旋转时,标题值与其他手机的相反方向相反。即使在设置中进行校准后,这也是唯一能够产生此结果的手机。另外他们是一个指南针我测试的动态壁纸不具有相同的问题。所以我会假设我会在软件中做些什么来避免这种情况。

+0

你确定Android是问题,而不是硬件? – 2011-06-06 19:09:39

+0

差异的一个明显来源是磁性与真北方。 FWIW,我的基本garmin gps单位直指前进,如果你转圈不动。使用这些基本的GPS单元的唯一方法是将其指向旅行和_move_ forward方向。这可能与你的问题没有关系,但? – JAL 2011-06-06 22:16:31

+0

首先感谢您的快速解答。以及传感器管理器始终应该返回磁北,GPS将返回真北,因为它使用基于真北的纬度/经度上的运动方向。至于它是一个硬件问题,这是一种可能性,但是我看到应用程序会全面返回类似的结果,并想知道如何做到这一点。我也测试过DroidX,并且结果在Droid X上有很大的不同,我的指南针图像甚至在相反的方向旋转? – ocross 2011-06-06 23:14:01

回答

3

那么经过多次测试和调试。我得出的结论是,正如你们中有些人提到我的droid 1和Nexus S是纯硬件差异和磁干扰的差异。

但是,Droid X是一个不同的问题,无论我尝试过,我无法通过getRotationMatrix和getOrientation获得正确的读数,即使添加了重新映射坐标函数。所以经过一些修补没有成功后,我觉得ID给方向传感器一个镜头。

谷歌说,这种方式已被弃用,他们建议按照我开始的方式来做,但我尝试了所有类型的组合,但没有成功。所以我继续前进,忽略了他们的警告,并使用了方向传感器......它工作。为什么?我不知道,droid x比我的droid 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

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

+0

感谢您的回应,并且您确实提出了一个关于校准的重要意见,这可以产生巨大的影响,并使指南针不可靠。不幸的是,这是我忘了提及我在测试前做过的一步(我现在编辑它)。这次我会再试一次并校准更长的时间,看看我是否看到了更好的结果。 – ocross 2011-06-06 23:26:49

31

即使笔者回答了自己的问题,我要在这里附和只是为了加强对任何几乎全然无用Android平台上的一种指南针功能。

我得出的结论是,任何依赖于Android指南针应用程序的人都在寻求麻烦,他们中的任何一个都不能可靠地工作,而且这不是开发人员的错。

谷歌和制造商根本没有提供一种方法来从这些设备获得可靠的准确性,甚至确定准确性是否可靠,甚至更糟糕,因为有时他们很多时候他们不是,如果有人相信这些真正的定向神器帮助他们。

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

首先,由磁性和方向传感器产生的噪声是可怕的,是的,这可以通过适当的DSP技术来克服,而且使用2.3和陀螺仪的手机将会获得更好的整体性,但对谷歌和制造商来说,许多开发人员用劣质的硬件和软件输出实现了时间。其次,我已经测试了至少18部具有适当DSP滤波功能的手机,虽然这样可以清除噪音,但对准确性没有帮助,即使是相同型号的手机也有不同的输出(尽管有些型号似乎比其他型号更好)

第三,对于确定传感器是否进行了校准,甚至是做痉挛状态的数字8运动可能会或可能不会校准电话,并且用户从不真正知道它是否工作,除非您有一个指南针来验证,哪种失败点不是它?

注意:您可以相互乘积和求和磁传感器,并取sqrt(x * x + y * y + z * z)的平方根并确保它在25到65之间,这个是你可以用来检测异常场的一个指标,但它不是完全可靠的,比我猜想的要好。第四,很多手机都是完全不可靠的,无论是否校准,这不仅限于模型类型,也可能是制造商方面质量低劣的问题,我真的不知道为什么,但我可以说3 HTC ARIA的生产不同的结果(一个30度关闭,另一个50度,第三个几乎发现)与令人难以置信的联系等相同的事情。

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

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

FITH,冷启动时总是要求我们测试每一个电话,其中包括X,令人难以置信,晓月的Nexus和迅雷的校准步骤。换句话说,首次启动传感器时,95%的时间需要校准步骤(即使是一个破损的时钟一天两次),所以如果您坚持添加此功能,我只会告诉您的用户在每个听众事件的开始。

如果离开运行senors(坏电池),那么你可能会或可能不会有依赖于它遇到的领域进行重新校准)上述方法工作正常了点。

底线是,当他们的工作,他们似乎很酷,但你永远目前可以肯定的方位,这使得它们非常不可靠的,无用的任何实际工作的准确性。

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

对不起,我已经浪费了将近一个月的时间,在一位专家的DSP工程师的帮助下工作,我们已经写了很多关于android平台的文章。

A“有时候这工作,其他时间也不会,你永远无法确定,除非你有一个真正的指南针”免责声明应放在在我看来,每一个指南针的应用程序。

+2

是的,我同意你的意见。我得出的结论是,你必须意识到,将有大约有好像在我的大多数设备(仅适用于6测试)读数误差±30度的余量是一个范围内围绕10 之间枝为什么我说方向传感器是修复是因为机器人X根本没有工作。当其他人靠近时有一个误差余量,并且切换到方向使X的工作与其他工作类似。降噪效果不错,但在获得价值之后,我已经在做我自己的低通滤波器了。 – ocross 2011-06-14 21:17:58

+0

@ocross我发现的是,如果传感器cfg文件被删除了偏移问题,并且重新校准问题消失了。问题是需要root访问权限,并且只是暂时的。此外,粘连问题似乎与我测试的手机上的手动校准有关,至少,懒惰-8手腕的运动是固定的。对于另一个我必须包括和抵消功能,可以“同步”到GPS轴承(速度精度必须是好的)或手动由用户。问题在于漂移随着时间的推移而发生 – Idistic 2011-07-09 20:02:25

+0

这种帖子既是祝福也是诅咒:我将依靠加速度计来确定标题(另一种不太可靠的方法),但是想知道是否切换到磁力仪的标题决心从一开始就不是一个好主意。由于我需要逐步准确地读取标题,加速度计不起作用,圆规似乎不起作用,那么剩下的是什么? GPS足够可靠吗?即使有天际线的干扰? – ravemir 2013-04-02 10:13:06