Ich arbeite mit GPS-Daten, erhalte jede Sekunde Werte und zeige die aktuelle Position auf einer Karte an. Das Problem ist, dass manchmal (besonders wenn die Genauigkeit niedrig ist) die Werte stark variieren, wodurch die aktuelle Position zwischen entfernten Punkten in der Karte "springt".
Ich habe mich über eine Methode gewundert, die einfach genug ist, um dies zu vermeiden. Als erste Idee habe ich darüber nachgedacht, Werte mit einer Genauigkeit über einen bestimmten Schwellenwert hinaus zu verwerfen, aber ich denke, es gibt einige andere bessere Möglichkeiten. Wie führen Programme dies normalerweise durch?
Antworten:
Hier ist ein einfacher Kalman-Filter, der genau für diese Situation verwendet werden kann. Es kam von einer Arbeit, die ich auf Android-Geräten gemacht habe.
In der allgemeinen Kalman-Filtertheorie dreht sich alles um Schätzungen für Vektoren, wobei die Genauigkeit der Schätzungen durch Kovarianzmatrizen dargestellt wird. Für die Standortschätzung auf Android-Geräten reduziert sich die allgemeine Theorie jedoch auf einen sehr einfachen Fall. Android-Standortanbieter geben den Standort als Breiten- und Längengrad sowie eine Genauigkeit an, die als einzelne Zahl in Metern angegeben wird. Dies bedeutet, dass anstelle einer Kovarianzmatrix die Genauigkeit im Kalman-Filter durch eine einzelne Zahl gemessen werden kann, obwohl die Position im Kalman-Filter durch zwei Zahlen gemessen wird. Auch die Tatsache, dass Breite, Länge und Meter effektiv alle unterschiedliche Einheiten sind, kann ignoriert werden, denn wenn Sie Skalierungsfaktoren in den Kalman-Filter einfügen, um sie alle in dieselben Einheiten umzuwandeln,
Der Code könnte verbessert werden, da davon ausgegangen wird, dass die beste Schätzung des aktuellen Standorts der letzte bekannte Standort ist. Wenn sich jemand bewegt, sollte es möglich sein, die Sensoren von Android zu verwenden, um eine bessere Schätzung zu erstellen. Der Code hat einen einzelnen freien Parameter Q, ausgedrückt in Metern pro Sekunde, der beschreibt, wie schnell die Genauigkeit abnimmt, wenn keine neuen Standortschätzungen vorliegen. Ein höherer Q-Parameter bedeutet, dass die Genauigkeit schneller abnimmt. Kalman-Filter funktionieren im Allgemeinen besser, wenn die Genauigkeit etwas schneller abnimmt als erwartet. Wenn ich also mit einem Android-Telefon herumlaufe, funktioniert Q = 3 Meter pro Sekunde einwandfrei, obwohl ich im Allgemeinen langsamer gehe. Aber wenn Sie in einem schnellen Auto fahren, sollte natürlich eine viel größere Anzahl verwendet werden.
quelle
Q_metres_per_second
entspricht der Variablensigma
im Abschnitt "Verwandte Prozesse" in diesem Wikipedia-Artikel.Q_metres_per_second
ist eine Standardabweichung und wird in Metern gemessen, daher sind Meter und nicht Meter / Sekunden die Einheiten. Sie entspricht der Standardabweichung der Verteilung nach Ablauf von 1 Sekunde.Was Sie suchen, wird als Kalman-Filter bezeichnet . Es wird häufig verwendet, um Navigationsdaten zu glätten . Es ist nicht unbedingt trivial und es gibt eine Menge Tuning, die Sie durchführen können, aber es ist ein sehr Standardansatz und funktioniert gut. Es ist eine KFilter-Bibliothek verfügbar, bei der es sich um eine C ++ - Implementierung handelt.
Mein nächster Fallback wäre die Anpassung der kleinsten Quadrate . Ein Kalman-Filter glättet die Daten unter Berücksichtigung von Geschwindigkeiten, während bei einem Ansatz zur Anpassung der kleinsten Quadrate nur Positionsinformationen verwendet werden. Dennoch ist es definitiv einfacher zu implementieren und zu verstehen. Es sieht so aus, als ob die GNU Scientific Library eine Implementierung davon haben könnte.
quelle
Dies könnte etwas spät kommen ...
Ich habe diesen KalmanLocationManager für Android geschrieben, der die beiden gängigsten Standortanbieter, Netzwerk und GPS, zusammenfasst, die Daten kalmanfiltert und Updates an a liefert
LocationListener
(wie die beiden "echten" Anbieter).Ich benutze es meistens, um zwischen den Messwerten zu "interpolieren" - um beispielsweise alle 100 Millis Aktualisierungen (Positionsvorhersagen) zu erhalten (anstelle der maximalen GPS-Rate von einer Sekunde), was mir eine bessere Bildrate beim Animieren meiner Position gibt.
Tatsächlich werden drei Kalman-Filter für jede Dimension verwendet: Breite, Länge und Höhe. Sie sind sowieso unabhängig.
Dies macht die Matrixmathematik viel einfacher: Anstatt eine 6x6-Zustandsübergangsmatrix zu verwenden, verwende ich 3 verschiedene 2x2-Matrizen. Eigentlich verwende ich im Code überhaupt keine Matrizen. Alle Gleichungen und alle Werte sind Primitive (doppelt) gelöst.
Der Quellcode funktioniert und es gibt eine Demo-Aktivität. Entschuldigung für den Mangel an Javadoc an einigen Stellen, ich werde aufholen.
quelle
Sie sollten die Geschwindigkeit nicht aus der Positionsänderung pro Zeit berechnen. GPS hat möglicherweise ungenaue Positionen, aber eine genaue Geschwindigkeit (über 5 km / h). Verwenden Sie also die Geschwindigkeit vom GPS-Positionsstempel. Und außerdem sollten Sie das natürlich nicht tun, obwohl es meistens funktioniert.
Die gelieferten GPS-Positionen sind bereits Kalman-gefiltert. Sie können sie wahrscheinlich nicht verbessern. Bei der Nachbearbeitung haben Sie normalerweise nicht die gleichen Informationen wie beim GPS-Chip.
Sie können es glätten, dies führt jedoch auch zu Fehlern.
Stellen Sie einfach sicher, dass Sie die Positionen entfernen, wenn das Gerät stillsteht. Dadurch werden Sprungpositionen entfernt, die einige Geräte / Konfigurationen nicht entfernen.
quelle
Normalerweise benutze ich die Beschleunigungsmesser. Ein plötzlicher Positionswechsel in kurzer Zeit impliziert eine hohe Beschleunigung. Wenn sich dies nicht in der Beschleunigungsmesser-Telemetrie widerspiegelt, liegt dies mit ziemlicher Sicherheit an einer Änderung der "besten drei" Satelliten, die zur Berechnung der Position verwendet werden (auf die ich als GPS-Teleportation beziehe).
Wenn ein Objekt aufgrund von GPS-Teleportation in Ruhe ist und herumhüpft und Sie den Schwerpunkt nach und nach berechnen, schneiden Sie effektiv einen immer größeren Satz von Muscheln und verbessern so die Präzision.
Um dies zu tun, wenn sich der Vermögenswert nicht in Ruhe befindet, müssen Sie seine wahrscheinliche nächste Position und Ausrichtung basierend auf Geschwindigkeit, Kurs sowie linearen und rotatorischen (wenn Sie Gyros haben) Beschleunigungsdaten schätzen. Dies ist mehr oder weniger das, was der berühmte K-Filter tut. Sie können das Ganze in Hardware für etwa 150 US-Dollar auf einem AHRS erhalten, das alles außer dem GPS-Modul enthält, und mit einer Buchse, um eines anzuschließen. Es verfügt über eine eigene CPU- und Kalman-Filterung an Bord. Die Ergebnisse sind stabil und recht gut. Die Trägheitsführung ist sehr widerstandsfähig gegen Jitter, driftet jedoch mit der Zeit. GPS ist anfällig für Jitter, driftet aber nicht mit der Zeit, sie wurden praktisch entwickelt, um sich gegenseitig zu kompensieren.
quelle
Eine Methode, die weniger Mathematik / Theorie verwendet, besteht darin, 2, 5, 7 oder 10 Datenpunkte gleichzeitig abzutasten und diejenigen zu bestimmen, die Ausreißer sind. Ein weniger genaues Maß für einen Ausreißer als ein Kalman-Filter ist die Verwendung des folgenden Algorithmus zu verwenden, um alle paarweisen Abstände zwischen Punkten zu ermitteln und den am weitesten von den anderen entfernten zu entfernen. In der Regel werden diese Werte durch den Wert ersetzt, der dem von Ihnen zu ersetzenden Außenwert am nächsten kommt
Beispielsweise
Glätten an fünf Probenpunkten A, B, C, D, E.
ATOTAL = Summe der Abstände AB AC AD AE
BTOTAL = Summe der Abstände AB BC BD BE
CTOTAL = Summe der Abstände AC BC CD CE
DTOTAL = Summe der Abstände DA DB DC DE
ETOTAL = Summe der Abstände EA EB EC DE
Wenn BTOTAL am größten ist, würden Sie Punkt B durch D ersetzen, wenn BD = min {AB, BC, BD, BE}
Diese Glättung bestimmt Ausreißer und kann durch Verwendung des Mittelpunkts von BD anstelle von Punkt D zum Glätten der Positionslinie erweitert werden. Ihr Kilometerstand kann variieren und es gibt mathematisch strengere Lösungen.
quelle
Da die kleinsten Quadrate passen, gibt es noch ein paar andere Dinge, mit denen Sie experimentieren können:
Nur weil die kleinsten Quadrate passen, heißt das nicht, dass es linear sein muss. Sie können eine quadratische Kurve mit kleinsten Quadraten an die Daten anpassen. Dies würde dann zu einem Szenario passen, in dem der Benutzer beschleunigt. (Beachten Sie, dass mit kleinsten Quadraten die Koordinaten als abhängige Variable und die Zeit als unabhängige Variable verwendet werden.)
Sie können auch versuchen, die Datenpunkte anhand der gemeldeten Genauigkeit zu gewichten. Wenn die Genauigkeit gering ist, sind diese Datenpunkte niedriger.
Eine andere Sache, die Sie versuchen möchten, ist, anstatt einen einzelnen Punkt anzuzeigen, wenn die Genauigkeit niedrig ist, einen Kreis oder etwas anzuzeigen, das den Bereich angibt, in dem der Benutzer auf der gemeldeten Genauigkeit basieren könnte. (Dies ist die Funktion der in das iPhone integrierten Google Maps-Anwendung.)
quelle
Sie können auch einen Spline verwenden. Geben Sie Ihre Werte ein und interpolieren Sie Punkte zwischen Ihren bekannten Punkten. Wenn Sie dies mit einer Anpassung der kleinsten Quadrate, einem gleitenden Durchschnitt oder einem Kalman-Filter (wie in anderen Antworten erwähnt) verknüpfen, können Sie die Punkte zwischen Ihren "bekannten" Punkten berechnen.
In der Lage zu sein, die Werte zwischen Ihren bekannten Daten zu interpolieren, gibt Ihnen einen schönen reibungslosen Übergang und eine / vernünftige / Annäherung daran, welche Daten vorhanden wären, wenn Sie eine höhere Wiedergabetreue hätten. http://en.wikipedia.org/wiki/Spline_interpolation
Unterschiedliche Splines haben unterschiedliche Eigenschaften. Die am häufigsten verwendeten sind Akima und Cubic Splines.
Ein weiterer zu berücksichtigender Algorithmus ist der Ramer-Douglas-Peucker-Algorithmus zur Linienvereinfachung, der häufig zur Vereinfachung von GPS-Daten verwendet wird. ( http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm )
quelle
Zurück zu den Kalman-Filtern ... Ich habe hier eine C-Implementierung für einen Kalman-Filter für GPS-Daten gefunden: http://github.com/lacker/ikalman Ich habe es noch nicht ausprobiert, aber es scheint vielversprechend.
quelle
Bei Interesse auf CoffeeScript abgebildet. ** edit -> sorry auch mit backbone, aber du kommst auf die idee.
Leicht modifiziert, um ein Leuchtfeuer mit Attributen zu akzeptieren
quelle
@lat
und gesetzt@lng
sind. Sollte+=
eher sein als=
Ich habe den Java-Code von @Stochastically in Kotlin umgewandelt
quelle
Hier ist eine Javascript-Implementierung der Java-Implementierung von @ Stochastically für alle, die sie benötigen:
Anwendungsbeispiel:
quelle