Skip to content
Snippets Groups Projects
architektur.tex 12.9 KiB
Newer Older
\documentclass[../mainDocument.tex]{subfiles}
\begin{document}
	\section{Architektur}
	\subsection{Systemarchitektur}
	Abbildung \ref{fig:hardware-sys} zeigt, welche Systemkomponenten in welcher Umgebung laufen und welche Kommunikationswege es zwischen den einzelnen Komponenten gibt. Zur Verf\"ugung steht uns ein Fahrzeug, welches mit einer Kamera, einem Ultraschallsensor, einem Motor, vier R\"adern, einem STM-Board und einem ODROID-Board ausger\"ustet ist.\\
	Auf dem STM-Board laufen die Treiber f\"ur die direkte Steuerung des Motors und der R\"ader. Die gesamte Software des STM-Boards wird von Assystem geliefert und unser Team muss sich lediglich darum k\"ummern, die entsprechenden Befehle vom ODROID-Board an das STM-Board zu schicken.\\
	Auf dem ODROID-Board laufen die Module zum Berechnen des Fahrverhaltens, sowie der Kommunikation mit dem STM-Board und anderen Fahrzeugen. Die Kamera und der Ultraschallsensor sind mit dem ODROID verbunden.
duc anh vu's avatar
duc anh vu committed
	\\\\
	Bis auf die einzelnen Module im ODROID ist die Architektur so von Assystem vorgegeben, da sie die Software f\"ur das STM liefern und auch den Bau der Fahrzeuge leiten.
unknown's avatar
unknown committed
	\begin{landscape}
		\begin{figure}[h]
unknown's avatar
unknown committed
			\begin{center}
				\includegraphics[scale=0.5]{SystemArchitektur}
unknown's avatar
unknown committed
			\end{center}
			\caption{Systemarchitektur}
			\label{fig:hardware-sys}
unknown's avatar
unknown committed
		\end{figure}
	\end{landscape}
	
	\subsection{ODROID}
	Abbildung \ref{fig:ODROID-sys} zeigt, welche Module auf dem ODROID laufen, welche Module miteinander kommunizieren und welche Datenfl\"usse es gibt.
	\paragraph*{MAVLINK}
	Die Kommunikationsschnittstelle zwischen dem ODROID und dem STM. Schickt L\"angsgeschwindigkeit vom Cruise Control an das STM. Schickt Lenkwinkel vom Lanekeeping an das STM. Bekommt vom STM die Eigengeschwindigkeit des Fahrzeugs.
	\paragraph*{Lanekeeping}
		Berechnet die Lenkbefehle, damit das Fahrzeug die Spur beim Fahren h\"alt. Braucht die Daten von der Kamera.
	\paragraph*{Cruise Control}
	Berechnet die zu fahrende Geschwindigkeit, um den Kolonnenabstand bzw. den Sicherheitsabstand zu halten.
	\paragraph*{Platoon Controller}
	K\"ummert sich um die Verwaltung des Kolonnenstatus. Braucht die Car2Car Nachrichten des Netzwerks. Braucht den Abstand nach vorne vom Egomotion-Model.
	\paragraph*{Egomotion-Modell}
	Speichert die Daten, die das Environment Modul berechnet.
	\paragraph*{Environment}
	Berechnet den Abstand nach vorne. Braucht die Daten des Ultraschallsensors und der Kamera.
	\paragraph*{Bildverarbeitung}
	Wegen Zeitmangel, keine Verwendung der Kamera.
	
	\paragraph*{Medianfilter}
	Rauschfilterung bzw. Gl\"attung die Daten des Ultraschallsensors. 
	
	\paragraph*{Logging}
	Speichert alle aktuellen Daten des Sensors, der Kamera, die Eigengeschwindigkeit, die berechnete L\"angsgeschwindigkeit, den berechneten Lenkwinkel und die Daten des Platoon Controllers.
	\paragraph*{Netzwerk}
	K\"ummert sich um das Empfangen und das Versenden von Nachrichten \"uber ein WLAN.
	\begin{landscape}
unknown's avatar
unknown committed
		\begin{figure}[h]
			\begin{center}
lenoelda's avatar
lenoelda committed
				\includegraphics[scale=0.45]{Odroid}
unknown's avatar
unknown committed
			\end{center}
			\caption{ODROID-System}
unknown's avatar
unknown committed
		\end{figure}
	\end{landscape}
	
	\subsection{Object Oriented Analysis}
	In Abbildung \ref{fig:ooa} ist das UML-Klassendiagramm f\"ur die Module des ODROIDs.
	
	\begin{figure}[H]
unknown's avatar
unknown committed
	\begin{tikzpicture}
		\begin{umlpackage}{Car}
			\begin{umlpackage}{ODROID}
				%classes
				\umlclass[scale = 0.5]
					{MAV-Link}
					{
						- $v_{new}$ : Integer\\
						- $\alpha_{new}$ : Integer\\
						- $v_O$ : Interger\\
						- $\alpha_O$ : Integer\\
						- RC-State : Integer
					}
					{
						+ set($v_{new}$, $\alpha_{new}$)\\
						+ RequestNewState(RC-State)\\
						+ updateOwn() : (Integer, Integer)
					}
				\umlclass[scale = 0.5, xshift = -8cm]
					{Lane-Keeping}
					{
						- Image/Path : ?\\
						- $\alpha_{new}$ : Integer
					}
					{
						+ Lanekeeping() : ?
					}
				\umlclass[scale = 0.5, xshift = 8cm, yshift = -4cm]
					{Cruise-Control}
					{
						- $d_O$ : Integer\\
						- $v_P$ : Integer\\
						- $IPD$ : Integer\\
						- $PS$ : Integer\\
						- PlatoonState : Integer\\
						- $v_s$ : Integer\\
						- $d_s$ : Integer\\
						+ $v_{new}$ Integer
					}
					{
						- CACC($d_O, v_P, IPD, PS$) : Integer\\
						- ACC($d_O, v_P, v_s, d_s$) : Integer\\
						- calcNewOptimalDistance($v_s$) : Integer\\
						+ setNewSpeed($v_{new}$)
					} (CruiseControl)
				\umlclass[scale = 0.5, xshift = -5.5cm, yshift = -9cm]
					{Egomotion}
					{
						- $d_O$ : Integer\\
						- $v_O$ : Integer\\
						- $v_R$ : Integer\\
						- $v_P$ : Integer\\
						- $\alpha_O$ : Integer\\
						- Path : ?\\
						+ $\alpha_{new}$ : Integer\\
						+ $v_{new}$ : Integer\\
					}
					{
						- calc\_$v_P$($v_R$) : Integer\\
						%- getEnvironment() : (Integer, Integer)\\
						%- getMavLink() : (Integer, Integer)\\
						%- getCurseControl : Integer
					} (EgoMotion)
				\umlclass[scale = 0.5, xshift = 6.7cm, yshift = -14cm]
					{PlatoonController}
					{
						- $IPD$ : Integer\\
						- $PS$ : Integer\\
						- PlatoonState : ENUM\\
						- $v_s$ : Integer\\
						- $CarID$ : Integer\\
						- PlatoonMemberList : ?\\
						- PlatoonPos : Integer\\
						- PlatoonPrevID : ?\\
						+ WantsPlatoon : Boolean
					}
					{
						- evaluate\_PlatoonState(PlatoonState : Integer) : ?\\
						- determine\_LV\_IPD-PS() : (Integer, Integer)\\
						- handle\_PBM() : ?\\
						- handle\_PCM() : ?\\
						- handle\_PHM() : ?\\
						- send\_PBM() : ?\\
						- send\_PCM() : ?\\
						- send\_PHM() : ?
					}
				\umlclass[scale = 0.5, xshift = -9cm, yshift = -20cm]
					{Environment}
					{
						- USS-Data : Integer\\
						+ $d_O$ : Integer\\
						+ $v_R$ : Integer\\
						+ PlatoonPrevID : ?
					}
					{
						- calc\_$v_R$
					}
				\umlclass[scale = 0.5, xshift = -4cm, yshift = -23cm]
					{Logging}
					{
						+ $d_O$ : Integer\\
						+ $v_O$ : Integer\\
						+ $\alpha_O$ : Integer\\
						+ $v_R$ : Integer\\
						+ $v_P$ : Integer\\
						+ Path : ?\\
						+ $\alpha_{new}$ : Integer\\
						+ $v_{new}$ : Integer\\
						+ WantsPlatoon : Boolean\\
						+ UpdateReady : Boolean\\
						+ $IPD$ : Integer\\
						+ $PS$ : Integer\\
						+ PlatoonState : ENUM\\
						+ $v_s$ : Integer\\
						+ $CarID$ : Integer\\
						+ PlatoonMemberList : ?\\
						+ PlatoonPos : Integer\\
						+ PlatoonPrevID : Integer
					}
					{
						- cacheDate() : ?\\
						+ sendToPC(ALL)
					}
				\umlclass[scale = 0.5, xshift = -11.5cm, yshift = -25cm]
					{Camera}
					{}
					{}
				\umlclass[scale = 0.5, xshift = -11.2cm, yshift = -28cm]
					{Ultrasonic}
					{}
					{}
				\umlclass[scale = 0.5, xshift = 9.5cm, yshift = -25cm]
					{Network}
					{
						+ $IPD$ : Integer\\
						+ $PS$ : Integer
					}
					{
						+ send\_PBM()\\
						+ send\_PCM()\\
						+ send\_PHM()\\
						+ send\_PLM()\\
						+ handle\_PBM()\\
						+ handle\_PCM()\\
						+ handle\_PHM()\\
						+ handle\_PLM()\\
						+ Car2PC-MSGs.
					}
				
				%arrows
				\umlinherit	[geometry=-|,  anchors =   0 and 250]	{Camera}{Environment}
				\umlinherit	[geometry=|-,  anchors =  90 and 180]	{Camera}{Lane-Keeping}
				\umlinherit	[geometry=|-,  anchors =  90 and  25]	{Cruise-Control}{MAV-Link}
				\umlinherit	[geometry=|-,  anchors = 217 and  50]	{Cruise-Control}{Egomotion}
				\umlinherit	[geometry=|-,  anchors =  50 and 217]	{Egomotion}{Cruise-Control}
				\umlinherit	[geometry=|-,  anchors = -35 and 152]	{Egomotion}{PlatoonController}
				\umlinherit	[geometry=-|,  anchors = 115 and 300]	{Egomotion}{Lane-Keeping}
				\umlinherit	[geometry=-|]							{Egomotion}{Logging}
				\umlinherit	[geometry=|-|, anchors = 90 and 245]	{Environment}{Egomotion}
				\umlinherit	[geometry=--]							{Lane-Keeping}{MAV-Link}
				\umlinherit	[geometry=-|,  anchors = 300 and 115]	{Lane-Keeping}{Egomotion}
				\umlinherit	[geometry=|- , anchors = -55 and 222]	{Logging}{Network}
				\umlinherit	[geometry=|-|, anchors = 235 and  70]	{MAV-Link}{Egomotion}
				\umlinherit	[geometry=-|,  anchors = 180 and 270]	{Network}{MAV-Link}
				\umlinherit	[geometry=-|]							{PlatoonController}{Cruise-Control}
				\umlinherit	[geometry=|-,  anchors = 240 and  25]	{PlatoonController}{Logging}
				\umlinherit	[geometry=-|,  anchors = 300 and  85]	{PlatoonController}{Network}
				\umlinherit	[geometry=-|,  anchors =  85 and 300]	{Network}{PlatoonController}
				\umlinherit	[geometry=-|,  anchors =   0 and 290]	{Ultrasonic}{Environment}
			\end{umlpackage}
		\end{umlpackage}
unknown's avatar
unknown committed
	\end{tikzpicture}
	\caption{Object Oriented Analysis}
	\label{fig:ooa}
	\end{figure}
unknown's avatar
unknown committed
	
	\subsection{Softwarearchitektur}
	Zur Unterst\"utzung in der Entwicklung des Systems benutzen wir die Tools des Robot Operating System (ROS) in der Version Lunar Loggerhead. ROS ist ein beliebtes Framework im Robotik-Bereich und ist durch das Messaging-System zwischen einzelnen ROS-Modulen auf Verteilbarkeit und Modularit\"at ausgerichtet. Weiterhin sind die Module, die uns Assystem liefert, bereits als ROS-Nodes implementiert. Daher ist es sinnvoll, dass wir selbst ROS benutzen, um so die Kompatibilit\"at mit Assystem zu gew\"ahren. ROS unterst\"utzt die Programmiersprachen Python und \CC . 
	Da unser System sehr zeitkritisch ist, haben wir uns entschieden, das gesamte System in \CC\ zu implementieren. Auf dem ODROID l\"auft Ubuntu 16.04.
	Anstatt ROS-Nodes zu nutzen, haben wir uns jedoch entschieden, auf Nodelets umzusteigen. Diese sind vom Konzept her ähnlich. ROS-Nodes kommunizieren untereinander \"uber TCP, was eventuell zu einem h\"oheren Zeitaufwand f\"uhrt. Im Gegensatz dazu kommunizieren Nodelets untereinander über shared pointer. 	
	
	Das Lanekeeping wird bereits als ROS-Node von Assystem geliefert. Die Kamera und der Ultraschallsensor erhalten jeweils eigene Nodelets, da sie nur damit besch\"aftigt sein werden, ihre Daten aufzunehmen und an ihr rostopic zu publishen. Das Environment Modul ist ein eigener Nodelet, da es die hochfrequenten Daten der Kamera und des Ultraschallsensors lesen und verarbeiten muss. Das MAVLINK Modul ist ein eigener Nodelet, da dessen Aufgabe das Versenden und Empfangen von Nachrichten \"uber das MAVLINK Protokoll ist.
	
	PlatoonController, CruiseControl, Netzwerk, Logging und Egomotion laufen zusammen in einem Nodelet. Das liegt daran, dass beim Designentwurf noch davon ausgegangen wurde, dass ROS-Nodes benutzt werden. Durch das Gruppieren mehrerer Module innerhalb des gleichen ROS-Nodes erhofften wir uns einen Performance-Gewinn, da Daten nicht node-\"ubergreifend \"uber TCP verschickt werden m\"ussen, sondern innerhalb des Nodes durch Getter bereitgestellt werden können. Durch die Verwendung von Nodelets k\"onnte es jedoch sein, dass es im Vergleich zur Alternative - die Module PlatoonController, CruiseControl, Netzwerk, Logging und Egomotion auf einzelne Nodelets zu verteilen - zu keinem Performance-Gewinn kommt. Aus Zeitmangel wollten wir aber das Design nicht mehr \"andern.
			\begin{center}
				%\includegraphics[width=\textwidth]{SoftwareArchitektur} %photo
				\includegraphics[scale=0.45]{sw_architektur} % some elements missing/ not recognizable
			\end{center}
			\caption{Softwarearchitektur}
			\label{fig:sw-arch}
		\end{figure}
unknown's avatar
unknown committed
	%uml-tikz stub TODO
	\begin{comment}
	\begin{tikzpicture}
		\begin{umlpackage}{Softwarearchitektur}
				%classes
				\umlclass[scale = 0.5, xshift = 8cm]
					{MAV-Link}
					{}
					{}
				\umlclass[scale = 0.5, xshift = 8cm, yshift = -4cm]
					{Lane-Keeping}
					{}
					{}
				\umlclass[scale = 0.5, xshift = 8cm, yshift = -8cm]
					{Kamera}
					{}
					{}
				\umlclass[scale = 0.5, xshift = 8cm, yshift = -12cm]
					{USS}
					{USS-Daten}
					{}
				%network
				\umlclass[scale = 0.5, xshift = -8cm]
					{C2C}
					{
						IPD, PS
					}
					{
						nach PC\\
						nP, NULL\\
						nP(FV)\\
						nP(LV)\\
						FV\\
						LV
					}
				\umlclass[scale = 0.5, xshift = -4cm]
					{PC2}
					{
					
					}
					{
						handle IPD aus
					}
				\umlclass[scale = 0.5]
					{Logging}
					{
					
					}
					{
					
					}
				\umlclass[scale = 0.5, yshift = -4cm]
					{Egomotion}
					{
						$v_p = v_0 + v_p$\\
						$d_0$
					}
					{
					
					} (EgoMotion)
				\umlclass[scale = 0.5, xshift = -6cm, yshift = -8cm]
					{PlatoonController}
					{
						IPD, PS, $d_0$, PlatSt, $v_s$
					}
					{
						noPlatoon:\\
						-wantsPlatoon\\
						- FV/LV\\
						- C2C initialisieren\\
						- IPD, PS bestimmen\\
						- $v_s$ weiterreichen\\
						- ACC fahren\\
						FV:\\
						- CACC fahren\\
						- leaveMsg\\
						LV:\\
						- ACC fahren\\
						- leaveMsg\\
						- IPD/PS update ($v_{new}$ vs. $v_{PC}$)
					}
				%Stuff: Pub $v_{new}$, Notify, für CC: PlatoonStat, IPD, PS, $v_s$
unknown's avatar
unknown committed
				\umlclass[scale = 0.5, yshift = -8cm]
					{CruiseControl}
					{
					
					}
					{
					
					}
				\umlclass[scale = 0.5, xshift = 4cm, yshift = -12cm]
					{Environment}
					{
						$d_0, v_r$
					}
					{
					
					}
				
				%arrows
				%\umlinherit	[geometry=-| ,anchors=   0 and 250]	{src}{dest}
			\end{umlpackage}
		\end{tikzpicture}
	\end{comment}
	
\end{document}