\documentclass[a4paper]{article}
\usepackage{graphicx}
\usepackage{eepic}
\usepackage{pst-all}
\usepackage{amsmath, amsthm}
\usepackage[latin1]{inputenc}
\usepackage[cyr]{aeguill}
\usepackage[francais]{babel}
\usepackage{listings}

%\usepackage{pdftricks}

%\usepackage{bookman}
%\usepackage{helvet}
%\usepackage{newcent}
%\usepackage{aeguill}

\DeclareMathOperator{\sinc}{sinc}



%\lstset{language=MATLAB}
%\lstset{basicstyle=\footnotesize,frame=single}

%\newenvironment{nom}[nb_arg]{avant}{après}

\newcommand{\projectName}{\emph{hydroMEX3 }} %current project name

%MATLAB code listings:
\newcommand{\MATcode}
{
	\lstset{language=MATLAB}
	\lstset{basicstyle=\footnotesize,frame=single,showstringspaces=false}
}
%MATLAB code line:
\newcommand{\MATline}
{
	\lstset{language=MATLAB}
	\lstset{basicstyle=\normalsize,frame=none,showstringspaces=false}
}
%C code listings:
\newcommand{\Ccode}
{
	\lstset{language=C}
	\lstset{basicstyle=\footnotesize,frame=single,showstringspaces=false}
}
%C code line:
\newcommand{\Cline}
{
	\lstset{language=C}
	\lstset{basicstyle=\normalsize,frame=none,showstringspaces=false}
}


\newcommand{\vbeg}{\left( \begin{array}{c} } 
\newcommand{\vend}{ \end{array} \right)} 




\begin{document}

%titre etc...:
\title{Modélisation et contrôle de l'Hydroptère}
\author{Projet de semestre \vspace{22pt}\\
	Basile Graf 	\vspace{0.1in} \\
	Collaborateurs responsables: Sébastien Gros, Phillipe Müllhaupt\\
	Prof. Dominique Bonvin\\
  Ecole Polytechnique Fédérale de Lausanne\\
  \texttt{basile.graf@epfl.ch}}
\date{\today}
\maketitle

\vspace{15pt}

\begin{figure}[htbp]
	\centering
		\includegraphics[width=0.55\textwidth]{figures/hydro_1st_page.png}
\end{figure}

\vspace{2cm}


\pagebreak




% Résumé:
\begin{abstract}
Ce document est une partie du compte-rendu concernant mon projet de semestre \emph{Modélisation et contrôle de l'Hydroptère}. L'autre partie du compte rendu étant la documentation du programme. Les principaux buts du projet ont été de développer une implémentation rapide du modèle de l'hydroptère et de l'intégrer dans une réalité virtuelle en temps réel. Pour ce faire, un programme de traduction automatique de MATLAB en C/C++ pour certaines parties de code a été écrit. Le modèle entier a également été écrit en C/C++ et un solver d'équations différentielles partielles en C a été utilisé. Un graphisme 3D en OpenGL pour un rendu temps réel a été écrit.\\
Les résultats sont une vitesse de calcul multipliée par plus de mille pour la simulation du modèle ainsi que la possibilité de piloter et de voir évoluer l'Hydroptère, même sur un ordinateur de puissance courante.
\end{abstract}

\vspace{30pt}


%Table des matière:
 \tableofcontents

\newpage


%Sections:
\section*{Introduction}

L'Hydroptère est un voilier à hydrofoils (surfaces portantes aquatiques). Les foils génèrent suffisamment de poussée pour porter le bateau ce qui réduit drastiquement les forces de frottement avec l'eau. Lorsque l'équilibre des forces est atteint, les coques de l'Hydroptère ne sont plus en contact avec l'eau et celui-ci "vole" grâce à ses foils et atteint ainsi des vitesses nettement supérieures à celles atteintes par des voiliers classiques. Cependant, l'Hydrofoil présente le désavantage d'être peu stable.\\
Ces considérations rendent intéressante l'idée de pouvoir disposer d'un modèle de la machine et de pouvoir ainsi tester différentes stratégies de contrôle.






\newpage



\section{Modèle MATLAB de l'hydroptère}
On donne ici une brève description du modèle MATLAB de l'hydroptère qui a servi de base pour le projet \cite{origiProg}.

\subsection{Géométrie}
Pour le calcule de la dynamique du modèle, on considère le bateau comme un objet solide  dans l'espace. Comme le montre la figure \ref{coord}, le bateau possède six degrés de liberté: trois pour sa position et trois pour son attitude.

\begin{figure}[htbp]
	\centering
		\includegraphics[width=0.5\textwidth]{figures/coord.png}
	\caption{Six degrés de liberté pour un objet solide dans l'espace}
	\label{coord}
\end{figure}

\begin{equation}
\vec{r}= \left( \begin{array}{c} x\\y\\z \end{array} \right) \ \ \ \ \ \vec{a}= \left( \begin{array}{c} \phi\\ \theta\\ \psi \end{array} \right)
\label{eq1}
\end{equation} 

Pour décrire la dynamique du système, nous avons donc besoin des coordonnées $\vbeg \vec{r} \\ \vec{a} \vend$ et de leur dérivées temporelles $\vbeg \dot{\vec{r}} \\ \dot{\vec{a}} \vend$ comme variables d'état.\\
L'état est donc décrit par

\begin{equation}
\vec{q} = \vbeg \vec{r} \\ \vec{a} \\ \dot{\vec{r}} \\ \dot{\vec{a}} \vend, \ \ \ \dim{(\vec{q})}=12
\label{eq2}
\end{equation}

L'évolution temporelle d'un tel système est décrite par un système d'équations différentielles du type

\begin{equation}
\dot{\vec{q}}=f(\vec{q}, \vec{Q}, \vec{p})
\label{eq3}
\end{equation}

\begin{itemize}
	\item[] $\vec{q}$: état
	\item[] $\vec{Q}$: forces appliquées
	\item[] $\vec{p}$: paramètres (positions des gouvernes, vent, etc...)\\
\end{itemize}

Le premier objectif est donc de déterminer la fonction vectorielle $f$. Cette fonction est (très) complexe. Ensuite, une intégration numérique du problème permet de simuler le comportement du bateau.



\subsection{Détermination du second membre}

La détermination de la fonction $f$ \eqref{eq3} se fait en grande partie par le calcul du Lagrangien et de ses dérivées partielles. Ce calcul tient également compte des forces généralisées appliquées au système.

\begin{eqnarray}
L=E_{cin}-E_{pot} \\[10pt]
\frac{\partial}{\partial t} \frac{\partial L}{\partial \dot{q_i}} - \frac{\partial L}{\partial q_i} = Q_i
\label{eq4}
\end{eqnarray}

Mais à leur tour, les forces généralisées $Q_i$ sont des fonctions des paramètres $\vec{p}$ et de l'état $\vec{q}$

\begin{equation}
Q_i = g_i(\vec{p}, \vec{q})
\label{eq5}
\end{equation}

Les fonctions $g_i$ expriment les dépendances des $Q_i$ à la position et à l'attitude (matrice de rotation) de la machine ainsi qu'à tous les paramètres extérieurs (hauteur de la mer par rapport aux surfaces portantes, vent, etc...).
La figure \ref{modele} montre un schéma bloc du programme MATLAB utilisé pour générer le modèle. On y utilise le toolbox de calcul symbolique pour générer des expressions qui pourront ensuite être évaluées numériquement lors de l'intégration.

\begin{figure}[htbp]
	\centering
		\includegraphics[width=0.65\textwidth]{figures/modele.png}
	\caption{Schéma bloc de la génération du modèle}
	\label{modele}
\end{figure}
  


\subsection{Limitations}

Les expressions à évaluer lors de chaque pas d'intégration générée par le programme sont très grandes et nécessitent des temps de calcul non négligeables (les chaînes de caractères qui représentent ces expressions dépassent $20000$ caractères pour certaines d'entre elles).\\
Dans la version MATLAB de la simulation (utilisation du solver \texttt{ode45(...)}), le temps relatif de simulation sur un Pentium IV à 1.7GHz est de environ $400$\%. On est encore loin d'une simulation en temps réel avec affichage simultané.



\newpage



\section{Conversion MATLAB - C/C++}

La raison pour laquelle la simulation est 'lente' tient au fait que MATLAB est un langage interprété. Comme nous le verrons, la traduction du modèle en C/C++ et sa compilation permettront un gain de vitesse dramatique. MATLAB propose une routine de traduction en C (MATLAB compiler), mais le code généré n'est en réalité qu'un interpréteur réduit exécutant des versions encryptées des fichiers de code (\texttt{.m}) fournis. Le programme résultant est donc bien un exécutable indépendant de MATLAB, mais n'est en aucun cas plus rapide que le programme de départ.\\
Comme nous l'avons vu, les expressions à évaluer sont très longues et les syntaxes de base de MATLAB et du C/C++ diffèrent légèrement. Par exemple, \texttt{3} doit être remplacé par \texttt{3.}, \texttt{3.0} ou \texttt{3.0f} pour ne pas être interprété comme un nombre entier, \texttt{a}\texttt{\^}\texttt{b} doit être remplacé par \texttt{pow(a,b)}, \texttt{\^} étant un opérateur logique en C/C++ (la surcharge serait également une solution). Une stratégie de type \emph{copier-coller-remplacer} est donc suicidaire, voire impossible.\\
Une première fonction a donc été écrite, \texttt{m2c()}, qui a pour tâche de traduire une expression d'opérateurs MATLAB en une expression d'opérateurs C. Par exemple

\MATline
\begin{lstlisting}{}
m2c('a^(1/2)+exp(b)+c^d')
\end{lstlisting}

donne

\Cline
\begin{lstlisting}{}
sqrt(a)+exp(b)+pow(c,d)
\end{lstlisting}

Attention, la confusion entre nombres entiers et nombres à virgule flottante n'est pas  traitée par \texttt{m2c}.\\
Nous n'en sommes pas pour autant au bout de nos peines, car si une expression MATLAB peut directement être évaluée, on ne peut pas directement compiler son équivalent en C/C++. Par ailleurs, les expressions du modèle sont complexes, mais contiennent beaucoup de sous-expressions redondantes. Pour un calcul efficace, il est donc intéressant de pouvoir précalculer ces sous-expressions. La nature du modèle fait également que les fonctions trigonométriques sinus et cosinus (projections) sont très fréquemment répétées, elles seront donc également recherchées et précalculées.\\
Une deuxième fonction \texttt{sym2c()} a été écrite, qui utilise entre autre \texttt{m2c()} et la fonction de recherche de sous-expressions du Symbolic Toolbox \texttt{subexpr()}. \\

\MATline
\begin{lstlisting}{}
[cfun, hdecl] = sym2c(varName, expr, funcname, cfun, hdecl) 
\end{lstlisting}

\vspace{12pt}

\begin{itemize}
\item[$\bullet$ \texttt{varName \ }]      Cell-array contenant les noms (\emph{strings}) des variables évaluées par \texttt{expr}.
\item[$\bullet$ \texttt{expr \ \ \ \ }]   Expression(s) symbolique(s) (classe \texttt{sym}). La dimension de \texttt{expr} doit être la même que le nomre de strings donnés dans \texttt{varName}.
\item[$\bullet$ \texttt{funcname }]     Nom de la fonction C/C++ à générer qui contiendra les évaluations.
\item[$\bullet$ \texttt{cfun \ \ \ \ }]   Cell-array à compléter. Chaque élement de \texttt{cfun} contient une ligne de code du fichier \texttt{.cpp} (code source) à générer sous la forme d'un string.
\item[$\bullet$ \texttt{hdecl \ \ \ }]    Cell-array à compléter. Chaque élement de \texttt{hdecl} contient une ligne de code du fichier \texttt{.h} (fichier header) à générer sous la forme d'un string.
\end{itemize}


Cette fonction peut-être utilisée pour générer des fichiers de code source compilable.



\subsection{Exemple de conversion}

On donne ici un exemple d'un script MATLAB pour générer du code source C/C++ à partir d'expressions symbolique. Ce code est fourni dans le fichier \texttt{CconversionExample.m}. \\



\MATcode
\begin{lstlisting}{}

clear all;

syms x y alpha beta       % variables
syms a b c real

%define (example) symbolic expressions:
symExpr1 = 2*sin(alpha)^2 + (1+y)^(3/2) + (5/4)*(1+2*sin(alpha)^2)
                            % First C/C++ function to be generated

%example with vectorial symbolic variable:
symExpr21 = solve(sym('x^3 + a*x^2 + b*x + c')) %result 
% is a sybolic expression with 3 elements (the 3 solutions to the 
% equation). The equations are pretty complicated and contains 
% common (repeated) subexpressions.
symExpr22 = x + y + cos(alpha) % second expression (scalar) for the
                               % second C/C++ function to be 
                               % generated         

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% Generate C/C++ files from these expressions %%%%%%%%%%%%

% A .cpp source file and a .h header file must be generated.
% All variables in C/C++ code are assumed to be part of a 
% datastructure (d) of type datas. 
% Each code line is stored as a string in a cell-array, cfun for 
% .cpp file and hdecl for the .h header file.

tic
disp('Starting C++ code generation') 

clear cfun;
clear hdecl;

%.cpp:
cfun{1}=['#include "conversionDemo.h" \n' ...
         '#include "toBeIncluded1.h" \n' ...
         '#include "toBeIncluded2.h" \n\n']; %files your code needs
cfun{2}=['// File generated on ' date ...
         ', Basile.Graf@epfl.ch \n\n\n'];

%.h:
hdecl{1}=['#ifndef CONVERSION_DEMO_H_DEF \n'
          '#define CONVERSION_DEMO_H_DEF \n \n'];
          %preprocessor constant, !!! MUST be a different name
          %for each file you create !!!
hdecl{2}=['// File generated on ' date ...
          ', Basile.Graf@epfl.ch \n\n\n'];

%function for symExpr1:
varName = {'symExpr1'};
expr = {symExpr1};
[cfun, hdecl] = sym2c(varName, expr, 'cfunction1', cfun, hdecl);

%function for symExpr21 and symExpr22:
varName = {'symExpr21','symExpr22'};
expr = {symExpr21, symExpr22};
[cfun, hdecl] = sym2c(varName, expr, 'cfunction2', cfun, hdecl);


hdecl{length(hdecl)+1}=['#endif \n']; %#endif preprocessor line 
                                      %at end of .h

%write to .cpp:
fid = fopen('conversionDemo.cpp','wt');
for k = 1:length(cfun)
   fprintf(fid,cfun{k}); 
end
fclose(fid);

%write to .h
fid = fopen('conversionDemo.h','wt');
for k = 1:length(hdecl)
   fprintf(fid,hdecl{k}); 
end
fclose(fid);

toc
disp('C++ code generation finished') %be happy

\end{lstlisting}



L'évaluation de l'expression \texttt{symExpr1} se fera donc dans une fonction nommée \texttt{cfunction1()} et le résultat sera stocké dans la variable nommée \texttt{symExpr1}. La fonction nommée \texttt{cfunction1()} évaluera les expressions \texttt{symExpr21} et \texttt{symExpr22} et stockera les résultat dans \texttt{symExpr21[0]} à \texttt{symExpr21[2]} et \texttt{symExpr22}.\\
Vu le grand nombre de variables d'entrée/sortie, on créera une structure de données de nom \texttt{datas} et c'est un pointeur vers celle-ci qui sera passé aux fonctions C/C++. Dans notre exemple, la structure pourrait-être écrite comme suit:\\


\Ccode
\begin{lstlisting}{}
struct datas
{
	double x, y;
	double alpha, beta;
	double a, b, c;
};
\end{lstlisting}



\subsection{Codes générés}

Dans notre exemple, on obtient les codes suivants.\\


\texttt{conversionDemo.h}:

\Ccode
\begin{lstlisting}{}
#ifndef CONVERSION_DEMO_H_DEF 
#define CONVERSION_DEMO_H_DEF 
 
// File generated on 05-Jun-2006, Basile.Graf@epfl.ch 


 void cfunction1(datas *d); 
 
 void cfunction2(datas *d); 
 
#endif 

\end{lstlisting}

\vspace{20pt}

\texttt{conversionDemo.cpp}:

\Ccode
\begin{lstlisting}{}
#include "conversionDemo.h" 
#include "toBeIncluded1.h" 
#include "toBeIncluded2.h" 

// File generated on 05-Jun-2006, Basile.Graf@epfl.ch 


 void cfunction1(datas *d) { 
 
double trigoV[1]; 
 
trigoV[0] = sin(d->alpha);
 
 
d->symExpr1 = 4.5000000000000000000000000000000*pow(trigoV[0],2)+
        pow((1.+d->y),(3/2))+1.2500000000000000000000000000000;
return; 
} 
 
 
 void cfunction2(datas *d) { 
 
double tempV[1]; 
double trigoV[1]; 
 
trigoV[0] = cos(d->alpha);
 
tempV[0] = 36.*d->b*d->a-108.*d->c-8.*pow(d->a,3)+12.*sqrt((12.*
        pow(d->b,3)-3.*pow(d->b,2)*pow(d->a,2)-54.*d->b*d->a*
        d->c+81.*pow(d->c,2)+12.*d->c*pow(d->a,3)));
 
d->symExpr21[0] = .16666666666666666666666666666667*pow(tempV[0],
        (1/3))-6.*(.33333333333333333333333333333333*d->b-
        .11111111111111111111111111111111*pow(d->a,2))/pow(
        tempV[0],(1/3))-.33333333333333333333333333333333*d->a;
        
d->symExpr21[1] = -.83333333333333333333333333333333e-1*pow(
        tempV[0],(1/3))+3.*(.33333333333333333333333333333333*
        d->b-.11111111111111111111111111111111*pow(d->a,2))/
        pow(tempV[0],(1/3))-.33333333333333333333333333333333*
        d->a+.86602540378443864676372317075295*i*
        (.16666666666666666666666666666667*pow(tempV[0],(1/3))+
        6.*(.33333333333333333333333333333333*d->b-
        .11111111111111111111111111111111*pow(d->a,2))/
        pow(tempV[0],(1/3)));
        
d->symExpr21[2] = -.83333333333333333333333333333333e-1*pow(
        tempV[0],(1/3))+3.*(.33333333333333333333333333333333*
        d->b-.11111111111111111111111111111111*pow(d->a,2))
        /pow(tempV[0],(1/3))-.33333333333333333333333333333333*
        d->a-.86602540378443864676372317075295*i*
        (.16666666666666666666666666666667*pow(tempV[0],(1/3))
        +6.*(.33333333333333333333333333333333*d->b-
        .11111111111111111111111111111111*pow(d->a,2))/
        pow(tempV[0],(1/3)));
        
d->symExpr22 = d->x+d->y+trigoV[0];
return; 
} 
\end{lstlisting}


Il est à noter que dans cet exemple, l'apparition de la variable complexe $i$ poserait un problème, la classe des nombres complexes n'existant pas par défaut dans C/C++. Mais ceci n'arrive pas dans le cas d'un modèle physique tel que l'hydroptère. Les codes générés dans le cas de l'hydroptère sont évidemment bien plus conséquents et deviennent tout à fait illisibles...




\newpage

\section{Utilisation du programme principal: \projectName}

On présente ici une description du programme principal \projectName (c'est à dire le programme C/C++ compilé et exécutable depuis MATLAB) qui se présente sous la forme d'un exécutable MEX. Un MEX (\underline{M}atlab \underline{EX}ecutable) et est une librairie de fonctions à linkage dynamique (\texttt{.dll} sous Windows) que MATLAB peut exécuter et qui se comporte comme une fonction MATLAB normale. L'avantage est qu'elle peut-être écrite en C/C++, qu'elle est précompilée et qu'elle est donc beaucoup plus rapide qu'un script MATLAB habituel. Un MEX peut également profiter de toutes les possibilités qu'offre C/C++, ce dont on fait usage dans le programme \projectName pour l'affichage 3D en OpenGL et pour l'intégration du système d'équations différentielles partielles avec une librairie spécialisée (CVODE de Sundials \cite{CVODE}).\\




\begin{figure}[htbp]
	\centering
		\includegraphics[width=0.85\textwidth]{figures/mainProg.png}
	\caption{Structure du programme \projectName}
	\label{mainProg}
\end{figure}


La figure \ref{mainProg} donne la structure générale du programme. Le programme est lancé depuis le prompt MATLAB et en reçoit divers paramètres ainsi que les conditions initiales du système. Ensuite, la boucle principale tourne, simule et affiche de manière indépendante de MATLAB. Lorsque la simulation est terminée et selon les paramètres passés, la fenêtre d'affichage est fermée et les résultats de simulation sont retournés ou non au workspace de MATLAB (pour d'éventuelles analyses supplémentaires). 




\subsection{Lancer le programme}

Il faut tout d'abord définir les structures de paramètres et le vecteur de conditions initiales. Ces données sont par exemple générées par le script \texttt{Main.m} qui calcule un point d'équilibre pour les conditions initiales et des dimensions adaptée pour les dimensions de la machine qui sont à préciser. Ces paramètres peuvent avantageusement être sauvés dans un fichier \texttt{.mat}.\\
On peut également définir soi-même un vecteur de condition initiales, par exemple:



\MATline
\begin{lstlisting}{}
>> X0 = [0  0  1.9410  0.01400  0  0  20  0  0  0  0  0];
\end{lstlisting}
\vspace{10pt}

Une structure de paramètres, par exemple:

\MATline
\begin{lstlisting}{}
>> P.reltol = 1e-6;
>> P.abstol = 1e-4;
>> P.param = [1.9613 ...  % x foil position
              0.0017...   % tan(cal angle of yaw)
              1.9410...
              0.0140...
              0.2291...   % tan(cal angle of sail)
              1.2938...   % G-shift
              42.5347...  % bridge-foil angle (deg)
              20... 
              2.0915...   % wind angle
              1];         % z foil position
\end{lstlisting}
\vspace{10pt}


Une structure de paramètres pour le joystick, par exemple:

\MATline
\begin{lstlisting}{}
>> jP4.doX: 1     % use jostick x-axis, 0: keyboard
>> jP4.doY: 1     % use jostick y-axis, 0: keyboard
>> jP4.doZ: 1     % use jostick z-axis, 0: keyboard
>> jP4.doR: 1     % use jostick r-axis, 0: keyboard
>> jP4.dirX: -1   % inverse positive joystick x direction
>> jP4.dirY: 1    % do not inverse
>> jP4.dirZ: -1   % inverse
>> jP4.dirR: -1   % inverse
\end{lstlisting}
\vspace{10pt}


On peut ensuite lancer le programme:

\MATline
\begin{lstlisting}{}
>> [sim_out,t_sim_out,numStep] = hydroMEX3(20,X0,P,jP4); 
>> clear hydroMEX3
\end{lstlisting}
\vspace{10pt}

Le premier paramètre donné est le temps de simulation désiré, ici, $20$ secondes. Si le temps de simulation désiré est $0$, la simulation est lancée et ne s'arrête que lorsque la fenêtre graphique est fermée; dans ce cas, aucun résultat de simulation n'est retourné. Les trois derniers paramètres sont ceux décrits plus haut. Le dernier paramètre (joystick) est optionnel (valeurs par défaut).\\
Les paramètres retournés sont: une matrice (\texttt{sim\_out}) contenant le vecteur d'état à chaque instant défini  par le vecteur temps (\texttt{t\_sim\_out}). \texttt{numStep} donne le nombre total de pas de simulation effectués par le solver (alors que les pas retournés sont ceux correspondant à chaque image affichée).



\subsection{Utiliser le programme}

La figure \ref{hydro_printScreen} est une copie d'écran du programme en action.


\begin{figure}[htbp]
	\centering
		\includegraphics[width=1.00\textwidth]{figures/hydro_printScreen.png}
	\caption{\projectName en action}
	\label{hydro_printScreen}
\end{figure}


En haut à gauche se trouve une girouette indiquant la direction du vent (flèche rouge) et celle de la baume (jaune). En bas à droite se trouve une cible indiquant la position des deux axes principaux du joystick (profondeur et différentiel du calage des foils) ainsi que deux sliders, un horizontal pour la commande de direction (lacet) et un vertical pour le calage commun des foils. En bas à gauche apparaissent certaines informations importantes.\\ \\
Contrôle par le clavier:
  \vspace{6pt}
\begin{itemize}
	\item[\texttt{'Q'} et \texttt{'V'}]: Tourner la caméra autour du bateau sur un plan horizontal.
	\item[\texttt{'E'} et \texttt{'R'}]: Tourner la caméra autour du bateau sur un plan vertical.
	\item[\texttt{'T'} et \texttt{'Z'}]: Rapprocher / éloigner la caméra du bateau.
	\vspace{6pt}
	\item[\texttt{'X'}]: Inverser la direction positive de l'axe X du joystick.
	\item[\texttt{'Y'}]: Inverser la direction positive de l'axe Y du joystick.
	\item[\texttt{'V'}]: Inverser la direction positive de l'axe Z du joystick.
	\item[\texttt{'C'}]: Inverser la direction positive de l'axe R du joystick.
	\vspace{6pt}
	\item[\texttt{'1'}]: Utiliser le joystick ou le clavier pour l'axe X.
	\item[\texttt{'2'}]: Utiliser le joystick ou le clavier pour l'axe Y.
	\item[\texttt{'3'}]: Utiliser le joystick ou le clavier pour l'axe Z.
	\item[\texttt{'4'}]: Utiliser le joystick ou le clavier pour l'axe R.
	\vspace{6pt}
	\item[$\uparrow$ et $\downarrow$]: Axe X lors du pilotage au clavier.
	\item[$\leftarrow$ et $\rightarrow$]: Axe Y lors du pilotage au clavier.
	\item[\texttt{'M'} et \texttt{'N'}]: Axe Z lors du pilotage au clavier.
	\item[\texttt{'H'} et \texttt{'B'}]: Axe R lors du pilotage au clavier.
	\vspace{6pt}
	\item[\texttt{'K'} et \texttt{'L'}]: Relâcher / ramener la baume (angle maximal).
	\vspace{6pt}
	\item[\texttt{'8'} et \texttt{'9'}]: Moins / plus de vent.
	\item[\texttt{'6'} et \texttt{'7'}]: Moins / plus de vagues.
	\vspace{6pt}
\end{itemize}

Le programme retourne à MATLAB si l'on ferme la fenêtre graphique.




\newpage

\section{Documentation du code source}

Une documentation complète du code source de \projectName a été réalisée \cite{doxy}. Elle se présente en deux versions: une version HTML et une version PDF (LateX). Il est conseillé de consulter la documentation HTML (les deux versions contiennent références croisées par hyperliens et graphes structurels, mais la version HTML est passablement plus claire). Les deux versions se trouvent dans les sous-répertoires suivants:\\
\texttt{/doxygen/html/index.html}   \\
\texttt{/doxygen/latex/refman.pdf}  \\ 
 

\newpage


%Bibliographie:
\begin{thebibliography}{9}

%	\bibitem{lamport94}
%	  Leslie Lamport,
%	  \emph{\LaTeX: A Document Preparation System}.
%	  Addison Wesley, Massachusetts,
%	  2nd Edition,
%	  1994.

%rajouter: bouquin de Papa (mécanique), bouquin OpenGL

\bibitem{origiProg}
	Modèle MATLAB de l'Hydroptère ayant servi de base à ce projet\\
	Sébastien Gros,\\
	EPFL

\bibitem{Goldstein}
	Classical Mechanics,\\
	Herbert Goldstein, \\
	Addison-Wesley

\bibitem{waiteCpp}
	The Waite Group's C++ Primer Plus,\\
	Stephen Prata \\
	Sams Publishing
	
\bibitem{CVODE}
	Sundials ODE solver documentation:\\
	User Documentation for cvode v2.4.0\\
	Alan C. Hindmarsh and Radu Serban \\
	Center for Applied Scientifc Computing \\
	Lawrence Livermore National Laboratory \\
	\emph{http://www.llnl.gov/casc/sundials/documentation/cv\_guide.pdf}
	
\bibitem{NeHe}
	Neon Helium's online OpenGL tutorial,\\
	\emph{http://nehe.gamedev.net/}
	
\bibitem{OpenGL}
	OpenGL Programming Guide: The Official Guide to Learning OpenGL,\\
	Mason Woo, Jackie Neider, Tom Davis, Dave Shreiner,\\
	OpenGL Architecture Review Board
	
\bibitem{doxy}
	Manuel du programme de documentation Doxygen,\\
	Dimitri van Heesch, \\
	\emph{http://tesla.desy.de/doocs/doxygen-1.3/doxygen\_manual-1.3.pdf}\\
	Doxygen download (Linux, Win, Mac OSX,...): \\
	\emph{http://www.stack.nl/$\sim$dimitri/doxygen/download.html}
	
\end{thebibliography}





\end{document}