Main text is finally done
This commit is contained in:
parent
762bffe668
commit
4652dc8f49
@ -472,4 +472,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@misc{intel_ark,
|
||||||
|
title = {{Intel ARK - Intel\textregistered \ Xeon\texttrademark \ Processor X5675 Specifications}},
|
||||||
|
howpublished = {\url{https://ark.intel.com/content/www/us/en/ark/products/52577/intel-xeon-processor-x5675-12m-cache-3-06-ghz-6-40-gts-intel-qpi.html}},
|
||||||
|
note = {Megtekintve: 2021-12-18}
|
||||||
|
}
|
||||||
|
@ -10,3 +10,4 @@ Emellett szeretném megköszönni családomnak és barátaimnak a végtelen tám
|
|||||||
|
|
||||||
|
|
||||||
% lackó, Josh, kszk
|
% lackó, Josh, kszk
|
||||||
|
% kszk
|
@ -14,6 +14,7 @@ Ez az alkalmazás a peremhálózati rendszerek adat aggregációs lehetőségeit
|
|||||||
|
|
||||||
|
|
||||||
\section{Felépítés}
|
\section{Felépítés}
|
||||||
|
\label{sec:birbnetes_short_desc}
|
||||||
|
|
||||||
A rendszer felépítése két rétegű. Az egyik réteg a felhőben futó szoftver a másik magukon az \acrshort{iot} eszközökön fut. A két rendszer magas szintű működésének funkcionális vázlatát \aref{fig:nagyon_simple_birbnetes}.\ ábra szemlélteti.
|
A rendszer felépítése két rétegű. Az egyik réteg a felhőben futó szoftver a másik magukon az \acrshort{iot} eszközökön fut. A két rendszer magas szintű működésének funkcionális vázlatát \aref{fig:nagyon_simple_birbnetes}.\ ábra szemlélteti.
|
||||||
|
|
||||||
|
@ -3,20 +3,94 @@
|
|||||||
\chapter{Alkalmazások tesztelése}
|
\chapter{Alkalmazások tesztelése}
|
||||||
%----------------------------------------------------------------------------
|
%----------------------------------------------------------------------------
|
||||||
|
|
||||||
% Ez érdekes lesz
|
A peremhálózati adatközpontok lehetőségeinek dinamikus kihasználásra felkészített alkalmazásokat \aref{ch:test_system}.\ fejezetben ismertetett és felépített teszt környezetben egymástól függetlenül teszteltem. A környezet és a benne futó alkalmazások jól megfigyelhetőek voltak, így sikerült mindkét alkalmazás esetében egyértelmű következtetéseket levonnom. Az egyes alkalmazások mérésének körülményeit, kivitelezését és a mért értékeket a következőkben ismertetem.
|
||||||
|
|
||||||
|
|
||||||
|
% mit, miért, hogyan, mivel, eredmények, konklúzió
|
||||||
|
\section{Madárhang elemző alkalmazás terhelésének dinamikus ütemezése}
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Környezet}
|
||||||
|
|
||||||
|
Az alkalmazás teszteléséhez feltelepítettem az alkalmazást a felhő adatközpontot szimbolizáló klaszterbe. Ugyanebbe a klaszterbe telepítettem \aref{sec:scheduler}.\ szekcióban ismertetett ütemező szoftvert is.
|
||||||
|
|
||||||
|
Az alkalmazás működésének teszteléséhez egy olyan forgatókönyvet állítottam össze, amelyben az ütemező számára mind a három adatközpont potenciális jelölt lehet az előszűrő szolgáltatás beütemezésére. Ehhez az alábbi prioritási sorrendet állítottam fel:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item \texttt{edge-1}
|
||||||
|
\item \texttt{edge-2}
|
||||||
|
\item \texttt{cloud}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
A mérés elvégezéséhez szükségem volt arra, hogy a klienseket emuláló virtuális gép képes legyen több \acrshort{iot} eszköz emulálására. \Aref{sec:birbnetes_short_desc}.\ szekcióban ismertetett kétrétegű szoftver architektúra miatt ez könnyen kivitelezhető volt. Egy új platform illesztő szoftver komponenst implementáltam, amely az \acrshort{iot} eszközön lévő hardverelemeket emulálja. A mikrofon emulációja egy fixen felvett hangfájl tartalmát szolgálja ki a logikai résznek, a többi hardver elem működése pedig csak naplózásra kerül.
|
||||||
|
|
||||||
|
Miután ez megvolt egy egyszerű szkriptet készítettem, amely konfigurálható számú \acrshort{iot} hardver emulációját indítja el és felel az életciklusuk kezeléséért. Ennek segítségével a mérések során tetszőleges számú eszközt tudtam emulálni.
|
||||||
|
|
||||||
|
\subsection{Mérés}
|
||||||
|
|
||||||
|
A mérések során az alkalmazás helyesen működött. Indulásuk után az emulált eszközök lekérdezték a feltöltés célját, majd megkezdték a hangminták feltöltését. Átütemezési eseményekre sikeresen átkonfigurálták a küldés helyét, ezzel az új adatközpontot terhelve. Szolgáltatás kiesés a teljes mérés alatt nem volt tapasztalható, egy hangminta sem veszett el.
|
||||||
|
|
||||||
|
Több mérést is futtattam más-más paraméterekkel. \Aref{fig:enhanced}.\ ábra összefoglalja az egyes adatközpontokon futó szolgáltatások által fenntartatott sorok hosszát az idő függvényében 5 darab eszköz emulálása során. Emellett ezen az ábrán jelölve vannak az ütemező algoritmus által hozott ütemezési döntések.
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[h!]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=0.8\textwidth]{figures/enhanced}
|
\includegraphics[width=0.8\textwidth]{figures/enhanced}
|
||||||
\caption{asd}
|
\caption{Szolgáltatás terheltsége adatközpontonként és átütemezési események. (5 eszköz) \\ \textbf{zöld}: Mérés kezdete \\ \textbf{kék}: Ütemezés \texttt{edge-1}-ből \texttt{edge-2}-be \\ \textbf{narancssárga}: Ütemezés \texttt{edge-2}-ből \texttt{cloud}-ba. }
|
||||||
\label{fig:enhanced}
|
\label{fig:enhanced}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
Jól látszik a grafikonokon, hogy kezdetben az összes eszköz a prioritásban első helyen álló adatközpontra ütemeződött. Ez túl nagy terhelés volt a szolgáltatás számára, ezért percekkel később az ütemező algoritmus átütemezett egy eszközt. Mivel az átütemezés pillanatában ebben az adatközpontban még nem futott szolgáltatás, így előbb elindította azt (ez az oka annak, hogy korábbról nem látszik mérési eredmény).
|
||||||
|
|
||||||
|
Egy eszköz átütemezése nem orvosolta még a problémát, ezért átütemezett még további kettőt. Ekkor már három eszköz volt az \texttt{edge-2} adatközpontra ütemezve. A harmadik eszköz átütemezése után az \texttt{edge-2} adatközpont is instabillá vált, ezért az algoritmus átütemezett egy eszközt a felhőbe. Ezek után stabilizálódott a rendszer állapota. További ütemezések nem történtek.
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Értékelés}
|
||||||
|
|
||||||
|
A tesztek eredménye jól demonstrálja, az ütemező algoritmus és az átalakított alkalmazások helyes működését.
|
||||||
|
|
||||||
|
Elsőre kevésnek tűnhet a másodpercenkénti két minta feldolgozása a peremhálózati rendszeren. Ennek több oka is volt. A feldolgozás sebessége erősen függ az alkalmazást futtató számítógép számítási teljesítményétől. A teszt során a környezet Intel\textregistered \ Xeon\texttrademark \ X5675 processzor alapú szervergép futtatta. Ez a processzor 2011-ben jött ki \cite{intel_ark}. Azóta léteznek sokkal jobb számítási kapacitással rendelkező processzorok és szervergépek.
|
||||||
|
|
||||||
|
A másik fő indok az alacsony feldolgozási kapacitás mellett a horizontális skálázás teljes hiánya. Az ütemező nem képes az elindított szolgáltatások skálázására. Így minden adatközpontban csak egy példányban futott az alkalmazás. Emiatt egyszerre csak egy minta kiértékelése történik, a többi minta addig vár a sorban. Horizontális skálázással a rendszer képes lenne kihasználni az adatközpontban elérhető teljes számítási kapacitást ami jóval nagyobb áteresztő képességet biztosítana.
|
||||||
|
|
||||||
|
Emellett feltűnő volt, hogy a rendszer nagyon lassan reagál a terhelésre és sokáig \enquote{tart neki} átütemezni a terhelést. Ez javítható lehet a paraméterek további optimalizálásával, hiszen jelentősen nagyobb terhelés esetén szükséges lehet a gyorsabb átütemezés.
|
||||||
|
|
||||||
|
\section{Robotkar vezérlés dinamikus ütemezése}
|
||||||
|
|
||||||
|
\subsection{Környezet}
|
||||||
|
|
||||||
|
Az alkalmazás teszteléséhez feltelepítettem az alkalmazást a felhő adatközpontot szimbolizáló klaszterbe. Ugyanebbe a klaszterbe telepítettem \aref{sec:scheduler}.\ szekcióban ismertetett ütemező szoftvert metrika gyűjtő komponenseit is, mivel itt nem volt szükség az ott ismertetett ütemező futtatására.
|
||||||
|
|
||||||
|
A robotkarok szimulálására \aref{sec:ursim_simulator}.\ szekcióban ismertetett \textit{DockURSim} szoftvert futtattam két példányban. Mivel a vezérlő szolgáltatások \acrshort{ip} cím alapján kapcsolódnak az egyes robotkarokhoz, így a klienseket emuláló virtuális gépnek felvettem két \acrshort{ip} címet, az egyik szimulátor portjait az egyik címhez a másikat a másikhoz rendeltem. Így képes voltam két robotkar szimulálására.
|
||||||
|
|
||||||
|
A méréshez növeltem a kliens és az egyes adatközpontok közötti linkek késleltetését úgy, hogy a következő értékeket érjék el:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \texttt{cloud}: 40ms
|
||||||
|
\item \texttt{edge-1}: 10ms
|
||||||
|
\item \texttt{edge-2}: 20ms
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\subsection{Mérés}
|
||||||
|
|
||||||
|
A mérés során a kliensek és az adatközpontok közötti késleltetést megfelelően mérte a rendszer. A késleltetési mérések kimenetét \aref{fig:latency}.\ ábra mutatja be. Tisztán látszik, hogy a legalacsonyabb késleltetés az \texttt{edge-1} nevű adatközpontban érhető el.
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[h!]
|
||||||
\centering
|
\centering
|
||||||
\includegraphics[width=1\textwidth]{figures/latency_feliratos_jo}
|
\includegraphics[width=1\textwidth]{figures/latency_feliratos_jo}
|
||||||
\caption{asd}
|
\caption{Detektált késleltetés az egyes adatközpontok és a kliens között az idő függvényében}
|
||||||
\label{fig:latency}
|
\label{fig:latency}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
Ezek után kezdeményeztem egy új \textit{program} futtatását a felhőben futó szolgáltatástól. A rendszer helyesen az \texttt{edge-1} adatközpontra ütemezte be a \textit{program} futtatását. Onnan sikeresen csatlakozott az emulált robotkarokhoz és hajtotta végre a \textit{program} futását.
|
||||||
|
|
||||||
|
Lefutás után megváltoztattam a késleltetési értékeket úgy, hogy az eddig kedvező \texttt{edge-1} késleltetése nagyobb legyen, mint az \texttt{edge-2} adatközponté, ehhez utóbbi késleltetését csökkentettem.
|
||||||
|
|
||||||
|
Ezek után a következő futásnál az ütemező sikeresen kiválasztotta ismét a megfelelő adatközpontot az alkalmazás futtatására.
|
||||||
|
|
||||||
|
\subsection{Értékelés}
|
||||||
|
|
||||||
|
Az ütemezés sikeresen választotta ki a legalacsonyabb késleltetéssel rendelkező adatközpontot. Így akár egy dinamikusan változó környezetben is képes mindig a legalacsonyabb késleltetéssel futtatni \textit{programok} sorozatát.
|
||||||
|
|
||||||
|
\section{Ütemező rendszer értékelése}
|
||||||
|
|
||||||
|
Az elkészített ütemező rendszer mindkét alkalmazás esetében sikeresen teljesítette a felé támasztott elvárásokat.
|
||||||
|
|
||||||
|
Ennek köszönhetően ezeknél az alkalmazásoknál képes a komponenseket emberi beavatkozás nélkül hatékonyan ütemezni.
|
@ -28,7 +28,7 @@ Az \textit{EdgeX Foundry} és \textit{Porject EVE} használatát korán elvetett
|
|||||||
|
|
||||||
A megvizsgált \acrshort{paas} rendszereket azért nem szerettem volna használni, mert célom volt egy teljesen nyílt megoldás készítése, ami nyílt szoftverekre épül és nem függ egy konkrét megoldástól. Továbbá így előfizetésre se volt szükségem.
|
A megvizsgált \acrshort{paas} rendszereket azért nem szerettem volna használni, mert célom volt egy teljesen nyílt megoldás készítése, ami nyílt szoftverekre épül és nem függ egy konkrét megoldástól. Továbbá így előfizetésre se volt szükségem.
|
||||||
|
|
||||||
A \textit{KubeFed} saját ütemezőt nem implementál (mint ahogy egyik másik vizsgált megoldás sem). Viszont az általa megvalósított egységes vezérlő felületnek köszönhetően nagyon könnyen képesek vagyunk az egyes komponenseket adatközpontokra mozgatni, így könnyen tudunk olyan saját ütemezőt készíteni, ami megvalósítja a feladatot. Emiatt választottam ezt a keretrendszert.
|
A \textit{KubeFed} saját ütemezőt nem implementál (mint ahogy egyik másik vizsgált megoldás sem). Viszont az általa megvalósított egységes vezérlő felületnek köszönhetően nagyon könnyen képesek vagyunk az egyes komponenseket adatközpontokra mozgatni, így könnyen tudunk olyan saját ütemezőt készíteni, ami megvalósítja a feladatot. Emiatt választottam ezt a keretrendszert és azt, hogy saját ütemezőt készítek.
|
||||||
|
|
||||||
\section{Szolgáltatás létesítés és mozgatás \textit{KubeFed} környezetben}
|
\section{Szolgáltatás létesítés és mozgatás \textit{KubeFed} környezetben}
|
||||||
|
|
||||||
@ -104,6 +104,7 @@ Az áthelyezés így jelentősen leegyszerűsödik, hiszen csak arra van szüks
|
|||||||
A vezérlést megvalósító szolgáltatás komponensek indításáért ebben az alkalmazásban külön szolgáltatás felel, ezért ez az a szoftverkomponens, amelynek támogatnia kell a dinamikus ütemezési döntések alkalmazását.
|
A vezérlést megvalósító szolgáltatás komponensek indításáért ebben az alkalmazásban külön szolgáltatás felel, ezért ez az a szoftverkomponens, amelynek támogatnia kell a dinamikus ütemezési döntések alkalmazását.
|
||||||
|
|
||||||
\section{Ütemező rendszer}
|
\section{Ütemező rendszer}
|
||||||
|
\label{sec:scheduler}
|
||||||
|
|
||||||
Bár a két alkalmazás működése és igényei jelentősen eltérnek, szerettem volna egy olyan rendszert megalkotni, aminek segítségével mindkét alkalmazás ütemezése megoldható. A szoftver tervezése során figyelembe vettem azokat a közös funkcionalitásokat, amelyeket mindkét alkalmazás egyformán használ. Emellett szétválasztottam azokat a komponenseket, amelyek alkalmazás specifikus funkciót valósítanak meg.
|
Bár a két alkalmazás működése és igényei jelentősen eltérnek, szerettem volna egy olyan rendszert megalkotni, aminek segítségével mindkét alkalmazás ütemezése megoldható. A szoftver tervezése során figyelembe vettem azokat a közös funkcionalitásokat, amelyeket mindkét alkalmazás egyformán használ. Emellett szétválasztottam azokat a komponenseket, amelyek alkalmazás specifikus funkciót valósítanak meg.
|
||||||
|
|
||||||
@ -215,3 +216,9 @@ Szerettem volna egy olyan megoldást készíteni, amely nem csak az adatközpont
|
|||||||
Ezt úgy oldottam meg, hogy felkonfiguráltam egy egyszerű webszerver konténert, amely minden kérésre egyből egy üres válasszal válaszol. Ezt a konténert \textit{KubeFed} segítségével úgy futtattam, mint bármelyik másik szolgáltatást minden adatközpontban. Ezt a szolgáltatást kiajánlottam minden adatközpont publikus címére. A szkriptem pedig a \acrshort{http} kérés körülfordulási idejét méri.
|
Ezt úgy oldottam meg, hogy felkonfiguráltam egy egyszerű webszerver konténert, amely minden kérésre egyből egy üres válasszal válaszol. Ezt a konténert \textit{KubeFed} segítségével úgy futtattam, mint bármelyik másik szolgáltatást minden adatközpontban. Ezt a szolgáltatást kiajánlottam minden adatközpont publikus címére. A szkriptem pedig a \acrshort{http} kérés körülfordulási idejét méri.
|
||||||
|
|
||||||
Az így mért értékeket az ütemező fel tudja használni arra, hogy eldöntse, hogy melyik adatközpontra ütemezze be a robotkarok vezérléséhez szükséges szolgáltatást.
|
Az így mért értékeket az ütemező fel tudja használni arra, hogy eldöntse, hogy melyik adatközpontra ütemezze be a robotkarok vezérléséhez szükséges szolgáltatást.
|
||||||
|
|
||||||
|
\subsection{Robotkarok vezérlésének átalakítása}
|
||||||
|
|
||||||
|
A robotkarok vezérlését megvalósító komponens a \textit{Kubernetes} \acrshort{api} interfészét használva indítja el \textit{KubeFed} segítségével az egyes \textit{programok} végrehajtását végző szolgáltatásokat. Ahhoz, hogy ezeket a szolgáltatásokat dinamikusan a legideálisabb környezetben indítsa el, arra van szükség, hogy szolgáltatás indítása előtt lekérje a \textit{Mérés kezelő} szolgáltatásból az egyes adatközpontok felé a cél telephely késleltetését, ezután pedig kiválassza azt, ahol legkisebb a késleltetés.
|
||||||
|
|
||||||
|
A viselkedés implementálása egy \acrshort{http} \acrshort{api} hívást igényelt csak, közvetlenül az ütemezés kezdete előtt. Ezzel lekérte a szolgáltatásból a linkek késleltetésének középértékét az elmúlt két percre vetítve. Ezután egy minimum függvénnyel meghatározható volt, hogy melyik adatközpontban kerüljön ütemezésre a szolgáltatás.
|
@ -1,6 +1,7 @@
|
|||||||
% !TeX root = ../thesis.tex
|
% !TeX root = ../thesis.tex
|
||||||
%----------------------------------------------------------------------------
|
%----------------------------------------------------------------------------
|
||||||
\chapter{Teszt környezet kialakítása}
|
\chapter{Teszt környezet kialakítása}
|
||||||
|
\label{ch:test_system}
|
||||||
%----------------------------------------------------------------------------
|
%----------------------------------------------------------------------------
|
||||||
|
|
||||||
A munkám során elkészített és módosított szoftverek helyes működésének demonstrálása egy teljes peremhálózati és felhő számítástechnikai rendszer kiépítését igénylik. Mivel az ilyen környezetek sokszor nem állnak rendelkezésünkre, ezért szükség van egy olyan megoldásra, amely jól modellezi az ilyen rendszerek működését, így képesek vagyunk az alkalmazásainkat telepíteni benne.
|
A munkám során elkészített és módosított szoftverek helyes működésének demonstrálása egy teljes peremhálózati és felhő számítástechnikai rendszer kiépítését igénylik. Mivel az ilyen környezetek sokszor nem állnak rendelkezésünkre, ezért szükség van egy olyan megoldásra, amely jól modellezi az ilyen rendszerek működését, így képesek vagyunk az alkalmazásainkat telepíteni benne.
|
||||||
@ -161,7 +162,7 @@ Elmondható ezek alapján, hogy a tesztkörnyezet futtatásához legalább 36.5
|
|||||||
|
|
||||||
A kliensek száma és erőforrás igénye teljesen a használt alkalmazástól függ. Itt ezért kezdetben 2 Gigabyte memóriát allokáltam, majd később kibővítettem, amikor szükség volt rá.
|
A kliensek száma és erőforrás igénye teljesen a használt alkalmazástól függ. Itt ezért kezdetben 2 Gigabyte memóriát allokáltam, majd később kibővítettem, amikor szükség volt rá.
|
||||||
|
|
||||||
Processzor tekintetében nem fedeztem fel különösen nagy elvárásokat. Tapasztalataim szerint a rendszer stabilan működött egy 2011-ben gyártott négymagos \textit{Intel}\textregistered \textit{Core}\texttrademark i7-3770 processzoron.
|
Processzor tekintetében nem fedeztem fel különösen nagy elvárásokat. Tapasztalataim szerint a rendszer stabilan működött egy 2011-ben gyártott négymagos \textit{Intel}\textregistered \ \textit{Core}\texttrademark \ i7-3770 processzoron.
|
||||||
|
|
||||||
A lemez elérések teljesítménye viszont egy jelentős tényező volt a rendszer teljesítménye szempontjából. A környezet önmagában stabilan üzemelt egy \acrshort{raid}5 tömbre telepítve, amelyet 8 darab 15.000 percenkénti fordulatú hagyományos mechanikus diszk alkotott. Viszont amint feltelepítettem a tesztelésre szánt alkalmazásokat a tárhely elérési késleltetés jelentősen megnőtt olyan mértékekig amik az alkalmazás instabil működését és átmeneti összeomlását okozták. Ezért mindenképpen ajánlott ilyen rendszert \acrshort{ssd} lemezekből álló tárhely tömbre telepíteni.
|
A lemez elérések teljesítménye viszont egy jelentős tényező volt a rendszer teljesítménye szempontjából. A környezet önmagában stabilan üzemelt egy \acrshort{raid}5 tömbre telepítve, amelyet 8 darab 15.000 percenkénti fordulatú hagyományos mechanikus diszk alkotott. Viszont amint feltelepítettem a tesztelésre szánt alkalmazásokat a tárhely elérési késleltetés jelentősen megnőtt olyan mértékekig amik az alkalmazás instabil működését és átmeneti összeomlását okozták. Ezért mindenképpen ajánlott ilyen rendszert \acrshort{ssd} lemezekből álló tárhely tömbre telepíteni.
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ A robotokat 125Hz-es rátával kell vezérelni (azaz 8ms-ként kell utasítást
|
|||||||
|
|
||||||
|
|
||||||
\subsubsection{Szimulátor}
|
\subsubsection{Szimulátor}
|
||||||
|
\label{sec:ursim_simulator}
|
||||||
|
|
||||||
A tanszéken található kettő robotkar természetesen nem áll mindig rendelkezésre. Más csapatok más-más projektekben is használják. A fejlesztés és a tesztelés megkönnyítésére több szimulátor is megvizsgálásra került a projekten korábban dolgozó csapat által. Végül a leghatékonyabban használhatónak a \textit{DockURSim}\footnote{\url{https://github.com/ahobsonsayers/DockURSim}} bizonyult.
|
A tanszéken található kettő robotkar természetesen nem áll mindig rendelkezésre. Más csapatok más-más projektekben is használják. A fejlesztés és a tesztelés megkönnyítésére több szimulátor is megvizsgálásra került a projekten korábban dolgozó csapat által. Végül a leghatékonyabban használhatónak a \textit{DockURSim}\footnote{\url{https://github.com/ahobsonsayers/DockURSim}} bizonyult.
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
% Declaration and Abstract
|
% Declaration and Abstract
|
||||||
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
\include{include/declaration}
|
\include{include/declaration}
|
||||||
%\include{content/abstract}
|
\include{content/abstract}
|
||||||
|
|
||||||
|
|
||||||
% The main part of the thesis
|
% The main part of the thesis
|
||||||
@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
% Appendix
|
% Appendix
|
||||||
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
%\include{content/appendices}
|
\include{content/appendices}
|
||||||
|
|
||||||
%\label{page:last}
|
%\label{page:last}
|
||||||
\end{document}
|
\end{document}
|
||||||
|
Loading…
Reference in New Issue
Block a user