Voici un simple filtre de Kalman qui pourrait être utilisé pour exactement cette situation. Il est venu de quelques travaux que j'ai réalisés sur les appareils Android.
Générale filtre de Kalman théorie est tout au sujet des estimations pour les vecteurs, avec la précision des estimations représentés par des matrices de covariance. Toutefois, pour l'estimation d'emplacement sur les appareils Android, la théorie générale se réduit à un cas très simple. Android localisation des fournisseurs de donner l'emplacement de la latitude et de la longitude, avec une précision qui est spécifié comme un numéro unique mesuré en mètres. Cela signifie qu'au lieu de la matrice de covariance, la précision dans le filtre de Kalman peut être mesurée par un numéro unique, même si l'emplacement dans le filtre de Kalman est mesurée par deux nombres. Aussi le fait que la latitude, la longitude et la m sont de manière efficace toutes les différentes unités peuvent être ignorés, parce que si vous mettez des facteurs d'échelle dans le filtre de Kalman pour les convertir dans les mêmes unités, alors que ces facteurs d'échelle fin jusqu'à l'annulation lors de la conversion des résultats dans les unités d'origine.
Le code pourrait être améliorée, car elle suppose que la meilleure estimation de l'emplacement actuel est le dernier emplacement connu, et si quelqu'un se déplace, il devrait être possible d'utiliser Android capteurs pour produire une meilleure estimation. Le code a un seul paramètre libre Q, exprimée en mètres par seconde), qui décrit la façon dont rapidement la précision se désintègre en l'absence de nouvelles estimations de localisation. Plus Q paramètre signifie que la précision se désintègre rapidement. Filtres de Kalman fonctionnent généralement mieux lorsque la précision de désintégrations un peu plus rapide que l'on pourrait attendre, donc, pour se promener avec un téléphone Android, je trouve que Q=3 mètres par seconde travaille très bien, même si en général je marche plus lentement que. Mais si vous voyagez dans une voiture rapide, un plus grand nombre doit évidemment être utilisé.
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;
}
}
}