www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik sin. cos, acos auf ATmegaX


Autor: Christoph Borowski (cborowski)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich entwicklte gerade aus Spass ein kleines GPS-Gerät bestehend aus 
einer seriellen GPS-Maus, einem ATmega-Board, einem Display & einer 
Matrixtastatur. Das ganze in C. Anzeige der GPS-Daten nach div. 
Kriterien klappt ohne Probleme.
Jetzt wollte ich dem ganzen auch eine Waypoint-Navigation spendieren & 
befasse mich gerade mit der Entfernungsberechnung zwischen zwei Orten 
(je mit Länge/Breite angegeben). Dafür gibt es eine Formel, die die 
kürzeste Strecke zwischen zwei Punkten auf der Kugeloberfläche 
ausrechnet.

Im folgenden seien:

pLat = Breitenangabe Ort 1
pLong = Längenangabe Ort 1
pLat2 = Breitenangabe Ort 2
pLong2 = Längenangabe Ort 2

Das Ergebnis der Formel (1)

w = sin(pLat)*sin(pLat2) + cos(pLat)*cos(pLat2)*cos(pLong2-pLong)

eingesetzt in Formel (2)

alpha = arccos(w)

berechnet den Winkel zwischen der Geraden, die durch den 
Kugelmittelpunkt zum Ort 1 und der Geraden, die durch den 
Kugelmitelpunkt zum Ort 2 geht.

alpha (wenn ich vorher schon mit dem Bogenmaß gerechnet habe) 
multipliziert mit dem Äquatorradius (Formel (2)) gibt dann die kürzeste 
Entfenung zwischen den zwei Orten auf der (erdgroßen) Kugeloberfläche.

Das Problem ist nur, dass ich hier mit sin, cos & acos rechnen muß & das 
ganze auf dem ATmegaX wegen Dauer & Speicher wohl nicht zu empfehlen 
ist. Oder ist das nicht so wild?
Oft wird davon gesprochen eine Tabelle mit Sinus-Werten anzulegen. Habe 
ich gemacht & zwar in 0,25° Schritten von 0-90°. Wenn ich die Berechnung 
(oder sollte ich lieber sagen den Lookup) von sin & cos über diese 
Tabelle laufen lasse, dann ist das Endergebnis der Berechnung äußerst 
ungenau. Bei der Entfernung fast Faktor 2! Das ganze wird deshalb so 
ungenau, weil das Ergebnis von Formel (1) ein Wert zw. (-1)-1 ist. Und 
wenn z. B. statt 0.99943 am Ende nur 0.9972 rauskommt, dann liefert das 
ganze eingesetzt in Formel (2) schon ziemlich unterschiedliche Werte. 
Damit ist die Entfernungsberechnung schon gescheitert :(

Hat jemand eine Idee, wie man das Problem elegant lösen kann? Feinere 
Auflösung der Sinus-Tabelle (Nachteil: sehr viele Einträge). 
Interpolieren zwischen zwei Werten aus der Sinus-Tabelle. DOch die sin-, 
cos- & acos-Funktionen nutzen?

Im voraus schon mal Danke...
Christoph

Autor: JojoS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eine Loesung habe ich nicht, aber in der Codesammlung gibt es einen 
langen Thread ueber eine GPS Software auf AVR.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie hast du die Sin/Cos Tabelle implementiert? Mit Float/Double?

Vorschlag: Nimm doch int oder long. Also ohne Kommaanteil. Dann geht zum 
Beispiel die Tabelle nicht von -1 bis +1 sondern zB von -1000 bis +1000. 
Alles nur eine Sache der Skalierung am Ende deiner Rechnung.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spar dir das mit den Tabellen, rechne erst mal in Fließkomma mit den 
trigonometrischen Funktionen die der Compiler bereitstellt. Sollte sich 
herausstellen dass das zu langsam ist (was ich bei den langsamen 
Aktualisierungsraten von GPS bezweifle), kannst du immer noch 
optimieren.

Autor: Christoph Borowski (cborowski)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon

das Problem ist nicht, dass die Werte zw. -1 & 1 sind, sondern dass ich 
in meiner Tabelle nur diskrete sin-Werte für die Winkel 0, 0.25, 0.5 ... 
90 habe. Wenn ich dann z. B. den sin-Wert für Winkel 44.8 haben will, 
dann kann ich bei der Einfachmethode aus der Tabelle den sin-Wert für 
Winkel 44.75 oder Winkel 45 nehmen. Beide sin-Werte sind verglichen mit 
dem tatsächlich berechneten sin-Wert ziemlich ungenau. Und wenn ich dann 
noch mit mehreren solcher ungenauer Werte weiterrechne (siehe Formel (1) 
z. B. Multiplikation), dann ist das Endergebnis sehr ungenau.

Also, das Problem ist NICHT float/double, sondern die diskreten Werte, 
die mir die Tabelle bietet.

Gruss
Christoph

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest linear interpolieren. Oder du könntest dir den ganzen Ärger 
erst einmal komplett sparen. Ein paar Sinus-Berechnungen pro Sekunde 
macht der AVR mit links.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie wärs mit interpolation der tabellen-werte für die 
dazwischenliegenden werte?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.