AiboControl ReadMe

Systemanforderungen

Betriebssystem

Entwicklungsumgebung

Hardware

Installation

Das Archiv AiboControl.zip kann irgendwo ausgepackt werden. Falls auf dem Rechner kein Cygwin installiert sein sollte, muss Bin\noCygwin.bat gestartet werden. Dabei muss Bin das aktuelle Verzeichnis sein, was z.B. gewährleistet ist, wenn man die Datei per Doppelklick startet.

Damit die Simulationsszenen später mit dem vorgesehenen Fensterlayout erscheinen, sollte man Config\Layout.reg per Doppelklick zur Registrierung hinzufügen.

Damit ist die Installation abgeschlossen und das Microsoft Developer Studio kann mit Make\SimGT2003.dsw gestartet werden.

Bedienung

Nach dem Starten von SimGT2003.dsw (und somit dem Microsoft Developer Studio) sollte SimGT2003 das aktuelle Projekt sein. Dieses kann dann mit Erstellen|SimGT2003.exe erstellen kompiliert werden. Das erstellte Programm kann mit Erstellen|Debug starten|Ausführen im Debugger gestartet werden. SimGT2003 lädt automatisch die Szene Config\Braitenberg.scn.

Im Config-Verzeichnis befinden sich fünf Szenen:

Braitenberg.scn
Eine Simulationsszene für eine Aufgabe des ersten Übungszettels. Es wird kein echter Roboter benötigt.
201.scn
Eine Szene, die eine Verbindung zum Roboter mit der IP-Adresse 172.21.3.201 herstellt. Bevor diese aufgebaut werden kann, muss der Roboter vollständig gestartet sein, d.h. er muss selbstständig stehen können. Nach dem Starten der Szene dauert es ein bisschen, bis die Verbindung hergestellt wurde. Die Ausgabe im Konsolenfenster muss nach einiger Zeit zweimal den Text "connection established" enthalten.
202.scn
Eine Szene, die eine Verbindung zum Roboter mit der IP-Adresse 172.21.3.202 herstellt.
203.scn
Eine Szene, die eine Verbindung zum Roboter mit der IP-Adresse 172.21.3.203 herstellt.
204.scn
Eine Szene, die eine Verbindung zum Roboter mit der IP-Adresse 172.21.3.204 herstellt.

Die Szene, die beim Starten von SimGT2003 im Debugger geladen wird, kann im Developer Studio unter Projekt|Einstellungen|Debug|Programmargumente eingestellt werden. Szenen dürfen nur im Config-Verzeichnis liegen, da von dort aus auf andere Dateien über relative Pfadangaben zugegriffen wird.

Roboter

Vorbereitung

Es gibt vier Memorysticks mit den Bezeichnungen 201, 202, 203 und 204. Die Nummern entsprechen jeweils der Endung der IP-Adresse des Roboters, der mit diesem Stick betrieben wird. Ein solcher Stick sollte sich im Roboter befinden, bevor er eingeschaltet wird.

Einschalten

Der Roboter wird durch Drücken des Knopfes an seiner Brust eingeschaltet. Sollte nach kurzer Zeit eine Tonfolge zu hören sein, nach der sich der Roboter abschaltet, muss der Akku gewechselt werden. Den Roboter beim Einschalten entweder festhalten, auf seine Styropor-Halterung oder auf den Boden legen. Niemals auf einem Tisch oder ähnlich erhöhten Flächen starten, da der Roboter herunterfallen könnte.

Ausschalten

Zum Ausschalten des Roboters bitte den Memorystick ein kurzes Stück herausziehen oder den Akku kurz entnehmen. Der Schalter an der Brust deaktiviert den Roboter nicht vollständig, daher eignet er sich nicht zum Ausschalten.

Akku-Handling

Es gibt nur vier Orte, an denen ein Akku sein darf: in einem Roboter, auf dem Stapel der leeren Akkus, im Ladegerät oder auf dem Stapel der geladenen Akkus. Immer, wenn Akkus im Ladegerät aufgeladen wurden (LED leuchtet grün), sollten sie entnommen und auf den Stapel der vollen Akkus gelegt werden. Immer, wenn Platz im Ladegerät ist, sollten leere Akkus geladen werden. Akkus sollten erst geladen werden, wenn sie leer sind, d.h. wenn der Roboter nicht mehr mit ihnen starten kann. Defekte Akkus sollten gemeldet werden.

Programmierung

Eigene Roboter-Steuerprogramme sind Instanzen von Klassen, die von SensorDataToMotionRequest abgeleitet werden. Diese Klasse findet sich in Src\Modules\SensorDataToMotionRequest\SensorDataToMotionRequest.h. Im gleichen Verzeichnis liegt eine leere Klasse MyController, die ergänzt werden kann. Die zentrale Funktion ist execute(), die jedes Mal aufgerufen wird, wenn ein neues Bild vom Roboter eintrifft. Die Funktion hat keine Parameter, weil alle Ein- und Ausgaben in der Basisklasse definiert sind und von dort geerbt werden.

Eingaben

Image image
Ein Kamerabild. Die Klasse Image ist in Src\DataTypes\Perception\Image.h definiert.
SensorData sensorData
Ein Vektor, der alle Messwerte der Sensoren außer dem Kamerabild enthält. Die Klasse SensorData ist in Src\DataTypes\Perception\SensorData.h definiert. Die dort vereinbarten enum-Konstanten können als Indizes in den Vektor data verwendet werden. Nähere Informationen zu den Sensoren liefert das Dokument Model Information for ERS 210 von Sony. Generell gilt, dass z.B. Winkel in Mikroradiant (Millionstel Bogenmaß) angegeben werden.

Ausgaben

MotionRequest motionRequest
Mit einem MotionRequest kann man die Laufbewegung des Roboters steuern. Die Klasse MotionRequest ist in Src\DataTypes\Motion\MotionRequest.h definiert. Vorerst reichen folgende Einstellungen:
motionRequest.motionType = MotionRequest::walk;
motionRequest.walkType = MotionRequest::normal;

motionRequest.walkParams.translation.x = Vorwärtsgeschwindigkeit in mm/s;
motionRequest.walkParams.translation.y = Seitwärtsgeschwindigkeit in mm/s;
motionRequest.walkParams.rotation = Rotationsgeschwindigkeit in Bogenmaß/s;

motionRequest.tailRequest = MotionRequest::Modus für Schwanzbewegung 
HeadMotionRequest headMotionRequest
Mit einem HeadMotionRequest kann man die Lage des Kopfes des Roboters steuern. Die Klasse HeadMotionRequest ist in Src\DataTypes\Motion\HeadMotionRequest.h definiert. Es können die drei Kopfwinkel tilt, pan und roll in Mikroradiant gesetzt werden.
 
LEDRequest ledRequest
Mit einem LEDRequest können die LEDs des Roboters an- und abgeschaltet werden. Die Klasse LEDRequest ist in Src\DataTypes\Motion\LEDRequest.h definiert. Dort ist für jede LED eine Konstante definiert. Diese Konstanten können "ver-odert" und an die Member-Variable state zugewiesen werden, z.B.:
ledRequest.state = LEDRequest::redLT | LEDRequest::redRT | LEDRequest::greenT;

Debug-Ausgaben

Es gibt zwei Sorten von Debugging-Ausgaben. Beide werden mit dem OUTPUT-Makro ausgegeben:

Text
Ausgaben können direkt im OUTPUT-Makro gemacht werden:
OUTPUT(idText,text,"Dies ist ein Text " << 42 << " " << 3.1415);
Zeichnungen
Eine Zeichnung ist eine Instanz der Klasse DebugDrawing, die in Tools\Debugging\DebugDrawing.h definiert ist. Zwei Arten von Zeichnungen können erzeugt werden: in Bildkoordinaten (176x144) und in Feldkoordinaten (in mm). Eine Zeichnung in Bildkoordinaten wäre z.B.:
DebugDrawing drawing(DebugDrawing::image);
drawing.line(0,0,175,143);
OUTPUT(idDebugDrawing,bin,drawing);
Für eine Zeichnung in Feldkoordinaten würde die Zeichnung stattdessen mit DebugDrawing::field initialisiert.

Das OUTPUT-Makro erzeugt mehrere C++-Anweisungen. Daher muss es in geschweifte Klammern eingefasst werden, falls es einen Block darstellen soll:

if(condition)
  OUTPUT(idText,text,"Dies ist falsch!");

Stattdessen:

if(condition)
{
  OUTPUT(idText,text,"Dies ist richtig!");
}

Zusicherungen

Das Makro ASSERT kann genutzt werden, um Zusicherungen zu überprüfen. Dazu muss die Datei Platform/GTAssert.h eingebunden sein. ASSERT hält das Programm an, wenn der als Parameter übergebene Ausdruck gleich 0 ist. Der dabei angezeigte Dialog ermöglicht durch Anwählen von Wiederholen den Sprung in den Debugger. Zum Beispiel überprüft das folgende Code-Fragment, ob der Index i innerhalb der Grenzen von array liegt, bevor auf array zugegriffen wird:

ASSERT(i >= 0 && i < sizeof(array) / sizeof(array[0]));
j = array[i];

Mehrere Steuerprogramme

Um ein weiteres Steuerprogramm neben MyController anzulegen, sind folgende Schritte notwendig:

  1. In dem Ordner, in dem auch MyController.cpp/.h liegen, muss eine neue Klasse angelegt werden, die wie MyController von SensorDataToMotionRequest erbt. Als Vorlage kann MyController verwendet werden. Die neuen Dateien müssen auch zum Projekt im Developer Studio hinzugefügt werden. Dazu klickt man mit der rechten Maustaste auf den Ordner SensorDataToMotionRequest im Dateien-Baum des Developer Studios und wählt Dateien hinzufügen aus und fügt die entsprechenden Dateien ein.
  2. In Src/Tools/Module/SolutionRequest.h muss der enum ModuleSolutionID zwischen myController und numOfSensorDataToMotionRequestSolutions um eine Konstante erweitert werden (ohne "= 0"). Diese Konstante wird verwendet, um die neue Klasse eindeutig zu identifizieren. Die Einfügestelle ist durch einen TODO-Kommentar markiert.
  3. In derselben Datei muss die Funktion getModuleSolutionName() so erweitert werden, dass sie für die neu definierte Konstante eine (eindeutige) Zeichenkette zurück liefert. Die Stelle ist wiederum markiert.
  4. Die Datei Src/Modules/SensorDataToMotionRequest/SensorDataToMotionRequestSelector.h muss die Header-Datei der neu definierten Klasse einbinden. Außerdem muss an der markierten Stelle im Konstruktor von SensorDataToMotionRequestSelector ein Funktionsaufruf nach folgendem Muster eingefügt werden:
    addSolution(SolutionRequest::neueKonstante,new NeueKlasse(interfaces));
  5. Damit die neu angelegte Klasse die Standard-Robotersteuerung wird, muss ihr Name (d.h. die Zeichenkette, die getModuleSolutionName() für sie zurückliefert) in Config/Modules.cfg hinter SensorDataToMotionRequest statt MyController eingetragen werden.

Systemzeit

Um die Systemzeit, z.B. für Zeitmessungen, abfragen zu können, muss Platform/SystemCall.h eingebunden werden. Die Klasse SystemCall hat nur zwei statische Funktionen, nämlich getCurrentSystemTime() und getTimeSince(). Erstere liefert einen Zeitstempel im Millisekunden, die zweite bestimmt die Zeitdifferenz zwischen der übergebenen Zeit und der aktuellen:

unsigned long time = SystemCall::getCurrentSystemTime();
// ...
OUTPUT(idText,text,SystemCall::getTimeSince(time));

Kommunikationsgeschwindigkeit

Es gibt zwei Geschwindigkeiten, mit denen der Roboter seine Daten mit dem PC austauschen kann. Es dauert dabei aber immer etwa 0,5 s, um Sensordaten zum PC zu übertragen und dessen Reaktion zurück zum Roboter. Es ist allerdings möglich, dass der PC und der Roboter alle 0,2 s mit Daten versorgt werden, nur dass sich diese dann zeitlich überlappen.

Zwischen beiden Varianten kann in der Datei Config\init.con gewechselt werden, indem eine der beiden Varianten einkommentiert und die andere auskommentiert wird. Kommt der PC bei der schnellen Variante nicht hinterher (die angezeigten Bilder sind "alt"), kann man in den beiden letzten Zeilen der Datei die Zahlen erhöhen (momentan steht da "2").