\chapter{Komponenten-/Softwareauswahl}
Die Auswahl der verwendeten Softwarekomponenten ist ein wichtiger Schritt der Entwicklung.
Diese Entscheidungen beeinflussen die späteren Entwicklungsprozess nachhaltig.

Im nachfolgenden findet die Auswahl der Komponenten statt.
Diese sollen später in der entwickelten Softwareumgebung ihre jeweiligen Teilbereiche abdecken.
Alle diese Teilbereiche können dann zu einer Simulation vebunden werden, welche das gesamte Problemfeld abdeckt.

Wie bereits in Abbildung \ref{concept_overview} dargestellt, ist für die Erfüllung der Aufgaben eine Dienst- und eine Simulationsumgebung erforderlich.
Dieses Kapitel beschreibt die Auswahl der Umgebungen und der in diesen laufenden Prozesse.
\section{Dienstumgebung}
Die Dienstumgebung bestimmt maßgeblich, wie Software im Entwicklungsprozess geschrieben wird.
Durch sie werden häufig benötigte Funktionen bereitgestellt, welche durch die Programme innerhalb der Umgebung genutzt werden können.

Bei einer Dienstumgebung für Roboter gehören zu den grundlegenden Aspekten die Nachrichtenübergabe zwischen einzelen interagierenden Programmen, um eine gemeinsame Basis für ein einfach erweiterbares System zu schaffen.
Außerdem sind Werkzeuge zur Einstellungsübergabe an Teilsysteme sinnvoll, um diese einfach an einer Stelle anpassen zu können.

\subsection{Auswahl}
Es existieren mehrere Systeme, die als Dienstumgebung für Roboter in Frage kommen, wenn es lediglich 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 Interprozesskommunikation 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 mehreren Programmen austauschen können.
Dabei dient ein Programm als Server, welches Anfragen von anderen Programmen, auch Clients genannt, entgegen nimmt.
Die Kommunikation zwischen Client und Server ist bidirektional möglich, was kompliziertere Protokolle ermöglicht.

Alle diese Lösungen besitzen einen gemeinsamen Nachteil in deren Nachrichtendefinition.
Dieser Nachteil besteht in der potentiellen Variation zahlreicher Kommunikationsmechanismen, welche zum Datenaustausch über all diese möglichen Systeme verwendet werden können.
Bei einem ausreichend großen Projekt treten so unweigerlich Unterschiede in der Handhabung auf, die es zu berücksichtigen gilt.

In diesem Bereich sticht ROS\cite{doi:10.1126/scirobotics.abm6074} als Dienstumgebung für Roboter hervor, da es sich um ein etabliertes und quelloffenes System handelt.
Der oben genannte Nachteil einzelner Systeme wird in ROS durch mehrere standartisierte und erweiterbare Nachrichtendefinition gelöst, welche von den Programmen in der Umgebung genutzt werden.
Um diese Nachrichten zu senden und empfangen liefert ROS eine eigene Implementation des Protokolls für zum Beispiel Python\cite{python} und C++\cite{cpp}, welche mehrere Arten der Nachrichtenübergabe unterstützten.

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 zwischenspeichern und über sowohl TCP, als auch UDP kommunizieren.
Außerdem werden nun neben CMake\cite{cmake} auch andere Buildsysteme unterstützt, was zum Beispiel die Verwendung von Python erlaubt.

Generell existieren im Feld der Roboter-Dienstumgebungen keine freien 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, wobei jedes Paket beliebig viele Daten und Programme beinhalten kann.

Jedes Paket enthält dabei eine \code{package.xml}-Datei, welche durch die Paketverwaltung genutzt wird.
In dieser befindet sich eine in XML verfasste Definition des Paketinhalts, welche verschiedene Aspekte des Pakets beschreibt.

Darunter fallen Informationen über den das Paket selbt, wie dessen Name, Beschreibung und Version.
Außerdem sind Name und Mailadresse des Autors, sowie die gewählte Lizenz des Codes vermerkt.
Um das Paket später korrekt ausführen zu können, werden außerdem benötigte Pakete für die Erstellung und Ausführung des Pakets eingetragen.

Falls C++ zur Entwicklung des Pakets verwendet wird, befindet sich außerdem eine \code{CMakeLists.txt}-Datei im Paket.
In  befinden sich die Buildinstruktionen für den Compiler für die im Paket befindlichen Programme.
Durch einen Aufruf von \code{ament_cmake} werden andere Parameter aus der \code{package.xml}-Datei ergänzt.

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 über die ROS internen Schnittstellen kommunizieren, werden in ROS ``Nodes'' genannt.

Zu den Aufgaben von ROS gehören dabei:
\begin{description}
 \item[Buildumgebung]\hfill \\
  ROS nutzt die eigene Buildumgebung \code{colcon} \cite{colcon}, um Pakete in den Workspaces reproduzierbar zu erstellen.
  Zu deren Konfiguration werden CMake\cite{cmake} und einige Erweiterungen, wie zum Beispiel das oben erwähnte \code{ament_cmake} eingesetzt.
  Anhand dieser Dateien werden die fertiggestellten Pakete dann im Workspace installiert, damit diese später verwendet werden können.

 \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 in diesem enthaltenen Pakete aus, um diese allesamt 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 ausführbar sind.
  Die generierten Warnungen bei fehlenden Paketen vermeiden Abstürze und undefiniertes Verhalten in der Ausführung von Nodes, welche diese benötigen.

 \item[Datenübertragung]\hfill \\
  Um Daten zwischen Nodes austauschen zu können, müssen miteinander auf einem festgelegten Weg kommunizieren können.
  Ein solcher Aufbau erlaubt den Austausch von Daten in vorher nicht durch die Entwickler bedachten Anwendungsfällen.
  Die von ROS gebotene Schnittstelle zur Datenübertragung wird in Form mehrerer Bibliotheken für unterschiedliche Programmiersprachen bereitgestellt.

  Der Datenaustausch geschieht in sogenannten Topics, welche Nachrichtenkanäle zwischen den Nodes darstellen.
  Eine Node kann entweder als Server ein Topic anbieten, was durch andere Nodes gelesen wird, oder als Client auf solche bereitgestellten Topics zugreifen.
  Durch die Kombination mehrerer Topics ist eine komplexere Interaktion abbildbar, welche zum Beispiel Rückgabewerte zum aktuell ausgeführten Steuerbefehl liefert.

 \item[Parameterübergabe]\hfill \\
  Um Nodes auf neue Anwendungsfälle anpassen zu können, wird ein Konfigurationsmechanismus benötigt.
  In ROS geschieht dies durch die Übergabe sogenannter Parameter, welche durch die Node gelesen werden können.
  Diese eignen sich zur Übergabe von Informationen, wie zum Beispiel einem Robotermodell, aber auch um die Topics der Nodes umbenennen zu können.

 \item[Startverwaltung]\hfill \\
  In sogenannten ``launch''-Files können verschiedene Nodes und andere ``launch''-Files zu komplexen Startvorgängen zusammengefasst werden.
  Dabei werden diese mit den gewünschten Parametern versehen, welche verschiedene Eigenschaften der Node an die aktuelle Umgebung anpassen können.

\end{description}
Durch eine solche Umgebung kann die gewünschte Simulation einfacher in mehrere Komponenten zerlegt werden, was die spätere Wartung des Projekts vereinfacht.

\section{Simulationsumgebung (Gazebo)}

\subsection{Auswahl}
Als Simulationsumgebung eignen sich verschiedenen Programme, die sich hinsichtlich ihres Funktionsumfangs stark unterscheiden.
Hierfür kommen dedizierte Werkzeuge zur Robotersimulation, aber auch beispielsweise universell einsetzbare Gameengines in Frage.
Ein Vergleich dieser Werkzeuge ist hierbei sinnvoll, da der gebotene Funktionsumfang der Softwares sich stark unterscheidet.
Auch andere Aspekte, wie Lizenzen oder schwer bewertbare Aspekte wie Nutzerfreundlichkeit, sind hierbei zu betrachten.
Eine Auswahl der als Simulationsumgebung in Frage kommenden Programme werden hier vorgestellt.

CoppeliaSim\cite{coppelia}, 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\cite{gazebo} 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\cite{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\cite{unreal} 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 die Erstellung eines Plugins zur ROS-Anbindung der Unreal Engine ermöglichte, welche von Nutzern gewartet wird.
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\cite{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.

Alle vorgestellten Softwares besitzten ein integriertes Physiksystem, welches die Simulation von starren Körpern und Gelenken erlaubt.
Aus diesen Funktionen kann ein Roboterarm aufgebaut werden, welcher dann durch eine ROS-Brücke gesteuert werden kann.

Um den Entwicklungsvorgang zu beschleunigen, ist die Auswahl einer Umgebung mit bereits existierender ROS-Unterstützung sinnvoll.
Durch diese Einschränkung scheiden sowohl Unreal Engine aber auch Godot aus, welche nur durch Nutzer unterstützt werden.
Für einen späteren Einsatz ist eine offene Lizenz von Vorteil, da diese in nahezu allen Umständen eingesetzt werden kann.

Die Wahl der Simulationsumgebung fiel deshalb auf Gazebo Ignition, welches gleichzeitig bereits im ROS-Ökosystem etabliert ist.
Dabei erlauben die offizielle ROS-Anbindung und offene Lizenz eine zuverlässige Verwendung in unterschiedlichsten Szenarien.
\subsection{Welt- und Modellbeschreibung}
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 innerhalb dieser Welten benutzt.

Um verschiedene Versionen des Formats zu unterstützen, enthält das einzige sdf-Element die gewünschte Versionsnummer.
Eine solche Datei kann, wie bereits oben beschrieben, unterschiedliche Daten enthalten.
Im Falle eines Objekts ist dies eine einzige Instanz von entweder einem Modell, Actor oder Licht.
Andernfalls können in der Datei eine oder mehrere Welten definiert werden.

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.

Ein Modell enhält meißt mindestens ein Link-Element, welches zur Darstellung von dessen Geometrie verwendet wird.
Mehrere Link-Elemente können dabei mit der Welt oder anderen Link-Elementen über Joint-Elemente verbunden werden.
Diese Joint-Elemente können jedoch nicht von außerhalb gesteuert werden, was dieses Dateiformat ungeeignet für Roboterdefinitionen macht.

Lichter besitzen einen Lichttyp, welcher die Ausbreitung des Lichtes im Raum bestimmt.
Die erste Art ist direktionales Licht, welches parallel zur gewünschten Achse auftrifft, welches vor allem zur grundlegenden Raumausleuchtung genutzt werden kann.
Außerdem existieren noch Punktlichtquellen, welche von einer Position im Raum ausgehen und Spots, welche außerdem noch nur einen gewissen Winkel abdecken.

Die Actor-Komponente wird für animierte Modelle in der Simulation eingesetzt.
Sie besteht aus einem Namen für das Modell, einer Skin, welche das Aussehen des Modells definiert und mehreren Animationen.
Diese können durch in einem Skript definierte Trajectories ausgeführt werden, was eine einfache Simulation eines Menschen erlaubt.
Eine solche Befehlsfolge kann jedoch nicht von außerhalb der Simulation zur Laufzeit angepasst werden, was weitere Entwicklungsarbeit erforderlich macht.

\subsection{Robotersimulation}
Für die Robotersimulation wird ein Modell des Roboters benötigt, in welchem dieser für die Simulationsumgebung beschrieben wird.
Gazebo und ROS nutzen hierfür .urdf-Dateien\cite{urdf-format}, welche auf XML basieren.
In diesen werden die einzelnen Glieder des Roboterarms 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 des Roboters 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.
Hierbei werden die Modelle für die Physiksimulation und das Aussehen des Roboters unterschieden.

Gelenke werden separat von den Gliedern definiert und verbinden jeweils zwei Glieder miteinander.
Durch das Aneinanderreihen von mehreren Gliedern und Gelenken ist die Beschreibung eines beliebigen Roboteraufbaus möglich.
Jedes Gelenk besitzt eine Position und Rotation im Raum, um dessen Effekte, welche vom Gelenktyp abhängen, berechnen zu können.
Aspekte wie Reibung und Dämpfung können auch hier für die Nutzung in der Physiksimulation beschrieben werden.
Folgende Typen von Gelenken können in urdf-Dateien genutzt werden:
\begin{description}
 \item[freie Gelenke]
  ermöglichen vollständige Bewegung in allen 6 Freiheitsgraden (Rotation und Translation). Sie stellen den normalen Zustand der Glieder zueinander dar.
 \item[planare Gelenke]
  erlauben Bewegungen senkrecht zur Achse des Gelenks. Sie werden zum Beispiel für Bodenkollisionen eingesetzt.
 \item[feste Gelenke]
  sperren alle 6 Freiheitsgrade und werden häufig zur Fixierung 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 kontinuierliche 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. Sie werden zur Umsetzung von Linearaktuatore in der Simulation verwendet.
\end{description}
\subsection{Menschensimulation}
Gazebo besitzt bereits ein einfaches Animationssystem für bewegliche Aktoren, welches auch für Menschen nutzbar ist.
Für diesen existiert bereits ein Modell mit mehreren Animationen, welche allein abgespielt, oder an Bewegungen gekoppelt werden können.
Dadurch ist eine Laufanimation realisierbar, welche synchronisiert zur Bewegung abgespielt wird.

Dies setzt jedoch voraus, dass der gesamte Bewegungsablauf zum Simulationsstart bekannt ist.
Der Grund dafür ist auf die Definition der Pfade, welche die Bewegung auslösen, zurück zu fü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 somit realisierbare Simulationsumfang nicht ausreichend, um die gewünschten Szenarien abzubilden.

Um diese Einschränkung 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.
Dafür soll ein ROS Action-Server verwendet werden, welcher die Befehle entgegennimmt, unter konstantem Feedback ausführt und nach Erfolgreicher Ausführung den Empfang des nächsten Befehlts zulässt.

Ein solches System soll 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\cite{moveit-docs} ist das meist genutzte ROS2 Paket für Bewegungsplanung von Robotern.
Deshalb existiert viel Dokumentation für die zahlreichen Komponenten, was die Entwicklung erleichtert und zahlreiche direkte Integrationen mit anderen ROS-Paketen, wodurch diese einfacher zusammen genutzt werden können.
Diese Eigenschaften machen das Paket als Roboterumgebung für dieses Projekt extrem attraktiv.

MoveIt besteht aus meheren Komponmenten, welche in ihrer Gesamtheit den Bereich der Bewegungsplanung abdecken.
Der Nutzer kann mit MoveIt auf verschiedenen Wegen Steuerbefehle für den Roboter absenden, welche durch die Software umgesetzt werden.

Die einfachste Art der Inbetriebnahme ist über das mitgelieferte RViz-Plugin und die demo-Launch-Files, welche durch einen mitgelieferten Setupassistenten für den Roboter generiert werden.
Durch die Ausführung dieser Demo startet RViz, eine Test- und Visualisierungsumgebung für ROS.
Darin können Roboterbewegungen unter Zuhilfenahme von Markierungen in RViz geplant und ausgeführt werden.

Da sich eine solche Bewegungsplanung nur beschränkt zur Automatisierung durch Software eignet, müssen die der Demo zugrundeliegenden Schnittstellen genutzt werden.
Für die Sprache Python existierte für die Vorgängerversion MoveIt noch das moveit_commander Paket, welches den Zugriff auf MoveIt in Pyhon erlaubt, welches aber für MoveIt2 noch nicht portiert wurde. \cite{moveitpython}

Die direkte Nutzung der C++-API ist aktuell die einzige offizielle Möglichkeit, mit MoveIt2 direkt zu interagieren.
Dabei kann sowohl die Planung und Ausführung von Bewegungen ausgelöst werden, aber auch Exklusionszonen eingerichtet werden.
Außerdem können Objekte virtuell mit dem Roboter verbunden werden, wodurch sich diese in RViz mit dem Roboter bewegen.
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.

Um die durch den Setupassistenten generierten Informationen an MoveIt zu übergeben, wird intern ein RobotStatePublisher verwendet.
Dieser läd alle Daten des Robotermodells und gibt sie an andere Programme weiter, welche diese zur Laufzeit anfordern, unter diesen auch MoveIt selbst.

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, die sich um den Roboter befinden.
Eine solche Erweiterung erlaubt die automatische 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 die \code{ros_control} Controller des Roboters weitergegeben.

Diese Abstaktion erlaubt die Nutzung von sowohl simulierten, aber auch echten Robotern.
Hiefür kann einfach ein anderer \code{ros_control} Controller geladen werden, welcher entweder die simulierte oder echte Hardware ansteuert.
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} im Anhang visualisiert.

\section{Programmiersprache}
Als Programmiersprache kommen in ROS standartmäßig Python\cite{python} und C++\cite{cpp} zum Einsatz.
Diese beiden Sprachen sind in der Softwareentwicklung beliebt, unterscheiden sich jedoch stark in Funktionsumfang und Entwicklungsprozess.

Python ist eine interpretierte Skriptsprache, welche zu den hohen Programmiersprachen zählt.
Sie wird in ROS zum Beispiel in .launch.py-Dateien eingesetzt, welche den Start von Diensten in der Umgebung verwalten.
Die Sprache kann aber auch für die Programmierung von Nodes innerhalb des ROS-Systems verwendet werden.

C++ hingegen ist eine kompillierte, statisch typisierte, maschinennahe Programmiersprache.
In ROS wird C++ für Code verwendet, welcher entweder häufig oder in zeitkritischen Szenarien ausgeführt wird.
Aus diesem Grund wird C++ in Nodes verwendet, welche schnell auf große Datenmengen reagieren müssen.

Die Nutzung eines Kompilierers beschleunigt C++ deutlich im Vergleich zu Python, ist jedoch weniger geeignet für häufige Modifikation.
Dies ist vor allem in häufig geänderten Programmen ein Nachteil, welche dann wieder kompilliert werden müssten.
Aus diesem Grund wird Python vor allem in .launch.py-Dateien verwendet, welche die Interaktion der anderen Programme in der Umgebung verwalten.

Um die gewünschten Funktionen für die Simulation umsetzen zu können, ist die Programmierung in C++ nötig.
Da zum Beispiel Gazebo-Plugins auf C++ als Programmiersprache ausgelegt sind, was die Nutzung anderer Sprachen stark erschwert.
Ein Grund dafür ist die hohe Geschwindigkeit, welche bei einer hohen Anzahl an Simulationsschritten pro Sekunde benötigt wird.
Außerdem kann MoveIt2 zur aktuellen Zeit nur mit C++ direkt gesteuert werden.

Die Verwendung von C++ für die zu entwickelnden Nodes erscheint deshalb aus oben genannten Gründen naheliegend.
In den Launch-Skripten wird jedoch Python verwendet werden, da hier die Vorteile einer Skriptsprache überwiegen.

\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 und dem geplanten Konzept 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.
  Darunter fällt die Modifizierung von Parametern der Aktionen, aber auch der vollständige Abbruch einer Aktion durch äußere Einflüsse.
  \item[Das .xml-Format der Behavior Trees] ermöglicht einen einfachen Austausch des Verhaltens, ohne die unterliegende Programme 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[Das Blackboard] ist eine Schicht, welche den Datenfluss zwischen den Nodes erlaubt.
  In diesem System kann unter Verwendung einer Zeichenkette als Identifikator ein Wert in Form einer Referenz hinterlegt werden.
  Sogenannte Ports erlauben Nodes, Daten aus dem Blackboard zu lesen und auf dieses zu schreiben.
  \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.

Ports können verwendet werden, um Nodes generischer zu gestalten.
Durch veränderbare Parameter im später erstellten Tree können Nodes ohne Programmänderung verändert werden.
Falls die Nodes mit Bedacht erstellt wurden, kann so auf viele spezialisierte Nodes verzichtet werden, da deren Funktionen aus einfacheren Nodes mit variablen Parametern abgebildet werden kann.
Diese in den Ports übertragenen Daten können sowohl aus einem String ausgelesen, aber auch aus dem sogenannten Blackboard entnommen werden.

Um die Übersetzung aus einem String zu ermöglichen, muss eine entsprechende Funktion implementiert werden, welche diesen String in den gewünschten Zieltyp übersetzt.
Viele einfache Datentypen, wie Ganzzahlen und Gleitkommazahlen, werden von BehaviorTree.Cpp bereits durch mitgelieferte Funktionen unterstützt.

Das Blackboard ist ein System, welches die Nutzung von Variablen als Parameter für Ports 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 auch ein Eingriff durch äußere Einflüsse 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 sofort vollständig durchgeführt werden kann, muss die Möglichkeit geschaffen werden, lang anhaltende Prozesse abzubilden.
Dies geschieht in \code{BehaviorTree.CPP} durch asynchrone Nodes.

Eine asynchrone Node besitzt neben den Zuständen SUCCESS und FAILURE einer normalen Node auch noch die beiden neuen Zustände RUNNING und IDLE.
Außerdem werden mehrere Funktionen definiert, welche den Lebenszyklus der Node darstellen.

Wird eine Node durch den Aufruf der \code{onStart}-Funktion gestartet, geht diese in einen der Zustände RUNNING, SUCCESS oder FAILURE über.

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 in der neuen \code{onRunning}-Funktion 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 deren Ausführung durch SUCCESS oder FAILURE beendet wurde.

Im Falle eines Abbruchs, welcher durch andere Nodes im Baum ausgelöst werden könnte, muss die Ausführung der Node vorzeitig beendet werden.
Dies geschieht mit der neuen \code{onHalted}-Funktion, welche die Ausführung der Node abbrechen kann.
\subsection{Dateiformat}
Das in BehaviorTree.Cpp 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 in Abbildung \ref{choice_tree_demo} zu sehen, umgewandelt.
Die resultierende Datei ist in Abbildung \ref{choice_tree_xml} abgebildet.
Dabei ist zu beachten, dass die Root-Node nicht in der Struktur existiert, da diese nur den Eintrittspunkt in die Struktur darstellt.
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{minted}[breaklines,frame=single,linenos]{xml}
<?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{minted}
\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 bereitstellt.
Dadurch wird die Inbetriebnahme von Anwendungen, welche spezielle Umgebungen für ihre Ausführung benötigen auf beliebigen Systemen ermöglicht.

Dies wird durch den Einsatz von sogenannten Containern erreicht.
Ein solcher Container wird über sogenannte Build-Files definiert.
Ein Build-File enthält exakte Instruktionen, wie der Container aus anderen Containern, Dateien oder einer Kombination beider erstellt werden kann.
Der so erstellte Container wird anhand dieser Definition durch den ausführenden Rechner erstellt.
Um diesen Prozess weiter zu beschleunigen, ist auch der Einsatz eines Buildservers möglich, welcher benötigte Container als Download bereitstellt.

Jeder 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 in einem Systemverzeichnis des Hostsystems, oder ein ``bind mount'' 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.
