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...
@Jochen Ah OK, ich dachte das geht irgendwie einfacher. Ja ich möchte ein float am Ende haben.
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 Das Ganze ist Zeitunkritisch. Generiere aus den GPS Koordinaten nur einen Google Maps Link der dann per SMS versendet wird.
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)
1 | #include <cstdlib> |
2 | #include <iostream> |
3 | |
4 | using namespace std; |
5 | |
6 | int main(int argc, char *argv[]) |
7 | {
|
8 | int Zehner_vorkomma; |
9 | int einer_vorkomma; |
10 | int vorkomma; |
11 | float nachkomma_1; |
12 | float nachkomma_2; |
13 | float nachkomma_3; |
14 | float nachkomma_4; |
15 | float nachkomma_5; |
16 | float nachkomma_6; |
17 | float nachkomma; |
18 | float Koordinate; |
19 | char Data[8]; |
20 | Data[0]='4'; |
21 | Data[1]='1'; |
22 | Data[2]='2'; |
23 | Data[3]='4'; |
24 | Data[4]='2'; |
25 | Data[5]='0'; |
26 | Data[6]='2'; |
27 | Data[7]='8'; |
28 | |
29 | |
30 | |
31 | Zehner_vorkomma=Data[0]-'0'; |
32 | einer_vorkomma=Data[1]-'0'; |
33 | vorkomma=Zehner_vorkomma*10+einer_vorkomma; |
34 | printf ("vorkomma %d",vorkomma); |
35 | printf (" \n" ); |
36 | |
37 | nachkomma_1=Data[2]-'0'; |
38 | nachkomma_2=Data[3]-'0'; |
39 | nachkomma_3=Data[4]-'0'; |
40 | nachkomma_4=Data[5]-'0'; |
41 | nachkomma_5=Data[6]-'0'; |
42 | nachkomma_6=Data[7]-'0'; |
43 | nachkomma=nachkomma_1*100000+nachkomma_2*10000+nachkomma_3*1000+nachkomma_4*100+nachkomma_5*10+nachkomma_6; |
44 | nachkomma=nachkomma/60/100000; |
45 | printf ("nachkomma %f",nachkomma); |
46 | printf (" \n" ); |
47 | Koordinate=(double)vorkomma+(double)nachkomma; |
48 | printf ("Koordinate %f \n",Koordinate); |
49 | |
50 | system("PAUSE"); |
51 | return EXIT_SUCCESS; |
52 | }
|
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
Habe es jetzt mit ATOI und ATOF gemacht...
1 | degree_lat_array[0]=gps_latitude[1]; |
2 | degree_lat_array[1]=gps_latitude[2]; |
3 | degree_lat=atoi(degree_lat_array); |
4 | |
5 | minutes_lat[0]= gps_latitude[3]; |
6 | minutes_lat[1]= gps_latitude[4]; |
7 | minutes_lat[2]= gps_latitude[5]; |
8 | minutes_lat[3]= gps_latitude[6]; |
9 | minutes_lat[4]= gps_latitude[7]; |
10 | minutes_lat[5]= gps_latitude[8]; |
11 | minutes_lat[6]= gps_latitude[9]; |
12 | minutes_lat[7]= gps_latitude[10]; |
13 | minute_lat = atof(minutes_lat); |
14 | minute_lat = minute_lat / 60; |
15 | lat = degree_lat + minute_lat; |
16 | //printf( "Wert des Strings: %f\n", lat);
|
17 | |
18 | degree_lon_array[0]=gps_longitude[1]; |
19 | degree_lon_array[1]=gps_longitude[2]; |
20 | degree_lon_array[2]=gps_longitude[3]; |
21 | degree_lon=atoi(degree_lon_array); |
22 | |
23 | minutes_lon[0]= gps_longitude[4]; |
24 | minutes_lon[1]= gps_longitude[5]; |
25 | minutes_lon[2]= gps_longitude[6]; |
26 | minutes_lon[3]= gps_longitude[7]; |
27 | minutes_lon[4]= gps_longitude[8]; |
28 | minutes_lon[5]= gps_longitude[9]; |
29 | minutes_lon[6]= gps_longitude[10]; |
30 | minutes_lon[7]= gps_longitude[11]; |
31 | minute_lon = atof(minutes_lon); |
32 | minute_lon = minute_lon / 60; |
33 | lon = degree_lon + minute_lon; |
34 | //printf( "Wert des Strings: %f\n", lon);
|
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...
hier gibts' funktionierende 64Bit float Routinen: Beitrag "64 Bit float Emulator in C, IEEE754 compatibel" Cheers Detlef
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.