Schlagwort-Archive: GPS

Die Praezision von GPS-Koordinaten

Ich bin auch schon Opfer der Idee gewesen, GPS-Koordinaten aus einem tatsaechlichen GPS-Empfaenger mit moeglichst vielen Nachkommastellen abzugreifen und zu speichern. Tatsaechlich ist schon die fuenfte Nachkommastelle bei handelsueblichen Empfaengern ohne Signalkorrektur schon eher eine ungenaue Angelegenheit:

  • The fourth decimal place is worth up to 11 m: it can identify a parcel of land. It is comparable to the typical accuracy of an uncorrected GPS unit with no interference.
  • The fifth decimal place is worth up to 1.1 m: it distinguish trees from each other. Accuracy to this level with commercial GPS units can only be achieved with differential correction.
  • The sixth decimal place is worth up to 0.11 m: you can use this for laying out structures in detail, for designing landscapes, building roads. It should be more than good enough for tracking movements of glaciers and rivers. This can be achieved by taking painstaking measures with GPS, such as differentially corrected GPS.
  • The seventh decimal place is worth up to 11 mm: this is good for much surveying and is near the limit of what GPS-based techniques can achieve.
  • The eighth decimal place is worth up to 1.1 mm: this is good for charting motions of tectonic plates and movements of volcanoes. Permanent, corrected, constantly-running GPS base stations might be able to achieve this level of accuracy.
  • The ninth decimal place is worth up to 110 microns: we are getting into the range of microscopy. For almost any conceivable application with earth positions, this is overkill and will be more precise than the accuracy of any surveying device.
  • Ten or more decimal places indicates a computer or calculator was used and that no attention was paid to the fact that the extra decimals are useless. Be careful, because unless you are the one reading these numbers off the device, this can indicate low quality processing!

Ich war damals so blauaeugig, acht Stellen anzugeben. Wuesste ich heute natuerlich besser 😉

Was das mit der Signalkorrektur und HDOP und sonstigen Dingen auf sich hat, laesst sich auf Kowoma.de nachlesen.

(via)

GPS und Java: NMEA-Daten auswerten (1)

Bild: GPS Recorder von andyp_uk, cc-by-nc

Irgendwann kommt die Zeit im Leben jedes Menschen, an der er GPS-Daten automatisiert verarbeiten will. Vertraut mir, was das angeht. Das passiert jedem.

Unter C++ ist sowas sicher viel simpler und toller. Ich hatte aber die fixe Idee, das unter Java zu machen, weil das ja gewohntes und damit vermeintlich sicheres Terrain fuer mich sei. Das lassen wir jetzt mal so dahingestellt.

Schritt 1: Daten holen

Die Idee, hier java.io verwenden zu wollen, kann man sich ziemlich in die Haare schmieren. Gleich gnu.io.rxtx zu verwenden, spart Aerger. Weil wir NMEA-Daten ueber die serielle Schnittstelle haben wollen, setzen wir die Parameter entsprechend: setSerialPortParams(4800, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

Hier kommt jetzt alles moegliche NMEA-Zeug heraus, das man theoretisch direkt parsen koennte. Alternativ kann man mit der Java NMEA API gezielt nach den interessanten NMEA-Saetzen lauschen. Kurz deren Doku ueberfliegen lohnt sich auf jeden Fall, da sich auch ein Beispiel findet, wie man ein GPS-Geraet ueber die serielle Schnittstelle einliest.

PS: Viele GPS-Maeuse kommen heute mit einem integrierten Serial-to-USB-Konverter daher, damit man sie per USB anschliessen kann. Sollte RxTx unter Linux zwar einen USB-Port (a la /dev/ttyUSB0) erkennen, darauf aber nicht zugreifen koennen („No such port“), helfen unter Umstaenden chown unsinn! chmod 666 /dev/ttyUSB0 und chgrp tty /dev/ttyUSB0 weiter.

Schritt 2: Was brauchen wir da eigentlich?

Wenn man sich mal direkt ansieht, was da ueber die Konsole rauscht, dann ist das ziemlich viel. Beispiel:

$GPRMC,101836.000,A,4825.1856,N,00956.8032,E,0.23,226.38,230710,,*07
$GPVTG,226.38,T,,M,0.23,N,0.4,K*68
$GPGGA,101837.000,4825.1857,N,00956.8023,E,1,04,1.4,567.4,M,48.0,M,,0000*5E
$GPGSA,A,3,17,05,08,18,,,,,,,,,8.6,1.4,8.5*36
$GPRMC,101837.000,A,4825.1857,N,00956.8023,E,0.57,292.18,230710,,*09

Das sieht auf den ersten Blick wenig einladend aus, im Endeffekt aber ziemlich simpel. „$GP“ bedeutet, dass es sich um GPS-Daten handelt. „RMC“, „VTG“, „GGA“, „GSA“ und Co. sind verschiedene Satztypen, die hierzu gehoeren. RMC muss jeder GPS-Empfaenger koennen, idealerweise nehmen wir uns aber die GGA-Saetze her, weil die in einem Satz alle fuer uns wichtigen Informationen bereitstellen.

Durch Kommas getrennt finden sich hier:

  • Uhrzeit in UTC
  • Breite und Bezeichner N oder S fuer die Breite
  • Laenge und Bezeichner W oder E fuer die Laenge
  • QualitĂ€t der Messung (0 == ungueltig, 1 == GPS, 2 == DGPS)
  • Anzahl der gemessenen Satelliten
  • Horizontal Dilution Of Precision (mehr dazu im naechsten Post)
  • Hoehe ueber Meer mit Einheit
  • Hoehe ueber Geoid minus Hoehe ueber Ellipsoid, mit Einheit

…gefolgt zum Schluss von einer Pruefsumme, die ich aber nie irgendwie beruecksichtigt habe. Bis auf das aktuelle Datum ist hier also alles vorhanden, was man braucht, es muss nur noch die Zeichenkette aufgetrennt und die WGS84-Koordinate in ein Format umgerechnet werden, mit dem man weiterarbeiten kann.

Schritt 3: Koordinaten umrechnen

Umrechnen? Ja. In den NMEA-Saetzen steht naemlich folgendes:

4825.1857,N,00956.8023,E

Das sind also 48° 25.1857′ noerdlicher Breite und 9° 56.8023′ oestlicher Laenge. In Minuten wollen wir aber nicht rechnen, wir wollen zwei glatte Dezimalbrueche — in diesem Fall etwa 48.4197616 und 9.946705. Dazu muessen wir aber erst einmal unsere NMEA-Saetze in ihre Bestandteile zerlegen.

In einigen Tutorials, die ich gefunden hatte, war hier immer vom StringTokenizer die Rede, um die Zeichenkette zu zerlegen. Das ist aber nicht immer eine gute Idee, da der NMEA-Output direkt nach dem GPS-Start oder beim Fix-Verlust (z.B. in einem Tunnel) so aussehen kann:

$GPGGA,103927.819,,,,,0,00,,,M,0.0,M,,0000*58

Schoener geht das alles mit der split()-Methode, um die Zeichenkette an den Kommas zu trennen:

String sentence_parts[] = e.getContent().split(",");

Nun ist klar definiert, an welcher Stelle was zu erwarten ist. Sollten wir keinen Fix haben, koennen wir das ganz einfach herausfinden:

if (sentence_parts[6].equals("0")) {
    System.err.println("No fix!");
    // TODO: Handle this further, if needed
 }

Gehen wir aber mal davon aus, dass wir einen Fix haben. Dann hilft uns der Algorithmus aus dem oben genannten Tutorial weiter, mit dem wir die Minutenangabe der NMEA-Koordinate in den Dezimalbruch nach dem Komma der Gradangabe umwandeln koennen:

float lat_val = convertLat(sentence_parts[2], sentence_parts[3]);
float lon_val = convertLon(sentence_parts[4], sentence_parts[5]);
public float convertLat (String raw_latitude, String lat_direction) {

  String lat_deg = raw_latitude.substring(0, 2);
  String lat_min1 = raw_latitude.substring(2, 4);
  String lat_min2 = raw_latitude.substring(5);
  String lat_min3 = "0." + lat_min1 + lat_min2;
  float lat_dec = Float.parseFloat(lat_min3)/.6f;
  float lat_val = Float.parseFloat(lat_deg) + lat_dec;

 // Direction of latitude. North is positive, south negative
  if (lat_direction.equals("N")) {
    // no correction needed
  } else {
    lat_val = lat_val * -1;
  }
 return lat_val;
 }
public float convertLon(String raw_longitude, String lon_direction) {
 // Conversion of longitude to floating point values

  String lon_deg = raw_longitude.substring(0, 3);
  String lon_min1 = raw_longitude.substring(3, 5);
  String lon_min2 = raw_longitude.substring(6);
  String lon_min3 = "0." + lon_min1 + lon_min2;
  float lon_dec = Float.parseFloat(lon_min3)/.6f;
  float lon_val = Float.parseFloat(lon_deg) + lon_dec;

  //direction of longitude, east is positive
  if (lon_direction.equals("E")) {
    // No correction needed
  } else {
    lon_val = lon_val * -1;
  }
 return lon_val;
 }

Jetzt haben wir unseren Standort. Naja, eigentlich nicht, sondern nur eine Annaeherung unserer Position. Hier kommt noch eine bestimmte Abweichung ins Spiel, die in Metern auszudruecken gar nicht so leicht ist. Wie man damit umgehen kann und wie das generell mit Genauigkeit, Praezision und Verfahren wie DGPS und SBAS geht, schreibe ich dann demnaechst mal.

Nachtrag: Waehrend ich das hier schreibe, faellt mir auf, dass ich bei den Vorzeichen automatisch das vom UTM-Koordinatensystem her bekannte Nordwert-Ostwert-Paradigma verwendet habe — bin mir aber aktuell nicht sicher, ob bei WGS84-Koordinaten nicht doch der Westwert ein positives Vorzeichen hat.

Nach-Nachtrag: Gpsvisualizer hat meine Annahme bestaetigt. Puh 🙂

GPS-Nerdereien

Momentan bin ich noch auf der Suche nach einer guenstigen Kompaktkamera in der 100-EUR-Klasse, die ich mit auf die Reise mit Raimar nehmen kann. Die DSLR werde ich wohl auch mitnehmen (in Minimalausstattung, ohne Batteriegriff etc.), aber auf Staedtereisen hat es mir bisher immer riesigen Spass gemacht, aus der Huefte heraus Bilder mit der Kompakten zu machen (die mittlerweile leider einmal zu oft heruntergefallen ist)

Ueber DonVanone bin ich aber auf die Idee aufmerksam geworden, doch vielleicht einen gescheiten GPS-Tracker zu kaufen, mit dem man die Reiseroute aufzeichnen und hinterher die Bilder verorten koennte.

Ja, eigentlich gesponnen. Aber fuer 160 EUR momentan irgendwie sehr reizvoll.

Muss. innerem. Nerd. widerstehen.