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
Olaf schrieb: > Finde den Fehler :-) Sollte nicht böse gemeint sein, sorry, aber ich bin schon am verzweifeln....
du könntest ja zumindest angeben wie sich der Fehler äußert
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.
DAs gleiche passiert übrigends auch wenn ich die Formel von Wiki (bild weiter oben) benutze
Dann poste doch mal die Rohdaten zusammen mit deinem Ergebnis als Tabelle (oder CSV-Datei).
Hallo, die Daten x,y, und TAN2 Ergebnis aus einer 360° Drehung (per Hand)
1 | X= -38 Y= -156 ATAN2 Erg. : 1.815782 |
2 | X= -38 Y= -156 ATAN2 Erg. : 1.815782 |
3 | X= -38 Y= -156 ATAN2 Erg. : 1.815782 |
4 | X= -33 Y= -108 ATAN2 Erg. : 1.892554 |
5 | X= -33 Y= -108 ATAN2 Erg. : 1.892554 |
6 | X= -33 Y= -108 ATAN2 Erg. : 1.892554 |
7 | X= -33 Y= -108 ATAN2 Erg. : 1.892554 |
8 | X= -249 Y= -392 ATAN2 Erg. : 2.356202 |
9 | X= -249 Y= -392 ATAN2 Erg. : 2.356202 |
10 | X= -249 Y= -392 ATAN2 Erg. : 2.356202 |
11 | X= 2 Y= -593 ATAN2 Erg. : 1.567418 |
12 | X= 2 Y= -593 ATAN2 Erg. : 1.567418 |
13 | X= 2 Y= -593 ATAN2 Erg. : 1.567418 |
14 | X= 2 Y= -593 ATAN2 Erg. : 1.567418 |
15 | X= 215 Y= -558 ATAN2 Erg. : 1.107149 |
16 | X= 215 Y= -558 ATAN2 Erg. : 1.107149 |
17 | X= 215 Y= -558 ATAN2 Erg. : 1.107149 |
18 | X= 215 Y= -558 ATAN2 Erg. : 1.107149 |
19 | X= 390 Y= -365 ATAN2 Erg. : 0.000000 |
20 | X= 390 Y= -365 ATAN2 Erg. : 0.000000 |
21 | X= 390 Y= -365 ATAN2 Erg. : 0.000000 |
22 | X= 441 Y= -111 ATAN2 Erg. : 0.000000 |
23 | X= 441 Y= -111 ATAN2 Erg. : 0.000000 |
24 | X= 441 Y= -111 ATAN2 Erg. : 0.000000 |
25 | X= 441 Y= -111 ATAN2 Erg. : 0.000000 |
26 | X= 311 Y= 93 ATAN2 Erg. : 0.000000 |
27 | X= 311 Y= 93 ATAN2 Erg. : 0.000000 |
28 | X= 311 Y= 93 ATAN2 Erg. : 0.000000 |
29 | X= 311 Y= 93 ATAN2 Erg. : 0.000000 |
30 | X= 95 Y= 176 ATAN2 Erg. : 1.570800 |
31 | X= 95 Y= 176 ATAN2 Erg. : 1.570800 |
32 | X= 95 Y= 176 ATAN2 Erg. : 1.570800 |
33 | X= -40 Y= 147 ATAN2 Erg. : 1.570800 |
34 | X= -40 Y= 147 ATAN2 Erg. : 1.570800 |
35 | X= -40 Y= 147 ATAN2 Erg. : 1.570800 |
36 | X= -40 Y= 147 ATAN2 Erg. : 1.570800 |
37 | X= -218 Y= 85 ATAN2 Erg. : 2.677948 |
38 | X= -218 Y= 85 ATAN2 Erg. : 2.677948 |
39 | X= -218 Y= 85 ATAN2 Erg. : 2.677948 |
40 | X= -218 Y= 85 ATAN2 Erg. : 2.677948 |
41 | X= -283 Y= -37 ATAN2 Erg. : 2.999699 |
42 | X= -283 Y= -37 ATAN2 Erg. : 2.999699 |
43 | X= -283 Y= -37 ATAN2 Erg. : 2.999699 |
44 | X= -283 Y= -37 ATAN2 Erg. : 2.999699 |
45 | X= -235 Y= -315 ATAN2 Erg. : 2.356202 |
46 | X= -235 Y= -315 ATAN2 Erg. : 2.356202 |
47 | X= -235 Y= -315 ATAN2 Erg. : 2.356202 |
48 | X= -173 Y= -246 ATAN2 Erg. : 2.356202 |
49 | X= -173 Y= -246 ATAN2 Erg. : 2.356202 |
50 | X= -173 Y= -246 ATAN2 Erg. : 2.356202 |
:
Bearbeitet durch Moderator
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.
Danke für deine Mühe, ich werde deine Tipps die Tage mal versuchen umzusetzen. Melde mich dann später nochmal.
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.