Die gesamte Oberfläche und der große Teil der restlichen Funktionen wurde mit Hilfe von PyQt5 implementiert. Ausgehend von der Anforderung mehrere Wiimotes gleichzeitig zu unterstüt-zen, begann die Implementierung an dieser Stelle. 5.1.1 WiimotePointerReceiver Damit sich Wiimotes jederzeit mit dem System verbinden können, wurde die Klasse WiiMotePointerReceiver erstellt, in der ein Hintergrundthread in regel-mäßig nach Wiimotes sucht. Werden welche gefunden, mit denen aktuell kei-ne Verbindung besteht, wird eine Verbindung hergestellt. Nach erfolgreicher Verbindungsherstellung wird über eine von außen geimpfte factory-Methode ein Pointer Objekt erstellt. Dieses wird unter dem Schlüssel der Wiimote MAC Adresse in der Receiver Instanz gespeichert. Der Ansatz der factory-Methode wurde gewählt, da zu diesem Zeitpunkt zwar bereits bekannt war, dass eine Art Pointer Virtualisierung stattfinden muss, jedoch war die exakte Implemen-tierung nicht bekannt. Um eventuelle Verbindungsabbrüche kompensieren zu können läuft ebenfalls in regelmäßigen Abständen eine Art Säuberung, wäh-rend der die Verbindung mit allen gespeicherten Wiimotes geprüft wird. Ist eine Wiimote nicht mehr verbunden, wird es aus der Speicherung entfernt, aber direkt ein neuer Verbindungsversuch angestoßen. Die Instanz des WiiMotePointerReceiver’s wird in der Programm Instanz verwaltet. Die Pro-gramm Instanz stellt den Einstieg in das System dar. Programm stellt ebenso sicher, dass WiiMotePointerReceiver die Verbindung mit allen Wiimo-tes abbricht, wenn der Hauptprozess der Anwendung beendet wird. Dies stellt sicher, dass eine spätere Neuverbindung problemlos möglich ist. 5.2 WiimotePointer Die WiimotePointer-Instanz, die für jede entdeckte Wiimote erstellt wird, wan-delt deren Signale in Events des Frameworks PyQt um. Wird ein Button der Wiimote gedrückt oder losgelassen und existiert zu diesem Button ein entspre-chendes Mapping zu einem PyQt Button, wird an die QApplication ein Poin-terEvent, der von QMouseEvent erbt, mit der letzten bekannten Pointerposition geschickt. Alle anwendungseigenen PointerEvents halten eine Referenz auf die PointerInstanz, der das Event ausgelöst hat. 5.2.1 Bestimmung der Position Die Zeigeposition wird bestimmt, indem die Daten der Infrarotkamera laufend von einer WiiMotePositionMapper Instanz ausgewertet werden. Übermittelt die Infrarotkamera Daten, aus denen erfolgreich eine Positionsan-gabe bestimmt werden konnte, wird ein PointerEvent mit dem type QMouse-Move gesendet. Für alle Events werden die aktiven Buttons der Wiimote in PyQt Buttons umgewandelt und im Event mit ausgeliefert. Für eine erfolgrei-che Bestimmung sind genau vier erkannte Infrarotlichtquellen nötig. 5.2.2 Rotation um die Längsachse Die Daten des Beschleunigungssensors der Wiimote werden, während der A Button gedrückt gehalten wird, zu Rotationsinformationen umgewandelt und als PointerWheelEvent an die QApplication übermittelt. Der A Button muss dabei gedrückt sein, damit nicht zufällig die Lautstärke des aktuell ‚gehover-ten‘ Elements geändert wird, während sich die Rotation der Wiimote durch die Bedienung ständig ändert. Zur Bestimmung des Drehwinkels wird der Normalenvektor der Beschleunigungswerte der Längs- und Querachse ermit-telt und der Winkel zwischen aktuellem und vorherigen Normalenvektor be-rechnet. Eventuelle Störsignale des Beschleunigungssensors, die sich in dem Winkelergebnis niederschlagen, werden mit Hilfe des One Euro Filters (Casiez, Roussel, & Vogel, 2012) bestmöglich ausgefiltert. Die Berechnung wird von Instanzen der Hilfsklasse TurnOperation vorgenommen, die bestehen, solange der Rotationsbutton gedrückt gehalten wird. 5.2.3 Eigener Undostack Die Klasse WiimotePointer erbt von Pointer, wobei jede Instanz dieser Basis-klasse einen eigenen QUndoStack hat, was es ermöglicht, dass jeder Nutzer seine eigenen Aktionen per Undo rückgängig machen kann und per Redo wiederherstellen kann. 5.3 Eventfilter Bei der Implementierung wurde großer Wert daraufgelegt, die Komponenten unabhängig voneinander zu gestalten. Aus diesem Grund wurde der Großteil der Anwendung als Event-Filter umgesetzt. Deren Funktionen und Umset-zung wird im Folgenden kurz beschrieben. 5.3.1 Bewegung des Zeigeelements Die Zeigeposition jeder verbundenen Wiimote wird durch ein farbiges, kreis-förmiges PointerWidget im Fenster repräsentiert. Der PointerEventFilter der QApplication übersetzt die PointerEvents mit dem Typ QMouseMove in Bewe-gungen dieser PointerWidgets. 5.3.2 Festhalten des Zeigers bei Lautstärkenänderung Der CapturePointerWheelEventFilter der QApplication sorgt dafür, dass sich das PointerWidget - solange der A Button gedrückt wird und dabei ein Element getroffen wurde – nicht vom Fleck bewegt, damit die Lautstärkenregulierung durch Rotation unabhängig von der Zeigeposition fertiggestellt werden kann. Dadurch müssen Nutzer während der Rotation nicht durchgehend auf das Element zeigen, was die Bedienung erleichtert. 5.3.3 Drag & Drop Die DragEventFilter-Instanz der QApplication sorgt dafür, dass man mit ge-drückter B Taste (Linke Maustaste) PlayWidgets per Drag & Drop im Sequen-zer verschieben kann und somit den Zeitpunkt der Wiedergabe ändern kann. Die entstandene DragOperation erbt von QUndoCommand und wird vom be-schriebenen Filter an den UndoStack des Pointers angehängt, dass sie rück-gängig gemacht werden kann. 5.3.4 Zeichnen von Symbolen Die PointerDrawEventFilter Instanz der MusicMakerApp ist dafür zuständig, für alle Pointer, die mit gedrückter A Taste auf einer freien Fläche eine Zeich-nung durchführen, die Punkte der Zeichnung zu speichern. Ist eine Zeich-nung abgeschlossen, indem der Zeichenbutton losgelassen wurde, während gezeichnete Punkte gespeichert sind, wird eine callback Methode aufgerufen, dem der Pointer und die Koordinaten der Zeichnung übergeben werden. Der PointerDrawEventFilter hat darüber hinaus die Method drawPoints, die einen QPainter erwartet und über diesen die Punkte und Verbindungslinien zeich-net. 5.3.5 Undo & Redo Der PointerUndoRedoEventFilter ist, wie der Name sagt, dafür zuständig, die undo und redo Methoden des Pointer-eigenen QUndoStacks aufzurufen, wenn, die in Abbildung 2 dargestellten Buttons für die entsprechenden Funktionen gedrückt wurden. 5.3.6 Maus als Pointer Um eine Entwicklung der allgemeinen Funktionen des Musiksequenzers un-abhängig von der Steuerung über die Wiimote vorantreiben zu können wurde der RemapMouseEventFilter implementiert, der, wie der Name schon sagt, QMouseEvents in PointerEvents umwandelt. Entsprechend lässt sich die An-wendung sowohl mit Maus als auch mit Wiimotes bedienen. Bis auf einer Ausnahme – des QWheelEvents – werden von der Anwendung ausschließlich PointerEvents interpretiert. QWheelEvents konnten nicht als PointerWheelEvent und an die QApplikation weitergereicht werden, da dies eine endlose Rekursi-on auslöste. Dieses Event wird vom PlayWidget selbst behandelt. Mehr dazu im Abschnitt „PlayWidget“.
-
Notifications
You must be signed in to change notification settings - Fork 0
woellij/wiimote-musicmaker
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published