Einlesen, speichern und ändern einer Choreografie von Tastendrücken

  • Hat das Spiel eine zeitliche Komponente? Dann wirst du um Bilderkennung nicht herumkommen. Oder ist das rein zugbasiert? Dann ist die Position entscheidend aufzuzeichnen, und die Zeit nur nachgeordnet.

  • Einlesen, speichern und ändern einer Choreografie von Tastendrücken? Schau mal ob du hier fündig wirst!

  • Es ist ein Autorennen, bei dem ich ein Gaspedal und ein Bremspedal habe. Aktuell nutze ich nur das Gaspedal und lasse zum Bremsen den Wagen rollen. Wenn ich den ersten Motor einigermaßen im Griff habe, werde ich versuchen, zwei Motoren zu steuern, um auch das Bremspedal zu nutzen. An Bilderkennung habe ich natürlich auch gedacht, weiß aber um meine limitierten Kenntnisse ;)

  • Dann wirst du keinen Erfolg haben. Alleine schon die immanente Ungenauigkeit zwischen Spielstart und dem Start seiner vordefinierten Sequenz bringt da Fehler rein. Dann gibts noch clockdrift zwischen den zwei Systemen, die weitere, akkumulierende Ungenauigkeiten mit sich bringt.

    Diese Ziel findet sich nur über den Weg der Bilderkennung. Da hast du keine andere Chance in meinen Augen.

  • Das Spiel hat verschiedene Modi. Bei dem von mir benutzten startet das Rennen mit dem ersten Drücken des Gaspedals. Die Übereinstimmung von Sequenz und Spiel ist folglich relativ einfach. Ich versuche das Gesamtsystem Schritt für Schritt zu verbessern, um in diesem Zuge zu lernen. Natürlich hat der Aufbau auch andere Schwächen, wie die Stabilität von Motor, Arm und Halterung. Aber auch das ist nur ein Einzelaspekt, den man optimieren kann.

    Hast Du Erfahrung mit Bilderkennung?

  • Mechanisch sollte natürlich so viel spiel wie möglich eliminiert werden.

    Und ja, ich habe Erfahrung mit Bilderkennung.

  • Mir ist klar, dass das Thema sehr weit weg ist. Dennoch würde mich interessieren, ob der Pi mit der Bilderkennung dafür geeignet wäre. Und sollte ich den Pi wegen seines Alters (Model B V1.1.) ersetzen müssen, welche Hardware wäre Deiner Meinung nach am besten dafür geeignet?

  • Grundsätzlich ist der PI geeignet, aber je mehr Leistung je besser. Ob man ihn nun ersetzen muss, kann ich nicht sagen. Bei einem solchen Projekt hat man oft den Vorteil, das die Grafik ja aus dem Computer kommt & recht gut dekonstruierbar ist. Dann reicht auch ein langsameres Modell.

  • @__deets__: Danke für Deine Einschätzung! Ich muss jetzt mal ein paar "Hausaufgaben" machen und leider komme ich in den nächsten Tagen nicht so richtig dazu, werde aber meinen Fortschritt gerne Teilen, wenn's soweit ist. Darüber hinaus muss ich noch herausfinden, wie ich meinen Pi aktualisiere. Dazu werde ich aber vermutlich lieber in einem neuen Beitrag fragen, weil dies ein anderes Thema darstellt.

  • Nun kann ich endlich wieder einen relevanten Fortschritt zeigen und den Inhalt dieses Thread abschließen. Natürlich freue ich mich dennoch über Anmerkungen, die mich und andere Interessierte weiterbringen!

    Im ersten Schritt habe ich den Raspberry Pi komplett neu aufgesetzt und die aktuellste Version von Python installiert. Als Anfänger denkt man ja nicht unbedingt daran, dass bestimmte Skripts nur deshalb nicht laufen, weil die Python-Version veraltet ist. Ich lerne dazu.

    Folgendes Setup habe ich jetzt:

    Raspberry Pi 2 Model B V1.1

    Betriebssystem: Linux-5.4.72-v7+-armv7l-with-debian-10.6

    Version: #1356 SMP Thu Oct 22 13:56:54 BST 2020

    Prozessor: armv7l

    Python-Version: CPython 3.7.3

    Compiler : GCC 8.3.0

    Build : ('default', 'Jul 25 2020 13:03:44')

    interpreter: ('32bit', 'ELF')

    Motor: Longruner SG90 Micro Servo Motor KY66

    Ich habe zwei Programme geschrieben:

    1. Das erste Programm nimmt die Choreografie auf. Mit dem Drücken der ENTER-Taste bewege ich den Motor vor. Wenn ich sie wieder loslasse, fährt der Motor wieder zurück. Die entsprechenden Zeiten von Drückdauer und den Zeiten zwischen dem Drücken, schreibe ich in eine Liste, welche ich am Ende in eine Datei "Choreografie.txt" übertrage. (Vermutlich könnte ich auch gleich in die Datei schreiben.)
    2. Das zweite Programm liest diese Zeiten aus der Datei aus und wiederholt die Choreografie.

    Wie zu erwarten lässt sich die Choreografie nicht in exakter Weise wiedergeben. Folgende Erklärungsversuche:

    1. Der Pi hat im Hintergrund andere Prozesse, die zu leichten Verzögerungen führen.
    2. Manchmal verschluckt der Aufbau/das Programm Sequenzen beim Abspielen. Der Motor sollte fahren, zuckt aber nur kurz.
    3. Der Motor hat grundsätzlich "Zuckungen". Ggf. liegt dies an einer suboptimalen Stromversorgung durch den Pi.
    4. Die App lässt das Fahrzeug trotz identischer Eingabe nicht exakt gleich fahren. Auch hier spielen vielleicht andere parallel laufende Prozesse mit rein.
    5. Der Aufbau von Motor und Pen, den ich an den Motorarm montiert habe, wird leichte unbemerkte Varianzen aufweisen - nicht starr genug.
    6. Interessanterweise arbeitet die Funktion pygame.event.get() nicht sauber. Obwohl ich die Entertaste konstant durchdrücke, misst die Funktion dennoch kurze Sequenzen, bei denen ich angeblich die Taste loslasse. Vielleicht arbeitet ja auch meine Tastatur unsauber?!

    Code des ersten Programms:

    Code des zweiten Programms:

    Abschließend nochmals Danke an alle, die mir bei dem kleinen Projekt weitergeholfen haben. Ich habe viel gelernt!

    Einmal editiert, zuletzt von djust (31. Oktober 2020 um 14:32)

  • Hallo djust,

    das mit den kurzen Sequenzen liegt daran, dass Du lediglich den Status der Taste abfragst. Üblicherweise ist es aber so, dass Du eine gedrückte Taste erst loslassen musst, bevor ein erneutes Drücken überhaupt registriert werden kann und darf. Du verwendet aber den Status "gedrückt" - und wenn die Taste immer noch gedrückt ist, gibt es eben ein neues Ereignis mit neuer Zeit (auch wenn die "alte" Zeit immer noch gilt).

    Deswegen verwendet man in GUI-Anwendungen auch nicht die Eigenschaft "pressed" sondern "released" als Basis von Anwender-Ereignissen.

    Hättest Du Motoren verwendet, deren Position man setzen und abfragen kann, ließe sich Dein Problem auf ein
    herkömmliches Teach-In reduzieren. So schaffst Du Dir halt Probleme, die extra-kompliziert anzugehen sind.

    Beispiel: Tiosch-Sonor (mehrmals hier im Forum vorgestellt und mit aussagekräftiger Abbildung versehen.) Damit ist eine Positionserkennung auf wenige Millimeter reproduzierbar möglich - bei Abständen bis zu 6 m).


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Du machst ja auch immer noch den Fehler, den ich dir schon ganz zu Beginn dargelegt habe: du gehst stumpf davon aus, dass time.sleep(wartezeit) exakt ist. Was es nachweislich nicht ist. Und dann auch noch obendrein voellig ignoriert, dass du ja auch anderen Code laufen laesst zwische deinen Warteperioden.

    Folgendes trivials Progamm legt das dar:

    Und resultiert auf meinem fetten PC ohne irgendwelche Last schon in einem merklichen Unterschied:

    Code
    15:06 $ python3 /tmp/test.py wrong 1000 0.01
    needed: 10.073621281999294
    15:06 $ python3 /tmp/test.py right 1000 0.01
    needed: 10.000085454999862

    Nicht nur sind das 3 Groessenordnungen schlechter, es ist ca 1% Abweichung / sleep. Das akkumuliert sich nunmal. Auf dem PI habe ich bei sleep schon teilweise zweistellige Abweichungen in Prozent ermittelt. Und das alles ist komplett ohne irgendwelche *anderen* Dinge, die man macht! Wenn die auch noch Zeit dauern, wird es ganz duester:

    Da schlaegt in deinem Ansatz die Zeit, die du etwas anderes machst, zu 100% auf die Gesamtzeit auf! Also hier 50% der Zeit!

    Code
    15:11 $ python3 /tmp/test.py right 100 0.1 0.05
    needed: 10.050174718000562
    15:11 $ python3 /tmp/test.py wrong 100 0.1 0.05
    15:11 $ needed: 15.021040810999693

    Ohne das du das erstmal in den Griff bekommst, ist das komplett fuer'n Poppes.

    Einmal editiert, zuletzt von MistyFlower59469 (1. November 2020 um 12:42)

  • Andreas ich verstehe deine Ausfuehrungen in diesem Zusammenhang nicht. Das das Standardverhalten von GUI-Rahmenwerken auf den Release abziehlt hat gute Gruende.

    Aber es ist absoluter Standard, dass in Situationen, in denen es sowohl auf schnelle Reaktion, als auch auf die Dauer eines Tastendruckes ankommt, diese Events so wie hier getrennt ausgewertet werden. Jedes Spiel mit Keyboard-Eingaben macht das so.

  • @__deets__ Vielen Dank für Deine ausführliche Darstellung! ich habe Dein Skript versucht zu starten und zu verstehen. Beides hat noch nicht geklappt :/

    Beim Ausführen bekomme ich eine Fehlermeldung:

    Ich verstehe die Funktion sys.argv auch nicht wirklich. Liest Du damit unter anderem Zeiten aus dem System aus?

    Darüber hinaus sehe ich nicht, wo Du die Funktionen "right" und "wrong" benutzt?

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!