Arkustangens
-
Der Arkustangens IST der Winkel.
(ggf. nach einer Bereichsanpassung auf )Aus Sinus und Cosinus kannst du höchstens den Tangens oder Cotangens errechnen.
-
MrChipsy schrieb:
Na Super, das Bild hat sich leider verschoben.
Dagegen gibt es die Code oder cpp Tags (Text markieren und einen der Buttons unter den
:p drücken)
Kommst du an den Wert ran, der in den Doppelintegrator rein geht?
Und brauchst du nicht eigentlich den atan2 ?
-
wenn der den winkel schon hat und nen sinus und nen cosinus berechnen kann, dann braucht er den arctan nicht, denn dann hat er den winkel schon.
siehe post von bashar
-
merk0r schrieb:
wenn der den winkel schon hat und nen sinus und nen cosinus berechnen kann, dann braucht er den arctan nicht, denn dann hat er den winkel schon.
Ach
-
Ich komme leider nicht an den Eingangswert des Doppelintegrators ran.
Der Ausgangswert des Doppelintegrators läuft zum einen in den Sinus Cosinus Generator, zum anderen auch in einen Quantisierer.
Aus der Addition des quantisierten Wertes und dem ATAN Wert vom Sinus Consinus Generator soll dann wieder der Winkel entstehen.Achso und der Satz mit dem Anfängerunsinn:
Ja, ich bin Anfänger und das ist die Aufgabe die mir gegeben wurde um C zu lernen.
-
Und was ist mit den schon genannten CORDIC oder der Integraldefinition? Technisch gesehen sind das keine Reihenentwicklungen (Reihenentwicklungen sind sowieso etwas für die Theorie und
nichtsehr selten praxistauglich). Vielleicht kann man sich auch ein passendes Newtonverfahren ausdenken. Für die Wurzel beim integral kannst du auf jeden Fall ein Newtonverfahren nehmen, 2-3 Iterationen reichen meistens. Aber guck dir zuerst einmal CORDIC an. Oder wenn dir das zu schwer ist, mach einen weiteren Lookup-Table mit Interpolation (aber großartig anders ist CORDIC auch nicht). Oder wenn du es gerne optimiert haben möchtest, dann guck dir mal das hier an:
http://www.electronics.dit.ie/staff/aschwarzbacher/research/ecs99.pdf
-
MrChipsy schrieb:
Ich komme leider nicht an den Eingangswert des Doppelintegrators ran.
Das wäre ja auch die Winkelbeschleunigung, non? Du brauchst den Ausgangswert des Doppelintegrators.
-
Ich habe nochmal mit meinem Betreuer gesprochen und jetzt kann ich den CORDIC benutzen. Ich soll damit allerdings dann ATAN2(oder ARCTAN2) bestimmen.
-
MrChipsy schrieb:
Ich habe nochmal mit meinem Betreuer gesprochen und jetzt kann ich den CORDIC benutzen. Ich soll damit allerdings dann ATAN2(oder ARCTAN2) bestimmen.
Ist ja auch sinnvoller. Mit dem atan bekommst du ja nur den halben Kreis.
Beachte aber auch die Reihenfolge der Parameter von der Funktion (atan2) aus der Standardbibliothek.
Du solltest es nicht anders machen.
-
Ich muss das ganze erst einmal verstehen, weiss noch nicht so richtig wie ich den Cordic-Alg. umsetzen soll. Das ist fürn Neuling ein wenig heavy.
-
Ich habe einen vorhandenen Cordic-Alg implementiert und auf meine Vorgaben hin abgeändert, allerdings liefert dieser mir nur falsche Werte. Sieht jemand einen Fehler?
float i_atan2(int x,int y) { float result; int k=0,xh=0,yh=0,winkel=0; int lmax = (0x1FFFFFFF); // die Eingangswerte begrenzen while ( x>lmax || (-x)>lmax || y>lmax || (-y)>lmax ) { x = x >> 1 ; y = y >> 1; } // initalisierung if(y>=0) { xh = y; yh = -x; winkel = -i_atantab[0]; } else { xh = -y; yh = x; winkel = i_atantab[0]; } x = xh; y = yh; // iteration maximum: i<31 for (int i=0;i<15;i++) { if(y>=0) { winkel -= i_atantab[i]; xh = x +( y >> k ); yh = y -( x >> k ); } else { winkel += i_atantab[i]; xh = x -( y >> k ); yh = y +( x >> k ); } x = xh; y = yh; k = k+1; } result=(float)(-winkel); return (result); }
Float als Rückgabewert war Vorgabe, weshalb ich am Ende den Winkel noch caste. Die Eingangswerte x und y sind die Werte aus meinem Sinus Cosinus Generator.
-
Winkel werden bei Computern meist/oft/häufig im Bogenmaß angegeben.
Du scheinst aber mit Grad zu rechnen.
Wofür ist der Algorithmus denn ausgelegt.Zum ausprobieren fehlt das i_atantab Array
-
Oh natürlich,
static const int i_atantab[] = { 1073741824,536870912,316933405,167458907,85004756,42667331,21354465,10679838, 5340245,2670163,1335087,667544,333772,166886,83443,41722,20861,10430,5215,2608, 1304,652,326,163,81,41,20,10,5,3,1};
Die Werte von x und y sind Fließkommazahlen, weshalb ich diese in der main auf Festkomma wandle und dann erst in die atan2 Funktion übergebe.
-
Die for-Schleife muss bei 1 anfangen.
(Das Element 0 benutzt du schon bei der initialisierung)Und die Rückgabewerte musst du noch skalieren
result=(float)((180.0 * -winkel)/(0x7FFFFFFFL));
-
Ich habe die Skalierung in der main vorgenommen. Habe deinen Vorschlag eingebaut, jedoch kommt nach wie vor ein falscher Wert heraus.
WinkelA= 0.000000 | WinkelF= -43.254131 | error= 43.254131
WinkelA= 0.099997 | WinkelF= 84.269104 | error= 84.169106
WinkelA= 0.199995 | WinkelF= 78.535240 | error= 78.335243
WinkelA= 0.299993 | WinkelF= 72.809349 | error= 72.509354
WinkelA= 0.399990 | WinkelF= 67.076645 | error= 66.676651
WinkelA= 0.499989 | WinkelF= 61.349762 | error= 60.849773
WinkelA= 0.599987 | WinkelF= 55.623222 | error= 55.023235
WinkelA= 0.699987 | WinkelF= 49.897209 | error= 49.197224
WinkelA= 0.799986 | WinkelF= 44.158195 | error= 43.358208
WinkelA= 0.899986 | WinkelF= 38.432198 | error= 37.532211
WinkelA= 0.999985 | WinkelF= 32.698338 | error= 31.698353
WinkelA= 1.099985 | WinkelF= 26.971798 | error= 25.871813
WinkelA= 1.199985 | WinkelF= 21.245785 | error= 20.045799
WinkelA= 1.299985 | WinkelF= 15.512209 | error= 14.212224
WinkelA= 1.399986 | WinkelF= 9.786195 | error= 8.386209
WinkelA= 1.499986 | WinkelF= 4.059656 | error= 2.559670
WinkelA= 1.599987 | WinkelF= -1.667833 | error= 3.267820
WinkelA= 1.699988 | WinkelF= -7.395354 | error= 9.095342
WinkelA= 1.799989 | WinkelF= -13.135355 | error= 14.935344
WinkelA= 1.899990 | WinkelF= -18.867949 | error= 20.767939
-
WinkelA ist der Wert der math.h atan2 Funktion, WinkelF ist der Wert den meine Funktion zurückliefert.
-
Mit welchen Werten rufst du denn die Funktionen auf?
Zeig doch mal die Funktion, mit der du die Ausgabe ("WinkelA= 0.000000 | WinkelF= -43.254131 | error= 43.254131 ") machst.
-
Also diesen Aufruf erzeuge ich über ein Textfile
fprintf(ATANFILE,"WinkelA= %f|WinkelF= %f|error= %f\n",atan2(mysin,mycos),winkelF,error);
Der Funktionsaufruf für atan2 : winkelF = (i_atan2(mysin2,mycos2));
mysin und mycos werden in einer anderen Funktion berechnet und anschließend für atan2 in integer umgewandelt.mysin2 = (int)(mysinPOW_31_MINUS_1);
mycos2 = (int)(mycosPOW_31_MINUS_1);In der main läuft eine for-Schleife, die mir 20 Sinus/Cosinus Werte und daraus atan2 Werte berechnet.Hier doch besser die main:
int main() { int i; int mysin2,mycos2; float angle=0,error=0.0; float mysin,mycos,arctan,winkelF=0.0; ATANFILE=fopen("atan.txt","w"); for(i=0;i<20;i++) { mysin = sinF(angle); mycos = cosF(angle); mysin2 = (int)(mysin*POW_31_MINUS_1); mycos2 = (int)(mycos*POW_31_MINUS_1); winkelF = (i_atan2(mysin2,mycos2)); error = fabs(winkelF-atan2(mysin,mycos)); fprintf(ATANFILE,"WinkelA= %f | WinkelF= %f | error= %f \n",atan2(mysin,mycos),winkelF,error); angle += 0.1; } fclose(ATANFILE); return 0; }
-
mysin/mycos liefert Werte zwischen -1 und 1
-
DirkB schrieb:
Beachte aber auch die Reihenfolge der Parameter von der Funktion (atan2) aus der Standardbibliothek.
Du solltest es nicht anders machen.Der Prototyp von atan2 aus der math.h lautet
double atan2 ( double y, double x );
Deine Funktion:
float i_atan2(int x,int y)
DirkB schrieb:
Winkel werden bei Computern meist/oft/häufig im Bogenmaß angegeben.
Du scheinst aber mit Grad zu rechnen.
Wofür ist der Algorithmus denn ausgelegt.atan2 aus der math.h gibt Bogenmaß zurück.
Bei der Umrechnung, die ich geschrieben habe, habe ich Grad verwendet, da Bogenmaß mit int nicht sehr sinnvoll ist.
(Wo ist diese Umrechnung denn jetzt? Du hast geschrieben die sei in der main)Statt POW_31_MINUS_1 kannst du auch 10000 (oder 100000) nehmen.
Interresant sind doch die Werte für 0, 45, 90 ... Grad.
winkelF = (i_atan2( 10000, 0)); // 0 Grad winkelF = (i_atan2( 10000, 10000)); // 45 Grad winkelF = (i_atan2( 0, 10000)); // 90 Grad winkelF = (i_atan2(-10000, 0)); // 180 Grad winkelF = (i_atan2( 0, -10000)); // -90 Grad