如何仅使用加速度计找到速度?

时间:2011-05-22 01:59:56

标签: android math accelerometer

仅使用内置加速度计的手机(Android),如何才能找到速度?

我一直在修补这个数学,但无论我想出什么功能都会导致速度呈指数增长。我的假设是,在应用程序启动时,手机处于静止状态。这绝对应该能够找到速度(至少粗略)。

我在物理和数学方面也有不错的背景,所以我对这里的任何概念都不会有任何困难。

我该怎么做?

8 个答案:

答案 0 :(得分:7)

首先,您必须从加速度计数据中移除重力引起的加速度。然后,只需要集成加速度来获得速度。不要忘记加速度和速度是正确的矢量,而不是标量,并且您还必须跟踪手机在空间中的旋转,以正确地确定加速度矢量相对于计算的速度矢量的方向。

答案 1 :(得分:7)

这实际上取决于加速度和持续时间。一个温和的,长的加速度是可以测量的,但加速度的任何突然增加,然后是恒定的速度,将使您的测量非常困难并且容易出错。

假设恒定加速度,公式非常简单:a =(V1-V0)/ t。因此,知道时间和加速度,并假设V0 = 0,则V1 = a * t

在更现实的世界中,您可能不会有恒定的加速度,因此您应该为每次测量计算Delta V,并添加所有这些速度变化以获得最终速度。一直认为你不会有连续的加速度数据,所以这是最可行的方法(即真实数据与积分数学理论)。

无论如何,即使在最好的情况下,你最终会得到一个非常高的误差范围,因此我不建议任何真正依赖于真实速度的应用程序采用这种方法。

答案 2 :(得分:4)

没有别的事可做但只是同意上面所有伟大答案中提出的合理论据,但如果你是像我这样务实的类型,我需要想出一个能以某种方式运作的解决方案。

我遇到了类似的问题,我决定在找不到任何联机后自行解决问题。我只需要一个简单的“倾斜”输入来控制游戏,所以这个解决方案可能无法满足更复杂的需求,但我决定分享它以防其他人寻找类似的东西。

注意:I have pasted my entire code here,可以出于任何目的免费使用。

基本上我在代码中所做的就是寻找加速计传感器。如果未找到,则将禁用倾斜反馈。如果存在加速计传感器,我会寻找磁场传感器,如果它存在,我会通过结合加速度计和磁场数据来推荐我的倾斜角度。

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();
    }
}

然而,如果仅存在加速计传感器,我会回退累积加速度,即连续阻尼(乘以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;
    }
}

总之,我只想重复一遍,这可能不是“正确”的任何方式,它只是作为游戏的简单输入。要使用此代码,我只需执行以下操作(是的魔术常量是糟糕的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);
}

Enjoi!

答案 3 :(得分:2)

集成加速度来获得速度是一个不稳定的问题,你的错误会在几秒钟之后发散。手机加速度计也不是很准确,这没有帮助,其中一些不允许你轻易区分倾斜和平移,在这种情况下你真的遇到了麻烦。

答案 4 :(得分:2)

手机中的加速度计对于这样的任务来说几乎没用。您需要具有极低漂移的高精度加速度计 - 这远远超出您在手机中所能找到的效果。在最好的情况下,您可能会在几秒钟内获得有用的结果,或者如果非常幸运一两分钟,结果就会变得毫无意义。

此外,您需要一个三轴陀螺仪,您可以使用它来将速度整合到正确的方向。有些手机有陀螺仪,但就漂移和精度而言,它们甚至比加速度计更差。

尽管如此,一个可能有用的应用是将加速度计与陀螺仪或磁罗盘一起使用以填充来自GPS的缺失数据。每次GPS提供良好的修复时,将重置位置,速度和方向的初始条件,并且加速度计将提供数据,直到下一次有效的GPS修复。

答案 5 :(得分:2)

重力会破坏你的所有测量。手机处于静止状态时,正在经历一个高的恒定向上(是,UP)加速度。加速度计无法区分加速度和重力(技术上,它们是相同的),所以它会在几秒钟后达到极高的速度。 如果你从不稍微倾斜你的加速度计,那么你可以简单地从z轴(或任何一个指向上/下的轴)减去恒定的重力拉力,但这是不太可能的。

基本上,您必须使用复杂的陀螺仪/磁力计和加速计系统来计算精确的重力方向,然后减去加速度。

答案 6 :(得分:1)

v =积分(a)?

一般来说,我认为加速度计中的不准确会使这非常困难

答案 7 :(得分:-2)

如果手机处于静止状态,则表示您的ZERO加速度为零,因此您的速度为0.您可能应该从GPS中找到位置数据并获取相关的时间样本并计算一段时间内的速度距离。