Habe GPS Koordinaten in folgender Form in einem Array...
Grad und Dezimalminuten (GMM): 41 24.2028, 2 10.4418
z.B. gps_data[0]=4 gps_data[1]=1 gps_data[2]=2 usw...
Zum Umrechnen in Dezimalgrad (GGG): 41.40338, 2.17403
muss man ja jetzt z.B. 24.2028 / 60 + 41 rechnen.
Wie komme ich jetzt von obigen Array zu
z.B. einem Wert wie dann 41.40338 in C?
Peter schrieb:> Wie komme ich jetzt von obigen Array zu> z.B. einem Wert wie dann 41.40338 in C?
Auf welcher Hardware (AVR, PC, kariertes Papier, ...)?
Hallo Peter,
im ersten Schritt muss um den "ZEICHEN" rechnen zu können aus dem Array
jeweils eine Zahl gemacht werden. Dazu verwendet man im Allgemeinen den
Ascii-Code des Zeichens und zieht dann Ascii 0 (das Zeichen Null) ab.
Hierbei kann Du schon auf Vor- und Nachkommastellen achten.
also die gps_data[0]=4 als Ziffer mit 10 multiplizieren und dann die 1
als Ziffer addieren.
Wenn es flexibel sein soo, muss due vorher im Array die Längen ermitteln
um zu wissen wie viele Stellen vor dem Komma stehen.
Bei den Dezimalminuten geht das vom Prinzip her genauso, allerdings
kommt hier noch deine /60 hinzu, dies ist aber kein großen Thema mehr,
wenn es erst mal Zahlen sind.
Wenn Du die Ausgabe als Kommazahl haben möchtest, denk dran einen
Datentyp zu verwenden der das kann.
Double , float
Hoffe ich konnte dir helfen. Meld dich einfach...
Peter schrieb:> @Jochen> Ah OK, ich dachte das geht irgendwie einfacher.> Ja ich möchte ein float am Ende haben.
Ich bin nicht sicher, ob Du das willst. Ich nehme an, die Daten kommen
als Datenstrom an, mit dem Du irgendwie mithalten musst?
Wenn Du die Umrechnung von Bogenminuten in Dezimalminuten als float
machst, dürfte das auf dem AVR ein wenig (möglicherweise ein wenig zu
lange) dauern.
Da ist es wahrscheinlich günstiger, die Vor- und Nachkommastellen
separat als Fixpunktzahl zu behandeln, so daß Du nur mit Ganzzahlen
rechnen mußt.
Markus F. schrieb:> Wenn Du die Umrechnung von Bogenminuten in Dezimalminuten als float> machst, dürfte das auf dem AVR ein wenig (möglicherweise ein wenig zu> lange) dauern.
Wenn die Daten von einem GPS-Empfänger kommen, dann kommen sie in der
Regel in einem Abstand von einer Sekunde. Ich denke, in einer Sekunde
schafft der AVR schon zwei oder drei Fließkomma-Operationen :-))
Peter schrieb:> @Markus> Das Ganze ist Zeitunkritisch.> Generiere aus den GPS Koordinaten> nur einen Google Maps Link der dann per SMS> versendet wird.
Dann kannst Du's so machen wie von Jochen oben beschrieben.
Oder, wenn Du genügend Platz hast, mit sscanf() aus der AVR-libc. Das
erspart dir, die float-Parserei von Hand zu machen.
Hallo Peter,
so schlimm ist es nicht.
Peter schrieb:> Habe GPS Koordinaten in folgender Form in einem Array...>> Grad und Dezimalminuten (GMM): 41 24.2028, 2 10.4418> z.B. gps_data[0]=4 gps_data[1]=1 gps_data[2]=2 usw...>> Zum Umrechnen in Dezimalgrad (GGG): 41.40338, 2.17403> muss man ja jetzt z.B. 24.2028 / 60 + 41 rechnen.>> Wie komme ich jetzt von obigen Array zu> z.B. einem Wert wie dann 41.40338 in C?
Deine Darstellung des Arrays passt leider nicht ganz mit dem zusammen,
was Du darüber geschrieben hast. In gps_data[2] müsste nach der obiger
Schreibweise ein Leerzeichen sein?
hier was Q&D zum spielen: (läuft auf PC in DEVcc)
Hallo Jochen danke für Dein Beispiel!
Das mit dem Array war nur ein Beispiel um klarzumachen was ich meine.
Der GPS Empfänger bringt an der Stelle kein Leerzeichen.
Aber da es ein ATMega2560 ist, hab ich genügend platz und ich werde
es dann mal mit sscanf probieren wie Markus vorgeschlagen hat.
Gruß und Danke an euch
Peter
Peter schrieb:> Habe es jetzt mit ATOI und ATOF gemacht...
zeig mal, wie du deine Arrays deklariert hast. Denn im Code hast du die
C-String Terminierung nicht gemacht.
Man sieht auch recht oft, dass die Leute für derartige Konvertierungen
jeweils verschiedene Arrays für die Strings benutzen. Wozu? DU kannst
alle Konvertierungen über ein und dasselbe Array abwickeln, da du je die
jeweiligen Teilstrings nach der Überführung in echte Zahlen nicht mehr
brauchst.
Auch wenn du genug Speicher hast, verprassen brauchst du den deswegen
auch nicht sinnlos.
Peter schrieb:> Habe es jetzt mit ATOI und ATOF gemacht...>
Das geht einfacher (ohne die Zwischenspeicherung):
1
sscanf(&gps_latitude[1],"%2d",°ree_lat);
2
sscanf(&gps_latitude[3],"%8f",&minute_lat);
3
minute_lat/=60;
4
lat=degree_lat+minute_lat;
5
6
sscanf(&gps_longitude[1],"%2d",°ree_lon);
7
sscanf(&gps_longitude[3],"%8f",&minute_lon);
8
minute_lon/=60;
9
lon=degree_lon+minute_lon;
sscanf() kann mit der Angabe einer Feldbreite direkt aus dem String
lesen.
Der Code ist ungetestet, nur mal "aus der Hüfte" hingeschrieben, aber
ich denke, so (oder ganz ähnlich) müsste es funktionieren.
Die sscanf() float-Version kriegst Du mit
-Wl,-u,vfscanf -lscanf_flt -lm
als Compileroption.
Ich bin gerade in einer ähnlichen Situation, in der ich auf einem µC mit
GPS-Daten arbeiten möchte. 64bit-floats werden nicht unterstützt.
Nach nachrechnen, stellt sich heraus, dass von float die Genauigkeit
nicht ausreicht.
Zum speichern vielleicht gerade so (am Äquator ~37cm pro digit).
Aber sobald gerechnet wird...
Detlef _a schrieb:> hier gibts' funktionierende 64Bit float Routinen:>> Beitrag "64 Bit float Emulator in C, IEEE754 compatibel"
Im allgemeinen ist es beim Rechnen mit GPS-Koordinaten gar nicht
notwendig, mit so hoher Genauigkeit zu rechnen, um trotzdem ausreichend
genaue Ergebnisse zu bekommen.
Sondern eigentlich braucht man nur geeignete Algorithmen zu verwenden.
Zum Beispiel für sehr kleine Abstände auf der Erdoberfläche den Abstand
nicht per Kugelgeometrie und Winkelfunktionen ausrechnen, sondern
stattdessen kleine Abstände als ebene Dreiecke mit euklidische Geometrie
rechnen.
Dazu rechnet man sich im ersten Schritt beispielsweise aus, wieviele
Meter ein millionstel Grad entspricht. Zum Beispiel am Äquator:
40070 km / 360° = 111,3 km
Entsprechend ist 1 Millionstel Grad:
111,3 * 1000 m / 1000000 = 0,1113 m
Und wenn man dann die GPS-Koordinaten nicht als Gleitkommazahlen
vorliegen hat, sondern als long Ganzzahlen in Millionstel Längengrad,
dann ist die Differenz zwischen Längengrad
10000004 (10,000004°) und
10000007 (10,000007°) am Äquator exakt
--------
3 Millionstel Grad a 0,1113m = 0,3339 m
Bei Koordinaten, die sich in Längen- und Breitengrad unterscheiden,
rechnet man den (kleinen) Abstand über den Pythagoras.
Im Endeffekt ist es dann nur Aufgabe zu entscheiden, wo man die Grenze
zwischen "kleine GPS-Abstände" und "große GPS-Abstände" berechnen legt
um zu entscheiden, ob man seinen gesuchten Abstandswert am besten per
sphärischer oder per euklidischer Geometrie ausrechnet, um den relativen
Fehler gering zu halten.