<?xml version="1.0" encoding="UTF-8"?> Definition der XML-Datei. Bei allen Dateien identisch. <Scene ...> Starttag der Szene <Floor .../> Der Untergrund <Lights> Die Lichtquellen <StaticObjects> <Cameras> Die Kameras </Scene> |
In folgenden Erläuterungen bezeichnet %lms-home% das LMS-Stammverzeichnis
(z.B. C:\Programme\lms)
Im Beispiel legen wir eine Umgebung mit dem Namen myScene.xml in dem Ordner
%lms-home%/scenario/myScenario an.
Der xml-Tag definiert den XML-Datei. Er ist bei allen Umgebungen identisch.
<?xml version="1.0" encoding="UTF-8"?> |
Bei diesem Eintrag beginnt die Definition einer Szene. Um den korrekten Aufbau der XML-Datei zu definieren, wird auf eine xsd-Datei (xsd=XML Schema Definition) eingebunden. Dies sieht wie folgt aus:
<Scene |
Die xsd-Datei (Scene.xsd) findet man im Verzeichnis %lms-home%/config/Scene. Wenn Sie Ihre Umgebungsdatei in diesem Verzeichnis ablegen, können Sie den Scene-Tag, wie er oben angegeben ist, genau so übernehmen. Falls Ihre Umgebungsdatei in einem anderen Ordner liegt, können Sie entweder die Datei „Scene.xsd“ in diesen Ordner kopieren oder einen relativen Pfad (von der Scene-Datei aus) auf die Schema-Definition anlegen. Im letzten Fall sieht die Szene-Definition wie folgt aus:
<Scene |
Der Scene-Tag wird am Ende der Datei wieder geschlossen:
</Scene> |
Hier wird der Untergrund der Umgebung definiert. Auf ihm bewegen sich die
Roboter. Er hat eine feste Größe und eine Textur, die von den Lichtsensoren
des RCX als Helligkeit des Untergrunds wahrgenommen werden können.
Die Größe des Untergrunds wird dabei in Metern angegeben. Die Textur kann
ein beliebiges Bild in den Formaten „gif“, „jpg“ und
„png“ sein. Der Pfad zur Bilddatei wird relativ zum %lms-home%
angegeben. In unserem Beispiel liegt im Ordner %lms-home%/scenario/myScenario
die Datei „floor.gif“. Der Untergrund ist 1 Meter hoch und breit.
Der Tag wird am Ende mit „/>“ wieder geschlossen.
<Floor Length="1.0" Width="1.0" GifFilename="scenario/myScenario/floor.gif" /> |
Mit diesen einfachen Schritten haben wir nun eine einfache Umgebung erstellt. Öffnet man sie im LMS, sieht man Folgendes:

Zusätzlich können in der Umgebungsdatei gerichtete Lichtquellen (Spotlights) gesetzt werden. Die Definition dieser Lichter beginnt mit dem Lights-Tag, gefolgt von einem oder mehreren SpotLight-Tags. Nach den SpotLights wird der Lights-Tag geschlossen:
<Lights> |
Eine typische Lichtquelle wird folgendermaßen beschrieben:
<SpotLight PositionX="-0.5" PositionY="0.5" PositionZ="1" |
In diesem Beispiel wird ein rotes Licht definiert. Man erkennt deutlich die Auswirkungen auf den probeweise geladenen Roboter (ATF1).
|
|
![]() |
Ohne Lichtquelle |
Mit roter Lichtquelle |
Ein SpotLight hat 11 Parameter. Die ersten drei Parameter beschreiben die X,Y und Z-Koordinaten des Lichtes. Alle Angaben beziehen sich auf den Mittelpunkt des Untergrundes und sind in Metern angegeben. In diesem Fall kommt das Licht also von einer Lichtquelle, die einen Meter über dem Boden auf der oberen linken Ecke des Untergrundes postiert ist. Die nächsten 3 Parameter beschreiben die Richtung des Lichts. In diesem Fall sind es die negativen Werte der Position, so dass das Licht genau auf das Zentrum strahlt.

Der Parameter Concentration gibt an, wie stark das Licht gebündelt
wird. Der SpreadAngle definiert den Öffnungswinkel des Scheinwerfers, also
den Winkel des Lichtkegels. Die letzten 3 Parameter beschreiben schließlich
die Farbe des Lichts mit den RGB-Werten.
Wir fügen nun einen zweiten Scheinwerfer 2 Meter über dem Untergrund hinzu,
der den Untergrund recht homogen beleuchtet:
<SpotLight PositionX="0" PositionY="0" PositionZ="2" |
Statische Objekte sind in einem StaticObjects-Tag zusammengefasst. Mit Hilfe von statischen Objekten werden Hindernisse auf dem Untergrund definiert. Dies ist zum Beispiel sinnvoll, wenn man um den Untergrund herum eine Begrenzung legen möchte, so dass Roboter ihn nicht verlassen können. Die Definitionen beginnen mit dem Tag:
<StaticObjects> |
In diesem Tag werden die Boxen definiert und schließlich wird der Tag mit
</StaticObjects> |
wieder geschlossen.
Die WorldObjects fassen einzelne Hindernisse zusammen. StaticObjects können mehrere WorldObjects beinhalten.
Die eigentlichen Hindernisse (Definiert durch den Tag <Box ...>) werden in einer ChildTransformGroup eingebettet. Diese wiederum unterliegt einer ParentTransformGroup, welche wiederum Bestandteil eines sogenannten WoldObjects ist. Hier nun zunächst ein Beispiel für eine einfache gelbe Box in der Mitte des Untergrundes. Diese Box wird später noch um eine weitere, gedrehte Box ergänzt, so dass ein Haus entsteht:
<StaticObjects> |
Die einzelnen Parmeter des Box-Tags stellen die Breite, Länge und Höhe, sowie
die Farbe des Hindernisses dar. Deutlich komplizierter ist dagegen die 4x4
Matrizen, die in den ChildTransformGroups definiert wird. Mit Hilfe dieser
Matrizen können die Boxen positioniert und gedreht werden.
Im folgenden werde ich nicht auf die mathematischen Hintergründe dieser Matrix
eingehen, da dies den Rahmen sprengen würde. Stattdessen werden hier Anleitungen
gegeben, mit dieser Matrix zu arbeiten.
In der XML-Definition der ChildTransformGroup erkennen wir folgende Matrix:
= 
In dem Beispiel sind die Parameter dx, dy und dz jeweils 0, d.h dass das Objekt nicht verschoben ist. Wir verschieben nun das Objekt um 50cm nach rechts und 10cm nach oben. Dazu müssen wir Value14=“0.5“ und Value24=“0.1“ setzen und erhalten Folgendes:
<ChildTransformGroup |

Wir fügen nun ein zweites Objekt als „Hausdach“ ein. Es liegt etwas höher als das erste Objekt und hat andere Dimensionen:
<StaticObjects> |
Um dieses Objekt zu drehen, muss folgender Teil der Matrix verändert werden:

Die Matrix (R) wird dabei wie folgt berechnet:
Rotation um die x-Achse:
(Rx) = 
Rotation um die y-Achse:
(Ry) = 
Rotation um die z-Achse:
(Rz) =
Wenn wir also die Box um 45° in Richtung der X-Achse drehen wollen, so bekommen
wir
(Rx) = 
und damit:
<StaticObjects> |

Um mehrere Rotationen durchzuführen, müssen einzelne Rotationsmatrizen multipliziert
werden. Um etwa erst in der X-Achse und anschliessend in der Z-Achse zu drehen,
muss man 2 Matrizen (Rx) und (Rz) berechnen, und diese dann dann multiplizieren.
(Rgesamt) = (Rx) x (Rz).
Beim den Multiplikationen ist die Reihenfolge zu beachten. Sie repäsentiert
die Reihenfolge der Rotationsschritte.
Verändern der Lage einer ChildTransformGroup
Das Haus und sein Dach sind nun in einer ParentTransformGroup zusammengefasst.
Man kann die Lage beider Objekte einfach verändern, indem man nur die Matrix
der ParentTransformGroup verändert. Um das komplette Haus etwa 90° um den
Mittelpunkt des Untergrundes herum in Z-Richtung zu drehen, reicht folgende
Veränderung:
Rotation um die z-Achse:
(R) =
= 
Daraus folgt für die ParentTransformGroup:
<StaticObjects> |

Auf diese Weise können wir erstellte ParentTransferGroups durch einfaches Duplizieren und Anpassen der Matrix mehrfach verwenden.

Im Menüpunkt „View“ des LMS können vorgefertigte Kammeraperspektiven ausgewählt werden, sofern diese in der XML-Datei definiert sind. Es gibt zwei Möglichkeiten, diese Kameraperspektiven zu definieren: manuell oder mit Hilfe des LMS.
Drehen, Ziehen und Zoomen Sie das Hauptfenster mit Hilfe der drei Maustasten
in die gewünschte Position und Klicken Sie dann auf „View -> Save
Camera Pos“.
Schon haben Sie in der XML-Datei eine Kameraperspektive definiert, die Sie
fortan im Menü-Punkt „View“ jederzeit wieder aufrufen können.
Aufgrund dieser einfachen Möglichkeit, Kamerapositionen zu definieren, wir
an dieser Stelle lediglich auf den allgemeinen Aufbau des Camera-Tags eingegangen.
Wie oben bereits zu sehen, sind mehrere Perspektiven in einem Cameras-Tag
gespeichert:
<Cameras> |
Die Kamera selbst hat einen Namen (Standardmäßig “Camera 0”,
“Camera 1” usw.) und eine TransformGroup. Diese TransformGroup
ist genauso aufgebaut, wie die Parent- und ChildTransformGroup, die wir bereits
kennen gelernt haben.
Die Parameter dx, dy und dz definieren die Kamera-Position, die Matrix (R)
definiert den Blickwinkel.
<Camera name="Camera 0"> |
Die Skalierung wird vorgenommen, indem man die Rotationsmatrix mit einer
Skalierungmatrix (S) multipliziert:
(Rs) =(R) x 
Dabei bezeichnet z den Zoom.
Dieses Tutorial hat gezeigt wie man eine einfache Umgebung (Szene) für den LMS erstellt. Diese Szene beinhaltet einen Untergrund mit einer Textur, die von den Lichtsensoren der Roboter erfasst werden kann, mehrere Lichtquellen, mehrere Häuser, die in Transformationsgruppen zusammengefasst sind und eine Kameraperspektive.
Die komplette Szene-Datei „myScene.xml“:
<?xml version="1.0" encoding="UTF-8"?> <Cameras> |