流畅的 GPS 数据 [英] Smooth GPS data

查看:16
本文介绍了流畅的 GPS 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理 GPS 数据,每秒获取值并在地图上显示当前位置.问题是有时(特别是在准确度较低的情况下)值变化很大,使得当前位置在地图中的遥远点之间跳跃".

I'm working with GPS data, getting values every second and displaying current position on a map. The problem is that sometimes (specially when accuracy is low) the values vary a lot, making the current position to "jump" between distant points in the map.

我想知道一些足够简单的方法来避免这种情况.作为第一个想法,我考虑过以超过某个阈值的精度丢弃值,但我想还有其他更好的方法可以做.程序执行此操作的通常方式是什么?

I was wondering about some easy enough method to avoid this. As a first idea, I thought about discarding values with accuracy beyond certain threshold, but I guess there are some other better ways to do. What's the usual way programs perform this?

推荐答案

这里有一个简单的卡尔曼滤波器,可以用于这种情况.它来自我在 Android 设备上所做的一些工作.

Here's a simple Kalman filter that could be used for exactly this situation. It came from some work I did on Android devices.

一般卡尔曼滤波器理论都是关于向量的估计,估计的准确性由协方差矩阵表示.但是,对于估计 Android 设备上的位置,一般理论简化为一个非常简单的情况.Android 位置提供程序以纬度和经度的形式给出位置,以及以米为单位的单个数字指定的精度.这意味着卡尔曼滤波器的精度可以用一个数字来衡量,而不是协方差矩阵,即使卡尔曼滤波器中的位置是用两个数字来衡量的.此外,纬度、经度和米实际上都是不同的单位这一事实可以忽略不计,因为如果您将缩放因子放入卡尔曼滤波器以将它们全部转换为相同的单位,那么在转换结果时这些缩放因子最终会被抵消回到原来的单位.

General Kalman filter theory is all about estimates for vectors, with the accuracy of the estimates represented by covariance matrices. However, for estimating location on Android devices the general theory reduces to a very simple case. Android location providers give the location as a latitude and longitude, together with an accuracy which is specified as a single number measured in metres. This means that instead of a covariance matrix, the accuracy in the Kalman filter can be measured by a single number, even though the location in the Kalman filter is a measured by two numbers. Also the fact that the latitude, longitude and metres are effectively all different units can be ignored, because if you put scaling factors into the Kalman filter to convert them all into the same units, then those scaling factors end up cancelling out when converting the results back into the original units.

代码可以改进,因为它假定当前位置的最佳估计是最后一个已知位置,如果有人在移动,应该可以使用 Android 的传感器产生更好的估计.该代码有一个自由参数 Q,以米每秒表示,它描述了在没有任何新位置估计的情况下精度衰减的速度.较高的 Q 参数意味着精度衰减得更快.卡尔曼滤波器通常在精度下降得比预期快一点时效果更好,因此对于使用 Android 手机四处走动,我发现 Q=3 米/秒可以正常工作,尽管我通常走得比这慢.但如果乘坐高速汽车,显然应该使用更大的数字.

The code could be improved, because it assumes that the best estimate of current location is the last known location, and if someone is moving it should be possible to use Android's sensors to produce a better estimate. The code has a single free parameter Q, expressed in metres per second, which describes how quickly the accuracy decays in the absence of any new location estimates. A higher Q parameter means that the accuracy decays faster. Kalman filters generally work better when the accuracy decays a bit quicker than one might expect, so for walking around with an Android phone I find that Q=3 metres per second works fine, even though I generally walk slower than that. But if travelling in a fast car a much larger number should obviously be used.

public class KalmanLatLong {
    private final float MinAccuracy = 1;

    private float Q_metres_per_second;    
    private long TimeStamp_milliseconds;
    private double lat;
    private double lng;
    private float variance; // P matrix.  Negative means object uninitialised.  NB: units irrelevant, as long as same units used throughout

    public KalmanLatLong(float Q_metres_per_second) { this.Q_metres_per_second = Q_metres_per_second; variance = -1; }

    public long get_TimeStamp() { return TimeStamp_milliseconds; }
    public double get_lat() { return lat; }
    public double get_lng() { return lng; }
    public float get_accuracy() { return (float)Math.sqrt(variance); }

    public void SetState(double lat, double lng, float accuracy, long TimeStamp_milliseconds) {
        this.lat=lat; this.lng=lng; variance = accuracy * accuracy; this.TimeStamp_milliseconds=TimeStamp_milliseconds;
    }

    /// <summary>
    /// Kalman filter processing for lattitude and longitude
    /// </summary>
    /// <param name="lat_measurement_degrees">new measurement of lattidude</param>
    /// <param name="lng_measurement">new measurement of longitude</param>
    /// <param name="accuracy">measurement of 1 standard deviation error in metres</param>
    /// <param name="TimeStamp_milliseconds">time of measurement</param>
    /// <returns>new state</returns>
    public void Process(double lat_measurement, double lng_measurement, float accuracy, long TimeStamp_milliseconds) {
        if (accuracy < MinAccuracy) accuracy = MinAccuracy;
        if (variance < 0) {
            // if variance < 0, object is unitialised, so initialise with current values
            this.TimeStamp_milliseconds = TimeStamp_milliseconds;
            lat=lat_measurement; lng = lng_measurement; variance = accuracy*accuracy; 
        } else {
            // else apply Kalman filter methodology

            long TimeInc_milliseconds = TimeStamp_milliseconds - this.TimeStamp_milliseconds;
            if (TimeInc_milliseconds > 0) {
                // time has moved on, so the uncertainty in the current position increases
                variance += TimeInc_milliseconds * Q_metres_per_second * Q_metres_per_second / 1000;
                this.TimeStamp_milliseconds = TimeStamp_milliseconds;
                // TO DO: USE VELOCITY INFORMATION HERE TO GET A BETTER ESTIMATE OF CURRENT POSITION
            }

            // Kalman gain matrix K = Covarariance * Inverse(Covariance + MeasurementVariance)
            // NB: because K is dimensionless, it doesn't matter that variance has different units to lat and lng
            float K = variance / (variance + accuracy * accuracy);
            // apply K
            lat += K * (lat_measurement - lat);
            lng += K * (lng_measurement - lng);
            // new Covarariance  matrix is (IdentityMatrix - K) * Covarariance 
            variance = (1 - K) * variance;
        }
    }
}

这篇关于流畅的 GPS 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆