This repository has been archived on 2024-10-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Bachelor-Arbeit-Latex/060_implementierung.tex
T
kleiax 193f1aae00 - evaluation ntrip revision
- first spelling and grammar fixes
2024-08-01 14:05:34 +02:00

387 lines
48 KiB
TeX

\chapter{Implementierung}
Im folgenden Teil dieser Arbeit wird auf den Aufbau der Basisstation eingegangen, dabei wird der mechanische Aufbau sowie die Implementierung und Einrichtung der Station erläutert. Außerdem werden die Erweiterungen des Rovers ausführlich beschrieben, dazu gehören die Implementierung weiterer Softwarekomponenten sowie der Einbau des GY-521 Moduls (siehe Abschnitt \ref{sec:gyroskop}).
\section{Basisstation}
\label{sec:Basisstation}
Für die Errichtung der Referenzstation stellte sich zunächst die Frage, wie das System aufgebaut werden soll. Dabei sind die bereits beschriebenen Anforderungen im Abschnitt \ref{sec:referenzstation_req} entstanden. Um das System den Anforderungen entsprechend erstellen zu können wurde die Hardwareauswahl in dem vorangegangenen Kapitel \ref{cha:Hardwareauswahl} bereits beschrieben. Deshalb wird in diesem Abschnitt die noch fehlende Installation und Konfiguration der Komponenten thematisiert. Darüber hinaus werden für die vollständige Montage Formteile benötigt, welche mit einem 3D-Drucker produziert werden sollen.
\subsection{Installation Betriebssystem}
Im ersten Schritt muss der Server betriebsbereit gemacht werden, dafür muss ein Betriebssystem installiert werden. Dazu soll das in Unterabschnitt \ref{ssec:debian} beschriebene Debian genutzt werden.
\par
Da der Server über übliche Anschlüsse für einen Monitor verfügt, kann die Installation über den Installationsassistenten mittels Tastatur und Bildschirm durchgeführt werden. Dafür wurde die iso-Datei von Debian so auf einen USB-Stick geschrieben, dass dieser Bootfähig ist. Während der Installation wurden die meisten Einstellungen bei ihrem Standard belassen.
\par
Nach der erfolgreichen Installation des Betriebssystems wurde sich zunächst als root Benutzer angemeldet, um die ersten grundlegenden Einstellungen zu tätigen.
\subsubsection{Netzwerk}
Nach der Installation bezieht der Server seine Netzwerkkonfiguration über einen DHCP-Server. Für eine feste Installation eines Servers ist die manuelle Konfiguration der Netzwerkschnittstelle dringend empfohlen, damit die IP-Adresse zu jeder Zeit persistent und bekannt ist. Dafür müssen zwei Dateien editiert werden und der Name des Netzwerkinterfaces muss bekannt sein.
Die erste Datei mit dem Pfad \url{/etc/network/interfaces} enthält die Konfigurationen aller auf dem System verfügbaren Interfaces. Da der Server lediglich über ein Interface verfügt, kann in der Datei auch der Name des Interfaces abgelesen werden. !!!Im folgenden Dings ist die Conf:!!!
Die zweite Datei ist unter dem Pfad \url{/etc/resolv.conf} zu finden. In diese Datei müssen die zu benutzen DNS-Server eingetragen werden. In jeder Zeile kann ein Eintrag getätigt werden. In diesem Fall nach dem Muster \flqq nameserver xxx.xxx.xxx.xxx\frqq. In dem Netz der FH-Dortmund lauten die IP-Adressen der Nameserver \mintinline{text}|172.22.1.10| und \mintinline{text}|172.22.1.20|
\par
Die Netzwerkkonfiguration wurde durch einen Mitarbeiter im Hardwarelabor der FH-Dortmund festgelegt und im System eingepflegt. Wenn die Bearbeitung der Datei abgeschlossen ist, muss das Netzwerkinterface neu gestartet werden. Dies kann mit dem Befehl !!!command!!! oder einem Neustart des Computers erfolgen.
\subsubsection{sudo}
Sudo ist ein Programm aus den Paketquellen von Debian, dass es anderen Nutzern erlauben kann Befehle mit root-Rechten auszuführen. Diese Vorgehensweise empfiehlt sich, damit nicht alle Befehle automatisch mit root-Rechten ausgeführt werden und das vollständige System über ein normales Benutzerkonto gesteuert werden kann. Das Paket kann mit dem Paketverwaltungstool \mintinline{bash}|apt-get| installiert werden. Davor sollten die Paketquellen jedoch aktualisiert und möglich Paketupdates installiert werden. Um die Aktualisierung und die Installation auszuführen müssen diese Befehle ausgeführt werden:
\begin{minted}[linenos, gobble=5]{bash}
apt-get update
apt-get upgrade
apt-get install sudo
\end{minted}
Im Anschluss müssen die Benutzer welche neben dem root-Benutzer ebenfalls Befehle mit erweiterten Rechten ausführen können sollen in die Benutzergruppe \mintinline{text}|sudo???| hinzugefügt werden. Für den bei der Installation automatisch erstellen Benutzer \mintinline{text}|rtk| sieht der Befehl wie folgt aus: \mintinline{text}|usermod -aG sudo rtk???|.
Danach wird der root-Account abgemeldet und nur noch der rtk-Benutzer verwendet. Befehle können nun mit einem vorangestellten \mintinline{bash}|sudo| als Administrator ausgeführt werden.
\subsubsection{ssh-server}
Der SSH-Server wird ebenfalls über die Paketquellen installiert, der Paketname entspricht der Überschrift dieses Abschnitts. Mit einem SSH-Server wird die Verwaltung des System über das Netzwerk ermöglicht und damit der Zugriff auf das Terminal erheblich zu vereinfacht. Der Server kann in mit den Standardeinstellungen betrieben werden, für eine erhöhte Sicherheit wird jedoch der Login mit dem root-Account verboten. Dafür wird in der Konfigurationsdatei (\url{/etc/ssh/sshd_config}) die Zeile \mintinline{text}|PermitRootLogin no| ergänzt und der SSH-Server anschließend mit \mintinline{bash}|sudo service sshd restart| neugestartet.
\par
Ab diesem Zeitpunkt der Installation kann der Server headless betrieben werden. Es ist nur noch eine die Netzwerkverbindung und die Stromversorgung notwendig. Zum einloggen wird ein SSH-Client, die Zugangsdaten und die Adresse des Servers benötigt.
\subsection{ser2net vorbereiten}
Die Konfiguration der GNSS-Module von U-Blox lässt sich am einfachsten mit dem u-center (siehe Abschnitt \ref{sssec:u-blox}) erledigen. Da das u-center ausschließlich unter Windows verfügbar und ein Programm mit grafischer Oberfläche ist, kann es nicht auf dem Server ausgeführt werden. Allerdings ist es nicht praktikabel das GNSS-Modul aus dem System der Referenzstation zu entfernen, um es an einem anderen Computer zu konfigurieren. Deshalb bietet sich die Installation von ser2net an, damit die Verbindung zwischen dem u-center und dem GNSS-Modul über eine Netzwerkverbindung aufgebaut werden kann.
\par
Die Installation erfolgt über die Paketquellen mit \mintinline{bash}|sudo apt-get install ser2net|. Das Programm wird dem Betriebssystem als Service hinzugefügt und läuft damit ständig. Da die Verbindung nur zur Verfügung stehen soll wenn diese auch benötigt wird, kann der automatische Start des Service beim Bootvorgang mit dem Befehl
\begin{minted}[linenos, gobble=4]{bash}
sudo systemctl disable ser2net
\end{minted}
deaktiviert werden. Die nächsten beiden Befehle sind zum stoppen und starten des Services. Nach der Deaktivierung läuft der Service weiter bis der Computer neugestartet wird oder der Service mit dem ersten Befehl gestoppt wird.
\begin{minted}[linenos, gobble=4]{bash}
sudo systemctl stop ser2net
sudo systemctl start ser2net
\end{minted}
Um ein serielles Interface über ser2net im Netzwerk freizugeben muss dieses in der Konfigurationsdatei (\url{/etc/ser2net.yaml}) deklariert werden. Dafür muss der Gerätepfad des GNSS-Moduls bekannt sein. Dieser kann herausgefunden werden indem das Modul an einen USB-Port angesteckt wird und in dem Verzeichnis \url{/dev} nach einer neuen Datei geschaut wird, welche mit \mintinline{text}|tty| beginnt. In der Konfigurationsdatei wird der folgende Yaml-Block ergänzt:
\begin{minted}[linenos, gobble=4, tabsize=4, showtabs=no]{yaml}
connection: &con0096
accepter: tcp,2000
enable: on !!!mach mal richtig hier!!!
options:
banner: *banner
kickolduser: true
telnet-brk-on-sync: true
connector: serialdev,/dev/ttyS0,9600n81,local
\end{minted}
Sollte der Service zum Zeitpunkt der Konfiguration aktiv gewesen sein, muss es mit dem genannten Befehl gestoppt werden und kann anschließend je nach Bedarf aktiviert werden. Sobald der Service aus Abschnitt \ref{ssec:pushService} aktiv ist, muss dieser gestoppt werden bevor eine Verbindung zu ser2net aufgebaut wird. Wenn dies nicht geschieht, ist es nicht vorhersehbar an welchen Service die ankommenden Daten des GNSS-Moduls geleitet werden.
\subsection{RTKLib installieren}
Die in den Grundlagen unter \ref{sssec:rtklib} beschriebene RTKLib ist nicht über die Paketquellen verfügbar und muss deshalb auf dem Server kompiliert werden. Um das Projekt von GitHub clonen zu können muss Git installiert werden. Außerdem wird als Abhängigkeit die Bibliothek \mintinline[]{text}|libpng-dev| benötigt. Der Compiler inklusive weiterer benötigter Tools wie \mintinline[]{text}|make| ist in dem Paket \mintinline[]{text}|build-essential| enthalten. Für die vollständige Installation wird die folgende Befehlsfolge in dem Home-Verzeichnis des rtk-Benutzers benötigt:
\begin{minted}[linenos, gobble=4]{bash}
sudo apt-get update
sudo apt-get install git
sudo apt-get install libpng-dev
sudo apt-get install build-essential
git clone https://github.com/rtklibexplorer/RTKLIB.git
cd RTKLIB/app/consapp/
make
make install
\end{minted}
\subsection{Dachinstallation}
Die Installation auf dem Dach wurde in ihren groben Zügen bei der in der Einleitung des Kapitels \ref{cha:Hardwareauswahl} beschriebenen Begehung des Installationsortes geplant. Von diesem Plan wurde die in dem Kapitel folgende Hardwareauswahl abgeleitet. Im ersten Schritt sollen nun alle Vorbereitungen getroffen werden, welche von dem Installationsort unabhängig sind. Im Anschluss wird die eigentliche Montage auf dem Dach vorgenommen.
\subsubsection{Befestigungen}
Die anzubringenden Komponenten benötigen Halterungen und Befestigungspunkte. Diese werden im folgenden Beschrieben:
\begin{itemize}
\item die \textbf{Antenne} soll am Ende des C-Profils welches zur Verlängerung des Pfostens dient befestigt werden. Dafür wurde ein Formteil konstruiert (siehe Abbildung !!!). Im wesentlichen besteht diesel Teil aus einem Quader, welcher in das C-Profil eingeführt werden kann. Der Quader verfügt über eine Bohrung, damit dieser mittels einer Schrauben-Mutter-Kombination am C-Profil fixiert werden kann. Am oberen Ende befindet sich ein Gewinde auf welches die Antenne aufgeschraubt werden kann,
\item der \textbf{Installationskasten} soll unterhalb des vorhandenen Kastens am Pfosten angebracht werden. Als Maße stehen der gemessene Durchmesser des Pfostens (\(90mm\)) und der aus dem Datenblatt !!!cite!!! verfügbare Lochabstand der Befestigungslöcher des Kastens. Mit diesen Werten konnte eine Halterung konstruiert werden, welche aus zwei Halbschalen besteht. Ein Halbschale verfügt über abstehende Arme mit vorhandenen Löchern für M!!!-Schrauben, an denen der Kasten befestigt werden kann. Die M!!!-Schrauben können von hinten mit der passenden Mutter gesichert werden. In die gleich Halbschale können passgenau M8-Muttern eingelegt werden. Die andere Halbschale verfügt über die Löcher und Vertiefungen um diese mit zwei M8-Schrauben an der anderen Halbschale befestigen zu können. Die Halterungen wurde für den oberen und den unteren Teil des Kastens jeweils einmal ausgedruckt. Eine Halterung ist in Abbildung !!!ref!!! zu sehen,
\item für den \textbf{Server} wird eine Halterung benötigt, damit dieser an der Hutschiene im Installationskasten befestigt werden kann. Es bot sich an die mitgelieferten Winkel und Schrauben von dem Computer in die Konstruktion mit einzubeziehen. Die Winkel sind für die Wandmontage gedacht und werden nach Herstellervorgaben auf der Rückseite des Computers befestigt, so dass nach der Montage der Winkel Befestigungspunkte neben Computer benutzbar sind. Die Winkel haben einen Versatz, der den Computer theoretisch etwas von der Wand hervorstehen lassen würde. Um die Befestigung an der Hutschiene zu ermöglichen, wurden die Winkel um \(180^\circ\) verdreht. Dadurch entsteht auf der Rückseite der Computer ein breites Trapez mit geringer Höhe. Diese Form wurde als Grundplatte für den Adapter genutzt. Auf dieser Grundplatte befinden sich neben der Aufnahme für die Hutschiene herausstehende Kegel, welche genutzt werden um den Adapter mittels der am Winkel vorgesehenen Löcher zur Wandmontage zu fixieren, !!!Bild?!!!
\item die letzte Konstruktion soll das \textbf{GNSS-Modul} ebenfalls an der Hutschiene fixieren. Das Formteil ist ein etwas in die Länge gezogene Quader. An einem Ende befindet sich der Mechanismus für die Hutschiene. Für das Modul ist eine Vertiefung mit Aussparungen für die Anschlüsse eingefügt worden. Das Modul wird durch das Einschieben einer Deckplatte gesichert. Das Formteil wird in Abbildung !!!ref!!! gezeigt.
\end{itemize}
\subsubsection{Installationskasten bestücken}
Der Installationskasten kann weitgehend vorbereitet werden. Dafür wurden zunächst ein Loch an der unteren Seite gebohrt, welches groß genug ist um ein RJ45-Stecker durchzuführen. Weiterhin wurde die Hutschiene außer mittig positioniert, damit im unteren Raum mehr Platz für Kabel bleibt. Danach wurden die beiden Halbschalen an der Rückseite des Kastens befestigt, weil die Löcher für die Befestigungen durch die Komponenten teilweise verdeckt werden. Anschließend konnten die Komponenten an der Hutschiene befestigt werden. Die Komponenten wurden rechtsbündig verbaut. Dabei wurde der PoE-Splitter links neben dem Server und das GNSS-Modul rechts neben dem Server eingehackt. Diese beiden Komponenten auf je eine Seite des Computers zu befestigen, vereinfacht die Kabelführung. Der PoE-Splitter befindet sich auf der linken Seite, weil dieser die beste Klemmwirkung an der Hutschiene aufweist und so das verrücken der anderen Komponenten verhindert.
\par
Um den Computer über den PoE-Splitter mit Strom zu versorgen wurde ein Kabel mit einem Hohlbuchsenstecker konfektioniert. Das andere Ende des Kabels wurde verzinnt und an dem Blockterminal des Splitters angebracht. Das Netzwerkkabel von dem PoE-Splitter zu dem Server konnte ebenfalls schon eingesetzt werden. Mit einem USB-C auf USB-A Kabel wurde die Verbindung zwischen dem GNSS-Modul und dem Server hergestellt. Das Antennenkabel wurde durch das gebohrte Loch geführt und an dem GNSS-Modul angeschraubt. Der vorbereitete Installationskasten wird in Abbildung !!!ref!!! dargestellt.
\par
Als weitere Vorbereitung wurden weitere benötigte Netzwerkkabel bereitgelegt und Adapter für die Antennenmontage wurde an dem C-Profil befestigt.
\subsubsection{Montage}
Die Montage began mit der Befestigung des Installationskastens, dafür wurde in je eine Halbschale ein griffiges Klebeband eingebracht, um den Halt zu verbessern. Der Kasten wurde an den Pfosten gehalten und durch die dazugehörigen Halbschalen fixiert. Daraufhin wurde die Antenne an dem C-Profil befestigt und das Antennenkabel angeschlossenen. Das C-Profil wurde an den bei der Begehung besprochen Befestigungspunkten angebracht. Das Antennenkabel wurde mit Kabelbindern an dem C-Profil befestigt.
\par
Als nächstes musste der PoE-Extender in den vorhanden Anschlusskasten eingebracht werden. Dieser wurde ebenfalls an der Hutschiene befestigt. Das von dem !!!DragiLoRaWAN-Gateway?!!! kommende Ethernetkabel wurde aus der Hutschienen-RJ45-Buchse entnommen und in mit dem ersten Ausgang des Extenders verbunden. Der Eingang wurde mit dem nun freien Port an der Hutschiene verbunden. Danach wurde kontrolliert, ob der vorhandene System wieder einsatzbereit ist. Für die letzte herzustellende Verbindung zwischen dem Poe-Extender und dem Poe-Splitter, musste das Loch in dem vorhanden Installationskasten etwas aufgebohrt werden. Danach konnte das Kabel verlegt werden, wobei die überschüssige Länge des Kabel im neuen Installationskasten aufgewickelt wurde. Durch die Betriebs-LED des Servers und den LEDs des Netzwerkinterfaces konnte schon während der Installation festgestellt werden, dass der Server mit Strom versorgt wird und einen Link aufbauen konnten.
\subsection{Antennenposition bestimmen}
Die nun folgenden Schritte wurde alle von einem Remote-Arbeitsplatz durchgeführt.
\par
Damit die Antennenposition bestimmt werden kann sind im grundlegenden drei Schritte notwendig:
\setlist{noitemsep}
\begin{enumerate}
\item Rohdaten des GNSS-Moduls aufzeichnen,
\item die Rohdaten in das RINEX-Format konvertieren
\item und die Daten von einem Post Processing Dienst auswerten lassen.
\end{enumerate}
\setlist{}
Damit die Rohdaten aufgezeichnet werden können, muss das Modul so konfiguriert werden, dass es diese ausgibt. Dafür wird das u-center und die Verbindung über ser2net genutzt. Die dafür benötigte Installation unter Windows, sowie die grundlegende Nutzung vom u-center wird im Anhang \ref{cha:winAndUcenter} beschrieben. Im u-center muss der Nachrichtentyp RAWX und RAW!!!?!!! für die USB-Schnittstelle aktiviert werden. Ob die benötigten Daten gesendet werden kann in !!!Packet-View?!!! kontrolliert werden.
\par
Die Aufzeichnung der Daten übernimmt der Kommunikations-Server der RTKLib. Das Programm heißt in der Kommandozeilenversion \mintinline[]{text}|STR2STR| und kann einen Dateneingang auf mehrere Datenausgänge übertragen. In diesem Fall werden die Daten des GNSS-Moduls in eine Datei geschrieben. Die meisten Post Processing Dienst verarbeiten bis zu 24 Stunden Aufzeichnungslänge, deshalb wird für die höchste Genauigkeit genau diese Dauer für die Einmessung verwendet. Die Länge der Aufzeichnung wird über den \mintinline[]{bash}|timeout| Befehl gesteuert. Damit die Aufzeichnung nicht als Kind-Prozess der Remote-Sitzung läuft wird das Hilfsprogramm \mintinline[]{bash}|screen| installiert, da ansonsten ein Abbruch der Verbindung auch die Aufzeichnung frühzeitig beenden würde. Aus dieser Beschreibung ergibt sich diese Befehlsfolge:
\begin{minted}[linenos, gobble=4, breaklines]{bash}
sudo apt-get update
sudo apt-get install screen
screen
cd ~
timeout 24h ./RTKLIB/app/consapp/str2str/gcc/str2str -in serial://ttyACM0:9600:8:n:1:off -out observation.ubx
\end{minted}
Die screen-Sitzung kann mit der Tastenkombinationen \keys{\ctrl + A} gefolgt von \keys{D} verlassen werden.
\par
Sobald die Aufzeichnung beendet ist, müssen die Daten in das allgemeingültige RINEX-Format umgewandelt werden. Dafür bietet die RTKLib einen RINEX Konverter an. Zur Benutzung im Terminal muss das Programm \mintinline[]{bash}|convbin| aufgerufen werden. Die Konvertierung erfolgt mit:
\begin{minted}[linenos, gobble=4, breaklines]{bash}
cd ~
./RTKLIB/app/consapp/convbin/gcc/convbin -od -os -oi -ot -ti 30 observation.ubx
\end{minted}
Für die Erklärung der verwendeten Optionen folgt ein Ausschnitt aus dem Manual der RTKLib !!!cite!!!:
\setlist{noitemsep}
\begin{itemize}[label=-]
\item od include doppler frequency in rinex obs
\item os include snr in rinex obs
\item oi include iono correction in rinex nav header
\item ot include time correction in rinex nav header
\item ti tint observation data interval (s)
\end{itemize}
\setlist{}
Die umgewandelte Datei muss als nächstes zu einem Post Processing Dienst übermittelt werden, der gewählte Dienst erhält die Daten über ein Formular im Browser, deshalb ist die einfachste Variante die Datei \url{ubservation.obs} auf einen Rechner mit einer Desktopumgebung zu kopieren. Dafür wurde die Datei mit dem Programm \mintinline[]{bash}|scp| über ssh kopiert.
\par
Nach einigen Stunden wird die Auswertung per E-Mail versandt. In dem erhaltenen Archiv befinden sich eine PDF (siehe Anhang \ref{cha:auswerungObservation}) in der die Auswertung grafisch veranschaulicht wird und neben anderen Dateien die Datei \url{observation.sum}. In dieser wird ab Zeile 69 die Position der Antenne im Erdkoordinatensystem angegeben. Zusätzlich werden geschätzt Genauigkeiten angegeben, diese liegen je nach Achse zwischen \(1,8mm\) und \(5,2mm\).
\par
Die Koordinaten für X, Y und Z müssen nun über das u-center in das GNSS-Modul programmiert werden. Dafür muss in der Konfigurationsansicht der TMODE ausgewählt werden. In den Einstellungen des TMODE muss der Modus auf \texttt{fixed} eingestellt werden, danach können die Koordinaten im gleichen Fenster eingetragen werden. Damit das Modul auch die Korrekturdaten ausgibt kann ich das Fenster zur Konfiguration der Nachrichten gewechselt werden. Dort sollten die Nachrichten für die Rohdaten wieder entfernt werden, um das Datenaufkommen zu reduzieren. Danach können die RTCM3 Nachrichten mit den Nummern 1005, 1074, 1084, 1094, 1124 und 1230 aktiviert werden. Ob die Konfiguration erfolgreich war kann wieder im Packet View Fenster kontrolliert werden. Diese Finale Konfiguration des Moduls sollte in den Flash des Moduls geschrieben werden um auch über einen neustart hinweg verfügbar zu sein. Dafür kann in der Menüleiste der Punkt !!!?!!! ausgewählt werden.
\subsection{Service einrichten}
\label{ssec:pushService}
Die von dem GNSS-Modul generierten Korrekturdaten müssen kontinuierlich an den Ntrip-Caster weitergeleitet werden. Dafür wird der bereits zuvor genutzte Kommunikationsserver der RTKLib verwendet. Als Ausgang wird anstelle der Datei nun der Ntrip-Caster angegeben.
\par
Damit die Ausgabe automatisch protokolliert wird und der Kommunikationsserver auch nach einem Neustart des Servers automatisch startet wird dem Betriebssystem ein Service hinzugefügt. Dafür muss eine Datei mit root-Rechten und der Endung \texttt{.service}, welche den Service definiert unter dem Pfad \url{/etc/systemd/system} erstellt werden. Der Inhalt der erstellten Datei \texttt{rtk.service} sieht wie folgt aus:
\begin{minted}[linenos, gobble=4, breaklines]{bash}
[Unit]
Description=Push RTCM correction data from serial to caster
After=network-online.target
[Service]
Type=simple
ExecStart=/home/rtk/pushRtcm2Caster.sh
[Install]
WantedBy=multi-user.target
\end{minted}
Das auszuführende Skript enthält zum aktuellen Zeitpunkt lediglich den Aufruf des Kommunikationsservers mit den benötigten Parametern.
\begin{minted}[linenos, gobble=4, breaklines]{bash}
#!/bin/bash
/home/rtk/RTKLIB/app/consapp/str2str/gcc/str2str -in serial://ttyACM0:9600:8:n:1:off -out ntrips://:password@rtk2go.com:2101/GER-Dortmund
\end{minted}
Anschließend muss der Service aktiviert und gestartet werden.
\begin{minted}[linenos, gobble=4, breaklines]{bash}
sudo systemctl activate rtk
sudo systemctl start rtk
\end{minted}
In den Logs kann die übermittelte Datenmenge oder auftretende Fehler betrachtet werden. Wenn der Caster die Daten akzeptiert, erscheint der zuvor bei rtk2go registrierte Mount Point \texttt{GER-Dortmund} in der Mount Point Tabelle unter \url{rtk2go.com:2101}
\section{Rover}
Die Implementierungen für den Rover beginnen mit der Integration des Gyroskops, dies umschließt den Einbau der Hardware und das einbinden der Sensorwerte in die dafür vorgesehene Komponente. Im nächsten Schritt wird der Ntrip-Client dem System hinzugefügt, damit in den folgenden Prozessen die hochgenaue Positionsbestimmung verfügbar ist. Sobald das GNSS-Modul die Korrekturdaten verarbeitet, kann die Implementierung der Verwaltung für die Routen beginnen. Danach sind alle voraussetzungen gegeben um den Modus zum Routen aufzeichnen programmieren zu können. Daraufhin können die Algorithmen für das automatische befahren der Route entwickelt werden.
\subsection{Gyroskop installieren}
Die elektrische Verbindung des Moduls wird über vier Pins hergestellt, dabei handelt es sich um die zwei I2C Leitungen sowie Masse und die Spannungsversorgung. Das Modul kann mit \(+5V\) betrieben werden. Auf der Hauptplatine sind Pin-Leisten vorhanden um weitere I2C-Module, welche mit \(+5V\) betrieben werden können, dem System hinzufügen zu können.
\par
Das Modul wird mit einer nicht bestückten Pin-Leiste geliefert, daher bestand die Möglichkeit eine gewinkelte Pin-Leiste einzulöten. Es wurde eben diese Pin-Leiste gewählt um das Modul waagerecht mit einer weiteren Platine verbinden zu können. Bei der zusätzlichen Platine handelt es sich lediglich um einen Verteiler, welcher in Abbildung !!!ref!!! gezeigt wird. Dort ist zu sehen wie der Verteiler, durch seine L-Form, an einem Querbalken mit einer Maul-Büroklammer befestigt wird. Das MPU-6050 Module wird seitlich an eine ebenfalls gewinkelte Sockel-Leiste eingesteckt. Auf der Oberseite der Platine befinden sich drei weitere Konnektoren an denen das Display und das Magnetometer angeschlossen werden. Zwei der Konnektoren sind für das Magnetometer um es entweder an den I2C-Bus des ESP32 oder an den Auxiliary-I2C-Bus des MPU-6050 anzuschließen. Auf der Unterseite der Platine ist ein Kabel angelötet welches auf die Hauptplatine gesteckt wird.
\par
Durch diese weitere Platine wurde zum einen der benötigte feste Platz für das neue Modul geschaffen und zum anderen die Möglichkeit offen gehalten den bereits verbauten Kompass nun über den MPU-6050 zu nutzen um eine 9-Achsen Sensorfusion zu ermöglichen. Der Versuch diese 9-Achsen Sensorfusion zu implementieren ist gescheitert. Der Hersteller wirbt zwar mit dieser Funktion, jedoch ist die Rechenleitung des Chips nicht ausreichend hoch genug um die Funktion umzusetzen. Daher müssten Berechnung dafür auf den ESP32 ausgelagert werden !!!cite \url{https://www.i2cdevlib.com/devices/mpu6050#help}!!!. Dieser Weg wurde aufgrund der Komplexität nicht weiter verfolgt.
\par
Die Einbindung des Sensors in den vorhandenen Programmcode erfolgte mit der bereits vorhanden \mintinline{c++}|class SensorData|. Für die Kommunikation mit dem Sensor wird die Bibliothek \texttt{I2Cdevlib-MPU6050} verwendet. Der Klasse wurden neben einer Funktionen zum Datenerhalt, die Funktion \mintinline{c++}|void enableGyroscope();| hinzugefügt. Diese erzeugt ein Objekt für den MPU6050 und initialisiert sowohl den MPU6050 als auch den verbauten Digital Motion Processor. Außerdem werden ermittelte Offsets eingestellt. Die periodische aufgerufene \mintinline{c++}|void run();| Funktion wurde ebenfalls erweitertet und überprüft jetzt im jeden Durchgang ob neue Daten des Sensors verfügbar sind und verarbeitet diese dann.
\subsection{Ntrip Client}
\label{ssec:ntripclient}
Die Implementierungen des Clients orientiert sich an dem von der RTCM herausgegebenen Paper \glqq Best Practices for NTRIP Client developers\grqq \cite{NTRIPWorkingGroup2023}. Außerdem können beide Revisionen des Protokolls mit dem Client benutzt werden. Die Revision 1 ist offiziell von der RTCM als \texttt{outdated} markiert. Der in dieser Arbeit verwendete Caster \url{rtk2go.com} gibt jedoch in seinen Statistiken an, dass \(95\%\) der eingehenden Verbindungen die Revision 1 verwenden. Zusätzlich kann durch die Implementierung beider Revisionen die angegeben Abwärtskompatibilität getestet werden. Des weiteren wird die Authentisierung mit Benutzernamen und Kennwort sowie die Übermittlung des eigenen Standorts an den Caster implementiert. Der Eigene Standort ist für Caster wichtig, welche mit einem Netz aus Referenzstationen betrieben werden. Die Implementierung erfolgt also damit der Rover auch abseits der errichteten Referenzstation von anderen Anbietern mit Korrekturdaten versorgt werden kann.
\subsubsection{Einstellungen}
Eine Instanz des Clients fordert die Adresse des Casters, den Mountpoint, die Zugangsdaten und das GNSS-Modul als Parameter für den Konstruktor, diese sind nur durch eine neue Instanz änderbar. Der Benutzername und das Passwort können ignoriert werden, wenn eine Anmeldung bei dem Caster ohne Zugangsdaten möglich ist.
\par
Eine erstellte Instanz verfügt über vier Einstellungsmöglichkeiten. Diese können entweder aktiviert oder deaktiviert werden.
\setlist{noitemsep}
\begin{itemize}[]
\item Automatisches Wiederverbinden bei Verbindungsabbrüchen \texttt{(default : true)}
\item Die eigene Position übertragen \texttt{(default : false)}
\item Ntrip Revision 1 verwenden \texttt{(default : false)}
\item Den Client selbst aktivieren \texttt{(default : true)}
\end{itemize}
\setlist{}
\subsubsection{Zustandsautomaten}
Der Ntrip Client wurde nach dem Schema eines Zustandsautomaten entworfen, welcher in Abbildung !!!ref!!! skizziert wird. Im folgenden wird auf die Funktionalitäten der einzelnen Zustände eingegangen. Die Zustände werden durch das \mintinline{c++}|enum NTRIPClientStates| definiert.
\begin{itemize}
\item \textbf{openingConnection} In diesem Zustand wird versucht die Verbindung zu dem Caster aufzubauen. Dafür wird zwischen den Revisionen von Ntrip unterschieden, ob die Position gesendet werden soll und ob Zugangsdaten angegeben worden sind. Sollte der Verbindungsaufbau scheitern wird in den \texttt{waiting} Zustand gewechselt ansonsten in den \texttt{pushingData} Zustand.
\item \textbf{pushingData} Wenn eine Verbindung zu dem Caster besteht, befindet sich der Client in diesem Zustand und leitet die empfangenen Daten an das GNSS-Modul weiter. Es kann nur in den \texttt{closingConnection} Zustand gewechselt werden.
\item \textbf{closingConnection} Sollt der Ntrip Client deaktiviert werden oder ein Timeout festgestellt werden, wird in diesen Zustand gewechselt, damit die Verbindung aus Sicht des Clients ordnungsgemäß beendet wird. Sobald die Verbindung getrennt ist wird der \texttt{waiting} Zustand aktiv.
\item \textbf{waiting} Wenn dieser Zustand betreten wird, wurde die Verbindung getrennt und es wird darauf gewartet in den \texttt{openingConnection} Zustand zu wechseln. Dafür muss entweder der Client wieder aktiviert werden oder die automatische Wiederverbindung muss aktiviert sein.
\item \textbf{notAvailable} Dieser Zustand wird betreten, wenn keine Verbindung zum Internet bereitsteht.
\end{itemize}
\subsection{Routen Management}
\label{ssec:route_management}
Die Implementierung der Routen Verwaltung erfolgt über die \mintinline{c++}|class Route|, welche eine Liste zur Speicherung der Punkte nutzt. Die Punkte sind Instanzen der \mintinline{c++}|class Point|. Es herrscht also eine 1 zu n Beziehung zwischen \mintinline{c++}|class Route| und \mintinline{c++}|class Point|.
\subsubsection{Postionen mit \mintinline{c++}|class Point|}
Eine Instanz dieser Klasse besteht unter anderem aus den Koordinaten, welche in dem \mintinline{c++}|struct Coordinates| als zwei \mintinline{c++}|double| Werte gespeichert werden. Zusätzlich kann die Zeit der Erzeugung und die geschätzte Genauigkeit des Punktes angegeben und gespeichert werden. Neben Methoden zur Datenkontrolle und Zugriff wird die Funktionalität der Klasse durch diese beiden Funktionen gegeben:
\begin{itemize}
\item \mintinline{c++}|double distanceTo(Point);| errechnet die Entfernung zwischen den Koordinaten der Instanz zu dem gegeben Punkt. Für die Berechnung wird die Erdkrümmung vernachlässigt, deshalb kann der Satz des Pythagoras genutzt werden. Dafür müssen die Grad angegebenen Koordinaten zunächst in Radianten umgewandelt werden und anschließend in ein kartesisches Koordinatensystem überführt werden. Anschließend kann die Entfernung der beiden Punkte berechnet werden. Dafür werden die beiden Koordinaten einer Achse voneinander abgezogen und anschließend quadriert. Die Ergebnisse der beiden Achsen werden schließlich aufsummiert und radiziert.
\begin{eqnarray}
d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}
\end{eqnarray}
\item \mintinline{c++}|int16_t courseTo(Point);| errechnet den Kurs von dem aktuellen Punkt zu dem gegebenen Punkt und gibt ihn in Grad aus. \(0^\circ\) entspricht Norden. Von da an wird im Uhrzeigersinn weiter gezählt, sodass \(270^\circ\) beispielsweise einen Kurs nach Westen angeben würden. Für die Berechnung müssen die Längen- und Breitengrade zunächst in Radianten umgewandelt werden. Anschließend kann dann mit der Formel
\begin{eqnarray}
\theta = \text{atan2}(\sin(\Delta \lambda)cos(\phi_2), \cos(\phi_1)\sin(\phi_2) - \sin(\phi_1)\cos(\phi_2)\cos(\Delta \lambda))
\end{eqnarray}
mit
\begin{eqnarray}
\Delta \lambda &=& \lambda_2 - \lambda_1 \\
\phi_1, \phi_2 &\widehat{=}& \text{Breitengrade der Punkte} \\
\lambda_1, \lambda_2 &\widehat{=}& \text{Längengrad der Punkte}
\end{eqnarray}
Anschließend muss \(\theta\) wieder in Grad umgewandelt werden und mit modulo auf den Wertebereich \(0 \text{ bis } 360\) normalisiert werden.
\end{itemize}
\subsubsection{Postionsspeicherung mit \mintinline{c++}|class Route|}
Die Klasse nutzt die Implementierung der Liste aus der C++ Standardbibliothek. Darüber hinaus wird ein Iterator für diese Liste von der Klasse verwaltet. Mit primitiven Datentypen wird festgehalten ob die Route gestartet ist und der wievielte Punkt gerade aus der Route selektiert ist.
\par
Die Funktionen der Klasse beschränken sich darauf den Iterator und Liste zu verwalten. Der Liste können nur Daten hinzugefügt werden. Die Entfernung einzelner Punkte ist nicht möglich und erfordert das Löschen der gesamten Liste. Es kann jeweils der nächste oder der vorherige Punkt ausgewählt werden. Die Route kann am Ende oder am Anfang gestartet werden. Soll die Route im Umgekehrter Reihenfolge abgefahren werden muss diese am Ende gestartet werden und immer der vorherige Punkt der Route abgerufen werden. Bei einem Fehler, weil beispielsweise keine Route aufgezeichnet wurde, wird von Funktionen eine Instanz von der \mintinline{c++}|class Point| mit den Koordinaten \(0 \text{ und } 0\) zurückgegeben. Dies kann von aufrufenden Funktion überprüft werden, dafür wurde eigens die Funktion \mintinline{c++}|bool Point::isValid();| implementiert.
\par
Damit Informationen über die Route abgefragt werden können, wurde ein Datentyp hinzugefügt. Das \mintinline{c++}|struct RouteInfo| enthält die Gesamtzahl der in der Route gespeicherten Punkte und der wievielte davon gerade ausgewählt ist.
\subsubsection{Verwaltung über das Menü}
In die vorhandene Menüstruktur wurde in der ersten Ebene der Punkt \flqq Route\frqq{} als Untermenü hinzugefügt. Dieses Menü stellt die in der folgenden Liste erläuterten Funktionen bereit. Für einige dieser Funktionen wird auf eine entwickelte HTTP-API zugegriffen, deshalb muss für diese Funktionen eine Internetverbindung bestehen. Die serverseitige Implementierung der API wird im Anhang \ref{cha:httpApi} beschrieben. Werden Teile der API auf dem Rover genutzt, zeigt dieser den HTTP-Code an. Mit diesem lässt sich erkennen ob die ausgeführte Operation korrekt ausgeführt wurde.
\begin{itemize}
\item \textbf{Points} - Unter diesem Punkt können die einzelnen Koordinaten der in der Route gespeicherten Punkte betrachtet werden.
\item \textbf{Clear} - Löscht die aktuell lokal erstellte Route.
\item \textbf{Import} - Bei Auswahl dieses Punktes muss der Benutzter die ID der Route wissen mit der diese Exportiert wurde. Sofern die gewählte ID existiert, wird die Route heruntergeladen und steht dem Rover nun zur Verfügung. Wenn bereits ein Route lokal vorhanden war, wird diese durch importierte überschrieben. In diesem Fall könnte die gefährdete Route vorher exportiert werden.
\item \textbf{Export} - Mit dieser Funktionen können Routen für die spätere Verwendung gesichert werden. Dafür muss ihnen eine ID zugewiesen werden, unter dieser ID lässt sich die Route später wieder abrufen.
\item \textbf{Delete} - Mit Delete kann eine exportierte Route mit ihrer ID gelöscht werden, dies betrifft allerdings nicht aktuell lokal vorhandene Route.
\end{itemize}
\subsection[Navigation]{\mintinline{c++}|class Navigation|}
\label{ssec:navigation_implementation}
Diese Klasse vereinigt die Verwaltung der Route mit den Sensorwerten wie die Positionsdaten und Ausrichtung um die eigentliche Navigation bereitzustellen. Außerdem werden die Anforderungen an die Genauigkeit überwacht. Die Navigation wird von den Modi zur Aufzeichnung und Abfahrt der Route benötigt.
\par
Es wurde ein \mintinline{c++}|enum Status| implementiert, welcher von einigen Funktionen der Klasse genutzt wird um Informationen über den Ausgang des Funktionsaufrufes zu informieren. Es kann mitgeteilt werden ob die Genauigkeit unzureichend ist, keine Änderungen erfolgt sind, etwas geändert wurde und ob die etwas abgeschlossen wurde. Des weiteren wird in der selben Header-Datei das \mintinline{c++}|struct CourseCorrection| definiert um die Distanz und die anzuwendende Kurskorrektur zum Zielpunkt in einem Datentypen zu vereinen.
\subsection{Modus - Route aufzeichnen}
Um eine Route aufzeichnen zu können wurde zum einen die \mintinline{c++}|class CaptureRoute| implementiert, welche von der bereits vorhanden Klasse zum manuellen Verfahren des Rovers erbt und damit auch in der Hierarchie des \texttt{DiveModi} Interfaces zu finden ist. Dadurch kann der Modus dem bestehenden System ohne weitere Änderungen hinzugefügt werden.
\par
Die Instanz der \mintinline{c++}|class Navigation| wird von dem aktuellen Modus erzeugt dafür wird Komponente \texttt{SensorData} benötigt und eine Route. Die \texttt{SensorData} Komponente wird jedem \texttt{DriveModi} über den Konstruktor zur Verfügung gestellt. Wenn keine Route übergeben wird, erzeugt die \texttt{Navigation} eine eigene. Da eine neue Route aufgezeichnet werden soll ist dieses Verhalten gewollt.
\par
Um die aktuellen Koordinaten der Route hinzuzufügen, muss der Aktions-Button auf der Fernbedienung gedrückt werden. Dadurch versucht \texttt{Navigation} die Route zu erweitern. Dies kann fehlschlagen, wenn die Genauigkeit der aktuellen Position nicht den eingestellten Anforderungen entspricht oder die aktuelle Position zu nah an der, sofern vorhanden, vorherigen ist. Der minimale Abstand zwischen zwei Punkten kann ebenfalls eingestellt werden. Auch der maximale Abstand zwischen zwei Punkten ist definiert und kann eingestellt werden. Wenn die gesamte Route aufgezeichnet wurde, kann der Modus verlassen werden. Dabei wird die Instanz von Navigationsklasse zerstört und damit auch die dort gehaltene Route. Deshalb wird diese zwischengespeichert und überschreibt gegebenen falls die zuletzt gespeicherte Route. Ein Überschreiben erfolgt nur wenn die Route mindesten über zwei Einträge verfügt. Die Datenhaltung der Route wird über statische Funktionen und Member in der Klasse \texttt{Route} realisiert, die zwischengespeicherte Route ist dementsprechend nicht persistent.
\par
Der Modus wird über einen Menüeintrag gestartet. Während der Modus aktiv ist, werden im Menü neben Informationen über Sensorwerte und die bisher aufgezeichnete Route auch Einstellungen zu der geforderten Genauigkeit geboten.
\subsection{Modus - Route abfahren}
\label{ssec:route_drive}
Die Funktionalität, erfasste Routen abzufahren erfordert die Zusammenarbeit mehrerer Komponenten. Zunächst wird beschrieben wie die Navigationsklasse den Kurs zum Zielpunkt berechnet und die Navigationsanweisungen gibt und bestimmt ab wann ein Punkt als erreicht gilt. Die Anweisungen müssen von dem Autopiloten umgesetzt werden, dafür muss sich dieser auf den Zielpunkt Ausrichten und die Strecke mit angepasster Geschwindigkeit zurücklegen.
\par
Der letztendlich ausführende Modus nennt sich \texttt{Autopilot} und wird wie \texttt{CaptureRoute} in das System eingebunden, da dieser Modus, um den Rover an die Startposition der Route fahren zu können, ebenfalls von dem Modus zum manuellen Verfahren erbt. Während der Autopilot die Steuerung übernimmt, werden keine Eingaben von dem Joystick zum verfahren des Rovers akzeptiert. Wenn der Autopilot verfügbar ist kann er durchs betätigen der Aktions-Taste aktiviert werden und auch wieder deaktiviert werden.
\par
Auch der \texttt{Autopilot} verfügt über ein Menü über den dieser aufgerufen wird. Das Menü stellt Status-, Sensor-, Routen-, und Navigationsinformationen zur Verfügung und ermöglicht das Einstellen der wie präzise ein Punkt angefahren werden muss, ob nach Abschluss der Route diese von vorne gestartet werden soll und ob der aktuelle Zielpunkt eingefroren werden soll was dazu führt, dass die Route an diesem Punkt pausiert wird.
\subsubsection{Kursberechnung}
Das Ziel der Kursberechnung ist es ein vorzeichenbehaftete Kurskorrektur in Grad zu erzeugen. Dafür muss die aktuelle Ausrichtung bekannt sein. Für diese Information stehen drei Quellen zur Verfügung.
\begin{itemize}
\item Das Magnetometer liefert absolute Werte, welche die Ausrichtung laut Datenblatt !!!cite!!! im optimalen Fall auf \(2^\circ\) genau beschreiben.
\item Die nächste Quelle ergibt sich aus den gefahrenen Strecken des Rovers. Dafür wird der erste Punkt nach einer Rotation und der letzte Punkt vor einer Rotation festgehalten und daraus die Ausrichtung mit der \mintinline{c++}|int16_t Point::courseTo(Point&);| Methode berechnet. Diese Variante ist bei kurzen Strecken ungenau und wird mit steigendem Abstand zwischen den Punkten genauer, wenn die Positionsbestimmung im niedrigen Zentimeter Bereich erfolgt. Sollte der Rover durch den Untergrund oder anderen Fehlern keineGerade fahren sondern ein leichte Kurve, wird dieses Verfahren ungenauer.
\item Es bleibt noch das hinzugefügte Gyroskop, dieses kann keine absoluten Werte bestimmen. Dafür kann es präzise relative Drehwerte angeben. Es eignet sich also um bei einem vorgegebenen Winkel die Drehung zu überwachen. !!!Sensorfusion ausgeführt?!!!
\end{itemize}
Nachdem die Datenquelle ausgewählt wurde muss der Kurs von der aktuellen Position zum Zielpunkt berechnet werden. Von diesem Ergebnis wird die aktuelle Ausrichtung subtrahiert. Anschließend muss das Resultat auf den gewünschten Wertbereich normiert werden.
\subsubsection{Navigationsanweisungen}
Aus der berechneten Kurskorrektur und dem verbleibenden Abstand zum Zielpunkt wird Navigationsanweisung erstellt. Die Informationen in das folgende \mintinline{c++}|struct| verpackt:
\begin{minted}[linenos, gobble=5, breaklines]{c++}
struct CourseCorrection
{
int16_t correction;
double distance;
};
\end{minted}
Wenn die Navigationsanweisungen bei der Navigationsklasse abgefragt werden muss das genannte \mintinline{c++}|struct| der Funktion als Referenz übergeben werden. Der Rückgabewert wird für das bereits beschriebene \mintinline{c++}|enum Navigation::Status| verwendet. Darüber wird mitgeteilt ob die Navigationsanweisungen aktualisiert wurden oder weshalb dies nicht geschah. Zum Beispiel wenn der Rover seine Position nicht wesentlich verändert hat, die aktuelle Positionsbestimmung zu ungenau ist oder das Ziel erreicht wurde.
\subsubsection{Autopilot aufbau}
Der Autopilot ist einen Zustandsautomaten nachempfunden. In den verschiedenen Zuständen können unterschiedliche und gleiche Funktionen aufgerufen werden. Die beiden häufigsten Funktionsaufrufe in den verschiedenen Status sollen erläutert werden:
\begin{itemize}
\item \mintinline{c++}|void Autopilot::askNavigationForOrder();| holt sich die aktuellen Navigationsanweisungen von \texttt{Navigation} und wertet dabei den zurückgegebenen Status aus. Durch diese Auswertung können Zustandsübergänge auftreten. Beispielsweise bei vollständiger abgefahrener Route oder mangelnder Genauigkeit bei der Positionsbestimmung. Sollte der zweite Fall eintreten wird der vorherige Zustand gespeichert, in welchen zurückgekehrt wird, wenn die Genauigkeit wieder den Anforderungen entspricht und
\item \mintinline{c++}|void Autopilot::checkButtonInput();| überprüft ob der Aktions-Button gedrückt ist. Wenn die Eingabe vorliegt werden Zustandswechsel durchgeführt, wie selbstständiges Fahren aktivieren und deaktivieren.
\end{itemize}
Die folgende Tabelle \ref{tab:autopilot} listet die Zustände auf und beschreibt die Funktionalitäten der einzelnen Zustände. Dabei wird in der Spalte \texttt{Update} angegeben ob die Navigationsanweisungen mit der beschriebenen Funktion in diesem Zustand aktualisiert werden und mit der Spalte \texttt{Check} wird das gleich für die Überprüfung der Benutzereingaben dargestellt.
\begin{table}[]
\centering
\begin{tabular}{|l|c|c|l|}
\hline
Zustand & \multicolumn{1}{l|}{Update} & \multicolumn{1}{l|}{Check} & Beschreibung \\ \hline
InsufficientAccuracy & x & - & -Warten auf bessere Genauigkeit \\ \hline
NoRoute & - & - & -Autopilot nicht verfügbar \\ \hline
None & - & - & -Default Zustand zum Programmbeginn \\ \hline
NavigationStarted & x & x & \begin{tabular}[c]{@{}l@{}}-Autopilot initialisiert\\ -Auf Benutzereingabe warten\end{tabular} \\ \hline
GetToStartPoint & x & - & \begin{tabular}[c]{@{}l@{}}-Warten bis Benutzer den Rover in die \\ Nähe des Startpunktes gebracht hat\\ -Fahren mit dem Joystick möglich\end{tabular} \\ \hline
SelfDrivingAvailable & x & x & \begin{tabular}[c]{@{}l@{}}-Autopilot bereit\\ -Auf Benutzereingabe warten\end{tabular} \\ \hline
SelfDriving & x & x & \begin{tabular}[c]{@{}l@{}}-Rover fährt geradeaus bis die\\ Abweichung zu groß ist.\end{tabular} \\ \hline
SelfDrivingRotate & x & - & -Abweichung korrigieren \\ \hline
TargetReached & - & - & -Navigation abgeschlossen \\ \hline
\end{tabular}
\caption{Auflistung und Beschreibung der Zustände des Autopiloten}
\label{tab:autopilot}
\end{table}
\subsubsection{Ausrichten}
Wenn der Rover zu weit von dem Kurs abweicht und damit nicht mehr ausreichend genau auf den Zielpunkt ausgerichtet ist, wird von dem Zustand \texttt{SelfDriving} in den Zustand \texttt{SelfDrivingRotate} gewechselt. Dieser wechsel kann nur aus \texttt{SelfDriving} erfolgen und beginnt damit die Rotation einzuleiten. Dabei wird Drehrichtung der Rotation durch das Vorzeichen der gegebenen Kurskorrektur bestimmt. Ab diesem Zeitpunkt wird ständig überprüft, wann sich der Rover weit genug gedreht hat um die Rotation rechtzeitig zu beenden. Anschließend wird wieder in den vorherigen Zustand gewechselt.
\subsubsection{Geschwindigkeit}
Die Geschwindigkeit wird je nach Abstand zu dem Zielpunkt eingestellt. Dabei gibt es drei verschiedene Abstandszonen. Die Werte für Geschwindigkeit und Abstand werden in Tabelle \ref{tab:roverSpeed} beschrieben. Die Geschwindigkeit wird im Nahbereich deutlich reduziert um einfacher auf Abweichungen reagieren zu können.
\begin{table}[]
\centering
\begin{tabular}{|l|c|c|}
\hline
Bereich & \multicolumn{1}{l|}{Abstand {[}m{]}} & \multicolumn{1}{l|}{Geschwindigkeit {[}m/s{]}} \\ \hline
ferm & 2!!! & 2 \\ \hline
mittel & 1!!! & 1 \\ \hline
nah & 0,75!!! & 0,5 \\ \hline
\end{tabular}
\caption{Geschwindigkeit der Rovers je nach Abstand zum Zielpunkt}
\label{tab:roverSpeed}
\end{table}