Android:加速度计错误检测
我有一个代码片段来检测加速度计的运动。有时它可以通过正确检测轻微的运动来工作,但有时当我保持设备空闲时它也会检测到运动。 Android 上的内置加速度计检测是否存在问题?
我使用 HTC G-1 设备。我的代码片段如下。如何解决这个问题,以便我可以检测到设备的微小移动,但在设备空闲时检测不到任何内容?
private static final int SHAKE_THRESHOLD = 50;
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
long curTime = System.currentTimeMillis();
long diff = (curTime - shakeTime);
shakeTime = curTime;
if (myFlagIgnoreShakeDetection==true) //Caused unneccessary accelerometer
//notification looping when device is idle
return;
// Doing something...
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
I have a code snippet to detect accelerometer movements. It works some times by properly detecting slight movements, but sometimes it detects movements when I kept my device idle too. Are there any problems with built-in accelerometer detection on Android?
I use an HTC G-1 device. My code snippet is below. How do I resolve it so I can detect small device movements but not detect anything when the device is idle?
private static final int SHAKE_THRESHOLD = 50;
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
long curTime = System.currentTimeMillis();
long diff = (curTime - shakeTime);
shakeTime = curTime;
if (myFlagIgnoreShakeDetection==true) //Caused unneccessary accelerometer
//notification looping when device is idle
return;
// Doing something...
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下是一些代码差异...
last_x
、last_y
和last_z
的更新可能存在问题。我相信它们应该包含在if ((curTime - lastUpdate) > 100) {
语句内内部。换句话说,每次调用onSensorChanged
时它们都会更新,而不是每 100 毫秒更新一次。您可能应该将这三个变量的更新移动到它们上方的大括号中。在计算
速度
的行上,公式以... / diffTime * 10000;
结尾,您是否只想乘以diffTime
code> 乘以 10000,还是整个结果?由于/
和*
通常具有相同的 运算符优先级 在我所知道的大多数语言中(例如 Java< /a>),您的方程将从左到右计算,首先除以diffTime
然后将该结果乘以 10000。我猜您的意思是将
diffTime
乘以 10000,从而将最终结果除以该值。这是除以 10000 或乘以 10000 之间的差异,这意味着您获得的速度
值可能比应有的值大 10^8,因此即使在设备空闲时也会触发您的阈值。您需要在乘法两边加上括号,例如... / (diffTime * 10000);
,以确保它在除法发生之前执行。此外,如果您打算将
diffTime
从毫秒缩放到秒,则比例因子应为 1000。Here are a few code discrepancies...
There may be a problem regarding the updating of
last_x
,last_y
, andlast_z
. I believe they should be included inside theif ((curTime - lastUpdate) > 100) {
statement. In other words, they are being updated every timeonSensorChanged
is called, not every 100 milliseconds. You should probably move the updating of those three variables into the curly brace above them.On the line where you compute the
speed
, the formula ends with... / diffTime * 10000;
Are you wanting to multiply justdiffTime
by 10000, or the entire result? Since/
and*
typically have the same operator precedence in most languages I know of (such as Java), your equation will be evaluated from left to right, dividing first bydiffTime
then multiplying that result by 10000.I'm guessing you mean to multiply just
diffTime
by 10000, thus dividing the final result by that amount. This is the difference between dividing by 10000 or multiplying by 10000, which means you are probably getting values forspeed
that are 10^8 greater than you should, thus tripping your threshold even when the device is idle. You need to put parentheses around the multiplication, like... / (diffTime * 10000);
, to make sure it's performed before the division takes place.Additionally, if you are intending to scale
diffTime
from milliseconds to seconds, your scale factor should be 1000.我个人在我的增强现实库中使用滚动平均值进行更新:
这往往可以很好地平滑数据,并且您可以调整过滤因子以获得您想要的响应能力。
rawZValue 是来自加速度计的原始值。
I personally, in my augmented reality library, use a rolling average for the updates:
This tends to smooth out the data pretty well, and you can tweak the filtering factor to get the responsiveness you want.
rawZValue is the raw value coming in from the accelerometer.