Problem mit der berechnung von sin/cos/acos

OP #1972487
Lesenswert?

Ich habe folgendes Problem:

Entwicklungsumgebung Keil uVision 3

Ich möchte gerne die entfernung von 2 GPS Positionen berechnen wenn ich 
die folgende Formel mit meinem Taschenrechner berechne (auf RAD 
eingestellt) bekomme ich das richtige ergebnis wenn ich das ganze aber 
mit dem Debugger von Keil durchgehe steht am ende folgendes Ergebnis im
Speicher: -1.#INF es sollte aber 1.593(mit Taschenrechner berechnet) 
drinstehen hier ist der code:


// initialisierung aus der Struktur im main
GPRMCDaten.dezimalLaengengrad   = 8.41321;
GPRMCDaten.dezimalLaengengrad2   = 8.42182;
GPRMCDaten.dezimalBreitengrad   = 49.9917;
GPRMCDaten.dezimalBreitengrad2   = 50.0049;
//


float   lat1,lat2,lon1,lon2;
float  distanz;
float   pi = 3.14159265;


lat1 = 2.0*pi*(ptrStrukt->dezimalBreitengrad/360.0);
lat2 = 2.0*pi*(ptrStrukt->dezimalBreitengrad2/360.0);
lon1 = 2.0*pi*(ptrStrukt->dezimalLaengengrad/360.0);
lon2 = 2.0*pi*(ptrStrukt->dezimalLaengengrad2/360.0);

distanz = 6378.388 * acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) 
* cos(lon2 - lon1));


fals jeamnd ne idee hat wäre ich für eine Antwort sehr dankbar
#1972572
Lesenswert?

Mit 8-Byte-doubles gerechnet sieht es erstmal vernünftig aus
(ich komme mit meinem double-Taschenrechner auf 1.593417 (km?)).

Aber selbst wenn er durch Kniffe das Problem soweit löst, sehe
ich ein ganz anderes (das mit dem obigen Rundungsfehler eng verwandt
ist):
Er versucht ja offenbar, eine relativ kleine Entfernung auf der
Erdoberfläche aus den Koordinaten zu berechnen.
D.h. er versucht, aus einem Wert sehr nahe bei 1.000 über den
acos den Winkel zu bestimmen. Leider ändert sich der cos
bei kleinen Winkeln kaum, dementsprechend ungenau ist die
umgekehrte Rechnung über den acos zum Winkel.

Mein Vorschlag: entweder eine Gleichung hinfummeln, die
den asin verwendet (das ist bei kleinen Winkeln viel genauer,
da der sin hier praktisch linear verläuft),
oder gleich einsehen, daß es kleine Winkel sind und damit die
Erdkrümmung wumpe ist und einfach die Länge des Geradenstücks
zwischen den beiden Punkten nehmen.
Das ist wesentlich genauer als mit 6 Dezimalstellen bei float
über den acos zu gehen.

Das könnte so aussehen, daß man aus den Koordinaten den
Abstand in N-S-Richtung berechnet sowie den in O-W-Richtung,
und daraus über Pythagoras die Länge der Strecke.

PS: der Winkel um den es hier geht, ist in rad 0.000249 bzw.
0.014313°.
Ich gehe jede Wette ein, daß mein GPS-Tracker die Formel von
Lukas nicht verwendet.
#1972596
Lesenswert?

Klaus Wachtler schrieb:

> oder gleich einsehen, daß es kleine Winkel sind und damit die
> Erdkrümmung wumpe ist und einfach die Länge des Geradenstücks
> zwischen den beiden Punkten nehmen.
> Das ist wesentlich genauer als mit 6 Dezimalstellen bei float
> über den acos zu gehen.
>
> Das könnte so aussehen, daß man aus den Koordinaten den
> Abstand in N-S-Richtung berechnet sowie den in O-W-Richtung,
> und daraus über Pythagoras die Länge der Strecke.

Genau so würde ich das auch machen.
Denn:
  Was interessiert mich die Distanz auf einer Kugel zwischen
  Oberammerhofen und Bad-Nirgendwo?

Die reale Distanz ist sowieso eine andere, weil die Erde nun mal keine 
glatt polierte Billiardkugel ist, sondern Berge und Täler hat.

Anstatt da lang auf einer Kugel rumzurechnen, kann ich genausogut 
annehmen, dass in hinreichender Näherung die Erde in 50km Umkreis eine 
ebene Fläche ist. Der Fehler wird dadurch auch nicht größer sein.
OP #1972791
Lesenswert?

Danke schon einmal für die vielen Antworten das mit dem geringen abstand 
und die berechnung mit dem pytagoras weis ich auch schon es gibt ja drei 
berechnungsmethoden einmal die mit dem pytagoras dann die 
berechnungsformel mit der kugeloberfläche und die Formel für eine 
Ellipsoide das Problem ist dass ich mit meinem GPS gerät 
unterschiedliche Abstände berechnen will und so wäre mir die 
Kugelberechnung etwas lieber mir ist nun aufgefallen dass mein 
Taschenrechner nicht runded der compiler dagegen rundet bei zB 0.9999984 
schon auf 1 gibt es eine möglichkeit das zu unterbinden wenn nicht dann 
wäre noch die möglichkeit mit einer groben vorberechnung des Abstands 
der zwei Punkte zu errechnen und dann zu entscheiden ob ich die 
Pytagoras Formel oder die Kugelformel zur berechnung nehme
#1972799
Lesenswert?

Lukas Honsell schrieb:

> Taschenrechner nicht runded der compiler dagegen rundet bei zB 0.9999984
> schon auf 1

das tut er nicht.
Aber du darfst bei 5 bis 6 signifikanten Stellen keine Wunder erwarten. 
Du hast die Genauigkeit einfach nicht.
Dein Taschenrechner rechnet auf 10, 12, 15 Stellen genau, dein µC aber 
nur auf ca 6.

Signifikante Stellen!
Das heist bei der Zahl  876.387
sind diese 6 Stellen aufgebraucht, alles dahinter ist nur noch 
'gelogen'. Und das 'Problem' wird schlimmer, je komplexer die 
Berechnungen werden.

Wenn man zu 1000.00 die Zahl 0.0001 addieren will, dann hat man einfach 
nicht die dazu nötige Stellenzahl. Das ist bei einer Addition nicht 
weiter schlimm. Willst du aber 10000 mal die 0.0001 addieren, dann ist 
das Ergebnis danach immer noch 1000.00 obwohl dein Taschenrechner ganz 
was andres raus bringt.
#1972803
Lesenswert?

Lukas Honsell schrieb:
> Danke schon einmal für die vielen Antworten das mit dem geringen abstand
> und die berechnung mit dem pytagoras weis ich auch schon es gibt ja drei
> berechnungsmethoden einmal die mit dem pytagoras dann die
> berechnungsformel mit der kugeloberfläche und die Formel für eine
> Ellipsoide das Problem ist dass ich mit meinem GPS gerät
> unterschiedliche Abstände berechnen will und so wäre mir die
> Kugelberechnung etwas lieber mir ist nun aufgefallen dass mein
> Taschenrechner nicht runded der compiler dagegen rundet bei zB 0.9999984
> schon auf 1 gibt es eine möglichkeit das zu unterbinden wenn nicht dann
> wäre noch die möglichkeit mit einer groben vorberechnung des Abstands
> der zwei Punkte zu errechnen und dann zu entscheiden ob ich die
> Pytagoras Formel oder die Kugelformel zur berechnung nehme

Nein, dein Problem ist, daß du keine Sätze schreiben kannst.
Das kann man doch nicht lesen, ohne daß sich die Fußnägel ablösen!
OP #1972840
Lesenswert?

@ Klaus Wachtler ich werde mich in Zukunft bemühen :D

Das heist es wäre besser erst eine grobe vorberechnung der Distanz 
vorzunehmen und dann eine Methode auszuwählen (Pytagoras oder Kugel).

Bei kleinen Entfernungen den Pyt und bei den grösseren Entfernungen die 
Kugelberechnung.

Ist das mit den 6 Signifikanten Stellen beim uController immer so oder 
(hardwarebezogen) oder lässt sich das durch die Software erweitern.
#1972849
Lesenswert?

Lukas Honsell schrieb:
> Bei kleinen Entfernungen den Pyt und bei den grösseren Entfernungen die
> Kugelberechnung.

Das hört sich sinnvoll an.

Lukas Honsell schrieb:
> Ist das mit den 6 Signifikanten Stellen beim uController immer so oder
> (hardwarebezogen) oder lässt sich das durch die Software erweitern.

Je nach Controller gibt es meist sowieso keine Gleitkommarechnung
in Hardware, also ist es nur eine SW-Frage.

Beim AVR bspw. gibt es in der glibc erstmal nur float (genau
genommen gibt es auch double, aber das ist dasselbe).
Mit zusätzlichen Libs kann man auch mit 64 Bit rechnen.

Das Problem dabei ist, daß die Rechenzeit drastisch ansteigt.
Schon mit 32 Bit kann man kaum noch einen Blumentopf gewinnen,
64-Bit-Rechnungen mit noch ein paar Winkelfunktionen wirst
du nicht mehr im msec-Takt machen wollen, falls wir von wenigen
MHz Takt reden.

Bei geschickterer Rechnung mit float leben zu können, wird dir
mehr helfen.
Wenn du nicht gerade asin(etwa 1) rechnen willst oder ähnliches,
sind 6 Stellen gar nicht so verkehrt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren