Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

projektesose17:username404public:start

Dokumentation Ruby der Zauberwürfellöser

Quadratisch, bunt, kultig: Das wohl bekannteste Geduldsspiel der Neuzeit, der Zauberwürfel! Nicht nur in den 80-ern war er in aller Munde (oder in aller Hände), sondern auch heute noch bringt er so manchen Spielenden zur Verzweiflung, sodass viele ungelöste Exemplare noch irgendwo daheim rumliegen.

DAS wollen wir ändern!

Ruby, der Zauberwürfellöser ist unser Roboter und wie der Name verrät, soll er einen Rubiks Cube, oder Zauberwürfel, lösen.

Paula Ruß, Philip Steiskal, Moritz von Köckritz, Jana Makowski

Überblick

Unsere Idee war es, einen Roboter zu bauen, der einen beliebig verdrehten Rubik’s Cube lösen kann. Zu Beginn wird die aktuelle Struktur des Würfels dazu einmal eingescannt bzw. manuell eingegeben. Die Daten wandelt Ruby in einen digitalen Würfel um, dieser dient als Grundlage für die Berechnung des Lösungsalgorithmus’. Ruby löst nun virtuell nacheinander erst die weiße Seite des Würfels, dann die mittlere Schicht und schlussendlich die gelbe Seite. Die notwendigen Drehungen gibt sie auf einem Terminal aus. Aktuell besitzt Ruby zwar schon die nötige Mechanik, um die Drehungen selbstständig durchzuführen- das heißt, den Würfel zu wenden und zu kippen sowie eine einzelne Seite zu drehen- diese ist jedoch aufgrund von technischen Schwierigkeiten noch nicht funktionsfähig. Diesbezüglich ist noch zu bemerken, dass Ruby nicht den Anspruch hat, den Würfel in Rekordzeit oder möglichst wenigen Zügen zu entwirren, vielmehr soll sie zum Spaß dienen und den Rubik’s Cube für Menschen nachvollziehbar lösen.

Einige von Rubys Verwandten sind unter den folgenden Links zu finden:

1. löst den Würfel sehr schnell - https://www.youtube.com/watch?v=by1yz7Toick

2. aus Lego, vier drehbare Arme - https://www.youtube.com/watch?v=Q8BYKwbwZSM

3. aus Lego, Plattform und 2 Arme - https://www.youtube.com/watch?v=dreTvumjNyw

4. arduinobasiert, Plattform und 3 Arme - https://www.youtube.com/watch?v=LA1OpkKENho

Umsetzung:

Überblick über das Gesamtsystem

Grob gesagt besteht Ruby aus einem „Corpus“ und einem „Hirn“:

Der "Corpus" (Die Mechanik)

skizze_oberansicht_hell.jpeg

Wie in der Skizze erkennbar besteht Ruby aus einer runden Bodenplatte, auf der die einzelnen Mechanismen angeordnet sind. Ruby besitzt einen Sensorarm, an dem der Farbsensor angebracht ist, einen Greifarm, der den Würfel fixieren kann, einen Stupsarm, der den Würfel kippt und eine drehbare Plattform, auf der der Würfel während der gesamten Durchführung liegt.

Das "Hirn" (Das Lösungsprogramm)

Das Lösungsprogramm ist vollkommen in Java geschrieben und besteht aus einer ausführenden Main-Klasse (LoeseWuerfel.java) und einer Objektklasse (Cube.java). Die Objektklasse ist die Digitalisierung des physischen Würfels, sie gibt die digitale Struktur des Würfels vor. Sie definiert die möglichen Drehungen und Bewegungen des Würfels und beinhaltet die einzelnen algorithmisierten Phasen, um einen Würfel zu lösen. Die Main-Klasse hat ausschließlich eine ausführende Funktion: Sie erstellt einen digitalen Cube mit gewünschter Ausgangsstruktur (derzeitig noch manuell einzugeben) und führt die einzelnen Lösungsphasen auf besagtem Objekt, dem digitalen Cube, aus. Die einzelnen Bewegungen werden in einer String abgespeichert, die nach Beendigung der Lösung ausgegeben wird. Die Ausgabe ist gemäß allgemeiner Notation für die Drehungen des Würfels geschrieben.

Bezüglich des Lösungsprogramms war das erste Problem das Fundament des gesamten anstehenden Programms: Wie kann man einen Würfel mit all seinen Eigenschaften digital greifbar machen? Doch das Problem, was intensivste Beschäftigung verlangte, war das einer künstlichen Intelligenz: Wie kann man Ruby beibringen die einzelnen Phasen des Lösungsalgorithmus durchzugehen, ihr beibringen die möglichen Fälle von Würfel-Konstellationen zu erkennen, zu deuten und selbständig daraufhin die nötigen Drehungen auszuführen.

Ruby sollte keine Weltrekord Maschine werden, sondern, wenn auch langatmig, den Würfel lösen. Auch wollten wir den Code selber schreiben und keinen aus dem Internet nehmen. Dementsprechend sind die Algorithmen nicht die effektivsten, sowie unsere Umsetzungen im Code, jedoch haben wir dafür alle Probleme selbst gelöst.

Einzelne Abschnitte zur Beschreibung von Details der einzelnen Systembestandteile

Der Lösungsalgorithmus

Wie löst man eigentlich einen Zauberwürfel? Die optimale Lösung in etwa 20 Zügen herauszufinden ist für Menschen quasi unmöglich und erfordert eine unglaubliche Rechenleistung. “Auf gut Glück” zufällige Drehungen auszuführen führt wahrscheinlich erst nach ein paar Jahren zum Ziel. Die meisten Menschen bedienen sich verschiedener Lösungsalgorithmen, die jeweils bestimmte Steine des Würfels verdrehen und/ oder vertauschen. Am wenigsten Algorithmen muss man sich merken, wenn man den Würfel in drei Ebenen löst: zuerst die weiße Seite mit den dazugehörigen Kanten, dann die mittlere Ebene, und zum Schluss die gelbe Seite. Diese sogenannte “Anfängermethode” erfordert zwar viele Drehungen, da Ruby aber nicht auf Schnelligkeit ausgelegt ist, haben wir uns dafür entschieden, dass sie den Würfel mit dieser Methode lösen soll. Mit einem Würfel in der Hand setzten wir uns also daran, alles aufzuschreiben, was Ruby lernen musste: eine Drehkombination für jeden Schritt und jede mögliche Position des zu ordnenden Steins. Diese sollten danach im Lösungsprogramm digitalisiert und Ruby beigebracht werden.

Am aufwändigsten gestaltete sich dies für die erste Ebene, in der zuerst das weiße Kreuz und dann die weißen Ecken gelöst werden. Dies ist normalerweise intuitiv möglich, für Ruby mussten wir jedoch alles in genaue Anweisungen übersetzen. Das erforderte viel Herumdrehen am Würfel und einiges an Schreibarbeit.

Für die zweite und dritte Ebene ließen sich online viele Anleitungen finden, die nur geringfügig angepasst werden mussten. Hierfür verwendeten wir zum Beispiel die folgenden Seiten https://speedcube.de/, https://rolandroid.wordpress.com/2012/03/24/zauberwuerfel-loesung-teil2/, https://www.keks.de/wuerfel/ und http://www.rubiks-cube-zauberwuerfel.com/.

Die Lösungsalgorithmen sind unter Code und Rohdaten einsehbar. Die Notation entspricht der internationalen Schreibweise (U- oben, D- unten, L- links, R-rechts, F-vorne, B-hinten, ‘- gegen den Uhrzeigersinn).

Die Drehungen eines Zauberwürfels

Das Lösungsprogramm:

Bezüglich des Lösungsprogramms waren wir uns schnell einig geworden, dass wir den Code in Java schreiben, da wir mit dieser Sprache am meisten vertraut waren. Des Weiteren sahen wir Vorteile in der Datenspeicherung: Arrays sollten uns das Arbeiten erleichtern und Java erfordert keine separate Speicherzuweisung. Die Auslagerung auf ein externes Gerät, beispielsweise einen PC, sahen wir auch als unabdingbar, da die Arduinomodelle überfordert sind mit der Ausführung des Programms.

Cube.java

Digitaler Würfel

Um den Würfel überhaupt über ein Programm zu lösen, mussten wir dem Würfel besagte digitale Struktur geben. Hier haben wir uns danach gerichtet, welcher Aufbau uns am praktischsten erscheint, welchen wir uns leicht vorstellen können. Hier ist der strukturelle Aufbau graphisch dargestellt:

Wir haben uns entschieden, jede Seite als ein einfaches Byte Array der Länge 9 darzustellen. Jedes Feld der insgesamt 9 Felder pro Seite ist somit ein Element des Arrays mit Index [0-8]. Das Element mit dem Index 0 ist in der Mitte: Es gibt immer die Farbe der Seite vor. Dies liegt an der physischen Beschaffenheit des Zauberwürfels: Er besteht aus einem Achsenkreuz auf dem die besagten sechs Mittelsteine liegen, unveränderlich. Die anderen Elemente von 1-8 sind angeordnet im Kreis.

Der Inhalt der Elemente der Byte-Arrays entscheidet über die derzeitige Farbe der Felder. Um den Code zu vereinfachen haben wir Zahlen von 1-6 eingeführt, die für die Farben stehen. Hier ein kleiner Überblick:

Des Weiteren hat ein Objekt „Cube“ eine String als Eigenschaft: Sie beinhaltet die bisherigen Schritte des Lösungsalgorithmus'.

Dabei haben wir diesen Würfel mit Nummern beklebt, um die verschiedenen Zuweisungen einfacher überprüfen zu können.

Methoden der Drehungen

Die Drehungen und Bewegungen des Würfels sind mit Objektmethoden realisiert. Sie erfolgen durch Zuweisung von Array-Elementen zu Array-Elementen, wobei selbstverständlich sich nur der Inhalt der Elemente ändert. Somit ist die Erhaltung der Struktur des Würfels gewährleistet. Dementsprechend sind die Dreh- und Bewegungsfunktionen nur Datenzuweisungen.

Hier eine Datenzusweisung am Beispiel der Funktion L', die die linke Würfelseite nach oben dreht:

Um die Drehung zu realisieren muss man sich die Struktur vor Augen führen, hier unterstützt mit Skizze. Wenn die linke Seite gedreht wird, werden alle Arrays bis auf das Array für die rechte Seite verändert.

Elemente der Arrays U, F, D, B tauschen gegenseitig den Inhalt, wie hier gezeigt: 1U übernimmt den Inhalt von 1F, 8U von 8F, 7U von 7F. Dies gilt auch für D und B.

Auch muss die ganze linke Seite gedreht werden, was nur das L-Array verändert. Hier tauschen die Kanten und Ecken gegen den Uhrzeigersinn die Position.

Im Code sieht das dann so aus:

Wie man hier aber sieht, ist es nötig ein paar Inhalte zwischenzuspeichern in einem Hilfs-Array, da sonst Daten überschrieben werden würden. Durch Zuordnung gegen den Uhrzeigersinn kann man gut eine for-Schleife nutzen (Zeile 458).

Es fällt auf im Methoden-Kopf: Die Methode gibt ein String zurück, hier im Beispiel „L', “. Dies ist unabdingbar, denn in der Durchführung der Lösungsalgorithmen wird der Rückgabewert jeder durchgeführten Drehmethode dem String loesung, Eingenschaft von Cube, hinzugefügt, sodass jede Drehung als Literal abgespeichert wird, um sie am Ende auszugeben.

Umsetzung: Lösungsalgorithmen

Wie schon im Abschnitt „Der Lösungsalgorithmus“ beschrieben, besteht der Lösungsalgorithmus aus drei großen Phasen, die vollkommen aufeinander aufbauen: Jeder der umgesetzten Algorithmen geht davon aus, dass die vorherige Schicht richtig ist. Zwei Phasen unterteilen sich nochmals: Weiße und gelbe Seite werden erstellt durch ein Kreuz und das Anpassen der Ecken. Hier ein Überblick über die Lösungsmethoden in chronologisch richtiger Reihenfolge.

Die grundlegende Funktionsweise der Lösungsalgorithmen ist simpel: Das Programm untersucht eine (oder mehrere) spezifische Stelle am Zauberwürfel, die aus einem oder mehreren Array-Elementen bestehen und Teil der jeweiligen Phase ist (zB einen Kantenstein des weißen Kreuzes). Anschließend sucht das Programm entweder die Stellen ab, an dem sich der passende Stein befinden könnte, und verwendet den zu der Position passenden Algorithmus, um den Stein an die spezifische Stelle zu bringen, oder er wendet einen Algorithmus mehrfach an, bis die richtigen Steine an der passenden Stelle sich befindet, und überprüft die Stelle nach jeder Anwendung.

Die Untersuchung der spezifischen Stelle richtet sich nach der jeweiligen (Unter-)Phase des Algorithmus.

Die Suche nach dem passenden Stein und dessen Ausrichtung im Würfel geschieht über if-Blöcke: Da der gesamte digitale Würfel durch Arrays strukturiert ist und somit jedes Feld eine Bezeichnung hat, wird jede Stelle, die als Position für den gesuchten Stein in Frage kommt, nach dem passenden Stein durch einen logischen Operator abgefragt. Sobald der logische Operator „true“ zurückgibt, wird die if-Bedingung aufgerufen, die den Algorithmus zum Positionieren des Steins von der abgefragten Stelle zu der spezifischen Stelle ausführt.

Ein Beispiel: loeseWeissesKreuz();

Algorithmusmethode erklärt

Beispiel für Algorithmusmethode: löst weißes Kreuz

Die Methode an sich ist unterteilt in vier Aufrufe der Methode weissesKreuz(), die sich auf den Kantenstein oben links bezieht, vier Aufrufe, da das weiße Kreuz aus vier Kantensteinen besteht. wuerfeldrehen() ermöglicht es jede spezifische Stelle, zu der ein Kantenstein muss, zu bearbeiten.

Wie man dem Code entnehmen kann, wird durch if-Bedingungen jede mögliche Position des gesuchten Steins auf der Struktur des Würfels daraufhin überprüft, ob sie die gesuchte Zahl (also Farben) im jeweiligen Array-Element hat. Wäre der Kantenstein nun oben vorne und weiß oben, so würde das Element u[6] den Inhalt 1 haben und das Element f[2] als Inhalt die Hauptfarbe der linken Seite, also l[0]. Somit würde sich der if-Block öffnen und der Algorithmus zur Positionierung würde ausgeführt werden.

LoeseWuerfel.java

Das auszuführende Programm mit der Main-Methode ist LoeseWuerfel.java. Dort geben wir den Würfel nach dem Schema per Hand ein und erstellen ein Cube-Objekt. Danach wird die Objektmethode loesung() aufgerufen und die Lösung mit System.out.println(wuerfel.loesung); danach auf dem Bildschirm ausgegeben. Zum Testen haben wir noch die toString() Methode überschrieben und lassen auch diese auf dem Bildschirm ausgeben, wobei es schematisch den gelösten Würfel darstellt.

Bildschirmausgabe einer Lösung nach Aufruf des Programms:

Verbindung von Java und Arduino

Natürlich gilt es nun Hardware und Software zu vereinen. Hierzu nutzten wir die RXTX library, die auch von Arduino selbst empfohlen wird. Auf der Arduino Website gibt es weitere Informationen zu dem Interface von Java und Arduino:

https://playground.arduino.cc/Interfacing/Java

Wir haben den dort vorhandenen Java-Code genutzt, um über die serielle Schnittstelle von Arduino und Computer mit Java zu kommunizieren. Die im seriellen Monitor ausgegeben Strings werden von dem Java Programm standardmäßig gelesen und in der Shell ausgegeben. Das von uns bearbeitete Programm ließt die für die jeweiligen Farben der Felder stehenden Werte ein, sobald sie von dem Arduino über den seriellen Port zum PC geschickt werden und im seriellen Monitor geprintet werden, und speichert sie sofort in Arrays ab, die später ein Objekt des Typs Cube initialisieren. Die Reihenfolge ist wie folgt: f > r > u > b > l > d Da nach neun Werten (Farben) eine Seite voll ist, springt das Programm selbstständig zum nächsten Array. Die Reihenfolge der Felder (Indices), die eingelesen werden lautet: 0 > 1 > 2 > 3 > 4 > 5 > 6 > 8

Es ist zur Anwendung hinzuzufügen: Es muss erst eine serielle Kommunikation hergestellt sein und das jeweilige Programm muss auf dem Arduino gestartet werden, erst dann kann man das Java Programm starten und die Werte werden eingelesen.

Sowohl Einlesen, als auch das Lösen funktioniert. Jedoch ist der Weg zurück, also die Übergabe des Lösungsalgorithmus von Java zu Arduino nicht geregelt. Des Weiteren erschien uns die RXTX library als unbequeme Lösung, da unter Anderem die Funktionsweise der einzelnen Methoden aus der Bibliothek nicht klar werden und leider eine Art „Handbuch“ zu der library uns fehlte. Auch waren wir zu wenig vertraut mit Programmierung auf diesem Niveau: Uns fehlte Zeit, um Verständnis für diese Sammlungen an Code aufzubringen. Zusätzlich ist die Java Datei „SerialTest.java“, die auf Arduino Playground zur Verfügung gestellt wird, sehr undurchsichtig und schlecht kommentiert: Wir brauchten auch hier Zeit, den Code zu verstehen, der auch Vorwissen in Sachen Threading benötigt. Schließlich reichte es, um Daten von Arduino auszuwerten und wir konnten es mit etwas Herumprobieren zum Laufen bringen. Jedoch raten wir auch hier weiter zu arbeiten und Alternativen zu Suchen! (Subtiler Verweis auf den Ausblick)

Der Farbsensor

RGB Farbsensor TCS3200

Wir konnten den Rot-Grün-Blau Farbsensor mit vier LEDs benutzen, wobei wir mit den LEDs einige Probleme hatten, da sie die umliegenden Felder beleuchtet haben und dadurch falsche Messwerte für das gesuchte Feld herauskamen. Das haben wir mit einem schwarz abgeklebten Trichter gelöst. Danach hatten wir noch falsche Rot Werte, die von dem roten Mainboard des Farbsensors herrührte, welches wir auch schwarz abgeklebt haben. Dadurch haben wir stabile Messwerte bekommen.

Die Ansteuerung des TCS3200 läuft so ab, dass je nachdem welcher Farbanteil gemessen werden soll, die Pins S2 und S3 HIGH bzw. LOW geschrieben werden. Dadurch filtert der Sensor die Farbanteile und gibt die Werte dazu aus. Mit S0 und S1 werden die Werte skaliert;

bei 100% (S0 -HIGH und S1-HIGH] gehen die Werte bis maximal 255, bei 20% (S0-HIGH, S1-LOW) sind die Werte niedriger.

Hier ein Link zu einem Datasheet mit den vollständigen Tabellen und noch einigen Zusatzinformationen: TCS3200: http://www.mouser.com/catalog/specsheets/TCS3200-E11.pdf

Messwerte

Der Farbsensor gibt vier Werte zurück: Rot-, Grün-, Blau- und Clear-Wert. Der Clear-Wert gibt die Helligkeit an. Hier sind unsere gemessenen Daten für die Farben auf unserem Rubiks Würfel:

Die Arme

Ruby hat viele Verwandte, die unterschiedliche Mechanik besitzen (siehe z.B. Links in der Einleitung). Für uns stellte sich die Frage, an welcher Version wir uns bei Ruby orientieren wollten. Roboter, die den Würfel auf Zeit lösen, haben oft sechs Stangen, die an den Mittelsteinen des Rubik’s Cubes befestigt sind. Der Würfel wird fest in den Roboter eingebaut und mit Schrauben oder ähnlichem fixiert. Die Konstruktion wäre vermutlich sehr schwer zu bauen, außerdem könnte der Würfel nicht ausgewechselt werden und der verwendete Rubik’s Cube würde beschädigt werden. Einen Farbsensor in dieser Konstruktion unterzubringen stellten wir uns ebenfalls schwierig vor. Eine andere Option der mechanischen Umsetzung Rubys waren vier Greifarme, welche den Würfel drehen, halten und im Zusammenspiel Seiten gegeneinander verdrehen können. Letztlich entschieden wir uns gegen diese Option, da wir uns auch hier das Scannen der Farben aufwändig vorstellten (einzelne Steine wären ständig von den Greifarmen verdeckt) und wir mit mindestens zwei Motoren pro Arm (für Zugreifen und Drehbewegung) einen recht hohen Materialaufwand gehabt hätten. Nach dem Vorbild der meisten von Arduino oder LEGO Mindstorms betriebenen “Rubik’s Cube Solver” entschieden wir uns dafür, dass Ruby eine drehbare Plattform bekommen sollte, auf der der Würfel platziert wird. Ein Sensorarm würde den Farbsensor über den Würfel schwenken und so die Farben einlesen. Weiterhin brauchte Ruby noch eine Möglichkeit, den Würfel zu kippen sowie ihn so zu halten, dass die unterste Schicht mithilfe der Plattform gedreht werden kann. Jede dieser Aufgaben soll in unserer Konstruktion mit einem eigenen Arm durchgeführt werden. In unserer aktuellen Konstruktion besitzt Ruby deshalb die folgenden “Gliedmaßen”:

Der Sensorarm

Skizze: Bewegung des Sensorarms

Der Sensorarm besteht aus einer Holzstange, an deren Ende der Farbsensor befestigt ist. Der Arm wird durch einen 180-Grad-Servo angetrieben. Für den Scan wird er aus seiner Ruheposition um etwa 90 Grad gedreht, sodass er sich über der Mitte des Würfels befindet. Ist die Farbe des Mittelsteins ausgelesen, fährt der Sensorarm ein kleines Stück zurück, sodass er sich über einem Kantenstein befindet. Während sich die Plattform mit dem Rubik’s Cube langsam dreht, liest der Farbsensor die Farben der Ecken und Kanten ein. Anschließend kehrt er in seine Ruheposition zurück und der Stupsarm kippt den Würfel, sodass die nächste zu scannende Seite oben liegt.

Der Greifarm

Skizze: Bewegung des Greifarms Foto Greifarm Der Greifarm besteht aus drei U-förmig angeordneten Holzbalken, deren Breite den Rubik’s Cube einspannt. Aus Stabilitätsgründen ist das U im hinteren Bereich mit einem weiteren Stück Holz fixiert. Die Konstruktion ist auf einer Seite an einem 180-Grad-Servo befestigt und liegt zudem auf einem Holzblock auf, um den Servomotor zu entlasten. In der Ruheposition steht der Greifarm senkrecht zur Bodenplatte, um den Würfel zu halten, dreht er sich um etwa 90 Grad in Richtung der Plattform. So spannt er die oberen beiden Schichten des Rubik’s Cubes ein, sodass die untere Schicht von der Plattform gedreht werden kann.

Der Stupsarm

Skizze: Bewegung des StupsarmsFoto Stupsarm

Der Stupsarm ist auf einem langen Holzblock angebracht. Er besteht aus einem Holzbalken mit einer kleinen Plastikschaufel am unteren Ende, der an einem Steppermotor befestigt ist. So ist der Stupsarm um 360 Grad drehbar. In der Ruheposition hängt er parallel zum Holzblock nach unten, in Aktion bewegt er sich auf die Plattform zu, stupst den Würfel an und dreht sich dann weiter, bis er wieder seine Ruheposition erreicht hat. Der Würfel dreht sich dabei um 90 Grad- so der Plan. Leider kippt er bis jetzt nur etwa 45 Grad, bleibt also auf der Kante liegen. Zudem müssen wir etwas nachhelfen, weil der Stupsarm Probleme hat, das Gewicht des Würfels zu stemmen.

Die Plattform

Die Plattform, die ziemlich genau die Grundfläche eines Rubik’s Cubes besitzt, ist ebenfalls auf einem Steppermotor angebracht. Mit diesem sind die Drehungen der Plattform theoretisch sehr genau steuerbar, was wichtig ist, damit der Würfel sich beim Drehen nicht verhakt.

Leider sind wir durch Zeitmangel nicht in der Lage gewesen, alle mechanischen Bauteile aufeinander abzustimmen. Während Greif- und Sensorarm sowie die Plattform technisch in der Lage sind ihre Aufgaben auszuführen und nur in der Programmierung und Zusammenarbeit verbessert werden müssen, hat der Stupsarm hinzukommend wie beschrieben noch einige andere Probleme.

Ausblick

Wenn ihr Lust bekommen habt, an Ruby weiterzuarbeiten sind hier noch die ungelösten Probleme, für die wir leider keine Zeit mehr hatten. Alle unsere Programme findet ihr am Ende der Dokumentation in programme.zip.

  1. Steuerung des Sensorarms
  2. Steuerung des Stupsarms
  3. Optimierung der Lösungsschritte
  4. Java-Arduino-Kommunikation
  5. Drehungen mit dem Roboter
  6. Fehlersuche und Codeimprovement
  7. Alternative: Mechanik umdenken?
1. Steuerung des Sensorarms

Der Sensorarm kann leicht angesteuert werden, unsere Programm ist FarbMessung.ino, welches verbessert werden kann und es ist noch etwas ungenau.

2. Steuerung und Optimierung des Stupsarms

Leider dreht sich der Würfel noch nicht, wenn wir ihn „angestupst“ haben, wahrscheinlich muss der Stupsarm noch geändert und angepasst werden. Der Motor müsste dann auch schnell genug sein, um den Würfel zu drehen, die Geschwindigkeit des Arms muss also noch ausprobiert werden. Demnach müsste dafür noch ein Programm geschrieben werden, welches den Würfel möglichst genau umdrehen kann.

3. Optimierung der Lösungsschritte

Unsere Lösungsalgorithmen sind zum größten Teil von uns selber entwickelt worden, nach der Anfängermethode, daher sind die Lösungsschritte sicher optimierbar. Besonders die Drehungen des ganzen Würfels kann auch anders gelöst werden, wir konnten dadurch allerdings einige Fälle zusammenfassen und hatten daher weniger Code.

4. Java-Arduino-Kommunikation

Die serielle Kommunikation zwischen Arduino und Java ist zwar bereits durch SerialTest.java gewährleistet, jedoch sollte hier noch an einem besseren Programm weiter gearbeitet werden. Durch richtiges Anwenden und verstehen der RXTX library sollte es schlussendlich möglich sein, eine Kommunikation von Arduino zu Java und von Java zu Arduino zu erstellen. Da das Arbeiten im Terminal und das Abstimmen von Arduino und Start der Java Datei wenig nutzerfreundlich ist, wäre auch hier eine optimale Erweiterung ein geeignetes GUI, wo eventuell auch das Abbilden der Zahlenwerte besser gestaltet werden kann.

Vielleicht sollte man aber hier auch ganz andere Möglichkeiten in Betracht ziehen:

Ardulink scheint eine wirklich angenehme Alternative zu der RXTX library zu sein. Es handelt sich um eine opensource Java Komplettlösung für Arduino, mit der man Arduinoboards vollkommen über Java steuern kann. Es besteht aus einer Sammlung von verschiedenen Bibliotheken, die sich ergänzen. Hiermit wäre beispielsweise das Problem mit der Abstimmung vom Start des Arduinoprogramms und des Javaprogramms gelöst, auch könnte man (wie dieses Youtube-Video zeigt: https://www.youtube.com/watch?v=Sm2pkr8E_S0) GUIs sehr gut gestalten, um den Arduino zu kontrollieren, sowie das Javaprogramm. Hier ist außerdem auch der Rückweg, also von Java zu Arduino, gewährleistet.

Soviel als Anregungen für ein weiteres Vorgehen auf diesem Gebiet.

Ein Link zum Arduino Playground, der für ein Java-Arduino Interface Lösungen anbietet:

https://playground.arduino.cc/Interfacing/Java

Ein Link zum offiziellen RXTX library Wiki:

http://rxtx.qbang.org/wiki/index.php/Main_Page

Ein Link zur offiziellen Ardulink Website:

http://ardulink.org/

5. Drehungen mit dem Roboter

Wir haben die Drehungen des Würfels noch nicht auf den Roboter übertragen. Da dieser nur eine Seite drehen kann, muss der Würfel auf die zu betreffende Seite gedreht werden. Der Greifarm wurde noch nicht zum Halten programmiert, wobei auch die Konstruktion noch angepasst werden könnte/müsste. Auch kann der Roboter den Würfel noch nicht drehen, also noch nicht selbst lösen. Die Drehungen über den 360° Steppermotor müssen sehr genau sein, da sich der Würfel sonst verkeilt und auch dann nicht gelöst werden kann. Das müsste auch noch umgesetzt werden, weitere Informationen siehe Die Arme.

6. Fehlersuche und Codeimprovement

Natürlich werden wir in unserem Code oder auch in den Algorithmen noch Fehler haben, denn obwohl viele Würfelkonstellationen bereits von Ruby gelöst wurden, war es uns nicht möglich ein Programmpart zu entwickeln, das alle Würfelkonstellationen (zumindest in den einzelnen Phasen) überprüft. Also müssten diese Fehler, die zu keiner Lösung für den Würfel führen, erkannt und behoben werden. Vielleicht könnte man also auch hier ansetzen und weitere Energie in Bugfixing stecken bzw. besagtes Programm erstellen, dass Würfelkonstellationen eigenständig erstellt und anschließend von Ruby lösen lässt. Selbstverständlich steht auch der Code zur allgemeinen Verbesserung bereit: Sobald Ihr der Ansicht seid, dass gewisse Algorithmen, egal ob formaler oder programmtechnischer Natur, unbedingt speicher- oder laufzeiteffizienter oder effizienter bezüglich der Umsetzung eines Algorithmus zu gestalten seien, bleibt dies natürlich Euch zur Verbesserung offen.

7. Alternative: Mechanik umdenken?

Wie schon mehrfach erwähnt, konnten wir die Mechanik nicht fertigstellen. Nun stellt sich aber auch die Frage, ob wir mit einer anderen Bauweise vielleicht besser ans Ziel gekommen wären. Im Nachhinein betrachtet hätten wir uns vielleicht doch für die Bauweise mit den vier Greifarmen entscheiden sollen. Dies hätte den Vorteil, dass die Arme alle gleich aufgebaut wären und somit eine geringere Anzahl an Bewegungen realisiert werden müssten. Außerdem bräuchten die vier Greifarme zwar einen sehr präzisen Greifmechanismus, doch auch unsere Arme müssen sehr präzise kalibriert werden. Der Kraftaufwand, den vor allem unser Stupsarm aufbringen muss, wäre bei vier Greifarmen voraussichtlich sehr viel geringer. Ein weiterer Vorteil dieser Methode wäre, dass die Drehkombinationen, die Ruby mit dem Lösungprogramm errechnet, nahezu übernommen werden könnten, da vier der sechs Seiten des Würfels frei drehbar wären, anstatt wie bei unserer jetzigen Konstruktion nur eine. Dieser Schritt war zu Anfang unserer Projektplanung noch so utopisch, dass wir ihn wenig beachtet haben. Als komplizierter würde sich allerdings der Farbscan erweisen. Entweder bräuchte man wohl noch zusätzliche Motoren, um den Farbsensor um mehrere Achsen drehen zu können, oder man müsste ihn so anbringen, dass er eine senkrecht stehende Seite des Würfels scannt, die dann vom gegenüberliegenden Greifarm gedreht wird (ähnlich wie jetzt von der Plattform). Ob ihr unsere Mechanik verbessern wollt, euch an den eben beschriebenen Ansatz mit den vier Armen macht oder eine ganz andere Bauweise entwickelt, bleibt euch natürlich überlassen.

Technische Daten, Bauteile, Pins, etc.

Verwendete Bauteile

Allgemein:
  • runde Holzplatte (Durchmesser 30cm)
  • Arduino Nano inkl. Board
  • Computer
  • Kabel
  • Kabelbinder
  • Isolierklebeband
Plattform:
  • Holzplatte, 7x7cm
  • 4 Holzplatten, 7×1,5cm
  • Steppermotor
Sensorarm:
  • Holzplatte, 2-3x21cm
  • RGB Farbsensor TCS3200
  • 180-Grad-Servomotor
  • Holzblock 4,5×2,5×7,5cm
Greifarm:
  • Holzplatte 2,5x7cm
  • 2 Holzplatten 2,5×15,5cm
  • Holzblock 1x1x7cm
  • 180-Grad-Servomotor
  • 2 Holzblöcke 4,5×2,5x5cm
Stupsarm:
  • Holzblock 4,5×1-2,5x16cm
  • Holzblock 1x1x15cm
  • Plastikplatte 1,5x4cm
  • Steppermotor

Pinbelegungstabelle

Code

programme.zip

Wir hoffen, dass Dir unser Projekt gefallen hat und vielleicht möchtest Du mit anderen daran weiterarbeiten. Viel Spaß mit Ruby!

projektesose17/username404public/start.txt · Zuletzt geändert: 2017/10/09 14:49 von c.jaedicke