MasterarbeitLaTeX/tex/3_Auswahl.tex
2023-04-23 03:34:39 +02:00

337 lines
25 KiB
TeX

\chapter{Komponenten-/Softwareauswahl}
Die Auswahl der verwendeten Softwarekomponenten ist ein wichtiger Schritt der Entwicklung, da diese Entscheidungen den späteren Entwicklungsprozess nachträglich beeinflussen.
Hierfür werden Komponenten ausgewählt, welche die im Konzept besprochenen Teilbereiche abdecken und miteinander verbunden werden können.
\section{Dienstumgebung (ROS2)}
Die Dienstumgebung bestimmt maßgeblich, wie Software im Entwicklungsprozess geschrieben wird.
Durch sie werden häufig benötigte Funktionen bereitgestellt, welche in Programmen in der Umgebung genutzt werden können.
Bei einer Dienstumgebung für Roboter gehören zu den grundlegendn Aspekten die Nachrichtenübergabe zwischen einzelen interagierenden Programmen, um eine gemeinsame Basis für ein einfach erweiterbares System zu schaffen.
\subsection{Auswahl}
Es existieren mehrere Systeme, welche als Dienstumgebung für Roboter in Frage kommen, wenn es nur um die Nachrichtenübergabe zwischen Programmen geht.
Jede Lösung, welche Nachrichten zwischen Prozessen austauschen kann, ist ein potentieller Kanidat für ein Roboterframework.
Wichtige Aspekte sind dabei die Geschwindigkeit der Anbindung und die Definition der Nachrichten, welche über das System ausgetauscht werden.
Nutzbare, bereits als IPC integrierte Systeme sind zum Beispiel Pipes, welche Daten zwischen Prozessen über Buffer austauschen.
Auch die Nutzung von Message Queues und Shared Memory ist hierfür denkbar.
Diese Systeme sind performant, jedoch nicht einfach zu verwalten, da sie von einer direkten Kommunikation von 2 oder mehr Komponenten, welche exakt für diesen Zweck entwickelt wurden, ausgehen.
Eine Alternative stellen Sockets dar, welche Daten zwischen zwei Programmen austauschen können.
In diesem Bereich sticht ROS als Dienstumgebung für Roboter hervor, da es sich um ein etabliertes, quelloffenes und häufig verwendetes System handelt.
Es bietet die oben genannten Aspekte und einige weitere Verbesserungen, welche später näher beleuchtet werden.
Die neuste Version ROS2 bietet dabei einige Verbesserungen im Vergleich zu früheren Version ROS1.
Ein neues Nachrichtenformat mit Quality of Service kann zum Beispiel Nachrichten vorhalten und über sowohl TCP als auch UDP kommunizieren.
Außerdem werden nun neben CMake auch andere Buildsysteme unterstützt, unter anderem auch Python.
Generell existieren im Feld der Roboter-Dienstumgebungen keine Alternativen mit ähnlichem Funktionsumfang und gleicher Reichweite.
Vor allem die unzähligen ROS-Bibliotheken, welche von Nutzern des Systems über die Jahre erstellt wurden, machen das System so populär.\cite{rospackages}
ROS kann für sowohl simulierte Umgebungen, aber auch für echte Roboter eingesetzt werden, da beide Anwendungsfälle durch Programme an die Umgebung angebunden werden können.
%-Alternative Ökosysteme mit gleichem Umfang wie ROS existieren nicht.
%-ROS2
%-Andere (nur) Messagingsysteme
%-LCM
%-ZeroMQ
\subsection{Beschreibung}
ROS2\cite{doi:10.1126/scirobotics.abm6074}, später auch einfach nur ROS genannt, beschreibt sich selbst als ``a meta operating system for robots''\cite{ros-git}.
Hierbei ist ``operating system'' nicht in seiner herkömmlichen Bedeutung eines vollständigen Betriebssystems zu verstehen.
Es handelt sich dabei um eine gemeinsame Grundlage für Programme und Daten, welche durch ROS bereitgestellt wird.
Einzelne Bestandteile in der Umgebung sind dabei in Pakete gegliedert.
Ein Paket kann beliebig viele Daten und Programme beinhalten, welche in zwei Dateien beschrieben werden.
In CMakeLists.txt befinden sich Buildinstruktionen für den Compiler, falls sich Programme im Paket befinden.
Außerdem können bestimmte Pfade aus dem Paket exportiert werden, sodass diese später im Workspace verfügbar sind.
Programme, welche mit anderen Programmen in der Umgebung interagieren, werden in ROS ``Nodes'' genannt.
Zu den Aufgaben von ROS gehören dabei:
\begin{description}
\item[Buildumgebung]\hfill \\
ROS benutzt colcon \cite{colcon}, um Pakete in den Workspaces reproduzierbar zu erstellen.
Hierfür werden CMake und einige Erweiterungen, wie z.B. ament\_cmake eingesetzt.
\item[Workspaceverwaltung]\hfill \\
Pakete können in verschiedenen Verzeichnissen installiert werden und müssen für andere Pakete auffindbar sein.
ROS nutzt hierfür von colcon generierte Skripte, welche beim Erstellen eines Pakets und eines Workspaces mit angelegt werden.
Das Skript des Pakets fügt nur dieses Paket der Umgebung hinzu, das Skript des Workspaces führt alle Skripte der enthaltenen Pakete aus, um diese der Umgebung hinzuzufügen.
\item[Abhängigkeitsverwaltung]\hfill \\
ROS kann durch die in den Paketen deklarierten Abhängigkeiten prüfen, ob diese in der aktuellen Umgebung verfügbar sind.
Dies vermeidet Abstürze und undefiniertes Verhalten in der Ausführung von Nodes.
\item[Datenübertragung]\hfill \\
Nodes müssen miteinander auf einem festgelegten Weg kommunizieren können, um beliebige Verbindungen dieser zu unterstützen.
Dieser wird durch ROS in Form mehrerer Bibliotheken für unterschiedliche Sprachen bereitgestellt.
\item[Parameterübergabe]\hfill \\
Nodes benötigen häufig problemspezifische Konfiguration, um in vorher nicht bedachten Szenarien eingesetzt werden zu können.
ROS stellt diese durch deklarierfähige und integrierte Argumente bereit.
\item[Startverwaltung]\hfill \\
In sogenannten ``launch''-Files können verschiedene Nodes und andere ``launch''-Files zu komplexen Startvorgängen zusammengefasst werden.
\end{description}
\section{Simulationsumgebung (Gazebo)}
\subsection{Auswahl}
Als Simulationsumgebung können verschiedene Programme genutzt werden, welche sich in ihrem Funktionsumfang stak unterscheiden.
Hierfür kommen dedizierte Werkzeuge zur Robotersimulation, aber auch zum Beispiel universell einsetzbare Gameengines in Frage.
Diese Werkzeuge müssen hierfür auf ihre Tauglichkeit für die gesetzte Aufgabe geprüft werden.
Auch andere Aspekte sind hierbei zu betrachten, wie Lizenzen oder schwer bewertbare Aspekte wie Nutzerfreundlichkeit.
Für die Auswahl kommen verschiedene Prgramme in Frage, welche im folgenden weiter beleuchtet werden.
CoppeliaSim, früher auch V-REP genannt, ist eine Robotersimulationsumgebung mit integriertem Editor und ROS-Unterstützung.
Es unterstützt viele Sprachen (C/C++, Python, Java, Lua, Matlab oder Octave) zur Entwicklung von Erweiterungen des Simulators.
Der Simulator selbst unterstützt Menschliche Aktoren, jedoch können diese nur Animationen abspielen oder zusammen mit Bewegungen abspielen.
CoppeliaSim existiert in 3 Versionen, welche sich im Funktionsumfang unterscheiden, jedoch hat nur die professionelle Version Zugriff auf alle Funktionen und Verwendungsszenarien.
Gazebo Ignition ist wie CoppeliaSim eine Robotersimulationsumgebung, jedoch ohne integrierten Editor und direkte ROS-Unterstützung.
Gazebo setzt wie CoppeliaSim auf Erweiterungen, welche die gewünschten Funktionen einbinden können.
Zum Beispiel existiert auch eine ROS-Brücke, welche die Anbindung an ROS ermöglicht.
Auch hier unterstützt der Simulator nur Animationen für menschliche Aktoren.
Das Projekt ist Open Source, unter der Apache Lizenz (Version 2.0), was die Verwendung in jeglichen Szenarien erleichtert.
Unity hingegen ist primär eine Grafikengine für Nutzung in Computerspielen.
Es existieren mehrere Systeme zur Anbindung der Engine an ROS, vor allem das offizielle ``Robotics Simulation''-Paket und ZeroSim.
Beide Systeme erlauben die Erweiterung der Gameengine um die Simulation von Robotern.
Unity besitzt eine gute Dokumentation, die vor allem auf die Nutzung im Einsteigerbereich zurückzuführen ist.
Auch die Optionen zur Menschensimulation sind gut, da diese häufig in Spielen verwendet werden.
Ein großer Nachteil hingegen ist die Lizenz, welche nur für Einzelpersonen kostenlos ist.
Die Unreal Engine ist wie Unity eine Grafikengine aus dem Spielebereich.
Auch hier ist die Menschensimulation aufgrund oben genannter Gründe gut möglich.
Jedoch existiert für Unreal Engine keine offizielle Lösung zur Anbindung an ROS2.
Die Programmierung der Engine erfolgt in C++, was einer Drittlösung erlaubte, eine ROS-Anbindung für Unreal Engine zu erstellen.
Die Lizenz der Unreal Engine erlaubt die kostenfreie Nutzung bis zu einem gewissen Umsatz mit der erstellten Software.
Eine weitere Möglichkeit zur Simulation stellt die Grafikengine Godot dar.
Im Vergleich zu Unity und Unreal Engine ist Godot quelloffene Software unter der MIT-Lizenz.
Auch hier stellt die Simulation von menschlichen Aktoren eine Standartaufgabe dar, jedoch befinden sich Teile des dafür verwendeten Systems derzeit in Überarbeitung.
Auch für diese Engine existiert eine ROS2-Anbindung, jedoch ist diese nicht offiziell.
Jede der drei Gameengines besitzt ein integriertes Physiksystem, welches die Simulation von starren Körpern und Gelenken erlaubt.
Aus diesen Funktionen könnte ein Roboterarm aufgebaut werden, welcher dann durch eine der ROS-Brücken der Engines gesteuert werden kann.
Die Wahl der Simulationsumgebung fiel auf Gazebo Ignition, da dieser Simulator bereits im ROS-Framework etabliert ist.
Dabei erlauben die offizielle ROS-Anbindung und offene Lizenz eine zuverlässige Verwendung in unterschidlichsten Szenarien.
\subsection{Verwendete Dateiformate}
Um die Simulationsumgebung zu beschreiben, nutzt Gazebo das .sdf-Dateiformat\cite{sdf-format}.
Dieses Format basiert auf XML und wird zur definition gesamter Welten, aber auch einzelner Objekte benutzt.
Um verschiedene Versionen des Formats zu unterstützen, enthält das einzige sdf-Element die gewünschte Versionsnummer.
In diesem befinden sich entweder ein Modell, Actor oder Licht, oder mindestens eine Welt.
Eine Welt definiert in Gazebo den kompletten Aubau des Simulators.
Zuerst enthält ein Welt-Element die Daten über die physikalischen Konstanten der Simulationsumgebung.
Außerdem werden alle benötigten Teile der Nutzeroberfläche deklariert, welche im ausgeführten Simulator verfügbar sein sollen.
Letzendlich können auch mehrere Modelle, Aktoren und Lichter in der Welt definiert werden.
Diese können auch aus anderen URIs stammen, welche in der Welt deklariert wurden.
Dies erlaubt das Laden von zum Beispiel vorher definierten Objekten oder Objekten aus der offiziellen Bibliothek\cite{gazebo-app}.
Ein Modell enthält einen Roboter oder ein anderes physikalisches Objekt in der Simulation.
Die Deklaration eines weiteren Untermodells ist möglich, um komplexere Strukturen abbilden zu können.
Über ein include-Element können auch andere .sdf-Dateien, welche nur ein Modell enthalten, zum Modell hinzugefügt werden.
Jedes Modell wird über eine Translation und Rotation im Simulationsraum verankert, wobei das Referenzsystem des überliegenden Modells genutzt wird.
Außerdem können im Modell Einstellungen für dessen Physiksimulation vorgenommen werden.
Für unbewegliche Modelle sollte ein \code{static}-Element auf 1 gesetzt werden, um dieses unbeweglich zu machen.
\subsection{Robotersimulation}
Für die Robotersimulation wird ein Modell des Roboters benötigt, in welchem dieser für die Simulationsumgebung beschrieben wird.
Gazebo nutzt hierfür .srdf-Dateien, welche auf xml basieren.
In diesen werden die einzelnen Glieder des Arms und die verbindenden Gelenke beschrieben.
Jedes Glied des Modells besitzt eine Masse, einen Masseschwerpunkt und eine Trägheitsmatrix für die Physiksimulation in Gazebo.
Außerdem werden Modelle für die visuelle Repräsentation in Gazebo und die Kollisionserkennung in der Physiksimulation hinterlegt.
Für beide existieren einfache Modelle wie Zylinder, Boxen und Kugeln.
Da diese Formen nicht jeden Anwendungsfall abdecken und in der visuellen Repräsentation nicht ausreichen, können auch eigene Modelle hinterlegt werden.
Gelenke werden separat von den Gliedern definiert und verbinden jeweils zwei Glieder miteinander.
Durch das Aneinanderreihen von mehreren Gliedern und Gelenken kann so jeder Roboteraufbau beschrieben werden.
Jedes Gelenk besitzt eine Position und Rotation im Raum, um dessen Effekte je nach Typ des Gelenks berechnen zu können.
Aspekte wie Reibung und Dämpfung können auch für die Physiksimulation angegeben werden.
Folgende Typen von Gelenken können in urdf genutzt werden:
\begin{description}
\item[freie Gelenke]
ermöglichen vollständige Bewegung in allen 6 Freiheitsgraden. Sie stellen den normalen Zustand der Gelenke zueinander dar.
\item[planare Gelenke]
erlauben Bewegungen senkrecht zur Achse des Gelenks. Sie werden für zum Beispiel Bodenkollisionen eingesetzt.
\item[feste Gelenke]
sperren alle 6 Freiheitsgrade und werden häufig zur Plazierung von Objekten in einer Szene genutzt.
\item[kontinuierliche Gelenke]
erlauben die beliebige Rotation um die Achse des Gelenks. Sie sind nur selten in rotierenden Gelenken mit Schleifkontakten oder anderen frei rotierbaren Übertragungsmechanismen zu finden.
\item[drehbare Gelenke]
verhalten sich wie kontinuerliche Gelenke, haben jedoch minimale und maximale Auslenkungen. Sie sind die häufigste Art von Gelenken in Roboterarmen.
\item[prismatische Gelenke]
ermöglichen die lineare Bewegung entlang der Achse des Gelenks. Denkbare Anwendungsfälle sind simulierte lineare Aktuatoren.
\end{description}
\subsection{Menschensimulation}
Gazebo besitzt bereits ein einfaches Animationssystem für bewegliche Aktoren, welches auch für Menschen nutzbar ist.
Es existiert bereits ein Modell eines Menschen mit mehreren Animationen, welche allein abgespielt, oder an Bewegungen gekoppelt werden können.
Dadurch ist eine Laufanimation realisierbar, welche synchronisiert zur Bewegung abgespielt wird.
Jedoch ist dies nur unter der Bedingung möglich, dass der gesamte Bewegungsablauf zum Simulationsstart bekannt ist.
Dies ist auf die Definition der Pfade, welche die Bewegung auslösen, zurückzuführen.
Diese können nur als dem Actor untergeordnetes Element in der .sdf-Datei definiert werden, was Veränderungen zur Laufzeit ausschließt.
Durch diesen Umstand ist der mögliche Simulationsumfang nicht ausreichend.
Um dieses Problem zu beheben, ist die Entwicklung eines eigenen Systems zum Bewegen und Animieren des Menschen unausweichlich.
Dieses System muss, wie im Konzept beschrieben, Steuerbefehle von außen empfangen, umsetzen und Feedback liefern können.
Ein solches System sollte als Gazebo-Plugin einbindbar sein, um Modifikationen an der Simulationsumgebung selbst auszuschließen, welche konstant weiter entwickelt wird.
Dies erlaubt die einfachere Wartung, da bei Updates der Simulationsumgebung nicht die Menschensimulation an den neuen Code angepasst werden muss.
\section{Roboterumgebung (MoveIt2)}
MoveIt 2 ist das empfohlene ROS2 Paket für Bewegungsplanung von Robotern.
Das System besteht aus meheren Komponmenten, welche in ihrer Gesamtheit den Bereich der Bewegungsplanung abdecken.
Der Nutzer kann mit MoveIt auf mehreren Wegen Steuerbefehle für den Roboter absenden.
Die einfachste Art der Inbetriebnahme ist über das mitgelieferte RViz-Plugin und die demo-Launch-Files, welche durch den Setupassistenten für den Roboter generiert werden.
Dort können Bewegungen durch das Bewegen von Markierungen oder in der Simulation geplant und ausgeführt werden.
Da sich ein solches System nur beschränkt zur Automatisierung durch Software eignet, existieren auch noch andere Schnitstellen.
Für die Sprache Python existierte früher noch das moveit_commander Paket, welches den Zugriff auf MoveIt in Pyhon erlaubt, welches aber aktuell noch nicht portiert wurde. \cite{moveitpython}
Die direkte Nutzung der C++-API ist aktuell die einzige offizielle Möglichkeit, mit MoveIt auf einer abstrakteren Ebene zu interagieren.
Natürlich können die Befehle auch direkt an die entsprechenden Topics gesendet werden um einzelne Bereiche des Systems zu testen, jedoch ist so kein einfacher Zugriff auf erweiterte Optionen möglich.
Aus einem Robotermodell können nun die Informationen, welche von MoveIt über den zu kontrollierenden Roboter benötigt werden, generiert werden.
Diese werden über einen RobotStatePublisher an MoveIt übergeben, welches daraus das Robotermodell für die Bewegungsplanung generiert.
Durch die vorher erwähne C++-API erhält die MoveGroup die Informationen über die gewünschte Bewegung.
Dabei können auch bestimmte Einschränkungen des Arbeitsraums, spezielle Trajektorien, oder Limitierungen der Gelenke in der Planung berücksichtigt werden.
Diese Daten können durch eine OccupancyMap ergänzt werden, welche die Bereiche beschreibt, welche sich um den Roboter befinden.
Eine solche Erweiterung erlaubt die Nutzung von Kollisionsvermeidung mit Objekten im Planungsbereich.
Die Planung der Bewegung wird durch einen der zahlreichen implementierten Solver erledigt, welcher durch die MoveGroup aufgerufen wird.
Um die generierte Bewegung umzusetzen, werden die gewünschten Gelenkpositionen als Abfolge an \code{ros_control} weitergegeben.
Dabei können sowohl echte Hardwaretreiber, aber auch simulierte Roboter genutzt werden.
Der Erfolg der gesamten Pipeline kann dabei durch einen Feedbackmechanismus überwacht werden.
Im Falle von Gazebo wird \code{ign_ros_control} genutzt, welches die benötigten \code{ros_control} Controller in die Simulation einbindet.
Diese können dann wie normale Controller von \code{ros_control} genutzt werden.
Dieser Ablauf ist auch im Anhang unter Abbildung \ref{moveitpipeline} visualisiert.
\section{Behavior Trees}
Zur Verwaltung der Abläufe sollen BehaviorTrees genutzt werden, welche durch die Bibliothek \code{BehaviorTree.CPP} bereitgestellt werden.
Diese Bibliothek wurde in C++ geschrieben, und ist somit einfach in ROS integrierbar.
Es existieren aber auch viele Beispiele und eine gute Dokumentation über die erweiterten Funktionen, welche im folgenden vorgestellt werden.
\begin{description}
\item[Asynchrone Nodes]
sind in \code{BehaviorTree.CPP} leichter umsetzbar, da diese im Lebenszyklus der Nodes beim Konzept der Bibliothek mit bedacht wurden.
Dies resultiert in Nodes, welche ohne spezielle Logik langanhaltende Aktionen ausführen können, ohne die Ausführung des BehaviorTrees zu behindern.
\item[Reaktives Verhalten] ist ein neues Konzept, um die Handhabung von asnchronen Nodes zu vereinfachen.
Diese Strukturelemente erlauben die parallele Ausführung von mehreren Zweigen, welche aktuell ausführende Aktionen beeinflussen können.
\item[Das .xml-Format] ermöglicht einen einfachen Austausch des Verhaltens, ohne die unterliegende Programmierung verändern zu müssen.
Dies ist vor allem in kompillierten Sprachen wie C++ sinnvoll, da Änderungen im Verhaltensablauf keiner Neukompillierung bedürfen, was die Iterationszeit für Änderungen verbessert.
\item[Plugins] können zum Start geladen werden, um weitere Nodes dem ausgeführten Programm hinzufügen zu können.
Dies vereinfacht die Erweiterung um neue Funktionen und das mehrfachen Nutzen von Code.
\item[Datenfluss] zwischen den Nodes erlaubt es, von außen konfigurierbares Verhalten der Nodes zu erreichen.
Diese können dabei sowohl statisch, als auch dynamisch über sogenannte Ports mit Informationen versorgt werden.
\item[Integriertes Logging] erlaubt es, Zustandsänderungen im Behavior Tree zu visualisieren, aufzunehmen und wieder abzuspielen.
Dies erleichtert das häufig schwierige Debuggen von Zustandsmaschienen erheblich, da das Verhalten genau untersucht werden kann.
\end{description}
BehaviorTrees werden in \code{BehaviorTree.CPP} als .xml-Dateien gespeichert.
Diese Dateien enthalten die Anordnung der Nodes selbst, aber auch weitere Konfigurationsmöglichkeiten in Form von Ein- und Ausgabeports.
Solche Ports können verwendet werden, um Nodes generischer gestalten zu können.
So kann auf feste Parameter in den Nodes selber verzichtet werden, was das erstellen mehrerer Nodes für ähnliche Funktionalitäten verhindert.
Diese Daten können sowohl aus einem String ausgelesen werden, falls die ensprechende Funktion, welche diese in den Zieltyp übersetzt, implementiert wurde.
Aber sie können auch aus dem sogenannten Blackboard entnommen werden.
Das Blackboard ist ein System, welches die Nutzung von Variablen als Parameter für Ein- und Ausgänge erlaubt.
Diese werden im Hintergrund als eine Referenz auf den eigentlichen Wert gespeichert.
Eine solche Funktion erlaubt das weitere Zerlegen von Vorgängen innerhalb des BehaviorTrees.
Solche kleineren Nodes sind durch ihren limitierten Umfang universeller einsetzbar, da sie nur kleinere Teilprobleme betrachten, welche zu komplexeren Strukturen zusammengesetzt werden können.
Um die dadurch wachsenden Strukturen besser überblicken zu können, lassen sich Nodes als sogenannte SubTrees abspeichern.
Diese bilden dann in ihrer Gesamtheit eine neue Node, welche im BehaviorTree eingesetzt werden kann.
Um den Einsatz von Variablen innerhalb eines SubTrees zu ermöglichen, besitzt jeder SubTree ein separates Blackboard.
Dadurch kann ein Eingriff in äußere Funktionalität verhindert werden.
Natürlich sollte es auch möglich sein, Variablen an solche SubTrees zu übergeben.
Diese können, wie auch bei normalen Nodes, einfach als Parameter an den SubTree übergeben werden.
Die Bibliothek \code{BehaviorTree.CPP} verbindet dann diese Werte und erlaubt die Datenübergabe zu und von dem SubTree.
\subsection{Asynchrone Nodes}
Da nicht jeder Prozess in einem einzigen Durchlauf des BehaviorTrees abgebildet werden kann, muss die Möglichkeit geschaffen werden, lang anhaltende Prozesse abzubilden.
Dies geschieht in in \code{behaviortree_cpp_v3} durch asynchrone Nodes.
Eine asynchrone Node besitzt neben den Zuständen SUCCESS und FAILURE auch noch die beiden anderen Zustände RUNNING und IDLE.
Der Zustand RUNNING steht dabei für eine Node, welche sich noch in der Ausführung befindet.
So lang dieser Zustand anhält, wird die Node nicht noch ein weiteres Mal gestartet, sondern nur der Zustand abgefragt.
Der IDLE-Zustand ist ein besonderer Zustand, welcher nur durch eine vollständige Ausführung erreichbar ist.
Er wird von der Node angenommen, nachdem ein RUNNING Zustand durch entweder SUCCESS oder FAILURE beendet wurde und darf sonst nicht verwendet werden.
\subsection{Dateiformat}
Das verwendete Dateiformat, um Behavior Trees zu erstellen, basiert auf XML.
Jedes Dokument beginnt dabei mit einem Root-Element, welches alle BehaviorTrees und eine Referenz auf die ID des Hauptbaumes enthält.
Diese wird benötigt, da auch Unterbäume im selben Dokument deklariert und genuzt werden können, diese aber sonst nicht vom Hauptbaum unterscheidbar sind.
Jeder Baum beginnt mit einem BehaviorTree-Element, welches als Attribut die ID des Baumes besitzen muss.
Als untergeornete Elemente des Baumes werden die Nodes entsprechend der gewünschten Baumstruktur angeordnet.
Zur besseren Visualisierung der XML-Struktur wurde hier die bereits aus dem Konzept bekannte Baumstruktur, hier noch einmal unter Abbildung \ref{choice_tree_demo} zu sehen, in XML umgewandelt.
Dabei ist zu beachten, dass die Root-Node nicht in der Struktur existiert.
Außerdem können selbst definierte Nodes sowohl direkt mit ihrem Namen, aber auch über den Namen Action mit ihrem Namen als ID-Parameter, referenziert werden.
\begin{figure}[hpt]
\includegraphics[width=\textwidth]{img/tree_demo}
\centering
\caption{Beispiel eines BehaviorTrees}
\label{choice_tree_demo}
\end{figure}
\begin{figure}[hpt]
\begin{lstlisting}[]
<?xml version="1.0"?>
<root main_tree_to_execute="demoTree">
<BehaviorTree ID="actorTree">
<Sequence>
<Fallback>
<Action ID="IsDoorOpen"\>
<Action ID="OpenDoor"\>
<Action ID="BreakDoor"\>
</Fallback>
<CanWalkThrough\>
<WalkThrough\>
</Sequence>
</BehaviorTree>
</root>
\end{lstlisting}
\caption{Beispiel eines BehaviorTrees als .xml}
\label{choice_tree_xml}
\end{figure}
\section{Docker-Compose als Virtualisierungsumgebung}
Docker ist eine Virtualisierungsumgebung für Anwendungen, welche die komplette Umgebung für deren Ausführung bereitstellen.
Dadurch wird die Inbetriebnahme von Anwendungen, welche spezielle Umgebungen für ihre Ausführung benötigen, ermöglicht.
Dies wird durch den Einsatz von sogenannten Containern erreicht, welche durch Buildfiles definiert werden.
Ein Buildfile enthält exakte Instruktionen, wie der Container aus anderen Containern, Dateien oder einer Kombination beider erstellt werden kann.
Die so erstellten Container können entweder lokal oder auf einem Server für die Verwendung bereitgehalten werden.
Ein solcher Container enthält ein eigenes Dateisystem, welches aus dem im Buildfile definierten Dateien und einem Overlay besteht.
In diesem Overlay werden Änderungen gespeichert, welche am Container während der Laufzeit vorgenommen werden.
Sofern nicht definiert, werden diese Änderungen beim Neustart des Containers wieder entfernt.
Um dies zu vermeiden, kann entweder ein Volume, eine Art virtuelles Laufwerk im \code{/var/lib/docker} Verzeichnis, oder ein ``bind mount'' in der compose.yml-Datei eingerichtet werden.
Ein ``bind mount'' ist eine direkte Verbindung zu einem Ort des Host-Dateisystems, welche in den Container hereingereicht wird.
Docker-Compose stellt eine Erweiterung von Docker dar, welche die Inbetriebnahme der Container über ein spezielles Dateiformat verwaltet.
In dieser Datei werden weitere Optionen angegeben, welche in die Umgebung des laufenden Containers eingreifen.
Dazu gehört zum Beispiel das automatisierte Übergeben von Umgebungsvariablen, Einrichten von Netzwekumgebungen und Erstellen von Volumes und ``bind mounts''.
Diese Automatisierung erleichtert die initiale Einrichtung eines Containers auf einem neuen System, da alle benötigten Aspekte leicht angepasst werden können.