c't-Bot und c't-Sim

Seite 3: Der Robotersimulator c't-Sim

Inhaltsverzeichnis

Damit kleine Programmierfehler keine großen Folgen haben, lohnt sich der ausführliche Test des Steuercodes, bevor dieser in den Roboter übertragen wird. Dazu bedarf es allerdings einer Umgebung, die den Routinen vorgaukelt, tatsächlich einen Bot zu steuern, der sich durch eine Welt voller Hindernisse bewegt. Eine solche Testumgebung bietet der Roboter-Simulator c't-Sim.

ACHTUNG: Für den c't-Sim-Labyrinthwettbewerb kommt eine spezielle Version des Simulators zum Einsatz. Wie man diese gezielt aus dem CVS auslesen kann, beschreibt ein gesonderter Abschnitt der Installationsanleitung.

Für Trainingsläufe haben wir den c't-Sim mit einem Labyrinthgenerator ausgestattet, der auf Knopfdruck jeweils einen neuen, mit den Regeln des Wettbewerbs konformen Parcours erzeugt.

Will man den Simulator möglichst schnell in Gang setzen, braucht man dazu nur eine Java-Laufzeitumgebung nebst der Java-3D-Bibliothek (siehe Installationsanleitung) und die beiden ausführbaren Dateien ct-Bot.exe (Windows) beziehungsweise ct-Bot.elf (Linux) sowie ct-Sim.jar (für beide Plattformen) aus dem Binaries-Zip-Archiv. Die Simulationsumgebung ct-Sim.jar startet man auf der Kommandozeile über:

java -jar ct-Sim.jar

Sie öffnet ein Fenster mit der grafischen Darstellung der (noch leeren) Welt sowie ein zweites, das später für jeden Bot eine Kontrolltafel zeigt. In einer zweiten Konsole startet man den ct-Bot. Dieser meldet sich über eine TCP/IP-Verbindung beim Simulator an, standardmäßig verwendet er die lokale IP (127.0.0.1) auf Port 10001. Sein roter Avatar taucht innerhalb der simulierten Umwelt auf, im anderen Fenster erscheint eine Kontrolltafel, auf der die Zustände der IR-Sensoren und der Motoren sowie Position und Blickrichtung des Bot als Zahlen angezeigt werden. Werte, die der Benutzer zur Laufzeit direkt beeinflussen kann, verfügen außerdem über einen Schieberegler. Wird die Checkbox "setzen" aktiviert, überschreibt der eingestellte Wert den aktuellen Zustand des Bot. Möchte man solche Einstellungen nicht im laufenden Betrieb vornehmen, unterbricht die "Pause"-Taste die Simulation vorübergehend.

Für Trainingsläufe zum c't-Sim-Wettbewerb haben wir den c't-Sim mit einem Irrgarten-Generator ausgestattet. Dieser liefert frische Herausforderungen, wenn der Bot die Standardstrecken des Simulators bereits mit links absolviert. Ein neues, mit den Regeln des Wettbewerbs konformes Labyrinth erhält man jedesmal, indem man im Sim auf den Menüpunkt Welt/Generieren klickt. Möchte man die Strecke intensiver trainieren, kann man sie über Welt/Speichern unter einem selbst gewählten Dateinamen auf die Festplatte bannen.

Klickt man auf Welt/Generieren, ruft der Simulator die Methode generateParc() auf einem Objekt des Typs ParcoursGenerator auf. Diese lost für sechs Parameter zufällige Werte aus: Breite und Höhe der Rennstrecke sind ebenso variabel wie die Dichte der Hindernisse entlang der Außenwände (wallRoughness) und im Inneren des Labyrinths (innerRoughness). Der Verschnörkelungsfaktor twirling bestimmt, um viele Ecken sich Hindernisse schlängeln dürfen, perforation legt die Häufigkeit von Löchern fest.

Jeder Schritt des Irrgartenbaus ist in eine eigene private Methode ausgelagert. Für Schikanen sorgen roughenWalls() und generateFreeObstacles(). Der Generator bestimmt für Hindernisse zunächst eine zufällige Anfangskoordinate und die Richtung, generateTwirl() zieht anschließend eine Wand durch das Spielfeld. Die Methode bestimmt zufällig eine Wunschlänge für das nächste Segment und prüft anschließend feldweise, ob in der angepeilten Richtung genügend freier Platz vorhanden ist, um die Mauer zu verlängern. Verhindern andere Wände das weitere Wachstum in diese Richtung oder ist die Wunschlänge des Segments erreicht, ruft sich generateTwirl() mit einer zufälligen neuen Richtung rekursiv selbst auf - insgesamt so oft, wie der Wert des Verschnörkelungsfaktors twirling beträgt.

Die Methoden stellen dabei sicher, dass keine Durchgänge schmaler als zwei Felder gebaut werden und dass jedes Bodenfeld im Labyrinth erreichbar ist. Sind die Wände platziert, werden zufällig bestimmte Mauerteile durch Fallgruben ersetzt. Bis hier arbeitet der Generator nur auf der linken Hälfte des Labyrinths, die rechte fügt er durch einfache Spiegelung hinzu, um einen symmetrischen Parcours zu erhalten. Anschließend fügt er noch die Startfelder ein und verpackt das ganze in einen XML-String, mit dem der ParcoursLoader des c't-Sim zurechtkommt.

Zu Testzwecken besitzt die Klasse ParcoursGenerator noch eine eigene main()-Methode, die nacheinander zwanzig Labyrinthe erzeugt und über printParc() auf der Textkonsole ausgibt - der besseren Übersicht wegen ohne XML-Kapselung.