Variable im Register verändern
-
Also ich hab nen Joystick und der hat drei Achsen die leider nie genau den Wert 0.00000000000 annehmen. Ich möchte aber eine Schleife programmieren in die nur dann reingesprungen wird wenn der Wert von Null abweicht, also wenn der Joystick bewegt wird. Wenn jetzt aber der Wert im Register nie Null wird, wird immer in die Schleife gesprungen und das muss ich irgendwie verhindern.
Achso ja und mit Nachkommastellen meine ich dass der Wert eben nicht "0.00000000" ist sondern halt zum Beispiel "-0.00782788"
-
laura84 schrieb:
Also ich hab nen Joystick und der hat drei Achsen die leider nie genau den Wert 0.00000000000 annehmen. Ich möchte aber eine Schleife programmieren in die nur dann reingesprungen wird wenn der Wert von Null abweicht, also wenn der Joystick bewegt wird. Wenn jetzt aber der Wert im Register nie Null wird, wird immer in die Schleife gesprungen und das muss ich irgendwie verhindern.
Fließkommazahlen mit einem Wert auf Gleichheit zu prüfen ist nie eine gute Idee. Für diesen Fall prüfst du einfach, ob der Absolutbetrag des Wertes größer als ein bestimmter Schwellwert ist.
-
Ja das habe ich auch schon überlegt, aber dann hatte ich es wieder verworfen, da ich dachte dass es mit dem Runden klappt. Ich habs jetzt mal so probiert:
if (0.05 < var || var < -0.05)Allerdings habe ich jetzt das Problem dass beim ersten mal Auslesen der Joystick Achsen immer ein Zufalls-Wert ausgelesen wird und der nicht mal annähernd 0 ist. Also wird immer beim ersten mal die Schleife aufgerufen und da in der Schleife nicht nochmal neu abgefragt wird springt er nie mehr raus.
-
laura84 schrieb:
Ja das habe ich auch schon überlegt, aber dann hatte ich es wieder verworfen, da ich dachte dass es mit dem Runden klappt. Ich habs jetzt mal so probiert:
if (0.05 < var || var < -0.05)Allerdings habe ich jetzt das Problem dass beim ersten mal Auslesen der Joystick Achsen immer ein Zufalls-Wert ausgelesen wird und der nicht mal annähernd 0 ist. Also wird immer beim ersten mal die Schleife aufgerufen und da in der Schleife nicht nochmal neu abgefragt wird springt er nie mehr raus.
Das Problem hättest du doch auch mit Runden oder? So ganz verstehe ich das nicht. Wie kommst du denn sonst aus der Schleife? Hilft es, wenn du den Wert vor der Abfrage nochmal ausliest?
-
Redest du hier von CPU-Registern? So ganz klar wird mir dass hier nämlich nicht.
Gleitkommazahlen setzen sich zusammen aus Vorzeichen, Mantisse, Basis und Exponent.
Siehe: IEEE 754
-
Ich hab das jetzt schon hinbekommen. Jetzt scheiterts wieder an was Anderem.

Zu der Schleifenbedingung habe ich auch noch was hinzugefügt.FrEEzE2046 schrieb:
Redest du hier von CPU-Registern?
Naja ich rede halt von den Registern in die VC++ seine Variablen abspeichert, ich denke das sind CPU Register.?.

-
laura84 schrieb:
Ich hab das jetzt schon hinbekommen. Jetzt scheiterts wieder an was Anderem.

Zu der Schleifenbedingung habe ich auch noch was hinzugefügt.Poste doch mal deinen Code. Dann kann man da sicherlich mehr zu sagen.
-
laura84 schrieb:
Naja ich rede halt von den Registern in die VC++ seine Variablen abspeichert, ich denke das sind CPU Register.?.

Hört sich so an als wäre da noch einiges Ungewiss bei dir. Ich kommentier den Satz jetzt mal nicht weiter und frag lieber:
Was ist die Aufgabe die du dir gesetzt hast? Was genau willst du erreichen?
-
Ist aber ziemlich verwirrend, außerdem muss ich dann erstmal mein eigentliches Vorhaben schildern:
Also wenn man den Joystick nach rechts/links/oben/unten bewegt würde ein damit gesteuertes Flugzeug ja einfach sofort in diese Richtung kippen. Ich möchte aber dass eine Verzögerung eingebaut wird. Und zwar soll das imaginäre Flugzeug sich bei Vollausschlag um 5 Grad in der Sekunde neigen.
Ich hoffe das ist verständlich. Und achja, ich möchte keinen Flugsimulator programmieren.
Außerdem sollte ich vielleicht noch dazu sagen dass ich die "plib" nutze, für die Joystick Anbindung.Hier mein Code:
#define WIN32_LEAN_AND_MEAN #include <js.h> #include <windows.h> #include <stdio.h> #include <windowsx.h> #include <stdlib.h> #include <iostream> using namespace std; CRITICAL_SECTION csQueueInAccess; jsJoystick *js; float *ax; int count = 0; int count2 = 0; int count3 = 0; int count4 = 0; float aend[3]; DWORD WINAPI ThreadFunc(LPVOID data) { EnterCriticalSection(&csQueueInAccess); for (int j = 0; j < 3; j++) { ax[j] = floorf(ax[j]*100 + .5)/100.; aend[j] = ax[j] * 5; while (0.05 < ax[j] || ax[j] < -0.05) { count4 = count3 + 1; Sleep(1000); while (count4>count3 && (0.05 < ax[j] || ax[j] < -0.05)) { aend[j] += aend[j]; } } printf (" "); printf ("%+.1f ", aend[j]); } return((DWORD)data); LeaveCriticalSection(&csQueueInAccess); } int main ( int, char ** ) { HANDLE hThread; DWORD dwThreadID; int index; InitializeCriticalSection(&csQueueInAccess); jsInit (); js = new jsJoystick (0); if (js->notWorking ()) printf ("Joystick not detected\n"); else printf ("Joystick is \"%s\"\n\n", js->getName()); if (js->notWorking ()) exit (1); ax = new float [js->getNumAxes ()]; int j; count2 = count + 1; Sleep (30); while (count2>count) { printf ("Joystick test program.\n"); printf ("~~~~~~~~~~~~~~~~~~~~~~\n\n"); printf ("+---------JS----------"); printf ("+----------------+\n"); printf ("| Btns "); for (j = 0 ; j < 3 ; j++) printf ("Ax:%d ", j); for ( ; j < 3 ; j++ ) printf (" "); printf ("|"); printf (" Aenderung |\n"); printf ("+---------------------"); printf ("+----------------+\n"); int b; js->read (&b, ax); printf ("| %04x ", b); for (j = 0 ; j < 3 ; j++) { ax[j] = floorf(ax[j]*100 + .5)/100.; printf ("%+.1f ", ax[j]); } printf("| "); for (int i = 0; i < 3; i++) { if (0.05 < ax[i] || ax[i] < -0.05) { hThread = CreateThread(NULL, 0, ThreadFunc, (LPVOID)index, 0, &dwThreadID); WaitForSingleObject(hThread, 15); CloseHandle(hThread); } } system("cls"); } DeleteCriticalSection(&csQueueInAccess); getchar(); return 0; }
-
Hmm erschließt sich mit tatsächlich nicht auf Anhieb
. Wozu brauchst du die Threads? Wenn ich das richtig sehe erzeugst du immer einen Thread und wartest dann darauf, das der fertig ist.
-
Was meinst du mit Verzögerung? Soll sich das Flugzeug zeitlich später neigen? soll die Neigung begrenzt werden?
-
siecpp schrieb:
Wenn ich das richtig sehe erzeugst du immer einen Thread und wartest dann darauf, das der fertig ist.
Siehst du richtig. Macht überhaupt keinen Sinn

Mit Verzögerung meint er wohl, dass das Flugzeug nicht sofort "volles rohr" nach oben/unten ziehen soll, sondern der Grad des Steigens zunimmt ... oder so ähnlich.
-
FrEEzE2046 schrieb:
Mit Verzögerung meint er wohl, dass das Flugzeug nicht sofort "volles rohr" nach oben/unten ziehen soll, sondern der Grad des Steigens zunimmt ... oder so ähnlich.
Das würde ja heißen den Joystickausschlag uber die Zeit zu integrieren (bzw zu addieren, da das ja diskret ist).
-
Also die Threads brauche ich, da ich eine Art Timer bauen musste um diese Verzögerung zu gestalten. Die Versögerung meinte ich so, dass wenn der Joystick ganz nach rechts gedrückt wird, bekomme ich ja den Wert +1.0 zurückgegeben. Das Flugzeug soll aber nicht sofort zur Seite kippen sondern immer nur 5 Grad pro Sekunde nach rechts geneigt werden. Wenn ich nur halb nach rechts drücke soll auch nur 2.5 Grad pro Sekunde geneigt werden.
Ich wollte das so machen, dass ich den Rückgabe Wert des Joysticks mal 5 rechne und dann pro Sekunde diesen Wert immer einmal aufaddiere. Leider funktioniert das eben nicht. Außerdem sollte das ja aufhören wenn der Joystick in eine andere Richtung gedrückt wird, bzw. einfach losgelassen wird.
Warum sollte das mit den Threads keinen Sinn machen? Ich bin irgendwann auf die Schlussfolgerung gekommen dass es ohne Threads nicht machbar ist. Man muss aber auch dazu sagen dass das mein erstes Programm in Richtung Multithreading ist und ich deswegen einiges falsch gemacht haben könnte.
-
laura84 schrieb:
Also die Threads brauche ich, da ich eine Art Timer bauen musste um diese Verzögerung zu gestalten. Die Versögerung meinte ich so, dass wenn der Joystick ganz nach rechts gedrückt wird, bekomme ich ja den Wert +1.0 zurückgegeben. Das Flugzeug soll aber nicht sofort zur Seite kippen sondern immer nur 5 Grad pro Sekunde nach rechts geneigt werden. Wenn ich nur halb nach rechts drücke soll auch nur 2.5 Grad pro Sekunde geneigt werden.
Ich wollte das so machen, dass ich den Rückgabe Wert des Joysticks mal 5 rechne und dann pro Sekunde diesen Wert immer einmal aufaddiere.OK ich denke fals ich dich richtig verstehe ist es das, was ich mit integrieren gemeint habe.
laura84 schrieb:
Leider funktioniert das eben nicht. Außerdem sollte das ja aufhören wenn der Joystick in eine andere Richtung gedrückt wird, bzw. einfach losgelassen wird..
Das müsste doch implizit funktionieren. Wenn der Joystick Null liefert wird die Neigung beibehalten, wenn der Wert negativ ist wird die Neigung verringert. Ich denke das Problem ist, das du einfach losprogrammiert hast ohne genau zu wissen was du tun willst. Das geht meistens in die Hose. Du solltest dir erstmal überlegen wie die Lösung konzeptionell funktionieren soll.
laura84 schrieb:
Warum sollte das mit den Threads keinen Sinn machen?
Threads machen bei deiner Lösung keinen Sinn. Threads sind dazu da, Dinge parallel zu machen. So wie du das gemacht hast, läuft aber immer nur ein Thread. Was soll das bringen?
laura84 schrieb:
Ich bin irgendwann auf die Schlussfolgerung gekommen dass es ohne Threads nicht machbar ist.
Ich denke Threads könnten durchaus nützlich sein bei dem was du machen möchtest aber nicht bei dem was du machst

laura84 schrieb:
Man muss aber auch dazu sagen dass das mein erstes Programm in Richtung Multithreading ist und ich deswegen einiges falsch gemacht haben könnte.

Der Punkt ist, dass deim Programm kein Multithreading macht.
-
siecpp schrieb:
Threads machen bei deiner Lösung keinen Sinn. Threads sind dazu da, Dinge parallel zu machen. So wie du das gemacht hast, läuft aber immer nur ein Thread. Was soll das bringen?
Ich denke Threads könnten durchaus nützlich sein bei dem was du machen möchtest aber nicht bei dem was du machst
Der Punkt ist, dass deim Programm kein Multithreading macht.Okay, jetzt wohl nicht mehr, da hast du recht. Ich hatte vorher in der main die Abfrage der Werte in einer endlos-while-Schleife und wollte gleichzeitig einen Wert ändern der in dieser Schleife genutzt wurde, deshalb hatte ich mich fürs (damals war es noch ein) Multithreading entschieden. Gestern habe ich dann die Endlosschleife abgeändert in eine zeitlich begrenzte Abfrage, seitdem ist mein Programm wohl kein Multithreading Programm mehr.

Mittlerweile klappt alles, also auch die Verzögerung habe ich gerade hinbekommen. Ich programmiere meistens einfach so drauf los, obwohl mir hier schon vorher bewusst war was ich erreichen möchte. Trotzdem bin ich wohl eher der Try-and-Error Typ. Ich programmiere aber auch noch nicht sehr lange.
Das einzige Problem dass ich jetzt noch habe ist die Ausgabe. Die will einfach nicht klappen. Momentan möchte ich die Werte ja einfach nur mal angezeigt bekommen, aber durch diese ständigen Abfragen musste ich ja ein
system ("cls");einbauen, sonst könnte man ja gar nichts mehr sehen. Allerdings gibt er mir jetzt nicht die veränderten Werte aus. Weißt du wpran das liegen könnte?
-
laura84 schrieb:
Allerdings gibt er mir jetzt nicht die veränderten Werte aus. Weißt du wpran das liegen könnte?
meinst du diese stelle im code?
printf (" "); printf ("%+.1f ", aend[j]);Wird da garnichts ausgegeben oder nur nicht das, was du möchtest? Was sagt der Debugger? Wesshalb benutzt du printf und nicht cout?
-
Ja genau die Stelle meinte ich, allerdings hab ich die erste Zeile jetzt weg gelassen, weil sie mittlerweile überflüssig ist. Außerdem hab ich herausgefunden dass es mir kurz ausgegeben wird, aber dann durch den "cls" Befehl gleich wieder gelöscht wird.
siecpp schrieb:
Wesshalb benutzt du printf und nicht cout?
Naja um ehrlich zu sein weil ich nicht wüsste wie ich sonst diese Zeilen ausgeben könnte:
printf ("Joystick is \"%s\"\n\n", js->getName());printf ("%+.1f ", ax[j]);Also das Begrenzen der float Variablen geht wohl irgendwie mit
setprecisionaber das geht bei mir irgendwie nicht, da gibt er dann mal keine Nachkommastelle an oder auch mal zwei, wie er gerade will. Deshalb nutze ich printf.
Mittlerweile ist mir noch aufgefallen, dass die Verzögerung jetzt wohl klappt, aber nur beim ersten mal Joystick bewegen und wenn ich dann wieder auf Null gehe ruft er mir nie wieder den Thread auf, egal wie ich den Joystick bewege. Außerdem wird immer nur eine Achse beachtet, wenn ich gleichzeitig nach oben und nach rechts drücke nimmt er nur die Achse die zuerst btätigt wurde.
Ich poste jetzt nochmal meinen Code, weil ich den jetzt nochmal abgeändert hab, vielleicht kannst du mir ja doch noch irgendwie helfen auch wenns total unübersichtlich ist.
#define WIN32_LEAN_AND_MEAN #include <js.h> #include <windows.h> #include <stdio.h> #include <windowsx.h> #include <stdlib.h> #include <iostream> using namespace std; CRITICAL_SECTION csQueueInAccess; #define MAX_THREADS 3 jsJoystick *js; float *ax; int count = 0; int count2 = 0; int count3 = 0; int count4 = 0; int index = 0; float aend[3]; float ausg[3]; int b; int j; DWORD WINAPI ThreadFunc(LPVOID data) { EnterCriticalSection(&csQueueInAccess); while (0.05 < ax[j] || ax[j] < -0.05) { count4 = count3 + 1; Sleep(1000); while (count4>count3 && (0.05 < ax[j] || ax[j] < -0.05)) { aend[j] = ax[j] * 5; ausg[j] += aend[j]; js->read (&b, ax); ax[j] = floorf(ax[j]*100 + .5)/100.; } aend[j] = 0; ausg[j] = 0; } printf ("%+.1f ", ausg[j]); return((DWORD)data); LeaveCriticalSection(&csQueueInAccess); } int main ( int, char ** ) { HANDLE hThread[MAX_THREADS]; DWORD dwThreadID[MAX_THREADS]; InitializeCriticalSection(&csQueueInAccess); jsInit (); js = new jsJoystick (0); if (js->notWorking ()) printf ("Joystick not detected\n"); else printf ("Joystick is \"%s\"\n\n", js->getName()); if (js->notWorking ()) exit (1); ax = new float [js->getNumAxes ()]; count2 = count + 1; Sleep (30); while (count2>count) { printf ("Joystick test program.\n"); printf ("~~~~~~~~~~~~~~~~~~~~~~\n\n"); printf ("+---------JS----------"); printf ("+----------------+\n"); printf ("| Btns "); for (j = 0 ; j < 3 ; j++) printf ("Ax:%d ", j); for ( ; j < 3 ; j++ ) printf (" "); printf ("|"); printf (" Aenderung |\n"); printf ("+---------------------"); printf ("+----------------+\n"); js->read (&b, ax); printf ("| %04x ", b); for (j = 0 ; j < 3 ; j++) { ax[j] = floorf(ax[j]*100 + .5)/100.; printf ("%+.1f ", ax[j]); } printf("| "); for (index = 0; index < 2; index++) { for (j = 0; j < 2; j++) { if (0.05 < ax[j] || ax[j] < -0.05) { hThread[index] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)index, 0, &dwThreadID[index]); WaitForSingleObject(hThread[index], 15); CloseHandle(hThread[index]); } } } system("cls"); } DeleteCriticalSection(&csQueueInAccess); getchar(); return 0; }
-
laura84 schrieb:
Naja um ehrlich zu sein weil ich nicht wüsste wie ich sonst diese Zeilen ausgeben könnte:
printf ("Joystick is \"%s\"\n\n", js->getName());printf ("%+.1f ", ax[j]);cout << "Joystick is \"" << js->getName() << ""\" << endl << endl;cout << setprecision(2) << ax[j];laura84 schrieb:
Mittlerweile ist mir noch aufgefallen, dass die Verzögerung jetzt wohl klappt, aber nur beim ersten mal Joystick bewegen und wenn ich dann wieder auf Null gehe ruft er mir nie wieder den Thread auf, egal wie ich den Joystick bewege. Außerdem wird immer nur eine Achse beachtet, wenn ich gleichzeitig nach oben und nach rechts drücke nimmt er nur die Achse die zuerst btätigt wurde.
Ich blicke da leider immer noch nicht ganz durch. Vielleicht kannst du das mal kommentieren. Was ich aber denke ist, dass du aus den Schleifen nie wieder rauskommst, weil sich die Bedingung wärend der Schleife nicht ändert. Auch das j bleibt immer gleich. Vielleicht ist das der Grund, warum immer nur eine Achse beachtet wird. Ich denke langsam dämmert mir, was du machen möchtest. Du möchtest wahrscheinlich alle Threads parallel laufen lassen, wartest mit dem starten des nächsten Threads aber immer, bis der letzte fertig ist, was nie passiert.
-
Eine zusätzlich Anmerkung: Falls du wirklich alle Threads parallel laufen lassen möchtest, kannst du das natürlich nicht mit der globalen Variable j machen, da diese für alle Threads gleich ist und somit jeder Thread dasselbe machen würde, Du müsstest statdessen jedem thread sein eigenes j als parameter mitgeben.