7

我有下面的代码似乎工作正常:

    // GPS Reader
    // Criteria
    Criteria criteria = new Criteria();
    //criteria.setAccuracy(Criteria.ACCURACY_COARSE); // Used when we can't get a GPS Fix
    criteria.setAccuracy(Criteria.ACCURACY_FINE); // Used when we can get a GPS Fix

    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);

    LocationListener locationListener = new MyLocationListener();
    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    lm.requestLocationUpdates(lm.getBestProvider(criteria, true), 0, 0,
            locationListener);

然而,当我在谷歌地图上绘制我收集的数据时,GPS坐标在某些情况下非常分散,或者它会沿着我正在行走的路径前进,然后突然跳到一英里外的一个点然后回来。有没有什么办法解决这一问题?我猜是某种准确性检查?

更新

基本上我的问题看起来像这样 - GPS Jitter

更新 2

我考虑过不要把这当作赏金,但我想我不妨完全了解这里发生的事情,看看我的方法是否过度杀戮。尽管我的精度为 3m 等,但我仍然遇到同样的问题,即我的坐标中有抖动。现在这可能是可用的卫星等。我不知道,但基本上我想了解如何所有这些其他应用程序,尤其是运动应用程序,是否能够在相同的情况下获得如此流畅的读数。

我在 Quora 上找到了这个是否有任何正在运行的应用程序具有过滤 GPS 数据以获得更准确跟踪的功能?不幸的是,它并没有深入了解我的问题,除非您可以根据需要使用卡尔曼滤波器,但肯定有不太复杂的方法,因为我怀疑大多数应用程序都在实现这一点。

无论如何,如果一位开发人员想分享他们正在做的一些伪代码,我们将不胜感激。我的意思是,如果我坚持使用卡尔曼,我会,但我确信必须有更容易实现的算法,并且希望学习这些以及如何实现它们,这很合适。

上下文:这是一个移动行人应用程序。

相关的 SO 问题我试图从 Create a smooth curve from a series of GPS coordinates Smooth gps data中收集信息:这是一个好的开始,虽然我不确定我需要实现什么伪代码才能正确获得最小二乘拟合正常工作,这样我就有了一个样条 GPS 数据,然后我可以在谷歌地图之类的东西上查看它,以确认我做得正确。我认为问题在于,如果这是我正在处理的一般 X 和 Y 数据,而不是 GEO 坐标,我可以在 matlab 中写一些东西来测试它,然后继续。

更新 3

我收到的混乱 GPS 数据的图像 https://www.dropbox.com/s/ilsf8snao2no65e/gpsdata2.png

代码 https://gist.github.com/4505688

4

4 回答 4

6

GPS 数据本身容易出错。即使您正确设置了所有 LocationManager(并且看起来确实如此),您也会在位置中看到偶尔的抖动。

准确性

需要注意的一件事是,GPS 精度只能让您估计接收到的 GPS 信号的计算效果。系统误差可以为您提供良好的准确度数(<10m),但仍代表较大的位置误差。这就是为什么即使您的准确度非常好,您也会看到抖动的原因。准确度测量可以很好地消除非常大的错误(>100m),但在较低的级别上,它只是给你一个计算收敛的指示。

过滤

过滤,就像很多事情一样,如果你做的越少越好。准确度过滤器应该能够消除大的错误,如果你最终得到一个好的阈值,你可能能够得到平滑的数据。

如果您对正在运行的应用程序的位置更改设置阈值,您也可能会获得一些好处。例如,跑步者只能随着时间的推移跑过一定的距离,通过设置上限(Usain Bolt Cutoff),您应该能够消除坏点。问题在于,如果您的第一点是错误,您最终会删除所有其他点。

卡尔曼滤波器

卡尔曼滤波器是一个很好的解决方案,我已经在我正在开发的导航应用程序上实现了它。结果非常合理,甚至可以在 GPS 故障或不可用的情况下进行有限的航位推算。不幸的是,我不能分享源代码,但如果你决定这样做,我可以给你一些指导。最好的结果来自 6 DoF 过滤器,您可以在其中计算加速度和速度并使用它来估计位置。这不是最简单的解决方案,但我们已经看到了很好的结果。

最小二乘

卡尔曼滤波器很棒,因为它可以实时用于过滤位置。它跟踪自己的状态,您不需要存储旧位置。但另一方面,如果您想对路线进行后处理,最小二乘拟合是一种最佳方式。(卡尔曼源自 LSQ 公式)。我没有做很多后期处理,但我怀疑我可以在上面挖掘一些旧教科书。然而,理论应该是相同的。

大多数 GPS 设备都非常好,从我所看到的所有测试中,我并不经常看到您在示例中看到的抖动。然而,我实施卡尔曼滤波器的一大优势和原因是您的行驶距离和速度计算更加准确

于 2013-01-16T18:59:50.650 回答
4

您得到的是因为您的标准将最佳提供商确定为NETWORK_PROVIDER. 它不会识别您的位置,而是为您提供覆盖您设备的手机信号塔的位置。因此,当您在任何建筑物之外时,最好使用它GPS_PROVIDER来获得精确的地理位置。为什么您会得到分散的坐标是因为您的设备进入了另一个蜂窝塔的范围,因此发生了位置跳跃。直接使用GPS_PROVIDER是您将获得的最佳解决方案。

于 2013-01-10T08:12:12.860 回答
2

查看Reto Meier 的这篇文章(包括代码)。它应该给你很多信息来思考。您至少应该设置最小距离和时间参数。

lm.requestLocationUpdates(lm.getBestProvider(criteria, true), 5000, 20,
        locationListener);

此外,您还可以组合多个提供商以获得目前可以得到的最佳坐标。祝你好运!

于 2013-01-10T08:20:37.853 回答
2

一种简单的方法是丢弃任何旧的或不准确的数据,并保持经度和纬度的运行平均值。

private static final long WILDLY_OUT = 15;
private static final long TOO_OLD = 30000;
private static final long NO_SAMPLES = 5;

double lastLocationTime;

double calclongitude(Location location, double oldLongitude) {
    double newLongitude = oldLongitude;

    if (location.getAccuracy() < WILDLY_OUT) {
        newLongitude = (NO_SAMPLES * oldLongitude + location
                .getLongitude()) / (NO_SAMPLES + 1);
        lastLocationTime = System.currentTimeMillis();
    }

    if (lastLocationTime > TOO_OLD) {
        newLongitude = location.getLongitude();
    }

    return newLongitude;
}

对纬度做同样的事情。

于 2013-01-17T01:21:10.660 回答