Android 指南针方向不可靠(低通滤波器)
我正在创建一个应用程序,我需要根据设备的方向定位 ImageView。 我使用磁场和加速度传感器的值来计算设备方向。
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerValues, magneticFieldValues)
SensorManager.getOrientation(rotationMatrix, values);
double degrees = Math.toDegrees(values[0]);
我的问题是 ImageView 的定位对方向的变化非常敏感。使图像视图不断地在屏幕上跳跃。 (因为度数发生变化)
我读到这可能是因为我的设备靠近可能影响磁场读数的物体。但这似乎并不是唯一的原因。
我尝试下载一些应用程序,发现“3D 指南针< /a>”和“Compass”仍然非常稳定在其读数中(设置噪声滤波器时),我希望在我的应用程序中具有相同的行为。
我读到我可以通过添加“低通滤波器”来调整读数的“噪音”,但我不知道如何实现这一点(因为我缺乏数学)。
我希望有人可以帮助我在我的设备上创建更稳定的读数,设备的轻微移动不会影响当前方向。 现在我做了一个小的
if (Math.abs(lastReadingDegrees - newReadingDegrees) > 1) { updatePosition() }
过滤噪音的工作。但它的效果不是很好:)
Im creating an application where i need to position a ImageView depending on the Orientation of the device.
I use the values from a MagneticField and Accelerometer Sensors to calculate the device orientation with
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerValues, magneticFieldValues)
SensorManager.getOrientation(rotationMatrix, values);
double degrees = Math.toDegrees(values[0]);
My problem is that the positioning of the ImageView is very sensitive to changes in the orientation. Making the imageview constantly jumping around the screen. (because the degrees change)
I read that this can be because my device is close to things that can affect the magneticfield readings. But this is not the only reason it seems.
I tried downloading some applications and found that the "3D compass" and "Compass" remains extremely steady in its readings (when setting the noise filter up), i would like the same behavior in my application.
I read that i can tweak the "noise" of my readings by adding a "Low pass filter", but i have no idea how to implement this (because of my lack of Math).
Im hoping someone can help me creating a more steady reading on my device, Where a little movement to the device wont affect the current orientation.
Right now i do a small
if (Math.abs(lastReadingDegrees - newReadingDegrees) > 1) { updatePosition() }
To filter abit of the noise. But its not working very well :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
虽然我没有在 Android 上使用过指南针,但下面显示的基本处理(在 JavaScript 中)可能适合您。
它基于 Windows Phone 团队进行了修改以适应指南针(每 360 度循环一次),
我假设指南针读数以度为单位,在 0-360 之间浮动,并且输出应该。类似,
你想在过滤器中完成两件事:
为此,我们将有 2 个常量:
我们在调用过程中保存了一个变量,一个名为 oldCompass 的浮点数,它是算法的结果。
所以变量定义是:
函数接收 newCompass,并返回 oldCompass 作为结果。
我发现该问题是 5 个月前提出的,可能不再相关,但我确信其他程序员可能会发现它有用。
奥德·埃利亚达.
Though I havn't used the compass on Android, the basic processing shown below (in JavaScript) will probably work for you.
It's based on the low pass filter on the accelerometer that's recommended by the Windows Phone team with modifications to suit a compass (the cyclic behavior every 360").
I assume the compass reading is in degrees, a float between 0-360, and the output should be similar.
You want to accomplish 2 things in the filter:
For that we will have 2 constants:
We have one variable saved across the calls, a float called oldCompass and it is the result of the algorithm.
So the variable defenition is:
and the function recieves newCompass, and returns oldCompass as the result.
I see that the issue was opened 5 months ago and probably isn't relevant anymore, but I'm sure other programmers might find it useful.
Oded Elyada.
该低通滤波器适用于以弧度为单位的角度。对每个罗盘读数使用add函数,然后调用average来获取平均值。
使用
Math.toDegrees()
或Math.toRadians()
进行转换。This lowpass filter works for angles in radians. Use the add function for each compass reading, then call average to get the average.
Use
Math.toDegrees()
orMath.toRadians()
to convert.请记住,例如 350 和 10 的平均值不是 180。我的解决方案:
Keep in mind that, for example the average of 350 and 10 is not 180. My solution:
低通滤波器 (LPF) 阻止快速变化的信号并
只允许信号缓慢变化。这意味着任何小的
突然的变化将被忽略。
在软件中实现这一点的标准方法是获取运行平均值
最后 N 个样本并报告该值。从 N 小至 3 开始,
继续增加 N,直到您在应用程序中找到足够的平滑响应。
请记住,N 越高,系统的响应就越慢。
A low pass filter (LPF) blocks fast changing signals and
allows only slow changes in the signals. This means any small
sudden changes will be ignored.
The standard way to implement this in software is to take a running average
of the last N samples and report that value. Start with N as small as 3 and
keep increasing N until you find sufficient smoothed out response in your app.
Do keep in mind that the higher you make N, slower the response of the system.
请参阅我对此相关问题的回答:平滑来自传感器的数据
软件低通滤波器基本上是其修改版本。事实上,在那个答案中,我什至提供了另一个相关问题的链接:低通滤波器软件?
See my answer to this related question: Smoothing data from a sensor
A software low pass filter is basically a modified version of that. Indeed, in that answer I even provided this link to another related question: Low pass filter software?