Masterarbeit

Transcription

Masterarbeit
Fachhochschule Köln
University of Applied Sciences
Fakultät 07
Informations-, Medien- und Elektrotechnik
Institut für Nachrichtentechnik
Studiengang Master of Science Technische Informatik
Masterarbeit
Spezifikation einer Robotic Task Definition Language
(RTDL)
Student:
Marcus Teske
Matrikelnummer:
1104 1133
Referent:
Prof. Dr. phil. Gregor Büchel
Koreferent:
Prof. Dr.-Ing. Georg Hartung
Abgabedatum:
17. Januar 2011
Hiermit versichere ich, dass ich die Masterarbeit selbständig angefertigt und keine anderen als die angegebenen und bei Zitaten kenntlich gemachten Quellen und
Hilfsmittel benutzt habe.
Marcus Teske
Inhaltsverzeichnis
1 Einleitung
2
2 Roboter
3
2.1
Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.2
Stationäre Roboter . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.3
Mobile Roboter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.3.1
Mobile ferngesteuerte Roboter . . . . . . . . . . . . . . . . . .
4
2.3.2
Mobile autonome Roboter . . . . . . . . . . . . . . . . . . . .
4
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.4.1
Sensoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.4.2
Aktoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
2.4.3
Kommunikationsgeräte . . . . . . . . . . . . . . . . . . . . . .
7
Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.4
2.5
3 Roboterplattformen
9
3.1
CokeRob . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2
Surveyor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.3
3.2.1
Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.2
Surveyor Architektur . . . . . . . . . . . . . . . . . . . . . . . 11
3.2.3
Capabilities des Surveyor Roboters (Services) . . . . . . . . . 13
RobotTI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4 JAUS
4.1
9
15
Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
i
4.2
JAUS Volume I: Domain Model . . . . . . . . . . . . . . . . . . . . . 16
4.3
JAUS Volume II: Reference Architecture . . . . . . . . . . . . . . . . 17
4.3.1
Architecture Framework . . . . . . . . . . . . . . . . . . . . . 17
4.3.2
Message Definition . . . . . . . . . . . . . . . . . . . . . . . . 18
4.3.3
Message Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3.4
Compliance Specification . . . . . . . . . . . . . . . . . . . . . 20
4.4
Surveyor als JAUS-System . . . . . . . . . . . . . . . . . . . . . . . . 22
4.5
Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5 Existierende Taskbeschreibungssprachen
27
5.1
PDDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2
Task Definition Language for Virtual Agents . . . . . . . . . . . . . . 30
5.2.1
Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2.2
Virtuelle Umgebung . . . . . . . . . . . . . . . . . . . . . . . 30
5.2.3
Die Task Definition Language . . . . . . . . . . . . . . . . . . 31
5.2.4
Aktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.2.5
Literals, Variablen und Funktionen . . . . . . . . . . . . . . . 33
5.2.6
Tasks definieren . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2.7
Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6 Robotic Task Definition Language
38
6.1
Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.2
Tasks und Anforderungen an die RTDL . . . . . . . . . . . . . . . . . 38
6.3
Taskzuweisung an Roboter . . . . . . . . . . . . . . . . . . . . . . . . 39
6.4
Aufbau von RTDL Taskbeschreibungen . . . . . . . . . . . . . . . . . 41
ii
6.5
Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
6.6
Definition der Robotic Task Definition Language . . . . . . . . . . . . 43
6.6.1
Funktionssyntax - Form . . . . . . . . . . . . . . . . . . . . . 43
6.6.2
Funktionssyntax - Aufbau . . . . . . . . . . . . . . . . . . . . 44
6.6.3
Funktionssyntax - Erweiterte Ausführungskonstrukte . . . . . 45
6.6.4
Funktionssyntax - Abfangen des Scheiterns einer Task . . . . . 46
6.7
Robotic Task Definition Language XML-Syntax . . . . . . . . . . . . 47
6.8
Beispiel für eine Task: fetchWater(Glass g, Tap t) . . . . . . . . . . . 52
7 Roboter Simulationsumgebung
55
7.1
Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.2
Simulationsumgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.3
7.2.1
Weltmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.2.2
Sensoren, Aktoren und Kommunikationsgeräte . . . . . . . . . 56
Implementierung der Simulationsumgebung . . . . . . . . . . . . . . . 57
7.3.1
WorldPosition . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
7.3.2
WorldObject . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
7.3.3
Wall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.3.4
Waypoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.3.5
Robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.3.6
WorldLocation . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.3.7
World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.3.8
RobotSim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
7.3.9
MyXmlParser . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
7.3.10 Main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
iii
7.4
7.5
Erweiterung der Simulationsumgebung . . . . . . . . . . . . . . . . . 66
7.4.1
DrinkingGlass . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
7.4.2
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
7.4.3
Tap
7.4.4
Robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
7.4.5
WorldObject . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
7.4.6
RobotSim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
7.4.7
Testen der Erweiterungen . . . . . . . . . . . . . . . . . . . . 70
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
RTDL Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.5.1
Klasse RtdlParser . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.5.2
Parsen einer Taskbeschreibung . . . . . . . . . . . . . . . . . . 72
8 Fazit
75
A Modellierungsansatz
76
A.1 Functional Capability (FC)
. . . . . . . . . . . . . . . . . . . . . . . 76
A.2 Informational Capability (IC) . . . . . . . . . . . . . . . . . . . . . . 78
A.3 Device Groups (DG) . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
A.4 Übersichtsgrafik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
B Liste ausgewählter JAUS-Komponenten
81
B.1 Command and Control Klasse . . . . . . . . . . . . . . . . . . . . . . 81
B.1.1 System Commander (ID 40) . . . . . . . . . . . . . . . . . . . 81
B.1.2 Subsystem Commander (ID 32) . . . . . . . . . . . . . . . . . 81
B.2 Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
B.2.1 Communicator (ID 35) . . . . . . . . . . . . . . . . . . . . . . 81
iv
B.3 Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
B.3.1 Global Pose Sensor (ID 38) . . . . . . . . . . . . . . . . . . . 82
B.3.2 Local Pose Sensor (ID 41) . . . . . . . . . . . . . . . . . . . . 82
B.3.3 Velocity State Sensor (ID 42) . . . . . . . . . . . . . . . . . . 82
B.3.4 Primitive Driver (ID 33) . . . . . . . . . . . . . . . . . . . . . 83
B.3.5 Reflexive Driver (ID 43) . . . . . . . . . . . . . . . . . . . . . 83
B.3.6 Global Vector Driver (ID 34)
. . . . . . . . . . . . . . . . . . 83
B.3.7 Local Vector Driver (ID 44) . . . . . . . . . . . . . . . . . . . 83
B.3.8 Global Waypoint Driver (ID 45) . . . . . . . . . . . . . . . . . 84
B.3.9 Local Waypoint Driver (ID 46) . . . . . . . . . . . . . . . . . 85
B.3.10 Global Path Segment Driver (ID 47) . . . . . . . . . . . . . . 85
B.3.11 Local Path Segment Driver (ID 38) . . . . . . . . . . . . . . . 85
B.4 Environment Sensor Components . . . . . . . . . . . . . . . . . . . . 85
B.4.1 Visual Sensor (ID 37) . . . . . . . . . . . . . . . . . . . . . . . 85
B.4.2 Range Sensor (ID 50) . . . . . . . . . . . . . . . . . . . . . . . 86
B.4.3 World Model Vector Knowledge Store (ID 61) . . . . . . . . . 86
B.5 Planning Components . . . . . . . . . . . . . . . . . . . . . . . . . . 87
B.5.1 Mission Planner (keine ID) . . . . . . . . . . . . . . . . . . . . 87
B.5.2 Mission Spooler (ID 36) . . . . . . . . . . . . . . . . . . . . . 87
C Liste ausgewählter JAUS-Nachrichten
88
C.1 Platform Subgroup Command Class (Code 0400-05FF) . . . . . . . . 88
C.2 Platform Subgroup Query Class (Code 2400-25FF) . . . . . . . . . . 88
C.3 Platform Subgroup Inform Class (Code 4400-45FF) . . . . . . . . . . 89
v
D Quelltexte
90
D.1 DrinkingGlass.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
D.2 Main.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
D.3 MyXmlparser.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
D.4 Robot.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
D.5 RobotSim.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
D.6 RtdlParser.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
D.7 Source.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
D.8 Tap.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
D.9 Wall.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
D.10 Waypoint.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
D.11 World.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
D.12 WorldLocation.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
D.13 WorldObject.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
D.14 WorldPosition.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
D.15 fetchWater.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
D.16 rtdl.xsl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
D.17 rtdl.dtd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
D.18 example.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
vi
Abbildungsverzeichnis
1
CokeRob - Quelle: [Cok10] . . . . . . . . . . . . . . . . . . . . . . . .
2
Surveyor - Quelle: [Erd09] . . . . . . . . . . . . . . . . . . . . . . . . 11
3
Surveyor Gesamtarchitektur . . . . . . . . . . . . . . . . . . . . . . . 12
4
JAUS Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5
JAUS Topologie - Quelle: [JAU07a] . . . . . . . . . . . . . . . . . . . 17
6
Einteilung von JAUS-Klassen nach Command Code - Quelle: [JAU07b] 19
7
Surveyor als JAUS-System . . . . . . . . . . . . . . . . . . . . . . . . 25
8
PDDL als Mindmap . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
9
RobotSim Weltmodell . . . . . . . . . . . . . . . . . . . . . . . . . . 56
10
RTDL Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
vii
9
Abstract
Roboter finden in der heutigen Zeit bereits in vielen Bereichen ihre Einsatzgebiete.
Zu diesen Bereichen gehören die Industrie, wo Roboter hauptsächlich für filigrane,
zu monotone oder gefährliche Arbeiten Anwendung finden. Ein weiterer wichtiger
Bereich ist die militärische Aufklärung und das Aufspüren von Personen in schwer
zugänglichen Gebieten, wie nach einer Umweltkatastrophe. All diese Roboter haben gemeinsam, dass sie bestimmte Aufgaben ausführen, für welche sie entwickelt
wurden.
Das Ziel dieser Arbeit ist die Definition einer allgemeinen Aufgaben-Beschreibungssprache, die nicht an einen einzelnen Roboter gebunden ist, sondern für alle möglichen Arten von Robotern einsetzbar ist. Dieses Ziel soll mit Hilfe der Robotic Task
Definition Language erreicht werden.
Die Robotic Task Definition Language (RTDL) ist eine Sprache, die an der Fachhochschule Köln im Rahmen des Instituts-übergreifenden Projektes “Verteilte Mobile Applikationen (VMA)” entwickelt wird. Die Aufgabe der RTDL besteht darin,
eine allgemein gültige Aufgabenbeschreibungssprache für unterschiedlichste Roboter zu definieren. Mit einer solchen Aufgabenbeschreibungssprache ist es möglich,
die Steuerungssoftware verschiedener Roboter in einer einheitlichen Sprache zu beschreiben und in einem weiteren Schritt auch umzusetzen.
1
Kapitel 1: Einleitung
1
Einleitung
Die Spezifikation einer Robotic Task Definition Language (RTDL) schafft eine Abstraktionsebene in der Steuerungssoftware von Robotern. Innerhalb dieser Ebene
werden Aufgaben (Tasks) in einer abstrakten Form als Hierarchie von primitiven
Roboteraktionen und untergeordneten Tasks beschrieben.
Die Motivation für die Spezifikation einer RTDL liegt in dem Wunsch nach der
Fähigkeit, Tasks unabhängig von einem bestimmten Roboter zu definierten. Erweitert man die Steuerungssoftware von verschiedenen Robotern um die Fähigkeit, eine
Taskdefinition die in der RTDL formuliert worden ist, zu interpretieren, so schafft
man eine Wiederverwendbarkeit von Taskdefinitionen, die es ermöglichen, definierte
Tasks von einem konkreten Roboter auf andere Roboter zu übertragen.
Im Rahmen dieser Arbeit wird eine Sprache für die Beschreibung von Robotertasks entwickelt. Hierzu werden zunächst existierende Sprachen zur Taskbeschreibung analysiert. Aus den Ergebnissen dieser Analyse wird eine neue Sprache erzeugt.
Zusätzlich wird eine einfache Simulationsumgebung für Roboter entwickelt, die unter
anderem als Testumgebung für die RTDL dient.
Diese Arbeit beginnt mit einigen Grundlagenkapiteln in denen das Umfeld dieserArbeit eingeführt wird. In Kapitel 2 dieser Arbeit werden zunächst Roboter von
einem allgemeinen Standpunkt aus betrachtet. Das darauf folgende Kapitel 3 liefert
eine Übersicht, über bereits existierende Roboter der Fakultät für Informations-,
Medien- und Elektrotechnik der Fachhochschule Köln, wo diese Arbeit entstanden
ist. In Kapitel 4 wird die Joint Architecture for Unmanned Systems (JAUS) eingeführt. Hierbei handelt es sich um einen Standard für die Beschreibung von Roboterarchitekturen.
Nachdem die Grundlagen für diese Arbeit in den ersten Kapiteln gelegt wurden,
wird ein Fokus auf Taskssprachen gelegt. In Kapitel 5 werden bereits existierende Sprachen zur Taskdefinition betrachtet. Diese Sprachen dienen als Grundlagen
für Kapitel 6, wo die RTDL beschrieben wird. In Kapitel 7 wird eine Simulationsumgebung für die beispielhafte Implementierung und Testmöglichkeit der RTDL
beschrieben. Zum Abschluss dieser Arbeit wird in Kapitel 8 ein Fazit gezogen.
2
Kapitel 2: Roboter
2
Roboter
2.1
Einleitung
Der Begriff Roboter stammt von dem tschechischen Schriftsteller Karl Čapek, der
diesen Begriff für sein 1921 erschienenes Bühnenstück “R.U.R. Rossum’s universal
robots” vom tschechischen Wort für Zwangsarbeit “robota” ableitete.
Da Roboter in teils sehr unterschiedlichen Bereichen eingesetzt werden, lassen sie
sich auch in mehrere Kategorien einteilen. Zu oberst können sie in stationäre und
mobile Roboter unterschieden werden.
2.2
Stationäre Roboter
Stationäre Roboter besitzen keine Möglichkeit, sich in ihrer Umgebung zu bewegen.
Zu stationären Robotern lassen sich beispielsweise Industrieroboter zählen. Einem
Industrieroboter werdenoftmalsWerkstückevorgesetzt,sei es manuell oderautomatisiert durch ein Förderband. Der Industrieroboter nutzt dann einen oder mehrere
mechanische Arme, an denen bestimmte Werkzeuge wie beispielsweise Schweißgeräte
oder Greifer befestigt sind, um das vor ihm liegende Werkstück zu bearbeiten.
Die wichtigsten Vorzüge eines stationären Roboters sind:
• Roboter ermüden nicht und liefern stets eine gleich bleibend hohe Qualität.
• Roboter können sehr präzise arbeiten, oftmals präziser als Menschen.
• Roboter können Tätigkeiten ausführen, die für Menschen zu gefährlich sind.
2.3
Mobile Roboter
Mobile Roboter besitzen die Fähigkeit, sich in ihrer Umgebung zu bewegen. Dieser
Umstand stellt einen mobilen Roboter jedoch vor weitere Herausforderungen: So
muss ein mobiler Roboter sich in seiner Umgebung orientieren können. Dies setzt
voraus dass er seine Umgebung über Sensoren erfassen und intern abbilden kann.
Des weiteren muss ein mobiler Roboter bei der Bewegung durch seine Umgebung auf
Hindernisse reagieren, das heißt diese erfassen, erkennen und ausweichen können.
3
Kapitel 2: Roboter
Bei mobilen Robotern ist eine weitere Unterteilung nach ferngesteuerten und autonomen Systemen sinnvoll.
2.3.1
Mobile ferngesteuerte Roboter
Ein mobiler ferngesteuerter Roboter besitzt die Fähigkeit, sich in seiner Umgebung
zu bewegen und, je nach Art der zusätzlich installierten Werkzeuge, diese auch manipulieren zu können. Wie der Name jedoch bereits vermuten lässt, wird ein solcher
Roboter dabei von einer entfernten Instanz über einen Kommunikationskanal ferngesteuert. Alle Entscheidungen werden von der entfernten Instanz getroffen, wobei es
sich in den häufigsten Fällen um einen Menschen mit einer Fernsteuerung handelt.
Diese Entscheidungen werden in Form von Anweisungen über den Kommunikationskanal an den Roboter übertragen, der diese Anweisungen dann als Aktionen
umsetzt.
Bei ferngesteuerten Robotern benötigt die entfernte Instanz wichtige Informationen
über die Umgebung, in welcher der ferngesteuerte Roboter eingesetzt wird. Es ist
häufig so, dass die entfernte InstanzVideodaten von am Roboter angebrachten Kameras verwendet, um die aktuelle Situation des ferngesteuerten Roboters erfassen
und Entscheidungen über weitere Aktionen treffen zu können.Alternativ kann sich
die entfernte Instanz an einer Position befinden, von der aus sie die relevanten Teile
der Umgebung des Roboters überblicken kann.
Ein Beispiel für einen mobilen ferngesteuerten Roboter findet man bei Firmen, die
Abwasserrohre sanieren. Hierbei wird ein kleiner fahrender Roboter mit einer Kamera in ein Kanalrohr abgelassen. Der Mitarbeiter, der den Roboter steuert, kann
mit Hilfe der Kamera an dem Roboter schadhafte Stellen in einem Abwasserrohr
aufspüren und gegebenenfalls reparieren.
2.3.2
Mobile autonome Roboter
Ein mobiler autonomer Roboter, auch mobiles autonomes System genannt, ist ein
Roboter, der in der Lage ist, selbstständig in seiner Umgebung zu navigieren und diese zu manipulieren. Er benötigt keine entfernte Instanz, welche ihn direkt fernsteuert. Auch wenn ein autonomer Roboter selbstständig agieren kann, ist es dennoch
oftmals sinnvoll einen Kommunikationskanal zu einer entfernten Instanz zu verwenden. Ein solcher Kommunikationskanal wird häufig verwendet um Informationen
4
Kapitel 2: Roboter
über bestimmte Situationen zu versenden. Des weiteren kann man auf diesem Wege
eine Art Failsafe bereitstellen, über welchen der Roboter in bestimmten kritischen
Situationen deaktiviert oder zwangsweise ferngesteuert werden kann.
Ein interessantes Einsatzgebiet für mobile autonome Roboter ist der kooperative
Einsatz mehrerer Roboter zur Erfüllung einer gemeinsamen Mission. Ein Beispiel für
kooperierende mobile autonome Systeme ist der RoboCup Wettbewerb [Rob11], bei
dem mehrere Roboter als Team gegen eine gegnerisches Roboter-Team ein Fußballspiel bestreiten. Das ehrgeizige Ziel dieses Wettbewerbs ist es, bis 2050 die Roboter
soweit zu entwickeln, dass diese in der Lage sind, den dann amtierenden Weltmeister
nach den gültigen Fußballregeln zu besiegen.
Innerhalb dieser Arbeit wird der Fokus auf mobile autonome Roboter gelegt, da
diese als einzige von einer Task-Beschreibungssprache profitieren.
2.4
Hardware
Zur Hardware eines Roboters zählen alle Komponenten, die physikalisch vorhanden
sind und dem Roboter zur Ausübung seiner Fähigkeiten dienen. Man unterscheidet
hierbei zwischen Sensoren, Aktoren und Kommunikationsgeräten.
2.4.1
Sensoren
Sensoren ermöglichen es einem Roboter, die Umwelt, in der er sich befindet, zu erfassen. Die Sensoren erzeugen entweder permanent oder auf Anfrage Sensordaten,
die auf dem Roboter weiterverarbeitetwerden müssen.Beider Verarbeitungder Sensordatenwerdenrelevante Informationen aus diesen Daten in eine symbolische Form
übersetzt, die einem internen Datenformat des Robotersentsprechen. DerRoboter
nutzt diese Informationen dann, um bestimmte Gegebenheiten seiner Umgebung
darstellen zu können und dienen der Planung von zukünftigen Aktionen oder als
Feedback zu aktuell durchgeführten Aktionen.
Reelle Sensoren sind fast immer fehlerbehaftet, was dazu führt, dass Entscheidungen,
die auf Basis solcher Daten getroffen werden, ebenfalls fehlerbehaftet oder gar völlig
falsch sind. Bei reellen Robotern gehören diese Aspekte zum Umgang mit unsicherem
Wissen. Hierzu gehört sowohl die Einschätzung der Abweichung von Sensordaten
zum tatsächlichen Ereignis als auch die Wahrscheinlichkeit, dass ein Sensorwert
5
Kapitel 2: Roboter
gänzlich verfälscht ist. Aus diesem Grund werden Entscheidungen eines Roboters
oftmals nicht allein auf Basis eines einzigen Sensorwertes getroffen. Statt dessen
werden mehrere Sensorwerte von unterschiedlichen Sensoren ausgewertet und deren
Informationen zusammengefasst. Diesen Vorgang nennt man Merging (nach dem
englischen Wort für zusammenfassen: to merge sth.). Auf diese Art lassen sich Fehler,
die in bestimmten Situationen bei bestimmten Sensoren auftreten, kompensieren.
Üblicherweise verändern Sensoren die Umgebung des Roboters nicht, sondern dienen
lediglich der Erfassung von Daten.
Im folgenden ist eine Liste von ausgewählten Sensoren und der Art ihrer erfassten
Daten dargestellt:
• Ein Kompass kann die aktuelle Orientierung des Roboters anhand des magnetischen Nordpols der Erde bestimmen.
• Ein Ultraschallsensor kann das Vorhandensein und gegebenenfalls den Abstand eines Objektes in der Nähe des Roboters ermitteln.
• Ein Radenkoder kann die über Rollen oder Raupen zurückgelegte Strecke
des Roboters über die Anzahl der Radumdrehungen ermitteln.
• Ein RFID-Reader kann RFID-Tags in seiner unmittelbaren Umgebung auslesen, auf deren Basis die aktuelle Position des Roboters ermittelt werden
kann.
• Eine Kamera kann Umgebungsbilder erfassen, auf deren Basis eine Positionsbestimmung und Hinderniserkennung möglich ist.
• Ein auf den Boden gerichteter optischer Mousesensor kann die zurückgelegte Strecke eines Roboters ermitteln.
• Ein GPS-Empfänger kann durch Triangulation von Signalen mehrerer GPSSatelliten zur Positionsbestimmung genutzt werden.
2.4.2
Aktoren
Aktoren sind Hardware-Geräte, die es dem Roboter ermöglichen sich in seiner Umgebung fort zu bewegen oder Objekte in der Umgebung zu manipulieren. Oftmals
werden Aktoren unter sensorischer Überwachung betrieben, damit der Roboter eine
Rückmeldung über die Manipulation durch die Aktoren erhält.
6
Kapitel 2: Roboter
• Fortbewegungsaktoren: Hierunter fallen alle Aktoren, die es dem Roboter ermöglichen seine Position und Ausrichtung zu verändern. In den meisten
Fällen handelt es sich hierbei um Räder oder Raupenketten zur Fortbewegung
auf dem Boden, Schrauben für die Fortbewegung auf oder unter dem Wasser
und Propeller oder Düsen für die Bewegung in der Luft.
• Objektmanipulatoren: Unter diesen Begriff fallen alle Aktoren die Objekte in der Umgebung manipulieren können. Diese Aktoren können vielfältiger
Natur sein: Beispielsweise gibt es Greifarme, die Objekte greifen, verdrehen,
ziehen, drücken und quetschen können. Aber auch Werkzeuge wie Nietenpistolen oder Schweißgeräte sind denkbar. Diese sind oftmals an einen beweglichen
Arm gekoppelt. Beim RoboCup dienen beispielsweise die Beine der Roboter,
welche primär für die Fortbewegung gedacht sind, zusätzlich als Abschusseinrichtung für den Fußball.
2.4.3
Kommunikationsgeräte
Wie bei der Vorstellung der unterschiedlichen Roboterarten bereits angeführt, besitzen Roboter oftmals einen Kommunikationskanal zu einer entfernten Instanz. Auf
welche Art und Weise dieser Kanal zustande kommt ist hierbei abhängig von der
verwendeten Technologie, die für die Kommunikation eingesetzt wird. Eine solche
Technologie ist beispielsweise WLAN. WLAN steht für Wireless Local Area Network
und ist in den IEEE Drafts 802.11 standardisiert. Auf WLAN wird dann häufig das
IP-Protokoll (Internet Protocol) und das TCP- (Transmission Control Protocol)
oder UDP-Protokoll (User Datagram Protokoll) verwendet, um die Daten vom Roboter zur entfernten Instanz und zurück zu übertragen. Es sind jedoch auch andere
Technologien, wie zum Beispiel proprietäre (nicht-standardisierte) Funkgeräte, zur
Realisierung eines Kommunikationskanal denkbar.
2.5
Software
Neben der Hardware spielt auch die Software bei einem Roboter eine entscheidende
Rolle. Bei einem Roboter ist die Software ähnlich aufgebaut wie bei einem PC.
1. Auf der untersten Ebene befindet sich die Hardware.
2. Auf der Hardware läuft ein Betriebssystem
7
Kapitel 2: Roboter
(a) Der zentrale Teil eines Betriebssystems ist der Betriebssystemkern, auch
Kernel genannt.
(b) An den Kernel angebunden sind auf der untersten Ebene die Treiber,
welche einen Zugriff auf die Hardware ermöglichen.
(c) Auf der obersten Ebene des Betriebssystems befindet sich ein API (Application Programming Interface), mit dessen Hilfe Systemtools und Anwendungsprogramme mit dem Betriebssystem interagieren können.
3. Die Systemtools dienen der Verwaltung des Betriebssystems.
4. Anwendungsprogramme bilden dann die eigentlichen Dienste aus, die ein Roboter erbringen soll.
Abbildung 3 auf Seite 12 verdeutlicht den Zusammenhang von Hardware und Software nochmals an Hand des Roboters Surveyor.
Ein entscheidendes Anwendungsprogramm bei einem Roboter ist die Steuerungssoftware. Bei einem mobilen autonomen System legt sie die Fähigkeiten und das
Verhalten des Roboters fest.
Die Steuerungssoftware nutzt die Daten der Sensoren um die Aktoren zur steuern.
Des weiteren kann sie unter Verwendung der Kommunikationsgeräte mit anderen
Robotern und Systemen in der Umgebung kommunizieren. All dies dient dem Roboter als Grundlage um bestimmte Aufgaben selbstständig erfüllen zu können. Oftmals sind die Fähigkeiten eines Roboters, also dessen Funktionalitäten, in Form von
Funktionsaufrufen in der Steuerungssoftware implementiert.
8
Kapitel 3: Roboterplattformen
3
3.1
Roboterplattformen
CokeRob
Der CokeRob [Cok10] gehört zur Kategorie der stationären Roboter. Er besteht aus
einer Tisch-großen Fläche, die von einer externen Kamera überwacht wird, einem
Steuerungsrechner und einem aus Lego-Steinen aufgebauten mobilen Roboter. Der
mobile Roboter kann sich lediglich auf der kleinen Fläche frei und autonom bewegen und da die Fläche ihrerseits nicht mobil ist, ist das Gesamtsystem des CokeRobs
eher als stationärer Roboter zu betrachten. Der einzige Sensor des CokeRob ist die
Kamera. Die Daten der Kamera werden in dem externen Steuerungsrechner mit Bilderkennungssoftware ausgewertet und per drahtloser Kommunikationsschnittstelle
an den mobilen Roboter gesendet.
Legt man nun eine Münze auf diese Fläche, erkennt der CokeRob diese und positioniert seinen Greifarm darüber. Dann lässt er den Arm herab und schiebt die Münze
an eine definierte Position. Dort wird die Münze von der Kamera erfasst und identifiziert. Dann schiebt der CokeRob die Münze in einen Kassenbereich. Im nächsten
Schritt betätigt der CokeRob einen Schalter, der eine Dose Cola freigibt.
Abbildung 1: CokeRob - Quelle: [Cok10]
9
Kapitel 3: Roboterplattformen
3.2
Surveyor
3.2.1
Übersicht
Der Surveyor ist derzeit die meist genutzte Entwicklungsplattform innerhalb der Fakultät 07 der FH Köln. Es handelt sich dabei um einen autonomen mobilen Roboter,
dessen primäres Ziel die Wegfindung in einer Flurwelt ist. Der Aufbau des Surveyors
wird im folgenden stichpunktartig beschrieben:
• Die zentrale Datenverarbeitungseinheit ist ein Blackfin Board.
• Aktoren
– Zwei differential angesteuerte Räder vorne und zwei nachlaufende Räder
hinten, verbunden durch eine Gummikette.
• Sensoren
– RFID-Reader für die Erkennung der auf dem Boden verklebten RFIDTags als Positionsmarker.
– Kompass für die Bestimmung der Ausrichtung der Plattform.
– Ultraschallsensor für die Hinderniserkennung und Kollisionsvermeidung.
– Laseremitter gekoppelt mit einer Kamera zur Abstandsmessung.
• Kommunikationsschnittstellen
– Zwei serielle Schnittstellen, wobei eine davon an einen WLAN-Adapter
gekoppelt ist, wodurch eine drahtlose serielle Kommunikation ermöglicht
wird.
Wie bereits in Kapitel 2.4.1 erwähnt, sind Sensoren oftmals fehlerbehaftet. Beim
Surveyor führt das zu den folgenden Problemen:
• Der Surveyor kann seine Position nicht immer genau bestimmen, da er lediglich
weiß, welches RFID-Tag er als letztes gelesen hat. Es kann also nur vermutet
werden dass der Surveyor sich nahe des zuletzt gelesenen Tags befindet. Dieser
Fehler ist nicht direkt auf einen Sensorenfehler zurückzuführen sondern ist
durch das Design der Positionsbestimmung mit Hilfe von RFID-Tags bedingt.
10
Kapitel 3: Roboterplattformen
• Der Kompass liefert eine maximale Genauigkeit von 1/10 Grad, jedoch wird
der Messwert durch Stahlträger und andere metallische Körper in seiner Umgebung stark verfälscht. Dies führt dazu dass der Kompass in einigen Regionen
die Ausrichtung sehr gut und anderen sehr unzuverlässig ermittelt.
• Dem Ultraschallsensor ist derzeit nicht im Einsatz. Deswegen liegen derzeit
noch keine Erkenntnisse über mögliche Fehlerquellen vor.
Abbildung 2: Surveyor - Quelle: [Erd09]
3.2.2
Surveyor Architektur
Die Surveyor Architektur besteht im Groben aus zwei Bestandteilen. Der erste Bestandteil ist der Surveyor Roboter bestehend aus der Hardware, wie sie in Kapitel
3.2.1 beschrieben ist, und der Steuerungssoftware. Als Betriebssystem wird uClinux
verwendet, eine Linuxvariante für eingebettete Systeme. Die gesamte Software ist
auf einem Flash-Speicher abgelegt. Innerhalb des uClinux existieren Treiber für die
Zugriffe auf die Hardwaregeräte. Des weiteren bietet das Betriebssystem eine Eingabeaufforderung, die sogenannte Shell an, mit welcher über eine entfernte TelnetVerbindung Kommandos auf dem Surveyor Roboter ausgeführt werden können. Auf
dieser Shell laufen eine Reihe von Programmen, die vordefinierte Aktionen auf dem
Roboter ausführen. Diese Programme sind vergleichbar mit vordefinierten Tasks,
11
Kapitel 3: Roboterplattformen
die intern aus Funktionsaufrufen bestehen, die ihrerseits Kommandos über die Treiber an die Hardware absetzen. Der Surveyor besitzt unter anderem zwei serielle
Schnittstellen, von der eine an einen WLAN-Adapter angeschlossen ist.
Die zweite Komponente ist der sogenannte Proxy. Der Proxy ist ein normaler PC
der über eine WLAN-Schnittstelle mit dem Surveyor Roboter kommuniziert. Auf
dem Proxy befindet sich zum einen die Entwicklungsumgebung für den Surveyor,
mit dessen Hilfe ein verändertes uClinux-Image erzeugt und in den Flash-Speicher
vom Surveyor geschrieben werden kann.
Abbildung 3: Surveyor Gesamtarchitektur
Zum anderen besteht der Proxy aus dem sogenannten Benutzer-PC. Der BenutzerPC bietet eine Schnittstelle an, um auf dem Surveyor über den Kommunikationskanal eine Task auszuführen. Eine solche Task ist zum Beispiel das Anfahren eines
bestimmten RFID-Tags auf einer Teststrecke. Der Benutzer-PC ist zudem an eine
Flurwelt-Datenbank angeschlossen. In dieser Datenbank befinden sich die Positionsinformationen der verklebten RFID-Tags. Über den Kommunikationskanal erhält
der Surveyor Zugriff auf diese Datenbank und ist in der Lage auf Basis dieser Daten
einen Pfad von einem Start zu einem Endpunkt zu erzeugen und diesem zu folgen.
12
Kapitel 3: Roboterplattformen
3.2.3
Capabilities des Surveyor Roboters (Services)
Im folgenden werden die wichtigsten Fähigkeiten (Capabilities, siehe Kapitel 6.5) des
Surveyor Roboters aufgelistet, die durch die Kombination von Steuerungssoftware,
Sensoren und Aktoren in Form von Funktionsaufrufen bereit gestellt werden.
Motorsteuerung (Aktoren zur Fortbewegung) Der Surveyor ist in der Lage
sich auf einer ebenen Fläche fahrend fort zu bewegen. Hierzu sind die folgenden
Funktionen implementiert:
• Geradeausfahrt:
motor forward();
• anhalten:
motor stop();
• nach rechts drehen (90◦ ):
motor turnright();
• nach links drehen (90◦ ):
motor turnleft();
• beliebig drehen:
motor turn(int direction);
RFID-Funktionen (Sensoren zur Positionsbestimmung)) Einen Großteil der
Navigation erreicht der Surveyor durch das Auslesen von RFID-Tags, die auf dem
Boden der Teststrecke verklebt sein müssen. RFID-Tags (Radio Frequency Identification) sind passive Transponder, die, wenn sie durch die Radiowellen eines RFIDLesegeräts angeregt werden, eine Information aussenden, die dann von dem Lesegerät ausgelesen werden kann. Der Surveyor besitzt ein solches Lesegerät und stellt
die folgenden Funktionen zum Umgang mit RFID-Tags zur Verfügung:
• Tag auswählen:
rfid selecttag();
• bei Tag authentifizieren:
rfid authenticate();
• Tag-Block 1 auslesen:
rfid readblock1();
• Tag auslesen:
rfid gettag();
• Block x in Tag t beschreiben:
rfid writeblock(int x, rfidtag t);
Kompass-Funktionen (Sensor zur Bestimmung der Ausrichtung) Der zweite wichtige Bestandteil der Navigationsfähigkeit des Surveyors, wird durch einen
13
Kapitel 3: Roboterplattformen
Kompass erbracht. Der Kompass erlaubt es dem Surveyor seine Ausrichtung in Bezug auf eine bekannte Umgebung zu ermitteln. Der Surveyor unterstützt die folgenden Funktionen im Umgang mit dem Kompass:
• auf eine bestimmte Gradzahl drehen: fahren drehenzu(int gradzahl);
• um eine bestimmte Gradzahl drehen: fahren drehenum(int gradzahl);
Höhere Funktionen Der Surveyor verknüpft einige seiner Basis-Fähigkeiten und
bietet diese gekapselt als eine höhere Funktion an. So bildet eine Kombination aus
RFID-, Kompass- und Fahr-Funktionen gekoppelt mit einem Modell der Umgebung
in Form einer Datenbank die Grundlage für autonome Fahrten innerhalb der Umgebung. Durch die Ermittlung der aktuellen Position durch ein gelesenes RFID-Tag
und der Ausrichtung durch den Kompass, kann mit Hilfe des Umgebungsmodell
in der Datenbank ein Vektor zu einem Ziel-Tag ermittelt werden. Dieser Vektor
wird dann mit Hilfe der Fahrfunktionen abgefahren. Während dieser Fahrt ist es
wahrscheinlich, dass der Surveyor andere RFID-Tags passiert. In dem Fall liest er
die Tags aus und prüft, ob sie mit dem berechneten Vektor der autonomen Fahrt
übereinstimmen und korrigiert seinen Kurs gegebenenfalls automatisch. Die autonome Fahrt kann durch Aufruf der folgenden Funktion gestartet werden:
• autonome Fahrt zu einer Koordinate: fahren drivetoxy(int x, int y);
3.3
RobotTI
Man kann den RobotTI als den großen Bruder des Surveyor bezeichnen. Er ist durch
seine Dimensionen in der Lage, ein Notebook als lokalen Verarbeitungsrechner an
Bord zu transportieren. Hierdurch kann der RobotTI auf ein enormes Datenverarbeitungspotential zurückgreifen, wie sie höher integrierte Roboterplattformen wie
der Surveyor nicht besitzen.
Ähnlich verhält es sich mit dem Aspekt der Software. Dadurch dass der RobotTI
gebräuchliche PC- bzw. -Notebook-Hardware verwendet, können auch unmodifizierte gebräuchliche Betriebssysteme für den lokalen Verarbeitungsrechner verwendet
werden.
14
Kapitel 4: JAUS
4
JAUS
4.1
Einführung
Die Joint Architecture for Unmanned Systems (JAUS) war ein offener Standard
der JAUS Working Group (WG), der eine gemeinsame Architektur für unbemannte
Systeme definierte. Die letzte veröffentlichte Version des JAUS Standards datiert auf
den 27.06.2007. Danach wurde die JAUS WG in die Society of Automotive Engineers
(SAE) eingegliedert und die Arbeit in nicht-öffentlicher Form fortgesetzt.
Trotz dieser Entwicklung von JAUS liefern die alten Version dieses Standards sehr
interessante Ansätze zum Entwurf und zur Beschreibung von unbemannten System beliebiger Art. Der Begriff “unbemanntes System” oder “unmanned System”,
wie er im Original heißt, umfasst im Grunde das gleiche, wie der Begriff des mobilen autonomen Systems, wie er in Kapitel 2.3.2 eingeführt worden ist. JAUS legt
dabei jedoch einen großen Fokus auf die Architektur eines solchen unbemannten
Systems und weniger auf dessen Einsatzgebiet oder Verhalten. Dieser Fokus ist bei
JAUS jedoch gewollt, da sich der Standard auf eine möglichst große Bandbreite von
unbemannten Systemen beziehen will und in keiner Weise Voraussetzungen oder
Einschränkungen auf die Bereiche Einsatzgebiet und Verhalten auferlegen möchte.
Der JAUS-Standard besteht aus mehreren Dokumenten, die sich mit jeweils unterschiedlichen Aspekten des Standards befassen:
• JAUS Volume I: Domain Model v3.2 [JAU05]
• JAUS Volume II Part 1-3: Reference Architecture v3.3 [JAU07a], [JAU07b]
und [JAU07a]
• JAUS Compliance Specification v1.1 [JAU06]
[Tes10] liefert eine ins Deutsche übersetzte Zusammenfassung des JAUS Standards,
doch für eine ausführliche Betrachtung der Details sei auf die direkten Quellen
zurückzugreifen.
Abbildung 4 zeigt den JAUS-Standard in einer Übersichtsgrafik. Für Details hierzu
sei auf die folgenden Unterkapitel verwiesen.
15
Kapitel 4: JAUS
Abbildung 4: JAUS Übersicht
4.2
JAUS Volume I: Domain Model
Das Domain Model von JAUS [JAU05] vermittelt die generelle Idee, die sich hinter
JAUS versteckt: Die Standardisierung einer Architektur für beliebige unbemannte Systeme, die zwar bestimmte Aspekte dringend vorschreibt, aber dennoch die
Einsetzbarkeit des Standards in keiner Weise beschränkt.
Als erstes werden Anforderungen an die Architektur spezifiziert und mit einigen
ausgewählten bereits bestehenden Standards verglichen. Im Verlauf dieses Vergleichs
werden die Schwachstellen der anderen Standards aufgedeckt und in JAUS berücksichtigt. Als Ergebnis dieser Spezifikation werden die folgenden Stützpfeiler von
JAUS festgehalten:
1. JAUS ist einsetzbar für alle Arten von Robotern und Fahrzeugplattformen.
2. JAUS erzeugt keine Beschränkungen für die Missionen, die ein unbemanntes
System ausführen kann.
3. JAUS ist unabhängig von bestimmten Computer Ressourcen.
4. JAUS ist unabhängig von bestimmten eingesetzten Technologien.
5. JAUS erzeugt keine Einschränkungen für den Anwender bzw. Bediener eines
unbemannten Systems.
16
Kapitel 4: JAUS
Im JAUS Domain Model werden im Bereich des Modellierungsansatzes zusätzlich
eine Reihe von Fähigkeiten (Capabilities) definiert, über die ein unbemanntes System
verfügen kann. Diese Fähigkeiten sind sehr ausführlich spezifiziert. Eine Übersicht
über diese Fähigkeiten findet sich in Anhang A.
4.3
JAUS Volume II: Reference Architecture
Die Referenzarchitektur von JAUS besteht aus drei Teilen:
• Part 1: Architecture Framework
• Part 2: Message Definition
• Part 3: Message Set
4.3.1
Architecture Framework
Der erste Teil, das Architecture Framework [JAU07a] stellt eine technische Spezifikation dar, nach welcher ein JAUS-konformes System entworfen und entwickelt
werden sollte. Hierzu gehört die Einführung einer Topologie, die zwischen verschiedenen JAUS-Elementen besteht. Diese Topologie ist in der folgenden Grafik dargestellt
und in den folgenden Unterkapiteln etwas näher beschrieben.
Abbildung 5: JAUS Topologie - Quelle: [JAU07a]
JAUS-Component
Die JAUS-Component oder JAUS-Komponente stellt das
kleinste Element bei JAUS dar. Komponenten sind definiert als eine Einheit, die
eine Menge an Operationen mit einer logischen Gruppierung innerhalb des gegebenen Kontextes ausführen.
Ein wichtiges Merkmal einer JAUS-Komponente ist, dass Informationen zwischen
ihnen lediglich über definierte JAUS- Nachrichten ausgetauscht werden dürfen.
17
Kapitel 4: JAUS
Die Kommunikation zu einer Komponente, die nicht in JAUS definiert ist, darf über
beliebige Nachrichten erfolgen.
Jede JAUS-Komponente besitzt eine Komponenten Schnittstelle (component interface), die als die Menge aller gültigen JAUS-Nachrichten dieser Komponente definiert ist.
Im Architecture Framework sind bereits viele JAUS-Komponenten für bestimmte
Aufgaben vordefiniert. Für eine ausführliche Liste sei auf [JAU07a] verwiesen.
Eine Liste von ausgewählten JAUS-Komponenten, die bei der Beschreibung der
meisten unbemannten Systeme vorhanden sind, befindet sich im Anhang B.
Node Eine Node ist definiert als eine Komposition aus allen Hardwaregeräten
und Softwarekomponenten, die für eine oder mehrere wohldefinierte Verarbeitungsfähigkeiten benötigt werden. Es ist möglich, Nodes als Hardware Blackboxen zu
betrachten, auf denen die benötigten Komponenten laufen.
Subsystem Ein Subsystem in JAUS ist eine unabhängige und unterscheidbare
Einheit, die aus einer Menge von Komponenten besteht die auf einer oder mehreren
Nodes laufen, um eine oder mehrere spezifizierte Aufgaben zu erfüllen.
System Ein System in JAUS ist eine Gruppierung von einem oder mehreren Subsystemen. Ein System wird häufig aus Subsystemen gewählt, bei denen die Kooperation
untereinander einen Vorteil erbringt.
4.3.2
Message Definition
Der zweite Teil der Referenzarchitektur, die Message Definition [JAU07b] oder Nachrichten Definition, legt das JAUS- spezifische Protokoll für die Übermittlung von
JAUS-Nachrichten fest.
Die Nachrichten Definition beschreibt den Aufbau der Nachrichtenheader der einzelnen definierten JAUS-Nachrichten und die Festlegungen, die für einzelne Felder
im Nachrichtenheader gelten.
JAUS-Nachrichten sind einer der wichtigsten Bestandteile von JAUS, denn sie sorgen
für einen wohl-definierten Nachrichtenaustausch zwischen JAUS-Komponenten und
werden für das Auslösen von Aktionen und Ereignissen verwendet.
18
Kapitel 4: JAUS
In JAUS werden Nachrichten in Nachrichtenklassen eingeteilt. Die Verwendung von
Nachrichtenklassen dient der Ordnung von Nachrichten. Die Nachrichtenklassen werden durch den Command Code, also dem Typ einer Nachricht, spezifiziert und lauten
wie folgt:
Message Class
Offset Range (0000h to FFFFh)
Command
0000h – 1FFFh
Query
2000h – 3FFFh
Inform
4000h – 5FFFh
Event Setup
6000h – 7FFFh (Deprecate v4.0)
Event Notification
8000h – 9FFFh (Deprecate v4.0)
Node Management
A000h – BFFFh
Reserved
C000h – CFFFh
Experimental Message
D000h – FFFFh
Abbildung 6: Einteilung von JAUS-Klassen nach Command Code - Quelle: [JAU07b]
1. Command Class Messages werden verwendet, um den Systemmodus zu
verändern, zur Bestätigungskontrolle, um den Status einer Komponente oder
eines Subsystems zu verändern oder um eine Aktion zu starten.
2. Query Class Messages werden verwendet, um Informationen von anderen
Komponenten einzuholen.
3. Inform Class Messages sind das Gegenstück zu Query Class Messages. Sie
erlauben es Komponenten, Daten wie z.B. Statusberichte, geographische Positionen und weitere Arten von Informationen untereinander auszutauschen.
4. Event Setup Class Messages werden verwendet, um die Parameter für eine
Event Notification Nachricht vorzubereiten und um eine andere Komponente
zu veranlassen auf ein Triggerevent zu warten. Eine Event Notice Nachricht
wird immer dann erzeugt, wenn Parameter in einer Event Setup Nachricht
gesetzt werden. Diese Nachrichtenklasse sollte ab JAUS v4.0 wegfallen.
5. Event Notification Class Messages kommunizieren das Auftreten eines
Ereignisses wie z.B. Motorüberhitzung, Ölüberdruck usw. Diese Nachrichtenklasse sollte ab JAUS v4.0 wegfallen.
19
Kapitel 4: JAUS
6. Node Management Class Messages werden nur von der Node Management Task verwendet. Diese Nachrichten werden für die Node-spezifische Kommunikation wie das Durchschleifen von Konfigurationsinformationen und die
Komponentenregistrierung verwendet.
7. Experimental Class Messages werden als Grundlage für die Experimentierung mit neuen Nachrichten, die noch nicht in der JAUS Reference Architecture definiert sind, verwendet. Die Idee dabei ist, dass experimentelle
Nachrichten in einer späteren Version der JAUS Reference Architecture in
diese einfließen. Wenn eine Experimental Class Message in die JAUS Reference Architecture einfließt, wird ihr ein Command Code von den anderen
Standardklassen zugewiesen. Die Anzahl dieser experimentellen Nachrichten
sollen zwecks einer guten Interoperabilität möglichst gering gehalten werden.
Weitere Information zur Message Definition von JAUS befinden sich in [Tes10] und
[JAU07b].
4.3.3
Message Set
Das Message Set von JAUS [JAU07c] beschreibt alle in JAUS definierten Nachrichten inklusive ihres Inhaltes. Der Fokus liegt dabei auf den Domänen-spezifischen
Semantiken des Nachrichtenaustauschs.
Da die Menge, der in JAUS definierten Nachrichten bereits sehr groß ist, wird hier auf
eine ausführliche Beschreibung aller Nachrichten verzichtet. Im Anhang C befindet
sich eine Menge ausgewählter JAUS-Nachrichten. Für eine vollständige Beschreibung aller JAUS-Nachrichten sei auf [JAU07c] verwiesen.
4.3.4
Compliance Specification
Über die JAUS Compliance Specification [JAU06] kann mit Hilfe der Domain Model Spezifikation und der Referenzarchitektur bestimmt werden, ob ein System die
Voraussetzungen von JAUS in so weit erfüllt, dass das System als JAUS-konform
bezeichnet werden kann.
Die JAUS Compliance ist definiert als die Verifikation, dass der Nachrichtenverkehr zwischen JAUS-Komponenten der Reference Architecture Spezifikation ent-
20
Kapitel 4: JAUS
spricht. JAUS ist eine nachrichtenbasierte Architektur, welche sich für eine Konformitätsprüfung besonders gut eignet. Es gibt drei Konformitäts-Ebenen, in denen
Elemente geprüft werden können. Diese Ebenen lauten wie folgt:
• Level I: Inter-Subsystem Compliance
• Level II: Inter-Nodal Compliance
• Level III: Inter-Component Compliance
Die Erfüllung der JAUS Compliance auf einer der Ebenen ist unabhängig von der
Compliance der anderen Ebenen und liefert diesbezüglich auch keinen Rückschluss
auf deren Status.
Die JAUS Compliance unterscheidet zudem zwischen der Standards Compliance
und der Applications Compliance. Der Unterschied zwischen diesen beiden Arten
der Konformität ist, dass bei der Standards Compliance nur die im JAUS Standard
definierten Nachrichten betrachtet werden, während bei der Applications Appliance
auch benutzerdefinierte Nachrichten (user defined messages) herangezogen werden,
die entweder die Anforderungen des JAUS Standards erweitern oder aber mit diesen
in Konflikt stehen. Hierbei muss ein Element die folgenden Regeln einhalten:
1. Alle unterstützten eingehenden und ausgehenden Nachrichten des betreffenden
Elements sind explizit aufgelistet.
2. Alle unterstützten ausgehenden Nachrichten dieses Elements geben ausdrücklich die Version der Referenzarchitektur an.
3. Alle unterstützten ausgehenden Nachrichten befolgen die JAUS Konventionen,
Definitionen, Formate und Regeln für Nachrichten, so wie sie in der Referenzarchitektur definiert sind.
4. Alle festgelegten Toleranzen für Timing und Latenz werden eingehalten.
5. Alle unterstützten Inform-Nachrichten sollen auf die entsprechenden QueryNachrichten antworten.
6. Alle unterstützten Event Notification Nachrichten sollen auf die entsprechenden Event Setup Nachrichten antworten.
7. Eine benutzerdefinierte Nachricht darf keine in JAUS definierte Nachricht umgehen oder duplizieren.
21
Kapitel 4: JAUS
4.4
Surveyor als JAUS-System
Da der JAUS Standard gut geeignet ist, um die Architektur eines unbemannten Systems zu beschreiben und es sich bei dem Roboter Surveyor der Fachhochschule Köln
um ein unbemanntes System handelt, wurde versucht dieses System mit Elementen
aus JAUS zu beschreiben.
Ein Ansatz um den Surveyor mit Elementen aus JAUS zu beschreiben, ist dass
man der Topologie von JAUS, wie in Kapitel 4.3.1 beschrieben folgt und dann die
einzelnen Ebenen der Topologie denjenigen Elementen des Surveyors zuweist, die
am besten auf die Definition der einzelnen Ebenen passen.
Auf der obersten Ebene hat man dann das System Surveyor, welches sich aus den
beiden Subsystemen Surveyor und OCU zusammensetzt, die durch das Subsystem
Network verbunden sind. Das Subsystem Network entspricht beim Surveyor dann
dem WLAN Netzwerk, das der Roboter und der Proxy zur Kommunikation nutzen.
Das Subsystem Surveyor bildet hierbei den Roboter Surveyor selbst ab. Es besteht
aus der Node Blackfin, die dem Blackfin Mainboard des Surveyors und der daran
angeschlossenen Sensoren und Aktoren entspricht. Da der Surveyor Roboter nur aus
dieser einen Node besteht, entfällt auch die Notwendigkeit eines Node Networks.
Das Subsystem OCU entspricht dem Proxy des Surveyors. Das Kürzel OCU steht für
Operator Control Unit und bezeichnet in JAUS ein Element, dass ein unbemanntes
System mit steuert. Steuern bedeutet in diesem Zusammenhang allerdings nicht
fernsteuern, sondern eher, dass das unbemannte System Missionen, der JAUS-Begriff
für Tasks, zugewiesen bekommt. Das Subsystem OCU besteht aus den beiden Nodes
Bedien-PC und Entwickler-PC, die durch ein Node-Network miteinander verbunden
sind.
Auf der Node-Ebene sind nun drei verschiedene Nodes identifiziert worden:
1. Das Blackfin-Board mit den angeschlossenen Sensoren und Aktoren,
2. der Bedien-PC
3. und der Entwickler-PC.
Innerhalb jeder dieser Nodes befinden sich die beiden Pflichtkomponenten Communicator und Node Manager.
22
Kapitel 4: JAUS
Die Komponente Communicator bildet den Zugangspunkt zum Subsystem Network.
Im Falle des Surveyor Roboters ist dies die Wireless LAN Schnittstelle mit welcher
der Roboter mit dem Proxy kommuniziert. Die Communicator der beiden anderen
Nodes sind entweder auch Wireless LAN Schnittstellen oder aber kabelgebundene
Schnittstellen zu einem Wireless LAN Access Point. Für JAUS sind beide Alternativen gleichwertig, da die konkrete Implementierung des Subsystem Networks in
JAUS nicht abgebildet wird.
Die andere Komponente ist der Node Manager. Der Node Manager dient den Nodes
als Kommunikationsschnittstelle innerhalb eines Subsystems, dem Node Network.
Im Falle des Surveyor Subsystems gibt es nur eine Node, weswegen das Node Network
nicht verwendet wird. Im Falle der beiden Nodes im OCU Subsystem, ist das NodeNetwork physikalisch das selbe wie das Subsystem Network. JAUS unterscheidet
diese beiden Netzwerke jedoch logisch voneinander, weswegen sie hier beide erwähnt
werden.
Innerhalb der Node Blackfin gibt es nun mehrere Komponenten, die für die Umsetzung der Fähigkeiten des Surveyors zuständig sind:
Die Komponente System Commander, die auch auf der Node Bedien-PC vorhanden ist, bildet die Befehlsquelle des Systems. Beim Surveyor wird über eine Benutzerschnittstelle ein Wegpunkt angegeben und das System fährt autonom zu diesen
Wegpunkt. Der System Commander ist die Benutzerschnittstelle, über welche dieser
Wegpunkt von einem Bediener eingegeben werden kann.
Der Local Waypoint Driver nimmt den Wegpunkt (Desired Global Waypoint) und
eine Geschwindigkeitsangabe (Desired Global Speed) von System Commander entgegen und berechnet einen Kurs zu diesem Wegpunkt. Hierzu bedient sich der Waypoint Driver der Daten des Global Pose Sensors.
Der Global Pose Sensor nutzt den RFID Reader als Sensor für die Bestimmung der
aktuellen Position und den Kompass als Sensor für die Bestimmung der momentanen Ausrichtung der Plattform. Diese beiden Informationen bilden zusammen die
sogenannte Pose, welche vom Global Pose Sensor an den Local Waypoint Driver
geschickt wird.
Der Reflexive Driver erhält vom Local Waypoint Driver einen Bewegungsbefehl
(Commanded Wrench Effort), welcher die Plattform zum nächsten Wegpunkt führen
soll.
23
Kapitel 4: JAUS
Der Reflexive Driver nimmt diese Information prüft mit dem Ultraschallsensor, ob
sich ein Hindernis in der Fahrtrichtung befindet und passt den Bewegungsbefehl
dementsprechend an, um die Sicherheit der Plattform nicht zu gefährden. Dieser
abgeänderte Befehl (Modified Wrench Effort) wird dann an den Primitive Driver
weitergegeben.
Der Primitive Driver bildet die eigentlich Motorsteuerung ab. Er erhält vom Reflexive Driver eine modifiziertes Steuerkommando und führt dieses aus.
Der Node Bedien-PC besitzt, wie bereits erwähnt, einen weitere Komponente vom
Typ System Commander, über welche ein Benutzer dem Roboter einen Wegpunkt
angeben kann. Des weiteren beinhaltet diese Node eine Komponente vom Typ World
Model Vector Store, in welcher das System Zugriff auf ein Weltmodell der Testumgebung hat. Das Weltmodell besteht derzeit aus einem Koordinatensystem, dessen
Punkte die jeweiligen RFID-Tags repräsentieren. Der Zugriff auf die Informationen
auf die Daten in der Flurwelt-Datenbank geschieht dann über Vector Knowledge Store Objects, die über die entsprechenden Query- und Inform-Nachrichten angefragt
und verschickt werden.
Der Entwickler-PC dient dem Erzeugen eines neuen uClinux Betriebssystemimages für den Surveyor Roboter. Diese Funktion ist hier als Nicht-JAUS-Komponente
OS-Flasher abgebildet. Die Komponente überträgt das Image bei Bedarf über das
Subsystem Network auf den Roboter.
Abbildung 7 fasst den Surveyor als JAUS-Architektur nochmals zusammen.
4.5
Bewertung
Der Joint Architecture for Unmanned Systems (JAUS) Standard ist vorrangig für
die Beschreibung und den Entwurf der Architektur von unbemannten Systemen oder
mobilen autonomen Robotern geeignet. JAUS hat zu diesem Zweck bereits viele vordefinierte Komponenten und Nachrichten für den Informationsaustausch zwischen
diesen an Bord. Hierdurch ist es möglich, eine sehr große Auswahl an verschiedenen
unbemannten Systemen mit den Möglichkeiten von JAUS in einer Art Baukastensystem zu spezifizieren. Hierbei legt JAUS einen Fokus auf die Kernbereiche der
Architektur in dem die Verarbeitung von Sensoren- und Aktorendaten geschieht.
Die Randbereiche der Architektur, an denen Sensoren und Aktoren an das System
angebunden werden sind absichtlich nicht festgelegt um die Auswahl der Techno24
Kapitel 4: JAUS
Abbildung 7: Surveyor als JAUS-System
logie der Sensoren und Aktoren nicht einzuschränken. Wenn man die Verwendung
von JAUS für den Entwurf der Steuerungssoftware bei verschiedenen unbemannten
Systemen stringent durchführt, kann man erreichen, dass auch teils sehr unterschiedliche Systeme mit oftmals auch sehr unterschiedlichen Einsatzgebieten, dennoch eine
gemeinsame Plattform, bestehend aus standardisierten Softwarekomponenten, besitzen.
Allerdings gibt es auch Punkte die gegen eine Verwendung von JAUS sprechen. Dazu gehört zum einen die Entscheidung, den JAUS Standard nicht weiter in einer
offenen Form zu entwickeln, wodurch es schwieriger wird an verbesserte Versionen
des Standards zu gelangen. Es könnte sogar passieren, dass die Interessen der SAE
dazu führen, dass die Plattformunabhängigkeit von JAUS zugunsten einiger weniger
Plattformen aufgegeben wird. Des weiteren ist der JAUS-Standard in seiner letzten
frei verfügbaren Version zwar schon recht umfangreich, aber einige wichtige Aspekte, wie die Planung von Missionen wurden bisher noch nicht spezifiziert. Es finden
sich zudem einige Festlegungen in der untersuchten JAUS Standard Version, die
als veraltet markiert sind und im damals nächsten geplanten Major-Release entfernt werden sollten. Dies zeigt, dass der JAUS Standard auch noch nicht frei von
unnötigem Ballast ist.
25
Kapitel 4: JAUS
Ein anderer Punkt, den man bei JAUS beachten muss, ist dass die Verwendung
von JAUS-Komponenten einen gewissen Overhead mit sich bringt, den man sich auf
hoch integrierten Systemen oftmals nicht leisten kann, da hierdurch mehr Ressourcen
benötigt werden, als bei einer monolithischen Umsetzung der Steuerungssoftware.
Zusammenfassend kann man festhalten, dass es gute Gründe gibt, den JAUS Standard für die Spezifikation von Architekturen bei unbemannten Systemen zu verwenden, vor allem wenn man diese Architekturen einheitlich und erweiterbar halten
möchte.
26
Kapitel 5: Existierende Taskbeschreibungssprachen
5
Existierende Taskbeschreibungssprachen
5.1
PDDL
Die Planning Domain Description Language, kurz PDDL, ist ein Standard für Planning Domains und Problembeschreibungen. Sie wurde 1998 von Drew McDermott
entwickelt und mit Hilfe von Planungswettbewerben (International Planning Competitions) weiter entwickelt [McD11].
Der bekannteste Teil der PDDL ist STRIPS. Die Abkürzung STRIPS steht für Stanford Research Institute Problem Solver. Man bezeichnet hiermit sowohl den Solver,
also eine Software zur Lösung eines Problems, als auch dessen formale Eingabesprache. Im folgenden wird die Eingabesprache kurz umrissen:
• In STRIPS werden Domänen (engl: domains) definiert. Eine Domäne hat folgende Bestandteile:
– Prädikate (engl.: predicates): Ein Prädikat ist eine Funktion mit einem
bool’schen Ergebniswert. Der Ergebniswert eines Prädikats ist wahr (true),
wenn die abgefragte Bedingung erfüllt ist.
– Aktionen (engl.: actions): Aktionen haben Vorbedingungen und Nachbedingungen. Eine Aktion kann ausgeführt werden wenn die Vorbedingungen erfüllt sind und erfüllt die Nachbedingungen nach Ausführung der
Aktion.
∗ Vor- und Nachbedingungen bestehen aus einer Reihe von Prädikaten.
• Planungsprobleme werden als Instanz einer Domäne beschrieben. Zu jeder
Instanz gehören:
– ein Initialzustand,
– eine Menge deklarierter Objekte, auf welche sich die Prädikate beziehen,
– und eine Menge von möglichen Endzuständen, für welche das beschriebene Problem gelöst ist.
Im folgenden ist ein sehr einfaches Beispiel für eine STRIPS-Instanz gegeben: In
diesem Beispiel wird die Domäne “robotmovement” definiert. Hierzu wird der Text
aus dem Beispiel in einer Textdatei “robotmovement.pddl” abgelegt.
27
Kapitel 5: Existierende Taskbeschreibungssprachen
1 ; PDDL / STRIPS Domain B e i s p i e l
2 ; D e f i n i t i o n d e r Domain robotmovement
3 ; Die Domain b e s c h r e i b t d i e M o e g l i c h k e i t e n d e r M a n i p u l a t i o n d e r Objekte
.
4
5 ( d e f i n e ( domain robotmovement )
6
7 ; Deklaration der Praedikate
− ( room ? r ) == true , wenn d e r Raum r e x i s t i e r t .
8 ; ( room ? r )
− ( at−room ? s ) == true , wenn s i c h d e r Roboter im
9 ; ( at−room ? s )
10 ; Raum s a u f h a e l t .
11
12
(: predicates
13
( room ? r )
( at−room ? s )
14
)
15
16 ; Aktionen / O p e r a t i o n e n d e f i n i e r e n
17 ; B e s c h r e i b u n g : Der Roboter bewegt s i c h von Raum a nach Raum b .
18 ; Vorbedingung : Die Raeume a und b e x i s t i e r e n und d e r Roboter b e f i n d e t
19 ; s i c h i n Raum A.
20 ; E f f e k t :
21 ;
( at−room ? a ) wird f a l s e
( at−room ?b ) wird true
22
23
( : a c t i o n move
24
: parameters
25
: p r e c o n d i t i o n ( and
( ? a ?b )
26
( and ( room ? a ) ( room ?b ) )
27
( and ( at−room ? a ) not ( at−room ?b ) )
28
)
29
: effect
30
( and ( at−room ?b )
( not ( at−room ? a ) )
31
)
32
)
33 )
Listing 1: robotmovement.pddl
Im ersten Schritt wird ein Problem namens “roomchange” in der Domäne “robotmovement” definiert. Die Beschreibung des Problems verwendet zur Lösung die Objekte
ra und rb stellvertretend für die Räume a und b aus der Domänendefinition. Bei der
Initialisierung des Startzustandes befindet sich der Roboter im Raum ra und nicht
im Raum rb. Der Zielzustand ist dadurch definiert, dass der Roboter sich im Raum
rb und nicht mehr im Raum ra befindet.
28
Kapitel 5: Existierende Taskbeschreibungssprachen
Hierdurch ist das Problem innerhalb der Domäne beschrieben. Um das Problem nun
zu lösen, kann man die beiden Dateien an einen STRIPS-Solver übergeben, welcher
dann versucht das gegebene Problem vom Initialzustand mit Hilfe der definierten
Actions der zugeordneten Domänendefinition in den Endzustand zu überführen. Der
Solver kann angewiesen werden den gesamten oder nur einen Teil des Lösungsweges
auszugeben. Für dieses Beispiel sieht die Lösung des Solvers wie folgt aus:
1 (
2
( move r a rb )
3 )
Listing 2: roomchange solved.txt
Die PDDL wird in Abbildung 8 noch einmal kurz zusammengefasst.
Abbildung 8: PDDL als Mindmap
29
Kapitel 5: Existierende Taskbeschreibungssprachen
5.2
5.2.1
Task Definition Language for Virtual Agents
Übersicht
Die Task Definition Language for Virtual Agents basiert auf SimHuman, einer Plattform für die Darstellung und Animation von virtuellen Agenten in Echtzeit. Virtuelle
Agenten sind eine Möglichkeit in virtuellen Umgebungen Aktivitäten stattfinden zu
lassen, die nicht direkt von einem oder mehreren Benutzern abhängig sind. Bei virtuellen Umgebungen spricht man auch häufig von virtueller Realität (VR = Virtual
Reality). Ein virtueller Agent kann als autonome Entität in einer virtuellen Umgebung betrachtet werden, der nicht nur das Aussehen, sondern auch das Verhalten,
von einem lebenden Organismus nachahmt.
Innerhalb einer virtuellen Umgebung ist ein virtueller Agent in der Lage, bestimmte
Aktionen auszuführen. Werden mehrere Aktionen miteinander in einer hierarchischen oder prozedualen Struktur kombiniert, so lassen sich damit Aufgaben, die
sogenannten Tasks, definieren. Durch einen geeigneten Aufbau der Tasks kann auf
die Verwendung eines rechenintensiven Planers bei der Ausführung der Tasks verzichtet werden. Ein Planer wird dann lediglich auf einer höheren Ebene für den
Wechsel zwischen unterschiedlichen Tasks eines virtuellen Agents benötigt.
Das Ziel der Task Definition Language ist es, Tasks in einer kontextunabhängigen
Hochsprache definieren zu können, wodurch ein hoher Grad an Wiederverwendbarkeit erreicht werden kann.
5.2.2
Virtuelle Umgebung
Die virtuelle Umgebung, auch Welt oder World genannt, bildet ein übergeordnetes
Objekt in dem die Menge aller Entitäten enthalten sind, die in der entsprechenden
Welt existieren. Eine Entität (Entity) ist entweder ein Agent oder ein Objekt, wobei der Unterschied darin liegt, dass ein Agent die Möglichkeit hat, den aktuellen
Zustand der Welt zu erfassen und Aktionen (Actions) in ihr auszuführen. Der aktuelle Zustand einer Welt setzt sich zusammen aus der Kombination der Zustände
der in ihr enthaltenen Entitäten. Der Zustand einer Entität kann durch Aktionen
eines Agenten verändert werden. Neben dem lebendigen Verhalten, das Agenten in
einer virtuellen Umgebung zeigen können, kann es auch reaktive Objekte geben. Ein
Beispiel hierfür ist ein fahrendes Auto.
30
Kapitel 5: Existierende Taskbeschreibungssprachen
In einer virtuellen Umgebung der Task Definition Language for Virtual Agents besitzen alle Entitäten eine eigene Geometrie. Es ist möglich, mehrere Entitäten in
einer baumartigen Struktur miteinander zu verknüpfen, wobei eine geometrische
Transformation einer Entität dieser Struktur sich auf die Entitäten in den Ebenen
darunter auswirken kann.
Eine weitere Eigenschaft der virtuellen Umgebung und der Entitäten darin sind
Attribute. Es wird hierbei zwischen globalen Attributen und lokalen Attributen unterschieden. Globale Attribute sind der Umgebung als ganzes zugeordnet und stehen
allen Entitäten innerhalb dieser Umgebung zur Verfügung. Lokale Attribute hingegen sind innerhalb von Entitäten definiert und stehen nur über den gemeinsamen
Aufruf mit dem zugehörigen Entitätsnamen zur Verfügung. Der allgemeine Aufbau
eines Attributs lautet:
<name, type, value>
wobei der Name der eindeutige Name, Type der Datentyp und Value der eigentliche Wert des Attributs ist. Der Aufruf von Variablen wird in Kapitel 5.2.5 näher
erläutert.
5.2.3
Die Task Definition Language
Die Task Definition Language verbindet einen Entscheidungsprozess auf oberster
Ebene mit den Bewegungs- und Interaktions-Möglichkeiten eines virtuellen Agenten in einer virtuellen Umgebung. Sie ermöglicht es, Tasks als Kombinationen von
parallel, sequentiell oder bedingt ausgeführten Aktionen zu beschreiben, ohne dabei
alle Implementierungsdetails explizit kennen und formulieren zu müssen. Diese kontextunabhängige Art der Beschreibung bringt einen hohen Grad an Wiederverwendbarkeit mit sich. Definiert ist eine Task im Rahmen der Task Definition Language
for Virtual Agents als “Eine Kombination von Aktionen eines virtuellen Agenten,
die ein bestimmtes Ziel erfüllt”. Jede Task hat hierbei einen eindeutigen Namen und
eine definierte Menge an Argumenten.
5.2.4
Aktionen
Eine Aktion (Action) ist ein Vorgang, ausgelöst oder durchgeführt durch einen virtuellen Agenten, der eine Änderung des Zustands der virtuellen Umgebung respek31
Kapitel 5: Existierende Taskbeschreibungssprachen
tive ihrer Entitäten bewirkt. Jede Aktion benötigt eine bestimmte Dauer für die
Durchführung. Die Dauer wird in Zeitrahmen (time frames) gemessen. Eine Aktion hat entweder eine fest definierte Dauer oder sie ist variabel und zielorientiert,
das heißt, die Aktion endet wenn ein bestimmter Zustand bei einer oder mehreren
Entitäten erreicht worden ist.
Primitive Aktionen sind innerhalb eines Zeitrahmens ausführbar. Zu den primitiven Aktionen gehört zum Beispiel das Ändern einer geometrischen Eigenschaft, das
Hinzufügen oder Entfernen einer Entität oder das Versenden von Nachrichten. Es
liegt in der Verantwortlichkeit der virtuellen Umgebung die Aktionen letztendlich
auszuführen und die resultierenden Effekte zu erzeugen. Komplexere Aktionen sind
oftmals eine Kombination aus mehreren primitiven Aktionen.
Ein wichtiges Feature für die lebhafte Darstellung von Agenten in einer virtuellen Umgebung ist das sogenannte Keyframing. Hierbei handelt es sich um die
Ausführung von vordefinierten Animationssequenzen.
Ein weiteres wichtiges Feature ist die Locomotion. Die Locomotion bezeichnet die
Fähigkeit des Agenten sich in der virtuellen Umgebung zu bewegen. Wichtige Aktionen beinhalten:
• zu einer bestimmten Position bewegen,
• sich in eine bestimmte Richtung drehen,
• in eine bestimmte Richtung gehen
• oder einem bestimmten Pfad zu folgen.
Positionen und Orientierungen in bestimmte Richtungen sind jeweils als Vektoren
gegeben. Die Locomotion Engine verwendet jedoch keine Körperteil-Bewegungen
sondern ein Zustandsmodell mit dem beliebige Bewegungsabläufe möglich sind. Um
die Interaktion des Agenten mit Objekten zu animieren, kann neben vordefinierten
Animationen auch auf die inverse Kinematik zurückgegriffen werden. Hierbei handelt
es sich um eine Reihe von Objekten die entlang einer Reihe von Vektoren bewegt
werden.
Neben dem Aufruf einer einzelnen Aktion, ist es möglich eine vollständige Task
mit entsprechenden Argumenten aufzurufen und damit auszuführen. Bei der Task
32
Kapitel 5: Existierende Taskbeschreibungssprachen
handelt es sich in dem Fall um eine Kombination aus Aktionen und Subtasks, die
zusammen ein bestimmtes Ziel erfüllen sollen.
Manche Aktionen haben bei ihrer Ausführung keinen direkten Einfluss auf die Umgebung. Zu diesen Aktionen gehört das Kopieren von Daten zwischen einzelnen
Variablen oder das Hinzufügen einer weiteren Annahme über die Umgebung im
virtuellen Agenten.
5.2.5
Literals, Variablen und Funktionen
Funktionen können mit Argumenten aufgerufen werden. Die Argumente können dabei direkte Werte, Variablen eines festgelegten Datentyps oder wiederum Funktionen
sein, wobei der Rückgabewert der Argumentfunktion dem Datentyp des Arguments
entsprechen muss. Gültige Datentypen für Argumente sind:
• bool
• integer
• float
• string
• entity
• list of entities
• vector
• list of vectors
• relation
Bei Relations handelt es sich um zusammengesetzte Dateitypen bestehend aus einem
eindeutigen Namen und einer Reihe von zusammenhängenden Daten von beliebigen
Datenformaten, ähnlich einem Array in anderen Programmiersprachen. Ein Beispiel
für eine Relation vom Typ Person kann wie folgt aussehen:
person(’John’, 28, 1.80, ’single’)
33
Kapitel 5: Existierende Taskbeschreibungssprachen
Durch die Möglichkeit Funktionen wiederum Funktionen als Argumente übergeben
zu können, ist ein verschachtelter Aufruf von mehreren Funktionen durch den Aufruf
einer einzigen Funktion möglich.
In einer virtuellen Umgebung gibt es vier verschiedene Variablenmengen:
• Attribute des Agenten
• Argumente der Task
• Interne Variablen einer Task
• Attribute der Entität
Der Zugriff auf diese Variablen geschieht über folgenden Aufruf:
[<entity name>]<variable name>
Hierbei muss der ¡entity name¿ nur angegeben werden, wenn es sich um Attribute
aus einer anderen als der Entität handelt, aus welcher die Abfrage gestartet wird.
Es gibt spezielle Funktionen um die räumliche Abhängigkeit zwischen zwei Entitäten
zu bestimmen:
• near(e1,e2)
• on(e1,e2)
• front of(e1,e2)
• behind(e1,e2)
• left of(e1,e2)
• right of(e1,e2)
• above(e1,e2)
• below(e1,e2)
• intersect(e1,e2): Kollisionserkennung
34
Kapitel 5: Existierende Taskbeschreibungssprachen
Diese Funktionen bestimmen einen bool’schen Rückgabewert über den Vergleich von
Position, Größe und Ausrichtung zweier Entitäten, die als Argumente übergeben
werden.
Des weiteren gibt es Funktionen, die eine neue Position in einer vorher festgelegten
Distanz relativ zu einer gegebenen Position erzeugen können. Diese lauten:
• left
• right
• front
• behind
• above
• below
• on
Zusätzlich sind die folgenden Logikfunktionen definiert:
• and
• or
• not
Die Funktion exists(ent,f) stellt eine weitere Besonderheit dar. Sie liefert den
Wert true zurück, wenn in der Welt die Funktion f mit dem Argument ent und
deren Argumenten, den Wert true zurückgibt.
5.2.6
Tasks definieren
Eine Task besteht aus drei Teilen:
1. Task Definition:
TASK name(type1, arg1, type2, arg2, , typen, argn)
35
Kapitel 5: Existierende Taskbeschreibungssprachen
2. Dem String #Variables gefolgt von der Variablendeklaration: type name =
value
3. Dem String #Body gefolgt von einem oder mehreren Kommandos. Dieser Block
wird abgeschlossen durch den String #end. Mögliche Kommandos sind:
• <action>: eine einzelne Aktion
• PAR(<block b1>, <block b2>): Gleichzeitige Ausführung von b1 und
b2.
• DO(<block b>) UNTIL c: Der Block b wird solange ausgeführt bis die
Bedingung c erfüllt ist.
• IF <bool c> THEN(<block b1>) ELSE (<block b2>): Wenn die Bedingung c wahr ist, führe b1 aus, sonst führe b2 aus.
Sollte irgendein Kommando innerhalb einer Task scheitern, so scheitert ebenfalls
die gesamte Task. Bei PAR dürfen die beiden Blöcke nicht zur gleichen Zeit auf die
selben kritischen Ressourcen zugreifen, da die Aktionen ansonsten scheitern würden.
Eine Besonderheit bei DO UNTIL ist, dass die Bedingung nach der Ausführung jedes einzelnen Schritts im Verarbeitungsblock ausgewertet wird und nicht erst wenn
der ganze Block verarbeitet worden ist. Hierdurch ist ein Verlassen der DO UNTIL
Schleifen quasi jederzeit möglich.
5.2.7
Beispiel
Ein Agent in einem Restaurant sucht einen freien Tisch an den er sich setzen kann.
1 TASK s i t o n f r e e t a b l e ( )
2 #V a r i a b l e s
3
e n t i t y Table ’ ’
4
e n t i t y Chair ’ ’
5
e n t i t y Human ’ ’
6 #Body
7 DO (
8
t a s k walk around ( )
9 ) UNTIL e x i s t s ( Table , and (
10
11
12
13
14
eq ( [ Table ] c l a s s , ’ t a b l e ’ ) ,
not ( e x i s t s ( Chair ,
and ( eq ( [ Chair ] c l a s s , ’ c h a i r ’ ) ,
and ( n e a r ( Chair , Table ) ,
e x i s t s ( Human ,
36
Kapitel 5: Existierende Taskbeschreibungssprachen
15
and ( eq ( [ Human ] c l a s s , ’ human ’ ) ,
16
i n t e r s e c t ( Human , Chair ) )
17
)
18
)
19
)
20
)
21
22
)
)
23 ) ;
24 t a s k g o a n d s i t ( Table )
25 #end
Listing 3: sit on free table.task
Der Agent läuft den Raum mittels eines bestimmten Pfades ab (walk around()) bis
er einen Tisch sieht an dem sich Stühle befinden, auf denen kein Mensch sitzt. Dabei
impliziert diese Taskbescheibung, dass sich an jedem Tisch auch Stühle befinden. Hat
er einen solchen Tisch gefunden, setzt er sich an diesen Tisch (go and sit(Table)).
37
Kapitel 6: Robotic Task Definition Language
6
6.1
Robotic Task Definition Language
Einführung
Die Robotic Task Definition Language, kurz RTDL, ist eine Sprache, mit welcher Tasks definiert und beschrieben werden können. Die Tasks, die mit Hilfe der
RTDL beschrieben werden können, werden speziell für Roboter definiert, welche diese Taskbeschreibungen dann mit Hilfe eines Interpreters auswerten und ausführen
können.
In diesem Kapitel werden zunächst der Begriff der Task und die Anforderungen an
die RTDL festgelegt. Den Abschluss dieses Kapitels bildet die Definition der RTDL
und ihrer Elemente.
6.2
Tasks und Anforderungen an die RTDL
Eine Task stellt eine spezifische Anweisung dar, die von einem Roboter ausgeführt
werden soll. Da es sich bei einer Task um die Zuweisung einer Aufgabe an einen Roboter handelt, lassen sich bestimmte Parallelen zur Kommandierung einer Aufgabe
zwischen Menschen finden.
Wenn es in einer zwischenmenschlichen Konstellation zu einer Situation kommt, in
welcher ein Mensch einem anderen Menschen eine Anweisung gibt, welche der zweite Mensch ausführen soll, so geschieht dies oftmals über den Weg der natürlichen
Sprache. Dies umfasst sowohl die mündliche, als auch die schriftliche Art der Aufgabenzuteilung. Im Kern der Anweisung steht immer ein Verb, das eine Tätigkeit
beschreibt. Zudem ist es oftmals notwendig, noch weitere Informationen in die Anweisung zu packen, um diese präzise zu formulieren. Die Anweisung “gehe in die
Küche” beschreibt die gewünschte Tätigkeit mit dem Verb “gehen” und ist parametriert mit der Entität “Küche”, die das Ziel der Bewegung ausmacht.
Damit eine Roboter eine bestimmte Task ausführen kann, müssen bestimmte Gegebenheiten geschaffen werden. Zum einen muss eine Tätigkeit für einen Roboter in
einer geeigneten Art und Weise formuliert sein, damit der Roboter die notwendigen
Informationen zur Durchführung einer Tätigkeit erhält. Diese Informationen erhält
der Roboter durch eine Taskbeschreibung.
Eine Anforderung an eine solche Taskbeschreibungssprache ist, dass sie ihr Ein38
Kapitel 6: Robotic Task Definition Language
satzgebiet nicht selbst einschränkt. Dies beinhaltet insbesondere, dass eine Taskbeschreibungssprache für Roboter sowohl unabhängig von der konkreten Hardware eines Roboters, als auch unabhängig von der Plattform, also der Softwareumgebung,
eines konkreten Roboters sein soll. Einschränkungen bezüglich der Möglichkeit der
Durchführung einer Task dürfen sich nur aus den Kombination von Roboter und gestellten Aufgabe ergeben, jedoch nicht aus der Art der Beschreibung der Tätigkeit.
Eine weitere Anforderung an die RTDL ist es, dass die Elemente, aus denen eine Taskbeschreibung aufgebaut ist, eine Blockstrukturierung aufweisen. Hierdurch
lassen sich sowohl die beschriebene Task selbst, als auch ihre Elemente, also die
enthaltenen Aktionen, aus gleichartigen Bausteinen aufbauen, die sogar ineinander
verschachtelt sein können. Ein weiterer Vorteil von Blöcken ist, dass sie sich sowohl
seriell als auch parallel abarbeiten lassen, wodurch eine potentielle Effizienzsteigerung in der Ausführung einer Task erreicht werden kann.
Schließlich sollte die RTDL noch über eine XML-basierte (eXtensible Markup Language) Repräsentation einer Taskbeschreibung verfügen, weil dadurch eine Vielzahl von Verarbeitungsmöglichkeiten mit bekannten und ausgereiften Werkzeugen
möglich ist. Zu diesen Werkzeugen gehört die Möglichkeit der Prüfung der Wohlgeformtheit (wellformed XML) und der Validität über eine Document Type Definition
(DTD) (valid XML). Außerdem bietet die XML Transformation Stylesheet Language (XSLT) die Möglichkeit, eine Taskbeschreibung im XML-Format in ein beliebiges
anderes Format zu transformieren.
6.3
Taskzuweisung an Roboter
Bei der Taskzuweisung wird ein Roboter vor einige Herausforderungen gestellt, die
ein Mensch eher intuitiv zu lösen weiß. So ist nicht jeder Roboter in der Lage auf
gesprochene Kommandos zu reagieren, da er hierfür über eine robuste Spracherkennung verfügen muss. Eine robuste Spracherkennung kann gesprochene Sätze in die
Schriftform überführen, man spricht hierbei von Text-to-Speech.
In [Hol10] werden die Fähigkeit der robusten Spracherkennung und der Sprachsynthese genannt. Bei der Spracherkennung muss der Roboter gesprochene Sätze
erkennen und analysieren können. Darüber hinaus muss der Roboter entscheiden,
ob es sich bei einem gesprochenem Satz um eine Anweisung an ihn handelt oder
nicht. Ebenso wichtig ist in diesem Zusammenhang eine gute Sprachsynthese, damit der Roboter qualifizierte Rückmeldungen zu einer Anweisung geben kann. Diese
39
Kapitel 6: Robotic Task Definition Language
Fähigkeiten sind für einen Roboter vor allem in einer Umgebung, in der er für oder
mit Menschen arbeiten soll, sinnvoll. Dies gilt vor allem in Bezug auf die Effizienz, Flexibilität und Akzeptanz seiner kooperativen Arbeit mit Menschen, da die
Zuweisung von Tasks an einen Roboter unmittelbar vor Ort und ohne Hilfsmittel
vorgenommen werden kann.
Aber selbst wenn gesprochene Sätze in ihrer Schriftform vorliegen, sind weitere
Hürden für den Roboter zu nehmen. Menschen sprechen in einer natürlichen Sprache.
In [MT10] werden einige Schwierigkeiten, welche die Verwendung von natürlicher
Sprache bei Maschinen mit sich bringt, erläutert. Zunächst ist die natürliche Sprache
voller Mehrdeutigkeiten und selten präzise genug formuliert, um von einer Maschine
direkt verarbeitet werden zu können. Zudem sprechen Menschen oftmals Sätze, die
in einem bestimmten Kontext vorliegen. Bei der zwischenmenschlichen Kommunikation ist der Kontext der Kommunikationspartner oftmals der selbe. Ist dies nicht
der Fall, so entstehen häufig große Missverständnisse in der Kommunikation, wie
jeder Mensch sicher schon einmal leidvoll erfahren musste.
Für einen Roboter existiert ein solcher Kontext jedoch oftmals nicht. Somit müssen
auch Anweisungen in der Schriftform oftmals weiter analysiert und verarbeitet werden, bevor ein Roboter diese als geeignete Anweisung ausführen kann. In seiner Arbeit beschreibt [Bud09] einen Küchenroboter, der Küchenrezepte, die in natürlicher
Sprache geschrieben sind, mit Hilfe einer Satzanalyse in Anweisungen zerlegt und
in Tätigkeiten umsetzt, welche das Rezept virtuell “nachkochen”. Bei der Domäne
eines Küchenroboters ist der Kontext der natürlichsprachlichen Anweisungen von
Rezepten jedoch vollständig bekannt, ein Luxus den ein generischer Roboter nicht
hat.
Bei der Entwicklung der RTDL wurde aus diesem Grund auf die Verwendung der
natürlichen Sprache zur Taskbeschreibung und -zuweisung verzichtet und stattdessen eine Funktionssyntax für Aktionen definiert, in welcher Tasks beschreiben werden können.
Aus [MT10] wurde die folgende Liste erstellt, welche eine Reihe von Fragestellungen
bezüglich der Zuweisung von Tasks an Roboter bildet.
• Besitzt ein Roboter das gesamte Wissen, dass für die Erfüllung einer Aufgabe
notwendig ist und wie erhält er dieses Wissen? Hierzu gehört:
– Bestimmung der involvierten Objekte bei der Ausführung einer Aktion.
40
Kapitel 6: Robotic Task Definition Language
– Korrekte Positionierung eines Roboters zu einem bestimmten Objekt.
– Spezifische Parameter bei der Manipulation eines Objekts wie zum Beispiel die verwendete Kraft beim Greifen und der sichere Ablauf von Armbewegungen an einem Objekt.
– Bestimmung des Zustands von Objekten.
– Das Ziehen von Schlüssen aus bestimmten Gegebenheiten in der Umgebung des Roboters oder eines Objekts.
• Auf was begründet ein Roboter die symbolischen Repräsentationen in seinem
Weltmodell?
• Wie soll ungenaues Wissen abgebildet und wie soll damit umgegangen werden.
• Was ist eine geeignete Repräsentation von Wissen, die sowohl ausdrucksstark
ist, als auch ein schnelles Schließen (Reasoning) ermöglicht?
• Wie erhält der Roboter ein Bewusstsein über Aktionen und wie können Auswirkungen von Aktionen vorhergesagt werden?
All diese Punkte gilt es beim Einsatz von Robotern zu beachten, während sie für
einen Menschen oftmals intuitiv erschlossen und einbezogen werden. Die hier genannten Punkte befassen sich vorwiegend mit der Fragestellung wie eine bestimmte
Aktion ausgeführt werden soll und weniger mit der Frage, welche Aktionen eine Task
ausmachen. Somit sind diese Punkte eher für die Entwicklung eines Roboters als für
die Entwicklung einer Taskbeschreibungssprache von Belang.
6.4
Aufbau von RTDL Taskbeschreibungen
Im letzten Unterkapitel wurde auf die Schwierigkeit der Verwendung von natürlicher
Sprache für die Taskzuweisung bei Robotern eingegangen. Diese Umstände haben
dazu geführt, dass bei der RTDL ein anderer Ansatz für die Beschreibung von Tasks
gewählt wurde.
Die verwendete Funktionssyntax verwendet bei der Definition einer Task einen Funktionsnamen und eine Menge von Parametern zu genaueren Spezifikation der Task.
Der Funktionsname wird hierbei durch die englische Version jenes Verbs gebildet,
welches den Kern einer Anweisung bildet. Angehängt an den Funktionsnamen wird
41
Kapitel 6: Robotic Task Definition Language
eine in runde Klammern gefasste und durch Kommata getrennte Liste von Parametern. Die einzelnen Parameter bestehen wiederum aus einem Entitätstypen und
einem Parameternamen. Das folgende Beispiel zeigt die Anweisung “Gehe in die
Küche” in der Funktionssyntax:
moveTo(kitchen);
Hierbei bezeichnet “moveTo” das Verb für Bewegung und “kitchen” das Ziel der
Bewegung. Definiert ist die Funktion “moveTo” allgemein als:
moveTo(location loc);
Hierbei ist “location” der Entitätstyp des ersten und einzigen Parameters und “loc”
die Referenz auf den übergebenen Wert dieses Parameters.
Zur Beschreibung einer Task ist neben der Definition der Signatur, also des Aufrufs
der Task, auch deren Umsetzung von Bedeutung. Jede Task besteht intern aus einer
Abfolge von Aktionen (actions), die von einem Roboter ausgeführt werden müssen,
um das Ziel der Task zu erreichen. Anders als bei der PDDL, vgl. Kapitel 5.1, ist das
Ziel einer RTDL Task nicht explizit beschrieben, sondern wird durch die Ausführung
der Task erreicht. Das bedeutet: Eine Task gilt als erfolgreich ausgeführt, wenn alle
Aktionen innerhalb der Taskbeschreibung erfolgreich ausgeführt werden konnten.
Eine Aktion, innerhalb einer Taskbeschreibung kann dabei entweder eine primitive Aktion sein, die von einem Roboter unmittelbar umgesetzt werden kann, oder
aber eine bereits definierte Task. Aus diesem Grund wird eine Aktion genauso wie
eine Task durch eine Signatur mit einem Funktionsnamen und einer Parameterliste
beschrieben.
Da eine Task auch im Rahmen der Beschreibung einer anderen Task aufgerufen
werden kann, lassen sich Taskhierarchien aufbauen, die jedoch auf der untersten
Ebene immer auf primitiven Aktionen von Robotern basieren, denn nur diese sind
von einem Roboter direkt ausführbar.
6.5
Capabilities
Die Capabilities eines Roboters sind die Fähigkeiten, die der Roboter besitzt, seine
Umgebung zu erfassen, zu verändern und sich in ihr zu bewegen. Sie werden be42
Kapitel 6: Robotic Task Definition Language
stimmt über die Kombination seiner Sensoren, Aktoren und der verwendeten Steuerungssoftware.
Im Kontext der RTDL sind die Capabilities eines Roboters gegeben durch die Menge
der primitiven Aktionen (actions), die ein Roboter über die Steuerungssoftware als
Funktionen anbietet. So ist beispielsweise ein Roboter mit angetriebenen Rädern und
ausreichenden Sensoren zur Kollisionserkennung physikalisch in der Lage, sich über
bestimmte Terrains zu bewegen. Es wird jedoch eine Schnittstelle benötigt, um diese
Fähigkeiten nutzen zu können. Diese Schnittstelle muss durch die Steuerungssoftware angeboten werden, beispielsweise in Form einer API (Application Programming
Interface), welche diese Funktionalität als Software-Funktion anbietet.
Führt ein Roboter eine RTDL Task aus, die auf einer oder mehreren Aktionen
basiert, welche nicht als Capability in der Steuerungssoftware angeboten werden
und die auch nicht als definierte RTDL Task vorhanden ist, so scheitert diese Task.
Ist diese Task nun Teil einer höherrangigen Taskdefinition so scheitern alle höherrangigen Tasks ebenfalls.
6.6
6.6.1
Definition der Robotic Task Definition Language
Funktionssyntax - Form
In diesem Unterkapitel wird der Aufbau der RTDL festgelegt. Ein RTDL-Dokument
ist eine Textdatei, in welcher Tasks in Form einer Funktionssyntax spezifiziert werden. Innerhalb einer RTDL-Taskbeschreibung dürfen ausschließlich Zeichen aus dem
ASCII-Zeichensatz (American Standard Code for Information Interchange) [Wik10]
verwendet werden.
In einer Programmiersprache sind Kommentare ein weit verbreitetes und probates
Mittel, um ein Programm für einen Menschen einfacher lesbar zu gestalten. Die
RTDL definiert ebenfalls Kommentare in der gleichen Form wie in der Programmiersprache Java:
/*
* Ich bin ein Kommentar und ich erstrecke mich über eine
* oder mehrere Zeilen.
*/
43
Kapitel 6: Robotic Task Definition Language
Die RTDL ist flexibel im Umgang mit Leerzeichen, Tabulatoren und Zeilenumbrüchen. RTDL-Elemente müssen durch Abstandshalter voneinander getrennt werden. Der Standard-Abstandshalter ist das Leerzeichen. Es ist jedoch auch möglich
anstatt eines einzelnen Leerzeichens beliebig viele Leerzeichen, Tabulatoren oder
Zeilenumbrüche oder eine Kombination aus diesen zu erzeugen.
6.6.2
Funktionssyntax - Aufbau
Ein RTDL-Dokument beginnt immer mit der folgenden obligatorischen Zeile:
rtdl <Versionsnummer>
Hiermit wird angezeigt dass es sich um ein RTDL-Dokument in der Version <Versionsnummer> handelt. Da die RTDL hier erstmalig definiert wird, ist hier bislang
nur der Wert 1.0 gültig. Somit sieht die erste Zeile wie folgt aus:
rtdl 1.0
In einem RTDL-Dokument dürfen Kommentare an beliebigen Stellen verwendet
werden, außer in der ersten Zeile vor der RTDL-Versionsdeklaration.
Nach der ersten Zeile folgt eine Taskdefinition, die wie folgt beginnt:
task <Taskname>(<Argtyp1> <Argname1>, ..., <ArgtypN> <ArgnameN>) {
<Body>
}
Das Schlüsselwort task leitet die Taskdefinition ein und wird gefolgt von einem
Tasknamen. An den Tasknamen wird unmittelbar eine in Klammern gefasste und
durch Kommata getrennten Liste von Argumenten angehängt, die ihrerseits aus
dem Entitätstypen und einem eindeutigen Namen des Arguments bestehen. Der in
geschweifte Klammern gefasste Body der Task bildet die Implementierung der Task
und wird im folgenden näher beschrieben.
Als erstes wird eine optionale Menge von benannten Enititäten, die für die Ausführung der Task benötigt werden, erzeugt. Diese Menge wird definiert durch mehrere
Strings mit dem folgenden Aufbau:
44
Kapitel 6: Robotic Task Definition Language
entity <Entitätstyp> <Entitätsname>;
Das Schlüsselwort entity zeigt an, dass eine benannte Entität definiert werden soll.
Der Entitätstyp und der Entitätsname sind selbsterklärend. Abgeschlossen werden
diese Definitionen durch ein Semikolon.
Eine Entität oder Entity bezeichnet im Sinne der RTDL ein irgendwie geartetes Objekt, mit dem ein Roboter auf eine beliebige Art interagieren kann. Jede Entität ist
genauer durch einen Entitätstypen spezifiziert, der angibt um welche Art von Objekt
es sich handelt. Oftmals sind mit bestimmten Entitätstypen bestimmte Eigenschaften und Interaktionsmöglichkeiten verknüpft. Wenn ein Roboter einen bestimmten
Entitätstypen kennt, so besitzt er häufig eine Menge von möglichen Interaktionen,
die er auf diesem Entitätstypen ausführen kann.
Im letzten und wichtigsten Abschnitt einer RTDL-Taskbeschreibung wird die eigentliche Task durch eine Menge von Operationen beschrieben. Zu diesen Operationen
gehört der Aufruf von primitiven Aktionen und bereits definierten Tasks. Ein Aufruf einer Aktion oder Task mit ihren entsprechenden Argumenten hat folgenden
Aufbau:
<Taskname>(<Argname1>, ..., <ArgnameN>);
Der Aufruf einer Task oder Aktion besteht aus dem Aufruf des Namens der Task oder
Aktion gefolgt durch eine Liste von Argumenten, abgeschlossen durch ein Semikolon.
6.6.3
Funktionssyntax - Erweiterte Ausführungskonstrukte
Neben der seriellen Ausführung von Tasks oder Aktionen, ermöglicht die RTDL,
die Ausführung durch Konstrukte, wie man sie in anderen Programmiersprachen
vorfindet.
Eine While-Schleife ist ein solches Konstrukt, bei dem eine Liste von Tasks oder
Aktionen so lange ausgeführt wird, solange eine boolsche Laufzeitbedingung wahr
ist. Ist <Bedingung> nicht erfüllt, so wird die Ausführung nach dem While-Block
fortgesetzt. In der RTDL hat eine While-Schleife den folgenden Aufbau:
while(<Bedingung>)
do
45
Kapitel 6: Robotic Task Definition Language
<Liste von Tasks oder Aktionen>
done
Ein weiteres Konstrukt ist die bedingte Ausführung durch if. Hierbei wird eine
Bedingung geprüft. Eine Liste von Tasks oder Aktionen wird nur dann ausgeführt,
wenn eine bestimmte boolsche Bedingung erfüllt ist, ansonsten wird der If-Block
übersprungen. Innerhalb der RTDL hat ein If-Konstrukt den folgenden Ausbau:
if(<Bedingung>)
<Liste von Tasks oder Aktionen>
endif
In bestimmten Situationen ist ein gleichzeitiges Ausführen von mehreren Tasks oder
Aktionen notwendig. Diese Möglichkeit wird durch das Par-Konstrukt gegeben, bei
dem zwei Blöcke von Anweisungen zeitgleich ausgeführt werden. Der Aufbau des
Par-Konstrukts ist wie folgt:
par
<Liste von Tasks oder Aktionen>
to
<Liste von Tasks und Aktionen>
endpar
6.6.4
Funktionssyntax - Abfangen des Scheiterns einer Task
Generell gilt, dass wenn eine Task oder Aktion innerhalb einer Taskdefinition bei deren Ausführung scheitert, so scheitert die gesamte definierte Task. Dieses Verhalten
wurde in [SV03] ähnlich definiert. Diese Einschränkung gilt nicht für Bedingungen
im Kopf von While- oder If-Blöcken. Jedoch bedeutet dies für die Ausführung einer
Task, dass es eine oftmals hohe Wahrscheinlichkeit gibt, dass diese Task während
ihrer Ausführung scheitert und damit eine ganze Hierarchie von Tasks und Aktionen scheitert. Um diese Problematik etwas abzuschwächen, gibt es verschiedene
Lösungsansätze.
Es ist beispielsweise möglich, dass die Ausführung einer Task zu einem bestimmten
Zeitpunkt scheitert, kurz darauf jedoch möglicherweise erfolgreich ausgeführt werden
könnte. Um sich diesen Umstand nutzbar zu machen, kann man den Aufruf von
46
Kapitel 6: Robotic Task Definition Language
bestimmten Tasks eine Schleife packen, die eine bestimmte Anzahl an Versuchen
hintereinander versucht, diese Task auszuführen. Ein solches Konstrukt hat den
folgenden Aufbau:
retry(int retries)
<Liste von Tasks oder Aktionen>
endtry
Darüber hinaus kann man auch die Anzahl der Ausführungsversuche für alle Tasks
und Aktionen innerhalb einer Taskdefinition global festlegen. Dies kann man beispielsweise über die folgende Anweisung innerhalb des Bodys einer Taskdefinition
festlegen:
retrycount(int tries);
Innerhalb einer Taskdefinition kann es neben den notwendigen Ausführung auch
die Möglichkeit der optionalen Ausführung von Tasks und Aktionen geben. Wenn
eine solche optionale Task oder Aktion scheitert, hat dieses keinen Einfluss auf die
Ausführung der Task als ganze. Die optionale Ausführung einer Task oder Aktion
erreicht man durch das Schlüsselwort optional vor der Ausführung:
optional <taskname>(<argument1>, ..., <argumentN>);
6.7
Robotic Task Definition Language XML-Syntax
Neben der Funktionssyntax der Robotic Task Definition Language, wie sie in Kapitel 6.6 definiert wurde, wurde eine äquivalente XML-Repräsentation definiert. Der
Aufbau einer Taskbeschreibung in der XML-Syntax ist im Grunde der selbe wie bei
der Funktionssyntax:
Die erste Zeile hat stets den folgenden Aufbau:
<?xml version="1.0" encoding="UTF-8"?>
Diese Zeile wird gefolgt von der Deklaration des XML-Stylesheets, mit welchem die
XML-Syntax in die Funktionssyntax transformiert werden kann. Das Stylesheet ist
als Quellcode in Listing 22 auf Seite 144 integriert.
47
Kapitel 6: Robotic Task Definition Language
<?xml-stylesheet type="text/xml" href="rtdl.xsl" version="1.0"?>
Nach der Deklaration des XML-Stylesheets kann man optional noch die Document
Type Definition (DTD) einbinden. Die DTD müsste sich bei diesem Beispiel im
selben Verzeichnis wie die Taskbeschreibung befinden und kann eingebunden werden
durch die folgende Zeile:
<!DOCTYPE rtdl SYSTEM "rtdl.dtd">
Das eigentliche RTDL Dokument ist in das folgende Wurzeltag gefasst:
<rtdl version="1.0">
</rtdl>
Innerhalb des Wurzeltags und auch innerhalb der weiteren Tags können Kommentare
mit dem folgenden Tag eingeleitet werden:
<comment>This is a comment.</comment>
Die Definition einer Task wird umschlossen von:
<task name="exampleTask">
</task>
Innerhalb der Taskdefinition werden als erstes die Argumente der Task als Var-Tags
mit ihren Entitätstypen aufgelistet:
<taskargs>
<var type="FirstArg">a1</var>
<var type="SecondArg">a2</var>
</taskargs>
Die globale Anzahl der Ausführungsversuche (Standardwert: 1) jeder Aktion wird
durch das folgende optionale Tag überschrieben:
<retrycount>1</retrycount>
48
Kapitel 6: Robotic Task Definition Language
Als nächstes folgt die Aufzählung der Entitäten, die während der Taskbeschreibung
verwendet werden, in Form von Var-Tags:
<entities>
<var type="Entity">entity1</var>
<var type="Entity">entity2</var>
<var type="Entity">entity3</var>
</entities>
Der interne Ablauf der Task wird durch ein Block-Tag eingeleitet:
<block>
</block>
Innerhalb eines Block-Elements können nun die verschiedenen Elemente zur Beschreibung des Ablaufs einer Task in beliebiger Reihenfolge und Anzahl verwendet
werden. Zu diesen Elementen gehören:
Die Aktion mit ihrem Namen und ihren zugehörigen Parametern. Die Parameter
einer Aktion werden in Arg-Tags gefasst. Arg-Tags sind vergleichbar mit Var-Tags,
jedoch wird hierbei kein Entitätstyp angegeben.
<action>
<name>Task1</name>
<args>
<arg>entity1</arg>
<arg>entity2</arg>
<arg>entity3</arg>
</args>
</action>
Die bedingte Ausführung eines Blocks durch ein If-Konstrukt:
<if>
<cond>condition</cond>
<block>
</block>
</if>
49
Kapitel 6: Robotic Task Definition Language
Die Ausführung eines Blocks in einer While-Schleife:
<while>
<cond>condition</cond>
<block>
</block>
</while>
Die parallele Ausführung zweier Blöcke block und block2:
<par>
<block>
</block>
<block2>
</block2>
</par>
Die Ausführung eines Blocks mit mehreren Wiederholungsversuchen:
<retry count="5">
<block>
</block>
</retry>
Die optionale Ausführung einer Aktion, bei der ein Scheitern keine Auswirkung auf
den Erfolg der definierten Task hat:
<action optional="true">
</action>
Durch die Verwendung des Block-Tags ist eine Verschachtelung von beliebiger Tiefe
bei der Beschreibung einer Task möglich.
Die Struktur einer RTDL Taskbeschreibung ist zusätzlich in Form einer Document
Type Definition (DTD) festgehalten. Diese hat den folgenden Aufbau:
1 <!−− RTDL v1 . 0 Document Type D e f i n i t i o n −−>
2
50
Kapitel 6: Robotic Task Definition Language
3 <!ELEMENT r t d l ( comment ∗ , task , comment ∗ )>
4 <!ATTLIST r t d l
5
v e r s i o n CDATA #REQUIRED
6>
7 <!ELEMENT comment (#PCDATA)>
8 <!ELEMENT t a s k ( comment ∗ ,
9
taskargs ,
10
comment ∗ ,
11
retrycount ? ,
12
comment ∗ ,
13
entities ,
14
comment ∗ ,
15
b lock ,
16
comment∗
17 )>
18 <!ATTLIST t a s k
19
name CDATA #REQUIRED
20 >
21 <!ELEMENT t a s k a r g s ( var | comment )∗>
22 <!ELEMENT var (#PCDATA)>
23 <!ATTLIST var
24
type CDATA #REQUIRED
25 >
26 <!ELEMENT r e t r y c o u n t (#PCDATA)>
27 <!ELEMENT e n t i t i e s ( var | comment )∗>
28 <!ELEMENT b l o c k ( a c t i o n | par | i f | while | r e t r y | comment )∗>
29 <!ELEMENT a c t i o n ( comment ∗ , name , comment ∗ , a r g s ? , comment ∗ )>
30 <!ATTLIST a c t i o n
31
o p t i o n a l CDATA #IMPLIED
32 >
33 <!ELEMENT name (#PCDATA)>
34 <!ELEMENT a r g s ( a r g | comment )∗>
35 <!ELEMENT a r g (#PCDATA)>
36 <!ELEMENT par ( b lock , b l o c k 2 )>
37 <!ELEMENT i f ( cond , b l o c k )>
38 <!ELEMENT cond (#PCDATA)>
39 <!ELEMENT while ( cond , b l o c k )>
40 <!ELEMENT r e t r y ( b l o c k )>
41 <!ATTLIST r e t r y
42
count CDATA #REQUIRED
43 >
Listing 4: rtdl.dtd
51
Kapitel 6: Robotic Task Definition Language
Die Einbinden einer DTD in Verbindung mit einem XML-Parser erlaubt die Validierung einer in der XML-Syntax formulierten RTDL Taskbeschreibung.
6.8
Beispiel für eine Task: fetchWater(Glass g, Tap t)
Das folgende Beispiel zeigt wie eine Task fetchWater(Glass g, Tap t) in der
Funktionssyntax aufgebaut sein könnte.
Bei dem Beispiel soll ein Roboter einem Benutzer ein Glas gefüllt mit Wasser holen,
wobei er das Wasser aus einem Wasserhahn besorgt. In einer natürlichsprachlichen
Formulierung würde man sagen: “Fetch me a glass of water from the tap!”. Aus dem
Verb “fetch” leitet sich der Name der Task ab. Der Zusatz “water” im Tasknamen
gibt der Task einen Namen mit mehr Aussagekraft. Die Substantive “glass” und
“tap” werden zu den Argumenten der Task.
Eine Besonderheit bei dieser Task ist, dass sie zwei Argumente verwendet. Das
erste Argument “Glass g” bezeichnet den Gegenstand, mit dem der Roboter das
Wasser transportieren soll. Das zweite Argument “Tap t” bezeichnet die Quelle, an
welcher der Roboter das Wasser erhält. Der Ablauf dieser Task wird im Folgenden
beschrieben.
Der Roboter befindet sich anfänglich an einem bestimmten Ausgangsort und muss
sich als erstes ein Glas besorgen. Dazu fährt er zu dem Glas hin und greift es. Dieses
Glas wird dann zu einem Wasserhahn transportiert und mit Wasser gefüllt. Danach
fährt der Roboter wieder zu seinem Ausgangsort zurück, wo er das Glas absetzt.
Im folgenden wird dieses Beispiel in Form einer RTDL-Taskbeschreibung in der
Funktionssyntax beschrieben. Die Umsetzung beschränkt sich hierbei jedoch auf die
oberste Ebene der Taskdefinition und lässt die Definition der aufgerufenen Tasks
und Aktionen weg.
1 rtdl 1.0
2
3 /∗ In d i e s e r Task s o l l e i n Roboter mit einem Greifarm und d e r
M ö g l i c h k e i t
4
∗ s i c h i n s e i n e r Umgebung zu bewegen e i n Glas Wasser b e s o r g e n und am
5
∗ Ausgangspunkt a b s t e l l e n .
6
∗/
7 t a s k f e t c h W a t e r ( G l a s s g , Tap t ) {
8 /∗ Wegpunkt f ü r d i e A u s g a n g s p o s i t i o n . ∗/
9
e n t i t y Waypoint s t a r t ;
52
Kapitel 6: Robotic Task Definition Language
10
11 /∗ Merke d i e A u s g a n g s p o s i t i o n ∗/
12
setCurrentPosition ( start ) ;
13 /∗ L o k a l i s i e r e das Glas und f a h r e zu d e s s e n P o s i t i o n ∗/
14
move ( g ) ;
15 /∗ G r e i f e das Glas ∗/
16
grip (g) ;
17 /∗ L o k a l i s i e r e den Wasserhahn und f a h r e zu d e s s e n P o s i t i o n ∗/
18
move ( t ) ;
19 /∗ S t e l l e das Glas ab ∗/
20
ungrip ( g ) ;
21 /∗ Benutze den Wasserhahn mit dem Glas , um e s zu f u e l l e n ∗/
22
f i l l ( Tap1 , G l a s s 1 ) ;
23 /∗ G r e i f e das Glas ∗/
24
grip (g) ;
25 /∗ Fahre zum Ausgangspunkt z u r u e c k ∗/
26
move ( s t a r t ) ;
27 /∗ S t e l l e das Glas ab ∗/
28
ungrip ( g ) ;
29 }
Listing 5: fetchWater.rtdl
Um diese Task ausführen zu können, muss ein Roboter die folgenden Tasks oder
Aktionen ausführen können:
• setCurrentPosition(Waypoint w);
Der Roboter merkt sich die aktuelle Position in Form eines Wegpunktes w.
• move(entity e);
Der Roboter lokalisiert die Position einer Entität e und bewegt sich zu dieser
hin. Wenn e nicht gefunden oder nicht erreicht werden kann, scheitert diese
Task.
• grip(entity e);
Der Roboter greift die greifbare Entität e. Wenn e nicht gegriffen werden kann,
scheitert diese Task.
• ungrip(entity e);
Der Roboter setzt die Entität e, die er in einem seiner Greifarme hält, an der
aktuellen Position ab. Wenn e nicht abgesetzt werden kann, scheitert diese
Task.
53
Kapitel 6: Robotic Task Definition Language
• fill(source s, container c);
Der Roboter befindet sich an einer WorldPosition, an der sich zusätzlich
ein WorldObject abgeleitet von source und ein WorldObject abgeleitet von
container befinden. Der Roboter lässt dann beide WorldObjects so interagieren, dass das von container abgeleitete WorldObject mit dem Ausstoß des
von source abgeleiteten WorldObjects gefüllt wird. In diesem Beispiel ist t
abgeleitet von source und g abgeleitet von container.
• wait(int timeframes);
Der Robooter wartet so viele vordefinierte Zeitrahmen ab, wie der Task übergeben wurden. Diese Task kann nicht scheitern.
• check(entity e, condition c);
Der Roboter nutzt seine Sensoren um den Wahrheitswert der Bedingung c
einer Entität e zu prüfen. Ist die Bedingung nicht erfüllt, so liefert check ein
false zurück.
Dieses Beispiel, jedoch in der XML-Syntax definiert, befindet sich in den Quelltexten
im Anhang in Kapitel 20.
54
Kapitel 7: Roboter Simulationsumgebung
7
7.1
Roboter Simulationsumgebung
Einleitung
Die Roboter-Simulationsumgebung bildet den praktischen Teil dieser Masterarbeit.
Sie besteht aus einer einfachen Robotersimulation und einem RTDL-Parser. Die
Simulationsumgebung hat den Zweck, das Verhalten eines virtuelles Roboters zu
verdeutlichen, der eine in der RTDL spezifizierte Task ausführt. Die eigentliche Simulation ist auf Textnachrichten beschränkt, welcher der virtuelle Roboter ausgibt
anstatt reale Aktionen auszuführen. Durch den Einsatz einer Simulationsumgebung
ist es möglich, sowohl während der Entwicklung, als auch nach Fertigstellung der
RTDL-Spezifikation die Auswirkungen von Tasks zu verdeutlichen.
7.2
Simulationsumgebung
Im folgenden wird der Aufbau der Simulationsumgebung beschrieben. Sie setzt sich
zusammen aus einem Weltmodell und einem Roboter der als die Summe seiner
Sensor-, Aktor- und Kommunikationskomponenten gesehen wird.
7.2.1
Weltmodell
Das verwendete Weltmodell repräsentiert einen dreidimensionalen Raum, welcher
aus diskreten Orten, den sogenannten WorldLocations, besteht. Innerhalb des Weltmodells befinden sich Weltobjekte, die sogenannten WorldObjects. Der virtuelle
Roboter basiert ebenfalls auf einem WorldObject.
Die grobmaschige Einteilung der Welt in Form eines dreidimensionalen Gitters wurde
gewählt, da die Simulationsumgebung lediglich als Hilfsmittel für die Entwicklung
der RTDL gedacht ist. Zwar würde eine realistischere Simulationsumgebung gerade
bei komplexen Tasks einen größeren Nutzen bieten, sie wäre allerdings auch mit
einem erheblich größeren Entwicklungsaufwand verbunden, was letztendlich sogar
die Entwicklung der RTDL in den Schatten stellen würde.
Im folgenden wird das verwendete Weltmodell anhand von Abbildung 9 erläutert:
Das Weltmodell der Simulationsumgebung besteht aus diskreten Punkten, die einen
dreidimensionalen Raum aufspannen. Zur besseren Übersicht wird in Abbildung 9
55
Kapitel 7: Roboter Simulationsumgebung
Abbildung 9: RobotSim Weltmodell
lediglich eine zweidimensionale Fläche zur Erläuterung verwendet.
Jeder Punkt in der Abbildung entspricht einer WorldLocation, also einem eindeutigen Ort innerhalb der Welt. Jede WorldLocation besitzt eine eindeutige dreidimensionale Koordinate. An jeder WorldLocation können sich beliebig viele WorldObjects befinden. In der Abbildung sind diese als Kreise dargestellt. Es besteht
eine Beziehung mit einer 1:n Kardinalität zwischen den Orten und den Objekten.
Das bedeutet, dass ein WorldObject sich lediglich an genau einer WorldLocation
befinden kann, jede WorldLocation jedoch 0 bis n WorldObjects beinhalten kann.
Ein WorldObject entspricht einer Entität in der simulierten Welt. Jedes WorldObject wird durch einen eindeutigen Namen referenziert und besitzt einen definierten
Typen, entsprechend dem Entitätstypen in der RTDL.
7.2.2
Sensoren, Aktoren und Kommunikationsgeräte
Im Rahmen der Simulationsumgebung werden Fehler in Sensordaten weder betrachtet noch modelliert. Der Grund hierfür ist, dass die Simulationsumgebung bewusst
einfach gehalten werden soll.
In der hier verwendeten Simulationsumgebung werden Aktionen der Aktoren als
56
Kapitel 7: Roboter Simulationsumgebung
Meldungen dargestellt, die anzeigen, ob die gewünschte Aktion erfolgreich durchgeführt wurde oder nicht.
Diese Simulationsumgebung definiert in der aktuellen Version keine Kommunikationsgeräte, da dies für die Entwicklung der RTDL keine Relevanz besitzt.
7.3
Implementierung der Simulationsumgebung
Die Roboter-Simulationsumgebung ist in der Programmiersprache Java implementiert. Bei der Entwicklung wurde Wert auf eine einfache Erweiterbarkeit gelegt. In
ihrer Basisversion verfügt ein simulierter Roboter über die Möglichkeiten sich in einer Welt zwischen den einzelnen WorldLocations zu bewegen. Ferner wurden Wände
implementiert, die einem Roboter das beschreiten bestimmter WorldLocations verbieten. Die Simulationsumgebung verfügt derzeit über keine Benutzerschnittstelle.
Wenn ein bestimmter Aufbau der Welt erzeugt werden soll, so müssen die einzelnen
WorldObjects von Hand mit Hilfe von definierten Java-Methoden an die entsprechenden WorldLocations gesetzt werden. Dies geschieht im Quelltext der Simulationsumgebung. Hiernach muss das Programm neu kompiliert werden, was jedoch
nur wenige Sekunden dauert. Die Entscheidung auf eine Benutzeroberfläche zu verzichten, ist begründet in dem Aufwand diese ständig mit der Simulationsumgebung
anzupassen, sofern man diese erweitert.
Um nun die Benutzerfreundlichkeit etwas zu erhöhen wurde eine Funktion in das
Programm übernommen, die es erlaubt, den Aufbau einer definierten Welt in eine
XML-Datei zu sichern, die später auch wieder geladen werden kann.
Für die Implementierung der Basisversion der Roboter-Simulationsumgebung wurden folgende Klassen erzeugt:
• WorldPosition.java
• WorldLocation.java
• WorldObject.java
• World.java
• Wall.java
• Robot.java
57
Kapitel 7: Roboter Simulationsumgebung
• RobotSim.java
• MyXmlParser.java
• Main.java
Die wichtigsten Implementierungsdetails der einzelnen Klassen werden in den folgenden Unterkapiteln erläutert.
7.3.1
WorldPosition
Eine WorldPosition ist eine einfache Klasse, um die Position innerhalb einer Welt
durch eine X-, Y- und Z-Koordinate zu bestimmen. Die Koordinatenwerte sind als
Datentyp long implementiert, wodurch die Welt lediglich aus diskreten Punkten
besteht.
Neben den obligatorischen Getter- und Setter-Methoden sind die folgenden Methoden erwähnenswert:
• public long getOffsetX(WorldPosition wp)
Diese Methode erhält als Argument ein WorldPosition-Objekt und gibt den
Abstand der X-Koordinaten der aktuellen zur übergebenen WorldPosition
zurück. Wenn die übergebene WorldPosition einen höheren oder den gleichen X-Koordinatenwert besitzt, wie die aktuelle WorldPosition, so ist der
Rückgabewert positiv beziehungsweise Null, ansonsten ist er negativ.
• public long getOffsetY(WorldPosition wp)
analog zu public long getOffsetX(WorldPosition wp)
• public long getOffsetZ(WorldPosition wp)
analog zu public long getOffsetX(WorldPosition wp)
• public boolean equals(WorldPosition wp)
Diese Methode gibt true zurück, wenn alle drei Koordinatenwerte der aktuellen WorldPosition mit denen der übergebenen WorldPosition übereinstimmen,
ansonsten wird false zurückgegeben.
58
Kapitel 7: Roboter Simulationsumgebung
7.3.2
WorldObject
Die Klasse WorldObject bildet die Basisklasse für alle Typen von Weltobjekten,
die innerhalb dieser Simulationsumgebung definiert sind. Jedes WorldObject besitzt
einen eindeutigen Namen und eine Reihe von Prädikaten. In der Basisversion sind
folgende Prädikate vordefiniert:
• protected boolean canMove = false
Dieses Prädikat legt fest, ob ein WorldObject in der Lage ist sich selbstständig
innerhalb der Welt zu bewegen.
• protected boolean grippeable = false
Dieses Prädikat legt fest, ob ein WorldObject greifbar ist.
• protected boolean passable = true
Dieses Prädikat legt fest, ob ein WorldObject durch ein sich bewegendes Objekt passierbar ist (true), oder ob es sich um ein Hindernis handelt (false).
In der Klasse WorldObject können weitere Prädikate definiert werden, sollte dies für
die Implementierung eines neuen WorldObject Typs notwendig sein. Ferner werden
relevante Prädikate in Ableitungen von WorldObjects überschrieben.
Neben den obligatorischen Getter- und Setter-Methoden gibt es weitere relevante
Methoden:
• public String getObjectType()
Diese Methode liefert den Typ eines abgeleiteten WorldObjects als String
zurück.
Darüber hinaus können in dieser Klasse Platzhalter-Methoden für jene Methoden definiert werden, die in abgeleiteten WorldObjects implementiert wurden. Ein Beispiel
hierfür ist die Methode public boolean move(World w, int x, int y, int z).
Durch den Aufruf dieser Methode eines abgeleiteten WorldObject soll sich dieses in
der Welt w an die WorldLocation bewegen, die durch die übergebenen X-, Y- und
Z-Koordinaten spezifiziert ist. Da der Standardwert für das Prädikat canMove allerdings false ist, muss im abgeleiteten WorldObject sowohl dieses Prädikat auf true
59
Kapitel 7: Roboter Simulationsumgebung
gesetzt als auch diese Methode überschreiben werden , so dass eine Bewegung innerhalb der Welt möglich wird. Für alle anderen abgeleiteten WorldObjects wird die
Methode der Oberklasse WorldObject aufgerufen, die lediglich eine Fehlermeldung
ausgibt, dass sich das aktuelle Objekt nicht innerhalb der Welt bewegen kann.
7.3.3
Wall
Die Klasse Wall ist eine einfache Ableitung der Klasse WorldObject und als Unterklasse von WorldObject definiert. Der Konstruktor Wall(String objectName)
erzeugt ein Objekt der Klasse Wall, setzt den Objektnamen entsprechend dem Argument und setzt das Prädikat passable auf false, wodurch eine Wall zu einem
Hindernis wird.
7.3.4
Waypoint
Die Klasse Waypoint ist eine weitere einfache Ableitung der Klasse WorldObject.
Der Konstruktor Waypoint(String objectName) erzeugt ein Objekt der Klasse
Waypoint und setzt den Objektnamen entsprechend dem Argument. Die Klasse
Waypoint repräsentiert einen Wegpunkt in der Welt. Ein Wegpunkt bezeichnet einen
benannten Ort.
7.3.5
Robot
Im Vergleich zur Klasse Wall ist die Klasse Robot eine ungleich kompliziertere Ableitung der Oberklasse WorldObject. In der Basisversion implementiert die Klasse
Robot einen Roboter, der in der Lage ist, sich innerhalb der Welt frei zu bewegen,
sofern er nicht auf Hindernisse stößt.
Ein Roboter verfügt wie jedes WorldObject über einen eindeutigen Namen. Zusätzlich
ist eine Blickrichtung implementiert, die an die einfache Welt aus diskreten Punkten
angepasst ist. So kann ein Roboter entweder nach Norden, Süden, Osten, Westen,
Oben oder Unten schauen. Die Änderung der Blickrichtung ist jederzeit über den
Aufruf entsprechender Methoden möglich.
In der Basisversion der Simulationsumgebung ist die wichtigste Fähigkeit des Roboters sich in der Welt zu bewegen. Hierzu wurde die Methode public boolean
move(World w, int x, int y, int z) der Oberklasse WorldObjects entsprechend
60
Kapitel 7: Roboter Simulationsumgebung
angepasst. Diese Methode verwendet einen sehr einfachen Algorithmus, um von
der aktuellen Position zu einer Zielposition zu gelangen. Alle weiteren Methoden
in der Basisversion dienen als Hilfsmethoden für die Methode public boolean
move(World w, int x, int y, int z).
Der Algorithmus bestimmt zunächst die Differenz der X-Koordinaten der aktuellen
und der Zielposition. Dann bewegt sich der Roboter so lange entlang der X-Achse bis
die Koordinaten übereinstimmen oder er auf ein unpassierbares Hindernis gestoßen
ist. Das gleiche wiederholt der Roboter dann entlang der Y- und dann entlang der
Z-Achse. In einem Raum ohne Hindernisse erreicht der Roboter stets sein Ziel, sofern
das Ziel innerhalb der definierten Welt liegt. Beim Vorhandensein von Hindernissen
zeigt der einfache Algorithmus sehr schnell seine Schwächen, da er in vielen Szenarien
den Zielpunkt oftmals nicht erreicht, obwohl das über einen Umweg möglich gewesen
wäre. Die offene Architektur der Simulationsumgebung erlaubt es jedoch, diesen
Algorithmus jederzeit durch einen besseren zu ersetzen.
7.3.6
WorldLocation
Eine WorldLocation bezeichnet einen eindeutigen Ort innerhalb der Welt. Die Position einer WorldLocation wird durch ein WorldPosition Objekt festgelegt. Darüber
hinaus verfügt eine WorldLocation über eine HashMap in welcher die WorldObjects,
die sich an diesem Ort befinden, über ihren eindeutigen Namen referenziert sind.
Neben den obligatorischen Getter- und Setter-Methoden sind die folgenden Methoden erwähnenswert:
• public void removeWorldObject(String name)
Diese Methode entfernt das WorldObject mit dem eindeutigen Namen name.
• public boolean isPassable()
Diese Methode liefert false zurück, wenn sich an diesem Ort mindestens ein
WorldObject befindet, dass nicht passierbar ist, ansonsten gibt sie true zurück.
7.3.7
World
ie Klasse World repräsentiert die Welt der Simulationsumgebung. Der Konstruktor
World(int x, int y, int z) erzeugt ein Java-Objekt vom Typ World. Die Argu61
Kapitel 7: Roboter Simulationsumgebung
mente int x, int y und int z bestimmen hierbei die Ausdehnung der Welt entlang
der jeweilige Koordinatenachsen. Jedes Argument muss mindestens den Wert 1 besitzen, da die Welt sonst nicht erzeugt werden kann.
Innerhalb einer Welt befinden sich alle WorldLocations in Form eines dreidimensionalen Arrays. Über die Koordinaten der Position ist dann ein direkter Zugriff auf
das entsprechende Objekt im dreidimensionalen Array aller WorldObjects möglich.
Ferner bietet die Klasse World einen vereinfachten Zugriff auf alle WorldObjects
in allen WorldLocations innerhalb der Welt über deren eindeutigen Namen. Dies
wird durch die Verwendung einer HashMap, die zu dem eindeutigen Namen eines
WorldObjects dessen Position innerhalb der Welt ablegt, erreicht.
Im folgenden sind die wichtigsten Methoden der Klasse World aufgeführt:
• public WorldObject getWorldObjectByName(String name)
Gibt das WorldObject, das durch den übergebenen Namen referenziert wird,
zurück.
• public String getWorldObjectType(String name)
Gibt den Typ des WorldObjects, das durch den übergebenen Namen referenziert wird, zurück. Der Typ bezeichnet hierbei den Klassennamen der von
WorldObject abgeleiteten Klasse.
• public boolean removeWorldObjectByName(String name)
Entfernt das WorldObject, das durch den übergebenen Namen referenziert
wird, aus der Welt.
• public boolean contains(String name)
Prüft, ob ein WorldObject mit dem Namen name in der Welt existiert.
• public String[] getWorldObjectNames()
Gibt die Namen aller in der Welt befindlichen WorldObjects als String-Array
zurück.
7.3.8
RobotSim
Die Klasse RobotSim bildet die eigentlich Simulationsumgebung ab. Diese Klasse
ist hauptsächlich ein Wrapper um ein Java-Objekt vom Typ World mit Methoden,
62
Kapitel 7: Roboter Simulationsumgebung
die den Zugriff auf die Welt vereinfachen.
• public boolean createWorldObject(String type, String name, int x,
int y, int z)
Diese Methode erzeugt ein Objekt der Klasse type und dem Namen name an
der Position in der Welt, die durch die Koordinaten x, y und z spezifiziert wird.
Der Typ type ist hierbei eine definierte Unterklasse der Klasse WorldObject.
• public boolean createRobot(String RobotName, int x, int y, int z)
Diese Methode entspricht einem Aufruf der Methode
public boolean createWorldObject(String type, String name, int x,
int y, int z) mit Type Robot.
• public WorldObject getObject(String name)
Diese Methode gibt Zugriff auf das WorldObject, dass durch name referenziert
wird.
• public boolean removeObject(String name)
Diese Methode entfernt das WorldObject, das durch name referenziert wird,
aus der Welt.
• public boolean place(String name, int x, int y, int z)
Diese Methode platziert das WorldObject, das durch name referenziert wird,
direkt an die Position, die durch x, y und z gegeben ist.
• public boolean move(String name, String destination)
Diese Methode ruft die Methode public boolean move(World w, int x,
int y, int z) des WorldObjects, das durch name referenziert wird, mit den
Argumenten x, y und z auf. Die Argumente x, y und z ergeben sich aus den
Koordinaten, an denen sich das WorldObject mit dem Namen aus der Variablen destination befindet.
• public String toXmlString()
Diese Methode erzeugt auf der Konsole die Ausgabe eines aktuellen Abbildes
der Welt mit ihren Dimensionen und allen WorldLocations inklusive aller in
ihnen enthaltenen WorldObjects im XML-Format.
63
Kapitel 7: Roboter Simulationsumgebung
7.3.9
MyXmlParser
Diese Klasse ermöglicht es den Zustand einer Welt, wie er mit der Methode public
String toXmlString() erzeugt wurde, aus einer Textdatei zu laden und die Welt
entsprechend zu rekonstruieren. Der Konstruktor MyXmlParser(String filename)
bekommt hierzu als filename den Pfad zu der Datei übergeben, in welcher der
Zustand der Welt als XML-Beschreibung abgelegt worden ist. Das Parsen der Datei
wird durch einen angepassten XMLStreamreader erledigt.
7.3.10
Main
Die Klasse Main bildet den Eingabeteil der Benutzerschnittstelle der Roboter-Simulationsumgebung ab. In ihr wird ein RobotSim- und ein MyXmlParser-Objekt definiert. In der ausführbaren Methode public static void main(String[] args)
kann dann entweder die Simulationsumgebung durch den Aufruf von Methoden der
Klasse RobotSim manuell erzeugt und gesichert werden oder alternativ durch Aufruf des MyXmlParsers aus einer bereits bestehenden Umgebungsbeschreibung rekonstruiert werden.
Manuelle Erzeugung der Simulationsumgebung Das folgende Beispiel der
Methode public static void main(String[] args) erzeugt ein neues RobotSim
Objekt mit den Dimensionen x=10, y=10, z=1. Innerhalb dieser Simulation wird
ein WorldObject mit eben jenen Dimensionen automatisch erzeugt. Danach wird
ein Roboter namens “Robot1” an der Position [0, 0, 0] erzeugt, der sich in einem
weiteren Schritt zur Position [5, 5, 0] bewegen soll.
Anschließend soll der aktuelle Zustand der Umgebung als XML-Beschreibung auf
die Konsole ausgegeben werden.
public static void main(String[] args) {
// Erzeugung der Simulationsumgebung
rs = new RobotSim(10, 10, 1);
// Erzeugung eines Roboters
rs.createRobot("Robot1", 0, 0, 0);
// Bewegung des Roboters zu Position [5, 5, 0]
64
Kapitel 7: Roboter Simulationsumgebung
rs.move("Robot1", 5, 5, 0);
// Sicherung des aktuellen Zustands der Welt.
echo(rs.toXmlString());
}
Der gesicherte Zustand der Welt sieht dann wie folgt aus:
<world>
<sizex>10</sizex>
<sizey>10</sizey>
<sizez>1</sizez>
<objects>
<object>
<name>Robot1</name>
<type>Robot</type>
<x>5</x>
<y>5</y>
<z>0</z>
</object>
</objects>
</world>
Rekonstruktion der Simulationsumgebung Das folgende Beispiel der Methode
public static void main(String[] args) lädt eine bereits definierte Simulationsumgebung aus der lokalen Datei ‘‘C:\RobotSim.xml’’ auf einem WindowsSystem:
public static void main(String[] args) {
// Beispiel Import
try {
MyXmlParser parser = new MyXmlParser("C:\\RobotSim.xml");
rs = parser.parse(rs);
} catch (Exception e) {
System.err.println("ERROR beim Parsen!");
}
65
Kapitel 7: Roboter Simulationsumgebung
// Manipulation der rekonstruierten Umgebung
// ...
}
Hierbei wird ein neuer MyXmlParser mit der Datei C:\RobotSim.xml erzeugt und
gestartet. Zu beachten ist, dass alle Blackslashes “\” im Windows-Pfad durch ein
weiteres Backslash-Zeichen escapet werden müssen.
7.4
Erweiterung der Simulationsumgebung
Die Roboter-Simulationsumgebung wurde im Hinblick auf einfache Erweiterbarkeit
entworfen. Um das Beispiel aus Kapitel 6.8 umsetzen zu können, muss die Simulationsumgebung um mehrere Bestandteile erweitert werden. In diesem Kapitel werden
die Erweiterungen an Hand dieses Beispiels erläutert.
Die Task fetchWater(DrinkingGlass glass, Tap tap) besteht aus den folgenden
Aktionen:
1. moveTo(posGlass)
2. grip(glass)
3. moveTo(posTap)
4. ungrip(glass)
5. fill(tap, glass)
6. grip(glass)
7. moveTo(posStart)
Hierbei bezeichnet posGlass die Position von einem Glas glass in der Welt, posTap
die Position eines Wasserhahns tap und posStart die Startposition des Roboters. Da
die Task moveTo(position p) bereits in der Basisversion der Simulationsumgebung
implementiert ist, ist hier keine Erweiterung notwendig.
Im folgenden werden die hierzu notwendigen Erweiterungen beschrieben. Zunächst
werden die neuen Weltobjekt Typen definiert und dann in die Simulationsumgebung
integriert.
66
Kapitel 7: Roboter Simulationsumgebung
7.4.1
DrinkingGlass
Die Klasse DrinkingGlass repräsentiert ein Wasserglas in der Simulationsumgebung.
Der Konstruktor DrinkingGlass(String objectName) setzt beim Instanzieren den
Objektnamen und einige Prädikate:
• super.isContainer = true;
Dieses Prädikat gibt an, ob es sich bei dem WorldObject um einen Container
handelt, der etwas beinhalten kann.
• super.isGrippeable = true;
Dieses Prädikat gibt an, ob das WorldObject greifbar ist.
Neben dem Objektnamen und den Prädikaten wird zusätzlich eine neue interne
Variable this.contentType = new String() deklariert. Der contentType gibt an,
mit welcher Art von Inhalt ein Container-artiges WorldObject gefüllt ist.
Die Klasse DrinkingGlass definiert zusätzlich zwei neue Methoden:
• public boolean fillContainer(World w, String source)
Diese Methode füllt das DrinkingGlass mit dem Erzeugnis einer Quelle source.
• public boolean emptyContainer()
Diese Methode leert das DrinkingGlass.
Diese Klasse wurde direkt von der Oberklasse WorldObject abgeleitet. Die nächsten
beiden Kapitel geben ein Beispiel, wie ein Weltobjekt indirekt von der Oberklasse
WorldObject abgeleitet definiert werden kann
7.4.2
Source
Die Klasse Source repräsentiert eine Quelle, die einen gewissen Ausstoß produziert. Der Konstruktor Source(String objectName, String sourceType) setzt
zum einen den Objektnamen der Source und definiert zusätzlich das Prädikat isSource,
das angibt, ob es sich bei dem WorldObject um eine Source handelt und die Variable
sourceType, welche die Art des Quellenausstoßes bezeichnet.
67
Kapitel 7: Roboter Simulationsumgebung
7.4.3
Tap
Die Klasse Tap repräsentiert einen Wasserhahn in der Simulationsumgebung. Der
Tap ist abgeleitet von der Oberklasse Source, die ihrerseits von der Oberklasse WorldObject abgeleitet ist. Der Konstruktor public Tap(String objectName) setzt
den Objektnamen und den Quellentyp hartkodiert auf water.
7.4.4
Robot
Um mit den Objekten der neu definierten Klassen interagieren zu können, muss der
Roboter erweitert werden.
Im ersten Schritt erhält der Roboter einen Arm, der ein greifbaren WorldObject
fassen kann:
private WorldObject arm;
Des weiteren erhält der Roboter neue Methoden um greifbare WorldObjects greifen
und wieder abstellen zu können:
• public boolean grip(World w, String name)
Diese Methode lässt den Roboter ein Object name greifen, wenn dieses das
Prädikat isGrippeable erfüllt und wenn der Roboter sich an der selben Position wie das benannte Objekt befindet.
• public boolean ungrip(World w, String name)
Mit dieser Methode stellt der Roboter das mit name benannte Objekt an seiner
aktuellen Position ab, sofern es sich beim Methodenaufruf in seinem Greifarm
befindet.
7.4.5
WorldObject
Da in der Definition der Klassen DrinkingGlass, Source und Tap neue Prädikate
und Methoden definiert worden sind, müssen diese in die Klasse WorldObject übernommen werden.
Die zusätzlichen Prädikate werden einfach zu den bereits existierenden Prädikaten
hinzugefügt:
68
Kapitel 7: Roboter Simulationsumgebung
/* Die bereits definierten Prädikate */
protected boolean canMove = false;
protected boolean isGrippeable = false;
protected boolean isPassable = true;
/* Die neu hinzugefügen Prädikate */
protected boolean isContainer = false;
protected boolean isSource = false;
Die zusätzlichen Methoden grip(World w, String name) und ungrip(World w,
String name) werden als Dummy-Methoden implementiert, die lediglich eine Fehlermeldung ausgeben.
7.4.6
RobotSim
Um nun einen einheitlichen Zugriff auf die Erweiterungen der Roboter-Simulationsumgebung zu erreichen muss die RobotSim Klasse noch angepasst werden.
Zunächst muss die Methode public boolean createWorldObject(String type,
String name, int x, int y, int z) angepasst werden, so dass auch WorldObjects von Typ DrinkingGlass und Tap instanziert werden können.
Danach müssen die folgenden Methoden in der RobotSim Klasse definiert werden:
• public boolean grip(String agent, String entity)
Diese Methode lässt einen agent, zum Beispiel einen Roboter, ein WorldObject
entity greifen, wenn entity greifbar ist und sich agent an der selben Position
wie entity befindet.
• public boolean ungrip(String agent, String entity)
Diese Methode lässt einen agent, zum Beispiel einen Roboter, ein WorldObject entity an seiner aktuellen Position absetzen, sofern sich entity zum
Zeitpunkt des Methodenaufrufs in seinem Greifarm befindet.
• public boolean fill(String agent, String source, String container)
Diese Methode lässt einen agent, zum Beispiel einen Roboter, einen Container
container mit dem Ausstoß einer Quelle source füllen. Hierzu müssen sich
agent, source und container an der selben Position befinden.
69
Kapitel 7: Roboter Simulationsumgebung
7.4.7
Testen der Erweiterungen
Zum Testen der Erweiterungen kann man das Beispiel fetchWater(DrinkingGlass
Glass1, Tap Tap1) aus Kapitel 6.8 als Reihe von Anweisungen in die Klasse Main
der Roboter-Simulationsumgebung eingeben.
Für dieses Beispiel wird eine Welt mit den Dimensionen [10, 10, 1] erzeugt. Danach
werden verschiedene WorldObjects gesetzt:
• Ein Roboter Robot1 an die Position [0, 0, 0].
• Ein Tap Tap1 an die Position [3, 3, 0].
• Ein DrinkingGlass Glass1 an die Position [6, 6, 0].
Danach lässt man Robot1 zu Glass1 fahren, es greifen und zu Tap1 fahren. An
Tap1 angekommen, wird Glass1 abgesetzt und von Robot1 mit dem Ausstoß von
Tap1 gefüllt. Danach greift Robot1 das Objekt Glass1 erneut und fährt es zur
Startposition [0, 0, 0] wo er Glass1 absetzt.
Als Implementierung der Methode public static void main(String[] args) ergibt das den folgenden Quellcode:
public static void main(String[] args) {
// Erzeugung der Simulationsumgebung
rs = new RobotSim(10, 10, 1);
// Erzeugen eines Roboters
rs.createRobot("Robot1", 0, 0, 0);
// Erzeugen eines Waypoints am Startpunkt [0, 0, 0]
rs.createWorldObject("Waypoint", "Start", 0, 0, 0);
// Erzeugen eines Wasserhahns an Position [3, 3, 0]
rs.createWorldObject("Tap", "Tap1", 3, 3, 0);
// Positionieren eines Wasserglases an Position [6, 6, 0]
rs.createWorldObject("DrinkingGlass", "Glass1", 6, 6, 0);
70
Kapitel 7: Roboter Simulationsumgebung
// Bewegung des Roboters zu Position [6, 6, 0]
rs.move("Robot1", "Glass1");
// Greifen von Glass1
rs.grip("Robot1", "Glass1");
// Zu Tap1 bewegen
rs.move("Robot1", "Tap1");
// Glass1 abstellen
rs.ungrip("Robot1", "Glass1");
// Glass1 mit Ausstoss von Tap1 fuellen
rs.fill("Robot1", "Tap1", "Glass1");
// Greifen von Glass1
rs.grip("Robot1", "Glass1");
// Zur Ausgangsposition fahren
rs.move("Robot1", "Start");
// Glass1 absetzen
rs.ungrip("Robot1", "Glass1");
}
Nach dem Kompilieren und Ausführen der Simulation wurden folgende Ausgaben
auf der Konsole ausgegeben:
Robot1 has moved to [6,6,0].
Robot1 has gripped Glass1.
Robot1 has moved to [3,3,0].
Robot1 has ungripped Glass1.
Robot1 fills Glass1 at Tap1.
Glass1 is now filled with water.
Robot1 has gripped Glass1.
Robot1 has moved to [0,0,0].
Robot1 has ungripped Glass1.
71
Kapitel 7: Roboter Simulationsumgebung
7.5
RTDL Parser
Nachdem die Roboter Simulationsumgebung durch die in Kapitel 7.4 beschriebenen
Änderungen erweitert worden ist, ist sie in der Lage das Beispiel fetchWater(Glass
g, Tap t) aus Kapitel 6.8 als eine Serie von Kommandos der Simulationsumgebung
zu beschreiben und auszuführen, wie in Kapitel 7.4.7 gezeigt.
Der letzte noch verbleibende notwendige Schritt zu einer RTDL-fähigen Roboter
Simulationsumgebung ist die Verschmelzung von RTDL und Simulationsumgebung.
Dies soll durch die Integration eines RTDL Parsers in die Roboter Simulationsumgebung geschehen.
7.5.1
Klasse RtdlParser
Um den RTDL Parser zu implementieren, wurde eine neue Klasse RtdlParser erzeugt. Der Konstruktor RtdlParser(String filename) erzeugt ein neues RtdlParser Objekt und erhält als Argument den Pfad zu einer RTDL Taskbeschreibung
im XML-Format übergeben.
Intern besteht die Klasse RtdlParser aus einer angepassten Instanz eines XMLStreamReaders, ähnlich der Klasse MyXmlParser aus Kapitel 7.3.9. Die wichtigste Methode
des RtdlParsers ist die Methode public RobotSim parse(RobotSim rs, String
robot). Diese Methode parst die im Konstruktor übergebene Taskbeschreibung und
führt die Aktionen als jener Roboter, der durch das Argument robot übergeben
wird, in der übergebenen Instanz der Klasse RobotSim aus. Im Anschluss an diesen
Vorgang wird die modifizierte RobotSim Instanz zurückgegeben.
7.5.2
Parsen einer Taskbeschreibung
Der in den Klassen RtdlParser und MyXMLParser verwendete XMLStreamReader
agiert ereignisgesteuert. Der Parser durchläuft ein XML-Dokument und erzeugt bei
jedem Auftreten eines XML-Elements ein Event. Die für den RTDL Parser wichtigsten Events sind der Beginn START ELEMENT und das Ende END ELEMENT jener
XML-Elemente.
Die Validität einer Taskbeschreibung muss derzeit noch durch den Benutzer festgestellt werden, da aus Zeitmangel auf die Implementierung eines XML Validierers in
72
Kapitel 7: Roboter Simulationsumgebung
den RTDL Parser verzichtet wurde.
Der Parser prüft zunächst, ob das Attribut version des rtdl Elements den Wert 1.0
hat, wenn nicht wird die Ausführung der Simulationsumgebung beendet.
Als zweites wird beim Betreten eines task Elements dessen Attribute name ausgewertet und zwischengespeichert.
Im dritten Schritt werden Aktionen, gegeben durch action Elemente, ausgewertet.
Zunächst wird der Name einer Aktion aus dem name Element zwischengespeichert.
Danach werden die Argumente der Aktion, gegeben durch arg Elemente, ausgewertet und in einem String Array zwischengespeichert. Beim Verlassen eines action
Elements wird auf Basis des action Namens ein entsprechendes Kommando in der
übergebenen RobotSim Klasse ausgeführt. Die Argumente der action werden als
Argumente des RobotSim Kommandos mit übergeben.
Aus Zeitmangel gegen Ende der Arbeit wurde kein vollständiger RTDL Parser geschrieben, so dass es einige Einschränkungen bei der Verwendung zu beachten gibt:
1. Der RTDL kann keine Elemente verarbeiten, die bisher nicht in diesem Kapitel
genannt wurden. Hierzu zählen:
(a) If-Konstrukte
(b) While-Schleifen
(c) Par-Konstrukte
(d) Retrycount Elemente
(e) Retry-Blöcke
2. Der RTDL Parser kann keine Entitätsdefinitionen auswerten, weswegen alle Entitäten, die bei der Ausführung von Aktionen beteiligt sind, vor der
Ausführung einer Taskbeschreibung in der RobotSim Klasse angelegt sein
müssen.
3. Der RTDL Parser kann keine Taskargumente der Taskdefinition auswerten.
Das bedeutet, dass Tasksbeschreibungen derzeit keine lokalen Entitätsnamen
verwenden dürfen, sondern nur solche, die bereits gültig in der RobotSim Klasse definiert wurden, vgl. Punkt 2.
4. Der RTDL Parser führt keine Validierung von Taskbeschreibungen gegen die
RTDL Document Type Definition durch.
73
Kapitel 7: Roboter Simulationsumgebung
5. Der RTDL Parser bricht die Ausführung einer Task nicht ab, wenn eine Aktion
innerhalb der Task scheitert, unabhängig von optional und retry Statements.
6. Der RTDL Parser kann derzeit maximal fünf Argumente je Aktion bei der
Ausführung einer Task zwischenspeichern.
74
Kapitel 8: Fazit
8
Fazit
Im Rahmen dieser Masterarbeit wurde mit der Spezifikation der Robotic Task Definition Language (RTDL) der Grundstein für eine neue Sprache der Taskbeschreibung
für mobile autonome Systeme geschaffen.
Die RTDL in ihrer jetzigen Version kann nur als Prototyp angesehen werden, da
bisher nur eine kleine Implementierung in Form der Roboter-Simulationsumgebung
existiert. Dennoch hat die RTDL das Potential durch Weiterentwicklung zu einem
einfachen und dennoch effizienten Weg der plattformunabhängigen Beschreibung
von Roboter-Tasks zu werden.
Das gleiche gilt für die Roboter-Simulationsumgebung, welche durch ihren einfachen
aber strukturierten Aufbau die Simulation von komplexeren Szenarien der RoboterSimulation in Zukunft ermöglichen könnte.
Aber auch andere interessante Aspekte, die nicht unmittelbar in die Entwicklung
der RTDL mit eingeflossen sind, wurden in dieser Arbeit betrachtet. Hier ist zum
Beispiel die Joint Architecture for Unmanned Systems (JAUS) zu nennen. JAUS ist
ein Standard, der gut geeignet ist, um die Architektur der Steuerungssoftware von
unbemannten Systemen beliebiger Art zu entwerfen und umzusetzen.
Auch wenn noch ein weiter Weg vor den Entwicklern von Robotern liegt, bis das Ziel
von selbstständig agierenden und mit Menschen kooperierenden Robotern erreicht
ist, so ist die Einführung einer plattformunabhängigen Task-Schicht dennoch einen
weiterer wichtiger Schritt hin zu diesem Ziel.
75
Kapitel A: Modellierungsansatz
A
Modellierungsansatz
(Dies ist ein Auszug aus [Tes10] Eine ausführliche Beschreibung der Capabilities
befindet sich in [JAU07a, S.17ff.]).
Der Modellierungsansatz von JAUS unterteilt sich in drei verschiedene Bereiche:
1. Functional Capabilities (FC): Was der Kunde/Benutzer tut.
2. Informational Capabilities (IC): Was der Kunde/Benutzer weiß.
3. Device Groups (DG): Womit der Kunde/Benutzer interagiert, die Schnittstellen.
Die funktionalen (FC) und informellen Fähigkeiten (IC) können mit den GeräteGruppen (DG) gekoppelt sein, jedoch wird das JAUS Domain Model diese Schnittstellen nicht spezifizieren. Diese Schnittstellen sind offene Standards und werden
entweder durch die Joint Technical Architecture (JTA) oder den Original Equipment Manufacturer (OEM) definiert.
A.1
Functional Capability (FC)
Funktionale Fähigkeiten sind eine Menge von Fähigkeiten mit ähnlichem funktionalem Zweck. Das Domain Model unterteilt die funktionalen Fähigkeiten in elf Kategorien, die festlegen, welche Funktionen das unbemannte System ausführen kann.
Die funktionalen Fähigkeiten sind jedoch nicht auf die genannten elf Kategorien
beschränkt.
1. Command Capabilities erstellen Pläne, passen Daten an, treffen Entscheidungen, weisen Aufgaben zu und behandeln unerwartete Ereignisse.
(a) Vehicle Commander
(b) Team Commander
(c) Team-of-Teams Commander
2. Maneuver Capabilities kommunizieren mit allen externen maneuvering control devices und können eine Menge von Sensoren beinhalten. Die Maneuver
Capability besitzt eine mehrschichtige Menge von intelligenten Komponenten,
die verschiedene Stufen von Manöveranweisungen akzeptieren.
76
Kapitel A: Modellierungsansatz
(a) Primitive Maneuver Capability
(b) Vector Maneuver Capability
(c) Waypoint Maneuver Capability
(d) Feature-Following Capability
(e) Leader-Follower Capability
3. Navigational Capabilities sind verantwortlich für die Pfadplanung des unbemannten Systems zwischen zwei oder mehreren geographischen Orten.
(a) Intelligent Navigation
(b) Primitive Navigation
(c) Semi-autonomous Navigation
(d) Autonomous Navigation
4. Communication Capabilities sind verantwortlich für die Behandlung der
Kommunikation zwischen dem unbemannten System und verschiedenen OCUs.
OCUs sind Operator Control Units, Steuerungseinheiten für unbemannte Systeme.
5. Payload Capabilities sind für die Aufrechterhaltung der Kontrolle und der
Statusüberwachung der Payloads zuständig.
(a) Articulation
i. Primitive Articulation
ii. Repeating-path Articulation
iii. Position and Attitude Articulation
(b) Reconnaissance/Surveillance/Target Acquisition & Identification (RSTAI)
i. Primitive RSTA-I
ii. Semi-autonomous RSTA-I
iii. Autonomous RSTA-I
(c) Weapon Payload
i. Weapon Payload Primitive Capability
ii. Area Engagement Capability
iii. Target Engagement Capability
77
Kapitel A: Modellierungsansatz
(d) Environmental Sensing
(e) Manipulation
6. Safety Capabilities sind verantwortlich für die Betriebssicherheit des unbemannten Systems.
(a) Primitive Safety Capability
(b) Intelligent Safety Capability
7. Security Capabilities verhindern den unautorisierten Zugriff auf das unbemannte System.
8. Resource Management Capabilities verwalten die wichtigsten Ressourcen
des unbemannten Systems wie zum Beispiel Treibstoff und Energie.
9. Maintenance Capabilities sind verantwortlich für die Systemwartung und
können mit externen Test-Equipments kommunizieren.
10. Training Capabilities bieten Trainingsmöglichkeiten für Anwender an.
11. Automatic Configuration Capabilities minimieren die notwendige Konfiguration des unbemannten Systems durch einen Anwender.
A.2
Informational Capability (IC)
Informale Fähigkeiten sind Gruppen von ähnlichen Informationstypen. Es handelt
sich hierbei um globale Repositories mit Systemdaten. Sie sind nach ihrem Datentyp
benannt und spezifizieren, welche Informationen das unbemannte System über sich
selbst besitzt. Die ICs stellen einen kontrollierten Zugang zu diesen Informationen
für das gesamte unbemannte System zur Verfügung.
1. Vehicle Status Capabilities sind verantwortlich für die Bereitstellung des
Fahrzeugstatus an andere Capabilities. Dies umfasst die Parameter: Position,
sichtbare und hörbare Daten, Kalender, u.a.
(a) Platform position and attitude
(b) Engine Data
2. World Model Capabilities unterhalten ein Repository an interessanten
Weltobjekten einschließlich freundlicher und feindlicher Einheiten, Hindernisse, Treppenbereiche, Karten, Routen, Wegpunkte und Aktionen.
78
Kapitel A: Modellierungsansatz
(a) Topographic layouts
(b) Building layouts and blueprints
(c) Terrain feature information
(d) Object of interest (last known and predicted location, last known and
predicted path)
3. Library Capabilities verwalten Referenzmaterial, Prozeduren und Leistungsdaten.
(a) Mission specific
i. Procedures and tactics
ii. Rules of Engagement
iii. Mission planning (assembly areas, mobility areas, avoidance areas,
potential target locations, etc.)
(b) Platform specific
i. Maintenance manuals
ii. Online help
iii. Training tutorials
iv. Vehicle capability lists
4. Log Capabilities haben die Verantwortlichkeit der Aufzeichnung von Einsatz-, Wartungs- und Trainingsdaten.
(a) System failures (vehicle and payload)
(b) Operator commands
(c) Events during mission execution
(d) Collaborative information
5. Time/Date Capabilities bieten Datums- und Zeitdienste für das unbemannte System an.
A.3
Device Groups (DG)
Gerätegruppen sind Gruppierungen von Sensoren und/oder Aktoren die für ähnliche
Funktionen verwendet werden. Spezifische Geräte werden nicht innerhalb von Gerätegruppen definiert.
79
Kapitel A: Modellierungsansatz
A.4
Übersichtsgrafik
Abbildung 10: RTDL Capabilities
80
Kapitel B: Liste ausgewählter JAUS-Komponenten
B
Liste ausgewählter JAUS-Komponenten
B.1
Command and Control Klasse
B.1.1
System Commander (ID 40)
• Koordination der Subsysteme
• Kommandierung
• Statusabfrage
• Diese Funktion kann von einem Menschen oder einer Maschine ausgefüllt werden. Bei einem Menschen gehören hierzu alle Elemente einer Benutzerschnittstelle, die zur Erbringung der Funktionalitäten dieser Komponente notwendig
sind.
B.1.2
Subsystem Commander (ID 32)
• Verantwortlich für Mission Planing
• Kommandierung, also das Übergeben von Anweisungen an das unbemannte
System.
• Statusabfrage
• Diese Funktion kann von einem Menschen oder einer Maschine ausgefüllt werden. Bei einem Menschen gehören hierzu alle Elemente einer Benutzerschnittstelle, die zur Erbringung der Funktionalitäten dieser Komponente notwendig
sind.
B.2
B.2.1
Communication
Communicator (ID 35)
• Single point of entry für jedes Subsystem
• Beinhaltet alle Data Links zu anderen Subsystemen
81
Kapitel B: Liste ausgewählter JAUS-Komponenten
B.3
Platform
B.3.1
Global Pose Sensor (ID 38)
• Bestimmung der globalen Pose (Position und Ausrichtung) der Plattform
• Werte werden angegeben in Form von Longitude (Längengrad), Latitude (Breitengrad) und Elevation (Erhöhung).
B.3.2
Local Pose Sensor (ID 41)
• Vergleichbar zum Global Pose Sensor
• Bestimmung der lokalen Pose anhand eines kartesischen Koordinatensystems
(x, y, z) angegeben in Relation zu einem definierten Referenzrahmen der Plattform.
B.3.3
Velocity State Sensor (ID 42)
• Ermittelt die aktuelle Geschwindigkeit der Plattform
• Die Geschwindigkeit wird bestimmt als die Summe der Teilgeschwindigkeiten eines definierten Punktes entlang der X-, Y- und Z-Achse des definierten
Referenzrahmens der Plattform. Die hierfür verwendeten JAUS-Nachrichten
sind:
– velocity x
– velocity y
– velocity z
• Zusätzlich kann die Änderung der Ausrichtung bzw. Deren Winkelgeschwindigkeit über die folgenden Nachrichten angegeben werden:
– omega x
– omega y
– omega z
82
Kapitel B: Liste ausgewählter JAUS-Komponenten
B.3.4
Primitive Driver (ID 33)
• Beinhaltet alle Basisfunktionen zum Fahren inklusive Hilfsmitteln.
• Der Freiheitsgrad der Fortbewegung entspricht der Bewegung und Drehung
entlang der X-, Y- und Z-Achse des definierten Referenzrahmens.
• Striktes open loop Verhalten (Steuerung), wobei keine Geschwindigkeit vorgegeben wird, da diese nicht ohne Geschwindigkeitssensor geregelt werden kann.
• Die genauen Aktoren-Kommandos sind nicht Teil der JAUS-Spezifikation.
B.3.5
Reflexive Driver (ID 43)
• Eine Art Filter vor dem Primitive Driver, bei dem Kommandos gefiltert und
modifiziert werden können. Anwendung findet dies immer dann, wenn eine
Operation die Sicherheit der Plattform gefährden könnte, zum Beispiel durch
zu hohe kommandierte Geschwindigkeiten usw.
• Es werden hierfür oftmals zusätzliche Sensoren an der Plattform angebracht,
welche die Ausführung und den Zustand einer Plattform überwachen. Auf Basis dieser Sensordaten werden die gegebenen Kommandos entsprechend modifiziert, dass die Sicherheit der Plattform nicht gefährdet wird.
• Die genaue Art der Sensoren ist nicht Teil der JAUS-Spezifikation.
B.3.6
Global Vector Driver (ID 34)
• Closed loop control (Regelung) von Richtung, Höhe und Geschwindigkeit einer
Plattform
• Die Komponente legt anhand des globlen Koordonatensystems die Änderung
der Richtung und Geschwindigkeit zum gegebenen Zielpunkt fest und gibt
diesen Befehl dann an den Primitive Driver oder Reflexive Driver.
B.3.7
Local Vector Driver (ID 44)
• Gleiche Funktion wie der Global Vector Driver unter Verwendung eines lokalen
Koordinatensystems
83
Kapitel B: Liste ausgewählter JAUS-Komponenten
• Informationen beinhalten:
– heading (Richtung)
– pitch (Neigung)
– roll (Neigung um Längst-Achse)
– speed (Geschwindigkeit)
• Verwendet Daten von folgenden Sensoren:
– Local Pose Sensor
– Velocity State Sensor
• Verwendete Nachrichten
– Set Wrench Effort
B.3.8
Global Waypoint Driver (ID 45)
• Bestimmt den neuen Wrench (Verschiebung) der Plattform aus den folgenden
Größen:
– Ziel-Wegpunkt
– gewünschte Reisegeschwindigkeit
– Pose
– aktuelle Geschwindigkeit
• Ein Wegpunkt setzt sich aus den folgenden Informationen zusammen:
– Position
– Ausrichtung
• Wenn die Plattform den letzten Wegpunkt einer Liste erreicht hat, so muss sie
in einen Standby Status übergehen.
• Verwendete Nachrichten:
– Set Global Waypoint
– Set Travel Speed
– Report Global Pose
– Report Velocity State
84
Kapitel B: Liste ausgewählter JAUS-Komponenten
B.3.9
Local Waypoint Driver (ID 46)
• Gleiche Funktionalität, wie der Global Waypoint Driver, jedoch mit einem
lokalen Koordinatensystem als Referenz.
• Verwendete Nachrichten:
– Set Local Waypoint
– Set Travel Speed
– Report Local Pose
– Report Velocity State
B.3.10
Global Path Segment Driver (ID 47)
• Closed loop Control (Regelung) von Position und Geschwindigkeit einer Plattform entlang eines festgelegten Pfades
• Der Unterschied zum Waypoint Driver liegt darin, dass der exakte Pfad zwischen zwei Wegpunkten strikt definiert ist und nicht nur aus einer generellen
Richtungsangabe besteht.
• Ein Pfad wird durch drei Punkte (P0, P1, P2) und einem Gewichtskoeffizienten
(w) bestimmt. Hierbei ist P0 oft der Startpunkt und P2 der Zielpunkt. Der
Pfad zwischen P0 und P2 wird nun so berechnet, dass der Weg zwischen P0
und P2 entlang dem gewichteten Punkt P1 verläuft. Ist w=0, fällt der Punkt
P1 aus der Gleichung heraus und der Pfad ist die direkte Verbindung zwischen
P0 und P2. Wird w¿0 gebildet, so verformt sich der Pfad zu einer Kurve die
je nach Größe von w in Richtung von P1 gekrümmt wird.
B.3.11
Local Path Segment Driver (ID 38)
• Laut Beschreibung in JAUS, gibt es keinen erkennbaren Unterschied zum Global Path Segment Driver.
B.4
B.4.1
Environment Sensor Components
Visual Sensor (ID 37)
• Steuert eine oder mehrere Kameras und deren Blickrichtungen
85
Kapitel B: Liste ausgewählter JAUS-Komponenten
• Zuständig für die Kamera-Einstellungen, Bildformate, Audio usw.
• Jeder Kamera wird ein lokales Kooridatensystem zugeordnet.
B.4.2
Range Sensor (ID 50)
• Steuert einen oder mehrere Abstandssensoren pro Komponente.
• Abstandsinformationen relativ zum lokalen Koordinatensystem der Plattform.
• Abstandswerte müssen von den Sensoren in einer festgelegten Genauigkeit
ermittelt werden.
B.4.3
World Model Vector Knowledge Store (ID 61)
• Zentrales Repository für vektorformatierte geospatiale Daten für die Elemente
aller Ebenen der JAUS-Topologie.
• Speichern und Verteilen der Daten im Vektorformat. Vektorisierte Positionsund Richtungsangaben sind speicherplatzeffizient.
• Objekte können aus Punkten, Linien, Polylinien und Polygone bestehen.
• Objekte können einen Region Buffer besitzen. Das ist eine Umgebung (angegeben in Metern) um ein Objekt herum, die es einer Plattform erlaubt sich
in die Nähe eines Objekts zu positionieren um dort Operationen ausführen zu
können.
• Verwendete Nachrichten:
– Create Vector Knowledge Store Objects
– Set Vector Knowledge Store Feature Class Metadata
– Delete vector Knowledge Store Objects
– Query Vector Knowledge Store Objects
– Query Vector Knowledge Store Feature Class Metadata
– Query Vector Knowledge Store Bounds
– Terminate Vector Knowledge Store Data Transfer
– Report Vector Knowledge Store Object(s) Creation
– Report Vector Knowledge Store Feature Class Metadata
86
Kapitel B: Liste ausgewählter JAUS-Komponenten
– Report Vector Knowledge Store Objects
– Report Vector Knowledge Store Bounds
– Report Vector Knowledge Store Data Transfer Termination
B.5
Planning Components
B.5.1
Mission Planner (keine ID)
• Missionplaner ist in der vorliegenden JAUS-Version v3.3 der Referenzarchitektur noch nicht definiert.
B.5.2
Mission Spooler (ID 36)
• Zentraler Ort für Missionspläne während der Ausführung oder kurz davor.
• Aufgabe ist die Aufteilung von Planbestandteilen in einzelne Elmente und
deren Auslieferungen an die entsprechenden Maschinenteile.
• Eine Mission ist definiert als eine Menge von JAUS-Nachrichten.
87
Kapitel C: Liste ausgewählter JAUS-Nachrichten
C
Liste ausgewählter JAUS-Nachrichten
C.1
Platform Subgroup Command Class (Code 0400-05FF)
• Code 0405h: Set Wrench Effort
• Code 0407h: Set Global Vector
• Code 0408h: Set Local Vector
• Code 040A: Set Travel Speed
• Code 040Ch: Set Global Waypoint
• Code 040Dh: Set Local Waypoint
• Code 040Fh: Set Global Path Segment
• Code 0410h: Set Local Path Segment
C.2
Platform Subgroup Query Class (Code 2400-25FF)
• Code 2402h: Query Global Pose
• Code 2403h: Query Local Pose
• Code 2404h: Query Velocity State
• Code 2405h: Query Wrench Effort
• Code 2407h: Query Global Vector
• Code 2408h: Query Local Vector
• Code 240Ah: Query Travel Speed
• Code 240Ch: Query Global Waypoint
• Code 240Dh: Query Local Waypoint
• Code 240Fh: Query Global Path Segment
• Code 2410h: Query Local Path Segment
88
Kapitel C: Liste ausgewählter JAUS-Nachrichten
C.3
Platform Subgroup Inform Class (Code 4400-45FF)
• Code 4402h: Report Global Pose
• Code 4403h: Report Local Pose
• Code 4404h: Report Velocity State
• Code 4405h: Report Wrench Effort
• Code 4407h: Report Global Vector
• Code 4408h: Report Local Vector
• Code 440Ah: Report Travel Speed
• Code 440Ch: Report Global Waypoint
• Code 440Dh: Report Local Waypoint
• Code 440Fh: Report Global Path Segment
• Code 4410h: Report Local Path Segment
89
Kapitel D: Quelltexte
D
Quelltexte
D.1
DrinkingGlass.java
1 /∗ ∗
2
∗ DrinkingGlass . java
3
∗ A drinking glass container .
4
∗
5
∗ @author Marcus Teske
6
∗/
7 package r t d l ;
8
9 public c l a s s D r i n k i n g G l a s s extends WorldObject {
10
11
private S t r i n g contentType ;
12
13
/∗ ∗
14
∗ Constructor
15
∗ @param objectName Name o f t h e d r i n k i n g g l a s s .
16
∗/
17
D r i n k i n g G l a s s ( S t r i n g objectName ) {
18
super . setObjectName ( objectName ) ;
19
super . i s C o n t a i n e r = true ;
20
super . i s G r i p p e a b l e = true ;
21
t h i s . contentType = new S t r i n g ( ) ;
22
}
23
24
/∗ ∗
25
∗ F i l l the drinking glass .
26
∗ @param w The World t h e t a k e s p l a c e i n .
27
∗ @param s o u r c e The s o u r c e t h a t f i l l s
t h i s container with i t s output
.
28
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
29
∗/
30
@Override
31
public boolean f i l l C o n t a i n e r ( World w, S t r i n g s o u r c e ) {
i f (w . getWorldObjectByName ( s o u r c e ) . i s S o u r c e ) {
32
33
S o u r c e s = ( S o u r c e ) w . getWorldObjectByName ( s o u r c e ) ;
34
t h i s . contentType = s . getSourceType ( ) ;
35
}
36
System . out . p r i n t l n ( t h i s . getObjectName ( ) + ” i s now f i l l e d with ”
37
+ contentType + ” . ” ) ;
38
39
return true ;
}
90
Kapitel D: Quelltexte
40
/∗ ∗
41
42
∗ Emptying t h e d r i n k i n g g l a s s .
43
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
44
∗/
45
@Override
46
public boolean emptyContainer ( ) {
47
t h i s . contentType = ” ” ;
48
return true ;
}
49
50 }
Listing 6: DrinkingGlass.java
D.2
Main.java
1 /∗ ∗
2
∗ Main . j a v a
3
∗ A programm t h a t i n s t a n t i a t e s a RobotSim o b j e c t and l e t ’ s t h e
programmer p l a y
4
∗ around w i t h i t .
5
∗
6
∗ @author Marcus Teske
7
∗/
8 package r t d l ;
9
10 public c l a s s Main {
11
// S i m u l a t i o n p a r a m e t e r s
12
13
14
// Anfang A t t r i b u t e
15
private s t a t i c MyXmlParser mxp ;
16
private s t a t i c RobotSim r s ;
17
private s t a t i c R t d l P a r s e r r t d l p ;
18
// Ende A t t r i b u t e
19
20
21
22
// Anfang Methoden
23
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
24
25
26
// Example f o r Import o f World
try {
mxp = new MyXmlParser ( ”C: \ \ temp \\ world . xml” ) ;
91
Kapitel D: Quelltexte
27
r s = mxp . p a r s e ( r s ) ;
28
} catch ( E x c e p t i o n e ) {
29
System . e r r . p r i n t l n ( ”ERROR beim Parsen ! ” ) ;
}
30
31
32
33
// Erzeugen d e r S im u l ati o n su m g e bu n g
34 //
r s = new RobotSim ( 1 0 , 10 , 1) ;
35
36
// Erzeugen e i n e s R o b o t e r s
37 //
r s . c r e a t e R o b o t (” Robot1 ” , 0 , 0 , 0) ;
38
39
// Erzeugen e i n e s Wasserhahns an P o s i t i o n [ 3 , 3 , 0 ]
40 //
r s . c r e a t e W o r l d O b j e c t (” Tap ” , ”Tap1 ” , 3 , 3 , 0) ;
41
42
// P o s i t i o n i e r e n e i n e s W a s s e r g l a s e s an P o s i t i o n [ 6 , 6 , 0 ]
43 //
r s . c r e a t e W o r l d O b j e c t (” D r i n k i n g G l a s s ” , ” G l a s s 1 ” , 6 , 6 , 0) ;
44
45
// Task p a r s e n und ausf à 14 hren .
46
try {
47
r t d l p = new R t d l P a r s e r ( ”C: \ \ temp \\ f e t c h W a t e r . xml” ) ;
48
r s = r t d l p . p a r s e ( r s , ” Robot1 ” ) ;
49
} catch ( E x c e p t i o n e ) {
50
System . e r r . p r i n t l n ( ”ERROR beim Parsen : \ n” + e . t o S t r i n g ( ) ) ;
51
52
}
53
54
55 //
// Bewegung d e s R o b o t e r s z u r P o s i t i o n [ 6 , 6 , 0 ]
r s . move (” Robot1 ” , ” G l a s s 1 ”) ;
56 //
57 //
r s . g r i p (” Robot1 ” , ” G l a s s 1 ”) ;
58 //
59 //
r s . move (” Robot1 ” , ”Tap1 ”) ;
60 //
61 //
r s . u n g r i p (” Robot1 ” , ” G l a s s 1 ”) ;
62 //
63 //
r s . f i l l (” Robot1 ” , ”Tap1 ” , ” G l a s s 1 ”) ;
64 //
65 //
r s . g r i p (” Robot1 ” , ” G l a s s 1 ”) ;
66 //
67 //
r s . move (” Robot1 ” , ” S t a r t ”) ;
68 //
69 //
r s . u n g r i p (” Robot1 ” , ” G l a s s 1 ”) ;
70
92
Kapitel D: Quelltexte
71
// Example f o r s a v i n g t h e World .
try {
72 //
73 //
echo ( r s . t o X m l S t r i n g ( ) ) ;
74 //
} catch ( NullPointerException e ) {
75 //
}
76
}
77
78
private s t a t i c void echo ( S t r i n g s ) {
79
80
System . out . p r i n t l n ( s ) ;
81
}
82
// Ende Methoden
83 }
Listing 7: Main.java
D.3
MyXmlparser.java
1 /∗ ∗
2
∗ MyXmlParser . j a v a
3
∗ h t t p : / /www. i k s . hs−merseburg . de /˜ u s c h r o e t / L i t e r a t u r / J a v a L i t /
JAVA Insel / j a v a i n s e l 1 5 0 0 4 . htm#m j d 0 d b b 5 3 e 7 2 e 3 b 5 3 b 0 1 1 e 1 5 c 2 0 0 5 4 0 7 8 f
4
∗
5
∗ @author Marcus Teske
6
∗/
7 package r t d l ;
8
9 import j a v a . i o . ∗ ;
10 import j a v a x . xml . stream . XMLInputFactory ;
11 import j a v a x . xml . stream . XMLStreamReader ;
12 import j a v a x . xml . stream . XMLStreamException ;
13 import j a v a x . xml . stream . XMLStreamConstants ;
14
15 public c l a s s MyXmlParser {
16
17
XMLStreamReader p a r s e r ;
18
19
/∗ P a rs e r v a r i a b l e s ∗/
20
private int s i z e X = 0 ; // h o l d s t h e s i z e a l o n g x o f t h e w o r l d .
21
private int s i z e Y = 0 ; // h o l d s t h e s i z e a l o n g x o f t h e w o r l d .
22
private int s i z e Z = 0 ; // h o l d s t h e s i z e a l o n g x o f t h e w o r l d .
23
private boolean i n O b j e c t = f a l s e ;
93
Kapitel D: Quelltexte
24
private S t r i n g name = ” ” ; // h o l d s t h e name o f t h e c u r r e n t
WorldObject .
25
private S t r i n g type = ” ” ; // h o l d s t h e t y p e o f t h e c u r r e n t
WorldObject .
26
private int x = 0 ; // h o l d s t h e x−c o o r d i n a t e o f t h e c u r r e n t
WorldObject .
27
private int y = 0 ; // h o l d s t h e y−c o o r d i n a t e o f t h e c u r r e n t
WorldObject .
28
private int z = 0 ; // h o l d s t h e z−c o o r d i n a t e o f t h e c u r r e n t
WorldObject .
29
30
MyXmlParser ( S t r i n g f i l e n a m e )
31
throws FileNotFoundException , XMLStreamException {
32
p a r s e r = XMLInputFactory . n e w I n s t a n c e ( ) . createXMLStreamReader (
33
34
new F i l e I n p u t S t r e a m ( f i l e n a m e ) ) ;
}
35
36
public RobotSim p a r s e ( RobotSim r s ) throws XMLStreamException {
37
38
39
40
41
while ( p a r s e r . hasNext ( ) ) {
switch ( p a r s e r . getEventType ( ) ) {
case XMLStreamConstants .START DOCUMENT:
break ;
42
43
case XMLStreamConstants .END DOCUMENT:
44
parser . close () ;
45
break ;
46
47
48
case XMLStreamConstants .NAMESPACE:
break ;
49
50
51
case XMLStreamConstants .START ELEMENT:
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” s i z e x ” ) ) {
52
s i z e X = I n t e g e r . p a r s e I n t ( p a r s e r . getElementText ( ) ) ;
53
}
54
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” s i z e y ” ) ) {
55
s i z e Y = I n t e g e r . p a r s e I n t ( p a r s e r . getElementText ( ) ) ;
56
}
57
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” s i z e z ” ) ) {
58
59
s i z e Z = I n t e g e r . p a r s e I n t ( p a r s e r . getElementText ( ) ) ;
}
60
61
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” o b j e c t ” ) ) {
62
System . out . p r i n t l n ( ”DEBUG: i n s i d e o b j e c t ” ) ;
94
Kapitel D: Quelltexte
63
i n O b j e c t = true ;
}
64
65
i f ( i n O b j e c t == true ) {
66
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ”name” ) ) {
67
68
name = p a r s e r . getElementText ( ) ;
} e l s e i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” type ” ) ) {
69
70
type = p a r s e r . getElementText ( ) ;
} e l s e i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ”x” ) ) {
71
72
x = I n t e g e r . p a r s e I n t ( p a r s e r . getElementText ( ) ) ;
} e l s e i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ”y” ) ) {
73
74
y = I n t e g e r . p a r s e I n t ( p a r s e r . getElementText ( ) ) ;
} e l s e i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” z ” ) ) {
75
76
z = I n t e g e r . p a r s e I n t ( p a r s e r . getElementText ( ) ) ;
}
77
78
}
79
break ;
80
81
case XMLStreamConstants .CHARACTERS:
82
break ;
83
84
case XMLStreamConstants .END ELEMENT:
85
// Check i f s i z e s a r e s e t and c r e a t e RobotSim
86
i f ( r s == null && s i z e X > 0 && s i z e Y > 0 && s i z e Z > 0 ) {
87
r s = new RobotSim ( sizeX , sizeY , s i z e Z ) ;
88
}
89
i f ( i n O b j e c t == true && p a r s e r . getLocalName ( ) . e q u a l s ( ” o b j e c t ”
)) {
90
System . out . p r i n t l n ( ”DEBUG( RobotSim ) : c r e a t e W o r l d O b j e c t ( ” +
type
91
+ ” , ” + name + ” , ” + x + ” , ” + y + ” , ” + z + ” )
”) ;
92
r s . c r e a t e W o r l d O b j e c t ( type , name , x , y , z ) ;
93
inObject = false ;
94
}
95
break ;
96
default :
97
break ;
98
}
99
p a r s e r . next ( ) ;
100
}
101
return r s ;
102
}
103 }
95
Kapitel D: Quelltexte
Listing 8: MyXmlparser.java
D.4
Robot.java
1 /∗ ∗
2
∗ Robot . j a v a
3
∗ An e x t e n s i o n o f t h e WorldObject c l a s s t h a t r e s e m b l e s a v i r t u a l Robot
that is
4
∗ a b l e t o a c t i n s i d e a v i r t u a l World .
5
∗
6
∗ @author Marcus Teske
7
∗/
8 package r t d l ;
9
10 public c l a s s Robot extends WorldObject {
11
12
private int f a c i n g D i r e c t i o n ;
13
private s t a t i c f i n a l int NORTH = 0 ;
14
private s t a t i c f i n a l int EAST = 9 0 0 ;
15
private s t a t i c f i n a l int SOUTH = 1 8 0 0 ;
16
private s t a t i c f i n a l int WEST = 2 7 0 0 ;
17
private s t a t i c f i n a l int UP = 1 0 0 0 0 ;
18
private s t a t i c f i n a l int DOWN = −10000;
19
private WorldObject arm ;
20
21
/∗ ∗
22
∗ Constructor
23
∗ @param objectName Name o f t h e r o b o t .
24
∗ @param f a c i n g D i r e c t i o n I n i t i a l f a c i n g d i r e c t i o n .
25
∗/
26
Robot ( S t r i n g objectName , int f a c i n g D i r e c t i o n ) {
27
super . setObjectName ( objectName ) ;
28
super . canMove = true ;
29
this . f a c i n g D i r e c t i o n = f a c i n g D i r e c t i o n ;
30
}
31
32
/∗ ∗
33
∗ Constructor
34
∗ @param objectName Name o f t h e r o b o t .
35
∗/
36
Robot ( S t r i n g objectName ) {
96
Kapitel D: Quelltexte
37
super . setObjectName ( objectName ) ;
38
t h i s . f a c i n g D i r e c t i o n = NORTH;
39
}
40
41
/∗ ∗
42
∗ The d i r e c t i o n t h e r o b o t i s f a c i n g a t .
43
∗ @return D i r e c t i o n t h e r o b o t i s f a c i n g a t .
44
∗/
45
public int g e t F a c i n g D i r e c t i o n ( ) {
46
47
return t h i s . f a c i n g D i r e c t i o n ;
}
48
49
/∗ ∗
50
∗ Turn t h e r o b o t t o a g i v e n f a c i n g d i r e c t i o n .
51
∗ @param d i r e c t i o n new f a c i n g d i r e c t i o n .
52
∗/
53
public void s e t F a c i n g D i r e c t i o n ( int d i r e c t i o n ) {
54
55
this . f a c i n g D i r e c t i o n = d i r e c t i o n ;
}
56
57
/∗ ∗
58
∗ Turning t h e r o b o t t o t h e r i g h t a b o u t 90 d e g r e e .
59
∗/
60
public void t u r n R i g h t ( ) {
61
t h i s . f a c i n g D i r e c t i o n += 9 0 0 ;
62
this . f a c i n g D i r e c t i o n = this . f a c i n g D i r e c t i o n % 3600;
63
}
64
65
/∗ ∗
66
∗ Turning t h e r o b o t t o t h e l e f t a b o u t 90 d e g r e e .
67
∗/
68
public void t u r n L e f t ( ) {
69
t h i s . f a c i n g D i r e c t i o n −= 9 0 0 ;
70
this . f a c i n g D i r e c t i o n = this . f a c i n g D i r e c t i o n % 3600;
71
}
72
73
/∗ ∗
74
∗ Get t h e W o r l d P o s i t i o n o f t h e Robot .
75
∗ @param w The w o r l d .
76
∗ @return The c u r r e n t p o s i t i o n o f t h e r o b o t .
77
∗/
78
79
public W o r l d P o s i t i o n g e t P o s i t i o n ( World w) {
return w . getWorldLocationByWorldObjectName ( super . getObjectName ( ) ) .
getPos ( ) ;
97
Kapitel D: Quelltexte
80
}
81
82
/∗ ∗
83
∗ Determins t h e p o s i t i o n n e x t t o t h e r o b o t s f r o n t .
84
∗ @param w The w o r l d i n which t h e a c t i o n t a k e s p l a c e
85
∗ @return The p o s i t i o n n e x t t o t h e r o b o t s f r o n t .
86
∗/
87
public W o r l d P o s i t i o n l o o k i n g A t ( World w) {
88
W o r l d P o s i t i o n pos = new W o r l d P o s i t i o n (
89
t h i s . g e t P o s i t i o n (w) . getX ( ) ,
90
t h i s . g e t P o s i t i o n (w) . getY ( ) ,
91
t h i s . g e t P o s i t i o n (w) . getZ ( ) ) ;
switch ( t h i s . f a c i n g D i r e c t i o n ) {
92
93
case NORTH:
94
pos . setY ( pos . getY ( ) + 1 ) ;
95
break ;
96
case EAST:
97
pos . setX ( pos . getX ( ) + 1 ) ;
98
break ;
99
case SOUTH:
100
pos . setY ( pos . getY ( ) − 1 ) ;
101
break ;
102
case WEST:
103
pos . setX ( pos . getX ( ) − 1 ) ;
104
break ;
105
case UP:
106
pos . s e t Z ( pos . getZ ( ) + 1 ) ;
107
break ;
108
case DOWN:
109
pos . s e t Z ( pos . getZ ( ) − 1 ) ;
110
break ;
111
}
112
return pos ;
113
}
114
115
/∗ ∗
116
∗ Moves t h i s r o b o t one s t e p f o r w a r d a l o n g h i s f a c i n g d i r e c t i o n , i f
117
∗ @param w The World where t h e a c t i o n t a k e s p l a c e .
118
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
119
∗/
possible .
120
public boolean moveForward ( World w) {
121
W o r l d P o s i t i o n pos = t h i s . l o o k i n g A t (w) ;
122
i f (w . i s P a s s a b l e ( pos ) ) {
98
Kapitel D: Quelltexte
i f (w . s e t W o r l d O b j e c t ( this , pos ) ) {
123
124
return true ;
} else {
125
126
System . e r r . p r i n t l n ( ”ERROR: moveForward ( ) f a i l e d ! ” ) ;
127
return f a l s e ;
}
128
129
}
130
System . e r r . p r i n t l n ( ”WARNING: Cannot move t o [ ” + pos . getX ( ) + ” , ”
131
+ pos . getY ( ) + ” , ” + pos . getZ ( ) + ” ] : L o c a t i o n i m p a s s a b l e . ”
);
132
133
return f a l s e ;
}
134
135
/∗ ∗
136
∗ Turn t h e r o b o t so he f a c e s n o r t h .
137
∗/
138
public void f a c e N o r t h ( ) {
139
140
t h i s . f a c i n g D i r e c t i o n = NORTH;
}
141
142
/∗ ∗
143
∗ Turn t h e r o b o t so he f a c e s e a s t .
144
∗/
145
public void f a c e E a s t ( ) {
146
147
t h i s . f a c i n g D i r e c t i o n = EAST;
}
148
149
/∗ ∗
∗ Turn t h e r o b o t so he f a c e s s o u t h .
150
∗/
151
152
public void f a c e S o u t h ( ) {
153
154
t h i s . f a c i n g D i r e c t i o n = SOUTH;
}
155
156
/∗ ∗
157
∗ tun t h e r o b o t so he f a c e s w e s t .
158
∗/
159
public void faceWest ( ) {
160
161
t h i s . f a c i n g D i r e c t i o n = WEST;
}
162
163
/∗ ∗
164
∗ Turn t h e r o b o t so he f a c e s up .
165
∗/
99
Kapitel D: Quelltexte
166
public void faceUp ( ) {
167
168
t h i s . f a c i n g D i r e c t i o n = UP;
}
169
170
/∗ ∗
171
∗ Turn t h e r o b o t so he f a c e s down .
172
∗/
173
public void faceDown ( ) {
174
175
t h i s . f a c i n g D i r e c t i o n = DOWN;
}
176
177
/∗ ∗
178
∗ Returns a g r e e t i n g message .
179
∗ @return G r e e t i n g message
180
∗/
181
public S t r i n g g r e e t i n g ( ) {
182
return t h i s . getObjectName ( ) + ” : H e l l o I am ” + t h i s . getObjectName
()
183
184
+ ”!”;
}
185
186
/∗ ∗
∗ Checks w h e t h e r t h e n e x t p o s i t i o n t h e r o b o t i s f a c i n g a t i s
187
passable .
188
∗ @param w The World .
189
∗ @return True i f t h e p o s i t i o n t h e r o b o t i s f a c i n g a t i s p a s s a b l e ,
otherwise
190
∗ false .
191
∗/
192
public boolean a h e a d P a s s a b l e ( World w) {
193
W o r l d P o s i t i o n wp = t h i s . l o o k i n g A t (w) ;
194
i f ( ! w . l o c a t i o n V a l i d (wp) ) {
195
System . e r r . p r i n t l n ( ”ERROR: ” + t h i s . getObjectName ( ) + ” cannot
move t o [ ”
196
+ wp . getX ( ) + ” , ” + wp . getY ( ) + ” , ” + wp . getZ ( ) +
197
” ] : Location i n v a l i d ! ” ) ;
198
return f a l s e ;
199
}
200
return w . i s P a s s a b l e (wp) ;
201
}
202
203
204
/∗ ∗
∗ L e t s t h e Robot w a l k a l o n g a s i m p l e p a t h t o a new l o c a t i o n . The
Robot
100
Kapitel D: Quelltexte
205
∗ f o l l o w s t h e x−a x i s u n t i l i t f i t s , t h e n t h e y−a x i s u n t i l i t f i t s
and
206
∗ f i n a l l y t h e z−a x i s u n t i l i t f i t s .
207
∗ @param w The World i n which t h e o p e r a t i o n t a k e s p l a c e .
208
∗ @param x x−c o o r d i n a t e
209
∗ @param y y−c o o r d i n a t e
210
∗ @param z z−c o o r d i n a t e
211
∗ @return True i f t h e movement was s u c c e s s f u l , f a l s e i f not .
212
∗/
213
@Override
214
public boolean move ( World w, int x , int y , int z ) {
215
i f ( !w. l o c a t i o n V a l i d (x , y , z ) ) {
216
System . e r r . p r i n t l n ( ”ERROR: ” + t h i s . getObjectName ( )
217
+ ” cannot move t o [ ” + x + ” , ” + y + ” , ” + z
218
+ ” ] : Location i n v a l i d ! ” ) ;
219
return f a l s e ;
220
}
221
W o r l d P o s i t i o n tp = new W o r l d P o s i t i o n ( x , y , z ) ; // t a r g e t
WorldPosition
222
W o r l d P o s i t i o n cp = t h i s . g e t P o s i t i o n (w) ; // c u r r e n t W o r l d P o s i t i o n
223
224
i f ( cp . e q u a l s ( tp ) ) {
225
return true ;
226
}
227
f o r ( long i = cp . g e t O f f s e t X ( tp ) ; i != 0 ; ) { // U n t i l x−c o o r d i n a t e
matches .
i f ( i > 0 ) { // T a r g e t e a s t
228
i f ( ! t h i s . moveEast (w) ) {
229
230
break ;
231
}
232
i −−;
} e l s e { // T a r g e t w e s t
233
i f ( ! t h i s . moveWest (w) ) {
234
235
break ;
236
}
237
i ++;
}
238
239
}
240
f o r ( long i = cp . g e t O f f s e t Y ( tp ) ; i != 0 ; ) { // U n t i l y−c o o r d i n a t e
matches .
241
242
i f ( i > 0 ) { // T a r g e t n o r t h
i f ( ! t h i s . moveNorth (w) ) {
243
244
break ;
}
101
Kapitel D: Quelltexte
i −−;
245
} e l s e { // T a r g e t s o u t h
246
i f ( ! t h i s . moveSouth (w) ) {
247
248
break ;
249
}
250
i ++;
}
251
252
}
253
f o r ( long i = cp . g e t O f f s e t Z ( tp ) ; i != 0 ; ) { // U n t i l z−c o o r d i n a t e
matches .
i f ( i > 0 ) { // T a r g e t ab o ve
254
i f ( ! t h i s . moveUp (w) ) {
255
256
break ;
257
}
258
i −−;
} e l s e { // T a r g e t b e l o w
259
i f ( ! t h i s . moveDown (w) ) {
260
261
break ;
262
}
263
i ++;
}
264
265
}
266
cp = t h i s . g e t P o s i t i o n (w) ;
267
return true ;
268
}
269
270
271
/∗ ∗
∗ Gets t h e n e x t p o s s i b l e s t e p f o r t h e Robot on h i s way t o a t a r g e t
position .
272
∗ @param w World
273
∗ @param x x−c c o r d i n a t e o f t a r g e t
274
∗ @param y y−c c o r d i n a t e o f t a r g e t
275
∗ @param z z−c c o r d i n a t e o f t a r g e t
276
∗ @return P o s i t i o n o f t h e n e x t p o s s i b l e s t e p
277
∗/
278
279
public W o r l d P o s i t i o n n e x t S t e p ( World w, int x , int y , int z ) {
W o r l d P o s i t i o n cp = t h i s . g e t P o s i t i o n (w) ;
280
281
i f ( cp . getX ( ) == x && cp . getY ( ) == y && cp . getZ ( ) == z ) {
282
return cp ;
283
}
284
i f ( cp . getX ( ) < x ) {
285
this . faceEast () ;
286
} e l s e i f ( cp . getX ( ) > x ) {
102
Kapitel D: Quelltexte
287
t h i s . faceWest ( ) ;
288
}
289
i f (w . l o c a t i o n V a l i d ( t h i s . l o o k i n g A t (w) ) &&
w . i s P a s s a b l e ( t h i s . l o o k i n g A t (w) ) ) {
290
291
return t h i s . l o o k i n g A t (w) ;
} else {
292
293
i f ( cp . getY ( ) < y ) {
294
this . faceNorth ( ) ;
} e l s e i f ( cp . getY ( ) > y ) {
295
296
this . faceSouth ( ) ;
297
}
298
i f (w . l o c a t i o n V a l i d ( t h i s . l o o k i n g A t (w) ) &&
w . i s P a s s a b l e ( t h i s . l o o k i n g A t (w) ) ) {
299
300
return t h i s . l o o k i n g A t (w) ;
} else {
301
i f ( cp . getZ ( ) < z ) {
302
303
t h i s . faceUp ( ) ;
} e l s e i f ( cp . getZ ( ) > z ) {
304
305
t h i s . faceDown ( ) ;
306
}
307
i f (w . l o c a t i o n V a l i d ( t h i s . l o o k i n g A t (w) ) &&
w . i s P a s s a b l e ( t h i s . l o o k i n g A t (w) ) ) {
308
309
return t h i s . l o o k i n g A t (w) ;
} else {
310
311
return null ;
}
312
}
313
314
}
315
316
}
317
318
/∗ ∗
319
∗ T r i e s t o move t h e r o b o t one p o s i t i o n t o t h e n o r t h .
320
∗ @param w World .
321
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
322
∗/
323
public boolean moveNorth ( World w) {
324
this . faceNorth ( ) ;
325
return t h i s . moveForward (w) ;
326
}
327
328
/∗ ∗
329
∗ T r i e s t o move t h e r o b o t one p o s i t i o n t o t h e s o u t h .
330
∗ @param w World .
103
Kapitel D: Quelltexte
331
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
332
∗/
333
public boolean moveSouth ( World w) {
334
this . faceSouth ( ) ;
335
return t h i s . moveForward (w) ;
336
}
337
338
/∗ ∗
339
∗ T r i e s t o move t h e r o b o t one p o s i t i o n t o t h e e a s t .
340
∗ @param w World .
341
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
∗/
342
343
public boolean moveEast ( World w) {
344
this . faceEast () ;
345
return t h i s . moveForward (w) ;
346
}
347
348
/∗ ∗
349
∗ T r i e s t o move t h e r o b o t one p o s i t i o n t o t h e w e s t .
350
∗ @param w World .
351
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
352
∗/
353
public boolean moveWest ( World w) {
354
t h i s . faceWest ( ) ;
355
return t h i s . moveForward (w) ;
356
}
357
358
/∗ ∗
359
∗ T r i e s t o move t h e r o b o t one p o s i t i o n up .
360
∗ @param w World .
361
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
362
∗/
363
public boolean moveUp ( World w) {
364
t h i s . faceUp ( ) ;
365
return t h i s . moveForward (w) ;
366
}
367
368
/∗ ∗
369
∗ T r i e s t o move t h e r o b o t one p o s i t i o n down .
370
∗ @param w World .
371
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
372
∗/
373
374
public boolean moveDown ( World w) {
t h i s . faceUp ( ) ;
104
Kapitel D: Quelltexte
375
376
return t h i s . moveForward (w) ;
}
377
378
/∗ ∗
379
∗ Gets t h e WorldObject t h e Robot has i n h i s arm .
380
∗ @return O b j e c t i n t h e r o b o t ’ s arm .
381
∗/
382
@Override
383
public WorldObject getArmPayload ( ) {
384
385
return t h i s . arm ;
}
386
387
/∗ ∗
388
∗ The Robot g r i p s an g r i p p e a b l e WorldObject .
389
∗ @param w The w o r l d t h e a c t i o n t a k e s p l a c e i n .
390
∗ @param name Name o f t h e WorldObject t o g r i p .
391
∗ @return True i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
392
∗/
393
@Override
394
public boolean g r i p ( World w, S t r i n g name ) {
395
W o r l d P o s i t i o n myPos = t h i s . g e t P o s i t i o n (w) ;
396
W o r l d P o s i t i o n oPos = w . getWorldLocationByWorldObjectName (
397
name ) . getPos ( ) ;
398
// I f t h e WorldObject i s a t my p o s i t i o n
399
i f ( myPos . e q u a l s ( oPos ) ) {
i f (w . getWorldObjectByName ( name ) . i s G r i p p e a b l e ) {
400
401
t h i s . arm = w . takeObjectByName ( name ) ;
402
System . out . p r i n t l n ( t h i s . getObjectName ( ) + ” has g r i p p e d ”
403
+ name + ” . ” ) ;
404
return true ;
}
405
}
406
407
408
System . e r r . p r i n t l n ( ”ERROR: Grip f a i l e d : Object ” + name
409
+ ” not found a t p o s i t i o n [ ” + myPos . getX ( ) + ” , ” + myPos .
getY ( )
410
+ ” , ” + myPos . getZ ( ) + ” ] ! ” ) ;
411
412
return f a l s e ;
}
413
414
/∗ ∗
415
∗ The Robot p u t s down t h e named WorldObject a h i s c u r r e n t p o s i t i o n .
416
∗ @param w The World t h e a c t i o n t a k e s p l a c e i n .
417
∗ @param name Name o f t h e WorldObject t o p u t down
105
Kapitel D: Quelltexte
418
∗ @return True i f t h e o p e r a t i o n i s s u c c e s s f u l , f a l s e o t h e r w i s e .
419
∗/
420
@Override
421
public boolean u n g r i p ( World w, S t r i n g name ) {
i f ( t h i s . arm != null ) {
422
i f ( t h i s . arm . getObjectName ( ) . e q u a l s ( name ) ) {
423
424
System . out . p r i n t l n ( t h i s . getObjectName ( ) + ” has u n g r i p p e d ”
425
+ name + ” . ” ) ;
426
return w . s e t W o r l d O b j e c t ( t h i s . arm , t h i s . g e t P o s i t i o n (w) ) ;
}
427
428
}
429
System . e r r . p r i n t l n ( ”ERROR: Ungrip f a i l e d : ” + t h i s . getObjectName ( )
430
+ ” d o e s not c a r r y o b j e c t ” + name + ” ! ” ) ;
431
return f a l s e ;
}
432
433 }
Listing 9: Robot.java
D.5
RobotSim.java
1 /∗ ∗
2
∗ RobotSim . j a v a
3
∗ A s i m u l a t i o n environment f o r v i r t u a l r o b o t s . I t c o n s i s t s o f e x a c t l y
one World
4
∗ and o f f e r s methods t h a t c a p s u l a t e t h e o p e r a t i o n s on t h e World and i t
’s
5
∗ contained WorldObjects .
6
∗
7
∗ @author Marcus Teske
8
∗/
9 package r t d l ;
10
11 // i m p o r t com . t h o u g h t w o r k s . xstream . ∗ ;
12 public c l a s s RobotSim {
13
14
private World w ; // The World where e v e r y t h i n g t a k e s p l a c e .
15
16
/∗ ∗
17
∗ Constructor to i n s t a n c i a t e a RobotSimulation .
18
∗ @param x Amount o f WorldLocation a l o n g t h e X−a x i s , s t a r t i n g a t 0 .
19
∗ @param y Amount o f WorldLocation a l o n g t h e Y−a x i s , s t a r t i n g a t 0 .
20
∗ @param z Amount o f WorldLocation a l o n g t h e Z−a x i s , s t a r t i n g a t 0 .
106
Kapitel D: Quelltexte
∗/
21
22
RobotSim ( int x , int y , int z ) {
23
24
t h i s . w = new World ( x , y , z ) ;
}
25
26
/∗ ∗
∗ C r e a t e s an O b j e c t w i t h a s p e c i f i e d t y p e and name a t a s p e c i f i e d
27
location .
28
∗ @param t y p e Type o f t h e O b j e c t .
29
∗ @param name Name o f t h e O b j e c t .
30
∗ @param x P l a c e a t t h i s x−c c o r d i n a t e .
31
∗ @param y P l a c e a t t h i s y−c c o r d i n a t e .
32
∗ @param z P l a c e a t t h i s z−c c o r d i n a t e .
33
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e i f not .
34
∗/
35
public boolean c r e a t e W o r l d O b j e c t ( S t r i n g type , S t r i n g name , int x , int
y,
int z ) {
36
i f ( ! w . c o n t a i n s ( name ) ) {
37
i f ( this .w. l o c a t i o n V a l i d ( x , y , z ) ) {
38
i f ( ” Robot ” . e q u a l s ( type ) ) {
39
40
return t h i s . w . s e t W o r l d O b j e c t (new Robot ( name ) , x , y , z ) ;
41 //
} e l s e i f (” RfidTag ” . e q u a l s ( t y p e ) ) {
42 //
r e t u r n t h i s . w . s e t W o r l d O b j e c t ( new RfidTag ( name ) , x , y , z ) ;
} e l s e i f ( ” Wall ” . e q u a l s ( type ) ) {
43
44
return t h i s . w . s e t W o r l d O b j e c t (new Wall ( name ) , x , y , z ) ;
} e l s e i f ( ” D r i n k i n g G l a s s ” . e q u a l s ( type ) ) {
45
46
return t h i s . w . s e t W o r l d O b j e c t (new D r i n k i n g G l a s s ( name ) , x , y ,
47
z) ;
} e l s e i f ( ”Tap” . e q u a l s ( type ) ) {
48
49
return t h i s . w . s e t W o r l d O b j e c t (new Tap ( name ) , x , y , z ) ;
} e l s e i f ( ” Waypoint ” . e q u a l s ( type ) ) {
50
51
return t h i s . w . s e t W o r l d O b j e c t (new Waypoint ( name ) , x , y , z ) ;
52
}
53
return f a l s e ;
54
}
55
return f a l s e ;
} else {
56
57
System . e r r . p r i n t l n ( ”ERROR: Cannot c r e a t e WorldObject ” + name
58
+ ” ! An Object by t h a t name a l r e a d y e x i s t s ! ” ) ;
59
return f a l s e ;
}
60
61
}
62
107
Kapitel D: Quelltexte
63
/∗ ∗
64
∗ C r e a t e s a WorldObject o f a s p e c i f i c t y p e and w i t h a s p e c i f i c name
65
∗ World ’ s o r i g i n .
66
∗ @param t y p e Type o f t h e WorldObject [ Robot ]
67
∗ @param name Name o f t h e WorldObject .
68
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e i f not .
69
∗/
at the
70
public boolean c r e a t e W o r l d O b j e c t ( S t r i n g type , S t r i n g name ) {
i f ( ” Robot ” . e q u a l s ( type ) ) {
71
72
return t h i s . w . s e t W o r l d O b j e c t (new Robot ( name ) , 0 , 0 , 0 ) ;
} else {
73
74
return f a l s e ;
}
75
76
}
77
78
/∗ ∗
79
∗ Simple Wrapper t o c r e a t e a r o b o t a t t h e w o r l d ’ s o r i g i n .
80
∗ @param RobotName Name o f t h e Robot .
81
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e i f not .
∗/
82
83
public boolean c r e a t e R o b o t ( S t r i n g RobotName ) {
84
85
return t h i s . c r e a t e W o r l d O b j e c t ( ” Robot ” , RobotName ) ;
}
86
87
/∗ ∗
∗ Wrapper t o c r e a t e a Robot w i t h a u n i q u e name a t a s p e c i f i e d
88
position .
89
∗ @param RobotName Name o f t h e Robot .
90
∗ @param x x−c o o r d i n a t e .
91
∗ @param y x−c o o r d i n a t e .
92
∗ @param z x−c o o r d i n a t e .
93
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e i f not .
94
∗/
95
public boolean c r e a t e R o b o t ( S t r i n g RobotName , int x , int y , int z ) {
96
97
return t h i s . c r e a t e W o r l d O b j e c t ( ” Robot ” , RobotName , x , y , z ) ;
}
98
99
/∗ ∗
100
∗ Gets an WorldObject by i t ’ s name
101
∗ @param name Name o f t h e WorldObject .
102
∗ @return t h e WorldObject o b j e c t .
103
∗/
104
public WorldObject g e t O b j e c t ( S t r i n g name ) {
108
Kapitel D: Quelltexte
105
106
return t h i s . w . getWorldObjectByName ( name ) ;
}
107
108
/∗ ∗
109
∗ Simple Wrapper f o r g e t t i n g r o b o t s .
110
∗ @param name Name o f t h e r o b o t
111
∗ @return t h e r o b o t o b j e c t .
112
∗/
113
public Robot getRobot ( S t r i n g name ) {
114
115
return ( Robot ) t h i s . w . getWorldObjectByName ( name ) ;
}
116
117
/∗ ∗
118
∗ Removes an O b j e c t from t h e World .
119
∗ @param name Name o f t h e O b j e c t .
120
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
121
∗/
122
public boolean removeObject ( S t r i n g name ) {
123
124
return t h i s . w . removeWorldObjectByName ( name ) ;
}
125
126
/∗ ∗
127
∗ Gets t h e P o s i t i o n o f an WorldObject as W o r l d P o s i t i o n o b j e c t .
128
∗ @param name name o f t h e WorldObject .
129
∗ @return t h e p o s i t i o n .
130
∗/
131
public W o r l d P o s i t i o n g e t P o s i t i o n ( S t r i n g name ) {
132
133
return t h i s . w . getWorldLocationByWorldObjectName ( name ) . getPos ( ) ;
}
134
135
/∗ ∗
136
∗ Gets t h e P o s i t i o n o f an WorldObject as S t r i n g [ x , y , z ] .
137
∗ @param name name o f t h e WorldObject .
138
∗ @return t h e p o s i t i o n .
139
∗/
140
public S t r i n g g e t P o s i t i o n S t r i n g ( S t r i n g name ) {
141
W o r l d P o s i t i o n wp = t h i s . g e t P o s i t i o n ( name ) ;
142
143
return ” P o s i t i o n o f ” + name + ” : [ ” + wp . getX ( ) + ” , ” + wp . getY ( )
+ ” ,”
144
145
+ wp . getZ ( ) + ” ] ” ;
}
146
147
/∗ ∗
109
Kapitel D: Quelltexte
148
∗ P l a c e s an WorldObject d i r e c t l y a t t h e s p e c i f i e d l o c a t i o n .
149
∗ @param name Name o f t h e WorldObject .
150
∗ @param x x−c c o r d i n a t e
151
∗ @param y y−c c o r d i n a t e
152
∗ @param z z−c c o r d i n a t e
153
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
154
∗/
155
public boolean p l a c e ( S t r i n g name , int x , int y , int z ) {
156
return t h i s . w . s e t W o r l dO b j e c t ( t h i s . g e t O b j e c t ( name ) , x , y , z ) ;
157
158
159
}
160
161
/∗ ∗
162
∗ Wrapper t h a t l e t s an WorldObject move a l o n g a s i m p l e p a t h t o a new
163
∗ location .
164
∗ The WorldObject a t f i r s t moves a l o n g t h e x−a x i s , t h e n a l o n g t h e y−
axis
165
∗ and a t l a s t a l o n g t h e z−a x i s .
166
∗ @param name Name o f t h e WorldObject t o move
167
∗ @param x x−c c o r d i n a t e
168
∗ @param y y−c o o r d i n a t e
169
∗ @param z z−c o o r d i n a t e
170
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
171
∗/
172
public boolean move ( S t r i n g name , int x , int y , int z ) {
i f ( ! t h i s . w . c o n t a i n s ( name ) ) {
173
174
System . e r r . p r i n t l n ( ”ERROR: Move f a i l e d : Object ” + name
175
+ ” not found ! ” ) ;
176
return f a l s e ;
177
}
178
i f ( t h i s . g e t O b j e c t ( name ) . move ( t h i s . w, x , y , z ) ) {
179
System . out . p r i n t l n ( name + ” has moved t o [ ” + x + ” , ” + y + ” , ” +
z
180
+ ” ] . ”) ;
181
return true ;
182
}
183
System . e r r . p r i n t l n ( ”ERROR: Moving t o [ ” + x + ” , ” + y + ” , ” + z
184
+ ” ] failed ! ”) ;
185
186
return f a l s e ;
}
187
188
/∗ ∗
110
Kapitel D: Quelltexte
∗ Wrapper t h a t l e t s an WorldObject name w a l k a l o n g a s i m p l e p a t h t o
189
the
190
∗ l o c a t i o n o f a n o t h e r WorldObject d e s t i n a t i o n .
191
∗ @param name Name o f WorldObject t o move .
192
∗ @param d e s t i n a t i o n Name o f t h e d e s t i n a t i o n WorldObject .
193
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
194
∗/
195
public boolean move ( S t r i n g name , S t r i n g d e s t i n a t i o n ) {
196
WorldLocation d e s t L o c ;
197
d e s t L o c = w . getWorldLocationByWorldObjectName ( d e s t i n a t i o n ) ;
198
i f ( d e s t L o c == null ) {
199
System . e r r . p r i n t l n ( ”ERROR: Moving t o ” + d e s t i n a t i o n + ” f a i l e d ! ”
200
+ ” No such WorldObject . ” ) ;
201
System . e x i t ( 1 ) ;
202
}
203
int x = d e s t L o c . getX ( ) ;
204
int y = d e s t L o c . getY ( ) ;
205
int z = d e s t L o c . getZ ( ) ;
206
207
208
return t h i s . move ( name , x , y , z ) ;
}
209
210
/∗ ∗
211
∗ Moves an WorldObject one P o s i t i o n t o t h e North . Only Robots .
212
∗ @param name Name o f The O b j e c t .
213
∗ @param s t e p s The amount o f s t e p s t o move .
214
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
215
∗/
216
public boolean moveNorth ( S t r i n g name , int s t e p s ) {
i f ( t h i s . g e t O b j e c t ( name ) . getObjectType ( ) . e q u a l s ( ” Robot ” ) ) {
217
218
Robot r = ( Robot ) t h i s . g e t O b j e c t ( name ) ;
219
while ( s t e p s > 0 ) {
220
s t e p s −−;
221
i f ( ! r . moveNorth (w) ) {
222
System . e r r . p r i n t l n ( ”ERROR: MovingNorth f a i l e d ! ” ) ;
223
return f a l s e ;
}
224
225
}
226
return true ;
227
}
228
return f a l s e ;
229
}
230
231
/∗ ∗
111
Kapitel D: Quelltexte
232
∗ Moves an WorldObject s e v e r a l P o s i t i o n t o t h e South . Only Robots .
233
∗ @param name Name o f The O b j e c t .
234
∗ @param s t e p s The amount o f s t e p s t o move .
235
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
236
∗/
237
public boolean moveSouth ( S t r i n g name , int s t e p s ) {
i f ( t h i s . g e t O b j e c t ( name ) . getObjectType ( ) . e q u a l s ( ” Robot ” ) ) {
238
239
Robot r = ( Robot ) t h i s . g e t O b j e c t ( name ) ;
240
while ( s t e p s > 0 ) {
241
s t e p s −−;
242
i f ( ! r . moveSouth (w) ) {
243
System . e r r . p r i n t l n ( ”ERROR: MovingSouth f a i l e d ! ” ) ;
244
return f a l s e ;
}
245
246
}
247
return true ;
248
}
249
return f a l s e ;
250
}
251
252
/∗ ∗
253
∗ Moves an WorldObject one P o s i t i o n t o t h e East . Only Robots .
254
∗ @param name Name o f The O b j e c t .
255
∗ @param s t e p s The amount o f s t e p s t o move .
256
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l l , f a l s e i f not .
257
∗/
258
public boolean moveEast ( S t r i n g name , int s t e p s ) {
i f ( t h i s . g e t O b j e c t ( name ) . getObjectType ( ) . e q u a l s ( ” Robot ” ) ) {
259
260
Robot r = ( Robot ) t h i s . g e t O b j e c t ( name ) ;
261
while ( s t e p s > 0 ) {
262
s t e p s −−;
263
i f ( ! r . moveEast (w) ) {
264
System . e r r . p r i n t l n ( ”ERROR: MovingEast f a i l e d ! ” ) ;
265
return f a l s e ;
}
266
267
}
268
return true ;
269
}
270
return f a l s e ;
271
}
272
273
/∗ ∗
274
∗ Moves an WorldObject one P o s i t i o n t o t h e West . Only Robots .
275
∗ @param name Name o f The O b j e c t .
112
Kapitel D: Quelltexte
276
∗ @param s t e p s The amount o f s t e p s t o move .
277
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e i f not .
∗/
278
279
public boolean moveWest ( S t r i n g name , int s t e p s ) {
i f ( t h i s . g e t O b j e c t ( name ) . getObjectType ( ) . e q u a l s ( ” Robot ” ) ) {
280
281
Robot r = ( Robot ) t h i s . g e t O b j e c t ( name ) ;
282
while ( s t e p s > 0 ) {
283
s t e p s −−;
284
i f ( ! r . moveWest (w) ) {
285
System . e r r . p r i n t l n ( ”ERROR: MovingWest f a i l e d ! ” ) ;
286
return f a l s e ;
}
287
288
}
289
return true ;
290
}
291
return f a l s e ;
292
}
293
294
/∗ ∗
295
∗ L e t s an a g e n t g r i p an g r i p p e a b l e WorldObject e n t i t y a t h i s c u r r e n t
296
∗ position .
297
∗ @param a g e n t Robot t o g r i p t h e e n t i t y .
298
∗ @param e n t i t y G r i p p e a b l e WorldObject t o g r i p .
299
∗ @return True i f t h e o p e a r t i o n i s s u c c e s s f u l , f a l s e i f not .
300
∗/
301
public boolean g r i p ( S t r i n g agent , S t r i n g e n t i t y ) {
i f ( ! this .w. c o n t a i n s ( agent ) ) {
302
303
System . e r r . p r i n t l n ( ”ERROR: Grip f a i l e d : Agent ” + a g e n t
304
+ ” not found ! ” ) ;
305
return f a l s e ;
306
}
307
i f ( ! this .w. c o n t a i n s ( e n t i t y ) ) {
308
System . e r r . p r i n t l n ( ”ERROR: Grip f a i l e d : E n t i t y ” + e n t i t y
309
+ ” not found ! ” ) ;
310
return f a l s e ;
311
}
312
i f ( t h i s . g e t O b j e c t ( a g e n t ) . g r i p ( t h i s . w, e n t i t y ) ) {
313
return true ;
314
}
315
return f a l s e ;
316
}
317
318
319
/∗ ∗
∗ L e t s an a g e n t p u t down t h e named WorldObject e n t i t y a t h i s c u r r e n t
113
Kapitel D: Quelltexte
320
∗ position .
321
∗ @param a g e n t Robot t o p u t down t h e e n t i t y .
322
∗ @param e n t i t y G r i p p e a b l e WorldObject t o p u t down .
323
∗ @return True i f t h e o p e r a t i o n i s s u c c e s s f u l , f a l s e i f not .
324
∗/
325
public boolean u n g r i p ( S t r i n g agent , S t r i n g e n t i t y ) {
i f ( ! this .w. c o n t a i n s ( agent ) ) {
326
327
System . e r r . p r i n t l n ( ”ERROR: Ungrip f a i l e d : Agent ” + a g e n t
328
+ ” not found ! ” ) ;
329
return f a l s e ;
330
}
331
i f ( ! t h i s . g e t O b j e c t ( a g e n t ) . getArmPayload ( ) . getObjectName ( ) . e q u a l s (
entity ) ) {
332
System . e r r . p r i n t l n ( ”ERROR: Ungrip f a i l e d : E n t i t y ” + e n t i t y
333
+ ” not found ! ” ) ;
334
return f a l s e ;
335
}
336
i f ( t h i s . g e t O b j e c t ( a g e n t ) . u n g r i p ( t h i s . w, e n t i t y ) ) {
337
return true ;
338
}
339
System . e r r . p r i n t l n ( ”ERROR: ” + a g e n t + ” f a i l e d p u t t i n g down ” +
entity ) ;
340
341
return f a l s e ;
}
342
343
344
/∗ ∗
∗ An a g e n t f i l l s a c o n t a i n e r w i t h t h e o u t p u t o f a s o u r c e . Agent ,
s o u r c e and
345
∗ c o n t a i n e r have t o be a t t h e same p o s i t i o n .
346
∗ @param a g e n t The a g e n t t o i n i t i a t e t h e f i l l i n g .
347
∗ @param s o u r c e The s o u r c e t o f i l l t h e c o n t a i n e r .
348
∗ @param c o n t a i n e r The c o n t a i n e r t o be f i l l e d w i t h t h e o u t p u t o f t h e
source .
349
∗ @return True i f t h e o p e r a t i o n i s s u c c e s s f u l , f a l s e i f not .
350
∗/
351
352
public boolean f i l l ( S t r i n g agent , S t r i n g s o u r c e , S t r i n g c o n t a i n e r ) {
i f ( ! this .w. c o n t a i n s ( agent ) ) {
353
System . e r r . p r i n t l n ( ”ERROR: F i l l f a i l e d : Agent ” + a g e n t
354
+ ” not found ! ” ) ;
355
return f a l s e ;
356
}
357
i f ( ! this .w. c o n t a i n s ( source ) ) {
358
359
System . e r r . p r i n t l n ( ”ERROR: F i l l f a i l e d : S o u r c e ” + s o u r c e
+ ” not found ! ” ) ;
114
Kapitel D: Quelltexte
360
return f a l s e ;
361
}
362
i f ( ! this .w. c o n t a i n s ( c o n t a i n e r ) ) {
363
System . e r r . p r i n t l n ( ”ERROR: F i l l f a i l e d : C o n t a i n e r ” + c o n t a i n e r
364
+ ” not found ! ” ) ;
365
return f a l s e ;
366
}
367
W o r l d P o s i t i o n agentPos =
368
t h i s . w . getWorldLocationByWorldObjectName ( a g e n t ) . getPos ( ) ;
369
WorldPosition sourcePos =
370
t h i s . w . getWorldLocationByWorldObjectName ( s o u r c e ) . getPos ( ) ;
371
WorldPosition containerPos =
372
t h i s . w . getWorldLocationByWorldObjectName ( c o n t a i n e r ) . getPos
() ;
373
// The a g e n t n ee d s t o be a t t h e same p o s i t i o n as t h e s o u r c e .
374
i f ( agentPos . e q u a l s ( s o u r c e P o s ) ) {
i f ( sourcePos . equals ( containerPos ) ) {
375
376
System . out . p r i n t l n ( a g e n t + ” f i l l s ” + c o n t a i n e r + ” a t ”
377
+ source + ” . ”) ;
378
return t h i s . w . getWorldObjectByName ( c o n t a i n e r ) . f i l l C o n t a i n e r (
t h i s . w, s o u r c e ) ;
} else {
379
380
System . e r r . p r i n t l n ( ”ERROR: F i l l f a i l e d : C o n t a i n e r ” + c o n t a i n e r
381
+ ” i s not a t t h e same p o s i t i o n a s s o u r c e ” + s o u r c e
382
+ ” . ”) ;
}
383
} else {
384
385
System . e r r . p r i n t l n ( ”ERROR: F i l l f a i l e d : Agent ” + a g e n t
386
+ ” i s not a t t h e same p o s i t i o n a s s o u r c e ” + s o u r c e + ” .
”) ;
387
}
388
return f a l s e ;
389
}
390
391
/∗ ∗
392
∗ C r e a t e s an xml r e p r e s e n t a t i o n o f t h e w o r l d and i t s c o n t e n t s .
393
∗ @return xml r e p r e s e n t a t i o n o f t h e w o r l d .
394
395
∗/
public S t r i n g toXmlString ( ) throws N u l l P o i n t e r E x c e p t i o n {
396
S t r i n g [ ] o b j e c t s = t h i s . w . getWorldObjectNames ( ) ;
397
S t r i n g xml = new S t r i n g ( ) ;
398
xml += ”<world >\n” ;
399
xml += ”
<s i z e x >” + t h i s . w . g e t S i z e X ( ) + ”</ s i z e x >\n” ;
400
xml += ”
<s i z e y >” + t h i s . w . g e t S i z e Y ( ) + ”</ s i z e y >\n” ;
115
Kapitel D: Quelltexte
401
xml += ”
<s i z e z >” + t h i s . w . g e t S i z e Z ( ) + ”</ s i z e z >\n” ;
402
xml += ”
<o b j e c t s >\n” ;
403
404
f o r ( int i = 0 ; i
< o b j e c t s . l e n g t h ; i ++) {
405
406
xml += ”
<o b j e c t >\n” ;
408
xml += ”
<name>” ;
409
xml += o b j e c t s [ i ] ;
410
xml += ”</name>\n” ;
407
411
412
xml += ”
413
xml += t h i s . w . getWorldObjectByName ( o b j e c t s [ i ] ) . getObjectType ( ) ;
<type>” ;
414
xml += ”</type >\n” ;
415
416
xml += ”
<x>” ;
417
xml += t h i s . w . getWorldLocationByWorldObjectName ( o b j e c t s [ i ] ) . getX
() ;
418
xml += ”</x>\n” ;
419
420
xml += ”
421
xml += t h i s . w . getWorldLocationByWorldObjectName ( o b j e c t s [ i ] ) . getY
<y>” ;
() ;
422
xml += ”</y>\n” ;
423
424
xml += ”
<z>” ;
425
xml += t h i s . w . getWorldLocationByWorldObjectName ( o b j e c t s [ i ] ) . getZ
() ;
426
xml += ”</z>\n” ;
427
428
xml += ”
</ o b j e c t >\n” ;
429
}
430
xml += ”
431
xml += ”</world>” ;
</ o b j e c t s >\n” ;
432
433
return xml ;
}
434
435 }
Listing 10: RobotSim.java
D.6
RtdlParser.java
116
Kapitel D: Quelltexte
1 /∗ ∗
2
∗ RtdlParser . java
3
∗ h t t p : / /www. i k s . hs−merseburg . de /˜ u s c h r o e t / L i t e r a t u r / J a v a L i t /
JAVA Insel / j a v a i n s e l 1 5 0 0 4 . htm#m j d 0 d b b 5 3 e 7 2 e 3 b 5 3 b 0 1 1 e 1 5 c 2 0 0 5 4 0 7 8 f
4
∗
5
∗ @author Marcus Teske
6
∗/
7 package r t d l ;
8
9 import j a v a . i o . ∗ ;
10 import j a v a x . xml . stream . XMLInputFactory ;
11 import j a v a x . xml . stream . XMLStreamReader ;
12 import j a v a x . xml . stream . XMLStreamException ;
13 import j a v a x . xml . stream . XMLStreamConstants ;
14
15 public c l a s s R t d l P a r s e r {
16
17
XMLStreamReader p a r s e r ;
18
S t r i n g taskName ;
19
boolean inTaskArgs = f a l s e ;
20
S t r i n g actionName ;
21
int a r g s c n t ;
22
S t r i n g [ ] a c t i o n A r g s = new S t r i n g [ 5 ] ;
23
24
RtdlParser ( String filename )
25
throws FileNotFoundException , XMLStreamException {
26
p a r s e r = XMLInputFactory . n e w I n s t a n c e ( ) . createXMLStreamReader (
27
28
new F i l e I n p u t S t r e a m ( f i l e n a m e ) ) ;
}
29
30
public RobotSim p a r s e ( RobotSim r s , S t r i n g r o b o t ) throws
XMLStreamException ,
31
InterruptedException {
32
33
34
35
36
while ( p a r s e r . hasNext ( ) ) {
switch ( p a r s e r . getEventType ( ) ) {
case XMLStreamConstants .START DOCUMENT:
break ;
37
38
case XMLStreamConstants .END DOCUMENT:
39
parser . close () ;
40
break ;
41
117
Kapitel D: Quelltexte
42
43
case XMLStreamConstants .NAMESPACE:
break ;
44
45
case XMLStreamConstants .START ELEMENT:
46
// Version c h e c k i n g , o n l y 1 . 0 i s v a l i d
47
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” r t d l ” ) ) {
f o r ( int i = 0 ; i < p a r s e r . g e t A t t r i b u t e C o u n t ( ) ; i ++) {
48
49
i f ( parser . getAttributeLocalName ( i ) . equals ( ” v e r s i o n ” )
&& p a r s e r . g e t A t t r i b u t e V a l u e ( i ) . e q u a l s ( ” 1 . 0 ” ) ) {
50
51
System . out . p r i n t l n ( ”RTDL V e r s i o n ”
52
+ p a r s e r . g e t A t t r i b u t e V a l u e ( i ) + ” OK! ” ) ;
} else {
53
54
System . e r r . p r i n t l n ( ”RTDL V e r s i o n ”
55
+ parser . getAttributeValue ( i )
56
+ ” invalid . ”) ;
57
System . e x i t ( 1 ) ;
}
58
}
59
60
}
61
62
// E x t r a c t t a s k name
63
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” t a s k ” ) ) {
f o r ( int i = 0 ; i < p a r s e r . g e t A t t r i b u t e C o u n t ( ) ; i ++) {
64
i f ( parser . getAttributeLocalName ( i ) . equals ( ” task ” ) ) {
65
66
taskName = p a r s e r . g e t A t t r i b u t e V a l u e ( i ) ;
67
System . out . p r i n t l n ( ” P a r s i n g t a s k ” + taskName ) ;
}
68
}
69
70
}
71
72
// E x t r a c t a c t i o n name
73
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ”name” ) ) {
74
actionName = p a r s e r . getElementText ( ) ;
75
System . out . p r i n t ( r o b o t + ” : ” + actionName + ” ( ” ) ;
76
}
77
78
// R e s e t a r g s c o u n t e r on e n t e r i n g a r gs −e l e m e n t .
79
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” a r g s ” ) ) {
a r g s c n t = −1;
80
81
}
82
83
// E x t r a c t a c i o n a r g s
84
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” a r g ” ) ) {
85
a r g s c n t ++;
118
Kapitel D: Quelltexte
86
a c t i o n A r g s [ a r g s c n t ] = p a r s e r . getElementText ( ) ;
87
i f ( a r g s c n t == 0 ) {
88
System . out . p r i n t ( ’ ” ’ + a c t i o n A r g s [ a r g s c n t ] + ’ ” ’ ) ;
} else {
89
90
System . out . p r i n t ( ” , ” + ’ ” ’ + a c t i o n A r g s [ a r g s c n t ] + ’ ” ’ ) ;
}
91
92
}
93
94
break ;
95
96
97
case XMLStreamConstants .CHARACTERS:
break ;
98
99
case XMLStreamConstants .END ELEMENT:
100
// Mark l e a v i n g o f t a s k a r g s t a g
101
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” t a s k a r g s ” ) ) {
102
103
inTaskArgs = f a l s e ;
}
104
105
// E x e c u t e a c t i o n s w i t h e x a c t l y one argument and c l e a n up
106
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” a c t i o n ” ) ) {
107
System . out . p r i n t l n ( ” ) ; ” ) ;
108
i f ( actionName . e q u a l s ( ”move” ) ) {
109
r s . move ( robot , a c t i o n A r g s [ 0 ] ) ;
110
Thread . s l e e p ( 1 0 0 0 ) ;
111
} e l s e i f ( actionName . e q u a l s ( ” g r i p ” ) ) {
112
r s . g r i p ( robot , a c t i o n A r g s [ 0 ] ) ;
113
Thread . s l e e p ( 1 0 0 0 ) ;
114
} e l s e i f ( actionName . e q u a l s ( ” u n g r i p ” ) ) {
115
r s . u n g r i p ( robot , a c t i o n A r g s [ 0 ] ) ;
116
Thread . s l e e p ( 1 0 0 0 ) ;
117
} e l s e i f ( actionName . e q u a l s ( ” f i l l ” ) ) {
118
r s . f i l l ( robot , a c t i o n A r g s [ 0 ] , a c t i o n A r g s [ 1 ] ) ;
119
Thread . s l e e p ( 1 0 0 0 ) ;
120
} e l s e i f ( actionName . e q u a l s ( ” s e t C u r r e n t P o s i t i o n ” ) ) {
121
r s . c r e a t e W o r l d O b j e c t ( ” Waypoint ” ,
122
actionArgs [ 0 ] ,
123
( int ) r s . g e t P o s i t i o n ( r o b o t ) . getX ( ) ,
124
( int ) r s . g e t P o s i t i o n ( r o b o t ) . getY ( ) ,
125
( int ) r s . g e t P o s i t i o n ( r o b o t ) . getZ ( ) ) ;
126
Thread . s l e e p ( 1 0 0 0 ) ;
127
}
128
actionName = ”” ;
129
a r g s c n t = −1;
119
Kapitel D: Quelltexte
}
130
131
132
// R e s e t a c t i o n c o u n t e r .
133
i f ( p a r s e r . getLocalName ( ) . e q u a l s ( ” a r g s ” ) ) {
134
}
135
136
break ;
137
default :
138
break ;
139
}
140
p a r s e r . next ( ) ;
141
}
142
return r s ;
}
143
144 }
Listing 11: RtdlParser.java
D.7
Source.java
1 /∗ ∗
2
∗ Source . j a v a
3
∗ A s o u r c e t h a t p r o d u c e s some o u t p u t o f a sourceType .
4
∗ Examples a r e a t a p or a power s o c k e t .
5
∗
6
∗ @author Marcus Teske
7
∗/
8 package r t d l ;
9
10 public c l a s s S o u r c e extends WorldObject {
11
12
protected S t r i n g sourceType ;
13
14
S o u r c e ( S t r i n g objectName , S t r i n g sourceType ) {
15
super . setObjectName ( objectName ) ;
16
super . i s S o u r c e = true ;
17
t h i s . sourceType = sourceType ;
18
}
19
20
public S t r i n g getSourceType ( ) {
21
22
return t h i s . sourceType ;
}
23 }
120
Kapitel D: Quelltexte
Listing 12: Source.java
D.8
Tap.java
1 /∗ ∗
2
∗ Tap . j a v a
3
∗ A t a p t h a t can be used t o f i l l c o n t a i n e r −l i k e W o r l d O b j e c t s w i t h an
output .
4
∗
5
∗ @author Marcus Teske
6
∗/
7 package r t d l ;
8
9 public c l a s s Tap extends S o u r c e {
10
11
public Tap ( S t r i n g objectName ) {
12
super ( objectName , ” water ” ) ;
}
13
14 }
Listing 13: Tap.java
D.9
Wall.java
1 /∗ ∗
2
∗ Wall . j a v a
3
∗ A simple obstacle .
4
∗ @author Marcus Teske
5
∗/
6 package r t d l ;
7
8 public c l a s s Wall extends WorldObject {
9
10
Wall ( S t r i n g objectName ) {
11
super . setObjectName ( objectName ) ;
12
super . i s P a s s a b l e = f a l s e ;
13
}
14 }
Listing 14: Wall.java
121
Kapitel D: Quelltexte
D.10
Waypoint.java
1 /∗ ∗
2
∗ Waypoint . j a v a
3
∗ A simple waypoint .
4
∗ @author Marcus Teske
5
∗/
6 package r t d l ;
7
8 public c l a s s Waypoint extends WorldObject {
9
Waypoint ( S t r i n g objectName ) {
10
11
super . setObjectName ( objectName ) ;
}
12
13 }
Listing 15: Waypoint.java
D.11
World.java
1 /∗ ∗
2
∗ World . j a v a
3
∗ A World i s an environment c o n s i s t i n g o f m u l t i p l e WorldLocations
arranged in a
4
∗ 3D c o o r d i n a t e system . The World may c o n t a i n an a r b i t r a r y number o f
different
5
∗ W o r l d O b j e c t s o f d i f f e r e n t t y p e s t h a t a r e r e f e r e n c e d by u n i q u e names .
6
∗
7
∗ @author Marcus Teske
8
∗/
9 package r t d l ;
10
11 import j a v a . u t i l . HashMap ;
12 import j a v a . u t i l . A r r a y L i s t ;
13
14 public c l a s s World {
15
/∗ HashMap h o l d i n g W o r l d P o s i t i o n s ( c o o r d i n a t e s ) r e f e r e n c e d by
16
WorldObjectNames . ∗/
17
18
19
20
private HashMap<S t r i n g , WorldLocation> p o s i t i o n s =
new HashMap<S t r i n g , WorldLocation >() ;
/∗ Array h o l d i n g WorldLocations ( which c o n t a i n W o r l d O b j e c t s )
r e f e r e n c e d by
122
Kapitel D: Quelltexte
21
t h e i r c o o r d i n a t e s . ∗/
22
private WorldLocation w o r l d L o c a t i o n s [ ] [ ] [ ] ;
23
private int s i z e X ;
24
private int s i z e Y ;
25
private int s i z e Z ;
26
27
/∗ ∗
28
∗ Constructor
29
∗ @param x Spread o f t h e World a l o n g t h e x−a x i s .
30
∗ @param y Spread o f t h e World a l o n g t h e y−a x i s .
31
∗ @param z Spread o f t h e World a l o n g t h e z−a x i s .
∗/
32
33
World ( int x , int y , int z ) {
34
this . sizeX = x ;
35
this . sizeY = y ;
36
this . sizeZ = z ;
37
38
w o r l d L o c a t i o n s = new WorldLocation [ x ] [ y ] [ z ] ;
39
f o r ( int i = 0 ; i < x ; i ++) {
f o r ( int j = 0 ; j < y ; j ++) {
40
f o r ( int k = 0 ; k < z ; k++) {
41
42
w o r l d L o c a t i o n s [ i ] [ j ] [ k ] = new WorldLocation ( i , j , k ) ;
}
43
}
44
}
45
46
}
47
48
/∗ ∗
49
∗ Get t h e WorldLocation where t h e WorldObject w i t h name ”name” i s
50
∗ @param name Name o f t h e WorldObject t h a t r e f e r e n c e s t h e
located .
WorldLocation .
51
∗ @return TODO
52
∗/
53
public WorldLocation getWorldLocationByWorldObjectName ( S t r i n g name ) {
i f ( t h i s . c o n t a i n s ( name ) ) {
54
55
return p o s i t i o n s . g e t ( name ) ;
56
}
57
return null ;
58
}
59
60
/∗ ∗
61
∗ Get t h e WorldObject w i t h t h e name ”name”
62
∗ @param name Name o f t h e WorldObject .
123
Kapitel D: Quelltexte
∗/
63
64
public WorldObject getWorldObjectByName ( S t r i n g name ) {
i f ( t h i s . c o n t a i n s ( name ) ) {
65
66
WorldLocation wl = t h i s . getWorldLocationByWorldObjectName ( name ) ;
67
return t h i s . w o r l d L o c a t i o n s [ wl . getX ( ) ] [ wl . getY ( ) ] [ wl . getZ ( ) ]
68
. getWorldObject ( name ) ;
} else {
69
70
return null ;
}
71
72
}
73
74
/∗ ∗
75
∗ Gets t h e t y p e / c l a s s n a m e o f t h e WorldObject r e f e r e n c e d by ”name ” .
76
∗ @param name Unique name o f t h e WorldObject .
77
∗ @return Type/ c l a s s n a me o f t h e WorldObject .
78
∗/
79
public S t r i n g getWorldObjectType ( S t r i n g name ) {
80
81
return t h i s . getWorldObjectByName ( name ) . getObjectType ( ) ;
}
82
83
/∗ ∗
84
∗ Remove t h e WorldObject w i t h name ”name” from t h e World .
85
∗ @param name Name o f t h e WorldObject t o remove .
86
∗/
87
public boolean removeWorldObjectByName ( S t r i n g name ) {
i f ( t h i s . c o n t a i n s ( name ) ) {
88
89
WorldLocation wl = t h i s . getWorldLocationByWorldObjectName ( name ) ;
90
// Remove t h e WorldObject i t s e l f .
91
w o r l d L o c a t i o n s [ wl . getX ( ) ] [ wl . getY ( ) ] [ wl . getZ ( ) ] . removeWorldObject
92
// Remove t h e e n t r y from t h e p o s i t i o n s
93
t h i s . p o s i t i o n s . remove ( name ) ;
94
return true ;
( name ) ;
} else {
95
96
System . e r r . p r i n t l n ( ”ERROR: Cannot remove WorldObject ” + name
97
+ ” ! I t d o e s not e x i s t s ! ” ) ;
98
return f a l s e ;
}
99
100
}
101
102
103
/∗ ∗
∗ Remove t h e WorldObject w i t h name ”name” from t h e w o r l d and r e t u r n
it .
104
∗ @param name Name o f t h e WorldObject t o remove .
124
Kapitel D: Quelltexte
105
∗ @return The WorldObject t h a t has been removed from t h e World .
106
∗/
107
public WorldObject takeObjectByName ( S t r i n g name ) {
108
WorldObject wo = t h i s . getWorldObjectByName ( name ) ;
109
i f ( removeWorldObjectByName ( name ) ) {
110
return wo ;
111
}
112
return null ;
113
}
114
115
/∗ ∗
116
∗ P l a c e a WorldObject a t t h e WorldLocation s p e c i f i e d by wl .
117
∗ @param wo WorldObject t o p l a c e .
118
∗ @param wl WorldLocation where t h e WorldObject s h o u l d be p l a c e d .
119
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
120
∗/
121
public boolean s e t W o r l d O b j e c t ( WorldObject wo , WorldLocation wl ) {
122
123
return t h i s . s e t W o r l d O b j e c t ( wo , wl . getX ( ) , wl . getY ( ) , wl . getZ ( ) ) ;
}
124
125
/∗ ∗
126
∗ P l a c e a WorldObject a t t h e WorldLocation s p e c i f i e d by wp .
127
∗ @param wo WorldObject t o p l a c e .
128
∗ @param wp WorldLocation where t h e WorldObject s h o u l d be p l a c e d .
129
∗ @return t r u e i f t h e o p e r a t i o n was s u c c e s s f u l , f a l s e o t h e r w i s e .
130
∗/
131
public boolean s e t W o r l d O b j e c t ( WorldObject wo , W o r l d P o s i t i o n wp) {
132
return t h i s . s e t W o r l d O b j e c t ( wo ,
133
( int ) wp . getX ( ) ,
134
( int ) wp . getY ( ) ,
135
( int ) wp . getZ ( ) ) ;
136
}
137
138
/∗ ∗
139
∗ P l a c e a WorldObject a t t h e WorldLocation s p e c i f i e d by x , y and z .
140
∗ @param wo WorldObject t o p l a c e .
141
∗ @param x X−c o o r d i n a t e o f t h e L o c a t i o n .
142
∗ @param y Y−c o o r d i n a t e o f t h e L o c a t i o n .
143
∗ @param z Z−c o o r d i n a t e o f t h e L o c a t i o n .
144
∗ @return Returns t r u e i f t h e WorldObject has been p l a c e d , f a l s e i f
not .
145
146
147
∗/
public boolean s e t W o r l d O b j e c t ( WorldObject wo , int x , int y , int z ) {
i f ( this . l o c a t i o n V a l i d (x , y , z ) ) {
125
Kapitel D: Quelltexte
148
t h i s . p o s i t i o n s . put (wo . getObjectName ( ) , new WorldLocation ( x , y , z )
);
149
t h i s . w o r l d L o c a t i o n s [ x ] [ y ] [ z ] . s e t W o r l d O b j e c t (wo) ;
150
return true ;
} else {
151
152
return f a l s e ;
}
153
154
}
155
156
/∗ ∗
157
∗ Checks i f a WorldObject w i t h ObjectName ”name” e x i s t s i n t h e w o r l d
158
∗ @param name Unique name o f t h e WorldObject .
159
∗ @return True i f t h e O b j e c t e x i s t s , F a l s e o t h e r w i s e .
160
∗/
.
161
public boolean c o n t a i n s ( S t r i n g name ) {
162
163
return t h i s . p o s i t i o n s . c o n t a i n s K e y ( name ) ;
}
164
165
/∗ ∗
166
∗ Gets t h e names o f a l l O b j e c t s i n t h e World as s t r i n g a r r a y .
167
∗ @return S t r i n g a r r a y w i t h t h e names o f a l l W o r l d O b j e c t s i n t h i s
world .
∗/
168
169
public S t r i n g [ ] getWorldObjectNames ( ) {
170
S t r i n g [ ] s a = new S t r i n g [ t h i s . p o s i t i o n s . k e y S e t ( ) . s i z e ( ) ] ;
171
int i = 0 ;
172
for ( S t r i n g s : this . p o s i t i o n s . keySet ( ) ) {
173
sa [ i ] = s ;
174
i ++;
175
}
176
return s a ;
177
}
178
179
/∗ ∗
180
∗ Checks w h e t h e r a WorldLocation / W o r l d P o s i t i o n i s v a l i d or not .
181
∗ @param x x−c c o r d i n a t e o f t h e WorldLocation / W o r l d P o s i t i o n .
182
∗ @param y y−c c o r d i n a t e o f t h e WorldLocation / W o r l d P o s i t i o n .
183
∗ @param z z−c c o r d i n a t e o f t h e WorldLocation / W o r l d P o s i t i o n .
184
∗ @return True i f t h e c o o r d i n a t e s a r e v a l i d , F a l s e i f not .
185
∗/
186
187
public boolean l o c a t i o n V a l i d ( int x , int y , int z ) {
i f ( x >= t h i s . s i z e X | | x < 0 ) {
126
Kapitel D: Quelltexte
188
System . e r r . p r i n t l n ( ”ERROR: WordLocation [ ” + x + ” , ” + y + ” , ” +
z
189
+ ” ] i n v a l i d : X−c o o r d i n a t e i s ” + ” o u t s i d e o f t h i s world ’
s ”
190
+ ” boundaries ! ” ) ;
191
return f a l s e ;
192
}
193
i f ( y >= t h i s . s i z e Y | | y < 0 ) {
194
System . e r r . p r i n t l n ( ”ERROR: WordLocation [ ” + x + ” , ” + y + ” , ” +
z
195
+ ” ] i n v a l i d : Y−c o o r d i n a t e i s ” + ” o u t s i d e o f t h i s world ’
196
+ ” boundaries ! ” ) ;
s ”
197
return f a l s e ;
198
}
199
i f ( z >= t h i s . s i z e Z | | z < 0 ) {
200
System . e r r . p r i n t l n ( ”ERROR: WordLocation [ ” + x + ” , ” + y + ” , ” +
z
201
+ ” ] i n v a l i d : Z−c o o r d i n a t e i s ” + ” o u t s i d e o f t h i s world ’
s ”
202
+ ” boundaries ! ” ) ;
203
return f a l s e ;
204
}
205
return true ;
206
}
207
208
/∗ ∗
209
∗ Checks w h e t h e r a WorldLocation / W o r l d P o s i t i o n i s v a l i d or not .
210
∗ @param wp W o r l d P o s i t i o n t o c h e c k .
211
∗ @return True i f t h e c o o r d i n a t e s a r e v a l i d , F a l s e i f not .
212
∗/
213
public boolean l o c a t i o n V a l i d ( W o r l d P o s i t i o n wp) {
214
return t h i s . l o c a t i o n V a l i d ( ( int ) wp . getX ( ) , ( int ) wp . getY ( ) , ( int )
wp . getZ ( ) ) ;
215
}
216
217
public int g e t S i z e X ( ) {
218
219
return s i z e X ;
}
220
221
public int g e t S i z e Y ( ) {
222
223
return s i z e Y ;
}
224
127
Kapitel D: Quelltexte
public int g e t S i z e Z ( ) {
225
226
return s i z e Z ;
}
227
228
/∗ ∗
229
230
∗ Gets a l l W o r l d O b j e c t s from t h e s p e c i f i e d WorldLocation .
231
∗ @param x x−c c o r d i n a t e o f t h e l o c a t i o n
232
∗ @param y y−c c o r d i n a t e o f t h e l o c a t i o n
233
∗ @param z z−c c o r d i n a t e o f t h e l o c a t i o n
234
∗ @return A l l O b j e c t s from t h a t l o c a t i o n
235
∗/
236
public A r r a y L i s t <WorldObject> g e t A l l O b j e c t s F r o m L o c a t i o n ( int x , int y ,
int z ) {
237
return t h i s . w o r l d L o c a t i o n s [ x ] [ y ] [ z ] . g e t O b j e c t s ( ) ;
}
238
239
/∗ ∗
240
241
∗ Returns w h e t h e r a l o c a t i o n i s p a s s a b l e or not .
242
∗ @param x x−c c o r d i n a t e o f t h e l o c a t i o n
243
∗ @param y y−c c o r d i n a t e o f t h e l o c a t i o n
244
∗ @param z z−c c o r d i n a t e o f t h e l o c a t i o n
245
∗ @return t r u e i f t h e l o c a t i o n i s p a s s a b l e , f a l s e o t h e r w i s e
246
∗/
public boolean i s P a s s a b l e ( int x , int y , int z ) {
247
248
return t h i s . w o r l d L o c a t i o n s [ x ] [ y ] [ z ] . i s P a s s a b l e ( ) ;
}
249
250
/∗ ∗
251
252
∗ Returns w h e t h e r a l o c a t i o n i s p a s s a b l e or not .
253
∗ @param pos P o s t i o n o f t h e l o c a t i o n
254
∗ @return t r u e i f t h e l o c a t i o n i s p a s s a b l e , f a l s e o t h e r w i s e
255
∗/
public boolean i s P a s s a b l e ( W o r l d P o s i t i o n pos ) {
256
257
return t h i s . w o r l d L o c a t i o n s [ ( int ) pos . getX ( ) ] [ ( int ) pos . getY ( ) ] [ ( int
) pos
258
. getZ ( ) ] . i s P a s s a b l e ( ) ;
}
259
260 }
Listing 16: World.java
D.12
WorldLocation.java
128
Kapitel D: Quelltexte
1 /∗ ∗
2
∗ WorldLocation . j a v a
3
∗ A WorldLocation i s a l o c a t i o n w i t h i n a World . I t c o n t a i n s a u n i q u e
4
∗ L o c a t i o n and can h o l d an a r b i t r a r y number o f named W o r l d o b j e c t s .
5
∗
6
∗ @author Marcus Teske
7
∗/
8 package r t d l ;
9
10 import j a v a . u t i l . HashMap ;
11 import j a v a . u t i l . A r r a y L i s t ;
12
13 public c l a s s WorldLocation {
14
/∗ The W o r l d P o s i t i o n o f t h i s WorldLocation . ∗/
15
16
W o r l d P o s i t i o n pos ;
17
/∗ A map where W o r l d O b j e c t s l o c a t e d i n t h i s L o c a t i o n a r e s t o r e d and
referenced
18
∗ by t h e i r u n i q u e name .
19
∗/
20
HashMap<S t r i n g , WorldObject> o b j e c t s = new HashMap<S t r i n g ,
WorldObject >() ;
21
22
/∗ ∗
23
∗ C o n s t r u c t o r o f WorldLoction
24
∗ @param x The x−c o o r d i n a t e .
25
∗ @param y The y−c o o r d i n a t e .
26
∗ @param z The z−c o o r d i n a t e .
27
∗/
28
WorldLocation ( int x , int y , int z ) {
29
30
pos = new W o r l d P o s i t i o n ( ( long ) x , ( long ) y , ( long ) z ) ;
}
31
32
/∗ ∗
33
∗ Get t h e named WorldObject r e f e r e n c e d by i t s u n i q u e name .
34
∗ @param name The u n i q u e name o f t h e named WorldObject .
35
∗ @return The named WorldObject .
36
∗/
37
public WorldObject getWorldObject ( S t r i n g name ) {
38
39
return ( WorldObject ) o b j e c t s . g e t ( name ) ;
}
40
41
/∗ ∗
129
Kapitel D: Quelltexte
∗ S t o r e a WorldObject i n d e x e d by i t s u n i q u e name i n t h e l o c a t i o n ’ s
42
object
43
∗ pool .
44
∗ @param wo WorldObject t o s t o r e .
45
∗/
46
public void s e t W o r l d O b j e c t ( WorldObject wo) {
47
t h i s . o b j e c t s . put (wo . getObjectName ( ) , wo) ;
48
}
49
50
/∗ ∗
51
∗ Gets t h e p o s t i o n o f t h i s WorldLocation as p o s i t i o n o b j e c t .
52
∗ @return P o s i t i o n as p o s i t i o n o b j e c t .
53
∗/
54
public W o r l d P o s i t i o n getPos ( ) {
55
56
return pos ;
}
57
58
/∗ ∗
59
∗ S e t s a new p o s i t i o n f o r t h i s WorldLocation .
60
∗ @param pos new p o s i t i o n f o r t h i s WorldLocation .
∗/
61
62
public void s e t P o s ( W o r l d P o s i t i o n pos ) {
63
64
t h i s . pos = pos ;
}
65
66
/∗ ∗
∗ Gets t h e d i s t a n c e from t h e o r i g i n a l o n g t h e x−a x i s o f t h i s
67
WorldLocation .
∗ @return D i s t a n c e t o t h e o r i g i n a l o n g t h e x−a x i s .
68
∗/
69
70
public int getX ( ) {
71
72
return ( int ) t h i s . pos . getX ( ) ;
}
73
74
/∗ ∗
∗ Gets t h e d i s t a n c e from t h e o r i g i n a l o n g t h e y−a x i s o f t h i s
75
WorldLocation .
76
∗ @return D i s t a n c e t o t h e o r i g i n a l o n g t h e y−a x i s .
77
∗/
78
public int getY ( ) {
79
80
return ( int ) t h i s . pos . getY ( ) ;
}
81
82
/∗ ∗
130
Kapitel D: Quelltexte
∗ Gets t h e d i s t a n c e from t h e o r i g i n a l o n g t h e z−a x i s o f t h i s
83
WorldLocation .
84
∗ @return D i s t a n c e t o t h e o r i g i n a l o n g t h e z−a x i s .
85
∗/
86
public int getZ ( ) {
87
88
return ( int ) t h i s . pos . getZ ( ) ;
}
89
90
/∗ ∗
91
∗ Remove t h e WorldObject w i t h name ”name ” .
92
∗ @param name Name o f t h e WorldObject t o remove .
∗/
93
94
public void removeWorldObject ( S t r i n g name ) {
95
96
t h i s . o b j e c t s . remove ( name ) ;
}
97
98
/∗ ∗
∗ Get t h e t y p e / c l a s s n a m e o f an named o b j e c t s e l e c t e d by i t s u n i q u e
99
name .
100
∗ @param name Unique name o f an named o b j e c t i n t h e World .
101
∗ @return The t y p e / c l a s s n a m e o f t h e named o b j e c t .
102
∗/
103
public S t r i n g getWorldObjectType ( S t r i n g name ) {
104
105
return t h i s . getWorldObject ( name ) . getObjectType ( ) ;
}
106
107
/∗ ∗
108
∗ Gets a l l o b j e c t s o f t h i s l o c a t i o n as A r r a y L i s t <WorldObject>
109
∗ @return A l l O b j e c t s as A r r a y L i s t
∗/
110
111
public A r r a y L i s t <WorldObject> g e t O b j e c t s ( ) {
112
113
return new A r r a y L i s t <WorldObject >( t h i s . o b j e c t s . v a l u e s ( ) ) ;
}
114
115
/∗ ∗
116
∗ Returns w h e t h e r t h i s l o c a t i o n c o n t a i n s any i m p a s s a b l e o b j e c t s .
117
∗ @return t r u e i f a l l o b j e c t s a r e p a s s a b l e , f a l s e o t h e r w i s e .
118
119
∗/
public boolean i s P a s s a b l e ( ) {
120
A r r a y L i s t <WorldObject> wos = t h i s . g e t O b j e c t s ( ) ;
121
f o r ( WorldObject wo : wos ) {
122
i f ( ! wo . i s P a s s a b l e ) {
123
124
return f a l s e ;
}
131
Kapitel D: Quelltexte
125
}
126
return true ;
}
127
128 }
Listing 17: WorldLocation.java
D.13
WorldObject.java
1 /∗ ∗
2
∗ WorldObject . j a v a
3
∗ A c l a s s t h a t r e p r e s e n t s the g e n e r a l f e a t u r e s of a l l WorldObjects .
These
4
∗ f e a t u r e s a r e t h e u n i q u e name o f an o b j e c t and t h e t y p e o f an o b j e c t .
5
∗
6
∗ @author Marcus Teske
7
∗/
8 package r t d l ;
9
10 public c l a s s WorldObject {
11
12
private S t r i n g objectName ;
13
// WorldObject ’ s p r e d i c a t e s
14
protected boolean canMove = f a l s e ;
15
protected boolean i s G r i p p e a b l e = f a l s e ;
16
protected boolean i s P a s s a b l e = true ;
17
protected boolean i s C o n t a i n e r = f a l s e ;
18
protected boolean i s S o u r c e = f a l s e ;
19
20
/∗ ∗
21
∗ Get t h e name o f t h i s WorldObject .
22
∗ @return The name o f t h i s o b j e c t .
23
∗/
24
public S t r i n g getObjectName ( ) {
25
26
return objectName ;
}
27
28
/∗ ∗
29
∗ S e t s t h e name o f an WorldObject .
30
∗ @param name The new name t o s e t .
31
32
33
∗/
public void setObjectName ( S t r i n g name ) {
t h i s . objectName = name ;
132
Kapitel D: Quelltexte
34
}
35
36
/∗ ∗
37
∗ Gets t h e c l a s s n a m e / t y p e o f t h i s WorldObject .
38
∗ @return The ObjectType o f t h i s WorldObject as S t r i n g .
39
∗/
40
public S t r i n g getObjectType ( ) {
41
42
return t h i s . g e t C l a s s ( ) . getSimpleName ( ) ;
}
43
44
/∗ ∗
45
∗ P l a c e h o l d e r method f o r moving i n s i d e t h e w o r l d .
46
∗ @param w The w o r l d t h e a c t i o n t a k e s p l a c e i n .
47
∗ @param x The x−c o o r d i n a t e o f t h e d e t i n a t i o n .
48
∗ @param y The y−c o o r d i n a t e o f t h e d e t i n a t i o n .
49
∗ @param z The z−c o o r d i n a t e o f t h e d e t i n a t i o n .
50
∗ @return f a l s e
51
∗/
52
public boolean move ( World w, int x , int y , int z ) {
i f ( ! t h i s . canMove ) {
53
54
System . e r r . p r i n t l n ( ”WARNING: A ” + t h i s . getObjectType ( )
55
+ ” cannot move ! ” ) ;
} else {
56
57
System . e r r . p r i n t l n ( ”WARNING: Movement o f ” + t h i s . getObjectType ( )
58
+ ” not y e t implemented ! ” ) ;
59
}
60
return f a l s e ;
61
}
62
63
public WorldObject getArmPayload ( ) {
64
System . e r r . p r i n t l n ( ”WARNING: A ” + t h i s . getObjectName ( )
65
+ ” has no arm ! ” ) ;
66
67
return null ;
}
68
69
/∗ ∗
70
∗ P l a c e h o l d e r method f o r f i l l i n g a c o n t a i n e r WorldObject w i t h a
71
∗ content type .
72
∗ @param c o n t e n t T y p e Type o f c o n t e n t t o f i l l t h e c o n t a i n e r w i t h .
73
∗ @return f a l s e
74
∗/
c e r t a i n#
75
76
public boolean f i l l C o n t a i n e r ( World w, S t r i n g contentType ) {
i f ( ! this . isContainer ) {
133
Kapitel D: Quelltexte
77
System . e r r . p r i n t l n ( ”WARNING: A ” + t h i s . getObjectType ( )
78
+ ” i s not a c o n t a i n e r ! ” ) ;
} else {
79
80
System . e r r . p r i n t l n ( ”WARNING: F i l l i n g o f ” + t h i s . getObjectType ( )
81
+ ” not y e t implemented ! ” ) ;
82
}
83
return f a l s e ;
}
84
85
/∗ ∗
86
87
∗ P l a c e h o l d e r method f o r emptying a c o n t a i n e r WorldObject .
88
∗ @return f a l s e
89
∗/
public boolean emptyContainer ( ) {
90
i f ( ! this . isContainer ) {
91
92
System . e r r . p r i n t l n ( ”WARNING: A ” + t h i s . getObjectType ( )
93
+ ” i s not a c o n t a i n e r ! ” ) ;
} else {
94
95
System . e r r . p r i n t l n ( ”WARNING: Emptying o f ” + t h i s . getObjectType ( )
96
+ ” not y e t implemented ! ” ) ;
97
}
98
return f a l s e ;
}
99
100
public boolean g r i p ( World w, S t r i n g name ) {
101
102
return f a l s e ;
}
103
104
public boolean u n g r i p ( World w, S t r i n g name ) {
105
106
return f a l s e ;
}
107
108 }
Listing 18: WorldObject.java
D.14
WorldPosition.java
1 /∗ ∗
2
∗ WorldPosition . java
3
∗ A W o r l d P o s i t i o n i s a P o i n t w i t h i n a World t h a t i s s p e c i f i e d by i t s x
4
∗ z−c o o r d i n a t e i n a 3D c o o r d i n a t e system .
5
∗
−, y− and
134
Kapitel D: Quelltexte
6
∗ @author Marcus Teske
7
∗/
8 package r t d l ;
9
10 public c l a s s W o r l d P o s i t i o n {
11
12
private long x ;
13
private long y ;
14
private long z ;
15
16
/∗ ∗
17
∗ Constructor of WorldPosition .
18
∗ @param x The x−c o o r d i n a t e .
19
∗ @param y The y−c o o r d i n a t e .
20
∗ @param z The z−c o o r d i n a t e .
21
∗/
22
public W o r l d P o s i t i o n ( long x , long y , long z ) {
23
this . x = x ;
24
this . y = y ;
25
this . z = z ;
26
}
27
28
/∗ ∗
∗ Gets t h e d i s t a n c e from t h e o r i g i n a l o n g t h e x−a x i s o f t h i s
29
WorldLocation .
30
∗ @return D i s t a n c e t o t h e o r i g i n a l o n g t h e x−a x i s .
31
∗/
32
public long getX ( ) {
33
34
return x ;
}
35
36
/∗ ∗
∗ S e t s t h e d i s t a n c e from t h e o r i g i n a l o n g t h e x−a x i s o f t h i s
37
WorldLocation .
∗/
38
39
public void setX ( long x ) {
40
41
this . x = x ;
}
42
43
44
/∗ ∗
∗ Gets t h e d i s t a n c e from t h e o r i g i n a l o n g t h e y−a x i s o f t h i s
WorldLocation .
45
∗ @return D i s t a n c e t o t h e o r i g i n a l o n g t h e y−a x i s .
46
∗/
135
Kapitel D: Quelltexte
47
public long getY ( ) {
48
49
return y ;
}
50
51
/∗ ∗
∗ S e t s t h e d i s t a n c e from t h e o r i g i n a l o n g t h e y−a x i s o f t h i s
52
WorldLocation .
∗/
53
54
public void setY ( long y ) {
55
56
this . y = y ;
}
57
58
/∗ ∗
∗ Gets t h e d i s t a n c e from t h e o r i g i n a l o n g t h e z−a x i s o f t h i s
59
WorldLocation .
60
∗ @return D i s t a n c e t o t h e o r i g i n a l o n g t h e z−a x i s .
61
∗/
62
public long getZ ( ) {
63
64
return z ;
}
65
66
/∗ ∗
∗ S e t s t h e d i s t a n c e from t h e o r i g i n a l o n g t h e z−a x i s o f t h i s
67
WorldLocation .
∗/
68
69
public void s e t Z ( long z ) {
70
71
this . z = z ;
}
72
73
public long g e t O f f s e t X ( W o r l d P o s i t i o n wp) {
return wp . getX ( ) − t h i s . getX ( ) ;
74
75
}
76
77
public long g e t O f f s e t Y ( W o r l d P o s i t i o n wp) {
return wp . getY ( ) − t h i s . getY ( ) ;
78
79
}
80
81
public long g e t O f f s e t Z ( W o r l d P o s i t i o n wp) {
return wp . getZ ( ) − t h i s . getZ ( ) ;
82
83
}
84
85
86
87
public boolean e q u a l s ( W o r l d P o s i t i o n wp) {
return ( t h i s . getX ( ) == wp . getX ( ) && t h i s . getY ( ) == wp . getY ( ) &&
t h i s . getZ ( ) == wp . getZ ( ) ) ;
136
Kapitel D: Quelltexte
}
88
89 }
Listing 19: WorldPosition.java
D.15
fetchWater.xml
1 <?xml v e r s i o n=” 1 . 0 ” e n c o d i n g=”UTF−8”?>
2 <?xml−s t y l e s h e e t type=” t e x t /xml” h r e f=” r t d l . x s l ” v e r s i o n=” 1 . 0 ”?>
3 <r t d l v e r s i o n=” 1 . 0 ”>
4
5
<t a s k name=” f e t c h W a t e r ”>
<t a s k a r g s >
6
<var type=” D r i n k i n g G l a s s ”>Glass1 </var>
7
<var type=”Tap”>Tap1</var>
8
</ t a s k a r g s >
9
<e n t i t i e s >
10
<var type=” Waypoint ”>s t a r t </var>
11
</ e n t i t i e s >
12
<blo ck >
13
<a c t i o n >
14
<name>s e t C u r r e n t P o s i t i o n </name>
15
<a r g s >
16
<arg>S t a r t </arg>
17
</a r g s >
18
</a c t i o n >
19
<a c t i o n >
20
<name>move</name>
21
<a r g s >
22
<arg>Glass1 </arg>
23
</a r g s >
24
</a c t i o n >
25
<a c t i o n >
26
<name>g r i p </name>
27
<a r g s >
28
<arg>Glass1 </arg>
29
</a r g s >
30
</a c t i o n >
31
<a c t i o n >
32
<name>move</name>
33
<a r g s >
34
<arg>Tap1</arg>
35
</a r g s >
36
</a c t i o n >
137
Kapitel D: Quelltexte
37
<a c t i o n >
38
<name>ungrip </name>
39
<a r g s >
40
<arg>Glass1 </arg>
41
</a r g s >
42
</a c t i o n >
43
<a c t i o n >
44
<name> f i l l </name>
45
<a r g s >
46
<arg>Tap1</arg>
47
<arg>Glass1 </arg>
48
</a r g s >
49
</a c t i o n >
50
<a c t i o n >
51
<name>g r i p </name>
52
<a r g s >
53
<arg>Glass1 </arg>
54
</a r g s >
55
</a c t i o n >
56
<a c t i o n >
57
<name>move</name>
58
<a r g s >
59
<arg>S t a r t </arg>
60
</a r g s >
61
</a c t i o n >
62
<a c t i o n >
63
<name>ungrip </name>
64
<a r g s >
65
<arg>Glass1 </arg>
66
</a r g s >
67
</a c t i o n >
68
69
</bloc k >
</task >
70 </ r t d l >
Listing 20: fetchWater.xml
D.16
rtdl.xsl
1 <?xml v e r s i o n=” 1 . 0 ” e n c o d i n g=”UTF−8”?>
2 <x s l : s t y l e s h e e t
3
v e r s i o n=” 2 . 0 ”
4
xmlns : x s l=” h t t p : / /www. w3 . o r g /1999/XSL/ Transform ”
138
Kapitel D: Quelltexte
5
xmlns : w=” h t t p : / / w i z z a r d . dyndns . i n f o ”
6>
7
<x s l : output method=” html ” i n d e n t=” y e s ”/>
8
9
<!−− This s t y l e s h e e t t r a n s f o r m s t h e xml r e p r e s e n t a t i o n o f an d e f i n e d
RTDL t a s k
10
i n t o i t the f u n c t i o n a l syntax .
11
Author : Marcus Teske
12
Date : 2011−01−11
13
−−>
14
15
<!−− S t a r t s t h e t r a n s f o r m a t i o n . −−>
16
<x s l : t e m p l a t e match=” / ”>
17
18
<html>
<head>
19
< t i t l e ><x s l : v alue −o f s e l e c t=” / r t d l / t a s k /@name”/></ t i t l e >
20
<s t y l e >
21
p {
22
margin− l e f t : 2em ;
23
f o n t −f a m i l y : monospace ;
f o n t −s i z e : 12 px ;
24
25
}
26
p . root {
27
margin− l e f t : 0em ;
}
28
29
</ s t y l e >
30
</head>
31
<body>
32
33
34
35
<x s l : apply−t e m p l a t e s />
</body>
</html>
</ x s l : template >
36
37
<!−− C r e a t e t h e ” r t d l <v e r s i o n >” l i n e . −−>
38
<x s l : t e m p l a t e match=” r t d l ”>
39
40
41
<p c l a s s=” r o o t ”>
<x s l : t e x t >r t d l </ x s l : t e x t >
<x s l : v alue −o f s e l e c t=” @ v e r s i o n ”/>
42
</p>
43
<x s l : apply−t e m p l a t e s/>
44
</ x s l : template >
45
46
<!−− Transforms t h e comment e l e m e n t s . −−>
47
<x s l : t e m p l a t e match=”comment”>
139
Kapitel D: Quelltexte
48
<p c l a s s=” r o o t ”>
49
<x s l : t e x t >/∗ </ x s l : t e x t >
50
< x s l : v a l u e −o f s e l e c t =”.”/>
51
< x s l : t e x t > ∗/</ x s l : t e x t >
52
53
</p>
</ x s l : template >
54
55
<!−− C r e a t e s t h e s i g n a t u r e o f t h e d e f i n e d t a s k . −−>
56
<x s l : t e m p l a t e match=” t a s k ”>
57
<p c l a s s=” r o o t ”>
58
<x s l : v alue −o f s e l e c t=”@name”/>
59
<x s l : t e x t >(</ x s l : t e x t >
60
<x s l : for−each s e l e c t=” t a s k a r g s / var ”>
61
<x s l : v alue −o f s e l e c t=” @type ”/>
62
<x s l : t e x t > </ x s l : t e x t >
63
<x s l : apply−t e m p l a t e s/>
64
<x s l : i f t e s t=” not ( p o s i t i o n ( )=l a s t ( ) ) ”>
65
66
<x s l : t e x t >, </ x s l : t e x t >
</ x s l : i f >
67
</ x s l : for−each>
68
<x s l : t e x t >) {</ x s l : t e x t >
69
<br/>
70
<x s l : apply−t e m p l a t e s s e l e c t=” r e t r y c o u n t ”/>
71
<br/>
72
<x s l : apply−t e m p l a t e s s e l e c t=” e n t i t i e s ”/>
73
<br/>
74
<x s l : apply−t e m p l a t e s s e l e c t=” b l o c k ” />
75
<br/>
76
<x s l : t e x t >}</ x s l : t e x t >
77
78
</p>
</ x s l : template >
79
80
<!−− C r e a t e comma s e p a r a t e d l i s t o f arguments and t h e i r t y p e s . −−>
81
<x s l : t e m p l a t e match=” a r g s ”>
82
83
<x s l : for−each s e l e c t=” var ”>
<x s l : v alue −o f s e l e c t=” @type ”/>
84
<x s l : t e x t > </ x s l : t e x t >
85
<x s l : apply−t e m p l a t e s/>
86
<x s l : i f t e s t=” not ( p o s i t i o n ( )=l a s t ( ) ) ”>
87
88
89
90
<x s l : t e x t >, </ x s l : t e x t >
</ x s l : i f >
</ x s l : for−each>
</ x s l : template >
91
140
Kapitel D: Quelltexte
92
<!−− C r e a t e comma s e p a r a t e d l i s t o f arguments w i t h o u t t h e i r t y p e s .
−−>
93
94
<x s l : t e m p l a t e match=” a r g s ”>
<x s l : for−each s e l e c t=” var ”>
95
<x s l : apply−t e m p l a t e s/>
96
<x s l : i f t e s t=” not ( p o s i t i o n ( )=l a s t ( ) ) ”>
97
<x s l : t e x t >, </ x s l : t e x t >
98
99
100
</ x s l : i f >
</ x s l : for−each>
</ x s l : template >
101
102
<!−− Transforms t h e r e t r y c o u n t e l e m e n t . −−>
103
<x s l : t e m p l a t e match=” r e t r y c o u n t ”>
104
<p>
105
<x s l : t e x t >r e t r y c o u n t (</ x s l : t e x t >
106
<x s l : v alue −o f s e l e c t=” . ”/>
107
<x s l : t e x t >);</ x s l : t e x t >
108
109
</p>
</ x s l : template >
110
111
<!−− C r e a t e f o r each e n t i t y a l i n e ” e n t i t y <type> <name>;” . −−>
112
<x s l : t e m p l a t e match=” e n t i t i e s ”>
113
<x s l : for−each s e l e c t=” var ”>
114
<p>
115
<x s l : t e x t >e n t i t y </ x s l : t e x t >
116
<x s l : v alue −o f s e l e c t=” @type ”/>
117
<x s l : t e x t > </ x s l : t e x t >
118
<x s l : apply−t e m p l a t e s/>
119
<x s l : t e x t >;</ x s l : t e x t >
120
121
122
</p>
</ x s l : for−each>
</ x s l : template >
123
124
<!−− Transforms b lock −e l e m e n t s . −−>
125
<x s l : t e m p l a t e match=” b l o c k ”>
126
<x s l : apply−t e m p l a t e s s e l e c t=” a c t i o n ”/>
127
<x s l : apply−t e m p l a t e s s e l e c t=” w h i l e ”/>
128
<x s l : apply−t e m p l a t e s s e l e c t=” i f ”/>
129
<x s l : apply−t e m p l a t e s s e l e c t=” par ”/>
130
</ x s l : template >
131
132
<!−− Transforms r e t r y −e l e m e n t s . −−>
133
<x s l : t e m p l a t e match=” r e t r y ”>
134
<p>
141
Kapitel D: Quelltexte
135
<x s l : t e x t >r e t r y (</ x s l : t e x t >
136
<x s l : v alue −o f s e l e c t=” @count ”/>
137
<x s l : t e x t >)</ x s l : t e x t >
138
<x s l : apply−t e m p l a t e s/>
139
<x s l : t e x t >endtry </ x s l : t e x t >
140
</p>
141
</ x s l : template >
142
143
<!−− t r a n s f o r m s a c t i o n s t o a f u n c t i o n c a l l . −−>
144
<x s l : t e m p l a t e match=” a c t i o n ”>
145
<p>
146
<x s l : i f t e s t=” @ o p t i o n a l =’ t r u e ’ ”>
147
<x s l : t e x t >o p t i o n a l </ x s l : t e x t >
148
</ x s l : i f >
149
<x s l : v alue −o f s e l e c t=”name”/>
150
<x s l : t e x t >(</ x s l : t e x t >
151
<x s l : for−each s e l e c t=” a r g s / a r g ”>
152
<x s l : apply−t e m p l a t e s/>
153
<x s l : i f t e s t=” not ( p o s i t i o n ( )=l a s t ( ) ) ”>
154
<x s l : t e x t >, </ x s l : t e x t >
155
</ x s l : i f >
156
</ x s l : for−each>
157
<x s l : apply−t e m p l a t e s s e l e c t=” a r g s ”/>
158
<x s l : t e x t >);</ x s l : t e x t >
159
160
</p>
</ x s l : template >
161
162
<!−− Transforms while−b l o c k s . −−>
163
<x s l : t e m p l a t e match=” w h i l e ”>
164
<p>
165
<x s l : t e x t >while</ x s l : t e x t >
166
<x s l : t e x t >(</ x s l : t e x t >
167
<x s l : apply−t e m p l a t e s s e l e c t=” cond ”/>
168
<x s l : t e x t >)</ x s l : t e x t >
169
<br/>
170
<x s l : t e x t >do</ x s l : t e x t >
171
<x s l : apply−t e m p l a t e s s e l e c t=” b l o c k ”/>
172
173
174
<x s l : t e x t >done</ x s l : t e x t >
</p>
</ x s l : template >
175
176
<!−− Transforms c o n d i t i o n o f a while b l o c k a s i s . −−>
177
<x s l : t e m p l a t e match=” cond ”>
178
<x s l : v alue −o f s e l e c t=” . ”/>
142
Kapitel D: Quelltexte
179
</ x s l : template >
180
181
<!−− Transforms i f −b l o c k . −−>
182
<x s l : t e m p l a t e match=” i f ”>
183
<p>
184
<x s l : t e x t >i f </ x s l : t e x t >
185
<x s l : t e x t >(</ x s l : t e x t >
186
<x s l : apply−t e m p l a t e s s e l e c t=” cond ”/>
187
<x s l : t e x t >)</ x s l : t e x t >
188
<br/>
189
<x s l : apply−t e m p l a t e s s e l e c t=” b l o c k ”/>
190
191
192
<x s l : t e x t >e n d i f </ x s l : t e x t >
</p>
</ x s l : template >
193
194
<!−− Transforms par−b l o c k s . −−>
195
<x s l : t e m p l a t e match=” par ”>
196
<p>
197
<x s l : t e x t >par </ x s l : t e x t >
198
<br/>
199
<x s l : apply−t e m p l a t e s s e l e c t=” b l o c k ”/>
200
<x s l : t e x t >to </ x s l : t e x t >
201
<br/>
202
<x s l : apply−t e m p l a t e s s e l e c t=” b l o c k 2 ”/>
203
<x s l : t e x t >endpar </ x s l : t e x t >
204
205
</p>
</ x s l : template >
206
207
<!−− Transforms f i r s t b l o c k o f par . −−>
208
<x s l : t e m p l a t e match=” b l o c k 1 ”>
209
210
<x s l : apply−t e m p l a t e s/>
</ x s l : template >
211
212
<!−− Transforms s e c o n d b l o c k o f par . −−>
213
<x s l : t e m p l a t e match=” b l o c k 2 ”>
214
215
<x s l : apply−t e m p l a t e s/>
</ x s l : template >
216
217 </ x s l : s t y l e s h e e t >
Listing 21: rtdl.xsl
D.17
rtdl.dtd
143
Kapitel D: Quelltexte
1 <!−− RTDL v1 . 0 Document Type D e f i n i t i o n −−>
2
3 <!ELEMENT r t d l ( comment ∗ , task , comment ∗ )>
4 <!ATTLIST r t d l
5
v e r s i o n CDATA #REQUIRED
6>
7 <!ELEMENT comment (#PCDATA)>
8 <!ELEMENT t a s k ( comment ∗ ,
9
taskargs ,
10
comment ∗ ,
11
retrycount ? ,
12
comment ∗ ,
13
entities ,
14
comment ∗ ,
15
b lock ,
16
comment∗
17 )>
18 <!ATTLIST t a s k
19
name CDATA #REQUIRED
20 >
21 <!ELEMENT t a s k a r g s ( var | comment )∗>
22 <!ELEMENT var (#PCDATA)>
23 <!ATTLIST var
24
type CDATA #REQUIRED
25 >
26 <!ELEMENT r e t r y c o u n t (#PCDATA)>
27 <!ELEMENT e n t i t i e s ( var | comment )∗>
28 <!ELEMENT b l o c k ( a c t i o n | par | i f | while | r e t r y | comment )∗>
29 <!ELEMENT a c t i o n ( comment ∗ , name , comment ∗ , a r g s ? , comment ∗ )>
30 <!ATTLIST a c t i o n
31
o p t i o n a l CDATA #IMPLIED
32 >
33 <!ELEMENT name (#PCDATA)>
34 <!ELEMENT a r g s ( a r g | comment )∗>
35 <!ELEMENT a r g (#PCDATA)>
36 <!ELEMENT par ( b lock , b l o c k 2 )>
37 <!ELEMENT i f ( cond , b l o c k )>
38 <!ELEMENT cond (#PCDATA)>
39 <!ELEMENT while ( cond , b l o c k )>
40 <!ELEMENT r e t r y ( b l o c k )>
41 <!ATTLIST r e t r y
42
count CDATA #REQUIRED
43 >
144
Kapitel D: Quelltexte
Listing 22: rtdl.dtd
D.18
example.xml
1 <?xml v e r s i o n=” 1 . 0 ” e n c o d i n g=”UTF−8”?>
2 <?xml−s t y l e s h e e t type=” t e x t /xml” h r e f=” r t d l . x s l ” v e r s i o n=” 1 . 0 ”?>
3
4 <!DOCTYPE r t d l SYSTEM ” r t d l . dtd ”>
5
6 <r t d l v e r s i o n=” 1 . 0 ”>
7
<comment>This i s a comment.</comment>
8
<t a s k name=” exampleTask ”>
9
<t a s k a r g s >
10
<var type=” F i r s t A r g ”>a1</var>
11
<var type=” SecondArg ”>a2</var>
12
</ t a s k a r g s >
13
<r e t r y c o u n t >3</r e t r y c o u n t >
14
<e n t i t i e s >
15
<var type=” E n t i t y ”>e n t i t y 1 </var>
16
<var type=” E n t i t y ”>e n t i t y 2 </var>
17
<var type=” E n t i t y ”>e n t i t y 3 </var>
18
</ e n t i t i e s >
19
<blo ck >
20
<a c t i o n >
21
<name>Task1</name>
22
<a r g s >
23
<arg>e n t i t y 1 </arg>
24
<arg>e n t i t y 2 </arg>
25
<arg>e n t i t y 3 </arg>
26
</a r g s >
27
</a c t i o n >
28
<a c t i o n >
29
<name>Task2</name>
30
<a r g s >
31
<arg>e n t i t y 1 </arg>
32
<arg>e n t i t y 2 </arg>
33
<arg>e n t i t y 3 </arg>
34
</a r g s >
35
</a c t i o n >
36
<while>
37
<cond>c o n d i t i o n 1 </cond>
145
Kapitel D: Quelltexte
38
39
<blo ck >
<a c t i o n >
40
<name>Task3</name>
41
<a r g s >
42
<arg>e n t i t y 1 </arg>
43
</a r g s >
44
</a c t i o n >
45
</bloc k >
46
</while>
47
<i f >
48
<cond>c o n d i t i o n 2 </cond>
49
<blo ck >
50
<a c t i o n >
51
52
53
<name>Task4</name>
</a c t i o n >
</bloc k >
54
</ i f >
55
<par>
56
57
58
<blo ck >
<a c t i o n >
<name>Task5</name>
59
</a c t i o n >
60
<par>
61
<blo ck >
62
<a c t i o n >
63
<name>Task6</name>
64
</a c t i o n >
65
</bloc k >
66
<blo ck >
67
<a c t i o n >
68
<name>Task7</name>
69
70
</a c t i o n >
</bloc k >
71
</par>
72
</bloc k >
73
<blo ck >
74
75
76
77
<a c t i o n >
<name>Task8</name>
</a c t i o n >
</bloc k >
78
</par>
79
<r e t r y count=” 5 ”>
80
81
<blo ck >
<a c t i o n o p t i o n a l=” t r u e ”>
146
Kapitel D: Quelltexte
82
<name>o p t i o n a l T a s k </name>
83
</a c t i o n >
84
85
86
87
</bloc k >
</ r e t r y >
</bloc k >
</task >
88 </ r t d l >
Listing 23: example.xml
147
LITERATUR
Literatur
[Bud09] Budde, Henning: Wissensakquisition und maschinelle Task-Generierung
für einen virtuellen Küchenroboter. , Fachhochschule Köln, 2009. Masterthesis.
[Cok10] CokeRob: Ein Blickfang am Tag der offenen Tür 2004, Aufruf: 9. November
2010. http://www.nt-rt.fh-koeln.de/News/n006.html.
[Erd09] Erdmann, Ralph: Steuerung eines autonom fahrenden Roboters auf der
Basis von RFID-Positionsmarken und Richtungsinformationen. , Fachhochschule Köln, 2009. Bachelorthesis.
[Hol10] Holz, Dirk: Effiziente Kartopraghie und Navigation für mobile Service
Roboter. Informatik Spektrum, 04/2010. Springer Verlag.
[JAU05] JAUS WG: JAUS Volume I: Domain Model, 20. März 2005. v3.2.
[JAU06] JAUS WG: JAUS Compliance Specification, 26. Oktober 2006. v3.2.
[JAU07a] JAUS WG: JAUS Volume II: Reference Architecture: Part 1 Architecture
Framework, 27. Juni 2007. v3.3.
[JAU07b] JAUS WG: JAUS Volume II: Reference Architecture: Part 2 Message
Definition, 27. Juni 2007. v3.3.
[JAU07c] JAUS WG: JAUS Volume II: Reference Architecture: Part 3 Message
Set, 27. Juni 2007. v3.3.
[McD11] McDermott, Drew V.: Planning Domain Definition Language, Aufruf:
11. Januar 2011. http://cs-www.cs.yale.edu/homes/dvm/.
[MT10] Moritz Ternorth, Dominik Jain, Michael Beetz: Knowledge Processing for Cognitive Robots. Künstliche Intelligenz, Nr. 24:233–240, 2010.
[Rob11] RoboCup, Aufruf: 11. Januar 2011. http://www.robocup.org.
[SV03]
Spyros Vosinakis, Themis Panayiotopoulos: A Task Definition Language for Virtual Agents. , Universität von Piräus, Griechenland, 2003.
http://wscg.zcu.cz/wscg2003/Papers_2003/D03.pdf.
[Tes10] Teske, Marcus: The Joint Architecture for Unmanned Systems (JAUS):
Eine Übersicht. v1.1, 3. Juni 2010.
148
LITERATUR
[Wik10] Wikipedia Enzyklopädie: American Standard Code for Information Interchange, Aufruf: 2. Dezember 2010.
http://de.wikipedia.
org/w/index.php?title=American_Standard_Code_for_Information_
Interchange&oldid=82181574.
149