# HG changeset patch # User schnalke@localhost.localdomain # Date 1213270626 -7200 # Node ID cf891206ae27a364b4c5ee0bb6fbf4bc0c3b98cb # Parent 94535a512cfec472551505842aef1fd3bb841323 added more content to intelligence module; improves some lines diff -r 94535a512cfe -r cf891206ae27 taetigkeit.tex --- a/taetigkeit.tex Thu Jun 12 13:35:57 2008 +0200 +++ b/taetigkeit.tex Thu Jun 12 13:37:06 2008 +0200 @@ -37,7 +37,7 @@ \paragraph{Programmablauf} -Als Ausgangsdaten habe ich die Positionen und Ausrichtungen der Roboter in der ``Welt'' und die sämtliche Gelenkwinkel. Aus diesen Daten habe ich die Welt-Koordinaten, also Koordinaten bezogen auf das globale Koordinatensystem, aller Gelenke berechnet. Mit den globalen Koordinaten führe ich die Kollisionsberechnung durch, denn diese liegen im gleichen Koordinatensystem und Abstandberechnungen sind somit einfach: $distance = \sqrt{\Delta x^{2} + \Delta y^{2} + \Delta z^{2}}$. +Als Ausgangsdaten habe ich die Position und Ausrichtung der Roboter in der ``Welt'' und sämtliche Gelenkwinkel. Aus diesen Daten habe ich die Welt-Koordinaten, also Koordinaten bezogen auf das globale Koordinatensystem, aller Gelenke berechnet. Mit den globalen Koordinaten führe ich die Kollisionsberechnung durch, denn diese liegen im gleichen Koordinatensystem und Abstandberechnungen sind somit einfach: $distance = \sqrt{\Delta x^{2} + \Delta y^{2} + \Delta z^{2}}$. \paragraph{Ergebnis} @@ -52,9 +52,9 @@ Im Laufe meiner Arbeiten an der Kollisionskontrolle musste ich mir oft ein Bild von den Stellungen der Roboter machen um die berechneten Werte überprüfen zu können. Ich wollte möglichst unabhängig von den realen Robotern im Labor arbeiten, von denen wir zu dieser Zeit sowieso nur zwei hatten. Anfangs habe ich mir die Winkelstellungen oder die Koordinaten der Gelenke ausgeben lassen und dann unseren defekten Testarm entsprechend eingestellt. So konnte ich mir die Situation einigermaßen vorstellen. Alternativ habe ich zu Stift und Papier gegriffen um mir die Situation zu zeichnen. Dies bedeutete jedoch immer wieder den gleichen Aufwand zu betreiben, nur um die Roboterstellungen visuell vor Augen zu haben. \paragraph{Bilderzeugung} -Wiederkehrende Aufgaben soll man automatisieren --- das ist bekannt. Ich wollte mir also automatisch Bilder generieren lassen, um die stupide Arbeit auf den Computer zu übertragen. Als geeignetes Grafikformat erschien mir das \emph{Scalable Vector Graphics}-Format, das eine Textdatei in XML ist. Somit konnte ich einfach line- und circle-Befehle vom Programm in eine Textdatei schreiben lassen. Im Vergleich zu den bisherigen Ausgaben der Gelenk-Koordinaten in der Welt, war in erster Linie nur eine andere Schreibweise. SVG-Dateien werden von gängigen Bildbetrachtern und aktuellen Browsern angezeigt. +Wiederkehrende Aufgaben soll man automatisieren --- das ist bekannt. Ich wollte mir also automatisch Bilder generieren lassen, um die stupide Arbeit auf den Computer zu übertragen. Als geeignetes Grafikformat erschien mir das \emph{Scalable Vector Graphics}-Format, das eine Textdatei in XML ist. Somit konnte ich einfach line- und circle-Befehle vom Programm in eine Textdatei schreiben lassen. Im Vergleich zu den bisherigen Ausgaben der Gelenk-Koordinaten, war es in erster Linie nur eine andere Schreibweise. SVG-Dateien werden von gängigen Bildbetrachtern und aktuellen Browsern angezeigt. -Ich habe die SVG-Generierung als separates Modul implementiert, das bei Bedarf aktiviert werden kann und dann in jedem Programm-Cycle ein Bild der Roboterstellungen zeichnet. Die Darstellung im Bild ist zwei-dimensional, da 3D-Abbilder nur bei beweglicher Kamera sinnvoll nutzbar sind. Ich habe deshalb die Dreitafelprojektion verwendet, die auch technischen Zeichnungen und Bauplänen bekannt ist. +Ich habe die SVG-Generierung als separates Modul implementiert, das bei Bedarf aktiviert werden kann und dann in jedem Programm-Cycle ein Bild der Roboterstellungen zeichnet. Die Darstellung im Bild ist zwei-dimensional, da 3D-Abbilder nur bei beweglicher Kamera sinnvoll nutzbar sind. Ich habe deshalb eine Dreitafelprojektion verwendet, die auch technischen Zeichnungen und Bauplänen bekannt ist. \begin{figure}[hbt] \centering @@ -64,10 +64,10 @@ \end{figure} \paragraph{Animation} -Wenig später waren dann selbst die Einzelbilder teilweise zu umständlich, so dass der Wunsch nach einer animierten Darstellung des Geschehens aufkam. SVG-Animationen ausgeben zu lassen wäre deutlich komplizierter geworden, und diese können auch nur von wenigen Programmen dargestellt werden. Deshalb habe ich mit der Programmsammlung \emph{ImageMagick} aus dem SVG-Bildern ein animiertes GIF gemacht. Dieses stellte dann auch die Zeitdimension in den Bewegungen dar. Später wurden die GIFs dann durch komprimierte AVI-Filme ersetzt, da diese deutlich weniger Speicher verbrauchen und schneller erzeugt werden konnten. +Wenig später waren dann selbst die Einzelbilder teilweise zu umständlich, so dass der Wunsch nach einer animierten Darstellung des Geschehens aufkam. SVG-Animationen ausgeben zu lassen wäre deutlich komplizierter geworden, und diese können auch nur von wenigen Programmen dargestellt werden. Deshalb habe ich mit der Programmsammlung \emph{ImageMagick} aus dem SVG-Bildern ein animiertes GIF gemacht. Dieses stellte dann auch die Zeitdimension in den Bewegungen dar. Später wurden die GIFs dann durch komprimierte AVI-Filme (mit \emph{MEncoder} erstellt) ersetzt, da diese deutlich weniger Speicher verbrauchen und schneller erzeugt werden konnten. \paragraph{Ergebnis} -Es liegt hier eine Komponente vor, die die Entwicklung des Restsystems deutlich vereinfacht hat. Mit ihr war es möglich, im Büro zu testen --- es mussten nicht die Roboter im Labor bemüht werden. Zudem konnten durch den direkteren Weg von den Basisdaten zum visuellen Ergebnis Fehlerquellen eliminiert werden. So war es unter anderem auch hilfreich bei der Suche nach einem Bug in der Kinematik --- der ja erst durch die Unterschiede zwischen SVG-Simulation und realen Roboterbewegungen sichtbar wurde. +Es liegt hier eine Komponente vor, die die Entwicklung des Restsystems deutlich vereinfacht hat. Mit ihr war es möglich, im Büro zu testen --- es mussten nicht die Roboter im Labor bemüht werden. Zudem konnten durch den direkteren Weg, von den Basisdaten zum visuellen Ergebnis, Fehlerquellen eliminiert werden. So war es unter anderem auch hilfreich bei der Suche nach einem Bug in der Kinematik --- der ja erst durch die Unterschiede zwischen SVG-Simulation und realen Roboterbewegungen sichtbar wurde. Es freut mich um so mehr, dass ich bei Fred Brooks ``The Mythical Man-Month'' bestätigt finde, was ich nebenbei herausgefunden habe: Es ist sinnvoll einen Simulator zu haben und diesen parallel mit dem eigentlichen Programm zu entwickeln. @@ -83,11 +83,11 @@ \paragraph{Aufgabe der Intelligenz} Das Logik-Modul plant, entscheidet und gibt die resultierenden Befehle. Es beherbergt den ``interessanten'' Programmcode, denn hier steckt eine Künstliche Intelligenz (so simpel sie auch sei). -In unserem Fall hat die Logik die aktuelle und letzte Ballposition, sowie die Roboterpositionen zur Verfügung. Das Modul soll ausgeben welcher Roboterarm was als nächstes tun soll. +In unserem Fall hat die Logik die aktuelle und letzte Ballposition, sowie die Roboterpositionen zur Verfügung. Das Modul soll ausgeben was welcher Roboterarm als nächstes tun soll. \paragraph{Grundgedanken} -Unser Showcase ist so aufgebaut, dass es immer mindestens einem Roboter möglich ist, den Ball zu spielen, nie jedoch mehr als zweien. In den meisten Fällen wird der Ball nur von genau einem Arm erreichbar sein, dann wird dieser ihn spielen. Wenn zwei Roboter nah genug sind, übernimmt der Arm mit der geringeren Entfernung (genannt ``Master'') die Kontrolle und spielt den Ball. Der andere Arm (genannt ``Slave'') fungiert als Unterstützung und bewegt sich relativ zum Master. Dieses Verhalten sollte uns bei unvorgesehenen Änderungen des Ballwegs nützlich sein. Die restlichen Arme fahren in eine Warte-Position. +Unser Showcase ist so aufgebaut, dass es immer mindestens einem Roboter möglich ist, den Ball zu spielen. In den meisten Fällen wird der Ball nur von genau einem Arm erreichbar sein, dann wird dieser ihn spielen. Wenn zwei Roboter nah genug sind, übernimmt der Arm mit der geringeren Entfernung (genannt ``Master'') die Kontrolle und spielt den Ball. Der andere Arm (genannt ``Slave'') fungiert als Unterstützung und bewegt sich relativ zum Master. Dieses Verhalten sollte uns bei unvorgesehenen Änderungen des Ballwegs nützlich sein. Die restlichen Arme fahren in eine Warte-Position. Nur wenn der Ball in der Mitte des Spielfeldes zum stehen kommt, haben mehrere Roboter die Möglichkeit ihn zu erreichen. Es wird dann der nahste Roboter aktiv werden. \paragraph{Die Schussbewegung} % FIXME: die paragraph-zeile weg? Der Ball sollte nicht nur am Paddle (= Schläger), den wir am Greifer des Arms befestigt haben, abprallen, sondern es sollte ihm wieder neue Bewegungsenergie mitgegeben werden. Es war also klar, dass die Roboter eine gewissen Schussbewegung ausführen mussten. Desweiteren war es notwendig das Paddle im richtigen Winkel auszurichten, um den Ball in eine bestimmte Richtung spielen zu können. Das Schussziel sollte in im Intelligenz-Modul gesetzt werden können. Damit wäre es dann auch möglich, dass sich nur zwei Roboter hin und her spielen. Solche ``Spielereien'' sollten auf jeden Fall machbar sein, denn diese machen einen Showcase erst interessant und zeigen einen Hauch menschlichen Verhaltens, was bei Robotern eine wichtige Komponente ist. @@ -95,8 +95,28 @@ \paragraph{Mögliche Erweiterungen} Die Intelligenz bietet Ausbaumöglichkeiten aller Art. Das geht von einer Bibliothek von Entscheidungsmöglichkeiten, über persönliche Verhaltensmuster einzelner Roboter, bis zu Gruppenverhalten, Taktik, oder gar Finten. +So zumindest die Theorie, denn \dots +\paragraph{Die Realität} +Bevor wir den Aufbau für die Roboter hatten, simulierten wir nur eine mögliche Ballbahn und betrachteten das Ergebnis in den erzeugten SVG-Grafiken. Es funktionierte alles ziemlich gut. Als wir das Ballspiel dann in echt sahen war es katastrophal! Wir hatten nicht bedacht, dass sich der reale Ball keineswegs auf geraden Bahnen bewegte. Eine Billard-Kugel hätte das auf einem Marmor-Untergrund vielleicht getan. Unser Schaumstoffball, der noch nicht mal eine ebene Oberfläche hatte, bewegte sich manchmal fast willkürlich. Er änderte seine Bahn, rollte wieder zurück, blieb einfach liegen, wackelte auf der Stelle \dots und unsere Intelligenz, die mit einem (idealen) simulierten Ball umgehen konnte, wusste plötzlich nicht mehr wie ihr geschah. +Es galt also diesen Unregelmäßigkeiten entsprechend zu begegnen. Sich ändernde Ballwege waren grundsätlich kein Problem, da sie schon von Beginn an bedacht waren. Liegen gebliebene Bälle mussten neu angestoßen werden --- auch dies war mit relativ wenig Aufwand machbar. Auf der Stelle wackelnde Bälle waren schon ein größeres Problem, denn einmal sieht es so aus, als ob der Ball nach rechts läuft, in nächsten Zyklus aber als wenn er nach links läuft, und so weiter. Die Roboter wissen also nicht wohin er sich denn nun bewegt. Ich habe dazu nur Ballbewegungen die zweimal in ungefähr die gleiche Richtung gehen, als tatsächliche Ballbewegung gewertet. Eine Bewegung in die entgegengesetzte Richtung im nächsten Zeitschritt, bedeutet Stillstand. So waren die auf der Stelle zitternden Bälle eliminiert. Alle tatsächlichen Ballbewegungen habe ich dann noch ausgeglichen um die Ballbahn gleichmäßiger zu machen. + +\paragraph{Zustandslosigkeit} +Das große Problem, das sich mit der Zeit herausstellte, war die Zustandslosigkeit des Intelligenz-Moduls. Ich hatte es so aufgebaut, dass jeweils nur anhand des letzten Zeitschrittes (wenn überhaupt) entschieden wird, wie als nächstes agiert werden soll. In der Realität stellte sich aber heraus, dass dies nicht genug war. Es war nötig, Roboter in Zustände zu versetzen und diese über mehrere Zyklen beibehalten zu können. So benötigt es mehrere Zyklen um einen Ball der hinter einem Roboterarm festgeklemmt ist, wieder in's Spiel zu bringen. Der Roboter muss dazu seinen Arm heben, über den Ball zurück fahren und ihn von hinten anstoßen. Während dieses Vorgangs sollte er nicht unterbrochen werden. Änderungen an der Grundstruktur der Intelligenz waren an diesem Punkt zeitlich nicht mehr möglich; so setzte ich auf \texttt{static}-Variablen, um Zustände speichern zu können. Die Lösung war nicht unbedingt schön, aber zweckmäßig. + +\paragraph{Wo ist der Ball?} +Die punktuelle Sichtweise der Dinge machten uns auch im Bezug auf die Position des Balles zu schaffen. Das Problem war, dass wir, wenn kein Ball vom Vision-Modul gefunden wurde, nicht sagen konnten, ob der Ball einfach nicht erkannt wurde, er sich gar nicht mehr im Bild befand, oder er unter einem Roboterarm für die Kamera unsichtbar war. Ein Mensch nimmt dieses Problem zuerst gar nicht wahr. Für uns war es aber zentral, denn je nach tatsächlicher Position mussten verschiedene Aktionen ausgeführt werden: Wurde der Ball nur nicht erkannt, dann sollten die Arme abwarten, in der Hoffnung, dass der Ball im nächsten Zyklus wieder erkannt würde. War der Ball vom Tisch, dann sollten die Roboter in die Wartestellung fahren und so verweilen. War der Ball aber unter einem Arm eingeklemmt, dann sollte dieser eine ``Befreiungsbewegung'' ausführen um den Ball wieder in's Spiel zu bringen. Würde er, im letzten Fall, dies nicht tun, dann wäre das Spiel in einer Sackgasse angelangt, denn beim Abwarten, oder Bewegen in die Wartestellung würde der Ball weiterhin unter dem Arm bleiben --- unsichtbar. + +Eine der wichtigsten Anforderungen an das Programm war jedoch, dass es ohne menschliches Einwirken quasi endlos laufen sollte. Aus Sackgassensituationen wie dieser mussten also auch Wege hinaus führen. + +Dieses Problem löste sich ziemlich gut, indem wir deine wahrscheinliche Ballposition (ausgehend von der bisherigen Bewegung) annahmen, falls er nicht gefunden wurde. Wurde er jedoch über mehrere Zyklen nicht gefunden, sollte zuerst der Roboter der dem Ball wahrscheinlich am nächsten war, eine Befreiungsbewegung ausführen. War der Ball dann immer noch verschwunden, sollten alle Roboter die Bewegung ausführen. Brachte dies den Ball noch immer nicht zum Vorschein, dann war er vermutlich außerhalb des Spielfeldes und die Roboter sollten in ihre Ruhestellung fahren und warten \dots bis der Ball wieder auftauchen würde. + + +\section{Bilderkennung} + + +\section{Auf der Messe}