2

我正在尝试计算房间中 Android 手机的大致位置。我尝试了不同的方法,例如定位(在室内非常糟糕)和陀螺仪+指南针。我只需要知道步行5-10秒后的大致位置,所以我认为线性加速度的积分就足够了。我知道由于错误的传播,错误很可怕,但它可能会在我的设置中起作用。我只需要大致位置即可将相机对准 Android 手机。

我对双重积分进行了编码,但我做错了。如果手机在桌子上是静止的,则位置 (x,y,z) 总是不断增加。问题是什么?

 static final float NS2S = 1.0f / 1000000000.0f;
    float[] last_values = null;
    float[] velocity = null;
    float[] position = null;
    float[] acceleration = null;
    long last_timestamp = 0;
    SensorManager mSensorManager;
    Sensor mAccelerometer;

public void onSensorChanged(SensorEvent event) {
         if (event.sensor.getType() != Sensor.TYPE_LINEAR_ACCELERATION)
             return;

         if(last_values != null){
                float dt = (event.timestamp - last_timestamp) * NS2S;

                acceleration[0]=(float) event.values[0] - (float) 0.0188;
                acceleration[1]=(float) event.values[1] - (float) 0.00217;
                acceleration[2]=(float) event.values[2] + (float) 0.01857;

                for(int index = 0; index < 3;++index){
                    velocity[index] += (acceleration[index] + last_values[index])/2 * dt;
                    position[index] += velocity[index] * dt;
                }
            }
            else{
                last_values = new float[3];
                acceleration = new float[3];
                velocity = new float[3];
                position = new float[3];
                velocity[0] = velocity[1] = velocity[2] = 0f;
                position[0] = position[1] = position[2] = 0f;
            }
            System.arraycopy(acceleration, 0, last_values, 0, 3);
            last_timestamp = event.timestamp;
    }

这些是我在手机放在桌子上时得到的位置(没有动作)。(x,y,z) 值在增加,但手机还在。在此处输入图像描述

这些是计算每个轴的移动平均值并从每个测量值中减去后的位置。电话也还在。 在此处输入图像描述

如何改进代码或其他方法以获取房间内的大致位置?

4

3 回答 3

4

加速度计中存在不可避免的测量误差。这些是由桌子上的微小振动、制造中的缺陷等造成的。随着时间的推移,这些错误的累积会导致随机游走。这就是为什么定位系统只能通过一些过滤器使用加速度计作为定位辅助。它们仍然需要某种形式的航位推算,例如 GPS(在室内效果不佳)。

目前有大量关于室内定位系统的研究。可以利用现有基础设施的系统研究的一些领域是 WiFi 和 LED 照明定位。目前还没有明显的解决方案,但我确信我们需要一个专门的解决方案来实现准确、可靠的室内定位。

你说职位一直在增加。你的意思是 x、y 和 z 分量只会变成正数,即使在重置几次后也是如此?或者你的意思是这个位置一直从零开始漂移?

如果您在手机静止时输出原始加速度测量值,您应该会看到测量误差。将这些测量值放入 Excel 电子表格中。计算平均值和标准差。所有轴的平均值应为零。如果没有,您可以使用简单的平均过滤器在代码中消除偏差(计算运行平均值并从每个结果中减去)。标准偏差将向您显示在 N 个时间步后每个轴可以漂移多远,如 standard_deviation * sqrt(N)。这应该可以帮助您在数学上确定作为时间函数(或 N 个时间步长)的预期精度。

于 2013-07-09T18:06:11.210 回答
2

布赖恩是对的,已经部署了与基础设施一起工作的室内定位系统,您可以在(几乎)任何房间轻松找到这些系统。已证明最可靠的解决方案之一是 WiFi 指纹识别。我建议您看看 indoo.rs - www.indoo.rs - 他们是该行业的先驱,并且已经拥有相当发达的系统。

于 2013-07-10T06:27:51.337 回答
0

这可能不是最优雅或最可靠的解决方案,但就我而言,它可以达到目的。

注意在我的例子中,我在用户甚至可以进入需要室内定位的活动之前抓取一个位置。我只关心他们移动了多少的粗略估计。

我有一个传感器管理器,它根据设备方向创建一个旋转矩阵。(使用Sensor.TYPE_ROTATION_VECTOR)这显然不会让我向前、向后或左右移动,而只是设备方向。通过该设备方向,我可以很好地了解用户的方位(他们面向的方向)并使用Sensor_Step_DetectorKitKat 4.4 中可用的功能,我假设在用户面向的方向上迈出 1 米。

同样,我知道这不是完全证明或非常准确,但根据您的目的,这也可能是一个简单的解决方案..

每次检测到一个步骤,我基本上都会调用这个函数:

public void computeNewLocationByStep() {
       Location newLocal = new Location("");
       double vAngle = getBearingInDegrees(); // returns my users bearing
       double vDistance = 1 / g.kEarthRadiusInMeters; //kEarthRadiusInMeters =  6353000;
        vAngle = Math.toRadians(vAngle);

        double vLat1 = Math.toRadians(_location.getLatitude());
        double vLng1 = Math.toRadians(_location.getLongitude());

        double vNewLat = Math.asin(Math.sin(vLat1) * Math.cos(vDistance) +
                      Math.cos(vLat1) * Math.sin(vDistance) * Math.cos(vAngle));

        double vNewLng = vLng1 + Math.atan2(Math.sin(vAngle) * Math.sin(vDistance) * Math.cos(vLat1),
                              Math.cos(vDistance) - Math.sin(vLat1) * Math.sin(vNewLat));



        newLocal.setLatitude(Math.toDegrees(vNewLat));
        newLocal.setLongitude(Math.toDegrees(vNewLng));

        stepCount =0;
        _location = newLocal;

    }
于 2014-06-23T15:27:45.083 回答