In diesem Abschnitt werden verschiedene Erweiterungen der Fallstudie vorgestellt und daraus resultierende Constraints ebenfalls in die Taxonomie eingeordnet werden.
\textcolor{blue}{
\begin{enumerate}
\item Kommunikation zwischen den Robotern über TCP Verbindungen
\item Synchronisation der Roboter und gemeinsamer Workflow
\item Verschiedene Behälterformen erfordern beispielsweise das Aufnehmen einer Zange → Handlung → Endeffektor spezifisch
\item Aufnehmen von schweren Behältern begrenzt die Beschleunigung durch maximal verfügbares Drehmoment
\item Sensoren überwachen Umgebung:
\begin{enumerate}
\item Änderung des Verhaltens, wenn Mensch in Sicherheitszone
\item Reagieren auf neue Hindernisse
\end{enumerate}
\item Verschiedene Arten von Behältern → Kraft muss angepasst werden
\end{enumerate}
}
\ No newline at end of file
\paragraph{Synchronisation der Roboter}
Im momentanen Stand der Demo arbeiten beide Roboter unabhängig voneinander und ohne jegliche Informationen über den jeweils anderen. Vorstellbar wäre eine Kommunikation über TCP/IP oder UDP, wodurch die Roboter ihre Workflows synchronisieren könnten. Das würde es ermöglichen alle Teilnehmer in einem einzelnen Ablaufplan zu modellieren, wie von Roman Froschauer und Rene Lindorfer~\cite{froschauer_roman_workflow-based_nodate} vorgeschlagen.
Für die Constraints des Roboters würde das eine Erweiterung der Handlungs-Constraints bedeuten, da die nächste mögliche Handlung nun nicht mehr nur von den eigenen vorherigen Zuständen abhängt, sondern auch von den Zuständen der anderen Teilnehmer. In die bestehende Taxonomie kann der Constraint wie folgt eingeordnet werden:
Die Art des Endeffektors ermöglicht momentan lediglich das Greifen von Objekten geraden Kanten. Ändert sich die Form der Behälter beispielsweise in einen Zylinder, muss der Roboter seinen Endeffektor anpassen oder zuerst eine Art Werkzeug aufnehmen, um die runde Form erfolgreich greifen zu können. Ob eine Handlung also möglich ist, wird in diesem Fall vom Endeffektor eingeschränkt:
Neben der Form der Behälter könnte sich auch deren Material und Stabilität ändern. Das würde eine Anpassung der Kraftaufwendung beim Greifen erfordern, um die Behälter nicht zu beschädigen aber trotzdem sicher zu greifen:
\begin{center}
Robotische Constraints → Bewegung → Geschwindigkeit → Eigenschaften des Werkstücks
\end{center}
\paragraph{Aktive Überwachung der Umgebung}
Durch das Einbinden von Kameras und anderen Sensoren ergibt sich eine Vielzahl an neuen Möglichkeiten. Mit Hilfe von Algorithmen zur Objekterkennung kann die Art des Behälters bestimmt werden, was zu den eben beschriebenen Erweiterungen der Constraints führt. Sensorinformationen können in MoveIt direkt in die Planning Scene mit eingebunden werden. 3D-Informationen sind dabei in einer Octomap repräsentiert, wodurch der Arbeitsbereich überwacht werden kann, um so auf neue Hindernisse reagieren zu können~\cite[Kapitel 3.4/3.5]{koubaa_anis_2016}.
Auch die Sicherheitszone kann erst durch eine aktive Überwachung sinnvoll realisiert werden, da der Roboter ansonsten keine Möglichkeit hat die Annäherung eines Menschen zu registrieren. Die Verwendung von Sensoren ermöglicht demnach das Einschränken des Roboters durch Sicherheitszonen:
Durch die Überwachung des Arbeitsbereichs per Kamera, wäre es möglich eventuell verschüttete Flüssigkeitsreste zu erkennen. Eine zusätzliche Aufgabe wäre diese Reste zu beseitigen.
Dazu benötigt der Roboter ein Werkzeug oder auch einfach ein Tuch, was ebenfalls ein endeffektor-spezifischer Handlungs-Constraint ist. Zum Entfernen muss ein Pfad durch die Flüssigkeit gefolgt werden, ohne die Berührung zum Tisch zu verlieren. Dies erfolgt, indem ein Teilpfad entlang der Ebene des Tisches definiert wird, den der Roboter folgen muss. Alternativ lassen sich auch zwei Punkte auf gegenüberliegenden Seiten der Flüssigkeit definieren, zwischen denen ein Pfad mit kartesischer Pfadplanung berechnet wird. Dabei wird eine Trajektorie gesucht, die die Punkte in einer Geraden verbindet, was auf einem ebenen Tisch auch einen Pfad ohne Berührungsverlust erzeugen würde.
In der Taxonomie wäre das als Definition eines Teilpfades einzuordnen:
Die Erweiterung der Fallstudie um diese Constraints kann auf verschiedene Weisen erfolgen. Constraints, die abhängig vom aktuellen Zustand angewandt und entfernt werden sollen, können anlog zu den Beschleunigungs- und Geschwindigkeits-Constraints realisiert werden, indem sie ebenfalls die abstrakte Klasse \textit{Constraints} implementieren (siehe \Cref{ch:constraint_impl}). Wird der Workflow beschränkt, müsste dieser Constraint Teil des \textit{CobotController}s werden, da dieser in der Demo für den Handlungsablauf verantwortlich ist (siehe \Cref{ch:cobot_impl}).
@@ -145,25 +145,22 @@ Die Drucksensoren veröffentlichen ihren Zustand auf einem Topic, welches von de
\section{Implementierung}
\textcolor{blue}{Kurze Beschreibung, wie die im Entwurf beschriebene Architektur unter Nutzung von ROS implementiert wurde und wie die Constraints in MoveIt umgesetzt worden sind. + Schwierigkeiten}
Implementiert wurde die Demo in \textit{C++} und der ROS Distribution ROS Melodic Morenia auf einem Ubuntu 18.04 System. Zur Kapselung von Verantwortlichkeiten und für eine bessere Wiederverwendbarkeit, ist die Implementation in mehrere Packages aufgeteilt, die über Cmake miteinander gelinkt werden. In den folgenden Abschnitten wird auf die zentralen Packages einzeln eingegangen.
\subsection{Cobot}
\subsection{Cobot}\label{ch:cobot_impl}
Die Pakete \textit{cobot\_1} und \textit{cobot\_2} enthalten jeweils die Implementationen des \textit{CobotController} und der \textit{Cobot}-Klasse. Der \textit{CobotController} ist nicht als tatsächliche Klasse im Sinne der Objektorientierung implementiert, sondern als ROS Node. Das bedeutet er enthält eine Main Methode, die als Einstiegspunkt gilt, sobald er durch den ROS Master initialisiert wird.
Nach erfolgreicher Initialisierung, wird das Topic \glqq pressure\_1\grqq{} beziehungsweise \glqq pressure\_2\grqq{} abonniert, um informiert zu werden, sobald das Glas auf den Drucksensor abgestellt wird. Ein Service Client wird zum Stellen von Anfragen an den \textit{SafezoneController} erstellt und mit Hilfe des \textit{ObjectCreators} werden die Umgebungsobjekte, wie der Tisch, die Behälter und die Drucksensoren, zur Planning Scene hinzugefügt. Erst anschließend beginnt die Abarbeitung des Ablaufdiagramms~\ref{fig:ablaufdiagramm}. Die einzelnen Zustände beziehungsweise Aufgaben werden von einer \textit{Cobot}-Instanz ausgeführt, die für jede Aufgabe eine entsprechende Methode bereitstellt. Eine Implementation einer solchen Aufgabe ist im Codebeispiel~\ref{lst:pick_bottle} dargestellt.
\lstinputlisting[firstline=27,lastline=39, label={lst:pick_bottle}, caption={Beispielimplementation einer Cobot-Aufgabe}]{../cobot_ws/src/cobot_1/src/Cobot.cpp}
Alle Aufgaben erwarten eine Referenz zu einer Move Group, auf der die Bewegung ausgeführt werden soll. Beinhaltet die Aufgabe ein Objekt, wie die Flasche beim Aufnehmen der Flasche, wird zusätzlich noch eine \textit{CollisionObject}-Beschreibung dieses Objektes benötigt, da in ihr Größe und Position des Objektes definiert ist. Die tatsächliche Implementation, zum Aufnehmen und Platzieren von Objekten, ist in einem weiteren Package ausgelagert, damit beide Cobots auf diese Funktionalität zugreifen können und Codeduplikate vermieden werden. Nach Ausführung der Bewegung, werden die notwendigen Constraints angepasst und dem \textit{CobotController}, in Form eines booleschen Werts, den Erfolg der Ausführung zurückgegeben.
Alle Aufgaben erwarten eine Referenz zu einer Move Group, auf der die Bewegung ausgeführt werden soll. Beinhaltet die Aufgabe ein Objekt, wie die Flasche beim Aufnehmen der Flasche, wird zusätzlich noch eine \textit{CollisionObject}-Beschreibung dieses Objektes benötigt, da in ihr Größe und Position des Objektes definiert ist. Die tatsächliche Implementation, zum Aufnehmen und Platzieren von Objekten, ist in einem weiteren Package ausgelagert, damit beide Cobots auf diese Funktionalität zugreifen können und Codeduplikate vermieden werden. Nach Ausführung der Bewegung, werden die notwendigen Constraints angepasst und dem \textit{CobotController}, in Form eines booleschen Werts, den Erfolg der Ausführung zurückgegeben. Die Constraints werden im Konstruktor des \textit{Cobot}s als Klassenvariablen instanziiert und lassen sich so innerhalb der Handlungen anwenden und entfernen.
Neben dem Programmcode enthält das Cobot Package auch noch eine Konfigurationsdatei, in der die vorhandenen Objekte und die Eigenschaften des Sensors beschrieben sind. Dadurch lässt sich die Ausgangssituation anpassen, ohne dass Änderungen am Programmcode notwendig sind, was die Nutzerfreundlichkeit erheblich steigert. Beim Start des Nodes werden die Parameter auf den Parameter Server veröffentlicht, wodurch sie auch von jedem anderen Node abgerufen werden können. Die Position der Flasche auf der X-Achse wird zum Beispiel durch den Parameter \verb|/object/bottle/x: 0.5| konfiguriert. Die Namensgebung der Parameter folgt dabei der ROS-Namenskonvention, um eine Überschneidung auf dem Parameter Server zu vermeiden.
Über die Launch Datei des Packages startet neben dem \textit{CobotController} auch den \textit{SafezoneController}- und \textit{PressureSensor}-Node und eine Simulationsumgebung.
Das Package \textit{constraints} enthält die Definition der abstrakten \textit{Constraint}-Klasse und die \textcolor{blue}{fünf} konkreten Implementationen \textit{AccelerationConstraint}, \textit{OrientationConstraint}, \textcolor{blue}{\textit{ProximityConstraint}}, \textit{SafezoneConstraint} und \textit{VelocityConstraint}.
Der Orientierungs-Constraint (Codebeispiel~\ref{lst:orientation_constraint}) wird realisiert, indem eine \verb|moveit_msgs::OrientationConstraint| Nachricht erstellt wird, die die aktuelle Orientierung des Endeffektors festsetzt. Diese Nachricht wird dann der Move Group als Pfad-Constraint hinzugefügt. Entfernt wird das Constraint durch das Leeren der Liste \verb|path_constraints.orientation_constraints|.