是否可以使用加速度计和磁力计跟踪手机位置?

时间:2017-08-16 17:24:59

标签: android math android-sensors

我想在用户手中跟踪手机的移动。

鉴于必须在手机静止时启动应用程序的条件,我想跟踪手机相对于应用程序启动时手机所处位置的位置。我正在使用手机的方向和我从加速度计读取的值。

这是我尝试使用的一些代码。我正在使用我从磁力计和加速度计值得到的旋转矩阵将加速度计传感器值(相对于手机屏幕)转换为地球坐标系(相对于北极)。然后我整合加速度值以获得速度,然后整合速度值以获得位置。

我不确定我的代码是否存在问题,或者传感器的错误是否很大。任何建议将不胜感激。

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        mGravity = event.values.clone();
    }
    else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        mGeomagnetic = event.values.clone();
    }
    else if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
        mAcceleration[0] = event.values[0];
        mAcceleration[1] = event.values[1];
        mAcceleration[2] = event.values[2];
        mAcceleration[3] = 0;
    }

    if (mGeomagnetic != null &&
            mGravity != null &&
            event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
        // mRotationMatrix and mInclinationMatrix are outputs
        SensorManager.getRotationMatrix(mRotationMatrix, mInclinationMatrix, mGravity, mGeomagnetic);

        // mOrientation is output matrix
        SensorManager.getOrientation(mRotationMatrix, mOrientation);

        // mRotationMatrixInverse is output matrix
        Matrix.invertM(mRotationMatrixInverse, 0, mRotationMatrix, 0);

        // mAccelerationEarthRelative is output matrix
        Matrix.multiplyMV(mAccelerationEarthRelative, 0, mRotationMatrixInverse, 0, mAcceleration, 0);

        long currTimestamp = event.timestamp;

        if (lastTimestamp == -1) {
            lastTimestamp = currTimestamp;
            return;
        }

        // timestamps are in nanoseconds
        long timeDeltaNs = (currTimestamp - lastTimestamp);
        float timeDelta = timeDeltaNs * 0.000000001f;

        lastTimestamp = currTimestamp;

        mSpeed[0] += mAccelerationEarthRelative[0] * timeDelta;
        mSpeed[1] += mAccelerationEarthRelative[1] * timeDelta;
        mSpeed[2] += mAccelerationEarthRelative[2] * timeDelta;

        mPosition[0] += mSpeed[0] * timeDelta;
        mPosition[1] += mSpeed[1] * timeDelta;
        mPosition[2] += mSpeed[2] * timeDelta;

        mTextView.setText(String.format(
                "AZM: %+05.2f PTC: %+05.2f ROL: %+05.2f\n\n" +
                "ACC:\n  X: %+05.2f  Y: %+05.2f  Z: %+05.2f\n\n" +
                "SPD:\n  X: %+05.2f  Y: %+05.2f  Z: %+05.2f\n\n" +
                "POS:\n  X: %+05.2f  Y: %+05.2f  Z: %+05.2f\n\n",
                mOrientation[0] * 57.2957795,
                mOrientation[1] * 57.2957795,
                mOrientation[2] * 57.2957795,
                mAccelerationEarthRelative[0],
                mAccelerationEarthRelative[1],
                mAccelerationEarthRelative[2],
                mSpeed[0], mSpeed[1], mSpeed[2],
                mPosition[0], mPosition[1], mPosition[2]
        ));
    }
}

为了给我正在构建的内容提供更多上下文 - 我正在尝试创建一个AR应用程序,它可以在相机输入的顶部渲染3D对象,就好像它们存在于实际场景中一样。我的想法是使用传感器跟踪空间中的手机位置,并相应地在3D场景中移动相机。

0 个答案:

没有答案