diff --git a/.kile/mechforsch.kilepr.gui b/.kile/mechforsch.kilepr.gui index 7725a01..f9e4f66 100644 --- a/.kile/mechforsch.kilepr.gui +++ b/.kile/mechforsch.kilepr.gui @@ -2,7 +2,7 @@ kile_livePreviewEnabled=true kile_livePreviewStatusUserSpecified=true kile_livePreviewTool=LivePreview-PDFLaTeX -lastDocument=tex/4_Umsetzung.tex +lastDocument=main.tex [document-settings,item:Einleitung.tex] Bookmarks= @@ -139,67 +139,67 @@ TextFolding={"checksum":"","ranges":[]} ViMarks= [view-settings,view=0,item:main.bib] -CursorColumn=33 -CursorLine=321 +CursorColumn=18 +CursorLine=326 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"64bbdc6d25aa8e655ff2b9b9aaa47140545f4269","ranges":[]} +TextFolding={"checksum":"4baf2bb15fceb5c9f2aabf1cf70c4c7dba5ec9f5","ranges":[]} ViMarks= [view-settings,view=0,item:main.tex] CursorColumn=0 -CursorLine=105 +CursorLine=96 Dynamic Word Wrap=false JumpList= TextFolding={"checksum":"80ccd936ce5ae7dc5995816ffe293139ed94b427","ranges":[]} ViMarks= [view-settings,view=0,item:tex/1_Einleitung.tex] -CursorColumn=0 -CursorLine=7 +CursorColumn=68 +CursorLine=43 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"752ca31e1c24d1d85d2d8fb12ebdefa2996283f2","ranges":[]} +TextFolding={"checksum":"75bcf6c0e7387bff6aee008e1995bfd43ba5a46b","ranges":[]} ViMarks= [view-settings,view=0,item:tex/2_Konzept.tex] -CursorColumn=12 -CursorLine=19 +CursorColumn=39 +CursorLine=116 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"6ef833b681fc8f01a09442bcb6e152ae53c9a838","ranges":[]} +TextFolding={"checksum":"03b463289e4adf34859cce5e79432be3ca9c3f53","ranges":[]} ViMarks= [view-settings,view=0,item:tex/3_Auswahl.tex] -CursorColumn=15 -CursorLine=45 +CursorColumn=0 +CursorLine=446 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"7cc0088b0b9cf29bb8431a83dabf12502827f1cd","ranges":[]} +TextFolding={"checksum":"0163bec2d59ee0fdc7502865f6859d4fffa2ee1b","ranges":[]} ViMarks= [view-settings,view=0,item:tex/4_Umsetzung.tex] -CursorColumn=29 -CursorLine=953 +CursorColumn=14 +CursorLine=915 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"109c6b373243657c2344cec26c14be91fef98dc1","ranges":[]} +TextFolding={"checksum":"f6689d8b4009907e1b500952fcd8c46a3c8d88d0","ranges":[]} ViMarks= [view-settings,view=0,item:tex/5_Evaluation_und_Diskussion.tex] -CursorColumn=45 -CursorLine=91 +CursorColumn=82 +CursorLine=135 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"ab50ad5132cf05a1290a02b2b48c793d41937fb9","ranges":[]} +TextFolding={"checksum":"f0868d9f15eec0ec90ab265f5c740a42a7b52d9b","ranges":[]} ViMarks= [view-settings,view=0,item:tex/6_Ausblick.tex] -CursorColumn=82 -CursorLine=21 +CursorColumn=28 +CursorLine=66 Dynamic Word Wrap=false JumpList= -TextFolding={"checksum":"85f5725ed69452476240fe61ecbb12cc35b38976","ranges":[]} +TextFolding={"checksum":"08c80e4a421859760de9f6abca5d28d188b891d5","ranges":[]} ViMarks= [view-settings,view=0,item:tex/Einleitung.tex] diff --git a/img/MA-Animation-Human-End.png b/img/MA-Animation-Human-End.png new file mode 100644 index 0000000..84cb8fa Binary files /dev/null and b/img/MA-Animation-Human-End.png differ diff --git a/img/MA-Animation-Human-Interpolated.png b/img/MA-Animation-Human-Interpolated.png new file mode 100644 index 0000000..2135b52 Binary files /dev/null and b/img/MA-Animation-Human-Interpolated.png differ diff --git a/img/MA-Animation-Human-Start.png b/img/MA-Animation-Human-Start.png new file mode 100644 index 0000000..a9e2f5b Binary files /dev/null and b/img/MA-Animation-Human-Start.png differ diff --git a/img/MA-bend-axis.pdf b/img/MA-bend-axis.pdf new file mode 100644 index 0000000..bc4ddb3 Binary files /dev/null and b/img/MA-bend-axis.pdf differ diff --git a/main.bib b/main.bib index 64bbdc6..8795c48 100644 --- a/main.bib +++ b/main.bib @@ -214,8 +214,8 @@ } @misc{gamerig, - title = {Arminando/GameRig: GameRig is an auto rigging for games addon for Blender. Built on top of Rigify, it adds rigs, metarigs and additional functionality that enable game engine friendly rig creation. Open source and can be used for personal and commercial projects.}, - url = {https://github.com/Arminando/GameRig}, + title = {BlenderBoi/Game_Rig_Tools}, + url = {https://github.com/BlenderBoi/Game_Rig_Tools}, note = {letzter Zugriff: 23.04.2023}, } @@ -323,3 +323,8 @@ doi = {https://doi.org/10.1201/9780429489105} url = {https://github.com/goldsborough/ipc-bench}, note = {letzter Zugriff 30.06.2023}, } +@misc{moveItStudio, + title = {MoveIt Studio Developer Platform \& SDK | PickNik}, + url = {https://picknik.ai/studio/}, + note = {letzter Zugriff 30.06.2023}, +} diff --git a/tex/1_Einleitung.tex b/tex/1_Einleitung.tex index 98f5f5a..2af1f3d 100644 --- a/tex/1_Einleitung.tex +++ b/tex/1_Einleitung.tex @@ -14,19 +14,19 @@ Dies erlaubt lediglich die Reproduktion des geplanten Bewegungsablaufes, aber ni Um eine solche Funktionalität bereitzustellen, müssen die Bewegungsabläufe sowohl von Roboter als auch Mensch zur Laufzeit der Simulation gesteuert werden können. Diese Steuerung soll durch eine eingängliche Beschreibungssprache erfolgen, die einfach erweitert und auf neue Szenarien angepasst werden kann. -Um diese Funktionalität zu demonstrieren, sind 3 unterschiedliche Testszenarien in der Simulationsumgebung abzubilden. +Um die Funktionalität zu demonstrieren, sind 3 unterschiedliche Testszenarien in der Simulationsumgebung abzubilden. Diese sollen durch verschiedene Aufgaben unterschiedliche Interaktionsgrade zwischen Mensch und Roboter simulieren. \section{Stand der Wissenschaft} -Aktuelle wissenschaftliche Arbeiten befassen sich mit vielen unterschiedlichen Teilaspekten einer Simulation eines Mensch-Roboter-Kollaborationsszenarios. +Aktuelle wissenschaftliche Arbeiten befassen sich mit vielen unterschiedlichen Teilaspekten der Simulation eines Mensch-Roboter-Kollaborationsszenarios. Die Planung von unterschiedlichen Reaktionen von Roboter auf den Menschen in verschiedenen Interaktionsszenarien stellt eine Grundlage für spätere Projekte dar.\cite{DOMBROWSKI2018134} Hierbei wird die erwünschte Interaktion betrachtet und aus den gewonnenen Daten werden Einschränkungen generiert. -Diese Einschränkungen können in der Interaktion verwendet werden, zum Beispiel Verletzungen des Menschen durch den Roboter auszuschließen. +Diese Einschränkungen können in der Interaktion verwendet werden, um zum Beispiel Verletzungen des Menschen durch den Roboter auszuschließen. Ein anderer Weg der Kollisionsvermeidung ist die Planung der maximal zurücklegbaren Distanz eines Menschen aus seiner aktuellen Position.\cite{ffdrobotsim} -Dafür werden die maximalen Beschleunigungen einzelner Körperteile ermittelt, um diese während der Interaktion überwachen zu können. +Dafür werden die maximalen Beschleunigungen einzelner Körperteile ermittelt, um diese während der Interaktion zu überwachen. Sollte ein Mensch den Roboter erreichen können, muss dieser in der dafür benötigten Zeit stoppen können. Dies sorgt für eine Geschwindigkeitsanpassung im Nahfeld, da hier schnellere Bewegungen möglich sind. @@ -35,14 +35,14 @@ Dabei kommt es auf die Umsetzung in der Beschreibungssprache, aber auch auf Anfo In Computerspielen werden Beschreibungssprachen schon seit langer Zeit eingesetzt, um verschiedene Systeme, wie zum Beispiel die Steuerung von Nichtspielercharakteren, zu beschreiben.\cite{halo2} -Eine vollständige Umsetzung einer erweiterbaren Simulation mit Mensch und Roboter, gesteuert durch eine Beschreibungssprache konnte bei der Recherche zu dieser Arbeit jedoch nicht gefunden werden. +Eine vollständige Umsetzung einer erweiterbaren Simulation mit Mensch und Roboter, gesteuert durch eine Beschreibungssprache, konnte bei der Recherche zu dieser Arbeit jedoch nicht gefunden werden. \section{Auswahl der Szenarien} -Die drei zu modellierenden Szenarien sollten so gewählt werden, dass spätere komplexere Szenarien auf einfacheren Vorgängern aufsetzten und deren Funktionen weiter nutzen und ergänzen. +Die drei zu modellierenden Szenarien sollten so gewählt werden, dass spätere komplexere Szenarien auf einfacheren Vorgängern aufsetzen und deren Funktionen weiter nutzen und ergänzen. Hierfür kommen bestimmte Aufgaben, wie zum Beispiel die Interaktion mit Objekten besonders in Frage. -Diese besitzen viele ähnliche Bestandteile, die in mehrere Umständen nutzbar sind. +Diese besitzen viele ähnliche Bestandteile, die in mehreren Umständen nutzbar sind. Das erlaubt den Einsatz von wenigen Animationen in vielen Szenarien. -Dazu zählen zum Beispiel das Hineingreifen in einen Prozess, das Aufheben von Material oder das Begutachten eines Objekts, die jeweils nur eine ähnliche Bewegungsabfolge des beteiligten Menschen sind. +Dazu zählen zum Beispiel das Hineingreifen in einen Prozess, das Aufheben von Material oder das Begutachten eines Objekts, welche jeweils nur eine ähnliche Bewegungsabfolge des beteiligten Menschen sind. Das erste Szenario soll sich mit der Simulation einer bereits vollautomatisierten Fertigungsaufgabe befassen, in der ein Roboter im Arbeitsbereich eines Menschen Teile fertigt. Die zu erwartende Interaktion beschränkt sich hierbei auf die Anpassung der Fahrgeschwindigkeit des Roboters bei Annäherung des Menschen, um Kollisionen zu vermeiden. @@ -66,4 +66,4 @@ Durch diese Arbeit soll in zukünftigen Projekten die Möglichkeit geschaffen we Dazu ist eine schnelle Adaption von sowohl Roboter als auch Mensch auf unterschiedliche Szenarien nötig. Die Szenarien sollen dabei durch eine Beschreibungssprache definiert werden. -Durch deren einfache Struktur soll komplexes Verhalten einfach und überschaubar definierbar sein, dass dann in der Simulation getestet werden kann. +Durch deren Struktur soll komplexes Verhalten einfach und überschaubar abbildbar sein, dass dann in der Simulation getestet werden kann. diff --git a/tex/2_Konzept.tex b/tex/2_Konzept.tex index d73a8c0..6822128 100644 --- a/tex/2_Konzept.tex +++ b/tex/2_Konzept.tex @@ -44,7 +44,7 @@ Die so erstellten Animationen müssen von außerhalb der Simulationsumgebung aus Ein solcher Mechanismus erlaubt die spätere Steuerung der Animation durch die Beschreibungssprache. Hierfür muss eine Komponente entwickelt werden, die in der Simulation die Anfragen der Beschreibungssprache entgegennimmt und umsetzt. Um die spätere Steuerung des Menschen von außerhalb zu erleichtern, soll diese Komponente die Ausführung der Befehle überwachen. -Da mehrere Befehle nacheinander ausgeführt werden sollen, soll der aktuelle Fortschritt der Aktion zurückgemeldet werden. +Da mehrere Befehle nacheinander ausgeführt werden sollen, wird der aktuelle Fortschritt der Aktion zurückgemeldet. Außerdem kann durch andere Komponenten in der Simulation der Abbruch einer Aktion des Menschen nötig werden. Die Weitergabe eines Abbruchbefehls soll demzufolge auch über die geplante Komponente realisiert werden können. @@ -58,7 +58,7 @@ Behavior Trees lösen dieses Problem, in dem sie sogenannte Nodes definieren, di Die einzelnen Nodes verändern dabei das System und lösen den Wechsel zu neuen Nodes aus. Ursprünglich wurde das Konzept der Behavior Trees von Rodney Brooks entwickelt, der diese für mobile Roboter einsetzen wollte. \cite{1087032} -Das System setzte sich später jedoch zuerst in der Spieleindustrie, für die Beschreibung von menschlichem Verhalten durch. \cite{isla2005handling} +Das System setzte sich später jedoch zuerst in der Spieleindustrie, für die Beschreibung von menschlichem Verhalten, durch. \cite{isla2005handling} Der Ablauf eines Behavior Trees startet vom sogenannten Root, der Wurzel des Baums. Von dort an werden Nodes, die je nach Node unterschiedliches Verhalten abbilden, miteinander verbunden. @@ -78,7 +78,7 @@ Es gibt mehrere grundlegende Arten von Tree-Nodes, die in vier Kategorien unters Sollte eine Node einen Fehler zurückgeben, wird die Ausführung der Sequenz abgebrochen, was wiederum zur Rückgabe eines Fehlers durch die Sequenz selbst führt. Beim erfolgreichen Durchlauf gibt die Sequenz einen Erfolg zurück. \item[Fallback-Nodes] - verhalten sich ähnlich wie Sequenz-Nodes, jedoch werden darunter liegenden Nodes nacheinander ausgeführt, bis eine Node Erfolg zurück gibt. + verhalten sich ähnlich wie Sequenz-Nodes, jedoch werden die darunter liegenden Nodes nacheinander ausgeführt, bis eine Node Erfolg zurück gibt. In diesem Fall wird die Ausführung der Fallback-Node mit einem Erfolg abgebrochen. Ein Fehler wird hier zurückgegeben, wenn alle Nodes ohne eine Erfolgsmeldung durchlaufen wurden. \end{description} @@ -114,7 +114,7 @@ Folgender Kontrollfluss findet in diesem Beispiel statt: } \item{ Da die untergeornete Node eine erfolgreiche Ausführung meldet, wird die Ausführung der Fallback-Node mit einem erfolgreichen Rückgabewert beendet. - Daher wird die Node "Tür eintreten" nicht mehr ausgeführt. + Aus diesem Grund wird die Node ``Tür eintreten'' nicht mehr ausgeführt. } \item{ Dadurch wird die nächste Node in der Sequenz ausgeführt, die prüft, ob die Tür durchlaufen werden kann. @@ -134,13 +134,13 @@ In dieser Arbeit sollen deshalb BehaviorTrees für die Steuerung von Mensch und Die hierfür erstellten Nodes sollen universell gestaltet werden, um alle Szenarien, die in dieser Arbeit betrachtet werden, abzudecken. \section{Virtualisierungsumgebung als Plattform} -Um Fehler durch die unvollständige Einrichtung der Umgebung zu vermeiden, ist der Einsatz fest definierter Prozesse in einer stabilen Umgebung unerlässlich. +Der Einsatz fest definierter Prozesse in einer stabilen Umgebung ist unerlässlich, um Fehler durch die unvollständige Einrichtung der Umgebung zu vermeiden. Dies kann durch den Einsatz einer Virtualisierungsumgebung geschehen, in der das zu entwerfende System ausgeführt wird. Dadurch können benötigte Programme, Pfade und Umgebungsvariablen in der Virtualisierungsumgebung hinterlegt werden, die diese bei der Ausführung auf einem anderen Grundsystem korrekt abbildet. Eine solche Struktur erhöht die Zuverlässigkeit der Umgebung, da die Änderungen an der Umgebung auf alle ausführenden Systeme gespiegelt werden. -Ein weiterer Vorteil ist die beschleunigte Entwicklung, da Änderungen nicht mehr an einzelne Zielsysteme angepasst werden müssen. +Ein weiterer Vorteil ist die beschleunigte Entwicklung, weil Änderungen nicht mehr an einzelne Zielsysteme angepasst werden müssen. Hinzu kommt die einfachere Inbetriebnahme eines bereits entwickelten Systems, da keine Anpassungen am Hostsystem vorgenommen werden müssen. Natürlich existieren auch Nachteile der Virtualisierung, die mit den Vorteilen abgewogen werden müssen. diff --git a/tex/3_Auswahl.tex b/tex/3_Auswahl.tex index d8d3f8f..e284faf 100644 --- a/tex/3_Auswahl.tex +++ b/tex/3_Auswahl.tex @@ -2,7 +2,7 @@ Die Auswahl der verwendeten Softwarekomponenten beeinflusst den späteren Entwicklungsprozess nachhaltig. Alle Komponenten sollen später in der entwickelten Softwareumgebung ihre jeweiligen Teilbereiche abdecken. -Alle diese Teilbereiche können dann zu einer Simulation vebunden werden, die das gesamte Problemfeld abdeckt. +Alle diese Teilbereiche können dann zu einer Simulation verbunden werden, die 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. @@ -12,10 +12,10 @@ Durch sie werden häufig benötigte Funktionen bereitgestellt, die Programme inn Bei einer Dienstumgebung für Roboter gehört die Nachrichtenübergabe zwischen den einzelnen Programmen zu den grundlegenden Aspekten. Diese wird genutzt, um eine gemeinsame Basis für ein erweiterbares System zu schaffen. -Außerdem sind Werkzeuge zur Einstellungsübergabe an Teilsysteme sinnvoll, um die Einstellungen an einer Stelle gesammelt anpassen zu können. +Außerdem sind Werkzeuge zur Parameterübergabe an Teilsysteme sinnvoll, um die Einstellungen an einer Stelle gesammelt 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. +Es existieren mehrere Systeme, die als Dienstumgebung für Roboter in Frage kommen, wenn man lediglich die Nachrichtenübergabe zwischen Programmen betrachtet. Jede Dienstumgebung, die Nachrichten zwischen Prozessen austauschen kann, ist potentiell als ein Roboterframework einsetzbar. Wichtige Aspekte sind dabei die Geschwindigkeit der Anbindung und die Definition der Nachrichten, die über das System ausgetauscht werden. @@ -23,7 +23,7 @@ Wichtige Aspekte sind dabei die Geschwindigkeit der Anbindung und die Definition Nutzbare, bereits als Interprozesskommunikation integrierte Systeme sind zum Beispiel Pipes, die Daten zwischen Prozessen über Buffer austauschen. Auch die Nutzung von Message Queues oder Shared Memory ist für diesen Einsatzzweck möglich. Diese Systeme sind performant, jedoch schwerer zu verwalten. -Ein Problem dieser Methoden ist die direkte Kommunikation mehrerer Komponenten, da diese Art der Kommunikation keine Modifikation von Nachrichten zur Anpassung an andere Szenarien vorsieht. +Ein Problem dieser Methoden ist die direkte Kommunikation mehrerer Komponenten, da die Art der Kommunikation keine Modifikation von Nachrichten zur Anpassung an andere Szenarien vorsieht. Eine Alternative stellen Sockets dar, die Daten zwischen mehreren Programmen austauschen können. Dabei dient ein Programm als Server, der Anfragen von anderen Programmen, auch Clients genannt, entgegen nimmt. @@ -34,19 +34,19 @@ Dieser Nachteil besteht in der potentiellen Variabilität dieser Kommunikationsm Bei einem ausreichend großen Projekt treten so unweigerlich Unterschiede in der Handhabung von Nachrichten auf, die es zu berücksichtigen gilt. Durch solche Unterschiede kann es zu Inkompatibilitäten zwischen Programmen kommen, was sich auf die universelle Nutzbarkeit der Programme negativ auswirkt. -Im Bereich der Robotik ist ROS\cite{doi:10.1126/scirobotics.abm6074} als Dienstumgebung für Roboter bekannt, da es sich um ein etabliertes und quelloffenes System handelt. -Der oben genannte Nachteil einzelner Systeme wird in ROS durch mehrere standardisierte und erweiterbare Nachrichtendefinition gelöst, die von den Programmen in der Umgebung genutzt werden. -Um diese Nachrichten senden und empfangen zu können, liefert ROS eine eigene Implementation des Protokolls für mehrere Programmiersprachen mit. -Für zum Beispiel Python\cite{python}, C und C++\cite{cpp} existieren entsprechende Implementationen in Form der Pakete \code{rospy}, \code{rclc} und \code{rclcpp}. +Im Bereich der Robotik ist ROS\cite{doi:10.1126/scirobotics.abm6074}, bei dem es sich um ein quelloffenes System handelt, als Dienstumgebung etabliert. +Der oben genannte Nachteil einzelner Systeme wird in ROS durch mehrere standardisierte und erweiterbare Nachrichtendefinitionen gelöst, die von den Programmen in der Umgebung genutzt werden. +Um diese Nachrichten senden und empfangen zu können, liefert ROS bereits eine eigene Implementation des Protokolls für mehrere Programmiersprachen mit. +Zum Beispiel existieren für Python\cite{python}, C und C++\cite{cpp} entsprechende Implementationen in Form der Pakete \code{rospy}, \code{rclc} und \code{rclcpp}. -Die neuste Version ROS2 bietet dabei mehrere Verbesserungen im Vergleich zu früheren Version ROS1 \cite{changesRosII}. +Die neuste Version ROS2 bietet mehrere Verbesserungen im Vergleich zu früheren Version ROS1 \cite{changesRosII}. Ein neues Nachrichtenformat mit Quality of Service kann beispielsweise Nachrichten zwischenspeichern und über sowohl TCP, als auch UDP kommunizieren. Außerdem werden neben CMake\cite{cmake} auch andere Buildsysteme unterstützt, was die Verwendung von Python erlaubt. Generell existieren im Feld der Roboter-Dienstumgebungen keine freien Alternativen mit ähnlichem Funktionsumfang und gleicher Reichweite. Vor allem die Vielzahl von ROS-Bibliotheken, die von Nutzern des Systems über die Jahre erstellt wurden, machen das System so populär.\cite{rospackages} -ROS kann für simulierte Umgebungen, aber auch für echte Roboter eingesetzt werden. +ROS kann sowohl für simulierte Umgebungen als auch für echte Roboter eingesetzt werden. Diese beiden Anwendungsfälle werden durch unterschiedliche Controller realisiert. Für simulierte Umgebungen leitet der Controller die Steuerdaten an die Simulationsumgebung weiter. Bei dem Einsatz echter Hardware werden die Zielpositionen durch den Controller an die Roboterhardware weitergeleitet. @@ -78,7 +78,7 @@ Zu den Aufgaben von ROS zählen folgende Teilbereiche: \item[Buildumgebung]\hfill \\ ROS nutzt die eigene Buildumgebung \code{colcon} \cite{colcon}, um Pakete in den Workspaces reproduzierbar zu erstellen. Zu deren Konfiguration wird eine \code{CMakeLists.txt}-Datei erstellt, die den Buildprozess beschreibt. - In dieser sind die Buildinstruktionen für den Kompiler enhalten, mit welchen die im Paket befindlichen Programme kompiliert werden können. + In dieser sind die Buildinstruktionen für den Kompiler enhalten, mit welchen die im Paket befindlichen Programme kompiliert werden. Der Aufruf des \code{ament_cmake}-Makros in dieser ergänzt den Kompiliervorgang um weitere Parameter aus der \code{package.xml}-Datei. Nach diesen Vorbereitungsschritten kann CMake das Paket kompilieren. @@ -88,7 +88,7 @@ Zu den Aufgaben von ROS zählen folgende Teilbereiche: Diese sind dann später im erstellten Workspace für die Nutzung durch andere Programme verfügbar. \item[Workspaceverwaltung]\hfill \\ - Gruppen von Paketen befinden sich in sogenannen ``Workspaces''. + Gruppen von Paketen werden zur einfacheren Handhabung in sogenannen “Workspaces” zusammengefasst. Diese vereinfachen das Auffinden der enthaltenen Pakete durch Skripte, die diese im System registrieren. Die Erstellung der Skripte erfolgt anhand der bereits beschriebenen \code{CMakeLists.txt}-Datei. Das Programm \code{colcon} analysiert diese und generiert die Skripte. @@ -116,7 +116,7 @@ Zu den Aufgaben von ROS zählen folgende Teilbereiche: Um Nodes auf neue Anwendungsfälle anpassen zu können, wird ein Konfigurationsmechanismus benötigt. In ROS geschieht dies durch die Übergabe sogenannter Parameter, die durch die Node gelesen werden können. Diese eignen sich zur Übergabe von Informationen, wie zum Beispiel Daten über ein verwendetes Robotermodell. - Um neue Konfigurationen zu unterstützen, kann das Umbenennen von Topics einer Node nötig werden, was auch mit einen Parameter erfolgen kann. + Um neue Konfigurationen zu unterstützen, kann das Umbenennen von Topics einer Node notwendig werden, was auch mit einem Parameter erfolgen kann. \item[Startverwaltung]\hfill \\ In sogenannten ``launch''-Files können verschiedene Nodes und andere ``launch''-Files zu komplexen Startvorgängen zusammengefasst werden. @@ -132,29 +132,29 @@ Dies vereinfacht die spätere Wartung des Projekts. \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. +Hierfür kommen beispielsweise dedizierte Werkzeuge zur Robotersimulation, aber auch universell einsetzbare Gameengines in Frage. +Ein Vergleich dieser Werkzeuge ist hierbei sinnvoll, da sich der gebotene Funktionsumfang der Softwares stark unterscheidet. +Auch andere Aspekte, wie Lizenzen oder die schwer bewertbare Nutzerfreundlichkeit, sind hierbei zu betrachten. Eine Auswahl der als Simulationsumgebung in Frage kommenden Programme wird 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, die sich im Funktionsumfang und Lizenz unterscheiden. +Der Simulator selbst unterstützt menschliche Aktoren, diese können aber nur Animationen allein oder in Kombination mit einer Bewegung abspielen. +CoppeliaSim existiert in 3 Versionen, die sich hinsichtlich Funktionsumfang und Lizenz unterscheiden. Jedoch besitzt 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, die die gewünschten Funktionen einbinden können. -Zum Beispiel existiert auch eine ROS-Brücke, welche die Anbindung an ROS ermöglicht. +Gazebo Ignition\cite{gazebo} ist wie CoppeliaSim eine Robotersimulationsumgebung, besitzt aber keinen integrierten Editor und direkte ROS-Unterstützung. +Gazebo setzt wie CoppeliaSim auf Erweiterungen, um zusätzliche Funktionen einbinden zu können. +So existiert zum Beispiel auch eine ROS-Brücke, die 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. +Unity\cite{unity} hingegen ist primär eine Grafikengine für die 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 umfangreich, da diese häufig in Spielen verwendet werden. -Ein großer Nachteil hingegen ist die Lizenz, die nur für Einzelpersonen kostenlos ist. +Ein großer Nachteil hingegen ist die Lizenz, die nur für Einzelpersonen kostenfrei 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. @@ -164,21 +164,21 @@ Die Lizenz der Unreal Engine erlaubt die kostenfreie Nutzung bis zu einem gewiss 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 hier stellt die Simulation von menschlichen Aktoren eine Standardaufgabe 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, dass die Simulation von starren Körpern und Gelenken erlaubt. +Alle vorgestellten Softwares besitzen ein integriertes Physiksystem, dass die Simulation von starren Körpern und Gelenken erlaubt. Diese Funktionen erlauben den Aufbau eines Roboterarms, der durch eine ROS-Brücke gesteuert wird. Um den Fokus dieser Arbeit auf die gestellte Aufgabe zu ermöglichen, ist die Auswahl einer Umgebung mit bereits existierender ROS-Unterstützung sinnvoll. Durch diese Einschränkung scheiden sowohl Unreal Engine aber auch Godot aus. -Diese bieten zwar diese Funktionalität, jedoch wird diese nur durch Nutzer gewartet und ist demzufolge nicht offiziell unterstützt. -Für einen späteren Einsatz ist eine offene Lizenz von Vorteil, da diese einen Einsatz in nahezu allen Umständen erlaubt. +Sie bieten zwar diese Funktionalität, jedoch werden sie nur durch Nutzer gewartet und sind demzufolge nicht offiziell unterstützt. +Für einen späteren Einsatz ist eine offene Lizenz von Vorteil, da diese einen Einsatz unter nahezu allen Umständen erlaubt. -Die Wahl der hier zu verwendenden Simulationsumgebung fiel deshalb auf Gazebo Ignition, dass gleichzeitig bereits im ROS-Ökosystem etabliert ist. -Dabei erlauben die offizielle ROS-Anbindung und offene Lizenz eine zuverlässige Verwendung in unterschiedlichsten Szenarien. +Die Wahl der hier zu verwendenden Simulationsumgebung fiel deshalb auf Gazebo Ignition, welche gleichzeitig bereits im ROS-Ökosystem etabliert ist. +Dabei erlauben die offizielle ROS-Anbindung und die 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}. +Gazebo nutzt das .sdf-Dateiformat, um die Simulationsumbebung zu beschreiben\cite{sdf-format}. Dieses Format basiert auf XML und wird zur Definition gesamter Welten, aber auch einzelner Objekte innerhalb dieser Welten benutzt. Eine Welt ist in Gazebo eine Umgebung aus mehreren Objekten, welche simuliert werden sollen. Die Welt beschreibt außerdem die simulierte Physikumgebung und deren Konstanten, wie zum Beispiel die Gravitation. @@ -188,10 +188,10 @@ Eine solche Datei kann, wie bereits oben beschrieben, unterschiedliche Daten ent 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. +Eine Welt definiert in Gazebo den kompletten Aufbau 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, die im ausgeführten Simulator verfügbar sein sollen. -Letzendlich ist auch die Definition mehrerer Modelle, Aktoren und Lichter in der Welt möglich. +Letzendlich ist die Definition mehrerer Modelle, Aktoren und Lichter in der Welt möglich. Diese können auch aus anderen URIs stammen, die in der Welt deklariert wurden. Dies erlaubt zum Beispiel das Laden von vorher definierten Objekten oder Objekten aus der offiziellen Bibliothek\cite{gazebo-app}. @@ -205,19 +205,19 @@ Außerdem können im Modell Einstellungen für dessen Physiksimulation vorgenomm Ein Modell enhält meist mindestens ein Link-Element, dass 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. +Diese Joint-Elemente können jedoch nicht von außerhalb gesteuert werden, was das Dateiformat ungeeignet für Roboterdefinitionen macht. Lichter besitzen einen Lichttyp, der die Ausbreitung des Lichtes im Raum bestimmt. Die erste Art ist direktionales Licht, dass parallel zur gewünschten Achse auftrifft. Solche Lichter werden vor allem zur grundlegenden Raumausleuchtung genutzt. -Außerdem existieren noch Punktlichtquellen, die von einer Position im Raum ausgehen. -Neben den Punklichtquellen existieren auch noch Spots, die außerdem noch nur einen gewissen Winkel ausleuchten. +Weiterhin sind Punktlichtquellen verfügbar, deren Licht von einer Position im Raum ausgeht. +Neben den Punklichtquellen existieren auch noch Spots, die außerdem nur einen gewissen Winkel ausleuchten. 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. +Diese können durch in einem Skript definierte Trajectories ausgeführt werden, was eine einfache, aber statische, Simulation des Menschen erlaubt. -Eine solche Befehlsfolge kann jedoch nicht von außerhalb der Simulation zur Laufzeit angepasst werden. +Eine solche Befehlsfolge kann nicht von außerhalb der Simulation zur Laufzeit angepasst werden. Diese Funktionalität wurde im Rahmen der Arbeit hinzugefügt. \subsection{Robotersimulation} @@ -259,16 +259,16 @@ Dadurch ist zum Beispiel eine Laufanimation realisierbar, die synchronisiert zu Dies setzt jedoch voraus, dass der gesamte Bewegungsablauf zum Simulationsstart bekannt ist. Der Grund dafür ist auf die Definition der Pfade zurückzuführen, die Aktionen wie Bewegungen und Animationen auslösen. 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. +Durch diesen Umstand ist der damit 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, der die Befehle entgegennimmt, unter konstantem Feedback ausführt und nach Erfolgreicher Ausführung den Empfang des nächsten Befehlts zulässt. +Dafür soll ein ROS Action-Server verwendet werden, der die Befehle entgegennimmt, unter konstantem Feedback ausführt und nach erfolgreicher Ausführung den Empfang des nächsten Befehls zulässt. Ein solches System soll als Gazebo-Plugin einbindbar sein, um Modifikationen an der Simulationsumgebung selbst auszuschließen, die konstant weiter entwickelt wird. Dies vereinfacht die 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. +MoveIt2\cite{moveit-docs} ist das meist genutzte ROS2 Paket für die Bewegungsplanung von Robotern. Deshalb existiert eine umfangreiche Dokumentation für die zahlreichen Komponenten, was die Entwicklung neuer Komponenten erleichtert. Außerdem sind zahlreiche direkte Integrationen mit anderen ROS-Paketen verfügbar, was die Nutzung dieser zusammen mit MoveIt erlaubt. Aufgrund dieser Eigenschaften ist MoveIt eine vorteilhafte Bewegungsplanungsumgebung für dieses Projekt. @@ -279,21 +279,21 @@ Der Nutzer kann mit MoveIt auf verschiedenen Wegen Steuerbefehle für den Robote Die erste Inbetriebnahme ist über das mitgelieferte RViz-Plugin und die demo-Launch-Files möglich. Diese wurden mit dem mitgelieferten Setupassistenten für den Roboter generiert. Durch die Ausführung dieser Demo startet RViz, eine Test- und Visualisierungsumgebung für ROS. -In dieser können Roboterbewegungen unter Zuhilfenahme von Markierungen in RViz geplant und ausgeführt werden. +In der Demo 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, dass den Zugriff auf MoveIt in Pyhon erlaubt, dass aber für MoveIt2 noch nicht portiert wurde\cite{moveitpython}. +Da sich eine Bewegungsplanung in einer Nutzeroberfläche 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 von MoveIt das moveit_commander Paket, welches den Zugriff auf MoveIt in Pyhon erlaubt, 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 können sowohl die Planung und Ausführung von Bewegungen ausgelöst aber auch Exklusionszonen eingerichtet werden. +Dabei können sowohl die Planung und die Ausführung von Bewegungen ausgelöst 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. +Natürlich können die Befehle auch direkt an die entsprechenden Topics gesendet werden, um einzelne Bereiche des Systems zu testen. 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, die Roboterparameter zur Laufzeit anfordern, unter diesen auch MoveIt selbst. +Dieser lädt alle Daten des Robotermodells und übergibt sie an andere Programme, die Roboterparameter 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. +Durch die vorher erwähnte 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. @@ -308,11 +308,11 @@ Der Erfolg der gesamten Pipeline kann dabei durch einen Feedbackmechanismus übe Im Falle von Gazebo wird \code{ign_ros_control} genutzt, dass 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. +Der Ablauf der Bewegungsplanungspipeline von MoveIt ist im Anhang unter Abbildung \ref{moveitpipeline} visualisiert. \section{Programmiersprache} Als Programmiersprache kommen in ROS standardmäß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. +Beide Sprachen sind in der Softwareentwicklung beliebt, unterscheiden sich jedoch stark im Funktionsumfang und im Entwicklungsprozess. Python ist eine interpretierte Skriptsprache, die zu den hohen Programmiersprachen zählt. Sie wird in ROS zum Beispiel in \code{.launch.py}-Dateien eingesetzt, die den Start von Diensten in der Umgebung verwalten. @@ -326,10 +326,10 @@ Die Nutzung eines Kompilierers beschleunigt C++ deutlich im Vergleich zu Python, Dies ist vor allem in häufig geänderten Programmen ein Nachteil, die nach einer Änderung erneut kompiliert werden müssen. 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++ nahezu unumgänglich. +Um die gewünschten Funktionen für die Simulation umzusetzen ist die Verwendung der Programmiersprache C++ nahezu unumgänglich. Zum Beispiel sind Gazebo-Plugins in C++ erstellt, was die Nutzung anderer Sprachen stark einschränkt. -Ein Grund für die Nutzung von C++ ist die hohe Geschwindigkeit, die bei einer hohen Anzahl von Simulationsschritten pro Sekunde benötigt wird. +Ein weiterer Grund für die Nutzung von C++ ist die hohe Geschwindigkeit, die bei einer hohen Anzahl von Simulationsschritten pro Sekunde benötigt wird. Außerdem kann MoveIt2 derzeit nur mit C++ direkt gesteuert werden. Die Verwendung von C++ für die zu entwickelnden Nodes erscheint deshalb aus oben genannten Gründen naheliegend. @@ -339,27 +339,27 @@ In den Launch-Skripten wird jedoch Python verwendet werden, da hier die Vorteile Zur Verwaltung der Abläufe sollen BehaviorTrees genutzt werden, die durch die Bibliothek \code{BehaviorTree.CPP} bereitgestellt werden. Diese Bibliothek wurde in C++ geschrieben, und ist somit in ROS und dem geplanten Konzept integrierbar. -Es existieren auch viele Beispiele und eine gute Dokumentation über die erweiterten Funktionen der Bibliothek, die im folgenden vorgestellt werden. +Es existieren viele Beispiele und eine gute Dokumentation über die erweiterten Funktionen der Bibliothek, die im Folgenden vorgestellt werden. \begin{description} \item[Asynchrone Nodes] sind in \code{BehaviorTree.CPP} leichter umsetzbar, da diese in Form verschiedener Zustände der Nodes beim Konzept der Bibliothek mit bedacht wurden. Dies resultiert in Nodes, die 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. + \item[Reaktives Verhalten] ist ein neues Konzept, um die Handhabung von asynchronen Nodes zu vereinfachen. Diese Strukturelemente erlauben die parallele Ausführung von mehreren Zweigen, die die aktuell ausgeführte Aktion 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 Austausch des Verhaltens, ohne die unterliegende Programme verändern zu müssen. + \item[Das .xml-Format der Behavior Trees] ermöglicht einen Austausch des Verhaltens, ohne die unterliegenden Programme verändern zu müssen. Dies ist vor allem in kompilierten Sprachen wie C++ sinnvoll, da Änderungen im Verhaltensablauf keiner Neukompilierung 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. + Dies vereinfacht die Erweiterung um neue Funktionen und das mehrfache Nutzen von Code. \item[Das Blackboard] ist eine Interaktionsebene, die 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. + Dies erleichtert das häufig schwierige Debuggen von Zustandsmaschinen erheblich, da das Verhalten genau untersucht werden kann. \end{description} -BehaviorTrees werden in \code{BehaviorTree.CPP} in Form von .xml-Dateien gespeichert. +BehaviorTrees werden bei Verwendung von \code{BehaviorTree.CPP} in Form von .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. @@ -369,15 +369,15 @@ Um dies zu ermöglichen, kann deren Funktion durch mehrere andere Nodes in einem 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, die einen String in den gewünschten Zieltyp übersetzt. -Viele primitive Datentypen, wie Ganzzahlen und Gleitkommazahlen, werden von BehaviorTree.Cpp bereits durch mitgelieferte Funktionen unterstützt. +Viele primitive Datentypen, wie Ganzzahlen und Gleitkommazahlen, werden von BehaviorTree.Cpp bereits durch native Funktionen unterstützt. Das Blackboard ist ein System, dass 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, die 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, die im BehaviorTree eingesetzt werden kann. +Um die dadurch wachsenden Strukturen besser überblicken zu können, lassen sich Gruppen von Nodes als sogenannte Subtrees abspeichern. +Diese bilden in ihrer Gesamtheit eine neue Node, die 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. @@ -389,29 +389,28 @@ Die Bibliothek \code{BehaviorTree.CPP} verbindet dann diese Werte und erlaubt di 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. +Eine asynchrone Node besitzt neben den Zuständen SUCCESS und FAILURE einer normalen Node auch die beiden neuen Zustände RUNNING und IDLE. Außerdem werden mehrere Funktionen definiert, die den Lebenszyklus der Node definieren. 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, die 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. +So lange 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, der 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, der durch andere Nodes im Baum ausgelöst werden könnte, muss die Ausführung der Node vorzeitig beendet werden können. -Dies geschieht mit der neuen \code{onHalted}-Funktion. -Diese wird ausgeführt, wenn die Ausführung der Node abgebrochen werden soll. +Dies geschieht mit der neuen \code{onHalted}-Funktion, welche ausgeführt wird, wenn die Ausführung der Node abgebrochen werden soll. \subsection{Dateiformat} Das in BehaviorTree.Cpp verwendete Dateiformat, um Behavior Trees zu erstellen, basiert auf XML. Jedes Dokument beginnt dabei mit einem Root-Element, dass 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. +Diese wird benötigt, da auch Unterbäume im selben Dokument deklariert und genutzt werden können, die aber sonst nicht vom Hauptbaum unterscheidbar sind. Jeder Baum beginnt mit einem BehaviorTree-Element, das als Attribut die ID des Baumes besitzen muss. -Als untergeornete Elemente des Baumes werden die Nodes entsprechend der gewünschten Baumstruktur angeordnet. +Als untergeordnete Elemente des Baumes werden die Nodes entsprechend der gewünschten Baumstruktur angeordnet. -Als Beispiel wird der bereits im Konzept verwendete Behavior Tree (hier nochmals in Abbildung \ref{choice_tree_xml} zu sehen) in die entsprechende XML-Repräsentation umgewandelt. +Als Beispiel wird der bereits im Konzept verwendete Behavior Tree (siehe Abbildung \ref{choice_tree_xml}) in die entsprechende XML-Repräsentation umgewandelt. Dabei ist zu beachten, dass die Root-Node in der Datei nicht 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] @@ -443,22 +442,22 @@ Außerdem können selbst definierte Nodes sowohl direkt mit ihrem Namen, aber au \section{Virtualisierungsumgebung} -Die Auswahl der Virtualisierungsumgebung erfolgt zwischen einer virtuellen Maschine und einer Containerumgebung. +Bei Virtualisierungsumgebungen wird zwischen virtuellen Maschinen und Containerumgebungen unterschieden. -Bei einer virtuellen Maschine (VM) werden alle Komponenten der Maschine simuliert, was das Nutzen anderer Betriebssysteme ermöglicht. +Bei einer virtuellen Maschine (VM) werden alle Komponenten der Maschine simuliert, was die Nutzung anderer Betriebssysteme ermöglicht. Dies beinhaltet auch die Abstraktion von Speichermedien und anderen Geräten. -Eine virtualisierte Umgebung erzeugt kleine Performanceverluste durch diese Abstraktion. +Eine virtualisierte Umgebung erzeugt kleine Performanceverluste durch die Abstraktion. Eine Containerumgebung nutzt den Kernel des Hostsystems mit, was die Virtualisierug auf die Ebenen über dem Betriebssystem beschränkt. Die auszuführende Umgebung muss also mit dem Systemkernel lauffähig sein, um in einem Container ausgeführt werden zu können. Die Performanceverluste dieser Umgebung sind kleiner als die einer virtuellen Maschine, da grundlegende Teile des Systems nicht mehrfach ausgeführt werden müssen. -Da bereits eine Linux-Maschine zur Entwicklung vorhanden ist, ist die Virtualisierung eines weiteren Linux-Kernels nur mit weiterem Performanceverlust verbunden. -Außerdem soll in der Virtualisierungsumgebung Grafikbeschleunigung genutzt werden, wozu in einer VM eine Grafikkarte an das Zielsystem durchgereicht wird. -In einer Containerumgebung kann die Grafikeinheit des Hostsystems mit genutzt werden, indem die Geräte in den Container hereingereicht werden. +Da bereits eine Linux-Maschine zur Entwicklung vorhanden ist, wäre die Virtualisierung eines weiteren Linux-Kernels nur mit weiterem Performanceverlust verbunden. +Außerdem soll in der Virtualisierungsumgebung Grafikbeschleunigung genutzt werden, wozu in einer VM eine Grafikkarte an das Zielsystem durchgereicht wird, die dann von der VM exklusiv genutzt wird. +In einer Containerumgebung kann die Grafikeinheit des Hostsystems mit genutzt werden, indem das durch das Hostsystem bereits abstrahierte Gerät in den Container hereingereicht werden. -Auf Grund dieser Punkte wurde eine Containerumgebung verwendet. -Docker ist eine verbreitete Umgebung für die Ausführung von Containern, die auf Grund der extensiven Dokumentation und Verfügbarkeit auf allen gängigen Linux-Systemen ausgewählt wurde. +Diese Punkte sprechen für die Nutzung einer Containerumgebung. +Docker ist eine etablierte Umgebung für die Ausführung von Containern, die auf Grund der extensiven Dokumentation und Verfügbarkeit auf allen gängigen Linux-Systemen ausgewählt wurde. Ein Container wird in Docker über sogenannte Build-Files definiert. Das Build-File enthält exakte Instruktionen, wie der Container aus anderen Containern, Dateien oder einer Kombination beider erstellt werden kann. diff --git a/tex/4_Umsetzung.tex b/tex/4_Umsetzung.tex index 6bdc45d..f6689d8 100644 --- a/tex/4_Umsetzung.tex +++ b/tex/4_Umsetzung.tex @@ -22,7 +22,7 @@ Um Docker für die Verwaltung einer ROS-Installation verwenden zu können, müss Da viele Anwendungen, unter anderem auch die Simulationsumgebung, eine Desktopumgebung benötigen, musste der Zugriff auf eine solche Umgebung berücksichtigt werden. Diese Probleme können nicht durch Docker allein gelöst werden, da die Virtualisierungsumgebung eine Trennung der Systeme vorsieht. -Die Isolation des Containers von der Benutzeroberfläche des Systemskann durch eine Kombination aus zwei Komponenten aufgehoben werden. +Die Isolation des Containers von der Benutzeroberfläche des Systems kann durch eine Kombination aus zwei Komponenten aufgehoben werden. Um diese Modifikationen trotzdem reproduzierbar zu machen, wurde ein Shellscript geschrieben, dass zum Starten des Containers verwendet wird. @@ -38,31 +38,36 @@ Um Zugriff auf die Grafikbeschleunigung des Systems zu erhalten, muss deren Repr Der Zugriff auf die Desktopumgebung, der im vorherigen Schritt entsperrt wurde, wird durch das mounten von \code{/tmp/.X11-unix} erreicht. Dabei handelt es sich um den Unix-Socket des X11 Displayservers. -Zum Starten des Containers muss das Script \code{start.sh} im Verzeichnis der Containerinstallation ausgeführt werden. -Dieser führt die obengenannten Schritte aus und startet den Container. +Zum Starten des Containers wird das Script \code{start.sh} im Verzeichnis der Containerinstallation ausgeführt. +Das Script führt die obengenannten Schritte aus und startet den Container. Eine Verbindung zum Container ist möglich, nachdem die Meldung \code{ros_1 | Ready to connect.} in der Konsole erscheint. -Dafür wird ein SSH-Client eingesetzt, der eine Verbindung zu der lokalen Netzadresse des Systems mit dem Benutzer \code{ros} aufbauen kann. +Dafür wird ein SSH-Client eingesetzt, der eine Verbindung zu der lokalen Netzadresse des Systems mit dem Benutzer \code{ros} aufbaut. Der Port des SSH-Servers wird dabei durch die Deklaration im docker-compose.yaml an das Hostsystem durchgereicht. -Hierbei ist zu beachten, dass der SSH-Server im Container auf Port 2222 ausgeführt wird. +Hierbei ist zu beachten, dass der SSH-Server im Container vom Host aus über Port 2222 erreichbar ist. Nach der Verbindung wird automatisch die ROS2-Umgebung eingerichtet. -Diese kann ohne weitere Befehle nach Verbindungsaufbau genutzt werden. -Um die erstellten Pakete zu kompilieren, wurde das Skript \code{build.sh} im \code{workspace}-Verzeichnis erstellt. +Diese kann ohne weitere Befehle nach dem Verbindungsaufbau genutzt werden. +Um die erstellten Pakete zu kompilieren, wurde das Skript \code{build.sh} (Abbildung \ref{buildscript}) im \code{workspace}-Verzeichnis erstellt. + +\begin{figure} \begin{minted}[breaklines,frame=single]{bash} #!/bin/bash pushd "$(dirname "$0")" || exit colcon build --event-handlers console_cohesion+ --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -G Ninja popd || exit \end{minted} +\caption{build.sh Shellskript} +\label{buildscript} +\end{figure} Dieses Skript nutzt \code{colcon}, um alle Pakete in \code{~/workspace}-Verzeichnis zu erstellen. Dabei wird auch eine \code{compile_commands.json}-Datei im build-Unterordner erstellt, die von Entwicklungsumgebungen zur Syntaxvervollständigung genutzt werden. Um eine Nutzung in allen Entwicklungsumgebungen zu erlauben, wurde diese zusätzlich in das Hauptverzeichnis des Workspaces gelinkt. -Dies ist dem Fakt geschuldet, dass einige Entwicklungsumgebungen nur dort nach dieser Datei suchen. +Dies ist notwendig, da einige Entwicklungsumgebungen nur dort nach dieser Datei suchen. -Da der Kompiliervorgang parallel abläuft, erscheinen Informationen zu allen Paketen gleichzeitig, was das Finden von Fehlern erschwert. +Da der Kompiliervorgang parallel abläuft, erscheinen Informationen zu allen Paketen gleichzeitig, was die Zuordnung von Fehlern erschwert. Um trotzdem alle wichtigen Informationen zu erhalten, kommt der Event-Handler \code{console_cohesion} zum Einsatz, der die Ausgaben neu formatiert. Durch diesen werden die Ausgaben gruppiert, und erst nach einen vollständigen Kompiliervorgang eines Pakets nacheinander ausgegeben. Dies ermöglicht es, aufgetretene Fehler einfacher auf ein bestimmtes Paket zurückführen zu können, ohne das gesamte Log zu durchsuchen. @@ -98,21 +103,20 @@ Dazu wird beim Start einer Verbindung zu einem entfernten System dieser Server a Die anfängliche Entwicklung wurde mit PyCharm und CLion durchgeführt, da diese durch ihre interne Codeanalyse die ROS-Umgebung ohne Konfiguration nutzen konnten. Jedoch sind diese Umgebungen sehr ressourcenintensiv, was die gleichzeitige Ausführung erheblich verlangsamt. -Aus diesem Grund wurde später eine Entwicklungsumgebung mit LSP-Unterstützung, in diesem Fall Lapce, verwendet. -Die Verwendung dieser Entwicklungsumgebung erfordert einen LSP-Server. -Dieser wird durch eine Veränderung des Buildscripts automatisch im Container installiert. +Daher wurde später eine Entwicklungsumgebung mit LSP-Unterstützung, in diesem Fall Lapce, verwendet. +Der dafür notwenige LSP-Server wird durch eine Veränderung des Buildscripts automatisch im Container installiert. Unter Verwendung dieser neuen Server kann Lapce die Codevervollständigung und Codeanalyse wie PyCharm und CLion durchführen. -Durch diese Maßnahme wird der Ressourcenverbrauch gesenkt, da nur ein einziger Editor benötigt wird. +Gleichzeitig wird der Ressourcenverbrauch gesenkt, da nur ein einziger Editor benötigt wird. -\begin{figure} +\begin{figure}[ht] \includegraphics[width=\textwidth]{img/MA-Umsetzung-Lapce} \centering \caption{Entwicklungsumgebung Lapce} \label{lapce} \end{figure} - +\newpage \section{Verwendete Datentypen}\label{datatypes} -In diesem Projekt werden viele unterschiedliche Datentypen für sowohl den Datenaustauch zwischen Nodes, aber auch in der internen Implementation der Nodes verwendet. +In diesem Projekt werden viele unterschiedliche Datentypen sowohl für den Datenaustauch zwischen Nodes, als auch in der internen Implementation der Nodes verwendet. Diese Datentypen sind größtenteils aus der Programmiersprache C++ bekannt, jedoch werden auch weitere Typen aus eigenem Code oder eingebundenen Bibliotheken verwendet. Um die Verständlichkeit der Dokumentation zu erleichtern, sind die in der Implementation verwendeten Datentypen hier zusammengefasst und beschrieben. \begin{description} @@ -123,29 +127,29 @@ Um die Verständlichkeit der Dokumentation zu erleichtern, sind die in der Imple Objekte wie der Mensch liegen in der Hierarchie der Simulation direkt unter der Welt, deren Pose sich direkt im Nullpunkt und ohne Rotation befindet. Durch diesen Umstand sind die Koordinaten des Menschen absolut, da sie nicht durch die Welt verschoben und rotiert werden. \item[Area] - ist eine Datenstruktur mit einem Vektor an Positionen, die eine Zone im Zweidimensionalen Raum definieren. - Jede Position ist eine einfache Datenstruktur aus 2 Gleitkommazahlen für je die X- und Y-Koordinate der Position. - Der Verwendungszweck dieser Struktur ist die einfache Definition von Zonen, die für Positionsgenerierungen und Postionsabfragen genutzt werden können. + ist eine Datenstruktur mit einem Vektor an Positionen, die eine Zone im zweidimensionalen Raum definieren. + Jede Position ist eine einfache Datenstruktur aus 2 Gleitkommazahlen, die den X- und Y-Koordinaten der Position entsprechen. + Der Verwendungszweck dieser Struktur ist die einfache Definition von Zonen, die für Positionsgenerierungen und Positionsabfragen genutzt werden können. \item[ActorPluginState] definiert 4 Zustände, die das ActorPlugin annehmen kann. Diese 4 Werte sind SETUP, IDLE, MOVEMENT und ANIMATION. \item[FeedbackMessage] beschreibt die erste der beiden MessageQueue-Nachrichten, die vom ActorPlugin an den ActorServer gesendet wird. - In dieser Struktur befindet sich der aktuelle Plugin-Zustand als \code{state} Parameter vom Typ ActorPluginState. - Außerdem ein \code{progress} Parameter in Form einer Gleitkommazahl, die den Fortschritt der aktuellen Aktion angibt. - Um bei Bewegungen die aktuelle Position des Menschen zu erhalten, ist auch die aktuelle Pose des Modells im Parameter \code{current} enthalten. + In dieser Struktur befindet sich der aktuelle Plugin-Zustand als \code{state} Parameter vom Typ ActorPluginState + und außerdem ein \code{progress} Parameter in Form einer Gleitkommazahl, die den Fortschritt der aktuellen Aktion angibt. + Um bei Bewegungen die aktuelle Position des Menschen zu erhalten, ist zusätzlich die aktuelle Pose des Modells im Parameter \code{current} enthalten. \item[ActionMessage] ist die zweite Nachricht, die über die zweite MessageQueue vom ActorServer an das ActorPlugin gesendet wird. Wie in der FeedbackMessage ist ein \code{state} Parameter vom selben Typ enthalten, jedoch dient dieser hier als Vorgabe für den nächsten State. - Ein \code{animationName} Parameter wird als ein char-Array mit einer maximalen Länge von 255 Zeichen übergeben. + Ein \code{animationName} Parameter wird als char-Array mit einer maximalen Länge von 255 Zeichen übergeben. Dieser bestimmt später die Animation, die je nach ActorPluginState während einer Bewegung oder Animation ausgeführt wird. Der \code{animationSpeed} Parameter beschreibt entweder die Abspielgeschwindigkeit der Animation, oder die zurückgelegte Distanz pro Animationsdurchlauf. Außerdem wird im Falle einer Bewegung der Parameter \code{target} vom Typ Pose verwendet, um die Endposition und Rotation des Actors zu bestimmen. \end{description} \section{Simulationswelt} -Die Definition aller Simulationselemente findet im Paket \code{ign_world} statt. +Die Definition aller Simulationselemente erfolgt im Paket \code{ign_world}. In diesem Paket sind sowohl die Geometrien der Welt, aber auch die benötigten Dateien zum Starten der Simulation enthalten. -In diesem Fall handelt es sich um den Raum, in dem die Interaktion zwischen Mensch und Roboter stattfinden soll. +Diese Dateien enthalten zum Beispiel die Definition des virtuellen Raumes, in dem die Simulation der Mensch-Roboter-Interaktion abläuft. Für diesen Raum wurde ein Raumplan erstellt, der alle benötigten Bereiche für die Szenarien besitzt (Abbildung \ref{room-plan}). Zuerst wird ein Stellplatz für den Roboter benötigt. @@ -184,44 +188,41 @@ Dieses veranlasst mit dem \code{create}-Programm das Erstellen der übergebenen \end{figure} \section{Mensch} -\subsection{Übersicht} -Das angepasste Verfahren zur Steuerung des simulierten Menschens in der Simulation verwendet mehrere Kommunikationswege. -Als erstes wird eine Bewegungs- oder Animationsanfrage an den ROS-Action-Server im ActorServer gesendet. -Wenn die Simulation aktuell keinen Befehl ausführt, wird diese Anfrage akzeptiert, ansonsten wird sie abgebrochen. -Daraufhin werden die Daten der Anfrage in Form des \code{ActionMessage}-Typs über eine Posix-Message-Queue vom ActorServer an das ActorPlugin in Gazebo gesendet. -Anhand der \code{ActionMessage} wird die State-Machine im ActorPlugin in den richtigen Zustand für die angefragte Aktion gesetzt. -Um diese auszuführen, werden der gewünschte Animationsname und weitere Parameter, die die Aktion beschreiben, aus der Nachricht übernommen. +Der Mensch soll in der Simulation verschiedene Aufgaben ausführen, die durch Behavior Trees definiert sind. +Um diese Aufgaben visuell darzustellen, werden verschiedene Animationen für ein Modell des Menschen benötigt. +Ein Modell eines Menschen ist bereits in Gazebo integriert, welches als sogenannter ``Actor'' durch vorher definierte Pfade bewegt werden kann. +Die für das Modell existierenden Animationen müssen um die gewünschten Animationen erweitert werden. -Das Feedback an den Client des ROS-Action-Servers wird bei Zustandswechseln und während laufenden Aktionen des ActorPlugins generiert. -Dabei wird der aktuelle Zustand mitsamt einigen weiteren Daten, in diesem Fall die Position des Actors und der aktuelle Fortschritt der Aktion an den ActorServer gesendet. -Dies geschieht über eine zweite MessageQueue, die den \code{FeedbackMessage}-Datentyp überträgt. -Diese werden durch den ActorServer aufbereitet, da nicht alle Daten für die jeweilige laufende Aktion relevant sind und an den ROS-Action-Client gesendet. +Um diese Animationen eines Modells in Bewegungen und Verhalten umzuwandeln, muss das Verhalten während der Simulation gesteuert werden. +Dies erfolgt über das ActorPlugin, welches in Gazebo ausgeführt wird. +Mit diesem Plugin kann der Mensch in der Simulation gesteuert werden. +Da eine Anbindung an ROS in Gazebo nicht möglich ist, kommuniziert das ActorPlugin mit dem ActorServer über MessageQueues. +Dieser ActorServer übersetzt Nachrichten und Anfragen zwischen ROS und der MessageQueue des ActorPlugins. -Um diese Befehle in der Simulation auch visuell umsetzen zu können, werden weitere Animationen für das Modell des Menschen benötigt, die im Kontext der zur erfüllenden Aufgabe relevant sind. -Dafür muss das Modell in einen animierbaren Zustand gebracht werden, in dem dann weitere Animationen erstellt und in die Simulation eingebunden werden können. \subsection{Modellierung} Um neue Animationen für den Menschen in der Simulation erstellen zu können, muss ein Modell für diesen erstellt werden. -Dafür wurde eine der bereits modellierten Laufanimationen von Gazebo in Blender geöffnet und das visuelle Modell kopiert. +Dafür wurde eine der bereits modellierten Laufanimationen von Gazebo in Blender geöffnet und bearbeitet. +Eine Kopie des Menschenmodells aus der Laufanimation dient als Grundlage für das neue Modell. Dieses Modell ist durch die interne Geometrie, zum Beispiel zwischen Körper und Pullover der Person, nur schlecht für Animationen geeignet. -Die Geometrie bildet ``Falten'' im Modell, die während der Animation hervortreten können, was zu unerwarteten Artefakten führen kann. -Solche Artefakte entstehen durch unterschiedliche Verschiebung der Strukturen, die aus dem inneren des ursprünglichen Modells hervortreten, wenn dieses bewegt wird. -In diesem Fall kam es häufig zum Hervortreten der Haut unter dem Rollkragen und der Hose. -Diese Artefakte wurden durch die Vereinfachung des Modells an diesen Stellen behoben. +Die interne Geometrie bildet ``Falten'' im Modell, die während der Animation hervortreten können, was zu unerwarteten Artefakten führen kann. +Solche Artefakte entstehen durch unterschiedliche Verschiebung der Strukturen, die aus dem inneren des ursprünglichen Modells hervortreten, wenn es bewegt wird. +Beim kopierten Modell kam es häufig zum Hervortreten der Haut unter dem Rollkragen und der Hose. +Diese Artefakte wurden durch die Vereinfachung des Modells an den entsprechenden Stellen behoben. An diesem Punkt könnte die Animation des Modells mit dem importierten Skelett beginnen, jedoch fehlen diesem viele Knochen, wie zum Beispiel für Finger und Zehen, aber auch Rotationsknochen für Arme und Beine. Diese fehlenden Knochen werden für einige der gewünschten Animationen benötigt und müssten hinzugefügt werden. -Da das importierte Skelett noch andere Fehler aufwies, wurde dieses verworfen. +Da das importierte Skelett noch andere Fehler aufwies, wurde es verworfen. Um ein neues, passendes Skelett zu erstellen, wurde mit dem ``Rigify''\cite{rigify}-Plugin ein standartisiertes Menschenskelett generiert. Dieses neue Skelett kann an das bereits vorhandene Modell angepasst werden. -Um eine bessere Übersicht zu ermöglichen, sollten als erstes alle nicht benötigten Skeletteile, wie zum Beispiel für Gesichtsanimationen, entfernt werden. +Um eine bessere Übersicht zu ermöglichen, sollten zuerst alle nicht benötigten Skeletteile, wie zum Beispiel für Gesichtsanimationen, entfernt werden. Danach müssen die Knochen durch Verschiebung und Skalierung an die richtigen Positionen im Modell gebracht werden. Dabei muss auf die Ausrichtung der Knochen zueinander geachtet werden. Das Kreuzprodukt der Vektoren beider Knochensegmente bestimmt die Richtung der Beugeachse, die sich im Verbindungspunkt beider Knochen befindet. -Ist diese nicht richtig ausgerichtet, wenn zum Beispiel beide Knochen auf einer Gerade liegen, bewegen sich Gelenke bei der Verwendung von inverser Kinematik zur Positionsvorgabe falsch. +Ist diese nicht richtig ausgerichtet, zum Beispiel wenn beide Knochen auf einer Gerade liegen, bewegen sich Gelenke bei der Verwendung von inverser Kinematik zur Positionsvorgabe falsch. Der Grund dafür ist das Kreuzprodukt, dass im oben genannten Fall ein Nullvektor ist, wodurch keine Beugeachse bestimmt werden kann. Deshalb muss bei der Platzierung darauf geachtet werden, dass der Startpunkt A des ersten und der Endpunkt C des zweiten Knochens auf einer Gerade liegen. @@ -245,7 +246,7 @@ Dieser muss senkrecht zu dieser Gerade und der gewünschten Biegeachse verschobe \end{figure} \begin{figure} -\includegraphics[width=.8\textwidth]{img/MA-Umsetzung-Joint} +\includegraphics[width=.5\textwidth]{img/MA-bend-axis} \centering \caption{Visualisierung der generierten Beugeachse} \label{bend} @@ -256,6 +257,7 @@ Das neu erstellte Skelett ist in Abbildung \ref{person-bones} visualisiert. Um eine bessere Verformung bei der Bewegung von Knochen zu erreichen, wird das so genannte ``weight painting'' eingesetzt. Hierfür werden für jeden Knochen entweder automatisch oder manuell Teile des Meshes mit Gewichten versehen. Je höher die Wichtung, desto stärker ist die Verformung an dieser Stelle, wenn der Knochen bewegt oder skaliert wird. +Die so erstellten Knochen werden auch als deformierende Knochen bezeichnet, da deren Bewegung das Modell beeinflusst. Da das Animieren aller Knochen einzeln sehr zeitaufwändig ist, werden diese in Gruppen zusammengefasst. Hierfür werden in Blender sogenannte Constraints eingesetzt, die Knochen automatisch durch eingestellte Bedingungen positionieren können. @@ -283,13 +285,41 @@ Der Quader in der Hüfte gibt die gewünschte Höhe des Modells vor, die auch f Die anderen Knochen beeinflussen die Rotation des Beckens, der Wirbelsäule, der Schultern und des Kopfes. Das hier erstellte, verbesserte Rigify-Skelett kann durch den Einsatz der neuen Constraints einfacher animiert werden. -Die Verwendung des so erstellten Rigs ist in vielen Grafikengines, darunter auch Gazebo, noch nicht möglich. -Es bedarf einer zusätzlichen Anpassung des Skeletts, bei der die verschachtelte Knochenstruktur aufgelöst wird. + +\subsection{Erstellen von Animationen} + +Animationen werden in Blender über sogenannte Keyframes erstellt. +Ein Keyframe stellt dabei einen spezifischen Zeitpunkt in der Animation dar. +Jedem Keyframe kann eine beliebige Anzahl von Knochenpositionen zugeordnet werden. + +Eine Animation entsteht, sobald mehrere Keyframes auf der Zeitachse existieren. +Alle zugeordneten Positionen werden zwischen beiden Keyframes durch auswählbare Kurven interpoliert. +In Abbildung \ref{actorinterpolate} wird dieser Prozess am Beispiel der ``low_to_standing''-Animation dargestellt. + +Für die neuen Animationen werden die erstellten Steuerknochen verwendet, welche die später in Gazebo sichtbaren Knochen über Constraints beeinflussen. + +\begin{figure} +\centering +\begin{minipage}{.25\textwidth} +\includegraphics[width=\textwidth]{img/MA-Animation-Human-Start} +\end{minipage} +\begin{minipage}{.25\textwidth} +\includegraphics[width=\textwidth]{img/MA-Animation-Human-Interpolated} +\end{minipage} +\begin{minipage}{.25\textwidth} +\includegraphics[width=\textwidth]{img/MA-Animation-Human-End} +\end{minipage} +\caption{Erste und letzte Keyframes einer Animation mit interpoliertem Zwischenbild} +\label{actorinterpolate} +\end{figure} \subsection{Export der Modellanimationen} -Um aus einem existierenden, vollständig verbundenen Skelett einzelne Knochen zu extrahieren, exisitiert ein weiteres Plugin mit dem Namen ``GameRig''\cite{gamerig}. -Dieses separiert die neuen Steuerknochen wieder vom ursprünglichen Modell, wodurch in diesem nur noch die deformierenden Knochen enthalten sind. +Die Verwendung des hier erstellten, verbesserten und animierten Rigs ist in vielen Grafikengines, darunter auch Gazebo, noch nicht möglich. +Es bedarf einer zusätzlichen Anpassung des Skeletts, bei der die neu erstellte Knochenstruktur aufgelöst wird, da Gazebo keine Constraints unterstützt. + +Um aus einem existierenden, vollständig verbundenen Skelett ein Skelett ohne verbundene Knochen zu extrahieren, exisitiert ein weiteres Plugin mit dem Namen ``Game_Rig_Tools''\cite{gamerig}. +Dieses separiert die neuen Steuerknochen wieder vom ursprünglichen Modell, damit in diesem nur noch die deformierenden Knochen enthalten sind. Alle erstellten Animationen der Steuerknochen müssen in direkte Bewegungen der deformierenden Knochen des Modells umgewandelt werden. Um dies zu erreichen wird der in Abbildung \ref{export-prepare} visualisierte Arbeitsablauf verwendet. @@ -328,7 +358,7 @@ Ein solcher Fehler äußert sich in Gazebo durch verdrehte Knochen während der \hfill \includegraphics[width=.5\textwidth]{img/MA-Umsetzung-Animation-Prepare2} \end{subfigure} -\caption{Vorbereitung zum Export mit GameRig} +\caption{Vorbereitung zum Export mit Game_Rig_Tools} \label{export-prepare} \end{figure} @@ -371,7 +401,7 @@ da diese zur Kommunikation genutzt werden Das HTTP besitzt jedoch keinen einheitlichen Feedbackmechanismus. Dieser müsste entweder durch kontinuierliche Abfragen des aktuellen Status, auch ``polling'' genannt, oder eine lang anhaltende Request realisiert werden. Eine Verwendung von kontinuierlichen Abfragen ist zwar mit fast jeder Programmiersprache möglich, jedoch ist die Reaktionszeit des Systems an die Antwortzeit des Servers gebunden. -Der Einsatz einer lang anhaltenden Request umgeht dieses Problem, jedoch müssen der eingesetzte Webserver und Client dieses Feature unterstützen. +Der Einsatz einer lang anhaltenden Request umgeht dieses Problem, jedoch müssen der eingesetzte Webserver und der Client diese Funktion unterstützen. Das neuere Websocket-Protokoll\cite{websocket} bieten die Möglichkeit, bidirektional Daten zu übertragen. Dadurch können Aktionsanfragen und Feedback auf dem gleichen Kanal übertragen werden, was das Protokoll übersichtlicher macht. @@ -397,8 +427,9 @@ Die Angaben zu den Durchsätzen der verschiedenen Datenübertragungsmechanismen Als Nachrichtendienst wurde die MessageQueue ausgewählt, da die integrierten Funktionen die Entwicklung erleichtern und die Geschwindigkeit ausreichend für das Einsatzszenario ist. Jedoch existieren unter Linux 2 unabhängige Implementationen von MessageQueues mit unterschiedlichen Funktionen. + Die erste Implementation ist die System V MessageQueue\cite{mqSystemV}, und verwendet zur Identifikation einfache Ganzzahlen. -Eine Spezialität dieser alten Implementation ist das Sortieren der Nachrichten nach Nachrichtentyp in der gleichen Warteschlange. + Die neuere Implementation der MessageQueue ist die POSIX-MessageQueue.\cite{mqPosix} Sie bietet einige weitere Funktionen, wie zum Beispiel asynchrone Benachrichtigungen bei neuen Nachrichten, Quality of Service und nutzt bis zu 256 Zeichen lange Zeichenketten zur Identifikation. @@ -440,6 +471,7 @@ Ein ActionServer innerhalb eines Programmes definiert 3 Funktionen, welche die H Diese erhält als Parameter ein Objekt, mit dem Feedback- und Endnachrichten an den Client gesendet werden können. } \end{itemize} + Die gesamte Kommunikation einer Anfrage verläuft wie in Abbildung \ref{plugin_sequence} dargestellt. Zuerst wird durch den Client eine Zielvorgabe an den Server gesendet. Sollte der Server diese abweisen, wird die Kommunikation beendet. @@ -482,7 +514,7 @@ Das Plugin wird durch den Startvorgang und später von den empfangenen Nachricht Diese kann durch einen Skalierungsfaktor beschleunigt oder verlangsamt werden. \end{description} -In diesen Zuständen muss das ActorPlugin die Simulationsumgebung beeinflussen, in dem die simulierte Person bewegt und animiert wird. +In diesen Zuständen muss das ActorPlugin die Simulationsumgebung beeinflussen, in der die simulierte Person bewegt und animiert wird. Dies erfordert den Zugriff auf simulationsinterne Daten, die durch das Plugin gelesen und verändert werden sollen. Der Zugriff auf diese Daten wird durch ein EntityComponentManager-Objekt ermöglicht. @@ -490,6 +522,7 @@ Durch den EntityComponentManager kann auf das so genannte ``Entity Component Sys Ein Entity Component System besteht aus einer oder mehr Entities, die Objekte innerhalb der Simulation abbilden. Objekte können beliebig viele Components besitzen, bei denen es sich um zusätzliche Eigenschaften und Erweiterungen der Funktionen des betroffenen Objekts handelt. Die wichtigsten Komponenten für die Funktion des Plugins sind dabei: + \begin{description} \item[components::Actor] Dieses Objekt beschreibt die simulierte Person mit allen weiteren Daten, wie zum Beispiel deren Animationen. @@ -531,14 +564,14 @@ Das ActorPlugin benötigt für seine Funktion das übergeornete Simulationsobjek Dies erfordert die Implementation des \code{ISystemConfigure}-Interfaces für das ActorPlugin. Außerdem soll die simulierte Person bewegt werden. Da dieser Vorgang während der Simulationszeit ablaufen soll, muss hierfür das \code{ISystemUpdate}-Interface genutzt werden. -Als erstes wird durch das Laden die Configure-Funktion aufgerufen. +Als erstes wird durch das Laden des Plugins die Configure-Funktion aufgerufen. Da das Plugin erst durch Gazebo geladen werden muss, kann davon ausgegangen werden, dass alle benötigten Message Queues bereits durch den ActorServer erstellt wurden. Trotz dieses Umstandes wartet das Plugin auf deren Erstellung, um bei Konfigurationsfehlern auffälliges Verhalten zu zeigen. Im Log wird diese Aktion vermerkt, um das Debugging zu erleichtern. Nach dem erfolgreichen Aufbau der Verbindung wird ein Thread gestartet, der die eingehenden Nachrichten verarbeitet. Dabei wird zuerst ein Sperre gesetzt, um parallele Zugriffe durch die Update-Funktion zu verhindern. Alle in der Anfrage gespeicherten Daten werden übernommen und der gewünschte State gesetzt. -Nach dem Entsperren der Sperre wird im nächsten Simulationschritt die gewünschte Aktion durchgeführt. +Nach dem Entfernen der Sperre wird im nächsten Simulationschritt die gewünschte Aktion durchgeführt. Das Setzen aller obrigen Zustände ist dabei möglich, jedoch werden nur Idle, Animation und Movement genutzt. Der Idle-Zustand kann zum Beenden eines anderen Zustands eingesetzt werden, falls dieser abgebrochen werden soll. @@ -549,7 +582,7 @@ Sollte die Animation nicht gefunden werden, wird versucht, diese anhand ihres Na Wurde eine Animation gefunden, wird deren Länge gespeichert, um diese später für das Feedback nutzen zu können. Ab diesem Zeitpunkt unterscheiden sich die Implementation von Animation und Movement. -Im Zustand der Animation wird die Komponente AnimationTime jedes Update aktualisiert. +Im Zustand der Animation wird die Komponente AnimationTime bei jedem Update aktualisiert. Um die Ausführungsgeschwindigkeit einer Animation anpassen zu können, wird ein Skalierungsfaktor genutzt. Dieser optionale Faktor kann mit der abgelaufenen Zeit multipliziert werden. Dies verursacht eine Beschleunigung oder Verlangsamung der Ausführung. @@ -601,10 +634,9 @@ Im Falle des Bewegungs-ActionServers werden mehrere Parameter benötigt. Zuerst werden Animationsname und -diztanz benötigt, um die richtige Animation auszuwählen und die Bewegung mit der Animation zu synchronisieren. Als Feedbacknachricht erhält der Client die aktuelle Pose des Actors im Simulationsraum. -Soll eine Animation über den Action Server abgespielt werden, wird auch hier ein Animationsname, jedoch auch eine Animationsgeschwindigkeit benötigt. -Die Feedbacknachricht enthält den Fortschritt der Animation als Gleitkommazahl. +Soll eine Animation über den Action Server abgespielt werden, wird neben dem Animationsnamen noch die Animationsgeschwindigkeit als Parameter benötigt. +Die Feedbacknachricht enthält den Fortschritt der Animation als Gleitkommazahl von null bis eins. \section{Roboter} -\subsection{Übersicht} Der Roboter besteht aus mehreren interagierenden Systemen, die in ihrer Gesamtheit das vollständige Robotermodell in der Simulation verwendbar machen. Zuerst muss ein Modell des Roboters erstellt werden, dass in Gazebo geladen werden kann. @@ -621,7 +653,7 @@ Dabei muss darauf geachtet werden, dass die exportierten Daten eine ausreichende Diese kann vor dem Export in FreeCAD eingestellt werden. Durch diese Einstellung bleiben feine Strukturen erhalten, die später in Blender wieder reduziert werden können. Ein solches Vorgehen erlaubt es Blender, bessere Entscheidungen über die Reduktion von Strukturen zu treffen. -Das Resultat ist ein besseres Endmodell des Roboters. +Das Resultat ist ein exakteres Endmodell des Roboters. \begin{figure} \includegraphics[width=\textwidth/2]{img/MA-Roboter-Rohdaten} @@ -631,13 +663,13 @@ Das Resultat ist ein besseres Endmodell des Roboters. \end{figure} Diese Dateien können dann in Blender bearbeitet werden, um sie für die Simulation tauglich zu machen. -Hierfür wurde die hohe Auflösung der Modelle reduziert, was sich in kleineren Dateien und Startzeiten der Simulation, aber auch in der Renderzeit der Simulation, auswirkt. +Hierfür wurde die hohe Auflösung der Modelle reduziert, was sich positiv auf die Dateigröße, die Startzeit der Simulation und die Rendergeschwindigkeit auswirkt. Außerdem wurden die Glieder so ausgerichtet, dass sich der Verbindungspunkt zum vorherigen Glied im Nullpunkt des Koordinatensystems befindet. Das vollständige visuelle Modell ist in Abbildung \ref{robot_visual} zu sehen. -Um die Simulation weiter zu beschleunigen, wurden die Kollisionsboxen des Arms noch weiter vereinfacht, was die Kollisionsüberprüfung dramatisch beschleunigt. +Um die Simulation weiter zu beschleunigen, wurden die Kollisionsboxen des Arms noch weiter vereinfacht, was die Kollisionsüberprüfung deutlich beschleunigt. Dabei werden stark simplifizierte Formen verwendet, die das hochqualitative visuelle Modell mit einfachen Formen umfassen. -Das resultierende Modell, dass in Abbildung \ref{robot_collision} dargestellt wird, wird später zur Kollisionserkennung verwendet. +Das resultierende Modell, in Abbildung \ref{robot_collision} dargestellt, wird später zur Kollisionserkennung verwendet. Diese Herangehensweise ist nötig, da die Kollisionserkennung auf der CPU durchgeführt und durch komplexe Formen stark verlangsamt wird. @@ -676,7 +708,7 @@ Diese können standardmäßig nicht in Gazebo, RViz und MoveGroup gleichzeitig g Eine Möglichkeit zur Lösung des Problems ist die Verwendung von \code{file://}-URIs, die von allen dieser Programme gelesen werden können. Der Moveit Setup Assistent kann diese URIs nicht lesen, was zu Fehlern bei einer Rekonfiguration führen kann. -Fall eine Neukonfiguration des Roboters mit dem Assistenten durchgeführt werden soll, muss diese Umwandlung temporär rückgängig gemacht werden. +Falls eine Neukonfiguration des Roboters mit dem Assistenten durchgeführt werden soll, muss diese Umwandlung temporär rückgängig gemacht werden. Das so erstellte Modell kann über den Aufruf von \code{ros2 launch iisy_config demo.launch.py} in RViz getestet werden. Hierfür erscheint das Robotermodell mit mehreren Markern und Planungsoptionen, die genutzt werden können, um beliebige Bewegungen zu planen und auszuführen. @@ -719,7 +751,7 @@ Diese lassen sich nach Nutzung in verschiedene Gruppen einordnen. \item[InterruptableSequence] stellt eine Sequence dar, die auch nach ihrem Abbruch ihre Position behält. Dies ist notwendig, wenn ein bestimmtes Verhalten unterbrechbar ist, aber zu einem späteren Zeitpunkt fortgesetzt werden soll. - Hierzu wird der Iterator der unterlegenden Sequenz nur erhöht, wenn die untergeordnete Node SUCCESS zurück gibt. + Hierzu wird der Iterator der unterlegenden Sequenz nur erhöht, wenn die untergeordnete Node SUCCESS zurückmeldet. Außerdem wird der Iterator nicht zurückgesetzt, wenn die Ausführung dieser modifizierten Sequenz abgebrochen wird. \item[WeightedRandom] ist eine Steuerungsnode, die mehrere untergeordnete Nodes besitzt. @@ -769,9 +801,9 @@ Um die RobotMove-Node nicht zu unterbrechen, wird diese nur über einen Callback \subsection{Subtrees} Um die Wiederverwendung von bestimmten Abläufen zu erleichtern, wurden diese in Subtrees ausgelagert. In diesem Fall wurden die Aktionen ``Arbeiten an der Werkbank'' und ``Ablegen eines Objekts im Lagerregal'' des Menschen ausgelagert, da diese in mehreren Fällen verwendet werden. -Dies erhöht die Lesbarkeit der Bäume und vereinfacht die Verwendung gleicher Aktionen in mehreren Bäumen. +Diese Abstraktion erhöht die Lesbarkeit der Bäume und vereinfacht die Verwendung gleicher Aktionen in mehreren Bäumen. -Für das Arbeiten an der Werkbank ist eine Bewegung zu dieser erforderlich. +Für das Arbeiten an der Werkbank ist eine Bewegung des Menschen hin zu dieser erforderlich. Außerdem muss sich der Mensch zur Werkbank ausrichten, um die späteren Animationen korrekt auszuführen. Dazu wird eine Bewegung zu einem Punkt vor der Werkbank mit vorgegebener Zielrichtung genutzt. Nach dieser Bewegung soll ein Arbeitsprozess simuliert werden. @@ -793,12 +825,11 @@ Der vollständige resultierende Baum ist in Abbildung \ref{subtree_work} visuali Das Ablegen von Objekten in einem Schrank ist ein komplizierterer Prozess, da der Schrank in mehreren Ebenen befüllt werden kann. Außerdem sind mehrere Fächer verfügbar, die genutzt werden können. -Wie bereits bei der Werkbank wird zuerst eine Bewegung zum Schrank ausgeführt. +Wie bereits bei der Werkbank wird zuerst eine Bewegung hin zum Schrank ausgeführt. Diese hat eines der drei im Schrank vorhandenen Schrankteile zum Ziel. Die Auswahl des Ziels erfolgt zufällig durch eine WeightedRandom-Node, die eine der drei Bewegungs-Nodes ausführt. -Nachdem erfolgt eine weitere zufällige Auswahl. -Diese entscheidet, ob ein oberes oder unteres Fach genutzt werden soll. +Danach erfolgt eine weitere zufällige Auswahl die entscheidet, ob das obere oder das untere Fach des betreffenden Schranks genutzt werden soll. Im Falle eines oberen Faches werden nur zwei Animationen benötigt. Die Hand wird zu einem oberen Fach ausgestreckt und zurückgezogen. @@ -824,7 +855,7 @@ Das grundlegende Verhalten des Roboters ist in jedem Anwendungsfall gleich. Dies hängt mit der automatischen Geschwindigkeitsanpassung zusammen. Der Roboter soll bei annäherndem Mensch zuerst seine Geschwindigkeit reduzieren, wenn dieser eine Warnzone betritt. Falls sich der Mensch weiter bis in die Sicherheitszone begibt, ist ein temporärer Stopp des Roboters vorgesehen. -Dieser Stopp soll nach dem Entfernen aus der Sicherheitszone wieder aufgehoben werden, um die Arbeit fortzusetzen. +Dieser Stopp soll nach dem Entfernen des Menschen aus der Sicherheitszone wieder aufgehoben werden, um die Arbeit fortzusetzen. Um diese Funktionen zu erlauben, ist eine Reaktion auf Statusänderungen von vorherigen Nodes nötig. Dies wird durch eine übergeordnete ReactiveSequence erreicht. @@ -880,11 +911,12 @@ Im anderen Fall soll das Objekt auf den rechten Tisch gelegt werden. Von dort aus soll der Mensch dieses Objekt abholen, um den Ausschuss im Regal zu verstauen. Es wird dafür die gleiche Operationsabfolge aus dem ersten Szenario verwendet. Am Ende der übernommenen Sequenz wird eine SetCalledTo-Node ergänzt, die den Menschen ruft. +Eine Visualisierung des modifizierten Baums wird in Abbildung \ref{tree_robot_coop} gezeigt. \begin{figure} \includegraphics[width=\textwidth]{img/MA-tree-robot-coop} \centering -\caption{BehaviorTree für das Ablegen von Objekten im Schrank} +\caption{Erweiterter BehaviorTree des Roboters bei Kooperation} \label{tree_robot_coop} \end{figure} @@ -898,11 +930,12 @@ Da diese Probleme durch den Menschen behoben werden sollen, muss ein Mechanismus Hierfür wird eine Fallback-Node über der InterruptableSequence angeordnet. Diese Fallback-Node führt im Fall eines Fehlers in der InterruptableSequence die nächste Node aus. Bei dieser handelt es sich um eine SetCalledTo-Node, welche den Menschen ruft. +Der Aufbau des Baumes wird in Abbildung \ref{tree_base_colab} dargestellt. \begin{figure} \includegraphics[width=\textwidth]{img/MA-tree-robot-colab} \centering -\caption{BehaviorTree für das Ablegen von Objekten im Schrank} +\caption{Erweiterter BehaviorTree des Roboters bei Kollaboration} \label{tree_base_colab} \end{figure} diff --git a/tex/5_Evaluation_und_Diskussion.tex b/tex/5_Evaluation_und_Diskussion.tex index 205d269..f0868d9 100644 --- a/tex/5_Evaluation_und_Diskussion.tex +++ b/tex/5_Evaluation_und_Diskussion.tex @@ -85,6 +85,17 @@ Dies wird durch die RandomFailure-Node erreicht. Eine Kombination dieser neu implementieren und den bereits in BehaviorTree.CPP verfügbaren Nodes kann alle in den Szenarien benötigten Verhaltensweisen darstellen. +\subsection{Erstellen der benötigten Pakete} + +Alle benötigten Pakete müssen vor der ersten Ausführung der Simulation kompilliert werden. +Dies wird durch das Ausführen des \code{build.sh}-Skripts im Verzeichnis \code{\textasciitilde/workspace} des Container ausgelöst. +Nach diesem Vorgang muss der Workspace neu geladen werden, damit die jetzt verfügbaren Pakete registriert werden. + +Die kann sowohl durch einen erneuten Aufbau der SSH-Verbindung erfolgen, da bei Start der Session die entsprechende Datei geladen wird, oder manuell geschehen. +Für das manuelle Laden des Workspaces muss der Befehl \code{source /home/ros/workspace/install/setup.bash} in der Konsole ausgeführt werden. + +Nach dem Laden des Workspaces ist die Umgebung für die Simulation einsatzbereit. + \section{Simulation der Szenarien} Das Starten der Simulation erfolgt über ein Skript innerhalb des \code{ign_world}-Pakets. Dieses Skript wird durch den Befehl \code{ros2 launch ign_world gazebo_controller_launch.py} ausgeführt. @@ -122,7 +133,7 @@ Diese werden nach dem Start einer Simulation ausgeführt und definieren das Verh Im Koexistenzszenario interagieren Roboter und Mensch nur im Ausnahmefall. Der Roboter simuliert einen Entladevorgang, bei welchem Objekte vom linken Tisch auf den rechten Tisch bewegt werden (Abbildung \ref{coex-move}). Die für diesen Zweck implementierten Bewegungsnodes werden in späteren Szenarien weiter verwendet. -Um den Menschen nicht zu gefährden, wird die Verfahrgeschwindigkeit automatisch and die Aufenthaltszone des Menschen angepasst. +Um den Menschen nicht zu gefährden, wird die Verfahrgeschwindigkeit automatisch an die Aufenthaltszone des Menschen angepasst. Der Arbeitsvorgang des Menschen besteht aus dem Arbeiten an einer Werkbank und dem Verbringen von Material in das Regal (Abbildung \ref{coex-shelf}). In diesem Szenario begibt sich der Mensch nur mit einer Wahrscheinlichkeit von 5\% nach jedem Arbeitsvorgang zum Roboter. diff --git a/tex/6_Ausblick.tex b/tex/6_Ausblick.tex index c4998f9..b1de7b8 100644 --- a/tex/6_Ausblick.tex +++ b/tex/6_Ausblick.tex @@ -17,13 +17,13 @@ Diese können für Roboterbewegungen und Menschensimulation verwendet werden. Die Simulation bewegter Objekte benötigt ein neues Gazebo-Plugin, welches mit den bereits entwickelten Komponenten der aktuellen Umgebung interagiert. Um ein Objekt mit dem Roboter oder Menschen zu bewegen, muss dieses auf eine von zwei Arten bewegt werden. -Die Bewegung mit dem Roboter ist möglich, da dieser aus mehreren Physikobjekten besteht. -Das Objekt kann somit an das Objekt des Endeffektors als Unterobjekt hinzugefügt werden. +Die Bewegung von Objekten mit dem Roboter ist möglich, da dieser mit der gegenwärtigen Implementation aus mehreren Physikobjekten besteht. +Das zu bewegende Objekt kann somit dem Objekt des Endeffektors als Unterobjekt hinzugefügt werden. Der daraus resultierende Übergang in lokale Koordinaten kann potentielle Umrechnung anhand der Transformationen vorhergehender Armteile erfordern. Eine Bewegung mit dem Menschen erfordert vor allem bei Animationen einen anderen Mechanismus. Da der Mensch nicht aus einzelnen Physikobjekten besteht, ist die Anbringung als Unterobjekt nicht möglich. -Stattdessen muss die aktuelle Position des Armes anhand der Animationsdaten verfolgt werden, um die Position des Objektes diesen anzupassen. +Stattdessen muss die aktuelle Position des Armes anhand der Animationsdaten verfolgt werden, um die Position des Objektes an diese anzupassen. Die unterschiedliche Anbindung von Roboter und Mensch erfordert mehrere Implementationen, welche Zustandsdaten über das Objekt austauschen müssen. Um die Objekte zu steuern, muss eine weitere ROS-Anbindung in einem entsprechenden Gazebo-Plugin erfolgen. @@ -69,7 +69,7 @@ Weitere universelle Node-Parameter vereinfachen den Aufbau von Bäumen durch die Ein Nachteil der Migration wäre jedoch das Wegfallen einiger Funktionen des Editors, welcher in dieser Version unter einer neuen Lizenz vertrieben wird. Die Analyse von Logdateien nach der Ausführung und die Überwachung von Bäumen zur Laufzeit sind ohne kostenpflichtige Lizenz nicht mehr möglich. -Eine weitere Alternative ist die Nutzung von MoveIt Studio, welches auch mit Behavior Trees arbeitet. +Eine weitere Alternative ist die Nutzung von MoveIt Studio\cite{moveItStudio}, welches ebenfalls mit Behavior Trees arbeitet. Die direkte Integration mit MoveIt vereinfacht die Anbindung an den Roboter, da wichtige Funktionen bereits implementiert sind. Jedoch ist die Unterstützung für eigene Befehle nur schlecht dokumentiert. Diese werden aber für die Steuerung des Menschen benötigt, was dieses Alternative nur für die Robotersteuerung attraktiv macht. diff --git a/uml/out/plugin_connectivity.eps b/uml/out/plugin_connectivity.eps index 60be78c..84f39bf 100644 --- a/uml/out/plugin_connectivity.eps +++ b/uml/out/plugin_connectivity.eps @@ -1,13 +1,13 @@ %!PS-Adobe-3.0 EPSF-3.0 %%Creator: PlantUML v1.2022.7 %%Title: noTitle -%%BoundingBox: 0 0 599 778 +%%BoundingBox: 0 0 589 641 %%ColorUsage: Color %%Origin: 0 0 %%EndComments gsave -0 778 translate +0 641 translate .01 -.01 scale /simplerect { newpath moveto 1 index 0 rlineto @@ -25,7 +25,7 @@ pop pop pop pop pop /rquadto { 3 index 3 index 4 2 roll rcurveto } def -/P$1d { +/P$17 { 25 0 51 -3 rquadto 28 -4 45 -10 rquadto 0 87 rlineto @@ -49,7 +49,7 @@ pop pop pop pop pop 31 29 79 29 rquadto closepath } def -/P$1k { +/P$1b { -87 0 -135 70 rquadto -48 68 -48 198 rquadto 0 128 46 196 rquadto @@ -117,7 +117,7 @@ closepath 114 0 rlineto 0 289 rlineto } def -/P$3o { +/P$3b { 0 -39 21 -54 rquadto 21 -17 53 -17 rquadto 29 0 51 17 rquadto @@ -128,7 +128,7 @@ closepath -21 -18 -21 -54 rquadto closepath } def -/P$2b { +/P$2c { 0 123 -90 192 rquadto -89 68 -240 68 rquadto -78 0 -145 -12 rquadto @@ -160,7 +160,7 @@ closepath 56 34 85 82 rquadto 29 46 29 120 rquadto } def -/P$2m { +/P$2k { -129 4 -179 40 rquadto -50 35 -50 103 rquadto 0 57 35 85 rquadto @@ -171,7 +171,7 @@ closepath -103 4 rlineto closepath } def -/P$3j { +/P$38 { 0 204 rlineto 107 0 rlineto 75 0 104 -28 rquadto @@ -180,25 +180,6 @@ closepath -29 -28 -109 -28 rquadto -103 0 rlineto } def -/P$3w { -0 709 rlineto --148 0 rlineto --26 -90 rlineto --9 0 rlineto --34 54 -93 79 rquadto --59 23 -125 23 rquadto --114 0 -184 -60 rquadto --68 -62 -68 -198 rquadto -0 -462 rlineto -193 0 rlineto -0 414 rlineto -0 75 26 114 rquadto -28 39 89 39 rquadto -87 0 120 -59 rquadto -32 -60 32 -173 rquadto -0 -334 rlineto -193 0 rlineto -} def /P$b { 0 185 -95 289 rquadto -93 101 -254 101 rquadto @@ -212,7 +193,7 @@ closepath 45 85 45 210 rquadto closepath } def -/P$2z { +/P$2q { 118 0 192 93 rquadto 75 92 75 273 rquadto 0 181 -76 275 rquadto @@ -231,7 +212,7 @@ closepath 48 -31 125 -31 rquadto closepath } def -/P$26 { +/P$1p { 35 0 62 17 rquadto 26 17 26 62 rquadto 0 45 -26 64 rquadto @@ -242,40 +223,20 @@ closepath 26 -17 64 -17 rquadto closepath } def -/P$2t { --118 0 -193 -92 rquadto --75 -93 -75 -273 rquadto -0 -182 75 -276 rquadto -76 -93 198 -93 rquadto -76 0 125 31 rquadto -50 29 79 73 rquadto -6 0 rlineto --4 -20 -9 -59 rquadto --4 -40 -4 -82 rquadto -0 -226 rlineto -193 0 rlineto -0 987 rlineto --148 0 rlineto --37 -92 rlineto --7 0 rlineto --29 43 -78 75 rquadto --46 29 -123 29 rquadto -closepath -} def -/P$1n { +/P$1l { -193 0 rlineto 0 -987 rlineto 193 0 rlineto 0 987 rlineto } def -/P$10 { +/P$u { -81 0 -129 53 rquadto -46 51 -56 145 rquadto 354 0 rlineto -1 -89 -42 -143 rquadto -39 -54 -126 -54 rquadto } def -/P$38 { +/P$2z { -100 0 -164 -78 rquadto -62 -79 -62 -231 rquadto 0 -154 62 -232 rquadto @@ -295,7 +256,7 @@ closepath -40 25 -104 25 rquadto closepath } def -/P$24 { +/P$27 { -64 0 -90 40 rquadto -25 39 -26 120 rquadto 0 17 rlineto @@ -305,7 +266,7 @@ closepath 28 -46 28 -134 rquadto 0 -178 -112 -178 rquadto } def -/P$3s { +/P$3g { 0 20 -1 54 rquadto -1 34 -3 57 rquadto 4 0 rlineto @@ -326,7 +287,7 @@ closepath 0 515 rlineto closepath } def -/P$1w { +/P$21 { -78 3 -109 29 rquadto -31 25 -31 68 rquadto 0 37 21 53 rquadto @@ -352,32 +313,7 @@ closepath -285 750 rlineto -140 0 rlineto } def -/P$3u { --59 0 rlineto -0 251 rlineto -62 0 rlineto -98 0 140 -32 rquadto -42 -32 42 -96 rquadto -0 -65 -45 -93 rquadto --45 -28 -140 -28 rquadto -} def -/P$3x { -171 0 254 65 rquadto -82 65 82 198 rquadto -0 73 -28 123 rquadto --26 50 -68 79 rquadto --42 28 -89 45 rquadto -254 415 rlineto --135 0 rlineto --225 -382 rlineto --184 0 rlineto -0 382 rlineto --117 0 rlineto -0 -928 rlineto -256 0 rlineto -closepath -} def -/P$2p { +/P$2n { 118 0 176 60 rquadto 59 59 59 195 rquadto 0 453 rlineto @@ -405,7 +341,7 @@ closepath 34 -60 95 -89 rquadto 60 -28 128 -28 rquadto } def -/P$1p { +/P$1n { -259 0 rlineto 0 -959 rlineto 259 0 rlineto @@ -415,7 +351,7 @@ closepath 118 0 rlineto 0 112 rlineto } def -/P$3d { +/P$33 { 128 0 206 90 rquadto 79 89 79 268 rquadto 0 178 -79 270 rquadto @@ -435,7 +371,7 @@ closepath 51 -31 135 -31 rquadto closepath } def -/P$33 { +/P$22 { 0 32 -3 67 rquadto -1 32 -3 51 rquadto 6 0 rlineto @@ -493,7 +429,7 @@ closepath 0 -750 rlineto 123 0 rlineto } def -/P$1j { +/P$1a { 68 0 123 26 rquadto 56 25 95 78 rquadto 6 0 rlineto @@ -518,7 +454,7 @@ closepath 76 -98 210 -98 rquadto closepath } def -/P$1v { +/P$20 { 120 0 184 53 rquadto 64 51 64 159 rquadto 0 400 rlineto @@ -542,7 +478,7 @@ closepath 59 -14 123 -14 rquadto closepath } def -/P$w { +/P$1k { -93 3 -131 34 rquadto -35 31 -35 81 rquadto 0 45 26 64 rquadto @@ -568,7 +504,19 @@ closepath 275 0 rlineto closepath } def -/P$2c { +/P$1o { +-584 0 rlineto +0 -107 rlineto +376 -540 rlineto +-367 0 rlineto +0 -137 rlineto +564 0 rlineto +0 107 rlineto +-375 540 rlineto +385 0 rlineto +0 137 rlineto +} def +/P$2d { 0 101 -75 153 rquadto -75 51 -203 51 rquadto -73 0 -126 -12 rquadto @@ -600,7 +548,7 @@ closepath 46 26 71 64 rquadto 25 35 25 92 rquadto } def -/P$3k { +/P$39 { 0 90 -64 140 rquadto -64 48 -192 48 rquadto -62 0 -107 -9 rquadto @@ -631,7 +579,7 @@ closepath 37 21 57 54 rquadto 20 32 20 87 rquadto } def -/P$29 { +/P$2a { 0 -51 26 -71 rquadto 28 -20 67 -20 rquadto 39 0 65 20 rquadto @@ -641,7 +589,7 @@ closepath -39 0 -67 -20 rquadto -26 -21 -26 -70 rquadto } def -/P$2l { +/P$2j { 0 696 rlineto -114 0 rlineto 0 -696 rlineto @@ -659,7 +607,7 @@ closepath -131 0 rlineto closepath } def -/P$15 { +/P$z { -92 0 -165 -37 rquadto -71 -37 -112 -115 rquadto -40 -79 -40 -203 rquadto @@ -698,7 +646,7 @@ closepath 35 -57 100 -85 rquadto 65 -29 135 -29 rquadto } def -/P$3g { +/P$35 { -75 0 -106 46 rquadto -29 46 -32 143 rquadto 0 20 rlineto @@ -731,7 +679,7 @@ closepath 175 0 rlineto 0 89 rlineto } def -/P$1o { +/P$1m { 32 0 62 -6 rquadto 29 -6 59 -15 rquadto 0 145 rlineto @@ -755,7 +703,7 @@ closepath 23 18 60 18 rquadto closepath } def -/P$2k { +/P$1f { -110 0 -154 64 rquadto -42 64 -42 198 rquadto 0 4 rlineto @@ -765,7 +713,7 @@ closepath 46 -70 46 -200 rquadto 0 -264 -187 -264 rquadto } def -/P$13 { +/P$x { -110 -287 rlineto -368 0 rlineto -109 287 rlineto @@ -776,7 +724,7 @@ closepath -121 0 rlineto closepath } def -/P$3f { +/P$19 { -264 -696 rlineto 121 0 rlineto 148 410 rlineto @@ -792,7 +740,7 @@ closepath -265 696 rlineto -131 0 rlineto } def -/P$2e { +/P$2f { 110 0 156 -60 rquadto 45 -60 45 -182 rquadto 0 -20 rlineto @@ -803,13 +751,13 @@ closepath 0 123 46 193 rquadto 46 68 139 68 rquadto } def -/P$18 { +/P$12 { 0 696 rlineto -114 0 rlineto 0 -696 rlineto 114 0 rlineto } def -/P$3e { +/P$34 { -107 0 -151 60 rquadto -42 59 -45 181 rquadto 0 21 rlineto @@ -821,7 +769,7 @@ closepath 0 -118 -46 -190 rquadto -45 -71 -140 -71 rquadto } def -/P$3b { +/P$1w { 0 89 28 135 rquadto 29 45 95 45 rquadto 65 0 93 -45 rquadto @@ -831,34 +779,7 @@ closepath -65 0 -95 45 rquadto -28 43 -28 132 rquadto } def -/P$s { -368 0 rlineto -0 481 rlineto --73 25 -151 39 rquadto --78 14 -179 14 rquadto --207 0 -320 -121 rquadto --110 -121 -110 -356 rquadto -0 -145 56 -251 rquadto -57 -106 165 -164 rquadto -107 -59 264 -59 rquadto -73 0 145 15 rquadto -71 15 129 40 rquadto --65 157 rlineto --42 -21 -96 -35 rquadto --54 -15 -114 -15 rquadto --85 0 -150 39 rquadto --62 39 -96 110 rquadto --34 70 -34 167 rquadto -0 90 25 160 rquadto -25 70 78 109 rquadto -53 39 139 39 rquadto -40 0 70 -3 rquadto -29 -4 54 -9 rquadto -0 -193 rlineto --176 0 rlineto -0 -164 rlineto -} def -/P$25 { +/P$28 { 26 0 51 -4 rquadto 26 -6 51 -14 rquadto 0 121 rlineto @@ -881,7 +802,7 @@ closepath 0 32 18 50 rquadto 20 17 53 17 rquadto } def -/P$2a { +/P$2b { 118 0 rlineto 0 -732 rlineto -118 0 rlineto @@ -892,7 +813,7 @@ closepath 0 -112 rlineto closepath } def -/P$23 { +/P$26 { 101 0 164 78 rquadto 62 78 62 231 rquadto 0 153 -65 232 rquadto @@ -911,7 +832,7 @@ closepath 40 -26 106 -26 rquadto closepath } def -/P$1s { +/P$31 { 96 0 154 51 rquadto 59 51 59 167 rquadto 0 392 rlineto @@ -930,6 +851,20 @@ closepath 28 -46 78 -67 rquadto 50 -20 106 -20 rquadto } def +/P$3h { +-518 0 rlineto +0 -928 rlineto +518 0 rlineto +0 103 rlineto +-401 0 rlineto +0 289 rlineto +378 0 rlineto +0 101 rlineto +-378 0 rlineto +0 331 rlineto +401 0 rlineto +0 103 rlineto +} def /P$i { 26 0 56 -4 rquadto 29 -4 48 -9 rquadto @@ -954,26 +889,6 @@ closepath 32 32 85 32 rquadto closepath } def -/P$2v { -0 40 -3 79 rquadto --1 39 -4 60 rquadto -7 0 rlineto -28 -43 76 -75 rquadto -48 -31 125 -31 rquadto -118 0 192 93 rquadto -75 92 75 273 rquadto -0 182 -75 276 rquadto --75 92 -198 92 rquadto --76 0 -121 -26 rquadto --45 -28 -73 -64 rquadto --12 0 rlineto --32 78 rlineto --148 0 rlineto -0 -987 rlineto -193 0 rlineto -0 229 rlineto -closepath -} def /P$h { -89 0 -140 57 rquadto -50 56 -59 156 rquadto @@ -981,7 +896,7 @@ closepath -1 -95 -45 -154 rquadto -42 -59 -135 -59 rquadto } def -/P$14 { +/P$y { -4 -10 -14 -37 rquadto -7 -28 -17 -56 rquadto -7 -29 -12 -45 rquadto @@ -991,7 +906,7 @@ closepath 293 0 rlineto -103 -281 rlineto } def -/P$1b { +/P$15 { -148 0 -234 100 rquadto -85 100 -85 275 rquadto 0 173 79 275 rquadto @@ -1012,7 +927,7 @@ closepath -42 -20 -95 -35 rquadto -53 -15 -115 -15 rquadto } def -/P$2d { +/P$2e { -129 0 -207 -89 rquadto -78 -90 -78 -270 rquadto 0 -179 78 -270 rquadto @@ -1032,7 +947,7 @@ closepath -51 31 -132 31 rquadto closepath } def -/P$1m { +/P$1h { -17 -53 -29 -104 rquadto -12 -51 -18 -79 rquadto -6 0 rlineto @@ -1063,7 +978,7 @@ closepath -134 0 rlineto -118 -392 rlineto } def -/P$3h { +/P$36 { 156 0 235 45 rquadto 81 43 81 154 rquadto 0 67 -31 114 rquadto @@ -1079,13 +994,13 @@ closepath 245 0 rlineto closepath } def -/P$27 { +/P$1q { 0 600 rlineto -164 0 rlineto 0 -600 rlineto 164 0 rlineto } def -/P$3r { +/P$3f { -117 0 rlineto 0 -928 rlineto 518 0 rlineto @@ -1106,7 +1021,7 @@ closepath 0 -98 -59 -139 rquadto -57 -42 -181 -42 rquadto } def -/P$1x { +/P$1y { 110 0 173 87 rquadto 4 0 rlineto 12 -76 rlineto @@ -1140,7 +1055,7 @@ closepath 0 -96 -62 -143 rquadto -60 -48 -193 -48 rquadto } def -/P$3a { +/P$1v { 0 150 -79 231 rquadto -78 81 -212 81 rquadto -84 0 -150 -35 rquadto @@ -1153,7 +1068,7 @@ closepath 37 68 37 168 rquadto closepath } def -/P$z { +/P$t { 89 0 153 39 rquadto 65 39 100 109 rquadto 34 70 34 165 rquadto @@ -1174,7 +1089,7 @@ closepath 70 -43 162 -43 rquadto closepath } def -/P$1r { +/P$2v { -4 -18 -14 -46 rquadto -7 -29 -17 -59 rquadto -9 -29 -14 -51 rquadto @@ -1185,40 +1100,13 @@ closepath 204 0 rlineto -57 -182 rlineto } def -/P$1e { -320 0 rlineto -0 456 rlineto --75 23 -151 34 rquadto --76 12 -175 12 rquadto --143 0 -243 -57 rquadto --98 -57 -150 -164 rquadto --50 -107 -50 -254 rquadto -0 -145 56 -251 rquadto -57 -107 164 -165 rquadto -107 -59 260 -59 rquadto -78 0 146 14 rquadto -70 14 129 40 rquadto --43 100 rlineto --50 -21 -112 -37 rquadto --60 -15 -128 -15 rquadto --165 0 -259 100 rquadto --92 100 -92 275 rquadto -0 110 35 196 rquadto -35 84 112 131 rquadto -76 46 201 46 rquadto -60 0 103 -6 rquadto -43 -6 78 -15 rquadto -0 -275 rlineto --203 0 rlineto -0 -104 rlineto -} def /P$f { -123 0 rlineto 0 -1064 rlineto 123 0 rlineto 0 1064 rlineto } def -/P$39 { +/P$30 { 68 0 95 -39 rquadto 28 -40 29 -121 rquadto 0 -17 rlineto @@ -1244,13 +1132,13 @@ closepath 53 115 53 270 rquadto closepath } def -/P$3m { +/P$1t { -164 0 rlineto 0 -835 rlineto 164 0 rlineto 0 835 rlineto } def -/P$37 { +/P$2y { 0 43 -3 84 rquadto -3 40 -4 57 rquadto 9 0 rlineto @@ -1280,27 +1168,7 @@ closepath -168 0 -250 107 rquadto -79 106 -79 295 rquadto } def -/P$2r { -146 0 232 84 rquadto -85 84 85 239 rquadto -0 93 rlineto --457 0 rlineto -3 81 48 128 rquadto -46 46 128 46 rquadto -68 0 125 -14 rquadto -56 -14 115 -42 rquadto -0 150 rlineto --51 26 -109 37 rquadto --57 12 -140 12 rquadto --106 0 -189 -39 rquadto --81 -39 -128 -120 rquadto --46 -81 -46 -203 rquadto -0 -125 42 -206 rquadto -43 -82 118 -125 rquadto -75 -42 175 -42 rquadto -closepath -} def -/P$11 { +/P$v { 0 696 rlineto -92 0 rlineto -17 -92 rlineto @@ -1318,7 +1186,7 @@ closepath 0 -362 rlineto 114 0 rlineto } def -/P$12 { +/P$w { 18 0 40 1 rquadto 23 1 40 6 rquadto -14 104 rlineto @@ -1336,13 +1204,6 @@ closepath 34 -57 87 -98 rquadto 53 -42 126 -42 rquadto } def -/P$2s { --56 0 -93 35 rquadto --35 35 -42 112 rquadto -270 0 rlineto -0 -64 -32 -106 rquadto --32 -42 -101 -42 rquadto -} def /P$r { 134 0 203 65 rquadto 68 64 68 209 rquadto @@ -1362,7 +1223,7 @@ closepath 65 -29 135 -29 rquadto closepath } def -/P$1t { +/P$3d { -142 0 rlineto 0 478 rlineto -164 0 rlineto @@ -1385,7 +1246,7 @@ closepath 142 0 rlineto 0 121 rlineto } def -/P$3n { +/P$3a { -78 3 -109 29 rquadto -31 25 -31 68 rquadto 0 37 21 53 rquadto @@ -1396,7 +1257,7 @@ closepath -64 1 rlineto closepath } def -/P$36 { +/P$2x { -134 0 -207 -73 rquadto -71 -75 -71 -234 rquadto 0 -109 37 -178 rquadto @@ -1416,54 +1277,7 @@ closepath -37 25 -79 34 rquadto -40 10 -103 10 rquadto } def -/P$3v { -0 107 -76 165 rquadto --75 57 -226 57 rquadto --73 0 -128 -9 rquadto --53 -9 -106 -31 rquadto -0 -160 rlineto -57 26 123 43 rquadto -67 17 117 17 rquadto -57 0 81 -17 rquadto -25 -17 25 -43 rquadto -0 -18 -10 -32 rquadto --9 -14 -42 -32 rquadto --31 -18 -101 -46 rquadto --65 -28 -109 -56 rquadto --42 -28 -64 -67 rquadto --20 -40 -20 -100 rquadto -0 -98 76 -148 rquadto -78 -50 204 -50 rquadto -67 0 126 14 rquadto -59 12 123 42 rquadto --59 139 rlineto --51 -21 -98 -35 rquadto --46 -15 -95 -15 rquadto --84 0 -84 46 rquadto -0 17 10 31 rquadto -10 12 42 28 rquadto -31 15 93 42 rquadto -62 25 106 51 rquadto -43 26 67 65 rquadto -25 39 25 103 rquadto -} def -/P$3t { -189 0 279 68 rquadto -90 68 90 209 rquadto -0 64 -25 112 rquadto --23 46 -62 79 rquadto --39 32 -85 53 rquadto -273 404 rlineto --218 0 rlineto --220 -356 rlineto --104 0 rlineto -0 356 rlineto --196 0 rlineto -0 -928 rlineto -270 0 rlineto -closepath -} def -/P$16 { +/P$10 { 25 0 51 -3 rquadto 28 -4 45 -10 rquadto 0 87 rlineto @@ -1486,12 +1300,6 @@ closepath 0 62 29 93 rquadto 31 29 79 29 rquadto } def -/P$1h { -0 -100 rlineto -315 0 rlineto -0 100 rlineto --315 0 rlineto -} def /P$g { 95 0 164 42 rquadto 70 42 107 118 rquadto @@ -1532,7 +1340,7 @@ closepath 60 -26 126 -26 rquadto closepath } def -/P$28 { +/P$29 { 0 -54 23 -92 rquadto 23 -37 79 -78 rquadto 48 -35 70 -60 rquadto @@ -1557,7 +1365,7 @@ closepath 0 -39 rlineto closepath } def -/P$31 { +/P$2s { 32 0 62 -6 rquadto 29 -6 59 -15 rquadto 0 145 rlineto @@ -1598,7 +1406,7 @@ closepath 37 -62 93 -106 rquadto 57 -45 135 -45 rquadto } def -/P$3l { +/P$1u { -228 -600 rlineto 171 0 rlineto 115 342 rlineto @@ -1611,7 +1419,7 @@ closepath -229 600 rlineto -168 0 rlineto } def -/P$y { +/P$s { 125 0 189 60 rquadto 64 59 64 195 rquadto 0 453 rlineto @@ -1647,7 +1455,7 @@ closepath 0 -390 rlineto 123 0 rlineto } def -/P$v { +/P$1j { 143 0 218 62 rquadto 76 60 76 187 rquadto 0 473 rlineto @@ -1671,7 +1479,7 @@ closepath 70 -17 145 -17 rquadto closepath } def -/P$21 { +/P$24 { 0 34 -3 68 rquadto -3 32 -6 67 rquadto 3 0 rlineto @@ -1690,7 +1498,7 @@ closepath 164 0 rlineto 0 373 rlineto } def -/P$3q { +/P$3e { 0 600 rlineto -126 0 rlineto -21 -76 rlineto @@ -1721,7 +1529,7 @@ closepath 21 -18 51 -18 rquadto closepath } def -/P$t { +/P$2o { 0 176 -93 273 rquadto -92 95 -253 95 rquadto -98 0 -176 -42 rquadto @@ -1734,7 +1542,7 @@ closepath 45 81 45 200 rquadto closepath } def -/P$3i { +/P$37 { 71 0 100 -23 rquadto 28 -23 28 -67 rquadto 0 -45 -32 -64 rquadto @@ -1765,7 +1573,7 @@ closepath -37 20 -82 29 rquadto -45 10 -109 10 rquadto } def -/P$1q { +/P$2u { -57 -187 rlineto -285 0 rlineto -56 187 rlineto @@ -1776,7 +1584,7 @@ closepath -179 0 rlineto closepath } def -/P$1y { +/P$1z { -115 0 -115 181 rquadto 0 179 117 179 rquadto 62 0 92 -35 rquadto @@ -1808,7 +1616,7 @@ closepath 0 68 32 101 rquadto 32 32 85 32 rquadto } def -/P$1f { +/P$1c { 126 0 187 56 rquadto 60 54 60 176 rquadto 0 475 rlineto @@ -1832,7 +1640,7 @@ closepath 62 -17 131 -17 rquadto closepath } def -/P$35 { +/P$2w { 0 600 rlineto -126 0 rlineto -21 -76 rlineto @@ -1851,7 +1659,7 @@ closepath 0 -282 rlineto 164 0 rlineto } def -/P$3p { +/P$3c { 0 -39 21 -54 rquadto 23 -17 54 -17 rquadto 31 0 53 17 rquadto @@ -1861,49 +1669,7 @@ closepath -31 0 -54 -17 rquadto -21 -18 -21 -54 rquadto } def -/P$2w { --75 0 -106 46 rquadto --29 46 -32 143 rquadto -0 20 rlineto -0 103 29 159 rquadto -31 54 112 54 rquadto -59 0 93 -54 rquadto -35 -56 35 -160 rquadto -0 -103 -35 -156 rquadto --35 -53 -96 -53 rquadto -} def -/P$2u { -81 0 112 -46 rquadto -32 -46 34 -142 rquadto -0 -20 rlineto -0 -104 -32 -159 rquadto --31 -54 -117 -54 rquadto --62 0 -100 56 rquadto --35 54 -35 157 rquadto -0 104 35 157 rquadto -37 51 103 51 rquadto -} def -/P$2y { -0 39 -3 79 rquadto --3 39 -7 79 rquadto -3 0 rlineto -18 -28 39 -54 rquadto -21 -28 45 -53 rquadto -198 -215 rlineto -218 0 rlineto --282 307 rlineto -300 401 rlineto --223 0 rlineto --204 -287 rlineto --82 67 rlineto -0 220 rlineto --193 0 rlineto -0 -987 rlineto -193 0 rlineto -0 442 rlineto -closepath -} def -/P$3c { +/P$32 { -335 0 rlineto 0 -67 rlineto 109 -25 rlineto @@ -1917,16 +1683,7 @@ closepath 109 25 rlineto 0 67 rlineto } def -/P$3y { --131 0 rlineto -0 343 rlineto -139 0 rlineto -112 0 164 -43 rquadto -53 -45 53 -132 rquadto -0 -90 -54 -128 rquadto --54 -39 -170 -39 rquadto -} def -/P$1u { +/P$1x { 10 0 26 1 rquadto 17 0 28 1 rquadto -12 154 rlineto @@ -1944,7 +1701,7 @@ closepath 26 -45 71 -78 rquadto 46 -32 107 -32 rquadto } def -/P$17 { +/P$11 { 26 0 46 17 rquadto 20 17 20 54 rquadto 0 37 -20 56 rquadto @@ -1955,7 +1712,7 @@ closepath 20 -17 48 -17 rquadto closepath } def -/P$1z { +/P$1r { 125 0 196 70 rquadto 73 70 73 201 rquadto 0 79 rlineto @@ -1975,46 +1732,14 @@ closepath 64 -35 148 -35 rquadto closepath } def -/P$20 { +/P$1s { -46 0 -78 31 rquadto -31 31 -37 95 rquadto 229 0 rlineto 0 -54 -28 -90 rquadto -28 -35 -85 -35 rquadto } def -/P$2q { --193 0 rlineto -0 -928 rlineto -531 0 rlineto -0 160 rlineto --337 0 rlineto -0 239 rlineto -314 0 rlineto -0 160 rlineto --314 0 rlineto -0 367 rlineto -} def -/P$2x { --159 0 -246 -87 rquadto --85 -87 -85 -276 rquadto -0 -129 43 -210 rquadto -45 -82 123 -121 rquadto -79 -39 181 -39 rquadto -73 0 126 15 rquadto -54 14 95 32 rquadto --57 150 rlineto --45 -18 -85 -29 rquadto --39 -12 -78 -12 rquadto --150 0 -150 215 rquadto -0 106 39 157 rquadto -40 50 110 50 rquadto -62 0 107 -15 rquadto -46 -17 92 -45 rquadto -0 164 rlineto --45 29 -93 40 rquadto --48 12 -121 12 rquadto -} def -/P$32 { +/P$2t { 14 0 32 1 rquadto 20 1 31 4 rquadto -14 181 rlineto @@ -2033,7 +1758,7 @@ closepath 54 -39 126 -39 rquadto closepath } def -/P$30 { +/P$2r { -75 0 -106 46 rquadto -29 46 -32 143 rquadto 0 20 rlineto @@ -2043,7 +1768,7 @@ closepath 32 -56 32 -160 rquadto 0 -209 -132 -209 rquadto } def -/P$1g { +/P$1d { -129 4 -179 40 rquadto -50 35 -50 103 rquadto 0 57 35 85 rquadto @@ -2074,7 +1799,7 @@ closepath -45 -20 -103 -37 rquadto -56 -17 -123 -17 rquadto } def -/P$2n { +/P$2l { 0 -32 17 -46 rquadto 18 -15 43 -15 rquadto 25 0 42 15 rquadto @@ -2097,7 +1822,7 @@ closepath 379 0 rlineto 0 89 rlineto } def -/P$1l { +/P$1g { -81 0 -129 53 rquadto -46 51 -56 145 rquadto 354 0 rlineto @@ -2105,7 +1830,7 @@ closepath -39 -54 -126 -54 rquadto closepath } def -/P$2j { +/P$1e { 0 43 -3 82 rquadto -1 37 -3 59 rquadto 6 0 rlineto @@ -2125,7 +1850,7 @@ closepath 0 240 rlineto closepath } def -/P$1a { +/P$14 { 0 123 48 196 rquadto 50 71 156 71 rquadto 104 0 154 -71 rquadto @@ -2145,7 +1870,7 @@ closepath 315 0 rlineto -112 -301 rlineto } def -/P$2f { +/P$18 { -642 0 rlineto 0 -89 rlineto 487 -734 rlineto @@ -2157,7 +1882,7 @@ closepath 501 0 rlineto 0 104 rlineto } def -/P$19 { +/P$13 { 0 173 -87 268 rquadto -87 93 -237 93 rquadto -92 0 -164 -42 rquadto @@ -2170,7 +1895,7 @@ closepath 40 79 40 195 rquadto closepath } def -/P$1c { +/P$16 { -114 0 rlineto 0 -987 rlineto 114 0 rlineto @@ -2186,7 +1911,7 @@ closepath -115 0 -167 76 rquadto -51 75 -51 207 rquadto } def -/P$22 { +/P$25 { -473 0 rlineto 0 -96 rlineto 278 -378 rlineto @@ -2198,7 +1923,7 @@ closepath 279 0 rlineto 0 125 rlineto } def -/P$u { +/P$2p { 0 104 34 159 rquadto 34 53 112 53 rquadto 76 0 110 -53 rquadto @@ -2208,13 +1933,6 @@ closepath -76 0 -110 53 rquadto -34 53 -34 157 rquadto } def -/P$x { --193 0 rlineto -0 -987 rlineto -193 0 rlineto -0 987 rlineto -closepath -} def /P$q { -93 0 -145 75 rquadto -51 75 -51 214 rquadto @@ -2226,7 +1944,7 @@ closepath 0 -154 -53 -220 rquadto -53 -67 -167 -67 rquadto } def -/P$34 { +/P$23 { -64 0 -90 40 rquadto -25 39 -26 120 rquadto 0 17 rlineto @@ -2256,7 +1974,7 @@ closepath 57 -45 135 -45 rquadto closepath } def -/P$2o { +/P$2m { 0 -32 17 -46 rquadto 18 -15 43 -15 rquadto 23 0 42 15 rquadto @@ -2267,43 +1985,43 @@ closepath -17 -17 -17 -50 rquadto } def 1 1 1 setrgbcolor -1000 59870 12900 11847 simplerect +1000 50729 12900 7277 simplerect closepath eofill 100 setlinewidth 0.69 0.69 0.69 setrgbcolor -1000 59870 12900 11847 simplerect +1000 50729 12900 7277 simplerect closepath stroke 1 1 1 setrgbcolor -1000 68712 31200 4906 simplerect +1000 55000 31200 4906 simplerect closepath eofill 100 setlinewidth 0.69 0.69 0.69 setrgbcolor -1000 68712 31200 4906 simplerect +1000 55000 31200 4906 simplerect closepath stroke 1 1 1 setrgbcolor -1000 68712 51700 4906 simplerect +1000 55000 51700 4906 simplerect closepath eofill 100 setlinewidth 0.69 0.69 0.69 setrgbcolor -1000 68712 51700 4906 simplerect +1000 55000 51700 4906 simplerect closepath stroke 150 setlinewidth 0.5 0.5 0.5 setrgbcolor -53750 51329 5050 19689 simplerect +53750 42188 5050 15118 simplerect closepath stroke 150 setlinewidth 0.5 0.5 0.5 setrgbcolor -51750 14653 6050 35042 simplerect +51750 14653 6050 25901 simplerect closepath stroke 150 setlinewidth 0.5 0.5 0.5 setrgbcolor -51750 8311 6050 51095 simplerect +51750 8311 6050 41954 simplerect closepath stroke 50 setlinewidth 0.69 0.69 0.69 setrgbcolor newpath 13350 3906 moveto -71{ +57{ 0 500 rlineto 0 500 rmoveto } repeat @@ -2312,7 +2030,7 @@ stroke 0.69 0.69 0.69 setrgbcolor newpath 31700 3906 moveto -71{ +57{ 0 500 rlineto 0 500 rmoveto } repeat @@ -2321,7 +2039,7 @@ stroke 0.69 0.69 0.69 setrgbcolor newpath 52200 3906 moveto -71{ +57{ 0 500 rlineto 0 500 rmoveto } repeat @@ -2453,129 +2171,129 @@ newpath P$i fill 0.89 0.89 0.94 setrgbcolor -12700 3306 7050 74418 250 roundrect +12700 3306 7050 60707 250 roundrect closepath eofill 50 setlinewidth 0.09 0.09 0.09 setrgbcolor -12700 3306 7050 74418 250 roundrect +12700 3306 7050 60707 250 roundrect closepath stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -8160 75615 moveto +8160 61903 moveto P$0 -8154 75724 moveto +8154 62012 moveto P$1 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -9657 76113 moveto +9657 62402 moveto P$2 -8868 76113 moveto +8868 62402 moveto P$3 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -10453 76348 moveto +10453 62636 moveto P$4 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -11712 76615 moveto +11712 62903 moveto P$5 -11442 75891 moveto +11442 62180 moveto P$6 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -12270 76629 moveto +12270 62917 moveto P$7 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -12920 76527 moveto +12920 62816 moveto P$8 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -13231 75584 moveto +13231 61872 moveto P$9 -13292 75865 moveto +13292 62153 moveto P$a fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -14221 76238 moveto +14221 62527 moveto P$b -13654 76238 moveto +13654 62527 moveto P$c fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -14729 75851 moveto +14729 62139 moveto P$d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -15714 75712 moveto +15714 62000 moveto P$e fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -16292 76615 moveto +16292 62903 moveto P$f fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -16631 75584 moveto +16631 61872 moveto P$9 -16692 75865 moveto +16692 62153 moveto P$a fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -17259 75851 moveto +17259 62139 moveto P$g -17257 75951 moveto +17257 62239 moveto P$h fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -18129 75851 moveto +18129 62139 moveto P$d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -18920 76527 moveto +18920 62816 moveto P$i fill 0.89 0.89 0.94 setrgbcolor @@ -2671,95 +2389,95 @@ newpath P$l fill 0.89 0.89 0.94 setrgbcolor -9200 3306 27100 74418 250 roundrect +9200 3306 27100 60707 250 roundrect closepath eofill 50 setlinewidth 0.09 0.09 0.09 setrgbcolor -9200 3306 27100 74418 250 roundrect +9200 3306 27100 60707 250 roundrect closepath stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -28562 76615 moveto +28562 62903 moveto P$5 -28292 75891 moveto +28292 62180 moveto P$6 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -29120 76629 moveto +29120 62917 moveto P$7 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -29770 76527 moveto +29770 62816 moveto P$8 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -30671 76238 moveto +30671 62527 moveto P$b -30104 76238 moveto +30104 62527 moveto P$c fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -31168 75851 moveto +31168 62139 moveto P$j fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -32003 76348 moveto +32003 62636 moveto P$4 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -32509 75851 moveto +32509 62139 moveto P$g -32507 75951 moveto +32507 62239 moveto P$h fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -33368 75851 moveto +33368 62139 moveto P$j fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -33784 76615 moveto +33784 62903 moveto P$k fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -34609 75851 moveto +34609 62139 moveto P$g -34607 75951 moveto +34607 62239 moveto P$h fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -35468 75851 moveto +35468 62139 moveto P$l fill 0.89 0.89 0.94 setrgbcolor @@ -2857,469 +2575,406 @@ newpath P$r fill 0.89 0.89 0.94 setrgbcolor -9200 3306 47600 74418 250 roundrect +9200 3306 47600 60707 250 roundrect closepath eofill 50 setlinewidth 0.09 0.09 0.09 setrgbcolor -9200 3306 47600 74418 250 roundrect +9200 3306 47600 60707 250 roundrect closepath stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -49062 76615 moveto +49062 62903 moveto P$5 -48792 75891 moveto +48792 62180 moveto P$6 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -49620 76629 moveto +49620 62917 moveto P$7 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -50270 76527 moveto +50270 62816 moveto P$8 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -51171 76238 moveto +51171 62527 moveto P$b -50604 76238 moveto +50604 62527 moveto P$c fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -51668 75851 moveto +51668 62139 moveto P$j fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -52200 75615 moveto +52200 61903 moveto P$m -52189 75723 moveto +52189 62011 moveto P$n fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -52842 76615 moveto +52842 62903 moveto P$f fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -53746 75865 moveto +53746 62153 moveto P$o fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -54284 75851 moveto +54284 62139 moveto P$p -54301 75954 moveto +54301 62242 moveto P$q fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -54981 75584 moveto +54981 61872 moveto P$9 -55042 75865 moveto +55042 62153 moveto P$a fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -55679 75851 moveto +55679 62139 moveto P$r fill 1 1 1 setrgbcolor -1000 59870 12900 11847 simplerect +1000 50729 12900 7277 simplerect closepath eofill 100 setlinewidth 0.69 0.69 0.69 setrgbcolor -1000 59870 12900 11847 simplerect +1000 50729 12900 7277 simplerect closepath stroke 1 1 1 setrgbcolor -1000 68712 31200 4906 simplerect +1000 55000 31200 4906 simplerect closepath eofill 100 setlinewidth 0.69 0.69 0.69 setrgbcolor -1000 68712 31200 4906 simplerect +1000 55000 31200 4906 simplerect closepath stroke 1 1 1 setrgbcolor -1000 68712 51700 4906 simplerect +1000 55000 51700 4906 simplerect closepath eofill 100 setlinewidth 0.69 0.69 0.69 setrgbcolor -1000 68712 51700 4906 simplerect +1000 55000 51700 4906 simplerect closepath stroke -0.93 0.93 0.93 setrgbcolor -59800 300 0 7092 simplerect -closepath eofill -100 setlinewidth -0.93 0.93 0.93 setrgbcolor -59800 300 0 7092 simplerect -closepath stroke -100 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -0 7092 moveto -59800 0 rlineto -stroke -100 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -0 7392 moveto -59800 0 rlineto -stroke -0.93 0.93 0.93 setrgbcolor -4300 2570 27750 5906 simplerect -closepath eofill -200 setlinewidth -0.5 0.5 0.5 setrgbcolor -4300 2570 27750 5906 simplerect -closepath stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28818 7174 moveto -P$s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29996 7340 moveto -P$t -29506 7340 moveto -P$u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -30442 6973 moveto -P$v -30470 7369 moveto -P$w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -31145 7696 moveto -P$x -fill 0.25 0.25 0.25 setrgbcolor newpath -11700 11447 moveto +11700 6877 moveto 1000 400 rlineto -1000 400 rlineto 400 -400 rlineto -11700 11447 lineto +11700 6877 lineto closepath eofill -200 setlinewidth +100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -11700 11447 moveto +11700 6877 moveto 1000 400 rlineto -1000 400 rlineto 400 -400 rlineto -11700 11447 lineto +11700 6877 lineto closepath stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -0 11847 moveto +0 7277 moveto 12300 0 rlineto stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -1395 10557 moveto +1395 5987 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +2129 5987 moveto +P$t +2128 6080 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +3142 5999 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +3629 5987 moveto +P$t +3628 6080 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +4385 5987 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +5457 6696 moveto +P$x +5207 6024 moveto P$y fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -2129 10557 moveto +5940 6708 moveto P$z -2128 10651 moveto +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +6493 6615 moveto P$10 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -3142 10570 moveto +6818 5738 moveto P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -3629 10557 moveto -P$z -3628 10651 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -4385 10557 moveto +6875 5999 moveto P$12 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -5457 11267 moveto +7665 6346 moveto P$13 -5207 10595 moveto +7139 6346 moveto P$14 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -5940 11279 moveto +8195 5987 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +9073 5857 moveto P$15 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -6493 11185 moveto +9575 6696 moveto P$16 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -6818 10309 moveto -P$17 -6875 10570 moveto -P$18 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -7665 10917 moveto -P$19 -7139 10917 moveto -P$1a -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -8195 10557 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -9073 10428 moveto -P$1b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -9575 11267 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -9818 10309 moveto -P$17 -9875 10570 moveto -P$18 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -10329 10557 moveto -P$z -10328 10651 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -11095 10557 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -11793 11185 moveto -P$1d -fill -0.25 0.25 0.25 setrgbcolor -newpath -30000 14618 moveto -1000 400 rlineto --1000 400 rlineto -400 -400 rlineto -30000 14618 lineto -closepath eofill -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -30000 14618 moveto -1000 400 rlineto --1000 400 rlineto -400 -400 rlineto -30000 14618 lineto -closepath stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -13900 15018 moveto -16700 0 rlineto -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19179 13947 moveto -P$1e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20265 14087 moveto -P$19 -19739 14087 moveto -P$1a -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20725 13729 moveto -P$1f -20757 14101 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21275 14437 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21401 14139 moveto -P$1h -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22457 14437 moveto -P$13 -22207 13765 moveto -P$14 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22995 13728 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23781 13829 moveto -P$1i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24185 13728 moveto +9818 5738 moveto +P$11 +9875 5999 moveto P$12 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -24625 13729 moveto +10329 5987 moveto +P$t +10328 6080 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +11095 5987 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +11793 6615 moveto +P$17 +fill +0.25 0.25 0.25 setrgbcolor +newpath +30000 10047 moveto +1000 400 rlineto +-1000 400 rlineto +400 -400 rlineto +30000 10047 lineto +closepath eofill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +30000 10047 moveto +1000 400 rlineto +-1000 400 rlineto +400 -400 rlineto +30000 10047 lineto +closepath stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +13900 10447 moveto +16700 0 rlineto +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19742 9867 moveto +P$18 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19918 8909 moveto +P$11 +19975 9170 moveto +P$12 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20429 9157 moveto +P$t +20428 9251 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20975 9867 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21314 9867 moveto +P$19 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22465 9517 moveto +P$13 +21939 9517 moveto +P$14 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22985 9157 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23407 9157 moveto +P$1a +23423 9253 moveto +P$1b +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24225 9159 moveto +P$1c +24257 9531 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24775 9120 moveto +P$1e +24971 9253 moveto P$1f -24657 14101 moveto +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25729 9157 moveto +P$t +25728 9251 moveto P$1g fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25307 13728 moveto -P$1j -25323 13823 moveto -P$1k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26129 13728 moveto -P$z -26128 13822 moveto -P$1l -fill 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -14000 18189 moveto +14000 13618 moveto 1000 -400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -14000 18189 moveto +14000 13618 moveto 1000 400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -13900 18189 moveto +13900 13618 moveto 43{ 200 0 rlineto 200 0 rmoveto @@ -3329,559 +2984,627 @@ stroke [] 0 setdash 0 0 0 setrgbcolor newpath -17207 17608 moveto -P$13 -16957 16936 moveto -P$14 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -17745 16898 moveto +16057 13037 moveto +P$x +15807 12365 moveto P$y fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -18443 17527 moveto -P$16 +16595 12328 moveto +P$s fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -19160 17214 moveto -P$1m +17293 12956 moveto +P$10 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -20315 17258 moveto -P$19 -19789 17258 moveto -P$1a +18010 12643 moveto +P$1h fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -20835 16898 moveto -P$12 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21243 17527 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22075 16900 moveto -P$1f -22107 17272 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23092 16911 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23631 17000 moveto -P$1i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24607 17608 moveto +19165 12687 moveto P$13 -24357 16936 moveto +18639 12687 moveto P$14 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -25145 16898 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25931 17000 moveto -P$1i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26335 16898 moveto -P$12 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26775 16900 moveto -P$1f -26807 17272 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27457 16898 moveto -P$1j -27473 16994 moveto -P$1k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28279 16898 moveto -P$z -28278 16992 moveto -P$1l -fill -0.93 0.93 0.93 setrgbcolor -newpath -5050 19689 moveto -11350 19689 lineto -11350 20659 lineto -10350 21659 lineto -5050 21659 lineto -5050 19689 lineto -closepath eofill -150 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -5050 19689 moveto -11350 19689 lineto -11350 20659 lineto -10350 21659 lineto -5050 21659 lineto -5050 19689 lineto -stroke -150 setlinewidth -0.5 0.5 0.5 setrgbcolor -53750 51329 5050 19689 simplerect -closepath stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -6942 20455 moveto -P$v -6970 20852 moveto +19685 12328 moveto P$w fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -7645 21178 moveto +20093 12956 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20925 12329 moveto +P$1c +20957 12701 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21942 12340 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22481 12429 moveto +P$1i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23442 13037 moveto +P$18 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23618 12079 moveto +P$11 +23675 12340 moveto +P$12 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24129 12328 moveto +P$t +24128 12422 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24675 13037 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25014 13037 moveto +P$19 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26165 12687 moveto +P$13 +25639 12687 moveto +P$14 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26685 12328 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27107 12328 moveto +P$1a +27123 12423 moveto +P$1b +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27925 12329 moveto +P$1c +27957 12701 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +28475 12290 moveto +P$1e +28671 12423 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +29429 12328 moveto +P$t +29428 12422 moveto +P$1g +fill +0.93 0.93 0.93 setrgbcolor +newpath +5050 15118 moveto +11350 15118 lineto +11350 16089 lineto +10350 17089 lineto +5050 17089 lineto +5050 15118 lineto +closepath eofill +150 setlinewidth +0.5 0.5 0.5 setrgbcolor +newpath +5050 15118 moveto +11350 15118 lineto +11350 16089 lineto +10350 17089 lineto +5050 17089 lineto +5050 15118 lineto +stroke +150 setlinewidth +0.5 0.5 0.5 setrgbcolor +53750 42188 5050 15118 simplerect +closepath stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +6942 15884 moveto +P$1j +6970 16281 moveto +P$1k +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +7645 16608 moveto +P$1l +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +8150 16466 moveto +P$1m +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +13185 16667 moveto P$1n fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -8150 21036 moveto +13860 16494 moveto P$1o fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -13185 21238 moveto +14018 15658 moveto P$1p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -13829 21065 moveto +14100 15894 moveto P$1q -13675 20555 moveto -P$1r fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -14476 20454 moveto +14482 15883 moveto +P$1r +14484 15999 moveto P$1s fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -15168 20586 moveto +15100 16494 moveto P$1t fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -15571 20454 moveto +15378 16494 moveto P$1u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -15982 20452 moveto +16381 16192 moveto P$1v -16004 20788 moveto +15967 16192 moveto P$1w fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -16631 20454 moveto +16871 15883 moveto P$1x -16682 20586 moveto +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +17231 15883 moveto P$1y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -17382 20454 moveto +17282 16016 moveto P$1z -17384 20569 moveto +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +17982 15881 moveto P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18382 20452 moveto -P$1v -18404 20788 moveto -P$1w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19000 20602 moveto +18004 16217 moveto P$21 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -19953 21065 moveto +18600 15853 moveto P$22 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20282 20454 moveto -P$1z -20284 20569 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21070 20454 moveto +18717 16013 moveto P$23 -21017 20583 moveto +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19382 15883 moveto +P$1r +19384 15999 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20382 15881 moveto +P$20 +20404 16217 moveto +P$21 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21000 16031 moveto P$24 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -21689 20944 moveto +21953 16494 moveto P$25 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -22018 20229 moveto +22282 15883 moveto +P$1r +22284 15999 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23070 15883 moveto P$26 -22100 20465 moveto +23017 16013 moveto P$27 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -22482 20454 moveto -P$1z -22484 20569 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23271 20454 moveto -P$1u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23689 20944 moveto -P$25 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23998 20765 moveto +23689 16374 moveto P$28 -23981 20988 moveto -P$29 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -24378 21126 moveto +24018 15658 moveto +P$1p +24100 15894 moveto +P$1q +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24482 15883 moveto +P$1r +24484 15999 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25271 15883 moveto +P$1x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25689 16374 moveto +P$28 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25998 16194 moveto +P$29 +25981 16417 moveto P$2a fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26378 16555 moveto +P$2b +fill 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -51500 24030 moveto +51500 19459 moveto -1000 -400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -51500 24030 moveto +51500 19459 moveto -1000 400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32200 24030 moveto +32200 19459 moveto 19400 0 rlineto stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -33845 22740 moveto -P$y +33845 18169 moveto +P$s fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -34579 22740 moveto -P$z -34578 22833 moveto -P$10 +34579 18169 moveto +P$t +34578 18263 moveto +P$u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -35592 22752 moveto -P$11 +35592 18182 moveto +P$v fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -36079 22740 moveto -P$z -36078 22833 moveto -P$10 +36079 18169 moveto +P$t +36078 18263 moveto +P$u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -36845 22740 moveto -P$y +36845 18169 moveto +P$s fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -38153 23201 moveto -P$2b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38543 23368 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39075 22741 moveto -P$1f -39107 23113 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39743 23368 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40592 22752 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41264 23257 moveto +38153 18630 moveto P$2c fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -42292 22752 moveto -P$11 +38543 18797 moveto +P$10 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -42845 22740 moveto -P$y +39075 18171 moveto +P$1c +39107 18542 moveto +P$1d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -43557 23462 moveto +39743 18797 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40592 18182 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41264 18686 moveto P$2d -43575 23368 moveto -P$2e fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -44992 23449 moveto +42292 18182 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42845 18169 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43557 18891 moveto +P$2e +43575 18797 moveto P$2f fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -45168 22491 moveto -P$17 -45225 22752 moveto +44992 18878 moveto P$18 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -45679 22740 moveto -P$z -45678 22833 moveto -P$10 +45168 17921 moveto +P$11 +45225 18182 moveto +P$12 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -46225 23449 moveto -P$1c +45679 18169 moveto +P$t +45678 18263 moveto +P$u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -47164 23257 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47579 22740 moveto -P$z -47578 22833 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -48243 23368 moveto +46225 18878 moveto P$16 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -48960 23449 moveto -P$2g +47164 18686 moveto +P$2d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -49379 22740 moveto -P$z -49378 22833 moveto +47579 18169 moveto +P$t +47578 18263 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +48243 18797 moveto P$10 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -50145 22740 moveto +48960 18878 moveto +P$2g +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +49379 18169 moveto +P$t +49378 18263 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +50145 18169 moveto P$2h fill 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32300 28971 moveto +32300 24401 moveto 1000 -400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32300 28971 moveto +32300 24401 moveto 1000 400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32200 28971 moveto +32200 24401 moveto 48{ 200 0 rlineto 200 0 rmoveto @@ -3892,966 +3615,876 @@ stroke [] 0 setdash 0 0 0 setrgbcolor newpath -36492 26620 moveto +36492 22049 moveto +P$18 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +37192 21352 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +37864 21857 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +38243 21968 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +38775 21341 moveto +P$1c +38807 21713 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39545 21340 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40257 22062 moveto +P$2e +40275 21968 moveto P$2f fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -37192 25923 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37864 26427 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38243 26538 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38775 25912 moveto -P$1f -38807 26284 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39545 25910 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40257 26632 moveto +41264 21857 moveto P$2d -40275 26538 moveto -P$2e fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -41264 26427 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41860 26226 moveto -P$1m -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42679 25910 moveto -P$z -42678 26004 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43390 26632 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43825 25921 moveto -P$2i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44964 26427 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45379 25910 moveto -P$z -45378 26004 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45925 26620 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46525 25873 moveto -P$2j -46721 26006 moveto -P$2k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47479 25910 moveto -P$z -47478 26004 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47968 25662 moveto -P$17 -48025 25923 moveto -P$2l -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -33895 27681 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -34625 27682 moveto -P$1f -34657 28054 moveto -P$2m -34432 27504 moveto -P$2n -34676 27504 moveto -P$2o -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -35340 28403 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -35775 27692 moveto -P$2i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36914 28198 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37293 28309 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37829 27681 moveto -P$z -37828 27775 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39025 27681 moveto -P$2p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40303 28142 moveto -P$2b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40518 27432 moveto -P$17 -40575 27693 moveto -P$18 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41525 27681 moveto -P$2p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42542 27693 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42875 28390 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43325 27682 moveto -P$1f -43357 28054 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43993 28309 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44318 27432 moveto -P$17 -44375 27693 moveto -P$18 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45165 28040 moveto -P$19 -44639 28040 moveto -P$1a -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45695 27681 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46614 28198 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47214 28198 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47640 28403 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -48075 27692 moveto -P$2i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -49085 27681 moveto -P$12 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -49318 27432 moveto -P$17 -49375 27693 moveto -P$18 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -49793 28309 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -50293 28309 moveto -P$1d -fill -0.93 0.93 0.93 setrgbcolor -59800 300 0 31956 simplerect -closepath eofill -100 setlinewidth -0.93 0.93 0.93 setrgbcolor -59800 300 0 31956 simplerect -closepath stroke -100 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -0 31956 moveto -59800 0 rlineto -stroke -100 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -0 32256 moveto -59800 0 rlineto -stroke -0.93 0.93 0.93 setrgbcolor -7600 2570 26100 30771 simplerect -closepath eofill -200 setlinewidth -0.5 0.5 0.5 setrgbcolor -7600 2570 26100 30771 simplerect -closepath stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27010 32561 moveto -P$2q -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27793 31837 moveto -P$2r -27795 31976 moveto -P$2s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28593 31837 moveto -P$2r -28595 31976 moveto -P$2s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29326 32573 moveto -P$2t -29393 32419 moveto -P$2u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -30095 31803 moveto -P$2v -30234 31992 moveto -P$2w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -30992 31837 moveto -P$v -31020 32234 moveto -P$w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -31790 32573 moveto -P$2x -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -32395 32015 moveto -P$2y -fill -0.93 0.93 0.93 setrgbcolor -newpath -6050 35042 moveto -15550 35042 lineto -15550 36012 lineto -14550 37012 lineto -6050 37012 lineto -6050 35042 lineto -closepath eofill -150 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -6050 35042 moveto -15550 35042 lineto -15550 36012 lineto -14550 37012 lineto -6050 37012 lineto -6050 35042 lineto -stroke -150 setlinewidth -0.5 0.5 0.5 setrgbcolor -51750 14653 6050 35042 simplerect -closepath stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -8296 36175 moveto -P$t -7806 36175 moveto -P$u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -8846 35808 moveto -P$2z -8784 35963 moveto -P$30 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -9550 36389 moveto -P$31 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -10546 35808 moveto -P$2z -10484 35963 moveto -P$30 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -11242 35808 moveto -P$v -11270 36205 moveto -P$w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -12148 35808 moveto -P$32 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -17385 36591 moveto -P$1p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18029 36418 moveto -P$1q -17875 35908 moveto -P$1r -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18500 35777 moveto -P$33 -18617 35936 moveto -P$34 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19200 35777 moveto -P$33 -19317 35936 moveto -P$34 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20071 35807 moveto -P$1u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20787 35818 moveto -P$35 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21179 36429 moveto -P$36 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21700 35752 moveto -P$37 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22726 36429 moveto -P$38 -22782 36297 moveto -P$39 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23482 35807 moveto -P$1z -23484 35922 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24271 35807 moveto -P$1u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25229 36418 moveto -P$1q -25075 35908 moveto -P$1r -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25700 35955 moveto -P$21 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26489 36297 moveto -P$25 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26818 35582 moveto -P$26 -26900 35818 moveto -P$27 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27581 36116 moveto -P$3a -27167 36116 moveto -P$3b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28076 35807 moveto -P$1s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28378 36479 moveto -P$2a -fill -0.25 0.25 0.25 setrgbcolor -newpath -30000 38983 moveto -1000 400 rlineto --1000 400 rlineto -400 -400 rlineto -30000 38983 lineto -closepath eofill -150 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -30000 38983 moveto -1000 400 rlineto --1000 400 rlineto -400 -400 rlineto -30000 38983 lineto -closepath stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -13900 39383 moveto -16700 0 rlineto -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18573 37963 moveto -P$1b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19225 38094 moveto -P$1f -19257 38466 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19995 38093 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20740 38815 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21329 38093 moveto -P$z -21328 38186 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21875 38802 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22001 38504 moveto +41860 21655 moveto P$1h fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -23057 38802 moveto -P$13 -22807 38130 moveto -P$14 +42679 21340 moveto +P$t +42678 21433 moveto +P$u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -23595 38093 moveto -P$y +43390 22062 moveto +P$z fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -24381 38194 moveto -P$1i +43825 21351 moveto +P$2i fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -24785 38093 moveto +44964 21857 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45379 21340 moveto +P$t +45378 21433 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45925 22049 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +46525 21302 moveto +P$1e +46721 21435 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47479 21340 moveto +P$t +47478 21433 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47968 21091 moveto +P$11 +48025 21352 moveto +P$2j +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +33895 23110 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +34625 23112 moveto +P$1c +34657 23484 moveto +P$2k +34432 22934 moveto +P$2l +34676 22934 moveto +P$2m +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +35340 23832 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +35775 23121 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +36914 23627 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +37293 23738 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +37829 23110 moveto +P$t +37828 23204 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39025 23110 moveto +P$2n +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40303 23571 moveto +P$2c +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40518 22862 moveto +P$11 +40575 23123 moveto P$12 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -25225 38094 moveto -P$1f -25257 38466 moveto -P$1g +41525 23110 moveto +P$2n fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -25907 38093 moveto +42542 23123 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42875 23820 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43325 23112 moveto +P$1c +43357 23484 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43993 23738 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44318 22862 moveto +P$11 +44375 23123 moveto +P$12 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45165 23470 moveto +P$13 +44639 23470 moveto +P$14 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45695 23110 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +46614 23627 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47214 23627 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47640 23832 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +48075 23121 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +49085 23110 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +49318 22862 moveto +P$11 +49375 23123 moveto +P$12 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +49793 23738 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +50293 23738 moveto +P$17 +fill +0.93 0.93 0.93 setrgbcolor +newpath +6050 25901 moveto +15550 25901 lineto +15550 26871 lineto +14550 27871 lineto +6050 27871 lineto +6050 25901 lineto +closepath eofill +150 setlinewidth +0.5 0.5 0.5 setrgbcolor +newpath +6050 25901 moveto +15550 25901 lineto +15550 26871 lineto +14550 27871 lineto +6050 27871 lineto +6050 25901 lineto +stroke +150 setlinewidth +0.5 0.5 0.5 setrgbcolor +51750 14653 6050 25901 simplerect +closepath stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +8296 27034 moveto +P$2o +7806 27034 moveto +P$2p +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +8846 26667 moveto +P$2q +8784 26821 moveto +P$2r +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +9550 27248 moveto +P$2s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +10546 26667 moveto +P$2q +10484 26821 moveto +P$2r +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +11242 26667 moveto P$1j -25923 38188 moveto +11270 27064 moveto P$1k fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -26729 38093 moveto -P$z -26728 38186 moveto -P$1l +12148 26667 moveto +P$2t +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +17385 27450 moveto +P$1n +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18029 27276 moveto +P$2u +17875 26767 moveto +P$2v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18500 26636 moveto +P$22 +18617 26795 moveto +P$23 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19200 26636 moveto +P$22 +19317 26795 moveto +P$23 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20071 26665 moveto +P$1x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20787 26676 moveto +P$2w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21179 27287 moveto +P$2x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21700 26611 moveto +P$2y +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22726 27287 moveto +P$2z +22782 27156 moveto +P$30 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23482 26665 moveto +P$1r +23484 26781 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24271 26665 moveto +P$1x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25229 27276 moveto +P$2u +25075 26767 moveto +P$2v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25700 26814 moveto +P$24 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26489 27156 moveto +P$28 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26818 26440 moveto +P$1p +26900 26676 moveto +P$1q +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27581 26975 moveto +P$1v +27167 26975 moveto +P$1w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +28076 26665 moveto +P$31 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +28378 27337 moveto +P$2b fill 0.25 0.25 0.25 setrgbcolor newpath -50500 42154 moveto +30000 29842 moveto 1000 400 rlineto -1000 400 rlineto 400 -400 rlineto -50500 42154 lineto +30000 29842 lineto closepath eofill -100 setlinewidth +150 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -50500 42154 moveto +30000 29842 moveto 1000 400 rlineto -1000 400 rlineto 400 -400 rlineto -50500 42154 lineto +30000 29842 lineto closepath stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32200 42554 moveto +13900 30242 moveto +16700 0 rlineto +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18407 29661 moveto +P$x +18157 28989 moveto +P$y +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18725 28914 moveto +P$1e +18921 29047 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19525 28914 moveto +P$1e +19721 29047 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20535 28951 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21292 28964 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21790 29673 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22225 28962 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23175 28953 moveto +P$1c +23207 29325 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23945 28951 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24731 29053 moveto +P$1i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25135 28951 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25575 28953 moveto +P$1c +25607 29325 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26257 28951 moveto +P$1a +26273 29047 moveto +P$1b +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27079 28951 moveto +P$t +27078 29045 moveto +P$1g +fill +0.25 0.25 0.25 setrgbcolor +newpath +50500 33012 moveto +1000 400 rlineto +-1000 400 rlineto +400 -400 rlineto +50500 33012 lineto +closepath eofill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +50500 33012 moveto +1000 400 rlineto +-1000 400 rlineto +400 -400 rlineto +50500 33012 lineto +closepath stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32200 33412 moveto 18900 0 rlineto stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -36253 41724 moveto -P$2b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36643 41891 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37175 41265 moveto -P$1f -37207 41637 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37843 41891 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38692 41276 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39364 41780 moveto +36253 32583 moveto P$2c fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -40075 41265 moveto -P$1f -40107 41637 moveto -P$1g +36643 32750 moveto +P$10 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -41092 41276 moveto -P$11 +37175 32124 moveto +P$1c +37207 32495 moveto +P$1d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -41631 41365 moveto +37843 32750 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +38692 32135 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39364 32639 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40075 32124 moveto +P$1c +40107 32495 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41092 32135 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41631 32224 moveto P$1i fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -42287 41973 moveto -P$3c +42287 32831 moveto +P$32 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -42657 41985 moveto -P$2d -42675 41891 moveto +42657 32844 moveto P$2e +42675 32750 moveto +P$2f fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -43325 41973 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43779 41263 moveto -P$z -43778 41357 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44964 41780 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45379 41263 moveto -P$z -45378 41357 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46043 41891 moveto +43325 32831 moveto P$16 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -46760 41973 moveto +43779 32122 moveto +P$t +43778 32216 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44964 32639 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45379 32122 moveto +P$t +45378 32216 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +46043 32750 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +46760 32831 moveto P$2g fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -47179 41263 moveto -P$z -47178 41357 moveto -P$10 +47179 32122 moveto +P$t +47178 32216 moveto +P$u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -47945 41263 moveto +47945 32122 moveto P$2h fill 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32300 45724 moveto +32300 36583 moveto 1000 -400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32300 45724 moveto +32300 36583 moveto 1000 400 rlineto stroke 100 setlinewidth 0.25 0.25 0.25 setrgbcolor newpath -32200 45724 moveto +32200 36583 moveto 48{ 200 0 rlineto 200 0 rmoveto @@ -4862,1404 +4495,1316 @@ stroke [] 0 setdash 0 0 0 setrgbcolor newpath -35192 45143 moveto -P$2f -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -35892 44446 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36564 44951 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36943 45062 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37475 44435 moveto -P$1f -37507 44807 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38245 44434 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38957 45156 moveto -P$2d -38975 45062 moveto -P$2e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39964 44951 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40560 44749 moveto -P$1m -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41379 44434 moveto -P$z -41378 44528 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42090 45156 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42525 44445 moveto -P$2i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43664 44951 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44079 44434 moveto -P$z -44078 44528 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44625 45143 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45375 44435 moveto -P$1f -45407 44807 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46392 44446 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46931 44535 moveto -P$1i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47587 45143 moveto -P$3c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47957 45156 moveto -P$2d -47975 45062 moveto -P$2e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -48625 45143 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -49079 44434 moveto -P$z -49078 44528 moveto -P$1l -fill -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -14000 48895 moveto -1000 -400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -14000 48895 moveto -1000 400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -13900 48895 moveto -43{ -200 0 rlineto -200 0 rmoveto -} repeat -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -15542 47604 moveto -P$3d -15521 47700 moveto -P$3e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -16615 47964 moveto -P$19 -16089 47964 moveto -P$1a -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -17264 48122 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -17468 47356 moveto -P$17 -17525 47617 moveto +35192 36002 moveto P$18 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -17943 48233 moveto -P$16 +35892 35305 moveto +P$v fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -18268 47356 moveto -P$17 -18325 47617 moveto -P$18 +36564 35810 moveto +P$2d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -18664 48314 moveto -P$3f -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19479 47604 moveto -P$z -19478 47698 moveto +36943 35921 moveto P$10 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -20807 48314 moveto -P$13 -20557 47642 moveto -P$14 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21125 47567 moveto -P$2j -21321 47700 moveto -P$2k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21925 47567 moveto -P$2j -22121 47700 moveto -P$2k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22935 47604 moveto -P$12 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23692 47617 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24190 48326 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24625 47615 moveto -P$2i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25575 47606 moveto -P$1f -25607 47978 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26345 47604 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27043 48233 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27760 47920 moveto -P$1m -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28915 47964 moveto -P$19 -28389 47964 moveto -P$1a -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29435 47604 moveto -P$12 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29843 48233 moveto +37475 35294 moveto +P$1c +37507 35666 moveto P$1d fill -0.93 0.93 0.93 setrgbcolor -newpath -6050 51095 moveto -13350 51095 lineto -13350 52065 lineto -12350 53065 lineto -6050 53065 lineto -6050 51095 lineto -closepath eofill -150 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -6050 51095 moveto -13350 51095 lineto -13350 52065 lineto -12350 53065 lineto -6050 53065 lineto -6050 51095 lineto -stroke -150 setlinewidth -0.5 0.5 0.5 setrgbcolor -51750 8311 6050 51095 simplerect -closepath stroke 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -7845 52584 moveto -P$1n +38245 35293 moveto +P$s fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -8696 52228 moveto -P$t -8206 52228 moveto -P$u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -9496 52228 moveto -P$t -9006 52228 moveto -P$u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -10046 51861 moveto -P$2z -9984 52016 moveto -P$3g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -15185 52644 moveto -P$1p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -15593 51685 moveto -P$3h -15612 51997 moveto -P$3i -15515 52128 moveto -P$3j -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -16118 51635 moveto -P$26 -16200 51871 moveto -P$27 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -16754 52292 moveto -P$3k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -17629 52471 moveto -P$1q -17475 51961 moveto -P$1r -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18100 52008 moveto -P$21 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18889 52350 moveto -P$25 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19218 51635 moveto -P$26 -19300 51871 moveto -P$27 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19981 52169 moveto -P$3a -19567 52169 moveto -P$3b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20476 51860 moveto -P$1s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21278 52471 moveto -P$3l -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22281 52169 moveto -P$3a -21867 52169 moveto -P$3b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22600 52471 moveto -P$3m -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22900 52471 moveto -P$3m -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23454 52292 moveto -P$3k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23789 52350 moveto -P$25 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24282 51858 moveto -P$1v -24304 52194 moveto -P$3n -24098 51716 moveto -P$3o -24314 51716 moveto -P$3p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25076 51860 moveto -P$1s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -25626 52482 moveto -P$38 -25682 52350 moveto -P$39 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26218 51635 moveto -P$26 -26300 51871 moveto -P$27 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -26631 51860 moveto -P$1x -26682 51992 moveto -P$1y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -27682 51858 moveto -P$1v -27704 52194 moveto -P$1w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28687 51871 moveto -P$35 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29254 52292 moveto -P$3k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29531 51860 moveto -P$1x -29582 51992 moveto -P$1y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -30282 51860 moveto -P$1z -30284 51975 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -31068 51992 moveto -P$1t -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -31687 51871 moveto -P$3q -31228 51716 moveto -P$3o -31443 51716 moveto -P$3p -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -32000 51805 moveto -P$37 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -32871 51860 moveto -P$1u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -33289 52350 moveto -P$25 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -34381 52169 moveto -P$3a -33967 52169 moveto -P$3b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -34726 52482 moveto -P$38 -34782 52350 moveto -P$39 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -35482 51860 moveto -P$1z -35484 51975 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36271 51860 moveto -P$1u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36982 51858 moveto -P$1v -37004 52194 moveto -P$1w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37600 51830 moveto -P$33 -37717 51989 moveto -P$34 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38331 51860 moveto -P$1x -38382 51992 moveto -P$1y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39082 51860 moveto -P$1z -39084 51975 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39700 51830 moveto -P$33 -39817 51989 moveto -P$34 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40571 51860 moveto -P$1u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41281 52169 moveto -P$3a -40867 52169 moveto -P$3b -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41679 52482 moveto -P$36 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42200 51805 moveto -P$37 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42982 51860 moveto -P$1z -42984 51975 moveto -P$20 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43776 51860 moveto -P$1s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44518 51635 moveto -P$26 -44600 51871 moveto -P$27 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45154 52292 moveto -P$3k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45489 52350 moveto -P$25 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45678 52532 moveto -P$2a -fill -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -32300 55436 moveto -1000 -400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -32300 55436 moveto -1000 400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -32200 55436 moveto -48{ -200 0 rlineto -200 0 rmoveto -} repeat -200 0 rlineto -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -39343 54855 moveto -P$3r -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40179 54146 moveto -P$z -40178 54239 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40879 54146 moveto -P$z -40878 54239 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41557 54868 moveto -P$2d -41575 54774 moveto +38957 36015 moveto P$2e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42225 54108 moveto -P$2j -42421 54241 moveto -P$2k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43175 54147 moveto -P$1f -43207 54519 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43890 54868 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44323 54383 moveto -P$3s -fill -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -14000 58607 moveto -1000 -400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -14000 58607 moveto -1000 400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -13900 58607 moveto -43{ -200 0 rlineto -200 0 rmoveto -} repeat -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19943 58026 moveto -P$3r -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20779 57316 moveto -P$z -20778 57410 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21479 57316 moveto -P$z -21478 57410 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22157 58038 moveto -P$2d -22175 57944 moveto -P$2e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -22825 57279 moveto -P$2j -23021 57412 moveto -P$2k -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -23775 57318 moveto -P$1f -23807 57690 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24490 58038 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -24923 57554 moveto -P$3s -fill -0.93 0.93 0.93 setrgbcolor -59800 300 0 62292 simplerect -closepath eofill -100 setlinewidth -0.93 0.93 0.93 setrgbcolor -59800 300 0 62292 simplerect -closepath stroke -100 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -0 62292 moveto -59800 0 rlineto -stroke -100 setlinewidth -0.5 0.5 0.5 setrgbcolor -newpath -0 62592 moveto -59800 0 rlineto -stroke -0.93 0.93 0.93 setrgbcolor -5600 2570 27100 61107 simplerect -closepath eofill -200 setlinewidth -0.5 0.5 0.5 setrgbcolor -5600 2570 27100 61107 simplerect -closepath stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28087 61968 moveto -P$3t -28073 62129 moveto -P$3u -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -28993 62173 moveto -P$2r -28995 62312 moveto -P$2s -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -29996 62685 moveto -P$3v -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -30753 62187 moveto -P$3w -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -31195 62896 moveto -P$1n -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -31700 62754 moveto -P$1o -fill -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -32300 67048 moveto -1000 -400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -32300 67048 moveto -1000 400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -32200 67048 moveto -48{ -200 0 rlineto -200 0 rmoveto -} repeat -200 0 rlineto -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -35192 66467 moveto +38975 35921 moveto P$2f fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -35892 65770 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36564 66275 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -36943 66386 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -37475 65759 moveto -P$1f -37507 66131 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38245 65757 moveto -P$y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -38957 66479 moveto +39964 35810 moveto P$2d -38975 66386 moveto -P$2e fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -39964 66275 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -40560 66073 moveto -P$1m -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -41379 65757 moveto -P$z -41378 65851 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42090 66479 moveto -P$15 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -42525 65768 moveto -P$2i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -43664 66275 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44079 65757 moveto -P$z -44078 65851 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -44625 66467 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -45375 65759 moveto -P$1f -45407 66131 moveto -P$1g -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46392 65770 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -46931 65859 moveto -P$1i -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47587 66467 moveto -P$3c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -47957 66479 moveto -P$2d -47975 66386 moveto -P$2e -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -48625 66467 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -49079 65757 moveto -P$z -49078 65851 moveto -P$1l -fill -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -14000 70218 moveto -1000 -400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -14000 70218 moveto -1000 400 rlineto -stroke -100 setlinewidth -0.25 0.25 0.25 setrgbcolor -newpath -13900 70218 moveto -43{ -200 0 rlineto -200 0 rmoveto -} repeat -stroke -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -18432 68709 moveto -P$3x -18425 68811 moveto -P$3y -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -19229 68928 moveto -P$z -19228 69022 moveto -P$10 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20114 69445 moveto -P$2c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -20842 68941 moveto -P$11 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21175 69637 moveto -P$1c -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21593 69556 moveto -P$16 -fill -0 setlinewidth -[] 0 setdash -0 0 0 setrgbcolor -newpath -21801 69339 moveto +40560 35608 moveto P$1h fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -22857 69637 moveto -P$13 -22607 68966 moveto -P$14 +41379 35293 moveto +P$t +41378 35386 moveto +P$u fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -23395 68928 moveto -P$y +42090 36015 moveto +P$z fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -24093 69556 moveto +42525 35304 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43664 35810 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44079 35293 moveto +P$t +44078 35386 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44625 36002 moveto P$16 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -24810 69244 moveto -P$1m +45375 35294 moveto +P$1c +45407 35666 moveto +P$1d fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -25965 69287 moveto -P$19 -25439 69287 moveto -P$1a +46392 35305 moveto +P$v fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -26485 68928 moveto +46931 35394 moveto +P$1i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47587 36002 moveto +P$32 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47957 36015 moveto +P$2e +47975 35921 moveto +P$2f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +48625 36002 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +49079 35293 moveto +P$t +49078 35386 moveto +P$1g +fill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +14000 39754 moveto +1000 -400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +14000 39754 moveto +1000 400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +13900 39754 moveto +43{ +200 0 rlineto +200 0 rmoveto +} repeat +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +15542 38463 moveto +P$33 +15521 38559 moveto +P$34 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +16615 38823 moveto +P$13 +16089 38823 moveto +P$14 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +17264 38980 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +17468 38215 moveto +P$11 +17525 38476 moveto P$12 fill 0 setlinewidth [] 0 setdash 0 0 0 setrgbcolor newpath -26893 69556 moveto +17943 39091 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18268 38215 moveto +P$11 +18325 38476 moveto +P$12 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18664 39173 moveto +P$19 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19479 38463 moveto +P$t +19478 38557 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20807 39173 moveto +P$x +20557 38501 moveto +P$y +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21125 38426 moveto +P$1e +21321 38559 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21925 38426 moveto +P$1e +22121 38559 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22935 38463 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23692 38476 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24190 39185 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24625 38474 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25575 38465 moveto +P$1c +25607 38837 moveto P$1d fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26345 38463 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27043 39091 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27760 38779 moveto +P$1h +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +28915 38823 moveto +P$13 +28389 38823 moveto +P$14 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +29435 38463 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +29843 39091 moveto +P$17 +fill +0.93 0.93 0.93 setrgbcolor +newpath +6050 41954 moveto +13350 41954 lineto +13350 42924 lineto +12350 43924 lineto +6050 43924 lineto +6050 41954 lineto +closepath eofill +150 setlinewidth +0.5 0.5 0.5 setrgbcolor +newpath +6050 41954 moveto +13350 41954 lineto +13350 42924 lineto +12350 43924 lineto +6050 43924 lineto +6050 41954 lineto +stroke +150 setlinewidth +0.5 0.5 0.5 setrgbcolor +51750 8311 6050 41954 simplerect +closepath stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +7845 43443 moveto +P$1l +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +8696 43087 moveto +P$2o +8206 43087 moveto +P$2p +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +9496 43087 moveto +P$2o +9006 43087 moveto +P$2p +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +10046 42720 moveto +P$2q +9984 42874 moveto +P$35 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +15185 43503 moveto +P$1n +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +15593 42543 moveto +P$36 +15612 42856 moveto +P$37 +15515 42987 moveto +P$38 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +16118 42493 moveto +P$1p +16200 42729 moveto +P$1q +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +16754 43151 moveto +P$39 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +17629 43329 moveto +P$2u +17475 42820 moveto +P$2v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18100 42867 moveto +P$24 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +18889 43209 moveto +P$28 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19218 42493 moveto +P$1p +19300 42729 moveto +P$1q +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19981 43028 moveto +P$1v +19567 43028 moveto +P$1w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20476 42718 moveto +P$31 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21278 43329 moveto +P$1u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22281 43028 moveto +P$1v +21867 43028 moveto +P$1w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22600 43329 moveto +P$1t +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22900 43329 moveto +P$1t +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23454 43151 moveto +P$39 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23789 43209 moveto +P$28 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24282 42717 moveto +P$20 +24304 43053 moveto +P$3a +24098 42575 moveto +P$3b +24314 42575 moveto +P$3c +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25076 42718 moveto +P$31 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25626 43340 moveto +P$2z +25682 43209 moveto +P$30 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26218 42493 moveto +P$1p +26300 42729 moveto +P$1q +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26631 42718 moveto +P$1y +26682 42851 moveto +P$1z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +27682 42717 moveto +P$20 +27704 43053 moveto +P$21 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +28687 42729 moveto +P$2w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +29254 43151 moveto +P$39 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +29531 42718 moveto +P$1y +29582 42851 moveto +P$1z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +30282 42718 moveto +P$1r +30284 42834 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +31068 42851 moveto +P$3d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +31687 42729 moveto +P$3e +31228 42575 moveto +P$3b +31443 42575 moveto +P$3c +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +32000 42664 moveto +P$2y +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +32871 42718 moveto +P$1x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +33289 43209 moveto +P$28 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +34381 43028 moveto +P$1v +33967 43028 moveto +P$1w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +34726 43340 moveto +P$2z +34782 43209 moveto +P$30 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +35482 42718 moveto +P$1r +35484 42834 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +36271 42718 moveto +P$1x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +36982 42717 moveto +P$20 +37004 43053 moveto +P$21 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +37600 42689 moveto +P$22 +37717 42848 moveto +P$23 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +38331 42718 moveto +P$1y +38382 42851 moveto +P$1z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39082 42718 moveto +P$1r +39084 42834 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39700 42689 moveto +P$22 +39817 42848 moveto +P$23 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40571 42718 moveto +P$1x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41281 43028 moveto +P$1v +40867 43028 moveto +P$1w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41679 43340 moveto +P$2x +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42200 42664 moveto +P$2y +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42982 42718 moveto +P$1r +42984 42834 moveto +P$1s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43776 42718 moveto +P$31 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44518 42493 moveto +P$1p +44600 42729 moveto +P$1q +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45154 43151 moveto +P$39 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45489 43209 moveto +P$28 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45678 43390 moveto +P$2b +fill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32300 46295 moveto +1000 -400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32300 46295 moveto +1000 400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32200 46295 moveto +48{ +200 0 rlineto +200 0 rmoveto +} repeat +200 0 rlineto +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39343 45714 moveto +P$3f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40179 45004 moveto +P$t +40178 45098 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40879 45004 moveto +P$t +40878 45098 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41557 45726 moveto +P$2e +41575 45633 moveto +P$2f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42225 44967 moveto +P$1e +42421 45100 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43175 45006 moveto +P$1c +43207 45378 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43890 45726 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44323 45242 moveto +P$3g +fill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +14000 49465 moveto +1000 -400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +14000 49465 moveto +1000 400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +13900 49465 moveto +43{ +200 0 rlineto +200 0 rmoveto +} repeat +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19943 48884 moveto +P$3f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20779 48175 moveto +P$t +20778 48269 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21479 48175 moveto +P$t +21478 48269 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22157 48897 moveto +P$2e +22175 48803 moveto +P$2f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22825 48138 moveto +P$1e +23021 48270 moveto +P$1f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23775 48177 moveto +P$1c +23807 48548 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24490 48897 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24923 48413 moveto +P$3g +fill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32300 53336 moveto +1000 -400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32300 53336 moveto +1000 400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +32200 53336 moveto +48{ +200 0 rlineto +200 0 rmoveto +} repeat +200 0 rlineto +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +35192 52755 moveto +P$18 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +35892 52058 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +36564 52563 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +36943 52674 moveto +P$10 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +37475 52047 moveto +P$1c +37507 52419 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +38245 52046 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +38957 52768 moveto +P$2e +38975 52674 moveto +P$2f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +39964 52563 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +40560 52361 moveto +P$1h +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +41379 52046 moveto +P$t +41378 52139 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42090 52768 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +42525 52057 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +43664 52563 moveto +P$2d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44079 52046 moveto +P$t +44078 52139 moveto +P$u +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +44625 52755 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +45375 52047 moveto +P$1c +45407 52419 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +46392 52058 moveto +P$v +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +46931 52147 moveto +P$1i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47587 52755 moveto +P$32 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +47957 52768 moveto +P$2e +47975 52674 moveto +P$2f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +48625 52755 moveto +P$16 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +49079 52046 moveto +P$t +49078 52139 moveto +P$1g +fill +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +14000 56507 moveto +1000 -400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +14000 56507 moveto +1000 400 rlineto +stroke +100 setlinewidth +0.25 0.25 0.25 setrgbcolor +newpath +13900 56507 moveto +43{ +200 0 rlineto +200 0 rmoveto +} repeat +stroke +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19245 55926 moveto +P$3h +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +19745 55216 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +20457 55938 moveto +P$2e +20475 55844 moveto +P$2f +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +21345 55216 moveto +P$s +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22075 55218 moveto +P$1c +22107 55590 moveto +P$1d +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +22790 55938 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +23225 55227 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24235 55216 moveto +P$w +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24468 54968 moveto +P$11 +24525 55229 moveto +P$12 +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +24990 55938 moveto +P$z +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +25425 55227 moveto +P$2i +fill +0 setlinewidth +[] 0 setdash +0 0 0 setrgbcolor +newpath +26343 55844 moveto +P$17 +fill 200 setlinewidth 0.69 0.69 0.69 setrgbcolor newpath -12500 71718 moveto +12500 58007 moveto 1800 1800 rlineto stroke 200 setlinewidth 0.69 0.69 0.69 setrgbcolor newpath -12500 73518 moveto +12500 59807 moveto 1800 -1800 rlineto stroke grestore diff --git a/uml/plugin_connectivity.puml b/uml/plugin_connectivity.puml index 1060f59..830a94b 100644 --- a/uml/plugin_connectivity.puml +++ b/uml/plugin_connectivity.puml @@ -11,20 +11,17 @@ participant ActorPlugin as plugin activate server activate plugin -==Goal== - [-> client: neuer ActionClient activate client -client -> server: Goal-Anfrage -server -->> client: Antwort auf Anfrage +client -> server: Zielvorgabe +server -->> client: Antwort auf Zielvorgabe -alt Anfrage akzeptiert? +alt Zielvorgabe akzeptiert? server ->> plugin: neuen Status und Ziel setzen plugin -->> server: Zustandswechsel bei\nnächstem Simulationsschritt -== Feedback== group opt par [Abbruch der Aktion] -client->server: Cancel-Anfrage +client->server: Abbruchanfrage server->plugin: Status auf Idle setzen plugin -->> server: Zustandswechsel auf Idle server-->>client: positive Abbruchantwort @@ -33,9 +30,8 @@ loop Bis Aktion vollständig ausgeführt oder abgebrochen ist plugin -->> server: Feedback server -->> client: Feedback end -==Result== plugin -->> server: Zustandswechsel auf Idle -server -->> client: Result-Antwort +server -->> client: Endnachricht end destroy client @enduml \ No newline at end of file