diff --git a/simulation/Makefile.am b/simulation/Makefile.am
index 05565af3e96fc4c5be548c53908fce93cb3cdecc..8ba7c6cc5de1570184b7922e5a338533f6d13f35 100644
--- a/simulation/Makefile.am
+++ b/simulation/Makefile.am
@@ -10,6 +10,7 @@ src/simul/main_window.cpp \
 src/simul/table.cpp \
 src/simul/robot.cpp \
 src/asservissement.cpp \
+src/command.cpp \
 src/Position.cpp \
 src/PositionPlusAngle.cpp \
 src/distance.cpp \
diff --git a/stm32/include/Angle.h b/stm32/include/Angle.h
index 1f8edb30426be5eefd502b3990182e50675824fd..38138ef91b5218a68e3e67b746cbe323a627aabd 100755
--- a/stm32/include/Angle.h
+++ b/stm32/include/Angle.h
@@ -21,6 +21,7 @@ class Angle
     bool presqueEgales(Angle &ang);
     Angle(const Angle &original);
     float getValueInRadian();
+    Angle wrap();
 };
 
 
diff --git a/stm32/include/asservissement.h b/stm32/include/asservissement.h
index e44e4011907a336d26c1b1ab8c64258245f217a0..f84184262e79862e908a4569a17868ebe56ab753 100755
--- a/stm32/include/asservissement.h
+++ b/stm32/include/asservissement.h
@@ -12,17 +12,12 @@
 #include "capteurs.h"
 #endif
 #include <stdint.h>
+#include "command.h"
 
 class Strategie;
 
 class Asservissement{
     public:
-        Distance vitesse_lineaire_a_atteindre;
-        Angle vitesse_angulaire_a_atteindre;
-        Distance vitesse_lineaire_max;
-        Angle vitesse_angulaire_max;
-        Distance acceleration_lineaire;
-        Angle acceleration_angulaire;
         float linearDutySent, angularDutySent;
         PIDFilterDistance pid_filter_distance;
         PIDFilterAngle pid_filter_angle;
@@ -34,25 +29,15 @@ class Asservissement{
         unsigned int buffer_collision;
         unsigned int nb_echantillons_buffer_collision;
 
-        Position destination;
-        Angle destAngle;
-        bool en_mouvement;
-        bool direction;
-        bool stop;
     public:
         Strategie* strategie;
         short toto;
         Odometrie* odometrie;
-        Asservissement(Odometrie* _odemetrie);
+	Command* command;
+        Asservissement(Odometrie* _odemetrie, class Command* command);
         static Asservissement * asservissement;
         static const uint16_t nb_ms_between_updates;
         void update(void);
-        void goTo(Position position, bool stop=true);
-        void goToDirection(Angle angle);
-        void recule(Distance distance);
-        void tourne(Angle angle);
-        Distance getVitesseLineaireAfterTrapeziumFilter(Distance vitesse_lineaire_atteinte, Distance distance_restante, Angle angle_restant);
-        Angle getVitesseAngulaireAfterTrapeziumFilter(Angle vitesse_angulaire_atteinte, Angle angle_restant);
 };
 
 #endif // ASSERVISSEMENT_H_INCLUDED
diff --git a/stm32/include/command.h b/stm32/include/command.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b094c7e2418c72267d2b29b2fc2da733e052f72
--- /dev/null
+++ b/stm32/include/command.h
@@ -0,0 +1,41 @@
+#include "Angle.h"
+#include "PositionPlusAngle.h"
+
+class Command
+{
+private:
+        float vitesse_lineaire_a_atteindre;
+        Angle vitesse_angulaire_a_atteindre;
+        float vitesse_lineaire_max;
+        Angle vitesse_angulaire_max;
+        float acceleration_lineaire;
+        Angle acceleration_angulaire;
+
+        Position destination;
+        Angle destAngle;
+        bool en_mouvement;
+        bool direction;
+        bool stop;
+public:
+	Command();
+	void update(PositionPlusAngle positionPlusAngleActuelle, Angle vitesse_angulaire_atteinte, float vitesse_lineaire_atteinte);
+
+        void goTo(Position position, bool stop=true);
+        void goToDirection(Angle angle);
+        void recule(Distance distance);
+        void tourne(Angle angle);
+        Distance getVitesseLineaireAfterTrapeziumFilter(Distance vitesse_lineaire_atteinte, Distance distance_restante, Angle angle_restant);
+        Angle getVitesseAngulaireAfterTrapeziumFilter(Angle vitesse_angulaire_atteinte, Angle angle_restant);
+
+	float getLinearSpeed()
+	{
+		return vitesse_lineaire_a_atteindre;
+	}
+
+	Angle getAngularSpeed()
+	{
+		return vitesse_angulaire_a_atteindre;
+	}
+
+};
+
diff --git a/stm32/include/simul/robot.h b/stm32/include/simul/robot.h
index d02e09f2ec1008f8de07eb256c2ce21de362cf80..a77838eae2a327f6e3bf32641f194cc7d2b18eed 100644
--- a/stm32/include/simul/robot.h
+++ b/stm32/include/simul/robot.h
@@ -17,7 +17,7 @@ public:
 	PositionPlusAngle pos;
 	PositionPlusAngle deriv;
 	boost::circular_buffer<PositionPlusAngle> olds;
-	class Asservissement* asservissement;
+	class Command* command;
 	class OdoRobot* odometrie;
 	class Strategie* strategie;
 	
diff --git a/stm32/include/strategie.h b/stm32/include/strategie.h
index c968d7f00efcf8769e316742ff9235ef824c6855..f908d2f893924043f7c74dd10781fba0121de122 100755
--- a/stm32/include/strategie.h
+++ b/stm32/include/strategie.h
@@ -7,12 +7,13 @@
 
 #include <stdint.h>
 
-class Asservissement;
+class Command;
+class Odometrie;
 
 class Strategie {
     private:
     bool is_blue;
-    Asservissement* asservissement;
+    Command* command;
     void doNext();
     int instruction_nb;
     bool collision_detected;
@@ -20,7 +21,7 @@ class Strategie {
 
     public:
     void collisionDetected();
-    Strategie(bool is_blue, Asservissement* asservissement);
+    Strategie(bool is_blue, Command* command, Odometrie* odometrie);
     void foundOtherRobot();
     void done();
     void doNthInstruction(uint16_t n);
diff --git a/stm32/src/Angle.cpp b/stm32/src/Angle.cpp
index dd5442c949a1b651d50db06fe037d623e18d674b..6a4a9dec5823cea0bbfce3b314ad3a0ec7ac4a31 100755
--- a/stm32/src/Angle.cpp
+++ b/stm32/src/Angle.cpp
@@ -31,7 +31,12 @@ Angle Angle::operator+(const Angle &ang)
 
 Angle Angle::operator-(const Angle &ang)
 {
-    double tmp_val = fmod(angle-ang.angle, 2*M_PI);
+      return Angle(angle - ang.angle);
+}
+
+Angle Angle::wrap()
+{
+    double tmp_val = fmod(angle, 2*M_PI);
     if(tmp_val<0) tmp_val += M_PI*2;
     return Angle(tmp_val <= M_PI ? tmp_val : tmp_val-2*M_PI);
 }
diff --git a/stm32/src/asservissement.cpp b/stm32/src/asservissement.cpp
index 1fbc84322513d5693c4b9f55622d00dbc8f8adb7..bd7a90c3030c5eb1419def238811a912eb688d55 100755
--- a/stm32/src/asservissement.cpp
+++ b/stm32/src/asservissement.cpp
@@ -38,30 +38,16 @@ float angle[DBG_SIZE];
 Asservissement * Asservissement::asservissement = NULL;
 const uint16_t Asservissement::nb_ms_between_updates = 10;
 uint32_t dbgInc = 0;
-Asservissement::Asservissement(Odometrie* _odometrie) :
-    vitesse_lineaire_a_atteindre(0),
-    vitesse_angulaire_a_atteindre(0),
-#if 0
-    vitesse_lineaire_max(4.), // en mm par nb_ms_between_updates
-    vitesse_angulaire_max(M_PI/100.0), // en radian par nb_ms_between_updates
-    acceleration_lineaire(4./200.0), // en mm par nb_ms_between_updates
-    acceleration_angulaire((M_PI/100.0)/200.0), // en radian par nb_ms_between_updates
-#else
-    vitesse_lineaire_max(4.), // en mm par nb_ms_between_updates
-    vitesse_angulaire_max(M_PI/500.0), // en radian par nb_ms_between_updates
-    acceleration_lineaire(4./200.0), // en mm par nb_ms_between_updates
-    acceleration_angulaire((M_PI/100.0)/200.0), // en radian par nb_ms_between_updates
-#endif
+Asservissement::Asservissement(Odometrie* _odometrie, Command* command) :
     seuil_collision(3.5),
     buffer_collision(0xffffffff),
-    nb_echantillons_buffer_collision(10),
-    destination(_odometrie->getPos().position)
+    nb_echantillons_buffer_collision(10)
 {
 	odometrie = _odometrie;
+	this->command = command;
     toto = 0;
     linearDutySent = 0;
     angularDutySent = 0;
-    en_mouvement = false;
     Asservissement::asservissement = this;
 
 #ifdef ROBOTHW
@@ -85,8 +71,14 @@ void Asservissement::update(void)
     //PositionPlusAngle before(odometrie.positionPlusAngle);
     asserCount++;
 
-    if(asserCount < 87000)
+    if(asserCount > 87000)
     {
+#ifdef ROUES
+        roues.gauche.tourne(0);
+        roues.droite.tourne(0);
+#endif
+        strategie->theEnd();
+    }
 
 #ifdef CAPTEURS
         capteurs.startConversion();
@@ -97,39 +89,35 @@ void Asservissement::update(void)
         Angle vitesse_angulaire_atteinte = odometrie->getVitesseAngulaire();
         Distance vitesse_lineaire_atteinte = odometrie->getVitesseLineaire();
 
+	command->update(positionPlusAngleActuelle, vitesse_angulaire_atteinte, vitesse_lineaire_atteinte);
+
         buffer_collision <<= 1;
-        bool tmp = (fabs((vitesse_lineaire_atteinte - vitesse_lineaire_a_atteindre)) < seuil_collision);
+        bool tmp = (fabs((vitesse_lineaire_atteinte - command->getLinearSpeed())) < seuil_collision);
         buffer_collision |= tmp;
 
 
         if (buffer_collision << (16 - nb_echantillons_buffer_collision)) {
             // Pas collision !!!
-            Position vecteur_pos_actuelle_pos_arrivee = destination-positionPlusAngleActuelle.position;
-
-            Distance distance_restante = (vecteur_pos_actuelle_pos_arrivee).getNorme();
-            Angle angle_restant = (direction ? destAngle : vecteur_pos_actuelle_pos_arrivee.getAngle()) - positionPlusAngleActuelle.angle;
-#ifdef CAPTEURS
-            bool is_there_someone_in_front = capteurs.getValue(Capteurs::AvantGauche) || capteurs.getValue(Capteurs::AvantDroite) || capteurs.getValue(Capteurs::Avant);
-#else
-            bool is_there_someone_in_front = false;
-#endif
+//#ifdef CAPTEURS
+//            bool is_there_someone_in_front = capteurs.getValue(Capteurs::AvantGauche) || capteurs.getValue(Capteurs::AvantDroite) || capteurs.getValue(Capteurs::Avant);
+//#else
+//            bool is_there_someone_in_front = false;
+//#endif
             //is_there_someone_in_front = false;
 
             //On s’arrête si l’on a atteint la cible ou s’il y a le robot adverse devant
-            if((distance_restante > Distance(20) && !is_there_someone_in_front && !direction) || (direction && fabs(angle_restant.getValueInRadian()) > 0.1))
-            {
-                if( (min(fabs(angle_restant.getValueInRadian()), fabs((angle_restant-Angle(M_PI)).getValueInRadian()))< M_PI_4) && !direction)
+            //if((distance_restante > Distance(20) && !is_there_someone_in_front && !direction) || (direction && fabs(angle_restant.getValueInRadian()) > 0.1))
+            //{
+                //if( (min(fabs(angle_restant.getValueInRadian()), fabs((angle_restant-Angle(M_PI)).getValueInRadian()))< M_PI_4) && !direction)
                 {
-                    vitesse_lineaire_a_atteindre = getVitesseLineaireAfterTrapeziumFilter(vitesse_lineaire_atteinte, distance_restante, angle_restant);
 #ifdef ROUES
                     float linear_duty_component = pid_filter_distance.getFilteredValue(vitesse_lineaire_a_atteindre-/*blah*/vitesse_lineaire_atteinte);
                     linearDutySent += linear_duty_component;
 #endif
                 }
-                else
-                    linearDutySent=0;
+                //else
+                //    linearDutySent=0;
 
-                vitesse_angulaire_a_atteindre = getVitesseAngulaireAfterTrapeziumFilter(vitesse_angulaire_atteinte, angle_restant);
 #ifdef ROUES
                 float angular_duty_component = pid_filter_angle.getFilteredValue(vitesse_angulaire_a_atteindre-/*didou*/vitesse_angulaire_atteinte);
 
@@ -159,7 +147,7 @@ void Asservissement::update(void)
                 roues.gauche.tourne(min(max(linearDutySent-angularDutySent, -0.9),0.9));
                 roues.droite.tourne(min(max(linearDutySent+angularDutySent, -0.9),0.9));
 #endif
-            }
+            /*}
             else
             {
                 if(stop || is_there_someone_in_front)
@@ -179,7 +167,7 @@ void Asservissement::update(void)
                     en_mouvement = false;
                     strategie->done();
                 }
-            }
+            }*/
 
         }
         else // collision
@@ -188,111 +176,102 @@ void Asservissement::update(void)
             roues.gauche.tourne(0);
             roues.droite.tourne(0);
 #endif
-            vitesse_lineaire_a_atteindre = Distance(0);
-            vitesse_angulaire_a_atteindre = Angle(0);
+            //vitesse_lineaire_a_atteindre = Distance(0);
+            //vitesse_angulaire_a_atteindre = Angle(0);
             linearDutySent = 0;
             angularDutySent = 0;
 
-            if(en_mouvement)
-            {
-                en_mouvement = false;
-                strategie->collisionDetected();
-            }
+            //if(en_mouvement)
+            //{
+            //    en_mouvement = false;
+            //    strategie->collisionDetected();
+            //}
         }
-    }
-    else
-    {
-#ifdef ROUES
-        roues.gauche.tourne(0);
-        roues.droite.tourne(0);
-#endif
-        strategie->theEnd();
-    }
 }
 
-void Asservissement::recule(Distance distance) {
-    goTo((odometrie->getPos() - distance).position);
-}
-
-Distance Asservissement::getVitesseLineaireAfterTrapeziumFilter(Distance vitesse_lineaire_atteinte, Distance distance_restante, Angle angle_restant)
-{
-
-    // Le pivot est la distance que l'on parcourerait si on commencait à décélérer dès maintenant jusqu'une vitesse nulle
-    Distance pivot(vitesse_lineaire_a_atteindre*vitesse_lineaire_a_atteindre/(2*acceleration_lineaire));
-    if( (distance_restante-pivot)<=0 &&
-         ((fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2 && vitesse_lineaire_atteinte<=0)
-          || (fabs((angle_restant - Angle(0)).getValueInRadian())<=M_PI_2 && vitesse_lineaire_atteinte>=0))
-         && stop)
-    {
-        //On est proche de la cible et l’on doit décélerer
-        if(vitesse_lineaire_a_atteindre>0.)
-        {
-            return vitesse_lineaire_a_atteindre-Distance(min(vitesse_lineaire_a_atteindre, acceleration_lineaire));
-        }
-        else
-        {
-            return vitesse_lineaire_a_atteindre-Distance(max(vitesse_lineaire_a_atteindre, -acceleration_lineaire));
-        }
-
-    }
-    else if(fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2)
-    {
-        // Sinon, on est en phase d'accélération
-        // Si la destination est derrière nous
-        // Alors on ajoute à la vitesse une accélération négative (jusqu'à la valeur (-vitesse_lineaire_max))
-        // Autrement dit, si on avance dans la mauvaise direction on ralenti et si on recule dans la bonne direction alors on recule plus vite
-        return vitesse_lineaire_a_atteindre
-               + Distance(max(-acceleration_lineaire, (-vitesse_lineaire_max-vitesse_lineaire_a_atteindre)));
-    }
-    else
-    {
-        // Sinon, la destination est devant nous
-        // Alors on ajoute à la vitesse une accélération positive (jusqu'à la valeur (vitesse_lineaire_max))
-        // Autrement dit, si on recule dans la mauvaise direction on ralenti et si on avance dans la bonne direction alors on avance plus vite
-        return vitesse_lineaire_a_atteindre
-               + Distance(min(acceleration_lineaire, (vitesse_lineaire_max-vitesse_lineaire_a_atteindre)));
-    }
-}
-
-Angle Asservissement::getVitesseAngulaireAfterTrapeziumFilter(Angle vitesse_angulaire_atteinte, Angle angle_restant)
-{
-    if(fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2)
-    {
-        angle_restant = angle_restant-Angle(M_PI);
-    }
-    Angle didou(angle_restant);
-    Angle pivot(vitesse_angulaire_a_atteindre.getValueInRadian()*vitesse_angulaire_a_atteindre.getValueInRadian()/(2*acceleration_angulaire.getValueInRadian()));
-
-    if((Angle(fabs(angle_restant.getValueInRadian()))-pivot).getValueInRadian()<=0)
-    {
-        return vitesse_angulaire_a_atteindre-Angle(copysign(min(fabs(vitesse_angulaire_a_atteindre.getValueInRadian()), acceleration_angulaire.getValueInRadian()), vitesse_angulaire_a_atteindre.getValueInRadian()));
-    }
-    else
-    {
-        return vitesse_angulaire_a_atteindre + Angle(copysign(min(acceleration_angulaire.getValueInRadian(), vitesse_angulaire_max.getValueInRadian()-fabs(vitesse_angulaire_a_atteindre.getValueInRadian())), angle_restant.getValueInRadian()));
-    }
-}
-
-void Asservissement::goTo(Position position, bool stop)
-{
-    destination = position;
-    direction = false;
-    en_mouvement = true;
-    this->stop = stop;
-}
-
-void Asservissement::goToDirection(Angle angle)
-{
-    destination = odometrie->getPos().position;
-    destAngle = angle;
-    direction = true;
-    en_mouvement = true;
-    this->stop = true;
-}
-
-void Asservissement::tourne(Angle angle){
-    goToDirection(odometrie->getPos().angle+angle);
-}
+//void Asservissement::recule(Distance distance) {
+    //goTo((odometrie->getPos() - distance).position);
+//}
+
+//Distance Asservissement::getVitesseLineaireAfterTrapeziumFilter(Distance vitesse_lineaire_atteinte, Distance distance_restante, Angle angle_restant)
+//{
+//
+//    // Le pivot est la distance que l'on parcourerait si on commencait à décélérer dès maintenant jusqu'une vitesse nulle
+//    Distance pivot(vitesse_lineaire_a_atteindre*vitesse_lineaire_a_atteindre/(2*acceleration_lineaire));
+//    if( (distance_restante-pivot)<=0 &&
+//         ((fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2 && vitesse_lineaire_atteinte<=0)
+//          || (fabs((angle_restant - Angle(0)).getValueInRadian())<=M_PI_2 && vitesse_lineaire_atteinte>=0))
+//         && stop)
+//    {
+//        //On est proche de la cible et l’on doit décélerer
+//        if(vitesse_lineaire_a_atteindre>0.)
+//        {
+//            return vitesse_lineaire_a_atteindre-Distance(min(vitesse_lineaire_a_atteindre, acceleration_lineaire));
+//        }
+//        else
+//        {
+//            return vitesse_lineaire_a_atteindre-Distance(max(vitesse_lineaire_a_atteindre, -acceleration_lineaire));
+//        }
+//
+//    }
+//    else if(fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2)
+//    {
+//        // Sinon, on est en phase d'accélération
+//        // Si la destination est derrière nous
+//        // Alors on ajoute à la vitesse une accélération négative (jusqu'à la valeur (-vitesse_lineaire_max))
+//        // Autrement dit, si on avance dans la mauvaise direction on ralenti et si on recule dans la bonne direction alors on recule plus vite
+//        return vitesse_lineaire_a_atteindre
+//               + Distance(max(-acceleration_lineaire, (-vitesse_lineaire_max-vitesse_lineaire_a_atteindre)));
+//    }
+//    else
+//    {
+//        // Sinon, la destination est devant nous
+//        // Alors on ajoute à la vitesse une accélération positive (jusqu'à la valeur (vitesse_lineaire_max))
+//        // Autrement dit, si on recule dans la mauvaise direction on ralenti et si on avance dans la bonne direction alors on avance plus vite
+//        return vitesse_lineaire_a_atteindre
+//               + Distance(min(acceleration_lineaire, (vitesse_lineaire_max-vitesse_lineaire_a_atteindre)));
+//    }
+//}
+//
+//Angle Asservissement::getVitesseAngulaireAfterTrapeziumFilter(Angle vitesse_angulaire_atteinte, Angle angle_restant)
+//{
+//    if(fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2)
+//    {
+//        angle_restant = angle_restant-Angle(M_PI);
+//    }
+//    Angle didou(angle_restant);
+//    Angle pivot(vitesse_angulaire_a_atteindre.getValueInRadian()*vitesse_angulaire_a_atteindre.getValueInRadian()/(2*acceleration_angulaire.getValueInRadian()));
+//
+//    if((Angle(fabs(angle_restant.getValueInRadian()))-pivot).getValueInRadian()<=0)
+//    {
+//        return vitesse_angulaire_a_atteindre-Angle(copysign(min(fabs(vitesse_angulaire_a_atteindre.getValueInRadian()), acceleration_angulaire.getValueInRadian()), vitesse_angulaire_a_atteindre.getValueInRadian()));
+//    }
+//    else
+//    {
+//        return vitesse_angulaire_a_atteindre + Angle(copysign(min(acceleration_angulaire.getValueInRadian(), vitesse_angulaire_max.getValueInRadian()-fabs(vitesse_angulaire_a_atteindre.getValueInRadian())), angle_restant.getValueInRadian()));
+//    }
+//}
+
+//void Asservissement::goTo(Position position, bool stop)
+//{
+//    destination = position;
+//    direction = false;
+//    en_mouvement = true;
+//    this->stop = stop;
+//}
+//
+//void Asservissement::goToDirection(Angle angle)
+//{
+//    destination = odometrie->getPos().position;
+//    destAngle = angle;
+//    direction = true;
+//    en_mouvement = true;
+//    this->stop = true;
+//}
+//
+//void Asservissement::tourne(Angle angle){
+//    goToDirection(odometrie->getPos().angle+angle);
+//}
 
 extern "C" void SysTick_Handler()
 {
diff --git a/stm32/src/command.cpp b/stm32/src/command.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1aad4e8a774f7aae594ad145c1852e6cb874be33
--- /dev/null
+++ b/stm32/src/command.cpp
@@ -0,0 +1,119 @@
+#include "command.h"
+#include <math.h>
+
+template<class T> T min(T a, T b)
+{
+	return a < b ? a : b;
+}
+
+template<class T> T max(T a, T b)
+{
+	return a > b ? a : b;
+}
+
+Command::Command() :
+    vitesse_lineaire_a_atteindre(0),
+    vitesse_angulaire_a_atteindre(0),
+#if 0
+    vitesse_lineaire_max(4.), // en mm par nb_ms_between_updates
+    vitesse_angulaire_max(M_PI/100.0), // en radian par nb_ms_between_updates
+    acceleration_lineaire(4./200.0), // en mm par nb_ms_between_updates
+    acceleration_angulaire((M_PI/100.0)/200.0) // en radian par nb_ms_between_updates
+#else
+    vitesse_lineaire_max(4.), // en mm par nb_ms_between_updates
+    vitesse_angulaire_max(M_PI/500.0), // en radian par nb_ms_between_updates
+    acceleration_lineaire(4./200.0), // en mm par nb_ms_between_updates
+    acceleration_angulaire((M_PI/100.0)/200.0) // en radian par nb_ms_between_updates
+#endif
+{
+}
+
+#include <iostream>
+
+void Command::update(PositionPlusAngle positionPlusAngleActuelle, Angle vitesse_angulaire_atteinte, float vitesse_lineaire_atteinte)
+{
+	Position vecteur_pos_actuelle_pos_arrivee = destination-positionPlusAngleActuelle.position;
+	
+	Distance distance_restante = (vecteur_pos_actuelle_pos_arrivee).getNorme();
+	Angle angle_restant = vecteur_pos_actuelle_pos_arrivee.getAngle() - positionPlusAngleActuelle.angle;
+
+	if(false) //distance_restante < 5)
+		vitesse_lineaire_a_atteindre = 0;
+	else
+        	vitesse_lineaire_a_atteindre = getVitesseLineaireAfterTrapeziumFilter(vitesse_lineaire_atteinte, distance_restante, angle_restant);
+
+	if(false) //fabs(angle_restant.getValueInRadian()) < 0.01)
+		vitesse_angulaire_a_atteindre = 0;
+	else
+		vitesse_angulaire_a_atteindre = getVitesseAngulaireAfterTrapeziumFilter(vitesse_angulaire_atteinte, angle_restant);
+	std::cout << "Ook " << distance_restante << " " << vitesse_lineaire_a_atteindre << std::endl;
+}
+
+
+
+Distance Command::getVitesseLineaireAfterTrapeziumFilter(Distance vitesse_lineaire_atteinte, Distance distance_restante, Angle angle_restant)
+{
+
+    // Le pivot est la distance que l'on parcourerait si on commencait à décélérer dès maintenant jusqu'une vitesse nulle
+    Distance pivot(vitesse_lineaire_a_atteindre*vitesse_lineaire_a_atteindre/(2*acceleration_lineaire));
+    if( (distance_restante-pivot)<=0 &&
+         ((fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2 && vitesse_lineaire_atteinte<=0)
+          || (fabs((angle_restant - Angle(0)).getValueInRadian())<=M_PI_2 && vitesse_lineaire_atteinte>=0))
+         && stop)
+    {
+        //On est proche de la cible et l’on doit décélerer
+        if(vitesse_lineaire_a_atteindre>0.)
+        {
+            return vitesse_lineaire_a_atteindre-Distance(min(vitesse_lineaire_a_atteindre, acceleration_lineaire));
+        }
+        else
+        {
+            return vitesse_lineaire_a_atteindre-Distance(max(vitesse_lineaire_a_atteindre, -acceleration_lineaire));
+        }
+
+    }
+    else if(fabs((angle_restant - Angle(0)).getValueInRadian())>M_PI_2)
+    {
+        // Sinon, on est en phase d'accélération
+        // Si la destination est derrière nous
+        // Alors on ajoute à la vitesse une accélération négative (jusqu'à la valeur (-vitesse_lineaire_max))
+        // Autrement dit, si on avance dans la mauvaise direction on ralenti et si on recule dans la bonne direction alors on recule plus vite
+        return vitesse_lineaire_a_atteindre
+               + Distance(max(-acceleration_lineaire, (-vitesse_lineaire_max-vitesse_lineaire_a_atteindre)));
+    }
+    else
+    {
+        // Sinon, la destination est devant nous
+        // Alors on ajoute à la vitesse une accélération positive (jusqu'à la valeur (vitesse_lineaire_max))
+        // Autrement dit, si on recule dans la mauvaise direction on ralenti et si on avance dans la bonne direction alors on avance plus vite
+        return vitesse_lineaire_a_atteindre
+               + Distance(min(acceleration_lineaire, (vitesse_lineaire_max-vitesse_lineaire_a_atteindre)));
+    }
+}
+
+Angle Command::getVitesseAngulaireAfterTrapeziumFilter(Angle vitesse_angulaire_atteinte, Angle angle_restant)
+{
+    if(fabs((angle_restant.wrap()).getValueInRadian())>M_PI_2 + 0.01)
+    {
+        angle_restant = (angle_restant+Angle(M_PI)).wrap();
+    }
+
+    Angle pivot(vitesse_angulaire_a_atteindre.getValueInRadian()*vitesse_angulaire_a_atteindre.getValueInRadian()/(2*acceleration_angulaire.getValueInRadian()));
+
+    if((Angle(fabs(angle_restant.getValueInRadian()))-pivot).getValueInRadian()<=0)
+    {
+        return vitesse_angulaire_a_atteindre-Angle(copysign(min((float)fabs(vitesse_angulaire_a_atteindre.getValueInRadian()), acceleration_angulaire.getValueInRadian()), vitesse_angulaire_a_atteindre.getValueInRadian()));
+    }
+    else
+    {
+        return vitesse_angulaire_a_atteindre + Angle(copysign(min(acceleration_angulaire.getValueInRadian(), vitesse_angulaire_max.getValueInRadian()-(float)fabs(vitesse_angulaire_a_atteindre.getValueInRadian())), angle_restant.getValueInRadian()));
+    }
+}
+
+void Command::goTo(Position position, bool stop)
+{
+    destination = position;
+    direction = false;
+    en_mouvement = true;
+    this->stop = stop;
+}
diff --git a/stm32/src/simul/robot.cpp b/stm32/src/simul/robot.cpp
index 276684e2f1b467ec7516f86867342e242700ed52..d0a60a03118bd339dc51755f905fa2e51869c35e 100644
--- a/stm32/src/simul/robot.cpp
+++ b/stm32/src/simul/robot.cpp
@@ -44,9 +44,6 @@ public:
 Robot::Robot(b2World & world) : world(world), olds(10000)
 {
 
-	deriv.position.x = 0;
-	deriv.position.y = 0;
-	deriv.angle = 0;
 
 	manual = false;
 	elem = NULL;
@@ -54,14 +51,16 @@ Robot::Robot(b2World & world) : world(world), olds(10000)
 	level = 0;
 
 	odometrie = new OdoRobot(this);
-	asservissement = new Asservissement(odometrie);
-	strategie = new Strategie(true, asservissement);
+	command = new Command;
+	Asservissement* asservissement = new Asservissement(odometrie, command);
+	strategie = new Strategie(true, command, odometrie);
+	asservissement->strategie = strategie;
 
-	pos.position.x=1000.;
-	pos.position.y=500.;
-	pos.angle=0;
+	pos = odometrie->getPos();
+	deriv.position.x = 0;
+	deriv.position.y = 0;
+	deriv.angle = 0;
 
-	asservissement->strategie = strategie;
 
 	b2BodyDef bodyDef;
 #ifndef BOX2D_2_0_1
@@ -116,6 +115,14 @@ Robot::Robot(b2World & world) : world(world), olds(10000)
 #ifdef BOX2D_2_0_1
 	body->SetMassFromShapes();
 #endif
+
+	//Little hack so that linear and angular speed of the object
+	//are those of the local coord (0,0) of the robot.
+	//We don't really care of the mass center accuracy.
+	b2MassData md;
+	body->GetMassData(&md);
+	md.center = b2Vec2(0,0);
+	body->SetMassData(&md);
 }
 
 void Robot::updateForces(int dt)
@@ -166,9 +173,9 @@ void Robot::paint(QPainter &p, int dt)
 		else
 		{
 			Asservissement::asservissement->update();
-			deriv.position.x = asservissement->vitesse_lineaire_a_atteindre;
+			deriv.position.x = command->getLinearSpeed();
 			deriv.position.y = 0;
-			deriv.angle = asservissement->vitesse_angulaire_a_atteindre;
+			deriv.angle = command->getAngularSpeed();
 		}
 	}
 
diff --git a/stm32/src/simul/table.cpp b/stm32/src/simul/table.cpp
index 4613c96483be53648dc70cf5afa348cbb8812d54..5469a39d95fc000107ab34c1716c6f36cefa0572 100644
--- a/stm32/src/simul/table.cpp
+++ b/stm32/src/simul/table.cpp
@@ -94,18 +94,18 @@ Table::Table(QWidget* parent) :
 	tableBody->CreateFixture(&fixture);
 
 	//Init position of elements
-	int l1 = rand() % 20; 
-	int l2 = rand() % 20; 
-	int r1 = rand() % 20; 
-	int r2 = rand() % 20; 
-
-	addCard(l1, 1);
-	addCard(l2, 2);
-	addCard(l2, 4);
-	addCard(l1, 5);
-	addCard(r1, -1);
-	addCard(r2, -2);
-	elements.push_back(new Element(world,getCase(3,3),Element::Pawn)); //Central element
+	//int l1 = rand() % 20; 
+	//int l2 = rand() % 20; 
+	//int r1 = rand() % 20; 
+	//int r2 = rand() % 20; 
+
+	//addCard(l1, 1);
+	//addCard(l2, 2);
+	//addCard(l2, 4);
+	//addCard(l1, 5);
+	//addCard(r1, -1);
+	//addCard(r2, -2);
+	//elements.push_back(new Element(world,getCase(3,3),Element::Pawn)); //Central element
 }
 
 Table::~Table()
diff --git a/stm32/src/strategie.cpp b/stm32/src/strategie.cpp
index 541409fa77359e46a3d0d3bc304b2e36741160cf..218eadbeb996c93830b1865a6c5dc1bc6e718fb6 100755
--- a/stm32/src/strategie.cpp
+++ b/stm32/src/strategie.cpp
@@ -1,4 +1,5 @@
 #include "strategie.h"
+#include "odometrie.h"
 #include "PositionPlusAngle.h"
 #ifdef ROBOTHW
 #include "stm32f10x.h"
@@ -6,12 +7,12 @@
 #include "stm32f10x_rcc.h"
 #include "stm32f10x_gpio.h"
 #endif
-#include "asservissement.h"
+#include "command.h"
 #include <math.h>
 
 #define INSTRUCTION_COLLISION 128
 
-Strategie::Strategie(bool is_blue, Asservissement* asservissement) :
+Strategie::Strategie(bool is_blue, Command* command, Odometrie* odometrie) :
 collision_detected(false)
 {
     this->is_blue = is_blue;
@@ -23,17 +24,17 @@ collision_detected(false)
     //Angle angleDeDepart(M_PI_2);
     //Position positionDeDepart(255,275);
     //Angle angleDeDepart(0.779);
-    Position positionDeDepart(0,0);
+    Position positionDeDepart(1000,700);
     Angle angleDeDepart(0);
 
     positionDeDepart.y = positionDeDepart.y*(is_blue ? 1:-1);
     angleDeDepart = angleDeDepart*(is_blue ? 1:-1);
-    //asservissement = new Asservissement(PositionPlusAngle(Position(335, 400), Angle(M_PI_2)), roueCodeuseGauche, roueCodeuseDroite);
-    this->asservissement = asservissement;
-    asservissement->odometrie->setPos(PositionPlusAngle(positionDeDepart,angleDeDepart));
-    //asservissement = new Asservissement(PositionPlusAngle(positionDeDepart, angleDeDepart), roueCodeuseGauche, roueCodeuseDroite);
-    //asservissement = new Asservissement(PositionPlusAngle(Position(0, 0), Angle(0)), roueCodeuseGauche, roueCodeuseDroite);
-    asservissement->strategie = this;
+    //command = new Asservissement(PositionPlusAngle(Position(335, 400), Angle(M_PI_2)), roueCodeuseGauche, roueCodeuseDroite);
+    this->command = command;
+    odometrie->setPos(PositionPlusAngle(positionDeDepart,angleDeDepart));
+    //command = new Asservissement(PositionPlusAngle(positionDeDepart, angleDeDepart), roueCodeuseGauche, roueCodeuseDroite);
+    //command = new Asservissement(PositionPlusAngle(Position(0, 0), Angle(0)), roueCodeuseGauche, roueCodeuseDroite);
+    //command->strategie = this;
     instruction_nb=1;
     doNthInstruction(instruction_nb);
 }
@@ -65,50 +66,50 @@ void Strategie::doNthInstruction(uint16_t n){
     int cote = (is_blue ? 1:-1);
 
     if(n==1)
-        asservissement->goTo(Position(100, 100), false);
+        command->goTo(Position(1500, 700), false);
     return;
 //rouleau.recracheBoule();
 //return;
 #ifdef DONTUSE
     switch(n) {
         case 1:
-            asservissement->goTo(Position(780, cote*780), false);
+            command->goTo(Position(780, cote*780), false);
         break;
         case 2:
             rouleau.avaleBoule();
-            asservissement->goTo(Position(1840, cote*2640));
+            command->goTo(Position(1840, cote*2640));
         break;
         case 3:
-            asservissement->goToDirection(Angle(0));
+            command->goToDirection(Angle(0));
             break;
         case 4:
             rouleau.recracheBoule();
             break;
         /*case 3:
             //rouleau.recracheBoule();
-            asservissement->goTo(Position(400, 600));
+            command->goTo(Position(400, 600));
         break;*/
         /*case 4:
             rouleau.arrete();
-            asservissement->goTo(Position(200, 800));
+            command->goTo(Position(200, 800));
         break;
         case 5:
-            asservissement->goTo(Position(-200, 800));
+            command->goTo(Position(-200, 800));
         break;
         case 6:
             rouleau.recracheBoule();
-            asservissement->goTo(Position(-400, 600));
+            command->goTo(Position(-400, 600));
         break;
         case 7:
             rouleau.arrete();
-            asservissement->goTo(Position(-400, 200));
+            command->goTo(Position(-400, 200));
         break;
         case 8:
-            asservissement->goTo(Position(-200, 0));
+            command->goTo(Position(-200, 0));
         break;
         case 9:
             rouleau.arrete();
-            asservissement->goTo(Position(0, 0));
+            command->goTo(Position(0, 0));
         break;*/
         default:
         break;
@@ -118,32 +119,32 @@ void Strategie::doNthInstruction(uint16_t n){
     switch(n) {
         case 1:
             //rouleau.avaleBoule();
-            //asservissement->tourne(Angle(1.5));
-            asservissement->goTo(Position(724, cote*779), false);
+            //command->tourne(Angle(1.5));
+            command->goTo(Position(724, cote*779), false);
         break;
         case 2:
             //rouleau.avaleBoule();
-            asservissement->goTo(Position(1242, cote*1694), false);
+            command->goTo(Position(1242, cote*1694), false);
         break;
         case 3:
             //rouleau.avaleBoule();
-            asservissement->goTo(Position(1790, cote*2610),false);
+            command->goTo(Position(1790, cote*2610),false);
         break;
         case 4:
-            asservissement->goToDirection(Angle(0));
+            command->goToDirection(Angle(0));
             break;
         case 5:
             //rouleau.recracheBoule();
-            asservissement->goTo(Position(1750, cote*2610));
+            command->goTo(Position(1750, cote*2610));
             break;
         case 6:
-            asservissement->goTo(Position(1820, cote*2610));
+            command->goTo(Position(1820, cote*2610));
             break;
         case INSTRUCTION_COLLISION:
-            asservissement->recule(Distance(100));
+            command->recule(Distance(100));
             break;
         case (INSTRUCTION_COLLISION+1):
-            asservissement->tourne(Angle(1.5));
+            command->tourne(Angle(1.5));
             collision_detected = false;
             instruction_nb--;
         break;
@@ -152,7 +153,7 @@ void Strategie::doNthInstruction(uint16_t n){
 /*
 if(n==0)
 {
-    asservissement->recule(2500);
+    command->recule(2500);
 }*/
 }