Hallo,
ich programmiere in CC-Basic mit der C-Controlpro IDE,
dort existiert leider die Funktion atan2 nicht (zur
Kompasskursberechnung).
Ich würde diese Funktion gerne im Code mit Programmieren, werde aber aus
der WIKI Beschreibung zur Atan2 Funktion nicht ganz schlau.
Kann mir jemand diese Funktion aufdröseln?
Gibt wohl 6 verschiedene Berechnungen je nach Wertigkeitvon X und Y.
Mit der Hoffnung auf ein wenig Hilfe
Olaf
Welche Funktionen hast du denn als Ausgangsbasis verfügbar?
Im Wesentlichen besteht atan2 typischerweise aus einer Behandlung
der diversen Sonderfälle, gefolgt von einem Rückfall auf atan(y/x).
Olaf schrieb:> Kann mir jemand diese Funktion aufdröseln?
Was gibt es da aufzudröseln? Der Autor des Artikels hat das doch schon
getan.
> Gibt wohl 6 verschiedene Berechnungen je nach Wertigkeitvon X und Y.
Eben. Und genau diese musst du mittels einer IF-ELSEIF-ENDIF-Kette in
Basic umsetzen. Wo ist das Problem?
Hier ist per Pseudocode skizziert, wie atan2() in der AVR-Libc
implementiert ist:
avr-libc-2.0.0/libm/fplib/atan2.S:
1
...
2
/* float atan2 (float A, float B); // A is y coord, B is x coord.
3
The atan2() function calculates the arc tangent of the two variables
4
A and B. It is similar to calculating the arc tangent of A/B, except
5
that the signs of both arguments are used to determine the quadrant
6
of the result. The atan2() function returns the result in radians,
7
which is between -PI and PI (inclusive).
8
9
Note:
10
This implementation returns +0.0 in all four cases: +0/+0, +0/-0,
11
-0/+0 and -0/-0. Unlike x86 (GCC/Glibc).
12
13
Algorithm:
14
if (x == 0 && y == 0) // A is y, B is x
15
return 0
16
if (x >= 0 && fabs(y) <= x)
17
return atan(y/x) // -Pi/4 .. +Pi/4
18
if (y >= 0 && fabs(x) <= y)
19
return Pi/2 - atan(x/y) // +Pi/4 .. +3*Pi/4
20
if (y <= 0 && fabs(x) <= fabs(y))
21
return -Pi/2 - atan(x/y) // -Pi/4 .. -3*Pi/4
22
if (y >= 0)
23
return Pi + atan(y/x) // +3*Pi/4 .. Pi
24
else
25
return -Pi + atan(y/x) // -3*Pi/4 .. -Pi
26
*/
27
...
Der eigentliche Programmcode ist in Assembler und hilft die vermutlich
nicht weiter.
Hallo,
vielen Dank.
Wenn ich avr-lib mit Wiki vergleiche
(soweit ich dazu in der Lage bin) fallen mir schon unterschiede auf:
aber ich versuche mal die Lib umzusetzen, sieht ja nicht so schwierig
aus.
Falls die Ergebnisse nicht passen, wäre ich mal so frech meinen Code zu
posten.
Danke
erst einmal
Auf die erste Frage: ich habe vom HMC5983 Die x,y,z Werte
Olaf schrieb:> Auf die erste Frage: ich habe vom HMC5983 Die x,y,z Werte
Sorry: die Frage bezog sich darauf, welche (trigonometrischen)
Funktionen deine Umgebung denn überhaupt bereitstellt.
Wenn du nicht nur kein atan2, sondern auch kein arctan überhaupt hast,
dann wird es natürlich drastisch aufwändiger.
Hallo Jörg,
ja meine IDE arbeitet mit arctan (atan)
bekomme zur Zeit aber noch keine vernünftigen Werte.
Problem bei dem Code von Yalu ist,
dass bei mir die fabs Funktion Float ist, ich aber nur mit integer eine
AND verknüpfung machen darf.......
sorry für so viel unwissen
Olaf schrieb:> dass bei mir die fabs Funktion Float ist, ich aber nur mit integer eine> AND verknüpfung machen darf
Da steht ja auch "fabs(...) <Vergleichsoperator> <wasanderes>", und
das Resultat der Vergleichsoperation ist natürlich ein Boolescher
Wert.
Hier nun mal mein Code:
Finde den Fehler :-)
If (datx = 0 And daty = 0) Then Kursrad = 0
'___________________________________________________
ElseIf (datx)>=0 And (fabs (daty)<= datx )Then
Kursrad = atan(daty/datx)
'________________________________________________________________
ElseIf daty >=0 And (fabs(datx)<= daty)Then
Kursrad = 1.5708 - atan(datx/daty)
'______________________________________________________________
ElseIf daty <=0 And (fabs(datx)<= fabs(daty)) Then
Kursrad = -1.5708 - atan(datx/daty):
'________________Fall
4______________________________________________
ElseIf daty>=0 Then Kursrad =3.1416 + atan(daty/datx):
Else Kursrad = -3.1416 + atan(daty/datx)
End If
Es scheint ein Teil der Formel nicht zu passen,
ich soll als Ergebniss Werte von - pi bis +pi bekommen.
Wenn ich mein Kompassmodul drehe bekomme ich in Teilkreisen von ca. 1/4
Umdrehungen gute fließende Werte. dann bleibt das Ergebniss aber längere
Zeit konstant. Obwohl meine Ausgangswerte x,y weiter verändern.
Olaf schrieb:> die Daten x,y, und TAN2 Ergebnis aus einer 360° Drehung (per Hand)
Ich glaube, da laufen gleich mehrere Dinge schief:
1. Bei den Divisionen datx / daty bzw. daty / datx scheinen die
Nachkommastellen abgeschnitten zu werden. Vermutlich sind beide
Operanden Integer-Variablen, was dazu führt, dass auch das Ergebnis
vom Typ Integer ist. Du müsstest mindestens einen der beiden
Operanden in ein Single konvertieren, damit die Division ebenfalls
Single ist und damit seine Nachkommastellen behält. Wie das geht,
weiß ich nicht. Wenn dir nichts besseres einfällt, kannst du es mit
1.0 * datx / daty
versuchen, auch wenn das nicht sehr elegant ist.
2. Die Vergleiche, in denen die fabs-Funktion verwendet wird, scheinen
so ausgeführt zu werden, also ob das fabs nicht vorhanden wäre. Statt
fabs(datx) <= fabs(daty)
wird also
datx <= daty
ausgewertet. Vielleicht hat fabs, das als Argument ein Single
erwartet, ein Problem, wenn es stattdessen ein Integer bekommt.
Eigentlich sollte der Wert in diesem Fall automatisch konvertiert
werden, aber wer weiß ...
3. Schließlich scheint beim Ergebnis der gesamten Berechnugn das
Vorzeichen verloren zu gehen, weswegen alle Ergebnisse nichtnegativ
sind. Vielleicht wird der Wert richtig berechnet, und der Fehler
geschieht erst bei der Ausgabe.
Wenn ich diese drei Probleme in einer anderen Programmiersprache
(Python) künstlich nachstelle, kommen tatsächlich exakt die von dir
aufgelisteten Ergebnisse heraus.
Falls du nicht weiterkommst, kannst du ja mal die an der Berechnung
beteiligten Operationen (Division, fabs, Vergleich, atan und die
Ausgabe) mit verschiedenen Operanden (Integer, Single, positiv und
negativ) einzeln testen,
- um zu sehen, und welchen Bedingungen die Fehler passieren, und
- um sicherzustellen, dass es sich dabei nicht um Compiler-Bugs handelt.