1

我知道我正在尝试使用加速度计获得设备的线性运动,但请幽默一下。

我试图找出正确的公式来获取Sensor.TYPE_LINEAR_ACCELEROMETER(我相信这是正常的加速度计数据减去重力)并基本上说“这么长时间过去了,自上次以来我已经加速了 x 量,所以我已经走了 d 量。

应该是这样的distanceTraveledOnX = linearAccerationOfX * TimePassed;

在现实世界中足够容易吧?如果我以每分钟 1 英里的速度行驶了 10 分钟,那么我已经行驶了 10 英里。速度 * 时间 = 距离

问题是我不确定linearAcceleration 使用什么度量单位。我知道我的 timePassed 是在 NanoSeconds 正如我所说的(在我的onSensorChanged

currentTime = System.nanoTime();//(double) 类型的var timePassed = currentTime - lastTime; 最后时间 = 当前时间;

有人可以帮我弄清楚将linearAcceleration值转换为nanoSecond测量的公式吗?

谢谢

编辑

这是我当前使用的代码,但我总是得到 0 :

public void onSensorChanged(SensorEvent evt) {   
 if (type == Sensor.TYPE_LINEAR_ACCELERATION) {

                        newTime = System.currentTimeMillis()/1000;
                        float oldVelocity = lastTime1-lastTime0;
                        float newVelocity = newTime- lastTime1;
                       if(oldVelocity<1)oldVelocity =1;

                        newX = lastX1 + ((lastX1 - lastX0)/oldVelocity)*newVelocity +(evt.values[0]/2)*(newVelocity*newVelocity);
                        lastX0 = lastX1;
                        lastX1 = newX;
                        lastTime0 = lastTime1;
                        lastTime1 = newTime;

                        Log.v("SENSOR MAN LINEAR", "new X:"+newX);


                    }
}
4

2 回答 2

1

这东西是高中物理,如果你不知道加速度和速度之间的区别,你需要先复习一下,然后才有希望。

我可以告诉你这么多:来自手机或平板电脑的线性加速度读数不够精确或不够准确,无法在没有不断校正的情况下(通过 gps 或其他方法)做你想做的事。有一个完整的研究领域试图解决这个问题。我参加过有关它的会议。

也就是说,您还需要考虑到设备的方向也会发生变化,除非这是某种特殊应用,例如设备被困在只能沿一个方向移动的雪橇上。

让我们假设这种情况,并假设设备被绑在您的雪橇上,设备右侧(+X 轴)与行进方向对齐。我们还假设程序启动时雪橇的初始位置是已知的(称为 X0),并且初始速度为零。

您的代码大致如下所示:

double x0;    // previous position, meters
double x;     // current position
double v0;    // previous velocity, meters/second
double v;     // current velocity
long t0;      // previous time, nanoseconds
long t;       // current time

public void onStart() {
    x0 = getInitialPosition();
    x = x0;
    v0 = 0;
    v = v;
    t0 = System.getCurrentTime() * 1000000;
    // Enable sensors; left as an exercise for the reader
}

public void onSensorChanged(SensorEvent event) {
    // Assume linear acceleration is the only active sensor
    double accel = event.values[0];   // X axis is our axis of acceleration
    t = event.timestamp;
    double dt = (t - t0) * .000001;
    v = v0 + accel * dt;
    x = x0 + v * dt;
    t0 = t;
    v0 = v;
    x0 = x;
}

这绝不是一个完整的解决方案。做这件事涉及微分方程,我没有能力在这里解释(翻译:我忘记了我在大学学到的一切)。但是,如果您的加速度值足够准确,并且您的时间片足够短,这是可行的。

如果您需要在多个方向上解决这个问题,只要设备永远不会改变方向,它只会稍微复杂一些。如果是这样,那么您还需要捕获旋转传感器并了解四元数和旋转矩阵。

即使你做的一切都正确,错误仍然会累积,所以现在你需要某种基于 GPS、已知环境几何形状的校正因子(例如,如果你在室内并且软件有建筑物的地图,它可以转弯时进行更正),以及其他环境线索,例如已知位置的 WiFi 热点。

此时您可能想阅读卡尔曼滤波器。

内容提要:这是一般情况下的HARD问题,如果你解决了,可能还有名利等着你。

于 2013-05-24T19:13:19.337 回答
0

嗯,正确的形式,从学校知道,finalXPosition = (linearAcceleration*timePassed^2)/2+ initialVelocity*timePassed+initialXPosition

finalVelocity = initialVelocity*timePassed

链接这些块你会得到你的理论值。

在实践中,通过 GPS 定期校准 initialXPosition 和 initialVelocity 可以获得最佳结果。

在 onSensorChanged 中接收校准的水平加速度的简单示例:

class Integrator {
    private float position = 0f;
    private float velocity = 0f;

    public void setGpsPosition (float gpsPosition) {
        position = gpsPosition;
    }
    public void setGpsVelocity (float gpsVelocity) {
        velocity = gpsVelocity;
    }
    public void onAccelerationChangeHandler(float acceleration, float timePassed) {
        position += acceleration*timePassed*timePassed/2f + velocity*timePassed;
        velocity += acceleration*timePassed;
    }
    public float getCurrentPosition() {
        return position;
    }
}

x 加速度的用法:

long lastTime = 0;
public void onSensorChanged(SensorEvent evt) { 
    if (evt.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
        long newTime = System.currentTimeMillis();
        OnAccelerationChangeHandler(evt.values[0], (newTime-lastTime)/1000);
        lastTime = newTime;
    }

请注意,在分钟范围之外,如果没有 gps 校正,错误会使这一切变得毫无意义。明白,如果你以恒定的速度行走,传感器根本不会给你任何东西

于 2013-05-23T20:32:13.930 回答