Mar*_*k D 10 math android accelerometer
仅使用内置加速度计的手机(Android),如何才能找到它的速度?
我一直在修补这个数学,但无论我想出什么功能都会导致速度呈指数增长.我的假设是,在应用程序启动时,手机处于静止状态.这绝对应该能够找到速度(至少粗略地).
我在物理和数学方面也有不错的背景,所以我对这里的任何概念都不会有任何困难.
我该怎么办?
首先,您必须从加速度计数据中移除由于重力引起的加速度.然后,只需要集成加速度来获得速度.不要忘记加速度和速度是正确的矢量,而不是标量,并且您还必须跟踪手机在空间中的旋转,以正确地确定加速度矢量相对于计算的速度矢量的方向.
这实际上取决于加速度和持续时间.一个温和的,长的加速度可以测量,但加速度的任何突然增加,然后是恒定的速度,将使您的测量非常困难并且容易出错.
假设恒定加速度,公式非常简单:a =(V1-V0)/ t.因此,知道时间和加速度,并假设V0 = 0,则V1 = a*t
在更现实的世界中,您可能不会有恒定的加速度,因此您应该为每次测量计算Delta V,并添加所有这些速度变化以获得最终速度.始终认为您不会有连续的加速度数据,因此这是最可行的方式(即实际数据与积分数学理论).
无论如何,即使在最佳情况下,您最终也会得到非常高的误差范围,因此我不建议将这种方法用于任何真正依赖于实际速度的应用程序.
除了同意上面所有精彩答案中提出的合理论点之外,别无他法,但是,如果您是像我这样的务实类型,我需要想出一个以某种方式起作用的解决方案。
我遇到了和你类似的问题,在网上找不到任何解决方案后,我决定自己制定解决方案。我只需要一个简单的“倾斜”输入来控制游戏,因此这个解决方案可能无法满足更复杂的需求,但是我决定分享它,以防其他人寻找类似的东西。
注意:我已将整个代码粘贴到此处,并且可以免费用于任何目的。
基本上我在代码中所做的就是寻找加速度计传感器。如果未找到,倾斜反馈将被禁用。如果存在加速度计传感器,我会寻找磁场传感器,如果存在,我会通过结合加速度计和磁场数据以推荐的方式获得倾斜角度。
public TiltSensor(Context c) {
man = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE);
mag_sensor = man.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
acc_sensor = man.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
has_mag = man.registerListener(this, mag_sensor, delay);
has_acc = man.registerListener(this, acc_sensor, delay);
if (has_acc) {
tiltAvailble = true;
if (has_mag) {
Log.d("TiltCalc", "Using accelerometer + compass.");
}
else {
Log.d("TiltCalc", "Using only accelerometer.");
}
}
else {
tiltAvailble = false;
Log.d("TiltCalc", "No acceptable hardware found, tilt not available.");
//No use in having listeners registered
pause();
}
}
Run Code Online (Sandbox Code Playgroud)
然而,如果仅存在加速度计传感器,我会回退到累积加速度,该加速度会连续阻尼(乘以 0.99)以消除任何漂移。对于我简单的倾斜需求来说,这非常有效。
@Override
public void onSensorChanged(SensorEvent e) {
final float[] vals = e.values;
final int type = e.sensor.getType();
switch (type) {
case (Sensor.TYPE_ACCELEROMETER): {
needsRecalc = true;
if (!has_mag) {
System.arraycopy(accelerometer, 0, old_acc, 0, 3);
}
System.arraycopy(vals, 0, accelerometer, 0, 3);
if (!has_mag) {
for (int i = 0; i < 3; i++) {
//Accumulate changes
final float sensitivity = 0.08f;
dampened_acc[i] += (accelerometer[i] - old_acc[i]) * sensitivity;
//Even out drift over time
dampened_acc[i] *= 0.99;
}
}
}
break;
case (Sensor.TYPE_MAGNETIC_FIELD): {
needsRecalc = true;
System.arraycopy(vals, 0, magnetic_field, 0, 3);
}
break;
}
}
Run Code Online (Sandbox Code Playgroud)
总之,我只是重复一遍,这可能在任何方面都不是“正确的”,它只是作为游戏的简单输入。要使用此代码,我只需执行如下操作(是的,魔术常量是不好的 mkay):
Ship ship = mShipLayer.getShip();
mTiltSensor.getTilt(vals);
float deltaY = -vals[1] * 2;//1 is the index of the axis we are after
float offset = ((deltaY - (deltaY / 1.5f)));
if (null != ship) {
ship.setOffset(offset);
}
Run Code Online (Sandbox Code Playgroud)
享受!
| 归档时间: |
|
| 查看次数: |
24994 次 |
| 最近记录: |