ocr*_*oss 10 android sensor android-sensors compass-geolocation
在过去的几天里,我一直在研究小型指南针应用程序,并且已经启动并运行了代码,但似乎指南针读数不准确.在校准了两部手机之后,我第一次测试了我发现这个,我只是把手机靠在平面上,看着读数然后水平翻转并将它放在同一平面上(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();
}
}
Run Code Online (Sandbox Code Playgroud)
并创建我的活动代码
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);
Run Code Online (Sandbox Code Playgroud)
提前致谢!
编辑:也用droid X尝试了最差的结果......当手机滚动45度左右(围绕z轴旋转一个计算机坐标系)时,返回的罗盘标题可以改变超过180度,实际上是标题值当朝同一方向旋转时,其他手机的方向相反.即使在设置中校准后,这也是唯一产生此结果的手机.他们是一个指南针动态壁纸我测试反对,没有相同的问题.所以我认为我可以在软件中做些什么来避免这种情况.
Idi*_*tic 33
即使作者回答了他自己的问题,我也必须在这里加入,以加强Android平台上任何类型指南针功能的几乎完全无用.
我得出的结论是,依赖Android指南针应用程序的任何人都会遇到麻烦,它们都不能可靠地运行,这不是开发人员的错.
谷歌和制造商只是没有提供从这些设备获得可靠准确度的方法,甚至没有提供确定准确性是否可靠的方法甚至更糟,因为有时他们是,而且很多时候他们不是,如果有人信任这些设备进行真正的定向运动上帝帮助他们.
作者可能认为他获得更好结果的原因是他们在弃用的方向传感器上使用了一个非常好的噪声滤波器(为什么他们不能在新的方法上做到这一点超出我),并且在校准后对单个器件进行有限的测试这似乎有效,但在使用许多设备的领域,我发现在大多数情况下,可靠性总是存在问题.
首先,磁性和方向传感器产生的噪音是可怕的,是的,这可以通过适当的DSP技术克服,并且使用2.3和陀螺仪的手机它将会变得更好整体,但是谷歌和制造商因为浪费了大量的开发人员时间而感到羞耻硬件和软件输出的劣质实现.
其次,我已经测试了至少18部具有适当DSP过滤功能的手机,虽然这样可以清除噪音,但对于精确度没有帮助,即使同一型号的手机也有不同的输出(尽管有些型号看起来比其他型号好)
第三,你几乎没有办法确定传感器是否经过校准,即使做了痉挛的数字8运动可能会或可能不会校准手机,用户从来不知道它是否正常工作,除非你有一个指南针来验证,那种失败点不是吗?
注意:您可以将磁传感器相互乘以和求和,并取该sqrt的平方根(x*x + y*y + z*z),并确保它在25到65左右,这是一个指标你可以用来检测异常场,但它不是完全可靠的,比我想的更好.
第四,许多手机完全不可靠,无法校准或不校准,不仅限于型号类型,但可能是制造商的劣质QA,我真的不知道为什么,但我可以说3 HTC ARIA产生了截然不同的结果(一个30度的关闭,另外50个,第三个几乎点在同一个东西与令人难以置信,nexus等.
我测试了18部手机,其中许多非常接近准确如果你能正确校准,但其中许多需要2-10次尝试(我们在每次校准尝试后使用高精度指南针进行验证)并且超过几次他们根本不校准一点都不
注意:你必须考虑真正北偏移的偏角,你可以使用Android中的API,如果你可以访问当前的GPS坐标,海拔高度,一天中的时间等等.问题不是赤纬,如果你是与指南针相比,这不是一个问题,因为它也会受到局部磁场的影响.
Fith,冷启动总是需要我们测试的每部手机上的校准步骤,其中包括X,令人难以置信的,Aria,Nexus和Thunderbolt.换句话说,第一次启动传感器监听95%的时间它需要一个校准步骤(即使每天两次破坏时钟也是如此)所以如果你坚持添加这个功能,我会告诉你的用户在每个监听器事件的开始.
如果您让传感器继续运行(对电池不利),那么您可能需要或可能不需要重新校准,具体取决于遇到的字段)上述方法可以正常工作.
底线是,当他们的工作,他们似乎很酷,但你永远目前可以肯定的方位,这使得它们非常不可靠的,无用的任何实际工作的准确性.
个人我会在移动时使用GPS轴承,然后在可能的情况下使用旋转矢量方法,它可能不是完美的但是它比你在当前的方位角电话线中所拥有的那些更好的实现要好得多.
对于冗长的回复感到抱歉,但是我已经浪费了将近一个月的时间,试图在专家DSP工程师的帮助下使用它,我们已经在这方面编写了很多有用的android平台.
"有时候这种情况有效,有时情况不会,除非你有真正的指南针,否则你永远无法确定"在我看来,应该在每个罗盘应用程序中放置免责声明.
经过大量测试和调试后。我得出的结论是,是的,正如你们中的一些人提到的,我的 droid 1 和 Nexus S 之间的差异纯粹是硬件差异和磁干扰。
然而,Droid X 是一个不同的问题,无论我尝试什么,即使添加了重新映射坐标功能,我也无法通过 getRotationMatrix 和 getOrientation 的推荐方式获得正确的读数。因此,经过一番修补但没有成功后,我想尝试一下方向传感器。
谷歌表示这种方式已被弃用,他们建议按照我开始的方式进行操作,但是我尝试了这种方式的所有类型的组合,但没有成功。所以我继续忽略他们的警告并使用方向传感器......并且它起作用了。为什么 ?我不知道,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();
}
Run Code Online (Sandbox Code Playgroud)
并初始化传感器监听器
mSMngr.registerListener(mSListener,mSMngr.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_NORMAL);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12027 次 |
| 最近记录: |