Dies ist eine alte Version des Dokuments!
Halli Galli ist ein sehr weit verbreitet Kartenpiel für Kinder welches als wichtiges Spielelement ein Glocke enthält, welche geläutet werden muss. Die genaueren Spielregeln findet man z. B. hier. Zu unseren Zwecken hab wir das Spiel so abgeändert, dass es nur angedacht ist im 1-gegen-1 gegen den Roboter zu spielen. Des weiteren habn wir uns gedacht, dass es schwierig zu realisieren ist ist, dass der Roboter Karten mischen soll. Auch das übergeben von den Karten an den Spieler, der nicht die Glocke geläutet hat, haben wir weggelassen.
Diese drei Hauptaufgaben haben wir auch in unserem Roboter getrennt betrachtet:
Unser Anspruch war, dass der Roboter ziemlich zuverlässig einzelne Karten ausgeben kann. Unsere Konstruktion besteht somit aus einer Kartenablage, in der die Karten liegen, einem Steppermoter, der über ein gummiertes Rad von unten die unterste Karte des Stapels nach vorne schiebt und einer Rampe, auf der die auszugebende Karte dann herrunterrutscht.
Damit wir sicherstellen konnten, dass auch nur eine Karte pro Ausgabe auch ausgegeben wird haben wir eine Art Wand noch vor den Kartenstapel eingezogen, welche von der Höhe so eingestellt war, dass nur eine Karten darunter durch passt. Da wir nicht genau bestimmen konnten, wie weit sich das Rad drehen muss, damit nur eine Karte ausgeben wird, haben wir noch eine Rückwärtsbewegung des Rades hinzugefügt, dass wenn die nächste Karte aus versehen schon mit nach vorne geschoben wird, sie wieder zurück geschoben wird.
Jede Abbildung soll eine Nummer und Unterschrift bekommen, z.B. „Abb. 3: Klingel“.
Ihr braucht zusätzlich eine Abbildung, wo das gesamte Roboter zu sehen ist. Es ist z.B. nicht klar, das die Klingel und der Inhalt der 1. Abbildung nebeneinander stehen, und der Kameraarm ist hier nicht sichtbar.
Nach einigen Überlegungen,wie die Klingel von dem Roboter betätigt werden soll,kamen wir auf den Entschluss,den Roboter nicht anhand einer „Hand“ klingeln zu lassen,also von oben,sondern von unten mithilfe eines Hubmagneten. Dieser stößt den Schwingungskörper der Klingel an wodurch diese klingelt. Der große Vorteil davon ist,dass der Mensch als Gegenspieler ohne Einschränkung auf die klingel schlagen kann. Mensch und Maschine stehen sich nicht unnütz im Weg. Da nun der Mensch zwar anhand des Geräusches wahrnehmen kann, ob der Roboter geklingelt hat und der Roboter nicht diese Fähigkeit besitzt, mussten wir uns eine Lösung dafür überlegen.
Als effektivste dafür hat sich eine Verbindung des Schwingungskörpers und der Klingelinnenseite mit Kabeln ergeben. Wenn der Mensch nun klingelt wird der Stromkreis geschlossen und der Arduino kann die Spannung am einem Pin messen. Dadurch weiß jetzt auch der Roboter ob sein Gegenüber schneller war als er.
Da oben bereits die Kartenausgabe erklärt und die Funktion der Klingel erläutert wurde, stellt sich nun die Frage wie der Roboter in der Lage sein sein soll die Karten richtig zu erkennen. Dass wir eine Kamera dafür benötigen und diese Farben erkennen soll ,ist nach dem Spielprinzip von Halli-Galli selbsterklärend. Unsere Kamera sollte nun in der Lage sein die ausgegebenen Karten des Roboters und des Menschen zu erkennen. Aufgrunddessen haben wir uns dazu entschieden sie am Ende der Rampe zu platzieren. Sie musste reichlich Fläche aufnehmen können, weshalb wir eine Vorrichtung gebaut haben, an der die Kamera kopfüber in ca. 20 cm Höhe befestigt wurde. Sie erfässt dadurch die Karten beider Spieler.
Besser z.B. so: „Damit der Roboter die ausgegebenen Karten anhand ihrer Farbe richtig erkennen kann, verwenden wir eine Kamera. Die Kamera soll die ausgegebenen Karten des Roboters und des Menschen…“
Der Kameraarm und die Licher sind auf der 1. Abbildung leider nicht zu sehen. Entweder braucht ihr hier eine andere Abbildung (am besten sowohl mit dem Kameraarm als auch mit dem Rest des Roboters, damit klar wird, wo der Roboterarm ist), oder ihr ändert die Abb. 1, oder ihr fügt eine Abbildung mit einer Gesamtansicht des Roboters hinzu.
Damit es zu weniger Lichtproblemen kommt, die bei der Programmierung der Farberkennung bemerkbar wurden, haben wir neben der Kamera Lichter befestigt die den aufgenommenen Bereich so gut wie möglich beleuchten. Zu der Funktion der Farberkennung kommen wir gleich.
Zur Ansteuerung der Hardwarekomponenten (Steppermotor und Hubmagnet) haben wir einen Arduino Nano benutzt. Dieser hat ausreichend Pins zum anschließen der Komponenten und eine ausreichende Rechenleistung, da der Großteil der Rechenleistung (mit der Bildverarbeitung) von einem seperaten Computer übernommen wird.
Der Arduino kommuniziert per USB über die serielle Schnittstelle mit dem Computer und empfängt Nachrichten, wann er eine Karten ausgeben oder die Klingel betätigen soll und sendet eine Nachricht, wenn die Klingel gedrückt wurde. Nähere Erklärung hier.
Material | Menge |
---|---|
Baumaterialien | |
Holz | |
Schrauben | |
Muttern | |
Unterlegscheiben | |
Metallwinkel | 5 |
Holzleim | |
Nägel | |
Kabelbinder | |
Elektronik | |
Arduino Nano | 1 |
Pololu Stepper Driver A4988 | 1 |
Stepper Motor | |
Hubmagnet | 1 |
Logitech Webcam | 1 |
5V 200mA LED Panel | 1 |
Kippschalter | 1 |
div. Wiederstände | 10Ω, 125Ω, 220Ω |
47µF Kondensator | 1 |
MOSFET | 1 |
Diode | 1 |
Schraubklemme | 4-polig |
diverse Materialien | |
Halli Galli Spiel | 1 |
gummiertes Rad für Stepper | 1 |
Breadboard | 1 |
Jumper-Kabel | 12 |
Die Bilderkennung war einer der wichtigsten Aspekte des Roboters, der ja erkennen sollte, welche Karten ausliegen. Um dies zu realisieren ist die Kamera am Kameraarm von oben auf das Spielfeld ausgerichtet, damit sie die beiden ausliegenden Karten überblicken kann. Die die Kamera wird also an den Computer angeschlossen und mithilfe von Processing (einer Entwicklungsumgebung für Java im Bereich Animation und Graphik) ein Livebild ausgegeben.
Um die Farben der ausliegenden Karten zu erkennen, werden in dem Livebild feste Bereiche definiert, in dem die Farbe erkannt wird. Von jedem Pixel in diesem Bereich wird nun der Farbwert genommen und der Median1) der Werte gebildet. Dieser neue Wert der Box wird nun mit Referenzfarbwerten verglichen und solte der Abstand von diesen zwei Farben unter einem bestimmten Schwellenwert liegen, wird angenommen, dass der gemessene Wert z. B. die Farbe Blau ist.
//Verfahren zur Bestimmung von Abständen zwischen Farben (Pseudocode) a = 23ab5c //Farbe in Hexadezimaldarstellung und RGB-Farbsystem b = 10a200 distanz = sqrt((rotWert(a)-rotWert(b))² + (grünWert(a)-grünWert(b))² + (blauWert(a)-blauWert(b))²) //Damit der Abstand von zwei Farben äquivalent zu dem Abstand von zwei Punkten im 2-dimensionalen Raum
Da hier keine Quelle angegeben ist, gehe ich davon aus, dass ihr selbst auf die Idee gekommen seid.
Könnt ihr kurz erläutern, woher die Referenzfarbwerte kommen? Falls ihr sie selbst ermittelt habt, könnt ihr eine Tabelle einfügen?
Das Hauptprogramm main arbeitet mit einer Instanz der Klasse Arduino und Camera
Die Arduino-Klasse kümmert sich um die Kommunikation zwischen dem Computer und dem Arduino. Dazu baut es die Verbindung zunächst auf und kümmert sich dann darum, dass Nachrichten an den Arduino gesendet werden können, aber auch die Nachricht empfangen werden kann, dass die Klingel gerade betätigt wurde.
Die Camera-Klasse sorgt dafür, dass das Kamerabild ausgewertet wird. Somit stellt die Klasse eine Verbindung zur der angeschlossenen Kamera auf, und sorgt dafür, dass die Boxen richtig geladen werden. Im Sinne der objektorientierten Programmierung sind diese Boxen natürlich auch eigene Instanzen von Objekten, die wiederum eigene Methoden implementieren. Somit wertet die Camera-Klasse das Bild aus und bestimmt für jede Box den Farbwert.
Des weiteren bietet die Camera-Klasse die Möglichkeit sich:
anzeigen zu lassen.
class Box { int x; //x-Position int y; //y-Position int dx; //Breite int dy; //Hoehe Capture cam; color theColor; //Farbe der Box color[] colorReference; //Farbreferenzwerte int[] colorThreshold; //Farbspielräume String[] colorName; //Frabnamen
Somit kann man also jedem festgelegten Bereich eine Farbe zuordnen. Danach müssen nur noch die Anzahl der jeweiligen Farbfelder bestimmt werden, und schon kann gesagt werden, ob die Gewinnbedingung nach den Spielregeln eintrifft.
Unser Halli-Galli Roboter ist in der Lage die Grundlagen des Spiels zu erledigen (Kartenausgabe → Kartenerkennung → Klingel ). Allerdings ist es noch nicht möglich ein richtiges Spiel gegen ihn zu spielen, weil er noch nicht erkennen kann ob sein Gegner eine neue Karte gelegt hat und folglich nicht weiß wann er am Zug ist. Jedoch haben wir ein sehr gut strukturiertes Framework geschaffen, welches auch sehr gut geeignet wäre für Gruppen in folgenden Projektlaboren weitergeführt zu werden.
Er ist außerdem noch Verbesserungswürdig: Der Roboter weiß z.B. nicht wie viele Karten er noch übrig hat, was allerdings nicht notwendig ist zu können, da der Mensch das überprüfen kann. Deshalb ist es oben nicht aufgelistet. Ein weiterer Punkt wäre, dass er in der Lage sein könnte ..?..
Gesamter Code und noch weitere Erklärungen: Code und Rohdaten
Box
) auch besser erklären, wie ihr die Karte in mehrere Bereiche unterteilt habt und dort den Medianwert ermittelt habt. Das ist ein großer Beitrag von euch, ist aber ein wenig in der Doku untergegangen. Der Text von der Titelseite kann in die Einführung eingegliedert sein.