Projektarbeit Wiimote Tracking (Nico Grupp)

To Do:

  • Marker bauen
  • Wiimote Bibliothek schreiben - Infrarot und Beschleunigungssensoren
  • Milestone: Marker erkennen und unterscheiden * Milestone: 3D-Tracking (ARToolKit), Positionsbestimmung der Wiimote im Raum mit einem Marker Quellen: ARToolkit Python Wrapper Beispiel, ARToolkit Python Wrapper Modul
  • Multimarkertracking
    • bei mehr als 4 Punkten: erkennbar durch Punktsprung -> 2D-Fallback
    • bei weniger als 4 Punkten -> 2D-Fallback
    • bei gar keinem Punkt -> Beschleunigungssensor-Fallback
    • Rückkehr von 2D auf 3D -> trivial, evtl. Sprungglättung
    • Rückkehr von 0 auf 2D -> schwierig, nur rudimentär, hoffen auf komplette Markerdaten

Gang der Datenauswertung:

  • Wiimote misst Koordinaten, z.B. x = 52
  • Wiimote wandelt die 52 in eine Binärzahl um: 00110100 und sendet diese
  • Bluetooth Adapter empfängt 00110100 und wandelt es in einen String um: "4" und sendet diesen in den Bluetooth Puffer
  • msg ist ein String mit der maximalen Länge 23. Er liest immer den aktuellen Inhalt des Bluetooth-Puffers aus - bis zu 23 Zeichen.
  • Um aus dem ausgelesenen Wert "4" wieder die X-Koordinate 52 zu erhalten, muss also der ord()-Operator angewendet werden.
  • ord(x) liefert zu einem String x, der aus einem einzelnen ASCII-Zeichen besteht, dessen ASCII-Nummer (dezimal). Z.B. ord(a) = 97 oder ord(5) = 54 oder ord(?)=63

Fakten:

  • Unterscheidung der Marker durch stufenloses Ändern der Helligkeit einzelner Eck-LEDs
  • Blinken wird also nicht durch An-Aus-An... erzeugt, sondern durch Hell-Dunkel-Hell...
  • Das "Dunkle" beim Blinken wird nicht durch geringere Spannung/Stromstärke erzeugt, sondern durch extrem schnelles Flackern der LED, gesteuert durch den PIC
  • Der erste Versuch, das Ausgangssignal des PIC mit einem Transistor zur Regulierung zu nutzen, scheiterte, da der Transistor nicht genügend Strom durchlies
  • Stattdessen wird nun ein LM3405 Buck Regulator benutzt. Mittels einem Widerstand kann die benötigte Spannung reguliert werden.

PIC-Programmierung:

  • Am Linux-Rechner mit C
  • im Menü: Piklab wählen, Build Project zum kompilieren
  • Hexfile mit dem ICD (link vom Desktop) auf den PIC laden
  • Falls ICD nicht funktioniert: mit grep Prozess finden, killen, den höchsten COM wählen (oder Str+Alt+Esc)
  • Oberfläche zum Testen: wmgui
  • zum kompilieren eignet sich auch ./make.sh im passenden svn-Verzeichnis

Test mit Helligkeitsausgabe:

  • Shell: python IRwiiviewer.py
  • zum editieren: kate IRwiiviewer.py

Stromeinstellungen:

  • 7,4 V, sollten ca. 100 mA fließen
  • zum Test mit der grünen LED: ca. 4V, fließen um die 15 mA
  • Der Pic hat eine Maximalspannungstoleranz von 7,5 V, aber bis jetzt scheint der Betrieb mit 7,4 V nicht geschadet zu haben.

Hardwareprobleme:

  • Grün: Problem gelöst
  • Orange: Problem nicht gelöst, hat aber momentan keine Auswirkungen auf das Ergebnis
  • Rot: Problem nicht gelöst und verhindert das gewünschte Ergebnis des Projekts

Problem 1: PIC liefert kein Signal an Quartz

  • Der PIC des Mittelteils lieferte trotz erfolgreicher Programmierung mit ICD kein Ausgangssignal am Pin des Quartz, folglich kam kein Signal am RC4 an und es blinkte nichts
  • Vermutung: PIC hält nur max. 7,5 V aus, vielleicht ist er bei der Nutzung von 7,4 V bereits durchgeschmort? Ein neuer PIC brachte aber keine Abhilfe
  • Vermutung: Quartz kaputt
  • Vermutung: Das Molex-Kabel zum Programmieren des PIC war unsauber, aber selbst wenn: Wenn ICD eine erfolgreiche Programmierung des PIC meldet, ist davon auszugehen, dass es geklappt hat
  • Vermutung: Eckteile kaputt: Konnte widerlegt werden, da sie mit der Breadboard-Version tadellos blinkten
  • Lösung: Da es sich um neue PICs handelte, waren diese noch nicht initialisiert. Dieses musste getan werden, indem im Programmcode, der auf den PIC geladen wurde ("blinker.c") die picconf.h inkludiert wurde. Diese Datei muss auch im selben Verzeichnis sein wie der Code. (#include "picconf.h" )

Problem 2: PIC liefert kein Signal am RC4

  • Der PIC des Mittelteils lieferte trotz erfolgreicher Programmierung mit ICD kein Ausgangssignal am Pin RC4, wo eigentlich eine Rechteckschwingung ankommen sollte
  • Lösung: Durch die Einbindung der picconf.h wurde vermutlich der USB-Pin aktiviert und damit auch RC4 irgendwie in Beschlag genommen. Durch ein Ausweichen auf RB4 in der blinker.c konnte dieses Problem umgangen werden. Bei Gelegenheit kann man die entsprechende Anpassung in der picconf.h durchführen, um so auch RC4 nutzen zu können.

Problem 3: LED blinkten nicht, sondern zeigten unvorsehbares Verhalten

  • Mal blinkten die LEDs, dann mal nicht, dann wechselten sie zwischen an und aus
  • Lösung: Auf den Mittelteilen wurde ein anderer Quartz verwendet (20 MHz) als auf dem Breadboard-Prototype (4 MHz). Der LED_Controller hat aber eine maximale Frequenz von 5 KHz. Die Zeit für die Operationen des PICs haben auf dem Breadboard eine ausreichende Verzögerung geliefert, aber dies war für den 5x schenlleren Quartz nicht mehr ausreichend. Eine Änderung im Code der blinker.c hat dieses Problem gelöst: Nach jeder Operation wird nun eine ms gewartet. Dafür werden die Schleifen nur noch 1.000 mal statt 10.000 mal durchlaufen.

Problem 4: Messungen des Oszilloskops zur Problemfindung nicht hilfreich

  • Da das Oszilloskop 14 picoFarad 1 einem Megaohm Widerstand hat, wird das Messergebnis durch anlegen der Oszilloskop-Sonde bereits verfälscht. Grund hab ich noch nicht ganz verstanden (Raphael fragen)

Problem 5: Im Viererring zeigte ein Eckteil seltsames Verhalten: Blinkte (AN/Aus) ohne dass es das sollte

  • Vier Eckteile ans Mittelteil angeschlossen, Stromversorgung stets in Direktverbindung zum Mittelteil. Das Eck mit Steuerverbindung zum Mittelteil blinkte wie erwartet, bei zwei anderen Dauerleuchten wie erwartet, aber das dritte blinkte an/aus im ca. 7-Sek. Rythmus (weit langsamer als das Steursignal des Pics, welches ca. jede Sekunde blinken lässt.)
  • Diese Verhalten tritt sowohl bei 5 Volt Spannung als auch bei 7,4 V auf.

Problem 6: Nachdem nach Problem 5 das fälschlicherweise blinkende Eck getauscht wurde, blinkte auch das Eck nicht mehr, das blinken sollte.

  • Selbst wenn man es als einziges Eck anschließt, kommt es nicht zum Blinken, sondern zeigt Dauerleuchten
  • Nachdem dieser Wiki-Eintrag gemacht wurde, trat Problem plötzlich nicht mehr auf, ohne das Änderungen am Versuchsaufbau vorgenommen wurden -> Kondensatorenproblem?
  • Als dann Schritt für Schritt weitere Ecken hinzugefügt wurden, trat schließlich auch Problem 5 nicht mehr auf.
  • Nach hinzufügen des fehlerhaften Ecks 4 trat es wieder auf. Das Entladen der Kondensatoren wurde (ohne Stromversorgung) durch Kurzschluss der Kondensatoren Beschleunigt; dadurch konnte das Blinken am designierte Eck wieder in Gang gebracht werden.
  • Lösung (?): Nachdem die Ecken mit einem Stahlbürstchen von Flussmittel gereinigt und zweifelhafte Lötstellen nochmal nachgelötet wurden, scheint Problem 5 & 6 behoben. Alle Ecken bis auf Eck 2 sind funktionsfähig.

Problem 7: LEDs reagieren sehr empfindlich auf Berührung des Quadrats und gehen dann aus; Wackelkontakte?

  • Berührt man die Ecken irgendwie, so verlöschen die LEDs manchmal
  • Dies kann auch dergestalt passieren, dass man Eck 1 berührt und daraufhin z.B. Eck 3 schwächer leuchtet und Eck 4 komplett ausgeht. Eck 1 und 2 bleiben unbeeindruckt. Kann sogar dann passieren, wenn alle über eine eigene Stromversorgung vom Mittelteil aus verfügen (also nicht an einem anderen Eck zur Stromversorgung hängen)!!
  • Durch nochmaliges Berühren oder Aus/Anschalten lässt sich das Problem oftmals lösen.
  • 1. Vermutung: Wackelkontakt. Deshalb einen kleinen Holzrahmen gebastelt, der die Ecken aufnimmt und stützt, außerdem die Drähte mit passenden Steckern versehen und diese benutzt
  • Des weiteren die Ecken mit kurzen Drahtbrücken verbunden, die eine geringere Wahrscheinlichkeit für Wackelkontakte aufweisen.
  • Lösung: Noch keine, denn das Problem trat von nun an seltener auf, war aber nicht vollständig beseitigt. Wackelkontakte können nun fast sicher ausgeschlossen werden. Vielleicht ein Phänomen, das mit den Kondensatoren zusammenhängt? Raphael bitten, mehr Stecker zu kaufen, denn der Stromanschluss über den Switch ist unpraktisch
  • Außerdem leuchtet Eck 3, welches besonders anfällig für spontanes Verlöschen zu sein scheint, nach Trennen der Stromversorgung nach - > Kondensatorenproblem? (Nein, lag daran, dass die Molex-Verbindung zum PIC-Programmer noch stand; die LEDs wurden so über USB mit Strom versorgt)
  • Nach Einbau einer Widerstandsbrücke von + zu Control bei einer der Ecken wurde das Problem nicht mehr beobachtet. Dieser 100 KOhm Widerstand lässt Restströme aus dem System abfließen.
  • Leider zu vorschnell: Das Problem tritt auch bei Einbau der Widerstände gelegentlich auf.

Problem 8: Sinuskurve beim Blinken der LEDs, LEDs scheinen bei hoher Blinkfrequenz gar nicht mehr zu blinken

  • Optimalerweise würden die LEDs alle 16 ms einen Phasenwechsel durchlaufen. Momentan durchläuft der PIC sowohl die helle als auch die gedimmte Schleife 50 Mal, jeweils mit 1 ms Pause.
  • Es ist also anzunehmen, dass wir mind. 50 ms pro Phase haben. Wird die blinkende LED durch ide Webcam beobachtet, zeigt sich, dass die Blinkintensität einer Sinuskurve zu unterliegen scheint: Erst ist der Unterschied zwischen hell dunkel sehr ausgeprägt, dann wird er immer schwächer, schließlich scheint die LED nur noch mit voller Helligkeit zu leuchten. Daraufhin werden die Dunkelphasen wieder intensiver. Stellt man eine höhere Blinkfrequenz ein (indem man den PIC beispielsweise die Schleife nur noch 20 mal durchlaufen lässt), so ist mit der Webcam überhaupt keine Helligkeitsänderung wahrnehmbar.
  • Vermutung: Möglicherweise ist die Frequenz, mit der die Webcam Bilder aufnimmt, niedriger als der Bereich, in dem wir uns befinden. Die Sinuskurve könnte ein Phänomen sein ähnlich den scheinbar Rückwärts laufenden Propellern bei Flugzeugen nach einiger Zeit und wäre somit ebenfalls ein "Wahrnehmungsfehler" der Webcam.

Problem 9: Wiimote scheint teilweise LEDs aus dem Vierercluster zu unterscheiden und somit als zwei verschiedene Punkte zu identifizieren

  • Jeweils vier LEDs sind in jedem Eck zu einem Cluster zusammengelegt, um die Helligkeit zu vergrößern.
  • Scheinbar nimmt die Wiimote diese jedoch nicht, wie gewünscht, als einen Punkt war, sondern kann die einzelnen Dioden unterscheiden.
  • Als Effekt wird bei der grafischen Ausgabe lediglich ein flacher Strich angezeigt, quasi ein nur wenige Pixel breites Quadrat
  • Lösungsansätze:
    • Beim Löten darauf achten, dass die LEDs eines Clusters möglichst parallel sitzen. Ursprünglich war eine schräge Ausrichtung in alle vier Richtungen erwünscht, um so auch ein Tracking bei flacheren Einfallswinkeln zu ermöglichen. Möglicherweise muss man diesen Ansatz aber überdenken.
    • Ein Kunststoffgehäuse für den Marker, versehen mit einem Polarisationsfilter über den LEDs könnte diesen Effekt ebenfalls abschwächen.
    • Nachtrag: Bei einem Test hat ein Polarisationsfilter keine Wirkung gezeigt. Eine Art trübes Glas könnte die Unterschiede zwischen den einzelnen LEDs im Cluster vielleicht "verschmieren", aber sicher zulasten der maximal emittierten Lichtmenge.

Problem 10: Einzelne LEDs leuchten schwächer als andere, so das Reflektionen statt der LEDs getrackt werden

  • Reflektionen an spiegelnden Oberflächen oder ähnliche Störeffekte beeinträchtigen das Tracking massiv. Da bereits die reinen Punkt-Koordinaten diese Fehler beinhalten, kann ein Software-Fehler nahezu ausgeschlossen werden (außer beim Auslesen und Formatieren des Wiimote-Streams. Aber dann wären die Störungen gleichmäßiger verteilt.)
  • Problematisch ist auch, dass sich nicht wahrnehmen lässt, ob eine Oberfläche im Infrarotbereich spiegelt. So hilft das unterlegen eiens schwarzen Kunststoffbrettchens nichts, sondern verschlimmert den Effekt sogar.
  • Als Lösung kommt hier nur infrage, die Marker an Stellen zu positionieren, wo es naturgemäß nur selten zu Reflektionen kommt. Bisher steht der Marker senkrecht auf einem Tischchen, aber eigentlich sollen sie ja an eine Wand oder einen Monitor "geklebt" werden. Ohne die Oberfläche, die im 90°-Winkel zum Marker steht, werden die Spiegelungen auch abnehmen.
  • Ein kleines Papphäubchen soll die Lichtabstrahlung in Unerwünschte Richtungen unterbinden (zweifelsohne einhergehend mit Einschränkungen des Richtungskegels, von dem aus die Wiimote tracken kann).
  • Die eigentliche Ursache scheint aber gar nicht so sehr in den Reflektionen zu liegen, sondern viel eher in der schwachen Leistung einzelner LEDs.

Problem 11:Teilweise scheinen vom Vierer-Cluster einer LED nur 2 LEDs zu leuchten

  • Ursache ist unbekannt; die Widerstandsbrücke aus Problem 7 löst es jedenfalls nicht
  • Möglicherweise ist dieses Phänomen auch verantwortlich für Hardwareproblem 10.
  • Der Effekt lässt sich manchmal vorrübergehend beseitigen, indem man mit den Fingern auf die LEDs drückt. Ein Wackelkontakt oder ähnliches liegt deshalb nahe.

Softwareprobleme:

Problem 1: Bestimmung von Punkt A scheint nicht zuverlässig zu sein

  • Punkt A wird momentan anhand der Helligkeitsdifferenz zwischen 3 Durchläufen bestimmt. Der Punkt, wo es zwischen Phase 1 und 2 bzw. zwischen Phase 2 und 3 zu den größten Helligkeitsunterschieden kam, ist höchstwahrscheinlich Punkt A (Die Differenzwerte werden addiert)
  • Dies klappt meist gut, aber durch die flackernde Verlagerung der gelben Ecke des Quadrats kann man erkennen, dass die Bestimmung manchmal nicht richtig funktioniert.
  • Es war bis jetzt möglich, dass der Mainloop des Programms die Abfragen schneller macht, als das die Wiimote überhaupt Daten liefert. Wenn die Wiimote alle 16 ms Daten liefert, der Mainloop aber z.B. nur 3 ms benötigt, so würde er dreimal die selben Werte Abfragen, und natürlich überhaupt keine Helligkeitsänderung feststellen. Deshalb wird der Mainloop nun nur durchlaufen, wenn ein Flag gesetzt ist, dass neue Nachrichten der Wiimote vorliegen. Dieses Flag wird dabei verbraucht. Der Mechanismus ist aber nicht völlig sauber: Raphale zeigen.
  • Wenn das Blinkmuster der LED zu langsam ist (momentan vermutlich der Fall mit mind. 50 ms), dann wird es auch nicht in jedem Durchlauf eine Helligkeitsänderung wahrgenommen.
  • Ist die Wiimote in Bewegung, so kann auch durch den Winkel, Reflexionen, Schatten, etc. dazu kommen, dass eine andere LED als die blinkende als LED A identifiziert wird, weil bei einer anderen die Helligkeitsänderung noch größer ist.
  • Gegenwärtig (Blinkphase: Schleife wird 50 mal wiederholt mit je einer ms Pause pro Durchlauf) kann die Wiimote jedenfalls das Blinken nicht wahrnehmen; eine relevante Änderung im Helligkeitswert der blinkenden LED findet nicht statt.
  • siehe: Bild mit falsch lokalisiertem A
  • Lösung: Da nun die Daten der Beschleunigungssensoren für die Ausrichtung genutzt werden, ist die Bestimmung von Punkt A damit hinfällig. Blinkmuster müssen nur noch zur Markerunterscheidung erkannt werden. Hierbei wurde die Fehlerrate durch Verwendung eines "Sliding Window"-Algorithmus enorm herabgesetzt.

Problem 2: Bestimmung von Punkt C scheint nicht zuverlässig zu sein

  • Im PointDebug Modus werden die Punkte, die die Kamera der Wiimote sendet, direkt benutzt, um ein Quadrat auf den Bildschirm zu zeichnen. Es wird also nicht das vorhandene Quadrat mit einer Transformationsmatrix so verzerrt, dass es aussieht wie der Marker, sondern es wird jedes Mal ein komplett neues Quadrat gezeichnet. Der Modus dient dazu, um festzustellen, ob Fehler in der Berechnung der Transformationsmatrix passieren oder ob sie schon in den darunterliegenden Routinen auftreten.
  • Dadurch, dass das Quadrat manchmal eine "Delle" erhält, kann man erkennen, dass die Bestimung von Punkt C nicht zuverlässig läuft.
  • Punkt A soll der Startpunkt sein; es ist derjenige, der durch sein Blinken identifiziert wird. Punkt C ist der Punkt schräg gegenüber.
  • Durch die Mittelpunktsbestimmung ist C eigentlich eindeutig identifiziert. Welcher Punkt B und welcher D ist ist für das Zeichnen irrelevant.
  • Das Problem tritt unabhängig von Problem 1 auf: Würde sich die Punkt C nur dann ändern, wenn sich Punkt A ändert, wäre ja alles gut. Aber die Fluktuation tritt auf, obwohl Punkt A gleich bleibt (erkennbar daran, dass die Ecke von Punkt A im Quadrat gelb gefärbt ist, die anderen sind rot)
  • siehe: Bild mit falsch lokalisiertem C
  • Lösung: Bei diesem Phänomen handelt es sich um keinen Berechnungsfehler, denn der einem Punkt gegenüberliegende Punkt kann durch die Mittelpunktsberechnung des Quadrats absolut zuverlässig bestimmt werden. Es ist viel mehr ein Darstellungsfehler, basierend auf der Tatsache, dass die Punkte von der OpenGL-Zeichenroutine in der Reihenfolge gezeichnet werden, wie sie in den Slots des Arrays sitzen. Durch geeignete Anpassungen sollte dieses Problem zu beheben sein.

Problem 3: Der Ansatz zur Zuordnung der LEDs zu Ecken des Markers hat Schwächen

  • Müller nutze zur Zuordnung der LEDs die Annahme, dass ein Punkt, der z.B. oben rechts des Mittelpunktes liegt auch das obere, rechte Eck des Markers sein muss.
  • Wie man hier sehen kann, ist diese Annahme falsch. Dies kann dazu führen, dass der selbe Eckpunkt mehrmals gespeichert wird und die Erzeugung des Quadrats versagt. + Mögliche Lösung: Das Abklappern der Eckpunkte im Uhrzeigersinn ist nicht-trivial, da man sich nicht an den absoluten X/Y-Koordinaten aufhalten kann, um zu bestimmen, welches der nächste Punkt wäre.
  • Deshalb wird folgender Algorithmus überprüft:
    • Wähle den Punkt mit der höchsten Y-Koordinate.
    • Bestimme den gegenüberliegenden Punkt (möglich durch den Algorithmus zur Mittelpunktsbestimmung)
    • Definiere die Gerade durch diese beiden Punkte (auf der auch der bekannt Mittelpunkt liegt)
    • Von dieser Gerade aus Winkelmessung im Uhrzeigersinn durchführen, mit dem Mittelpunk als Scheitel. Der Punkt, der den kleineren Winkel zwischen Mittelpunkt und nächstem Punkt bildet ist der, der im Uhrzeigersinn als nächstes kommt
  • Leider löst das allerdings immer noch nicht das Problem, wie man z.B. den oberen, linken Punkt des Vierecks bestimmt. Außerdem ist die Winkelmessung über den Cosinussatz nicht unproblematisch, weil nicht injektiv: Ab 180 Grad wiederholen sich die Werte. Man bräuchte also zwei Messungen.
  • Lösung: Dadurch, dass die Markerorientierung nun aus den Beschleunigungssensor-Daten berechnet wird, ist dieser Ansatz überflüssig

Problem 3b: Alternative zum bestimmen des linken, oberen Punktes

  • Statt der Winkelmessung könnte man die Linien des Vierecks verlängern. Dann legt man um jeden Eckpunkt vier weitere Punkte, einen in jedem Bereich der entstehenden Felder
  • Dabei wählt man einen beliebigen Punkt auf der Geraden, indem man entweder X- oder Y-Wert zufällig festlegt (natürlich muss z.B. der Y-Wert größer sein, wenn man einen Punkt erzeugen möchte, der in einem der oberen Felder liegt)
  • Dann trägt man soviel zum Wert des Punktes dazu, dass die dazugetragene Strecke kleiner ist als der Koordinatenwert des Punktes der jeweiligen kreuzenden Geraden (hier also einen X-Wert, so dass wir die Geade AD noch nicht kreuzen.
  • In die andere Richtung ebenso
  • Auf diese Art und Weise erzeugt man also für jeden Eckpunkt vier Hilfspunkte. Nun kann man überprüfen, welcher von ihnen in der Vierecksfläche liegt.
  • Liegt z.B. bei Punkt A der untere rechte Hilfspunkt im Viereck, so muss es sich bei Punkt A um den oberen linken Punkt handeln.
  • Leider kann es sein, dass diese Methode versagt: Bei bezeichneten Viereck würde die Methode ergeben, dass sowohl Punkt B als auch Punkt C der obere, rechte Punkt sind. Problematisch ist, dass hier auch ein Mensch nicht intuitiv sagen kann, welcher Punkt welcher ist. Denn wie könnte man Punkt D guten Gewissens als den unteren linken Punkt bezeichnen, wo er doch der am weitesten rechts liegende Punkt überhaupt ist?
  • Momentan wird ein simpler, arithmetischer Ansatz genutzt: Der Punkt, der dem Ursprung am nächsten ist, liegt links unten (Die anderen Punkte analog). Hierbei sind jedoch Ambivalenzen zu erwarten, die auch bei der Funktion order_controller auftreten, siehe Software Problem 10.

Problem 4: Überprüfen der Gleichheit von Objekten schlägt fehl

  • Im Programmteil für die Bestimmung der Markerorientierung werden die LED-Objekte von der Liste leds in ein Hilfsarray kopiert
  • Wenn nun auf Gleichheit überprüft wird: if self.leds[0] == array[0] , so ist Gleichheit nicht gegeben, obwohl an dem Slot eine Kopie des selben LED-Objekts liegt
  • Ursache: Vermutlich wird mit dem Operator == die Gleichheit der Objekt-ID überprüft, und diese ist einmalig. Was gesucht wird ist ein Vergleich der Werte - wenn alle Wert identisch sind, ist Gleichheit gegeben.
  • Vermutung lag falsch, die wahre Ursache war, dass gar nicht die selben Typen verglichen wurden. In der Hilfsliste "array" lagen gar keine Kopien der LED-Objekte, sondern nur Kopien der MyCenter-Objekte. Diese werden zwar mit den Koordinaten der LED-Objekte initialisiert, sind aber vom Typ verschieden, weshalb eine Überprüfung auf Gleichheit stets fehlschlägt.

Problem 5: Unnachvollziehbare Änderung der Werte im Array self.leds

  • Das Programm bricht nach ein, zwei Durchgängen ab, weil die Längenbestimmung der Hilfsliste "array" versagt. Dieses Array sollte zu dem Zeitpunkt stets zwei Elemente beinhalten.
Das ist aber manchmal nicht der Fall. der Grund dafür ist eine Änderung eines Wertes im Array, welches die LED-Punkte speichert.
  • Merkwürdig dabei ist:
    • 1. Wird der Wert scheinbar an unterschiedlichen Stellen/bzw. zu unterschiedlichen Zeitpunkten verändert. Der Wert des Arrays wurde zur genaueren Eingrenzung der Fehlerursache mehrmals ausgegeben. Einmal zu Beginn des Abschnitts, dann in der Mitte und schließlich zum Schluss. Während bei manchen Programmdurchläufen die Änderung zwischen der ersten und zweiten Ausgabe stattfand, geschah es bei anderen Abläufen erst zwischen der zweiten und dritten Ausgabe.
    • 2. In den entsprechenden Codezeilen wird lediglich lesend auf das Array zugegriffen, Änderungen werden überhaupt nicht vorgenommen
    • 3. So ein Verhalten legt den Verdacht nahe, dass unterschiedliche Threads gleichzeitig auf die selben Daten (hier: self.leds) zugreifen. Allerdings kommt diese Erklärung auch nicht in Frage, denn das Programm besteht nur aus dem Haupt-Thread und einem Neben-Thread, der die Nachrichten der Wiimote empfängt, verarbeitet und dann an den Mainthread weiterleitet. Der Wiimote-Thread schreibt niemals direkt in das array leds.
  • Die Ursache des Problems liegt in der Art, wie Python Listen handhabt. So wird bei der Kopie einer Liste eine Art Pointer auf die Originalliste erzeugt, und kein neues, eigenständiges Objekt (wie es sonst der Fall ist).
  • Zur Verdeutlichung:
list = ["a", "b", "c", "d"]
list2 = list
list3 = [list[0], list[1], list[2], list[3]]
list.remove (list[1])

for i in range (len(list2)):
   print str(list2[i])

for i in range (len(list3)):
   print str(list3[i])
  • Hierbei wird deutlich, dass list2 ebenfalls verändert wird, sobald sich list ändert, denn es wird nur a, c und d ausgegeben, das b fehlt. list3 hingegen ist ein neu erzeugtes Objekt und bleibt unbeeinflusst; es wird a, b, c und d ausgegeben.

Problem 6: Der Direct-Point Debug-Modus funktioniert nicht

  • Um die Korrektheit der Transformationsmatrix zu überprüfen sollen in diesem Modus zusätzlich zu dem durch die Matrix verzerrten Viereck die wahrgenommenen Punkte direkt auf dem Bildschirm ausgegeben werden
  • Dabei sollen die direkt projizierten Punkte ein semi-transparentes Viereck bilden, so dass man idealerweise eine Übereinstimmung feststellen kann.
  • Erste Versuche, bei denen die Direkt-Punkte als 2D-Overlay über gestalteten sich als schwierig, da dann meist gar kein Viereck gezeichnet wurde, Ursache unbekannt
  • Wenn man das Direct-Point-Viereck als Fläche im 3D-Raum mit konstanten Z-Werten realisiert, stellt man fest, dass die Vierecke an unterschiedlichen Stellen gezeichnet werden.
  • Könnte eventuell die Modelview-Matrix die falsche sein und für unsere Darstellung die Projection-Matrix verlangt sein? Dies würde auch Effekte erklären, wonach das Koordinatensystem spiegelverkehrt zu sein scheint.
  • Eventuell sollte man doch ein 2D-Overlay benutzen, um solchen Schwierigkeiten aus dem Weg zu gehen.
  • Das 2D-Overlay funktioniert jetzt, allerdings sind die Auslenkungen des transformierten Quadrats größer als die des Pure-Point-Quadrats. Laut Sebastian liegt das an der Projektion; da es sich aber nur um eine Debug-Option handelt, genügt der gegenwärtige Status.

Problem 7: Helligkeitswerte der einzelnen LEDs werden vermixt

  • Die Helligkeitswerte der LEDs werden in einem Array gespeichert. Sobald genug Werte vorhanden sind (= das Array hat eine gewisse Länge), werden die Differenzwerte der einzelnen Phasen addiert, die LED mit dem größten Helligkeitdifferenzswert (= blinkende LED) bestimmt und das LED-Array so umsortiert, dass das diese LED im ersten Slot liegt.
  • Der letzte Wert des Helligkeits-Arrays wurde an die erste Stelle gesetzt, alle anderen Werte verworfen und der Prozess begann von neuem.
  • Nun war es scheinbar so, dass nachdem der zweite Wert in das Helligkeitsarray geschrieben wurde, gleichzeitig auch die Werte, die in den ersten Slots lagen, willkürlich unter den einzelnen LEDs getauscht wurden.
  • Die Ursache war erst nicht zu ermitteln, aber des Rätsels Lösung war die Umsortierung der LEDs in ihrem Array. Nachdem LED 2 nach der Umsortierung womöglich nicht mehr an Position 2 lag, das Helligkeitsarray aber mit Position 2 verknüpft war, ging die Zuordnung verloren.

Problem 8: Das Inverse der ModelViewMatrix stellt die Wiimote nicht richtig dar

  • Im Endeffekt soll die Anwendung die Position der Wiimote im Raum bestimmen. Dazu ist aber ausschlaggebend, wo die Wiimote sich aus "Sicht" des Markers befindet, nicht umgekehrt.
  • Zur Visualisierung ist also die Darstellung einer Wiimote aus Sicht des Markers besser geeignet als der Marker aus Sicht der Wiimote.
  • Das Inverse Element der ModelViewMatrix lässt sich mit dem numpy-Modul leicht berechnen. Allerdings entspricht die Darstellung nicht dem gewünschten Ergebnis. Die Wiimote ist hinter dem Sichtkegel des Markers.
  • Des Rätsels Lösung liegt in der Hintereinanderausführung der Rotationen: So bringt:
                glRotatef(180.0,1.0,0.0,0.0)
                glRotatef(180.0,0.0,0.0,1.0)
ein anderes Ergebnis als:
                glRotatef(180.0,1.0,0.0,1.0)

Problem 9: Bei der Nutzung der inversen Matrix kommt es zu Sprüngen

  • Die dargestellte Wiimote wechselt extrem schnell die Position und flackert hin und her. Das kann darauf zurückzuführen sein dass kleine Ungenauigkeiten und Zittern, welches bei der Originalmatrix nur minimale Positionsänderungen zur Folge hatte, bei der invertierten Matrix extreme Effekte hat.
  • Wahrscheinlicher sind allerdings Rundungseffekte, da die Sprünge auch auftreten, wenn die Bewegung der Wiimote nur simuliert wird und Handzittern ausgeschlossen werden kann.
  • Lösung: Unbekannt.
  • Das Problem wird auch hier thematisiert: http://www.hitlabnz.org/forum/showthread.php?t=56
  • Ebenso hier: http://www.hitlabnz.org/forum/showthread.php?t=211
  • Das Problem scheint nicht mehr aufzutreten, wenn man nicht die gesamte ModelviewMatrix invertiert, sondern sich zunutze macht, dass die lediglich aus einem Rotations- und einem Translationsanteil besteht. Die Inverse Matrix erhält man nun durch Transponieren der oberen, linken 3x3 Matrix (der Rotationsmatrix), und negieren der untersten Zeile (dem Translationsanteil).
  • Siehe auch hier: http://www.hitlabnz.org/forum/showpost.php?p=142&postcount=2
  • Das Flackern der Ausrichtung bleibt bestehen, auch wenn es durch die Beseitigung eines Bugs bei der Mittelpunktberechnung verringert wurde. Siehe Hardware-Problem 9.

Problem 10: Transformationsmatrix berechnet manchmal die Rückseite des Markers als sichtbare Seite

  • Der dargestellte Marker sollte logischerweise nur von vorne sichtbar sein; schlimmstenfalls noch die Seiten bei extremen Winkeln.
  • Manchmal wird allerdings die Rückseite präsentiert, was ja allein deshalb schon unlogisch ist, weil auf der Rückseite die LEDs gar nicht sichtbar sind.
  • Das Problem hängt mit der Reihenfolge der übergebenen Punkte zusammen. Werden sie im Uhrzeigersinn übergeben (A oben rechts, B unten rechts, C unten links, D oben links), so wird der Marker von hinten gezeichnet. Sind B und D jedoch vertauscht, so wird die Vorderseite gezeichnet. Die Werte beziehen sich auf die nichttransformierten, nicht sortierten Rohdaten der Wiimote.
  • Hier die Vorderseite, hier die Rückseite.
  • Lösungsansatz: Die Position der Punkte B und D darf nicht mehr vom Zufall abhängig sein
  • Dies lässt sich zwar umsetzen, allerdings rächt sich dann der primitive Ansatz zur Bestimmung der Positionierung der Punkte. So kann ein sehr weit rechts liegender Punkt sowohl als der obere rechte als auch als der untere rechte identifiziert werden.
  • Möglicher Ausweg: Test, ob ein Punkt Mehrfachkandidat ist. Wenn ja, Vergleich mit dem Punkt, der noch nicht gewählt wurde und entsprechende Auswahl der Positionierung.
  • Wurde implementiert in Form der Funktion "order_controller". Leider versagt dieser Mechanismus, sobald das Quadrat derart verzerrt ist, dass der Positionsbestimmungsfehler zweifach auftritt; also der obere rechte Punkt auch als unterer rechter berechnet wird und der untere linke auch als oberer linker.
  • Weitere Aufgabe: Modifizieren der Funktion order_controller dergestalt, dass bei zwei Doppelbelegungen die beiden fehlenden Punkte gewählt werden und der wahrscheinlichste für die jeweilige Position ausgewählt wird.
  • Durch die Einführung der accelerometerbasierten Rückrptation zur Eckenbestimmung wird der order_controller kaum noch benötigt. Die hier beschriebenen Probleme sind damit quasi beseitigt.

Problem 11: Transformationsmatrix berechnet manchmal den Marker hinter dem Sichtkegel der Kamera

  • Der Marker wird manchmal gar nicht gezeichnet, obwohl vier LEDs erkannt wurden und obwohl die reinen LED-Werte im Debug-Modus auch gezeichnet werden. Da der Transformationsanteil der ModelViewMatrix hier negiert ist (im Vergleich zu Matrizen, wo der Marker erfolgrecih gezeichnet wird), ist anzunehmen, dass der Marker hinter dem Frustrum gezeichnet wird.
  • In diesem Thread http://www.hitlabnz.org/forum/showthread.php?t=590 wird behauptet, das läge daran, dass der Marker an der Mittelachse gespiegelt sei. Unsere Marker bestehen nur aus den Eckpunkten, also trifft das ebenfalls zu. Zwar lässt sich die Orientierung anhand der Beschleunigungssensoren ermitteln, aber das hilft bei diesem Problem nicht.
  • Marker ist da, Marker ist weg.
  • Lösung: Überprüfe, ob der Z-Vektor positiv ist. Wenn ja, dann nimm nicht die ModelViewMatrix, sondern das Inverse.

Problem 12: Bei der Übergabe der Raw-Werte an die Zeichenroutine zum Ausdrucken kommt es zu mysteriösen "Rundungsfehlern"

  • Diese geschehen zufällig und liegen irgendwo im Bereich von 2 bis 10 VORKommastellen (!!!). Aus 374.0 wird also plötzlich 378.0
  • Da dies nur bei den Raw-Werten zu passieren scheint, die direkt aus den irvalues der Wiimote gelesen werden, stellt sich die Frage, was mit den Raw-Werten gemacht wird, was mit den anderen Werten nicht geschieht.
  • Die Beobachtungen wurden im Debugmode 1 gemacht, wo aus den Raw-Werten die Koordinaten der kleinen, weißen Quadrate berechnet werden, die die Originaleckpunkte anzeigen sollen.
  • Dabei kommt es zwar im Funktionsaufruf zu folgender "Addition":
             glBegin(GL_QUADS);         
                glColor3f(1.0,1.0,1.0);         
                glVertex2f(self.Ax_raw + 3, self.Ay_raw +3);      
                glVertex2f(self.Ax_raw + 3, self.Ay_raw -3);
                glVertex2f(self.Ax_raw - 3, self.Ay_raw -3);
                glVertex2f(self.Ax_raw - 3, self.Ay_raw +3);
             glEnd();
  • Doch weder sind diese Additionen permanent, noch können sie die Werteänderungen erklären, denn diese scheinen zufällig und auch nicht notwendigerweise ein Vielfaches von 3 zu sein.
  • Auch nachdem "round" entfernt wurde, bleibt der Effekt bestehen.

Problem 13: In 45°-Lage versagt die Erstellung der Transformationsmatrix

  • Dies muss irgendwie mit den Direction-Werten mi.dir zusammenhängen. Bei 45° gibt es einen Switch in der Orientierung. Bei exakt 45 Grad lässt sich auch kein eindeutiger oberer linker Punkt bestimmen, nur ein oberer und ein linker. Die resultierende Transformationsmatrix entspricht aber leider keiner sinnvollen Darstellung.
  • Hier als flache Form, hier als verzerrte Form. Man beachte, wie die tatsächliche Position der gemessenen Eckpunkte ein perfektes Kreuz bilden, wo kein eindeutig "oberer, linker" Punkt, etc. existiert.
  • Durch hinzufügen der beschleunigungsbasierten Lageerkennung geklärt.

Problem 14: Drehung des Markerbildes um den Rotationswinkel versagt

  • Um das Problem der faslchen/doppelten Punktzuweisung zu vermeiden (siehe Software Problem 10.), soll auf Basis der Accelerometer-Daten der Rotationswinkel der Wiimote um die Z-Achse gemessen werden. (Im von der Wiimote genutzten Koordinatensystemwird diese als Y-Achse bezeichnet. Sie verläuft vom Extension-Port durch die Kamera). Nachdem der Rotationswinkel berechnet wurde, soll das Bild in die Gegenrichtung zurückrotiert werden. Mit dem entstehenden Quadrat, dessen Seiten zu den Bildschirmachsen fast parallel sein sollten, sollte nun problemlos der primitive Algorithmus zur Eckenbestimmung durchgeführt werden können.
  • Leider erzeugte die Rotation nicht das gewünschte Quadrat.
  • Lösung: Aus unbekannten Gründen musste man nicht mit dem Gegenwinkel (- alpha) rotieren, sondern mit dem Winkel alpha selber. Vermutlich liegt die Ursache in den unterschiedlichen Koordinatensystemen.
  • Der Grund liegt in einem Denkfehler: Wenn die Wiimote um alpha rotiert wird, rotiert das Kamerabild dadurch um den Gegenwinkel -alpha. Um einen Ausgleich zu erlangen muss das Kamerabild um alpha "nachgedreht" werden, um eine parallele Ausrichjtung zu erreichen.

Problem 15: Nach erfolgreicher Markerrotation springen die Punktbelegungen wild umher

  • Selbst als die Rotation des Quadrats mit Accelerometerdaten sauber funktionierte, kam es weiterhin zu zufälligen Sprüngen in der Punktbelegung. Punkt A war mal, oben links, dann plötzlich unten rechts.
  • Das Problem wurde gelöst, indem darauf verzichtet wurde, das Richtungs-Attribut mi.dir zu belegen. Indem wir garantieren, dass die Punkte stets in der korrekten Reihenfolge übergeben werden, ist die Nutzung von mi.dir nicht nur überflüssig, sondern sogar kontraproduktiv, da es die Wohlsortierte Punktereihenfolge durch eigene Umsortierung wieder durcheinander bringt.

Problem 16: Berechnung des Vektors Kamera-Marker in real world Koordinaten nicht möglich

  • Die Gesamtlänge des Vektors wird zuverlässig berechnet, die einzelnen Anteile X, Y und Z jedoch nicht
  • Es wird zwar die Verschiebung in X- und Y-Richtung des Bildes auf der Bildebene der Kamera berechnet, aber zum Übergang in real world Koordinaten sind noch weitere Schritte nötig.
  • Dabei wird die Brennweite (focal_lenght) der Kamera der Wiimote benötigt: Werte um 1000 herum schienen realistisch
  • Der Vektor vom Brennpunkt der Kamera selbst zu einem Punkt A mit (Ax | Ay) auf der Bildebene wäre dann: ( Ax, Ay, focal_length). Wird dieser Vektor normalisiert, so hat man die Richtung, in der, von der Kamera aus gesehen, auch der Marker in real world Koordinaten liegt. Siehe hier.

Problem 16a: Änderung des Drehwinkels um die Y-Achse ändert den X-Wert des Transformationsvektors

  • Als weiteres Problem tritt hinzu, dass die hier beschriebene Methode bei Rotationen der Kamera nicht mehr funktioniert.
  • Sowohl eine Verschiebung der Kamera nach links als auch eine Drehung nach links verschieben das Bild des Markers nach rechts; bei der Rotation kommt allerdings noch ein perspektivisch bedingter Verzerrungseffekt zu tragen.Siehe hier und hier
  • In diesem Thread wird von genau dem selben Problem berichtet.
  • Das Problem tritt natürlich auch bei Drehungen um die X-Achse / Translation in Y-Richtung auf, ist aber Aufgrund des kleineren Kamerawinkels der Wiimote hier schwerer festzustellen.
  • Da die Rotation um X- und Y-Achse jedoch einigermaßen zuverlässig berechnet werden können, wäre folgende Lösung denkbar:
    • Die Kamera wird um den jeweiligen Winkel zurückrotiert, so dass die Bildebene parallel zur Markeroberfläche ist. Siehe hier und hier
    • Das resultierende Bild des Markers liegt dann zwar möglicherweise außerhalb des tatsächlichen Sichtkegels der so rotierten Kamera, aber mathematisch sollte sich das nicht auswirken.
    • Mit dem Verfahren aus 16 wird dann die X- und Y-Verschiebung berechnet

Problem 17: Ab 35° Rotation um die Y-Achse rotiert die ausgegebene Transformationsmatrix um die X-Achse

  • Mit dem Debug99-Modus lässt sich das Phänomen allerdings nicht reproduzieren.

Problem 18: Die ausgegebene Transformationsmatrix ist stets um 90° rotiert

  • Diese Rotation ist bereits in der modelViewmatrix_rh enthalten. Ursache unbekannt.
  • Womöglich besteht ein Zusammenhang mit dem Orientierungswert mi.dir (der in dieser Anwendung stets auf Null bleibt)
  • Das Problem konnte gelöst werden, indem die Sortierreihenfolge in find_circular_set umarrangiert wurde. Jetzt wird wie folgt sortiert:
self.find_bottomleft(), self.find_bottomright(), self.find_topright(), self.find_topleft()

Problem 19: Bei Rotationen um die Y-Achse produziert ARToolkit im Bereich von +2 bis -2 ° unbrauchbare Transformationsmatrizen

  • Optisch lässt sich das nicht erkennen, aber gluProject wirft eine Exception, da die Projektion der 3D-Modellkoordinaten auf 2D-Bildschirmkoordinaten nicht durchgeführt werden kann.
  • Die falsch berechnete ModelViewMatrix ist hier:
-- Current Model View Matrix --
1.00 0.00 0.02 0.00
0.00 1.00 -0.00 0.00
-0.02 0.00 1.00 0.00
0.00 0.00 -500.00 1.00

-- Calculated Model View Matrix -- (incorrect)
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 1.00

  • Dabei handelt es sich wohl um das Gimbal-Lock-Problem. Nach der Umstellung auf Quaternionen gibt es in diesem Bereich einen Divison through Zero Error.

Offene Punkte:

Unterschiedliche Koordinatensysteme:

Das Koordinatensystem der Wiimote hat den Ursprung links unten, wie bei mathematischen Zeichnungen. Bewegt man die Wiimote nach unten, so rückt der Marker in ihrem Kamerasichtfeld nach oben und die Y-Koordinaten der gelieferten Punkte werden größer. OpenGL 2D hat den Ursprung des Koordinatensystems allerdings links oben, wie bei Computergrafikanwendungen üblich. Zur Vereinheitlichung könnte man die Y-Achse von OpenGL invertieren. Allerdings ist das 3D-Koordinatensystem von OpenGL so gelagert, dass der Ursprung in der Bildschirmmitte sitzt, mit der positiven Z-Achse aus dem Bildschirm zeigend. Das Koordinatensystem soll so geändert werden, dass der Ursprung links unten sitzen soll. Durch die Skalierung der Y-Achse mit -1 erhält man zwar den gewünschten Effekt, dass sich der Marker im Bild nach unten bewegt, wenn man die Wiimote nach oben verschiebt, allerdings wird dann die Perspektivische Verzerrung ebenfalls verdreht; Hält man die Wiimote von schräg oben auf den Marker, so scheinen die oberen Punkte des Quadrats weiter auseinander als die unteren. Dies entspricht aber der falschen Verzerrung. Eine nochmalige Anwendung der Skalierung nach der Matrixmultiplikation mit der ModelViewMatrix zeigt keinen Effekt.

Wird statt dessen lediglich der Y-Wert des Translationsteils der ModelViewMatrix negiert, so funktioniert zwar die Grundbewegung (Wiimote hoch -> Markerbild runter) richtig und auch die perspektivische Verzerrung passt. Allerdings verläuft nun die Rotation um die Z-Achse verkehrtherum.

Probleme mit dem Timing des Blinkens:

Die Wiimote sendet alle 16 ms neue Daten an den Rechner. Müller hat deshalb die Mindestdauer einer Blinkphase (also eines Zustands der LED, bis sie in den jeweils anderen Zustand übergeht) sinnvollerweise mit mindestens 16 ms festgelegt; darunter könnte es passieren, dass eine Phase von der Wiimote völlig übersehen wird. Je länger man die Blinkphasen dauern lässt, desto länger dauert es aber auch, bis der Rechner genug Daten hat, um eine Entscheidung treffen zu können, um welchen Marker es sich handelt. Da wir die LEDs beim Blinken nicht vollständig abschalten wollen, sondern lediglich dimmen, brauchen wir aber als Übertragungsmodus den Full-Mode, bei dem 2 Berichte für die vollständigen Daten aller vier LEDs benötigt werden. Damit steigt jedoch die Zeit, die zwischen neuen Berichte für eine spezielle LED verstreicht, von 16 ms auf 32 ms. Wenn man dann aber unter den 100 ms für die Markererkennung bleiben will, um Ruckelfreiheit und flüssige Benutzerinteraktion zu gewährleisten, dann hat man nur 3 Durchgänge zum Erkennen der Blinksequenz. Im worst case beinhaltet das genau einen hell-dunkel-Übergang. Des weiteren wird die "dunkle" Phase nicht durch weniger Strom/Spannung simuliert, sondern durch sehr schnelles An/Ausschalten der LED durch den PIC. Rise/FallTime der LEDs beträgt 0,8 ms. In der Zeit von 32 ms werden also maximal 32.000 ns / (2 * 800 ns) = 20 "Flackerphasen" durchlaufen; reicht das aus, um einen gedimmten Eindruck des Lichts zu vermitteln??

Probleme mit dem Erstellen der Transformationsmatrix:

Meine Algorithmen zur Mittelpunktsfindung liefern leicht abweichende Ergebnisse von denen des Beispiels mit dem Hiro-Marker (test_ar.py). Aber das Problem geht noch viel weiter: Nicht nur, dass die von der Mittelpunktsberechnung eigentlich unabhängige Berechnung der Kantenlinien zu anderen Ergebnissen führt; im Beispielcode selbst wird eine völlig andere Transformationsmatrix (Model View Matrix) generiert, je nach dem, an welcher Position im Array sich welcher Punkt befindet. Das Tupel [A, B, C, D] erzeugt also eine andere Transformationsmatrix als [A, C, B, D], und das, obwohl durch die Angabe der vier Außenlinien eigentlich klar sein sollte, welche Punkte miteinander zu verbinden sind, um das Viereck zu erzeugen.

-- NicoGrupp - 02 Jul 2008
Topic attachments
I Attachment Action Size Date Who Comment
example_square.jpgjpg example_square.jpg manage 7.1 K 02 Feb 2009 - 16:01 NicoGrupp Ein Beispiel für ein perspektivisch verzerrtes Quadrat, bei dem sowohl der obere linke als auch der obere recht Eckpunkt X- und Y-Koordinaten hat die größer als die des Mittelpunktes sind.
marker_problems.jpgjpg marker_problems.jpg manage 10.4 K 01 Apr 2009 - 09:54 NicoGrupp Upper left cluster works flawlessly, lower left not at all, lower right has only two of the four LEDs of the cluster working and the upper right is only weakly glowing.
methode_2_bild_1.jpgjpg methode_2_bild_1.jpg manage 11.7 K 06 Feb 2009 - 17:41 NicoGrupp Verlängerung der Geraden, die das Viereck bilden
methode_2_bild_2.jpgjpg methode_2_bild_2.jpg manage 12.0 K 06 Feb 2009 - 17:43 NicoGrupp Eine gewisse Strecke wird von einem zufällig gewählten Punkt abgetragen, um zu vermeiden, dass wir über die Kreuzungsgerade hinausschießen
methode_2_bild_3.jpgjpg methode_2_bild_3.jpg manage 12.8 K 06 Feb 2009 - 17:43 NicoGrupp Dies wird für alle vier "Felder" gemacht
methode_2_bild_4.jpgjpg methode_2_bild_4.jpg manage 13.9 K 06 Feb 2009 - 17:45 NicoGrupp Indem man überprüft, welche Hilfspunkte innerhalb des Vierecks liegen, lässt sich die Position der Eckpunkte bestimmen. Ist der untere rechte Hilfpunkt im Viereck, so handelt es sich um den oberen linken Punkt
methode_2_bild_6.jpgjpg methode_2_bild_6.jpg manage 13.5 K 06 Feb 2009 - 17:46 NicoGrupp Leider gibt es Vierecke, bei denen diese Methode versagt. Hier wären z.B. sowohl B als auch C der obere rechte Punkt.
picture_00.jpgjpg picture_00.jpg manage 17.8 K 16 Apr 2009 - 16:54 NicoGrupp Berechnung der Position der Kamera in real world Koordinaten
picture_01.jpgjpg picture_01.jpg manage 19.5 K 16 Apr 2009 - 16:56 NicoGrupp Ist die Kamera nach links verschoben, so wird der Marker auf dem Bild nach rechts verschoben dargestellt. Wie groß ist abhängig von der Brennweite
picture_02.jpgjpg picture_02.jpg manage 19.1 K 16 Apr 2009 - 16:56 NicoGrupp Ein verschobenes Bild hat entweder eine verschobene Kamera zur Ursache...
picture_03.jpgjpg picture_03.jpg manage 25.7 K 16 Apr 2009 - 16:57 NicoGrupp ...oder eine verdrehte Kamera. Die Verdrehung äußert sich allerdingsauch in einer Verzerrung des Bildes.
rotate_00.jpgjpg rotate_00.jpg manage 13.5 K 16 Apr 2009 - 16:52 NicoGrupp Wenn die Kamera rotiert ist und deshalb das Bild des Markers im Bild verschoben ist...
rotate_01.jpgjpg rotate_01.jpg manage 17.3 K 16 Apr 2009 - 16:54 NicoGrupp ...so könnte man die Kamera zurückrotieren, so dass die Bildebene mit der Markerebene parallel ist. Die Position des Markers ist dann zwar nicht mehr tatsächlich auf der Bildebene darstellbar, aber mathematisch (roter Rahmen) durchaus.
square_backside.jpgjpg square_backside.jpg manage 33.5 K 17 Mar 2009 - 15:45 NicoGrupp Die Rückseite des Markers, fälschlicherweise gezeichnet. Die Punkte wurden im Uhrzeigersinn übergeben.
square_behind_frustrum.jpgjpg square_behind_frustrum.jpg manage 32.6 K 17 Mar 2009 - 15:48 NicoGrupp Der Marker fehlt, lediglich die von der Wiimote erkannten Punkte werden gezeichnet. Vermutlich befindet sich der Marker hinter dem Frustrum.
square_correct.jpgjpg square_correct.jpg manage 13.9 K 29 Jan 2009 - 13:50 NicoGrupp Korrekte Darstellung des Quadrats: Die linke untere Ecke ist Punkt A, gelb gefärbt
square_deformed.jpgjpg square_deformed.jpg manage 32.5 K 23 Mar 2009 - 15:46 NicoGrupp Bei 45° versagt die Matrixerzeugung und liefert eine verzerrte Form
square_flat.jpgjpg square_flat.jpg manage 35.0 K 23 Mar 2009 - 15:46 NicoGrupp Bei 45° versagt die Matrixerzeugung und liefert eine flache Form
square_frontside.jpgjpg square_frontside.jpg manage 33.5 K 17 Mar 2009 - 15:43 NicoGrupp Die Vorderseite des Markers, korrekt dargestellt. Die Punkte wurden gegen den Uhrzeigersinn übergeben.
square_wrong_A.jpgjpg square_wrong_A.jpg manage 13.9 K 29 Jan 2009 - 13:52 NicoGrupp Hier wurde fälschlicherweise der obere linke Punkt als Punkt A identifiziert; deshalb liegt die gelbe Färbung oben. Scheinbar war in den gemessenen Phasen hier die Helligkeitsdifferenz größer als beim eigentlichen Punkt A unten links.
square_wrong_C.jpgjpg square_wrong_C.jpg manage 14.7 K 29 Jan 2009 - 13:57 NicoGrupp Hier wurde zwar Punkt A korrekt identifiziert, aber Punkt C liegt falsch. Daran, welche Linie welche überdeckt, sieht man, wie die Ecken identifiziert wurden, denn die Randlinien werden von A nach B nach C nach D und zurück zu A gezeichnet. Da sich C direkt aus der Mittelpunktberechnung ergibt, die ja offensichtlich korrekt sein muss, ist mir dieses Ergebnis besonders schleierhaft.
Topic revision: r54 - 22 Apr 2009, NicoGrupp
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Medieninformatik-Wiki? Send feedback