Plenz Geschrieben June 3, 2012 at 14:06 Geschrieben June 3, 2012 at 14:06 Beim Rumspielen mit dem IMU-Brick habe ich jetzt eine grafische Oberfläche gebastelt, die die verschiedenen gemessenen Winkel darstellt. Dabei ist mir aufgefallen, dass das Programm manchmal den Callbacks hinterher läuft. Das mag daran liegen, dass ich alle 50ms ein Callback erzeugen lasse, oder auch an meinem manchmal langsamen Notebook, das vielleicht im Hintergrund mit anderen Dingen beschäftigt ist. Jedenfalls bewege ich den IMU-Brick und nichts passiert... und ein paar Sekunden später werden die gerade durchgeführten Bewegungen zeitversetzt dargestellt. Ich habe versucht, über Variablen den Zustand "Callback-Subroutine ist noch nicht abgearbeitet" festzuhalten, wenn die Subroutine erneut aufgerufen wird, das hat aber nicht geklappt. Offensichtlich wird die Subroutine erst dann wieder aufgerufen, wenn der letzte Aufruf komplett abgearbeitet ist. Wie kann man solche "Hänger" abfangen? Zitieren
AuronX Geschrieben June 3, 2012 at 17:36 Geschrieben June 3, 2012 at 17:36 Kurze Erklärung: Die Callbacks werden soweit ich weiß bei allen Bindings innerhalb eines einzelnen Threads abgearbeitet. Das heißt also es kann nur ein Callback nach dem anderen bearbeitet werden. Deswegen das von dir beobachtete Verhalten, dass die Callbacks hinterherrennen. Die Lösung ist so simpel wie kompliziert: Du solltest nicht so lange zum Bearbeiten der Callbacks brauchen. Wie geht das? Ich vermute jetzt gerade mal, dass du die ganze GUI-Zeichnerei einfach sofort beim Abarbeiten des Callbacks machst. Aber das ist teuer, also GUI allgemein ist teuer, das heißt es dauert lange (für die Verhältnisse eines Computers). Lösen kann man das durch folgenden Trick: Wenn dein IMU neue Daten hat, dann schreibst du dir das irgendwo auf (also von mir aus Winkel, Neigung, whatever). Du kannst auch schon irgendwelche Umrechnungen machen, aber mache keine GUI-Arbeit, dabei kommt es zu IO, das dauert. In einem extra Thread oder per Timer lässt du jetzt regelmäßig die GUI aktualisieren, diese kann die per Callback gesetzten - jeweils aktuellen - Daten zeichnen. Das bringt dir aber auch die Verantwortung für eine gute Synchronisierung der Threads zu sorgen :/ Das sind jetzt leider nur Stichwörter dessen was du tun musst, kein Code. Ich hätte bestenfalls C#-Beispiele parat ^^ Ist leider recht viel auf das man da so achten muss... Aber das lässt sich m.E. nicht vermeiden, auch nicht durch tollere Programmiersprachen, denn die Probleme sind überall die gleichen und können nur schlecht allgemein-gültig gelöst werden. Viel Glück, villt hat jemand anders noch konkretere Tipps parat... Zitieren
Plenz Geschrieben June 3, 2012 at 18:19 Autor Geschrieben June 3, 2012 at 18:19 Hast völlig recht, ich werde das mit einem Timer versuchen. Das Auge braucht ja nur ein paar Updates pro Sekunde, während das Programm intern viel schneller arbeiten muss. Zitieren
Faab Geschrieben June 4, 2012 at 10:00 Geschrieben June 4, 2012 at 10:00 @AuronX , du meinst eine Art Observer Pattern damit, richtig? http://de.wikipedia.org/wiki/Observer_%28Entwurfsmuster%29 bzw. http://en.wikipedia.org/wiki/Observer_pattern#Python Gruß Faab Zitieren
AuronX Geschrieben June 4, 2012 at 13:31 Geschrieben June 4, 2012 at 13:31 Nein. Das Observer-Pattern beinhaltet ja das aktive rufen der Update-Methode durch das beobachtete Objekt. Dies entfällt hier. 1. Grund: Dadurch, dass es einfach ständig Änderungen gibt, lohnt es sich nicht CPU-Zeit sparen zu wollen, indem man nur veränderte Bilder zeichnet 2. Grund: Es soll ja eh entkoppelt werden, das rendern der GUI soll also nicht bei jedem Update passieren. Das heißt man würde in der Update-methode bestenfalls ein "hasChanged"-flag auf true setzen. Vom Observer ist also nur der Teil übrig, dass ein Objekt sich auf den Zustand eines anderen bezieht ^^ Im Endeffekt geht es hier nur um die grundlegende Trennung von Model und View, dazu siehe auch den (umfangreichen) Model View Controller. Zitieren
Faab Geschrieben June 4, 2012 at 14:07 Geschrieben June 4, 2012 at 14:07 Ja, da hast du Recht... hab ich wohl zu schnell meinen Senf dazu geben wollen 1. Grund: Dadurch, dass es einfach ständig Änderungen gibt, lohnt es sich nicht CPU-Zeit sparen zu wollen, indem man nur veränderte Bilder zeichnet 2. Grund: Es soll ja eh entkoppelt werden, das rendern der GUI soll also nicht bei jedem Update passieren. Das heißt man würde in der Update-methode bestenfalls ein "hasChanged"-flag auf true setzen. Richtig.. wir hatten das damals in Miniaturform bei einem Sudoku-Spiel angewendet, da macht es dann ja eher Sinn, da sich die Werte erst nach Abschluss eines Zuges ändern ( und nicht wie du schon sagst, ständig ) Im Endeffekt geht es hier nur um die grundlegende Trennung von Model und View, dazu siehe auch den (umfangreichen) Model View Controller Jo, jetzt wo du es sagst Kam da wohl durcheinander.. ( Mein damaliger Prof würde mich jetzt an den Pranger stellen ) Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.