Prog_cate-Mbed - Reception de consigne à revoir -,,,

Dependencies:   Asservissement Encoder_Nucleo_16_bits MYCRAC mbed

Fork of Asserv_mot by Brandon Modon

Files at this revision

API Documentation at this revision

Comitter:
Brand101
Date:
Wed Apr 19 17:50:19 2017 +0000
Commit message:
Dernier version

Changed in this revision

Asservissement.lib Show annotated file Show diff for this revision Revisions of this file
Encoder-Nucleo-16bits.lib Show annotated file Show diff for this revision Revisions of this file
MYCRAC.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Asservissement.lib	Wed Apr 19 17:50:19 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/CRAC-Team/code/Asservissement/#162aa6608ffe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder-Nucleo-16bits.lib	Wed Apr 19 17:50:19 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/CRAC-Team/code/Encoder_Nucleo_16_bits/#c57c8fe63263
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MYCRAC.lib	Wed Apr 19 17:50:19 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/CRAC-Team/code/MYCRAC/#cbe368f18aeb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Apr 19 17:50:19 2017 +0000
@@ -0,0 +1,2327 @@
+#include "mbed.h"
+#include "Nucleo_Encoder_16_bits.h"
+#include <math.h>
+#include "MYCRAC_utility.h"
+#include "Asservissement.h"
+#include "global.h"
+#include "MY_Asserv.h"
+#include "My_ident.h"
+
+//#include "CRAC_utility.h"
+
+//------------------------ prototypes de fcts ------------------------------------
+
+void Asser_Pos_Mot1(double pcons_pos);
+void Asser_Pos_Mot2(double pcons_pos);
+
+void Avancer_ligne_droite(long pcons, short vmax, short amax, short dmax);
+void Avancer_ligne_droite_XYTheta(long pcons, short vmax, short amax, short dmax);
+void Rotation(long pcons, short vmax, short amax, short dmax);
+void Rotation_XYTheta(long pcons, short vmax, short amax, short dmax);
+void X_Y_Theta(long px, long py, long ptheta, long sens, short vmax, short amax);
+
+void Recalage(int pcons, short vmax, short amax, short dir, short nv_val);
+void Rayon_De_Courbure(short rayon, short theta, short vmax, short amax, short sens, short dmax);
+
+void Odometrie(void); // void Odometrie(void);
+void Ralentir(short nouvelle_vitesse);
+void Arret(void);
+
+void canProcessRx(void);
+
+void clacul_odo();
+
+void canRx_ISR();
+void MY_ISR();
+
+
+Serial pc(SERIAL_TX, SERIAL_RX);
+
+
+CAN can1(PB_8, PB_9);
+
+CANMessage canmsg = CANMessage();
+
+char message[8]= {0x00,0x01,0x10,0x11,0x00,0x01,0x10,0x11};
+
+CANMessage msgRxBuffer[SIZE_FIFO]; // buffer en r�ception pour le CAN
+unsigned char FIFO_ecriture=0; //Position du fifo pour la reception CAN
+unsigned char FIFO_lecture=0;//Position du fifo de lecture des messages CAN
+
+Ticker timer;
+Ticker cal_odo;
+
+//------------------------ def de var globales ------------------------------------
+
+PwmOut mot1(PA_8);
+PwmOut mot2(PA_5);
+
+DigitalOut INA_M2(PC_6); //p37
+DigitalOut INB_M2(PC_7); //p38
+DigitalOut INA_M1(PB_0); //P26
+DigitalOut INB_M1(PB_1); //P27
+
+Nucleo_Encoder_16_bits encoder1(TIM3, 0xffff, TIM_ENCODERMODE_TI12);
+Nucleo_Encoder_16_bits encoder2(TIM4, 0xffff, TIM_ENCODERMODE_TI12);
+
+double   consigne_pos, consigne_vit,                 // Consignes de position et de vitesse dans les mouvements
+         commande1, commande2,                       // Commande, aka duty cycle des PWM de chaque moteur
+         last_pos1, last_pos2, pos1, pos2,           // Valeurs des compteurs incr�mentaux aux instants t et t-1
+         ErreurPos1, ErreurPos2, last_ErreurPos1, last_ErreurPos2,       // Valeurs des erreurs de position de la boucle d'asservissement
+         Somme_ErreurPos1, Somme_ErreurPos2,                             // Valeurs des int�grales des erreurs
+         Delta_ErreurPos1, Delta_ErreurPos2,                             // Valeurs des d�riv�es des erreurs
+         Kpp1, Kip1, Kdp1, Kpp2, Kip2, Kdp2,                             // Valeurs des correcteurs d'asservissement pour les 2 moteurs
+         Kpp1a, Kip1a, Kdp1a, Kpp2a, Kip2a, Kdp2a,                       // Valeurs des correcteurs d'asservissement pour les 2 moteurs
+         VMAX, AMAX, DMAX,                                               // Valeurs maximales d'acc�leration, d�c�l�ration et vitesse
+         Odo_x, Odo_y, Odo_theta, Odo_val_pos_1, Odo_val_pos_2, Odo_last_val_pos_1, Odo_last_val_pos_2;  // Variables de positions utilis�es pour l'odom�trie
+uint32_t        roue_drt_init, roue_gch_init;                                   // Valeur des compteurs (!= 0) quand on commence un nouveau mouvement
+short    etat_automate, etat_automate_depl, new_message,
+         xytheta_sens, next_move_xyt, next_move, i, cpt, stop, stop_receive, param_xytheta[3],
+         etat_automate_xytheta, ralentare, recalage_debut, couleur_debut, recalage_debut_receive;
+char     nb_ordres, vitesse_danger, Stop_Danger, cpt_ordre, asser_actif;
+struct Ordre_deplacement liste[200];
+
+uint16_t        ms_count = 0,       // Compteur utilis� pour envoyer �chantillonner les positions et faire l'asservissement
+                ms_count1 = 0,      // Compteur utilis� pour envoyer la trame CAN d'odom�trie
+                flag_odo,
+                test3 = 0,
+                test4 = 0,
+                test5 = 0,
+                test6 =0,
+                test7 =0,
+                test8 =0;
+
+
+
+double test1=0,
+       test2=0;
+
+
+//------------------------ main ------------------------------------
+
+int main()
+{
+    pc.baud(230400);
+    pc.printf("Debut du prog");
+
+    INA_M2 = 0;
+    INB_M2 = 0;
+    INA_M1 = 0;
+    INB_M1 = 0;
+
+    mot1.period(1./20000.);
+    mot2.period(1./20000.);
+    can1.frequency(1000000);
+
+    consigne_pos = 0.0;
+    next_move = 0;
+    asser_actif=1;
+    cpt_ordre = 0;
+    nb_ordres = 1;
+    stop = 1;
+    stop_receive = 1;
+    ralentare = 0;
+    recalage_debut_receive = 0;
+
+    VMAX = 50;
+    AMAX = 125;
+    DMAX = 125;
+
+    roue_drt_init = (encoder1.GetCounter() + 20000);
+    roue_gch_init = COEF_ROUE_GAUCHE * ((double)encoder2.GetCounter() + 20000);
+
+    liste[0] = (struct Ordre_deplacement) {
+        TYPE_DEPLACEMENT_STOP,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+    };
+
+
+    timer.attach(&MY_ISR, 0.001);
+    can1.attach(&canRx_ISR); // cr�ation de l'interrupt attach�e � la r�ception sur le CAN
+
+    cal_odo.attach(&clacul_odo, 0.01);
+    
+    Kpp1 = 0.5;
+    Kip1 = 0.0001;
+    Kdp1 = 0.8;
+
+    Kpp2 = 0.5;
+    Kip2 = 0.0001;
+    Kdp2 = 0.8;
+
+    while(1) {
+        //TEST
+        //Asser_Pos_Mot1(0.0);
+        //Asser_Pos_Mot2(0.0);
+        //test3++;
+
+        canProcessRx();
+
+        if(flag_odo) {
+            flag_odo = 0;
+            Odometrie();
+        }
+        pc.printf("init_d:%d inti_g:%d dit:%hd t8:%d\n", roue_drt_init, roue_gch_init, liste[cpt_ordre].distance, test8);
+
+        //pc.printf("com1=%f com2=%f ePos1=%f ePos2=%f  enc2=%d  enc1=%d\n",commande1, commande2, ErreurPos1, ErreurPos2, encoder2.GetCounter(), encoder1.GetCounter());
+        //wait(0.001);
+        //pc.printf("t1=%d t2=%d t3=%d t4=%d t5=%d t6=%d t7=%d      drt_init=%f  g_init=%f \n", test1, test2, test3, test4, test5, test6, test7, roue_drt_init, roue_gch_init);
+        /*
+        write_PWM2(commande2);
+        if(ms_count==19) {
+            test3++;
+        }
+        */
+    }
+}
+
+void clacul_odo()
+{
+    flag_odo = 1;
+}
+
+void canRx_ISR()
+{
+    if (can1.read(msgRxBuffer[FIFO_ecriture])) {
+        FIFO_ecriture=(FIFO_ecriture+1)%SIZE_FIFO;
+        /*
+        if(msgRxBuffer[FIFO_ecriture].id==RESET_STRAT) mbed_reset();
+        else FIFO_ecriture=(FIFO_ecriture+1)%SIZE_FIFO;
+        */
+    }
+}
+
+void canProcessRx(void)
+{
+    static signed char FIFO_occupation=0,FIFO_max_occupation=0;
+    CANMessage msgTx=CANMessage();
+    FIFO_occupation=FIFO_ecriture-FIFO_lecture;
+    if(FIFO_occupation<0)
+        FIFO_occupation=FIFO_occupation+SIZE_FIFO;
+    if(FIFO_max_occupation<FIFO_occupation)
+        FIFO_max_occupation=FIFO_occupation;
+    if(FIFO_occupation!=0) {
+
+        switch(msgRxBuffer[FIFO_lecture].id) {
+            case ASSERVISSEMENT_INFO_CONSIGNE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_INFO_CONSIGNE);
+                Send_assev_info_comfig();
+                break;
+            case ASSERVISSEMENT_CONFIG_KPP_DROITE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG_KPP_DROITE);
+                break;
+            case ASSERVISSEMENT_CONFIG_KPI_DROITE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG_KPI_DROITE);
+                break;
+            case ASSERVISSEMENT_CONFIG_KPD_DROITE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG_KPD_DROITE);
+                break;
+            case ASSERVISSEMENT_CONFIG_KPP_GAUCHE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG_KPP_GAUCHE);
+                break;
+            case ASSERVISSEMENT_CONFIG_KPI_GAUCHE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG_KPI_GAUCHE);
+                break;
+            case ASSERVISSEMENT_CONFIG_KPD_GAUCHE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG_KPD_GAUCHE);
+                break;
+            case ASSERVISSEMENT_ENABLE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_ENABLE);
+                asser_actif = msgRxBuffer[FIFO_lecture].data[0];
+                break;
+                /*
+                case ODOMETRIE_SMALL_POSITION:
+                SendAck(ACKNOWLEDGE_MOTEUR, ODOMETRIE_SMALL_POSITION);
+                Odometrie();  // il envoie automatiquement d'odo apr�s calcule
+                break;
+                */
+            case ODOMETRIE_SMALL_VITESSE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ODOMETRIE_SMALL_VITESSE);
+                SendSpeed(consigne_pos, 0);
+                break;
+
+            case ASSERVISSEMENT_STOP:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_STOP);
+                stop_receive = 1;
+                liste[cpt_ordre].type = TYPE_DEPLACEMENT_STOP;
+                break;
+
+            case ASSERVISSEMENT_SPEED_DANGER:  //
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_SPEED_DANGER);
+                break;
+
+            case ASSERVISSEMENT_XYT:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_XYT);
+                etat_automate_xytheta = 1;
+                liste[cpt_ordre].type = TYPE_DEPLACEMENT_X_Y_THETA;
+                liste[cpt_ordre].x = (msgRxBuffer[FIFO_lecture].data[0]) + (msgRxBuffer[FIFO_lecture].data[1] << 8);
+                liste[cpt_ordre].y = (msgRxBuffer[FIFO_lecture].data[2]) + (msgRxBuffer[FIFO_lecture].data[3] << 8);
+                liste[cpt_ordre].theta = (msgRxBuffer[FIFO_lecture].data[4]) + (msgRxBuffer[FIFO_lecture].data[5] << 8);
+                liste[cpt_ordre].sens = msgRxBuffer[FIFO_lecture].data[6];
+                break;
+
+            case ASSERVISSEMENT_COURBURE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_COURBURE);
+                liste[cpt_ordre].type = TYPE_DEPLACEMENT_RAYON_COURBURE;
+                liste[cpt_ordre].rayon = (msgRxBuffer[FIFO_lecture].data[0]) + (msgRxBuffer[FIFO_lecture].data[1] << 8);
+                liste[cpt_ordre].theta_ray = (msgRxBuffer[FIFO_lecture].data[2]) + (msgRxBuffer[FIFO_lecture].data[3] << 8);
+                liste[cpt_ordre].sens = msgRxBuffer[FIFO_lecture].data[4];
+                liste[cpt_ordre].enchainement = msgRxBuffer[FIFO_lecture].data[5];
+                break;
+
+            case ASSERVISSEMENT_CONFIG:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_CONFIG);
+                VMAX = ((msgRxBuffer[FIFO_lecture].data[0]) + (msgRxBuffer[FIFO_lecture].data[1] << 8));
+                AMAX = ((msgRxBuffer[FIFO_lecture].data[2]) + (msgRxBuffer[FIFO_lecture].data[3] << 8));
+                ralentare = 1;
+                break;
+
+            case ASSERVISSEMENT_ROTATION:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_ROTATION);
+                liste[cpt_ordre].type = TYPE_DEPLACEMENT_ROTATION;
+                liste[cpt_ordre].angle = ((msgRxBuffer[FIFO_lecture].data[0]) + (msgRxBuffer[FIFO_lecture].data[1] << 8));
+                Rotate (Odo_theta);
+                break;
+
+            case ASSERVISSEMENT_RECALAGE:
+                SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_RECALAGE);
+                liste[cpt_ordre].type = TYPE_DEPLACEMENT_RECALAGE;
+                liste[cpt_ordre].distance = ((msgRxBuffer[FIFO_lecture].data[0]) + (msgRxBuffer[FIFO_lecture].data[1] << 8));
+                liste[cpt_ordre].recalage = ((msgRxBuffer[FIFO_lecture].data[3]) + (msgRxBuffer[FIFO_lecture].data[4] << 8));
+                liste[cpt_ordre].val_recalage = msgRxBuffer[FIFO_lecture].data[2];
+                recalage_debut = 1;
+                recalage_debut_receive = 1;
+                break;
+
+            case ASSERVISSEMENT_LIGNE_DROITE:   // n'existe pas encore
+                //SendAck(ACKNOWLEDGE_MOTEUR, ASSERVISSEMENT_LIGNE_DROITE);
+                test8 = 10;
+                if(msgRxBuffer[FIFO_lecture].data[2] == 0) {
+                    liste[cpt_ordre].type = TYPE_DEPLACEMENT_LIGNE_DROITE;
+                } else {
+                    liste[cpt_ordre].type = TYPE_DEPLACEMENT_RECALAGE;
+                    liste[cpt_ordre].recalage = ((msgRxBuffer[FIFO_lecture].data[3]) + (msgRxBuffer[FIFO_lecture].data[4] << 8));
+                }
+                recalage_debut_receive = msgRxBuffer[FIFO_lecture].data[2];
+                liste[cpt_ordre].distance = ((msgRxBuffer[FIFO_lecture].data[1] << 8) + (msgRxBuffer[FIFO_lecture].data[0]));
+                liste[cpt_ordre].enchainement = msgRxBuffer[FIFO_lecture].data[5];
+                //GoStraight(); /////////////////////////////////
+                break;
+
+            case MOTOR_IMOBILE:
+                SendAck(ACKNOWLEDGE_MOTEUR, MOTOR_IMOBILE);
+                liste[cpt_ordre].type = TYPE_DEPLACEMENT_IMMOBILE;
+                break;
+
+        }
+
+        FIFO_lecture=(FIFO_lecture+1)%SIZE_FIFO;
+    }
+}
+
+
+void Asser_Pos_Mot1(double pcons_pos)
+{
+    pos1 = (double)encoder1.GetCounter();
+
+    ErreurPos1 = pcons_pos - pos1;
+    Delta_ErreurPos1 = ErreurPos1 - last_ErreurPos1;
+    Somme_ErreurPos1 += ErreurPos1;
+
+    if(Somme_ErreurPos1>1.0) {
+        Somme_ErreurPos1=1.0;
+    } else if(Somme_ErreurPos1<-1.0) {
+        Somme_ErreurPos1=-1.0;
+    }
+
+    commande1 = (Kpp1 * ErreurPos1 + Kip1 * Somme_ErreurPos1 + Kdp1 * Delta_ErreurPos1);
+
+    last_ErreurPos1 = ErreurPos1;
+    last_pos1 = pos1;
+    
+    commande1=commande1/2500.;
+    
+    if(commande1>1.0) {
+        commande1=1.0;
+    } else if(commande1<-1.0) {
+        commande1=-1.0;
+    }
+
+    //test5++;
+}
+
+void Asser_Pos_Mot2(double pcons_pos)
+{
+    pos2 = (double)encoder2.GetCounter();
+
+    ErreurPos2 = pcons_pos - pos2;
+
+    Delta_ErreurPos2 = ErreurPos2 - last_ErreurPos2;
+    Somme_ErreurPos2 += ErreurPos2;
+
+    if(Somme_ErreurPos2>1.0)
+        Somme_ErreurPos2=1.0;
+    else if(Somme_ErreurPos2<-1.0)
+        Somme_ErreurPos2=-1.0;
+
+    commande2 = (Kpp2 * ErreurPos2 + Kip2 * Somme_ErreurPos2 + Kdp2 * Delta_ErreurPos2);
+
+    last_ErreurPos2 = ErreurPos2;
+    last_pos2 = pos2;
+    
+    commande2=commande2/2500.;
+    
+    if(commande2>1.0) {
+        commande2=1.0;
+    } else if(commande2<-1.0) {
+        commande2=-1.0;
+    }
+
+    test6++;
+}
+
+
+void Avancer_ligne_droite(long pcons, short vmax, short amax, short dmax)
+{
+    //Declaration des variables
+    static double tc, ta, td;   //tc temps � vitesse constante, ta en acceleration, td en deceleration
+    static double vmax_tri;     //Vitesse maximale atteinte dans le cas d'un profil en triangle
+
+    if(pcons >= 0) {    //Mode avancer
+        switch(etat_automate_depl) { //Automate de gestion du deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //Remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                consigne_vit = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps � vitesse constante en fonction de l'acceleration
+                tc = ((double)pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;    //Passage a l'etat ACCELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    // Le prochain �tat de l'automate sera l'�tat 5
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de vitesse par la valeur de l'acceleration
+                consigne_vit += amax;
+
+                //Incrementation de la consigne de position
+                consigne_pos += ((double)consigne_vit / 1000.0);
+
+                if(cpt >= ta) { //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;      //Passage a l'etat VITESSE_CONSTANTE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :   //Etat de vitesse constante en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {   //Condition pour quitter la phase de vitesse constante
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat DECELERATION
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :    //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour quitter la phase de deceleration en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :       //Etat d'arret
+                if(cpt >= 20) {     //Condition pour sortir de l'etat arret
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat INITIALISATION
+                    next_move = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) { //Condition pour sortir de l'etat acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {     //Condition pour sortir de l'etat deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    }
+
+    else if(pcons < 0) {    //Mode reculer
+        switch(etat_automate_depl) {    //Automate de gestion du deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //Remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps � vitesse constante en fonction de l'acceleration
+                tc = ((double)-pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;      //Passage a l'etat ACCELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);  //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);  //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * -pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :        //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (double)(((double)cpt * (double)amax)/1000.0);
+
+                if(cpt >= ta) {     //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse continue en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {   //Condition pour sortir de l'etat de vitesse constante en profil trapeze
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat de DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :        //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour sortir de l'etat deceleration en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :       //Etat d'arret
+                if(cpt >= 20) {     //Condition pour sortir de l'etat arret
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat d'INITIALISATION
+                    next_move = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :    //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {     //Condition pour sortir de l'etat d'acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {     //Condition pour sortir de l'etat de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    }
+
+
+    //Calcul des commande 1 et 2
+    Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+    Asser_Pos_Mot2(roue_gch_init + consigne_pos);
+
+    //Ecriture du PWM sur chaque modeur //*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+
+}
+
+
+void Avancer_ligne_droite_XYTheta(long pcons, short vmax, short amax, short dmax)
+{
+    //Declaration des variables
+    //char val1[8];
+    static double tc, ta, td;   //tc temps � vitesse constante, ta en acceleration, td en deceleration
+    static double vmax_tri;     //Vitesse maximale atteinte dans le cas d'un profil en triangle
+
+    if(pcons >= 0) {    //Mode avancer
+        switch(etat_automate_depl) {    //Automate de gestion du deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps a vitesse constante en fonction de l'acceleration
+                tc = ((double)pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;  //Passage a l'etat ACCELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if(cpt >= ta) {     //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse constante en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de vitesse par la valeur de l'acceleration
+                consigne_pos += vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {   //Condition pour quitter la phase de vitesse constante
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :    //Etat de vitesse constante en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour quitter la phase de deceleration en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :       //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INITIALISATION;    //Passage a l'etat d'INITIALISATION
+                    next_move_xyt = 1;
+
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {     //Condition pour sortir de la phase d'acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {     //Condition pour sortir de la phase de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    } else if(pcons < 0) {  //Mode reculer
+        switch(etat_automate_depl) {    //Automate de gestion du deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //Remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps � vitesse constante en fonction de l'acceleration
+                tc = ((double)-pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;      //Passage a l'etat ACCELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                } else if(tc < 0) { //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * -pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (double)(((double)cpt * (double)amax)/1000.0);
+
+                if(cpt >= ta) { //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse continue en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {   //Condition pour sortir de l'etat de vitesse constante en profil trapeze
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat de DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :        //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour sortir de l'etat vitesse continue en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :       //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat INITIALISATION
+                    next_move_xyt = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {     //Condition pour sortir de la phase d'acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {     //Condition pour sortir de l'etat de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    }
+
+    //Calcul des commande 1 et 2
+    Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+    Asser_Pos_Mot2(roue_gch_init + consigne_pos);
+
+    //Ecriture du PWM sur chaque modeur //*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+
+}
+
+
+void Rotation(long pcons, short vmax, short amax, short dmax)
+{
+    //Declaration des variables
+    //char val1[8];
+    static double tc, ta, td;   //tc temps � vitesse constante, ta en acceleration, td en deceleration
+    static double vmax_tri;     //Vitesse maximale atteinte dans le cas d'un profil en triangle
+
+    if(pcons >= 0) {    //Mode avancer
+        switch(etat_automate_depl) {    //Automate de gestion de deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps a vitesse constante en fonction de l'acceleration
+                tc = ((double)pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;      //Passage a l'etat AACELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if(cpt >= ta) {     //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse constante en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :        //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour quitter la phase de deceleration en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :       //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat INITIALISATION
+                    next_move = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);    //Condition pour sortir de la phase d'acceleration en profil triangle
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {     //Condition pour sortir de la phase de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    } else if(pcons < 0) {  //Mode reculer
+        switch(etat_automate_depl) {    //Automate de gestion du deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //Remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps � vitesse constante en fonction de l'acceleration
+                tc = ((double)-pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;      //Passage a l'etat ACCELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * -pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (double)(((double)cpt * (double)amax)/1000.0);
+
+                if(cpt >= ta) { //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse continue en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat de DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :    //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour sortir de l'etat vitesse continue en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :   //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat INITIALISATION
+                    next_move = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {     //Condition pour sortir de la phase d'acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) { //Condition pour sortir de l'etat de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    }
+
+    //Calcul des commande 1 et 2
+    Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+    Asser_Pos_Mot2(roue_gch_init - consigne_pos);
+
+    //Ecriture du PWM sur chaque modeur    /*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+}
+
+void Rotation_XYTheta(long pcons, short vmax, short amax, short dmax)
+{
+    //Declaration des variables
+    //char val1[8];
+    static double tc, ta, td;   //tc temps � vitesse constante, ta en acceleration, td en deceleration
+    static double vmax_tri;     //Vitesse maximale atteinte dans le cas d'un profil en triangle
+
+    if(pcons >= 0) {    //Mode avancer
+        switch(etat_automate_depl) {    //Automate de gestion de deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps a vitesse constante en fonction de l'acceleration
+                tc = ((double)pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;      //Passage a l'etat AACELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if(cpt >= ta) {     //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse constante en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :        //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour quitter la phase de deceleration en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :       //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat INITIALISATION
+                    next_move_xyt = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);    //Condition pour sortir de la phase d'acceleration en profil triangle
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {     //Condition pour sortir de la phase de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    } else if(pcons < 0) {  //Mode reculer
+        switch(etat_automate_depl) {    //Automate de gestion du deplacement
+            case INITIALISATION :      //Etat d'initialisation et de calcul des variables
+                //Remise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps � vitesse constante en fonction de l'acceleration
+                tc = ((double)-pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) {   //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE;      //Passage a l'etat ACCELERATION_TRAPEZE
+
+                    ta = (((double)vmax * 1000.0) / (double)amax);      //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);      //Calcul du temps de deceleration
+                }
+
+                else if(tc < 0) {   //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE;     //Passage a l'etat ACCELERATION_TRIANGLE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * -pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE :    //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (double)(((double)cpt * (double)amax)/1000.0);
+
+                if(cpt >= ta) { //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE;     //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE
+                    cpt = 0;
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE :       //Etat de vitesse continue en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {
+                    etat_automate_depl = DECELERATION_TRAPEZE;      //Passage a l'etat de DECELERATION_TRAPEZE
+                    cpt = 0;
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE :    //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) {     //Condition pour sortir de l'etat vitesse continue en profil trapeze
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    consigne_pos = pcons;
+                    cpt = 0;
+                }
+                break;
+
+            case ARRET :   //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INITIALISATION;        //Passage a l'etat INITIALISATION
+                    next_move_xyt = 1;
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE :        //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) {     //Condition pour sortir de la phase d'acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE;     //Passage a l'etat DECELERATION_TRIANGLE
+                    cpt = 0;
+                }
+                break;
+
+            case DECELERATION_TRIANGLE :        //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Decrementation de la consigne de position
+                consigne_pos -= vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) { //Condition pour sortir de l'etat de deceleration en profil triangle
+                    etat_automate_depl = ARRET;     //Passage a l'etat ARRET
+                    cpt = 0;
+                }
+                break;
+        }
+    }
+
+    //Calcul des commande 1 et 2
+    Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+    Asser_Pos_Mot2(roue_gch_init - consigne_pos);
+
+    //Ecriture du PWM sur chaque modeur //*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+
+}
+
+void X_Y_Theta(long px, long py, long ptheta, long sens, short vmax, short amax)
+{
+    //Variables pr�sentes Odo_x, Odo_y : position de d�part
+    //Declaration des variables
+    static short dist = 0, ang1 = 0, ang2 = 0;
+    //shar val[4];
+
+    switch(etat_automate_xytheta) {
+        case INIT_X_Y_THETA :   //etat INIT_X_Y_THETA
+            //Mode Avancer
+            if(sens >= 0) {
+                /*pour avancer, on tourne dans le sens horaire//MOI*\*/
+
+                // Son hypoth�nuse correspond � la distance � parcourir
+                dist = (short)sqrt((px - Odo_x)*(px - Odo_x)+(py - Odo_y)*(py - Odo_y));
+
+                // la 1ere rotation correspond � l'angle du triangle, moins l'angle de la position de d�part
+                // C'est-�-dire la tangente du c�t� oppos� sur l'angle adjacent
+                // La fonction atan2 fait le calcul de la tangente en radians, entre Pi et -Pi
+                // On rajoute des coefficients pour passer en degr�s
+                // On ajoute 7200 dixi�mes de degr�s pour �tre s�rs que le r�sultat soit positif
+                ang1 = (short)((atan2((double)(py - Odo_y), (double)(px - Odo_x)) * 1800 / PI) - Odo_theta + 7200) % 3600;
+
+                // On passe le r�sultat entre -1800 et 1800
+                if(ang1 > 1800) ang1 = (ang1 - 3600);
+
+                // La 2� rotation correspond � l'angle de destination, moins l'angle � la fin de la ligne droite,
+                // donc le m�me qu'� la fin de la 1�re rotation, donc l'angle de d�part plus la premi�re rotation
+                // On ajoute 3600 pour �tre s�r d'avoir un r�sultat positif
+                ang2 = (short)(ptheta - ang1 - Odo_theta + 3600) % 3600;
+
+                // On passe le r�sultat entre -1800 et 1800
+                if(ang2 > 1800) ang2 = (ang2 - 3600);
+
+                // On transforme les r�sultats en distance et angles utilisables avec les fonctions d�j� d�finies
+                dist = dist * RESOLUTION_ROUE_CODEUSE / PERIMETRE_ROUE_CODEUSE;
+                ang1 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang1 / (3600 * PERIMETRE_ROUE_CODEUSE);
+                ang2 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang2 / (3600 * PERIMETRE_ROUE_CODEUSE);
+            }
+
+            //Mode Reculer
+            else if(sens < 0) {
+
+                /*pour avancer, on tourne dans le sens anti-horaire//MOI*\*/
+
+                // Idem qu'au-dessus, mais laligne droite doit �tre faite en marche arri�re
+                // La distance est l'oppos� de celle calcul�e au dessus
+                // Les angles sont les m�mes � 1800 pr�s
+                dist = -(short)sqrt((px-Odo_x)*(px-Odo_x)+(py-Odo_y)*(py-Odo_y));
+
+                //Premiere rotation
+                ang1 = (short)(((atan2((double)(py - Odo_y), (double)(px - Odo_x)) * 1800 / PI) - Odo_theta) + 5400) % 3600;
+                if(ang1 > 1800) ang1 = (ang1 - 3600);
+
+                //Deuxieme rotation
+                ang2 = (short)(ptheta - ang1 - Odo_theta + 3600) % 3600;
+                if(ang2 > 1800) ang2 = (ang2 - 3600);
+
+                // On transforme les r�sultats en distance et angles utilisables avec les fonctions d�j� d�finies
+                dist = dist * RESOLUTION_ROUE_CODEUSE / PERIMETRE_ROUE_CODEUSE;
+                ang1 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang1 / (3600 * PERIMETRE_ROUE_CODEUSE);
+                ang2 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang2 / (3600 * PERIMETRE_ROUE_CODEUSE);
+            }
+
+            param_xytheta[0] = ang1;
+            param_xytheta[1] = dist;
+            param_xytheta[2] = ang2;
+
+            // La fonction xyth�ta utilise un automate propre, similaire � l'automate g�n�ral
+            etat_automate_xytheta = 1;
+            etat_automate_depl = ROTATION_X_Y_THETA_1;  //Passage a l'etat ROTATION_X_Y_THETA_1
+            break;
+
+        case ROTATION_X_Y_THETA_1 : //etat ROTATION_X_Y_THETA_1
+            //Execution de la fonction de rotation pour la fonction de deplacement X_Y_THETA
+            Rotation_XYTheta(ang1, vmax, amax, DMAX);
+
+            if(next_move_xyt) {
+                roue_drt_init = encoder1.GetCounter();
+
+                //#elif GROS_ROB == 0
+                roue_gch_init = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+                //#endif
+
+                next_move_xyt = 0;
+                etat_automate_xytheta = LIGNE_DROITE_X_Y_THETA; //Passage a l'etat LIGNE_DROITE_X_Y_THETA
+            }
+            break;
+
+        case LIGNE_DROITE_X_Y_THETA :   //etat LIGNE_DROITE_X_Y_THETA_1
+            //Execution de la fonction de ligne droite pour la fonction de deplacement X_Y_THETA
+            Avancer_ligne_droite_XYTheta(dist, vmax, amax, DMAX);
+
+            if(next_move_xyt) {
+                roue_drt_init = encoder1.GetCounter();
+
+                //#elif GROS_ROB == 0
+                roue_gch_init = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+                //#endif
+                next_move_xyt = 0;
+                etat_automate_xytheta = ROTATION_X_Y_THETA_2;   //Passage a l'etat ROTATION_X_Y_THETA_2
+            }
+            break;
+
+        case ROTATION_X_Y_THETA_2 : //etat ROTATION_X_Y_THETA_2
+            //Execution de la fonction de rotation pour la fonction de deplacement X_Y_THETA
+            Rotation_XYTheta(ang2, vmax, amax, DMAX);
+            if(next_move_xyt) {
+                roue_drt_init = encoder1.GetCounter();
+
+                //#elif GROS_ROB == 0
+                roue_gch_init = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+                //#endif
+
+                next_move_xyt = 0;
+                etat_automate_xytheta = INIT_X_Y_THETA; //Passage a l'etat INIT_X_Y_THETA
+                next_move = 1;
+            }
+            break;
+
+        default :   //Etat par defaut, on fait la meme chose que dans l'etat d'initialisation
+            //Mode Avancer
+            if(sens >= 0) {
+                /*pour avancer, on tourne dans le sens horaire//MOI*\*/
+
+                dist = (short)sqrt((px - Odo_x)*(px - Odo_x)+(py - Odo_y)*(py - Odo_y));
+                ang1 = (short)((atan2((double)(py - Odo_y), (double)(px - Odo_x)) * 1800 / PI) - Odo_theta + 7200) % 3600;
+                if(ang1 > 1800)
+                    ang1 = (ang1 - 3600);
+                ang2 = (short)(ptheta - ang1 - Odo_theta + 3600) % 3600;
+                if(ang2 > 1800)
+                    ang2 = (ang2 - 3600);
+
+                dist = dist * RESOLUTION_ROUE_CODEUSE / PERIMETRE_ROUE_CODEUSE;
+                ang1 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang1 / (3600 * PERIMETRE_ROUE_CODEUSE);
+                ang2 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang2 / (3600 * PERIMETRE_ROUE_CODEUSE);
+            }
+
+            //Mode Reculer
+            else if(sens < 0) {
+                /*pour avancer, on tourne dans le sens anti-horaire//MOI*\*/
+                dist = -(short)sqrt((px-Odo_x)*(px-Odo_x)+(py-Odo_y)*(py-Odo_y));
+                ang1 = (short)(((atan2((double)(py - Odo_y), (double)(px - Odo_x)) * 1800 / PI) - Odo_theta) + 5400) % 3600;
+                if(ang1 > 1800)
+
+                    ang1 = (ang1 - 3600);
+                ang2 = (short)(ptheta - ang1 - Odo_theta + 3600) % 3600;
+                if(ang2 > 1800)
+                    ang2 = (ang2 - 3600);
+
+                dist = dist * RESOLUTION_ROUE_CODEUSE / PERIMETRE_ROUE_CODEUSE;
+                ang1 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang1 / (3600 * PERIMETRE_ROUE_CODEUSE);
+                ang2 = LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE * ang2 / (3600 * PERIMETRE_ROUE_CODEUSE);
+            }
+
+            param_xytheta[0] = ang1;
+            param_xytheta[1] = dist;
+            param_xytheta[2] = ang2;
+
+            etat_automate_xytheta = 1;
+            etat_automate_depl = INIT_X_Y_THETA;
+            break;
+    }
+}
+
+void Odometrie(void)  //void Odometrie(void)
+{
+    //Declaration des variables
+    //char val1[8];
+    double dist, ang;   //distance, angle
+
+    //Recuperation des valeurs des compteurs des encodeurs
+    Odo_val_pos_1 = (double)encoder1.GetCounter();
+
+    /* MOI*\
+    //#elif GROS_ROB == 0
+    Odo_val_pos_2 = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+    //#endif
+    */
+    Odo_val_pos_2 = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+
+
+    //Calcul de la distance parcourue
+    dist = 0.5*((Odo_val_pos_1 - Odo_last_val_pos_1) + (Odo_val_pos_2 - Odo_last_val_pos_2));
+
+    //Calcul de la valeur de l'angle parcouru
+    ang = ((Odo_val_pos_1 - Odo_last_val_pos_1) -(Odo_val_pos_2 - Odo_last_val_pos_2))*1800.0*PERIMETRE_ROUE_CODEUSE/(LARGEUR_ROBOT*PI*RESOLUTION_ROUE_CODEUSE);
+
+    //Determination de la position sur le terrain en X, Y, Theta
+    Odo_theta += ang;
+    Odo_x += dist*cos((double)(Odo_theta*PI/1800.0))*PERIMETRE_ROUE_CODEUSE/RESOLUTION_ROUE_CODEUSE;
+    Odo_y += dist*sin((double)(Odo_theta*PI/1800.0))*PERIMETRE_ROUE_CODEUSE/RESOLUTION_ROUE_CODEUSE;
+
+    //Stockage de la derniere valeur de l'odometrie
+    Odo_last_val_pos_1 = Odo_val_pos_1;
+    Odo_last_val_pos_2 = Odo_val_pos_2;
+
+
+    //Condition d'envoi des informations de l'odometrie par CAN
+    Send_odometrie();
+
+    /****************************************/
+    /****************************************/
+    /*               <DEBUG>                */
+    /****************************************/
+    /****************************************/
+
+    Debug_Asserv();
+
+    /****************************************/
+    /****************************************/
+    /*               <DEBUG>                */
+    /****************************************/
+    /****************************************/
+
+
+}
+
+
+void Ralentir(short nouvelle_vitesse)
+{
+    //Si on allait en avant (cpt >= 0), on decremente cpt jusqu'a la nouvelle vitesse
+    if(cpt >= 0) {
+        cpt --;
+        if(cpt <= ((double)nouvelle_vitesse / ((double)AMAX/1000.0))) {     //La vitesse souhaitait est atteinte
+            cpt = (short)((double)nouvelle_vitesse / ((double)AMAX/1000.0));
+            ralentare = 0;
+        }
+    }
+
+    //Si on allait en arri�re (cpt < 0), on incr�mente cpt jusqu'a la nouvelle vitesse
+    else if(cpt < 0) {
+        cpt ++;
+        if(cpt >= -((double)nouvelle_vitesse / ((double)AMAX/1000.0))) {    //La vitesse souhaitait est atteinte
+            cpt = (short)-((double)nouvelle_vitesse / ((double)AMAX/1000.0));
+            ralentare = 0;
+        }
+    }
+
+    //Ralentir fonctionne comme une acc�l�ration standard, donc on modifie la consigne de position
+    consigne_pos += (double)(((double)cpt * (double)AMAX)/1000.0);
+
+    //Calcul de la valeur de commande 1 et 2
+    Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+    Asser_Pos_Mot2(roue_gch_init + consigne_pos);
+
+    //Ecriture de la valeur de la commande souhait�e
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+
+}
+
+void Arret(void)
+{
+    //Recuperation de la valeur de l'odometrie de la roue de droite et de gauche
+    roue_drt_init = (double)encoder1.GetCounter();
+
+    /* MOI*\
+    //#elif GROS_ROB == 0
+    roue_gch_init = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+    //#endif
+    */
+    roue_gch_init = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+
+
+    //Calcul de la valeur des commandes 1 et 2
+    Asser_Pos_Mot1(roue_drt_init);
+    Asser_Pos_Mot2(roue_gch_init);
+
+    //Ecrire un PWM egal a 0
+    write_PWM2(0.0);
+    write_PWM1(0.0);
+
+    next_move = 1;
+
+}
+
+void Recalage(int pcons, short vmax, short amax, short dir, short nv_val)
+{
+    //char val1[8];
+
+    //Mode AVANCER
+    if(pcons >= 0) {
+        switch(etat_automate_depl) {
+            case INIT_RECALAGE :   //etat INIT_RECELAGE
+                etat_automate_depl = ACCELERATION_RECALAGE;     //Passage a l'etat ACCELERATION_RECALAGE
+                consigne_pos = 0;   //Initialisation des differentes variables
+                cpt = 0;
+                break;
+
+            case ACCELERATION_RECALAGE :    //etat ACCELERATION_RECALAGE
+                // Phase d'acc�leration comme si on faisait une ligne droite
+
+                if(consigne_pos >= pcons/2) etat_automate_depl = FIN_RECALAGE;  //Passage a l'etat FIN_RECALAGE
+                cpt ++;
+
+                //Calcul de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax)/1000.0);
+
+                if(cpt >= ((double)vmax / ((double)amax/1000.0))) {
+                    etat_automate_depl = VITESSE_CONSTANTE_RECALAGE;  //Passage a l'etat VITESSE_CONSTANTE_RECALAGE
+                }
+
+                // Si les 2 erreurs sont sup�rieures � un seuil d�fini, on a fini le recalage
+                if(ErreurPos1 >= RECALAGE_TH && ErreurPos2 >= RECALAGE_TH) {
+                    etat_automate_depl = FIN_RECALAGE;  //Passage a l'etat FIN_RECALAGE
+                    commande1 = 0.0;  //Remise a zero des valeurs des commandes
+                    commande2 = 0.0;
+                }
+                // Si on d�tecte une augmentation d'erreur sur une roue, on l'arr�te pour �viter de patiner
+                else if(ErreurPos1 >= RECALAGE_TH)  commande1 = 0.0;
+                else if(ErreurPos2 >= RECALAGE_TH)  commande2 = 0.0;
+                break;
+
+            case VITESSE_CONSTANTE_RECALAGE :   //etat VITESSE_CONSTANTE_RECALAGE
+                // Phase de vitesse constante
+                consigne_pos += vmax;
+
+                // Idem que plus haut, on surveille les erreurs des 2 roues
+                if(ErreurPos1 >= RECALAGE_TH && ErreurPos2 >= RECALAGE_TH) {
+                    etat_automate_depl = FIN_RECALAGE;  //Passage a l'etat FIN_RECALAGE
+                    commande1 = 0.0;  //Remise a zero des valeurs des commandes
+                    commande2 = 0.0;
+                } else if(ErreurPos1 >= RECALAGE_TH)  commande1 = 0.0; //Mise a zero de la commande 1
+                else if(ErreurPos2 >= RECALAGE_TH)  commande2 = 0.0;  //Mise a zero de la commande 2
+                break;
+
+            case FIN_RECALAGE :     //etat FIN_RECALAGE
+                // Fin du recalage, on met � jour les donn�es de position
+                if(cpt >=20) {
+                    //Recalage de x
+                    if(dir == 1) {
+                        Odo_x = nv_val;
+                        // On met l'angle � jour en fonction de la position sur le terrain
+                        // Si on est dans la partie haute ( > la moiti�), on est dans un sens,
+                        // Si on est dans la partie basse, on met � jour dans l'autre sens
+                        // On prend aussi en compte le sens dans lequel on a fait la ligne droite
+
+                        if(nv_val > 1000) {
+                            if(pcons >=0)
+                                Odo_theta = 0;
+                            else
+                                Odo_theta = 1800;
+                        }
+
+                        else {
+                            if(pcons >= 0)
+                                Odo_theta = 1800;
+                            else
+                                Odo_theta = 0;
+                        }
+                    }
+
+                    //Recalage de y
+                    else {
+                        Odo_y = nv_val;
+
+                        if(nv_val > 1500) {
+                            if(pcons >=0)
+                                Odo_theta = 900;
+                            else
+                                Odo_theta = -900;
+                        }
+
+                        else {
+                            if(pcons >= 0)
+                                Odo_theta = -900;
+                            else
+                                Odo_theta = 900;
+                        }
+                    }
+
+                    etat_automate_depl = INIT_RECALAGE;
+
+                    next_move = 1;
+
+                    //Mise a zero des commandes et des moteurs;
+                    commande1 = 0.0;
+                    commande2 = 0.0;
+                    write_PWM1(0.0);
+                    write_PWM2(0.0);
+                }
+                cpt ++;
+                break;
+        }
+    }
+
+    //Mode RECULER
+    else if(pcons < 0) {
+        switch(etat_automate_depl) {
+            case INIT_RECALAGE :    //etat INIT_RECELAGE
+                etat_automate_depl = ACCELERATION_RECALAGE;     //Passage a l'etat ACCELERATION_RECALAGE
+                consigne_pos = 0;   //Initialisation des diff�rentes variables
+                cpt = 0;
+                break;
+
+            case ACCELERATION_RECALAGE :    //etat ACCELERATION_RECALAGE
+                // Phase d'acc�leration comme si on faisait une ligne droite
+                if(consigne_pos <= pcons/2) etat_automate_depl = FIN_RECALAGE;  //Passage a l'etat FIN_RECALAGE
+
+                cpt --;
+                consigne_pos += (double)(((double)cpt * (double)amax)/1000.0);
+
+                if(cpt <= -((double)vmax / ((double)amax/1000.0))) {
+                    etat_automate_depl = VITESSE_CONSTANTE_RECALAGE;    //Passage a l'etat VITESSE_CONSTANTE_RECALAGE
+                }
+
+                // Si les 2 erreurs sont inf�rieures � un seuil d�fini, on a fini le recalage
+                if(ErreurPos1 <= -RECALAGE_TH && ErreurPos2 <= -RECALAGE_TH) {
+                    etat_automate_depl = FIN_RECALAGE;  //Passage a l'etat FIN_RECALAGE
+                    commande1 = 0.0;
+                    commande2 = 0.0;
+                }
+                // Si on d�tecte une augmentation d'erreur sur une roue, on l'arr�te pour �viter de patiner
+                else if(ErreurPos1 <= -RECALAGE_TH) commande1 = 0.0;
+                else if(ErreurPos2 <= -RECALAGE_TH) commande2 = 0.0;
+                break;
+
+            case VITESSE_CONSTANTE_RECALAGE :   //etat VITESSE_CONSTANTE_RECALAGE
+                // Phase de vitesse constante
+                consigne_pos -= vmax;
+
+                // Idem que plus haut, on surveille les erreurs des 2 roues
+                if(ErreurPos1 <= -RECALAGE_TH && ErreurPos2 <= -RECALAGE_TH) {
+                    etat_automate_depl = FIN_RECALAGE;  //Passage a l'etat FIN_RECALAGE
+                    commande1 = 0.0;
+                    commande2 = 0.0;
+                } else if(ErreurPos1 <= -RECALAGE_TH) commande1 = 0.0;
+                else if(ErreurPos2 <= -RECALAGE_TH)commande2 = 0.0;
+                break;
+
+            case FIN_RECALAGE :     //etat FIN_RECALAGE
+                if(cpt >=20) {
+                    //Recalage de x
+                    if(dir == 1) {
+                        Odo_x = nv_val;
+
+                        if(nv_val > 1000) {
+                            if(pcons >=0)
+                                Odo_theta = 0;
+                            else
+                                Odo_theta = 1800;
+                        }
+
+                        else {
+                            if(pcons >= 0)
+                                Odo_theta = 1800;
+                            else
+                                Odo_theta = 0;
+                        }
+                    }
+
+                    //Recalage de y
+                    else {
+                        Odo_y = nv_val;
+
+                        if(nv_val > 1500) {
+                            if(pcons >=0)
+                                Odo_theta = 900;
+                            else
+                                Odo_theta = -900;
+                        }
+
+                        else {
+                            if(pcons >= 0)
+                                Odo_theta = -900;
+                            else
+                                Odo_theta = 900;
+                        }
+                    }
+
+                    etat_automate_depl = 0;
+
+                    next_move = 1;
+
+                    //Mise a zero des commandes et des moteurs
+                    commande1 = 0.0;
+                    commande2 = 0.0;
+                    write_PWM1(0.0);
+                    write_PWM2(0.0);
+                }
+                cpt ++;
+                break;
+        }
+    }
+
+    //Calcul des correcteurs a apporter aux moteurs
+    Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+    Asser_Pos_Mot2(roue_gch_init + consigne_pos);
+
+    //Envoi de la nouvelle valeur de commande aux PWM
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+
+}
+
+
+void Rayon_De_Courbure(short rayon, short theta, short vmax, short amax, short sens, short dmax)
+{
+    //Declaration des variables
+    //char val1[8];
+    static double tc, ta, td, vmax_tri, pcons;
+
+    //Si l'angle a parcourir est positif
+    if(theta >= 0) {
+        switch(etat_automate_depl) {
+            case INIT_RAYON_COURBURE : //etat d'initialisation
+                etat_automate_depl = ACCELERATION_TRAPEZE_RAYON_COURBURE;   //Passage a l'etat ACCELERATION_TRAPEZE_RAYON_COURBURE
+
+                //Mise a zero des variables car on effectue un nouveau deplacement
+                consigne_pos = 0;
+                cpt = 0;
+
+                //Calcul de la position voulue
+                pcons = ((rayon + LARGEUR_ROBOT/2) * 2 * PI * theta / 3600) * RESOLUTION_ROUE_CODEUSE / PERIMETRE_ROUE_CODEUSE;
+
+                //Elaboration du profil de vitesse
+                //Calcul du temps a vitesse constante
+                tc = ((double)pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+
+                if (tc > 0) { //Resultat positif, il y a une phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRAPEZE_RAYON_COURBURE;   //Passage a l'etat ACCELERATION_TRAPEZE_RAYON_COURBURE
+                    ta = (((double)vmax * 1000.0) / (double)amax);  //Calcul du temps d'acceleration
+                    td = (((double)vmax * 1000.0) / (double)dmax);  //Calcul du temps de deceleration
+
+                    canmsg.id = 0x7F1;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+
+                //Temps a vitesse constant inexistant
+                else if(tc < 0) { //Resultat negatif, il n'y a pas de phase de vitesse constante
+                    etat_automate_depl = ACCELERATION_TRIANGLE_RAYON_COURBURE;  //Passage a l'etat ACCELERATION_TRIANGLE_RAYON_COURBURE
+
+                    //Calcul de la vitesse maximale en profil triangle
+                    vmax_tri = sqrt((2 * pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+
+                    canmsg.id = 0x7F5;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+
+            case ACCELERATION_TRAPEZE_RAYON_COURBURE :  //Etat d'acceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if(cpt >= ta) { //Condition pour quitter la phase d'acceleration
+                    etat_automate_depl = VITESSE_CONSTANTE_TRAPEZE_RAYON_COURBURE;  //Passage a l'etat VITESSE_CONSTANTE_TRAPEZE_RAYON_COURBURE
+                    cpt = 0;
+
+                    canmsg.id = 0x7F2;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+
+            case VITESSE_CONSTANTE_TRAPEZE_RAYON_COURBURE : //Etat de vitesse constante en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de vitesse par la valeur de la vitesse
+                consigne_pos += vmax;
+
+                //Si il n'y a pas d'enchainements
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) { //Condition pour quitter la phase de vitesse constante
+                    etat_automate_depl = DECELERATION_TRAPEZE_RAYON_COURBURE;   //Passage a l'etat DECELERATION_TRAPEZE_RAYON_COURBURE
+                    cpt = 0;
+
+                    canmsg.id = 0x7F3;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+
+            case DECELERATION_TRAPEZE_RAYON_COURBURE :  //Etat de deceleration en profil trapeze
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+
+                if(cpt >= td) { //Condition pour quitter la phase de deceleration en profil trapeze
+                    etat_automate_depl = ARRET_RAYON_COURBURE;  //Passage a l'etat ARRET_RAYON_COURBURE
+                    consigne_pos = pcons;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F4;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+
+            case ARRET_RAYON_COURBURE : //Etat d'arret
+                if(cpt >= 20) {
+                    etat_automate_depl = INIT_RAYON_COURBURE; //Passage a l'etat d'INIT_RAYON_COURBURE
+                    next_move = 1;
+
+                }
+                cpt ++;
+                break;
+
+            case ACCELERATION_TRIANGLE_RAYON_COURBURE : //Etat d'acceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += (((double)cpt * (double)amax) / 1000.0);
+
+                if((cpt * amax / 1000.0) >= vmax_tri) { //Condition pour sortir de la phase d'acceleration en profil triangle
+                    etat_automate_depl = DECELERATION_TRIANGLE_RAYON_COURBURE;  //Passage a l'etat DECELERATION_TRIANGLE_RAYON_COURBURE
+                    cpt = 0;
+
+                    canmsg.id = 0x7F6;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+
+            case DECELERATION_TRIANGLE_RAYON_COURBURE : //Etat de deceleration en profil triangle
+                cpt ++;
+
+                //Incrementation de la consigne de position
+                consigne_pos += vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) { //Condition pour sortir de la phase de deceleration en profil triangle
+                    etat_automate_depl = ARRET_RAYON_COURBURE;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F4;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+        }
+    }
+
+    //Si l'angle a parcourir est negatif
+    else if(theta < 0) {
+        switch(etat_automate_depl) {
+            case 0 :
+                etat_automate_depl++;
+                consigne_pos = 0;
+                cpt = 0;
+                pcons = ((rayon + LARGEUR_ROBOT/2) * 2 * PI * theta / 3600) * RESOLUTION_ROUE_CODEUSE / PERIMETRE_ROUE_CODEUSE;
+                tc = ((double)pcons / (double)vmax) - (((double)vmax * 500.0) / (double)amax) - (((double)vmax * 500.0) / (double)dmax);
+                if (tc > 0) {
+                    etat_automate_depl++;
+                    ta = (((double)vmax * 1000.0) / (double)amax);
+                    td = (((double)vmax * 1000.0) / (double)dmax);
+
+                    canmsg.id = 0x7F1;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                } else if(tc < 0) {
+                    etat_automate_depl = 5;
+                    vmax_tri = sqrt((2 * -pcons) / ((1000.0 / (double)amax) + (1000.0 / (double)dmax)));
+
+                    canmsg.id = 0x7F5;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+            case 1 :
+                cpt ++;
+                consigne_pos -= (((double)cpt * (double)amax) / 1000.0);
+                if(cpt >= ta) {
+                    etat_automate_depl ++;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F2;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+            case 2 :
+                cpt ++;
+                consigne_pos -= vmax;
+                if(cpt >= tc && liste[cpt_ordre].enchainement != 1) {
+                    etat_automate_depl ++;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F3;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                //Si on est dans un enchainement, on passe � l'instruction suivante
+                else if(consigne_pos >= pcons && liste[cpt_ordre].enchainement == 1) {
+                    consigne_pos = pcons;
+                    cpt_ordre = 0;
+                }
+                break;
+            case 3 :
+                cpt ++;
+                consigne_pos -= vmax - (double)(((double)cpt * (double)dmax) / 1000.0);
+                if(cpt >= td) {
+                    etat_automate_depl ++;
+                    consigne_pos = pcons;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F4;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+            case 4 :
+                if(cpt >= 20) {
+                    etat_automate_depl = 0;
+                    next_move = 1;
+
+                }
+                cpt ++;
+                break;
+            case 5 :
+                cpt ++;
+                consigne_pos -= (((double)cpt * (double)amax) / 1000.0);
+                if((cpt * amax / 1000.0) >= vmax_tri) {
+                    etat_automate_depl ++;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F6;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+            case 6 :
+                cpt ++;
+                consigne_pos -= vmax_tri - (((double)cpt * (double)dmax) / 1000.0);
+                if(((double)vmax_tri - (((double)cpt * (double)dmax)) / 1000.0) <= 0) {
+                    etat_automate_depl = 4;
+                    cpt = 0;
+
+                    canmsg.id = 0x7F4;
+                    canmsg.len = 0;
+                    can1.write(canmsg);
+
+                }
+                break;
+        }
+    }
+
+    //Determination des commandes en fonction de la direction de deplacement du robot
+    if(sens >= 0) {
+
+        Asser_Pos_Mot1(roue_drt_init + consigne_pos);
+        Asser_Pos_Mot2(roue_gch_init + (consigne_pos * ((2 * rayon) - LARGEUR_ROBOT)/((2 * rayon) + LARGEUR_ROBOT)));
+    } else if(sens < 0) {
+
+        Asser_Pos_Mot1(roue_drt_init + (consigne_pos * ((2 * rayon) - LARGEUR_ROBOT)/((2 * rayon) + LARGEUR_ROBOT)));
+        Asser_Pos_Mot2(roue_gch_init + consigne_pos);
+    }
+
+    //Envoi de la vitesse aux moteurs
+    write_PWM2(commande2);
+    write_PWM1(commande1);
+}
+
+
+void MY_ISR()
+{
+    char val1[8];
+    if(ms_count == 20) {
+        //pc.printf("vit1=%f vit2=%f\n", test1, test2);
+        if(asser_actif) {
+            //Si on a re�u l'instruction de stop...
+            if(stop_receive) {
+                stop_receive = 0;
+                ErreurPos1 = 0;
+                ErreurPos2 = 0;
+                Somme_ErreurPos1 = 0;
+                Somme_ErreurPos2 = 0;
+                Delta_ErreurPos1 = 0;
+                Delta_ErreurPos2 = 0;
+                //On poursuit l'action si on est en rotation
+                if(liste[cpt_ordre].type == TYPE_DEPLACEMENT_ROTATION);
+                //On s'arr�te tout de suite si on est en ligne droite
+                else if(liste[cpt_ordre].type == TYPE_DEPLACEMENT_IMMOBILE || liste[cpt_ordre].type == TYPE_DEPLACEMENT_LIGNE_DROITE || liste[cpt_ordre].type == TYPE_DEPLACEMENT_RAYON_COURBURE) {
+                    //On vide le buffer de mouvements et on pr�voit de s'asservir sur la position atteinte
+                    for(i = 0; i<nb_ordres; i++)  liste[i] = (struct Ordre_deplacement) {
+                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                    };
+                    liste[0] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_STOP,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                    };
+                    nb_ordres = 0;
+                    etat_automate_depl = 0;
+                    cpt_ordre = 0;
+                }
+                //Si on est en X_Y_Theta, on poursuit la rotation, ou on arr�te la ligne droite
+                else if(liste[cpt_ordre].type == TYPE_DEPLACEMENT_X_Y_THETA) {
+                    if(etat_automate_xytheta == 2) {
+                        //On vide le buffer de mouvements et on pr�voit de s'asservir sur la position atteinte
+                        for(i = 0; i<nb_ordres; i++)  liste[i] = (struct Ordre_deplacement) {
+                            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                        };
+                        liste[0] = (struct Ordre_deplacement) {
+                            TYPE_DEPLACEMENT_STOP,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                        };
+                        nb_ordres = 0;
+                        cpt_ordre = 0;
+                    }
+                }
+            }
+            //Si on a re�u un changement de vitesse...
+            else if(ralentare) {
+                Ralentir(VMAX);
+                for(i = 0; i<nb_ordres; i++) {
+                    liste[i].vmax = VMAX;
+                    liste[i].amax = AMAX;
+                }
+            }
+
+            else if(recalage_debut_receive) {
+                if(couleur_debut == 1) {
+
+                    //#if GROS_ROB == 0
+                    Odo_x = 1961;
+                    Odo_y = 2800;
+                    Odo_theta = 1800;
+                    liste[0] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_LIGNE_DROITE,0,30,500,(971 * RESOLUTION_ROUE_CODEUSE) / PERIMETRE_ROUE_CODEUSE,0,0,0,0,0,0,0,0,0,0
+                    };
+                    liste[1] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_ROTATION,0,30,500,0,0,0,900 * LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE / (3600 * PERIMETRE_ROUE_CODEUSE),0,0,0,0,0,0,0
+                    };
+                    liste[2] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_RECALAGE,0,30,500,(-1000 * RESOLUTION_ROUE_CODEUSE) / PERIMETRE_ROUE_CODEUSE,2,2961,0,0,0,0,0,0,0,0
+                    };
+                    liste[3] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_LIGNE_DROITE,0,30,500,(111 * RESOLUTION_ROUE_CODEUSE) / PERIMETRE_ROUE_CODEUSE,0,0,0,0,0,0,0,0,0,0
+                    };
+                    liste[4] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_ROTATION,0,30,500,0,0,0,900 * LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE / (3600 * PERIMETRE_ROUE_CODEUSE),0,0,0,0,0,0,0
+                    };
+
+                    recalage_debut_receive = 0;
+                } else if(couleur_debut == 0) {
+
+
+                    //#if GROS_ROB == 0
+                    Odo_x = 1961;
+                    Odo_y = 200;
+                    Odo_theta = 1800;
+                    liste[0] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_LIGNE_DROITE,0,30,500,(971 * RESOLUTION_ROUE_CODEUSE) / PERIMETRE_ROUE_CODEUSE,0,0,0,0,0,0,0,0,0,0
+                    };
+                    liste[1] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_ROTATION,0,30,500,0,0,0,-900 * LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE / (3600 * PERIMETRE_ROUE_CODEUSE),0,0,0,0,0,0,0
+                    };
+                    liste[2] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_RECALAGE,0,30,500,(-1000 * RESOLUTION_ROUE_CODEUSE) / PERIMETRE_ROUE_CODEUSE,2,39,0,0,0,0,0,0,0,0
+                    };
+                    liste[3] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_LIGNE_DROITE,0,30,500,(111 * RESOLUTION_ROUE_CODEUSE) / PERIMETRE_ROUE_CODEUSE,0,0,0,0,0,0,0,0,0,0
+                    };
+                    liste[4] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_ROTATION,0,30,500,0,0,0,-900 * LARGEUR_ROBOT * PI * RESOLUTION_ROUE_CODEUSE / (3600 * PERIMETRE_ROUE_CODEUSE),0,0,0,0,0,0,0
+                    };
+
+                    recalage_debut_receive = 0;
+                }
+            }
+
+            //Si on vient de finir un mouvement...
+            else if(next_move) {
+
+                ErreurPos1 = 0;
+                ErreurPos2 = 0;
+                Somme_ErreurPos1 = 0;
+                Somme_ErreurPos2 = 0;
+                Delta_ErreurPos1 = 0;
+                Delta_ErreurPos2 = 0;
+                //Si on devait s'arr�ter...
+                if(stop) {
+                    //On vide le buffer de mouvements et on pr�voit de s'asservir sur la position atteinte
+                    for(i = 0; i<nb_ordres; i++)  liste[i] = (struct Ordre_deplacement) {
+                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                    };
+                    liste[0] = (struct Ordre_deplacement) {
+                        TYPE_DEPLACEMENT_IMMOBILE,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                    };
+                    nb_ordres = 0;
+                    cpt_ordre = 0;
+                    stop = 0;
+                    next_move = 0;
+                    cpt = 0;
+
+                    //On pr�vient qu'on s'est arr�t�
+                    motor_of();
+
+                }
+                //Sinon...
+                else if(!stop) {
+                    next_move = 0;
+                    //On conserve la position du robot pour la prochaine action
+                    roue_drt_init = encoder1.GetCounter();
+
+                    //MOI*\*/ // bug Edouard
+                    //#elif GROS_ROB == 0
+                    roue_gch_init = COEF_ROUE_GAUCHE * (double)encoder2.GetCounter();
+                    //#endif
+
+                    cpt_ordre++;
+
+                    if(recalage_debut == 1) {
+
+                        if(cpt_ordre >= 5) {
+                            recalage_debut = 2;
+                            //On vide le buffer de mouvements et on pr�voit de s'asservir sur la position atteinte
+                            for(i = 0; i<nb_ordres; i++)  liste[i] = (struct Ordre_deplacement) {
+                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                            };
+                            liste[0] = (struct Ordre_deplacement) {
+                                TYPE_DEPLACEMENT_IMMOBILE,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                            };
+                            nb_ordres = 0;
+                            cpt_ordre = 0;
+                        }
+                    }
+                    //Si on n'est pas dans un enchainement...
+                    else if(liste[cpt_ordre].enchainement != 1) {
+                        //On envoie le flag de fin d'instruction correspondant sur CAN
+                        switch(liste[cpt_ordre].type) {
+                            case TYPE_DEPLACEMENT_LIGNE_DROITE :
+                                val1[0] = ASSERVISSEMENT_RECALAGE;
+                                break;
+                            case TYPE_DEPLACEMENT_ROTATION :
+                                val1[0] = ASSERVISSEMENT_ROTATION;
+                                break;
+                            case TYPE_DEPLACEMENT_X_Y_THETA :
+                                val1[0] = ASSERVISSEMENT_XYT;
+                                break;
+                            case TYPE_DEPLACEMENT_RAYON_COURBURE :
+                                val1[0] = ASSERVISSEMENT_COURBURE;
+                                break;
+                            case TYPE_DEPLACEMENT_RECALAGE :
+                                val1[0] = ASSERVISSEMENT_RECALAGE;
+                                break;
+                            default :
+                                val1[0] = 0;
+                                break;
+                        }
+
+                        //On vide le buffer de mouvements et on pr�voit de s'asservir sur la position atteinte
+                        for(i = 0; i<nb_ordres; i++)  liste[i] = (struct Ordre_deplacement) {
+                            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                        };
+                        liste[0] = (struct Ordre_deplacement) {
+                            TYPE_DEPLACEMENT_IMMOBILE,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+                        };
+                        nb_ordres = 0;
+                        cpt_ordre = 0;
+                        cpt = 0;
+
+                        //On pr�vient qu'on s'est arr�t�
+                        motor_of();
+                    }
+                }
+            } else {    //On v�rifie le type d'action � effectuer, en fonction du buffer d'instructions
+                test3++;
+                switch(liste[cpt_ordre].type) {
+                    case TYPE_DEPLACEMENT_STOP :
+                        Arret();
+                        break;
+
+                    case TYPE_DEPLACEMENT_IMMOBILE:
+                        test4++;
+                        Asser_Pos_Mot1(roue_drt_init);
+                        Asser_Pos_Mot2(roue_gch_init);
+                        write_PWM2(commande2);
+                        write_PWM1(commande1);
+                        break;
+
+                    case TYPE_DEPLACEMENT_LIGNE_DROITE:
+                        Avancer_ligne_droite(liste[cpt_ordre].distance, VMAX, AMAX, DMAX);
+                        break;
+
+                    case TYPE_DEPLACEMENT_ROTATION:
+                        Rotation(liste[cpt_ordre].angle, VMAX, AMAX, DMAX);
+                        break;
+
+                    case TYPE_DEPLACEMENT_X_Y_THETA:
+                        X_Y_Theta(liste[cpt_ordre].x, liste[cpt_ordre].y, liste[cpt_ordre].theta,
+                                  liste[cpt_ordre].sens, VMAX, AMAX);
+                        break;
+
+                    case TYPE_DEPLACEMENT_RAYON_COURBURE :
+                        Rayon_De_Courbure(liste[cpt_ordre].rayon, liste[cpt_ordre].theta_ray, VMAX,
+                                          AMAX, liste[cpt_ordre].sens, DMAX);
+                        break;
+
+                    case TYPE_DEPLACEMENT_RECALAGE :
+                        Recalage(liste[cpt_ordre].distance, 10, 500, liste[cpt_ordre].recalage, liste[cpt_ordre].val_recalage);
+                        break;
+
+                    default :
+                        Asser_Pos_Mot1(roue_drt_init);
+                        Asser_Pos_Mot2(roue_gch_init);
+                        write_PWM2(commande2);
+                        write_PWM1(commande1);
+                        test7++;
+                        break;
+
+                }
+            }
+            //On calcule l'odom�trie � chaque tour de boucle
+
+            //MOI*\
+            ms_count = 0; // reset ms counter
+            ms_count1 ++;
+            //Odometrie();
+            if(ms_count1 == 5)
+                ms_count1 = 0;
+        } else {
+            ms_count = 0; // reset ms counter
+            ms_count1 ++;
+            //Odometrie();
+            if(ms_count1 == 5)
+                ms_count1 = 0;
+        }
+
+    } else {
+        ms_count ++;
+    }  /*else if(ms_count % 10 == 0) {
+        Odometrie();
+
+    }
+    */
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Apr 19 17:50:19 2017 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/mbed_official/code/mbed/builds/856d2700e60b
\ No newline at end of file