with class

Dependencies:   ISR_Mini-explorer mbed

Fork of VirtualForces by Georgios Tsamis

Files at this revision

API Documentation at this revision

Comitter:
Ludwigfr
Date:
Fri Jun 09 00:28:32 2017 +0000
Parent:
32:d51928b58645
Child:
34:c208497dd079
Commit message:
version with class

Changed in this revision

Map.cpp Show annotated file Show diff for this revision Revisions of this file
Map.hpp Show annotated file Show diff for this revision Revisions of this file
MiniExplorerCoimbra.cpp Show annotated file Show diff for this revision Revisions of this file
MiniExplorerCoimbra.hpp Show annotated file Show diff for this revision Revisions of this file
Sonar.cpp Show annotated file Show diff for this revision Revisions of this file
Sonar.hpp 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Map.cpp	Fri Jun 09 00:28:32 2017 +0000
@@ -0,0 +1,166 @@
+#include "Map.hpp"
+
+Map::Map(float widthRealMap, float HeightRealMap, int nbCellWidth, int nbCellHeight){
+	this->widthRealMap=widthRealMap;
+	this->HeightRealMap=HeightRealMap;
+	this->nbCellWidth=nbCellWidth;
+	this->nbCellHeight=nbCellHeight;
+	this->sizeCellWidth=widthRealMap/(float)nbCellWidth;
+	this->sizeCellHeight=HeightRealMap/(float)nbCellHeight;
+	
+	this->cellsLogValues= new float*[nbCellWidth];
+	for(int i = 0; i < nbCellWidth; ++i)
+    	this->cellsLogValues[i] = new float[nbCellHeight];
+    	
+	this->initialLogValues= new float*[nbCellWidth];
+	for(int i = 0; i < nbCellWidth; ++i)
+    	this->initialLogValues[i] = new float[nbCellHeight];
+    	
+	this->fill_initialLogValues();
+}
+
+//fill initialLogValues with the values we already know (here the bordurs)
+void Map::fill_initialLogValues(){
+    //Fill map, we know the border are occupied
+    for (int i = 0; i<this->nbCellWidth; i++) {
+        for (int j = 0; j<nbCellHeight; j++) {
+            if(j==0 || j==nbCellHeight-1 || i==0 || i==nbCellWidth-1)
+                this->initialLogValues[i][j] = proba_to_log(1);
+            else
+                initialLogValues[i][j] = proba_to_log(0.5);
+        }
+    }
+}
+
+//returns the probability [0,1] that the cell is occupied from the log valAue lt
+float Map::log_to_proba(float lt){
+    return 1-1/(1+exp(lt));
+}
+
+
+//returns the log value that the cell is occupied from the probability value [0,1]
+float Map::proba_to_log(float p){
+    return log(p/(1-p));
+}
+
+void Map::print_final_map() {
+    float currProba;
+    pc.printf("\n\r");
+    for (int y = this->nbCellHeight -1; y>-1; y--) {
+        for (int x= 0; x<this->nbCellWidth; x++) {
+                currProba=this->log_to_proba(this->cellsLogValues[x][y]);
+            if ( currProba < 0.5) {
+                pc.printf("   ");
+            } else {
+                if(currProba==0.5)
+                    pc.printf(" . ");
+                else
+                    pc.printf(" X ");
+            }
+        }
+        pc.printf("\n\r");
+    }
+}
+
+
+void Map::print_final_map_with_robot_position(float robot_x,float robot_y) {
+    float currProba;
+    float Xrobot=this->robot_x_coordinate_in_world(robot_x,robot_y);
+    float Yrobot=this->robot_y_coordinate_in_world(robot_x,robot_y);
+    
+    float heightIndiceInOrthonormal;
+    float widthIndiceInOrthonormal;
+    
+    float widthMalus=-(3*sizeCellWidth/2);
+    float widthBonus=sizeCellWidth/2;
+    
+    float heightMalus=-(3*sizeCellHeight/2);
+    float heightBonus=sizeCellHeight/2;
+
+    pc.printf("\n\r");
+    for (int y = nbCellHeight -1; y>-1; y--) {
+        for (int x= 0; x<nbCellWidth; x++) {
+            heightIndiceInOrthonormal=this->cell_height_coordinate_to_world(y);
+            widthIndiceInOrthonormal=this->cell_width_coordinate_to_world(x);
+            if(Yrobot >= (heightIndiceInOrthonormal+heightMalus) && Yrobot <= (heightIndiceInOrthonormal+heightBonus) && Xrobot >= (widthIndiceInOrthonormal+widthMalus) && Xrobot <= (widthIndiceInOrthonormal+widthBonus))                    
+                pc.printf(" R ");
+            else{
+                currProba=this->log_to_proba(this->cellsLogValues[x][y]);
+                if ( currProba < 0.5)
+                    pc.printf("   ");
+                else{
+                    if(currProba==0.5)
+                        pc.printf(" . ");
+                    else
+                        pc.printf(" X ");
+                } 
+            }
+        }
+        pc.printf("\n\r");
+    }
+}
+
+void Map::print_final_map_with_robot_position_and_target(float robot_x,float robot_y,float targetXWorld, float targetYWorld) {
+    float currProba;
+    float Xrobot=this->robot_x_coordinate_in_world(robot_x,robot_y);
+    float Yrobot=this->robot_y_coordinate_in_world(robot_x,robot_y);
+    
+    float heightIndiceInOrthonormal;
+    float widthIndiceInOrthonormal;
+    
+    float widthMalus=-(3*sizeCellWidth/2);
+    float widthBonus=sizeCellWidth/2;
+    
+    float heightMalus=-(3*sizeCellHeight/2);
+    float heightBonus=sizeCellHeight/2;
+
+    pc.printf("\n\r");
+    for (int y = this->nbCellHeight -1; y>-1; y--) {
+        for (int x= 0; x<this->nbCellWidth; x++) {
+            heightIndiceInOrthonormal=this->cell_height_coordinate_to_world(y);
+            widthIndiceInOrthonormal=this->cell_width_coordinate_to_world(x);
+            if(Yrobot >= (heightIndiceInOrthonormal+heightMalus) && Yrobot <= (heightIndiceInOrthonormal+heightBonus) && Xrobot >= (widthIndiceInOrthonormal+widthMalus) && Xrobot <= (widthIndiceInOrthonormal+widthBonus))
+                pc.printf(" R ");
+            else{
+                if(targetYWorld >= (heightIndiceInOrthonormal+heightMalus) && targetYWorld <= (heightIndiceInOrthonormal+heightBonus) && targetXWorld >= (widthIndiceInOrthonormal+widthMalus) && targetXWorld <= (widthIndiceInOrthonormal+widthBonus))                    
+                    pc.printf(" T ");
+                else{
+                    currProba=this->log_to_proba(this->cellsLogValues[x][y]);
+                    if ( currProba < 0.5)
+                        pc.printf("   ");
+                    else{
+                        if(currProba==0.5)
+                            pc.printf(" . ");
+                        else
+                            pc.printf(" X ");
+                    } 
+                }
+            }
+        }
+        pc.printf("\n\r");
+    }
+}
+
+void Map::update_cell_value(int widthIndice,int heightIndice ,float proba){
+    this->cellsLogValues[widthIndice][heightIndice]=this->cellsLogValues[widthIndice][heightIndice]+this->proba_to_log(proba)+this->initialLogValues[widthIndice][heightIndice];//map is filled as map[0][0] get the data for the point closest to the origin
+}
+
+float Map::robot_x_coordinate_in_world(float robot_x, float robot_y){
+    return this->nbCellWidth*this->sizeCellWidth-robot_y;
+}
+
+float Map::robot_y_coordinate_in_world(float robot_x, float robot_y){
+    return robot_x;
+}
+
+float Map::cell_width_coordinate_to_world(int i){
+	return this->sizeCellWidth/2+i*this->sizeCellWidth;
+}
+
+float Map::cell_height_coordinate_to_world(int j){
+	return this->sizeCellHeight/2+j*this->sizeCellHeight;
+}
+
+float Map::get_proba_cell(int widthIndice, int heightIndice){
+	return  this->log_to_proba(this->cellsLogValues[widthIndice][heightIndice]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Map.hpp	Fri Jun 09 00:28:32 2017 +0000
@@ -0,0 +1,76 @@
+#ifndef MAP_HPP
+#define MAP_HPP
+
+#include "MiniExplorerCoimbra.hpp"
+
+        /*
+Robot coordinate system:      World coordinate system:
+      ^                                 ^
+      |x                                |y
+   <--R                                 O-->
+    y                                    x
+
+Screen coordinate system
+   x
+ O--->
+y|
+ v
+ 
+how the float[2] arrays stock the position 
+Start at 0,0 end top right
+^
+|heightIndice
+|
+_____>
+widthIndice
+*/
+
+
+class Map {
+
+public:
+    float widthRealMap;
+    float HeightRealMap;
+    int nbCellWidth;
+    int nbCellHeight;
+    float sizeCellWidth;
+    float sizeCellHeight;
+    float** cellsLogValues;
+    float** initialLogValues;
+
+    Map(float widthRealMap, float HeightRealMap, int nbCellWidth, int nbCellHeight);
+
+    void print_final_map();
+
+    void print_final_map_with_robot_position(float robot_x,float robot_y);
+
+    void print_final_map_with_robot_position_and_target(float robot_x,float robot_y,float targetXWolrd, float targetYWorld);
+
+    protected:
+
+    //returns the probability [0,1] that the cell is occupied from the log valAue lt
+    float log_to_proba(float lt);
+
+    //returns the log value that the cell is occupied from the probability value [0,1]
+    float proba_to_log(float p);
+
+    //fill initialLogValues with the values we already know (here the bordurs)
+    void fill_initialLogValues();
+
+    //Updates map value
+    void update_cell_value(int widthIndice,int heightIndice ,float proba);
+
+    float robot_x_coordinate_in_world(float robot_x, float robot_y);
+
+    float robot_y_coordinate_in_world(float robot_x, float robot_y);
+
+    float cell_width_coordinate_to_world(int i);
+
+    float cell_height_coordinate_to_world(int j);
+
+    float get_proba_cell(int widthIndice, int heightIndice);
+
+}; 
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MiniExplorerCoimbra.cpp	Fri Jun 09 00:28:32 2017 +0000
@@ -0,0 +1,458 @@
+#include "MiniExplorerCoimbra.hpp"
+
+#define PI 3.14159
+
+MiniExplorerCoimbra::	MiniExplorerCoimbra(float defaultX, float defaultY, float defaultTheta):map(200,200,20,20),sonarLeft(10*PI/36,-4,4),sonarFront(0,0,5),sonarRight(-10*PI/36,4,4){
+	i2c1.frequency(100000);
+    initRobot(); //Initializing the robot
+    pc.baud(9600); // baud for the pc communication
+
+    measure_always_on();//TODO check if needed
+
+	this->setXYTheta(defaultX,defaultY,defaultTheta);
+	this->radiusWheels=3.25;
+	this->distanceWheels=7.2; 
+	
+	this->khro=12;
+	this->ka=30;
+	this->kb=-13;
+	this->kv=200;
+	this->kh=200;
+
+	this->rangeForce=30;
+	this->attractionConstantForce=10000;
+	this->repulsionConstantForce=1;
+} 
+
+void MiniExplorerCoimbra::setXYTheta(float x, float y, float theta){
+	X=x;
+	Y=y;
+	theta=theta;
+}
+
+//generate a position randomly and makes the robot go there while updating the map
+void MiniExplorerCoimbra::randomize_and_map() {
+    //TODO check that it's aurelien's work
+    float movementOnX=rand()%(int)(this->map.widthRealMap/2);
+    float movementOnY=rand()%(int)(this->map.heightRealMap/2);
+    
+    float signOfX=rand()%2;
+    if(signOfX < 1)
+        signOfX=-1;
+    float signOfY=rand()%2;
+    if(signOfY  < 1)
+        signOfY=-1;
+        
+    float targetX = movementOnX*signOfX;
+    float targetY = movementOnY*signOfY;
+    float targetAngle = 2*((float)(rand()%31416)-15708)/10000.0;
+    this->go_to_point_with_angle(targetX, targetY, targetAngle);
+}
+
+//go the the given position while updating the map
+void MiniExplorerCoimbra::go_to_point_with_angle(float targetX, float targetY, float targetAngle) {
+    bool keep_going=true;
+    float leftMm;
+    float frontMm; 
+    float rightMm;
+    float dt;
+    Timer t;
+    float d2;
+    do {
+        //Timer stuff
+        dt = t.read();
+        t.reset();
+        t.start();
+        
+        //Updating X,Y and theta with the odometry values
+        Odometria();
+       	leftMm = get_distance_left_sensor();
+    	frontMm = get_distance_front_sensor();
+    	rightMm = get_distance_right_sensor();
+
+        //if in dangerzone 
+        if((frontMm < 150 && frontMm > 0)|| (leftMm <150 && leftMm > 0) || (rightMm <150 && rightMm > 0) ){
+            leftMotor(1,0);
+            rightMotor(1,0);
+            this->update_sonar_values(leftMm, frontMm, rightMm);
+            //TODO Giorgos maybe you can also test the do_half_flip() function
+            Odometria();
+            //do a flip TODO
+            keep_going=false;
+            this->do_half_flip();   
+        }else{
+            //if not in danger zone continue as usual
+            this->update_sonar_values(leftMm, frontMm, rightMm);
+
+        	//Updating motor velocities
+            d2=this->update_angular_speed_wheels_go_to_point_with_angle(targetX,targetY,targetAngle,dt);
+    
+            wait(0.2);
+            //Timer stuff
+            t.stop();
+            pc.printf("\n\r dist to target= %f",d2);
+        }
+    } while(d2>1 && (abs(targetAngle-theta)>0.01) && keep_going);
+
+    //Stop at the end
+    leftMotor(1,0);
+    rightMotor(1,0);
+}
+
+void MiniExplorerCoimbra::update_sonar_values(float leftMm,float frontMm,float rightMm){
+    float xWorldCell;
+    float yWorldCell;
+    for(int i=0;i<this->map.nbCellWidth;i++){
+        for(int j=0;j<this->map.nbCellHeight;j++){
+        	xWorldCell=this->map.cell_width_coordinate_to_world(i);
+            yWorldCell=this->map.cell_height_coordinate_to_world(j);
+            //compute_probability_t(float distanceObstacleDetected, float x, float y, float[2] robotCoordinatesInWorld)
+        	this->map.update_cell_value(i,j,this->sonarRight.compute_probability_t(rightMm,xWorldCell,yWorldCell,this->get_converted_robot_X_into_world(),this->get_converted_robot_Y_into_world()));
+        	this->map.update_cell_value(i,j,this->sonarLeft.compute_probability_t(leftMm,xWorldCell,yWorldCell,this->get_converted_robot_X_into_world(),this->get_converted_robot_Y_into_world()));
+        	this->map.update_cell_value(i,j,this->sonarFront.compute_probability_t(frontMm,xWorldCell,yWorldCell,this->get_converted_robot_X_into_world(),this->get_converted_robot_Y_into_world()));
+
+       	}
+    }
+}
+
+float MiniExplorerCoimbra::get_converted_robot_X_into_world(){
+	//x world coordinate
+	return this->map.nbCellWidth*this->map.sizeCellWidth-Y;
+}
+
+float MiniExplorerCoimbra::get_converted_robot_Y_into_world(){
+	//y worldcoordinate
+	return X;
+}
+
+void MiniExplorerCoimbra::do_half_flip(){
+    Odometria();
+    float theta_plus_h_pi=theta+PI/2;//theta is between -PI and PI
+    if(theta_plus_h_pi > PI)
+        theta_plus_h_pi=-(2*PI-theta_plus_h_pi);
+    leftMotor(0,100);
+    rightMotor(1,100);
+    while(abs(theta_plus_h_pi-theta)>0.05){
+        Odometria();
+       // pc.printf("\n\r diff=%f", abs(theta_plus_pi-theta));
+    }
+    leftMotor(1,0);
+    rightMotor(1,0);    
+}
+
+//Distance computation function
+float MiniExplorerCoimbra::dist(float robotX, float robotY, float targetX, float targetY){
+    //pc.printf("%f, %f, %f, %f",robotX,robotY,targetX,targetY);
+    return sqrt(pow(targetY-robotY,2) + pow(targetX-robotX,2));
+}
+
+float MiniExplorerCoimbra::update_angular_speed_wheels_go_to_point_with_angle(float targetX, float targetY, float targetAngle, float dt){
+    //compute_angles_and_distance
+    float alpha = atan2((targetY-Y),(targetX-X))-theta;
+    alpha = atan(sin(alpha)/cos(alpha));
+    float rho = this->dist(X, Y, targetX, targetY);
+    float d2 = rho;
+    float beta = -alpha-theta+targetAngle;        
+    
+    //Computing angle error and distance towards the target value
+    rho += dt*(-this->khro*cos(alpha)*rho);
+    float temp = alpha;
+    alpha += dt*(this->khro*sin(alpha)-this->ka*alpha-this->kb*beta);
+    beta += dt*(-this->khro*sin(temp));
+
+    //Computing linear and angular velocities
+    float linear;
+    float angular;
+    if(alpha>=-1.5708 && alpha<=1.5708){
+        linear=this->khro*rho;
+        angular=this->ka*alpha+this->kb*beta;
+    }
+    else{
+        linear=-this->khro*rho;
+        angular=-this->ka*alpha-this->kb*beta;
+    }
+    float angular_left=(linear-0.5*this->distanceWheels*angular)/this->radiusWheels;
+    float angular_right=(linear+0.5*this->distanceWheels*angular)/this->radiusWheels;
+    
+    //Normalize speed for motors
+    if(angular_left>angular_right) {
+        angular_right=this->speed*angular_right/angular_left;
+        angular_left=this->speed;
+    } else {
+        angular_left=this->speed*angular_left/angular_right;
+        angular_right=this->speed;
+    }
+
+    //compute_linear_angular_velocities 
+    leftMotor(1,angular_left);
+    rightMotor(1,angular_right);
+    
+    return d2;
+}
+
+void MiniExplorerCoimbra::try_to_reach_target(float targetXWorld,float targetYWorld){
+    //atan2 gives the angle beetween PI and -PI
+    float angleToTarget=atan2(targetXWorld,targetYWorld);
+    turn_to_target(angleToTarget);
+    bool reached=false;
+    int print=0;
+    while (!reached) {
+        vff(&reached,targetXWorld,targetYWorld);
+        //test_got_to_line(&reached);
+        if(print==10){
+            leftMotor(1,0);
+            rightMotor(1,0);
+            /*
+            pc.printf("\r\n theta=%f", theta);
+            pc.printf("\r\n IN ORTHO:");
+            pc.printf("\r\n X Robot=%f", this->get_converted_robot_X_into_world());
+            pc.printf("\r\n Y Robot=%f", this->get_converted_robot_Y_into_world());
+            pc.printf("\r\n X Target=%f", targetXWorld);
+            pc.printf("\r\n Y Target=%f", targetYWorld);
+            */
+            print_final_map_with_robot_position_and_target();
+            print=0;
+        }else
+            print+=1;
+    }
+    //Stop at the end
+    leftMotor(1,0);
+    rightMotor(1,0);
+    pc.printf("\r\n target reached");
+    wait(3);//
+}
+
+void MiniExplorerCoimbra::vff(bool* reached, float targetXWorld, float targetYWorld){
+    float line_a;
+    float line_b;
+    float line_c;
+    //Updating X,Y and theta with the odometry values
+    float forceX=0;
+    float forceY=0;
+    //we update the odometrie
+    Odometria();
+    //we check the sensors
+    float leftMm = get_distance_left_sensor();
+    float frontMm = get_distance_front_sensor();
+    float rightMm = get_distance_right_sensor();
+    //update the probabilities values 
+    this->update_sonar_values(leftMm, frontMm, rightMm);
+    //we compute the force on X and Y
+    this->compute_forceX_and_forceY(&forceX, &forceY,targetXWorld,targetYWorld);
+    //we compute a new ine
+    this->calculate_line(forceX, forceY, &line_a,&line_b,&line_c);
+    //Updating motor velocities
+    this->go_to_line(line_a,line_b,line_c,targetXWorld,targetYWorld);
+
+    //wait(0.1);
+    Odometria();
+    if(dist(this->get_converted_robot_X_into_world(),this->get_converted_robot_Y_into_world(),targetXWorld,targetYWorld)<10)
+        *reached=true;
+}
+
+//compute the force on X and Y
+void MiniExplorerCoimbra::compute_forceX_and_forceY(float* forceX, float* forceY, float targetXWorld, float targetYWorld){
+     float xRobotWorld=this->get_converted_robot_X_into_world();
+     float yRobotWorld=this->get_converted_robot_Y_into_world();
+
+     float forceRepulsionComputedX=0;
+     float forceRepulsionComputedY=0;
+     //for each cell of the map we compute a force of repulsion
+     for(int i=0;i<this->map.nbCellWidth;i++){
+        for(int j=0;j<this->map.nbCellHeight;j++){
+            this->update_force(i,j,&forceRepulsionComputedX,&forceRepulsionComputedY,xRobotWorld,yRobotWorld);
+        }
+    }
+    //update with attraction force
+    *forceX=+forceRepulsionComputedX;
+    *forceY=+forceRepulsionComputedY;
+    float distanceTargetRobot=sqrt(pow(targetXWorld-xRobotWorld,2)+pow(targetYWorld-yRobotWorld,2));
+    if(distanceTargetRobot != 0){
+        *forceX-=this->attractionConstantForce*(targetXWorld-xRobotWorld)/distanceTargetRobot;
+        *forceY-=this->attractionConstantForce*(targetYWorld-yRobotWorld)/distanceTargetRobot;
+    }
+    float amplitude=sqrt(pow(*forceX,2)+pow(*forceY,2));
+    if(amplitude!=0){//avoid division by 0 if forceX and forceY  == 0
+        *forceX=*forceX/amplitude;
+        *forceY=*forceY/amplitude;
+    }
+}
+
+void MiniExplorerCoimbra::update_force(int widthIndice, int heightIndice, float* forceX, float* forceY, float xRobotWorld, float yRobotWorld ){
+    //get the coordonate of the map and the robot in the ortonormal space
+    float xWorldCell=this->map.cell_width_coordinate_to_world(widthIndice);
+    float yWorldCell=this->map.cell_height_coordinate_to_world(heightIndice);
+
+    //compute the distance beetween the cell and the robot
+    float distanceCellToRobot=sqrt(pow(xWorldCell-xRobotWorld,2)+pow(yWorldCell-yRobotWorld,2));
+    //check if the cell is in range
+    if(distanceCellToRobot <= this->rangeForce) {
+        float probaCell=this->map.get_proba_cell(widthIndice,heightIndice);
+        float xForceComputed=this->repulsionConstantForce*probaCell*(xWorldCell-xRobotWorld)/pow(distanceCellToRobot,3);
+        float yForceComputed=this->repulsionConstantForce*probaCell*(yWorldCell-yRobotWorld)/pow(distanceCellToRobot,3);
+        *forceX+=xForceComputed;
+        *forceY+=yForceComputed;
+    }
+}
+
+//robotX and robotY are from Odometria, calculate line_a, line_b and line_c
+void MiniExplorerCoimbra::calculate_line(float forceX, float forceY, float *line_a, float *line_b, float *line_c){
+    /*
+    in the teachers maths it is 
+    
+    *line_a=forceY;
+    *line_b=-forceX;
+    
+    because a*x+b*y+c=0
+    a impact the vertical and b the horizontal
+    and he has to put them like this because
+    Robot space:      orthonormal space:
+      ^                 ^
+      |x                |y
+   <- R                 O ->
+    y                     x
+    but since our forceX, forceY are already computed in the orthonormal space I m not sure we need to 
+    */
+    *line_a=forceX;
+    *line_b=forceY;
+    //because the line computed always pass by the robot center we dont need lince_c
+    //*line_c=forceX*yRobotWorld+forceY*xRobotWorld;    
+    *line_c=0;
+}
+
+//currently line_c is not used
+void MiniExplorerCoimbra::go_to_line(float line_a, float line_b, float line_c,float targetXWorld, float targetYWorld){
+    float lineAngle;
+    float angleError;
+    float linear;
+    float angular; 
+    
+    bool direction=true;
+    
+    //take as parameter how much the robot is supposed to move on x and y (world)
+    float angleToTarget=atan2(targetXWorld-this->get_converted_robot_X_into_world(),targetYWorld-this->get_converted_robot_Y_into_world());
+    bool inFront=true;
+    if(angleToTarget < 0)//the target is in front
+        inFront=false;
+
+    if(theta > 0){
+        //the robot is oriented to the left
+        if(theta > PI/2){
+            //the robot is oriented lower left
+            if(inFront)
+                direction=false;//robot and target not oriented the same way
+        }else{
+            //the robot is oriented upper left
+            if(!inFront)
+                direction=false;//robot and target not oriented the same way
+        }
+    }else{
+        //the robot is oriented to the right
+        if(theta < -PI/2){
+            //the robot is oriented lower right
+            if(inFront)
+                direction=false;//robot and target not oriented the same way
+        }else{ 
+            //the robot is oriented upper right
+            if(!inFront)
+                direction=false;//robot and target not oriented the same way
+        }
+    }
+    //pc.printf("\r\n Target is in front");
+    
+     if(line_b!=0){
+        if(!direction)
+            lineAngle=atan(-line_a/line_b);
+        else
+            lineAngle=atan(line_a/-line_b);
+    }
+    else{
+        lineAngle=1.5708;
+    }
+    
+    //Computing angle error
+    angleError = lineAngle-theta;
+    angleError = atan(sin(angleError)/cos(angleError));
+
+    //Calculating velocities
+    linear=this->kv*(3.1416);
+    angular=this->kh*angleError;
+
+    float angularLeft=(linear-0.5*this->distanceWheels*angular)/this->radiusWheels;
+    float angularRight=(linear+0.5*this->distanceWheels*angular)/this->radiusWheels;
+    
+    //Normalize speed for motors
+    if(abs(angularLeft)>abs(angularRight)) {  
+        angularRight=this->speed*abs(angularRight/angularLeft)*this->sign1(angularRight);
+        angularLeft=this->speed*this->sign1(angularLeft);
+    }
+    else {
+        angularLeft=this->speed*abs(angularLeft/angularRight)*this->sign1(angularLeft);
+        angularRight=this->speed*this->sign1(angularRight);
+    }
+    leftMotor(this->sign2(angularLeft),abs(angularLeft));
+    rightMotor(this->sign2(angularRight),abs(angularRight));
+}
+
+//return 1 if positiv, -1 if negativ
+float MiniExplorerCoimbra::sign1(float value){
+    if(value>=0) 
+        return 1;
+    else 
+        return -1;
+}
+
+//return 1 if positiv, 0 if negativ
+int MiniExplorerCoimbra::sign2(float value){
+    if(value>=0) 
+        return 1;
+    else 
+        return 0;
+}
+
+/*angleToTarget is obtained through atan2 so it s:
+< 0 if the angle is bettween PI and 2pi on a trigo circle
+> 0 if it is between 0 and PI
+*/
+void MiniExplorerCoimbra::turn_to_target(float angleToTarget){
+    Odometria();
+    float theta_plus_h_pi=theta+PI/2;//theta is between -PI and PI
+    if(theta_plus_h_pi > PI)
+        theta_plus_h_pi=-(2*PI-theta_plus_h_pi);
+     if(angleToTarget>0){   
+        leftMotor(0,1);
+        rightMotor(1,1);
+    }else{
+        leftMotor(1,1);
+        rightMotor(0,1);
+    }
+    while(abs(angleToTarget-theta_plus_h_pi)>0.05){
+        Odometria();
+        theta_plus_h_pi=theta+PI/2;//theta is between -PI and PI
+         if(theta_plus_h_pi > PI)
+            theta_plus_h_pi=-(2*PI-theta_plus_h_pi);
+        //pc.printf("\n\r diff=%f", abs(angleToTarget-theta_plus_h_pi));
+    }
+    leftMotor(1,0);
+    rightMotor(1,0);    
+}
+
+
+/*
+//x and y passed are TargetNotMap
+float get_error_angles(float x, float y,float theta){
+    float angleBeetweenRobotAndTarget=atan2(y,x);
+    if(y > 0){
+        if(angleBeetweenRobotAndTarget < PI/2)//up right
+            angleBeetweenRobotAndTarget=-PI/2+angleBeetweenRobotAndTarget;
+        else//up right
+            angleBeetweenRobotAndTarget=angleBeetweenRobotAndTarget-PI/2;
+    }else{
+        if(angleBeetweenRobotAndTarget > -PI/2)//lower right
+            angleBeetweenRobotAndTarget=angleBeetweenRobotAndTarget-PI/2;
+        else//lower left
+            angleBeetweenRobotAndTarget=2*PI+angleBeetweenRobotAndTarget-PI/2;
+    }
+    return angleBeetweenRobotAndTarget-theta;
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MiniExplorerCoimbra.hpp	Fri Jun 09 00:28:32 2017 +0000
@@ -0,0 +1,91 @@
+#ifndef MINIEXPLORERCOIMBRA_HPP
+#define MINIEXPLORERCOIMBRA_HPP
+
+#include "Map.hpp"
+#include "Sonar.hpp"
+#include "robot.h"
+#include "mbed.h"
+#include "math.h"
+
+	/*
+Robot coordinate system:      World coordinate system:
+      ^                 				^
+      |x                				|y
+   <--R                 				O-->
+    y                     				 x
+*/
+
+class MiniExplorerCoimbra {
+
+	public:
+
+	Map map;
+	Sonar sonarLeft;
+	Sonar sonarFront;
+	Sonar sonarRight;
+	float speed;
+	float radiusWheels;
+	float distanceWheels; 
+	float khro;
+	float ka;
+	float kb;
+	float kv;
+	float kh;
+
+	float rangeForce;
+	float attractionConstantForce;
+	float repulsionConstantForce;
+
+	MiniExplorerCoimbra(float defaultX, float defaultY, float defaultTheta);
+
+	void setXYTheta(float x, float y, float theta);
+	
+	//generate a position randomly and makes the robot go there while updating the map
+	void randomize_and_map();
+	
+	//go the the given position while updating the map
+	void go_to_point_with_angle(float targetX, float targetY, float targetAngle);
+	
+	void update_sonar_values(float leftMm,float frontMm,float rightMm);
+	
+	float get_converted_robot_X_into_world();
+	
+	float get_converted_robot_Y_into_world();
+	
+	void do_half_flip();
+	
+	//Distance computation function
+	float dist(float robotX, float robotY, float targetX, float targetY);
+	
+	float update_angular_speed_wheels_go_to_point_with_angle(float targetX, float targetY, float targetAngle, float dt);
+	
+	void try_to_reach_target(float targetXWorld,float targetYWorld);
+	
+	void vff(bool* reached, float targetXWorld, float targetYWorld);
+	
+	//compute the force on X and Y
+	void compute_forceX_and_forceY(float* forceX, float* forceY, float targetXWorld, float targetYWorld);
+	
+	void update_force(int widthIndice, int heightIndice, float* forceX, float* forceY, float xRobotWorld, float yRobotWorld );
+	
+	//robotX and robotY are from Odometria, calculate line_a, line_b and line_c
+	void calculate_line(float forceX, float forceY, float *line_a, float *line_b, float *line_c);
+	
+	//currently line_c is not used
+	void go_to_line(float line_a, float line_b, float line_c,float targetXWorld, float targetYWorld);
+	
+	//return 1 if positiv, -1 if negativ
+	float sign1(float value);
+	
+	//return 1 if positiv, 0 if negativ
+	int sign2(float value);
+	
+	/*angleToTarget is obtained through atan2 so it s:
+	< 0 if the angle is bettween PI and 2pi on a trigo circle
+	> 0 if it is between 0 and PI
+	*/
+	void turn_to_target(float angleToTarget);
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sonar.cpp	Fri Jun 09 00:28:32 2017 +0000
@@ -0,0 +1,104 @@
+#include "Sonar.hpp"
+
+Sonar::Sonar(float anlgeFromCenter, float distanceXRobot, float distanceYRobot ){
+	this->anlgeFromCenter=anlgeFromCenter;
+	this->distanceXRobot=-distanceYRobot;
+	this->distanceYRobot=distanceXRobot;
+	this->maxRange=50;//cm
+	this->minRange=10;//Rmin cm
+	this->incertitudeRange=10;//cm
+	this->angleRange=3.14159/3;//Omega rad
+}
+
+//ODOMETRIA MUST HAVE BEEN CALLED
+//function that check if a cell A(x,y) is in the range of the front sonar S(xs,ys) (with an angle depending on the sonar used, front 0, left pi/3, right -pi/3) returns the probability it's occupied/empty [0;1]
+float Sonar::compute_probability_t(float distanceObstacleDetected, float x, float y, float robotCoordinateXWorld, float robotCoordinateYWorld){
+	float xSonar=robotCoordinateXWorld+this->distanceX;
+	float ySonar=robotCoordinateYWorld+this->distanceY;
+    float distancePointToSonar=sqrt(pow(x-xSonar,2)+pow(y-ySonar,2));
+    if( distancePointToSonar < this->maxRange){
+        float anglePointToSonar=this->compute_angle_between_vectors(x,y,xSonar,ySonar);//angle beetween the point and the sonar beam
+        float alphaBeforeAdjustment=anglePointToSonar-theta-angleFromSonarPosition;
+        anglePointToSonar=rad_angle_check(alphaBeforeAdjustment);//TODO I feel you don't need to do that but I m not sure
+        
+        if(alphaBeforeAdjustment>pi)
+            alphaBeforeAdjustment=alphaBeforeAdjustment-2*pi;
+        if(alphaBeforeAdjustment<-pi)
+            alphaBeforeAdjustment=alphaBeforeAdjustment+2*pi;
+            
+        //float anglePointToSonar2=atan2(y-ys,x-xs)-theta;
+        
+        //check if the distance between the cell and the robot is within the circle of range RADIUS_WHEELS
+        //check if absolute difference between the angles is no more than Omega/2
+        if(anglePointToSonar <= this->angleRange/2 || anglePointToSonar >= this->rad_angle_check(-this->angleRange/2)){
+            if( distancePointToSonar < (distanceObstacleDetected - this->incertitudeRange)){
+            //point before obstacle, probably empty
+            /*****************************************************************************/
+                float Ea=1.f-pow((2*alphaBeforeAdjustment)/this->angleRange,2);
+                float Er;
+                if(distancePointToSonar < this->minRange){
+                    //point before minimum sonar range
+                    Er=0.f;
+                }else{
+                    //point after minimum sonar range
+                    Er=1.f-pow((distancePointToSonar-this->minRange)/(distanceObstacleDetected-this->incertitudeRange-this->minRange),2);
+                }
+             /*****************************************************************************/
+                //if((1.f-Er*Ea)/2.f >1 || (1.f-Er*Ea)/2.f < 0)
+                //    pc.printf("\n\r return value=%f,Er=%f,Ea=%f,alphaBeforeAdjustment=%f",(1.f-Er*Ea)/2.f,Er,Ea,alphaBeforeAdjustment);
+                return (1.f-Er*Ea)/2.f;
+            }else{
+                //probably occupied
+            /*****************************************************************************/
+                float Oa=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2);
+                float Or;
+                if( distancePointToSonar <= (distanceObstacleDetected + this->incertitudeRange)){
+                    //point between distanceObstacleDetected +- INCERTITUDE_SONAR
+                    Or=1-pow((distancePointToSonar-distanceObstacleDetected)/(this->incertitudeRange),2);
+                }else{
+                    //point after in range of the sonar but after the zone detected
+                    Or=0;
+                }
+            /*****************************************************************************/
+                //if((1+Or*Oa)/2 >1 || (1+Or*Oa)/2 < 0)
+                //    pc.printf("\n\r return value=%f,Er=%f,Ea=%f,alphaBeforeAdjustment=%f",(1+Or*Oa)/2,Or,Oa,alphaBeforeAdjustment);
+                return (1+Or*Oa)/2;
+            }
+        }   
+    }
+    //not checked by the sonar
+    return 0.5;
+}
+
+//returns the angle between the vectors (x,y) and (xs,ys)
+float Sonar::compute_angle_between_vectors(float x, float y,float xs,float ys){
+    //alpha angle between ->x and ->SA
+    //vector S to A ->SA
+    float vSAx=x-xs;
+    float vSAy=y-ys;
+    //norme SA
+    float normeSA=sqrt(pow(vSAx,2)+pow(vSAy,2));
+    //vector ->x (1,0)
+    float cosAlpha=1*vSAy/*+0*vSAx*//normeSA;;
+    //vector ->y (0,1)
+    float sinAlpha=/*0*vSAy+*/1*vSAx/normeSA;//+0*vSAx;
+    if (sinAlpha < 0)
+        return -acos(cosAlpha);
+    else
+        return acos(cosAlpha);
+}
+
+//makes the angle inAngle between 0 and 2pi
+float Sonar::rad_angle_check(float inAngle){
+    //cout<<"before :"<<inAngle;
+    if(inAngle > 0){
+        while(inAngle > (2*pi))
+            inAngle-=2*pi;
+    }else{
+        while(inAngle < 0)
+            inAngle+=2*pi;
+    }
+    //cout<<" after :"<<inAngle<<endl;
+    return inAngle;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sonar.hpp	Fri Jun 09 00:28:32 2017 +0000
@@ -0,0 +1,33 @@
+#ifndef SONAR_HPP
+#define SONAR_HPP
+
+#include "MiniExplorerCoimbra.hpp"
+
+class Sonar {
+
+public:
+	float maxRange;//cm
+	float minRange;//Rmin cm
+	float incertitudeRange;//cm
+	float angleRange;//Omega rad
+	float angleFromCenter;
+	float distanceX;
+	float distanceY;
+	
+
+	Sonar(float anlgeFromCenter, float distanceXRobot, float distanceYRobot );
+
+	//ODOMETRIA MUST HAVE BEEN CALLED
+	//function that check if a cell A(x,y) is in the range of the front sonar S(xs,ys) (with an angle depending on the sonar used, front 0, left pi/3, right -pi/3) returns the probability it's occupied/empty [0;1]
+	float compute_probability_t(float distanceObstacleDetected, float x, float y, float robotCoordinateXWorld, float robotCoordinateYWorld);
+
+	//returns the angle between the vectors (x,y) and (xs,ys)
+	float compute_angle_between_vectors(float x, float y,float xs,float ys);
+
+	//makes the angle inAngle between 0 and 2pi
+	float rad_angle_check(float inAngle);
+
+};
+
+#endif
+
--- a/main.cpp	Wed May 03 16:46:43 2017 +0000
+++ b/main.cpp	Fri Jun 09 00:28:32 2017 +0000
@@ -1,555 +1,8 @@
-#include "mbed.h"
-#include "robot.h" // Initializes the robot. This include should be used in all main.cpp!
-#include "math.h"
-
- using namespace std;
-
-//fill initialLogValues with the values we already know (here the bordurs)
-void fill_initial_log_values();
-//generate a position randomly and makes the robot go there while updating the map
-void randomize_and_map();
-//make the robot do a pi/2 flip
-void do_half_flip();
-//go the the given position while updating the map
-void go_to_point_with_angle(float target_x, float target_y, float target_angle);
-//Updates sonar values
-void update_sonar_values(float leftMm, float frontMm, float rightMm);
-//function that check if a cell A(x,y) is in the range of the front sonar S(xs,ys) (with an angle depending on the sonar used, front 0, left pi/3, right -pi/3) returns the probability it's occupied/empty [0;1]
-float compute_probability_t(float x, float y,float xs,float ys, float angleFromSonarPosition, float distanceObstacleDetected);
-//print the map
-void print_final_map();
-//print the map with the robot marked on it
-void print_final_map_with_robot_position();
-
-//MATHS heavy functions
-float dist(float robot_x, float robot_y, float target_x, float target_y);
-//returns the probability [0,1] that the cell is occupied from the log value lt
-float log_to_proba(float lt);
-//returns the log value that the cell is occupied from the probability value [0,1]
-float proba_to_log(float p);
-//returns the new log value
-float compute_log_estimation_lt(float previousLogValue,float currentProbability,float originalLogvalue );
-//makes the angle inAngle between 0 and 2pi
-float rad_angle_check(float inAngle);
-//returns the angle between the vectors (x,y) and (xs,ys)
-float compute_angle_between_vectors(float x, float y,float xs,float ys);
-float robot_center_x_in_orthonormal_x();
-float robot_center_y_in_orthonormal_y();
-float robot_sonar_front_x_in_orthonormal_x();
-float robot_sonar_front_y_in_orthonormal_y();
-float robot_sonar_right_x_in_orthonormal_x();
-float robot_sonar_right_y_in_orthonormal_y();
-float robot_sonar_left_x_in_orthonormal_x();
-float robot_sonar_left_y_in_orthonormal_y();
-float estimated_width_indice_in_orthonormal_x(int i);
-float estimated_height_indice_in_orthonormal_y(int j);
-void compute_angles_and_distance(float target_x, float target_y, float target_angle);
-void compute_linear_angular_velocities();
-//update foceX and forceY if necessary
-void updateForce(int widthIndice, int heightIndice, float range, float* forceX, float* forceY, float xRobotOrtho, float yRobotOrtho );
-//compute the X and Y force
-void compute_forceX_and_forceY(float targetX, float targetY,float forceX, float forceY);
-
-
-const float pi=3.14159;
-
-//CONSTANT FORCE FIELD
-const float FORCE_CONSTANT_REPULSION=10;//TODO tweak it
-const float FORCE_CONSTANT_ATTRACTION=10;//TODO tweak it
-const float RANGE_FORCE=50;//TODO tweak it
+#include "MiniExplorerCoimbra.hpp"
 
-//spec of the sonar
-//TODO MEASURE THE DISTANCE on X and Y of the robot frame, between each sonar and the center of the robot and add it to calculus in updateSonarValues
-const float RANGE_SONAR=50;//cm
-const float RANGE_SONAR_MIN=10;//Rmin cm
-const float INCERTITUDE_SONAR=10;//cm
-const float ANGLE_SONAR=pi/3;//Omega rad
-
-//those distance and angle are approximation in need of measurements, in the orthonormal frame
-const float ANGLE_FRONT_TO_LEFT=10*pi/36;//50 degrees
-const float DISTANCE_SONAR_LEFT_X=-4;
-const float DISTANCE_SONAR_LEFT_Y=4;
-
-const float ANGLE_FRONT_TO_RIGHT=-10*pi/36;//-50 degrees
-const float DISTANCE_SONAR_RIGHT_X=4;
-const float DISTANCE_SONAR_RIGHT_Y=4;
-
-const float ANGLE_FRONT_TO_FRONT=0;
-const float DISTANCE_SONAR_FRONT_X=0;
-const float DISTANCE_SONAR_FRONT_Y=5;
-
-//TODO adjust the size of the map for computation time (25*25?)
-const float WIDTH_ARENA=120;//cm
-const float HEIGHT_ARENA=90;//cm
-
-//const int SIZE_MAP=25;
-const int NB_CELL_WIDTH=24;
-const int NB_CELL_HEIGHT=18;
-
-//position and orientation of the robot when put on the map (ODOMETRY doesn't know those) it's in the robot frame
-//this configuration suppose that the robot is in the middle of the arena facing up (to be sure you can use print_final_map_with_robot_position
-const float DEFAULT_X=HEIGHT_ARENA/2;
-const float DEFAULT_Y=WIDTH_ARENA/2;
-const float DEFAULT_THETA=0;
-
-//used to create the map 250 represent the 250cm of the square where the robot is tested
-//float sizeCell=250/(float)SIZE_MAP;
-float sizeCellWidth=WIDTH_ARENA/(float)NB_CELL_WIDTH;
-float sizeCellHeight=HEIGHT_ARENA/(float)NB_CELL_HEIGHT;
-
-float map[NB_CELL_WIDTH][NB_CELL_HEIGHT];//contains the log values for each cell
-float initialLogValues[NB_CELL_WIDTH][NB_CELL_HEIGHT];
-
-//Diameter of a wheel and distance between the 2
-const float RADIUS_WHEELS=3.25;
-const float DISTANCE_WHEELS=7.2;
-
-const int MAX_SPEED=250;//TODO TWEAK THE SPEED SO IT DOES NOT FUCK UP
-
-float alpha; //angle error
-float rho; //distance from target
-float beta;
-float kRho=12, ka=30, kb=-13; //Kappa values
-float linear, angular, angular_left, angular_right;
-float dt=0.5;
-float temp;
-float d2;
-Timer t;
-
-int speed=MAX_SPEED; // Max speed at beggining of movement
-
-float leftMm;
-float frontMm;
-float rightMm; 
+using namespace std;
 
 int main(){
-    
-    i2c1.frequency(100000);
-    initRobot(); //Initializing the robot
-    pc.baud(9600); // baud for the pc communication
-
-    measure_always_on();//TODO check if needed
-    wait(0.5);
-    
-    fill_initial_log_values();
-
-    theta=DEFAULT_THETA;
-    X=DEFAULT_X;
-    Y=DEFAULT_Y;
-
-    
-    for (int i = 0; i<10; i++) {
-        randomize_and_map(); 
-        //print_final_map();
-        print_final_map_with_robot_position();   
-    }
-    while(1){
-        print_final_map();
-        print_final_map_with_robot_position();
-    }
-
-}
-
-//fill initialLogValues with the values we already know (here the bordurs)
-void fill_initial_log_values(){
-    //Fill map, we know the border are occupied
-    for (int i = 0; i<NB_CELL_WIDTH; i++) {
-        for (int j = 0; j<NB_CELL_HEIGHT; j++) {
-            if(j==0 || j==NB_CELL_HEIGHT-1 || i==0 || i==NB_CELL_WIDTH-1)
-                initialLogValues[i][j] = proba_to_log(1);
-            else
-                initialLogValues[i][j] = proba_to_log(0.5);
-        }
-    }
-}
-
-//generate a position randomly and makes the robot go there while updating the map
-void randomize_and_map() {
-    //TODO check that it's aurelien's work
-    float target_x = (rand()%(int)(HEIGHT_ARENA*10))/10;//for decimal precision
-    float target_y = (rand()%(int)(WIDTH_ARENA*10))/10;
-    float target_angle = 2*((float)(rand()%31416)-15708)/10000.0;
-    
-    //TODO comment that
-    //pc.printf("\n\r targ_X=%f", target_x);
-    //pc.printf("\n\r targ_Y=%f", target_y);
-    //pc.printf("\n\r targ_Angle=%f", target_angle);
-    
-    go_to_point_with_angle(target_x, target_y, target_angle);
-}
-
-
-void do_half_flip(){
-    Odometria();
-    float theta_plus_h_pi=theta+pi/2;//theta is between -pi and pi
-    if(theta_plus_h_pi > pi)
-        theta_plus_h_pi=-(2*pi-theta_plus_h_pi);
-    leftMotor(0,100);
-    rightMotor(1,100);
-    while(abs(theta_plus_h_pi-theta)>0.05){
-        Odometria();
-       // pc.printf("\n\r diff=%f", abs(theta_plus_pi-theta));
-    }
-    leftMotor(1,0);
-    rightMotor(1,0);    
-}
-
-//go the the given position while updating the map
-//TODO clean this procedure it's ugly as hell and too long
-void go_to_point_with_angle(float target_x, float target_y, float target_angle) {
-    Odometria();
-    alpha = atan2((target_y-Y),(target_x-X))-theta;
-    alpha = atan(sin(alpha)/cos(alpha));
-    rho = dist(X, Y, target_x, target_y);
-    beta = -alpha-theta+target_angle;
-    //beta = atan(sin(beta)/cos(beta));
-    bool keep_going=true;
-    do {
-        //Timer stuff
-        dt = t.read();
-        t.reset();
-        t.start();
-        
-        //Updating X,Y and theta with the odometry values
-        Odometria();
-        leftMm = get_distance_left_sensor();
-        frontMm = get_distance_front_sensor();
-        rightMm = get_distance_right_sensor();
-
-        //pc.printf("\n\r leftMm=%f", leftMm);
-        //pc.printf("\n\r frontMm=%f", frontMm);
-        //pc.printf("\n\r rightMm=%f", rightMm);
-    
-        //if in dangerzone 
-        if(frontMm < 120 || leftMm <120 || rightMm <120){
-            leftMotor(1,0);
-            rightMotor(1,0);
-            update_sonar_values(leftMm, frontMm, rightMm);
-            //TODO Giorgos maybe you can also test the do_half_flip() function
-            Odometria();
-            //do a flip TODO
-            keep_going=false;
-            do_half_flip();   
-        }else{
-            //if not in danger zone continue as usual
-            update_sonar_values(leftMm, frontMm, rightMm);
-            compute_angles_and_distance(target_x, target_y, target_angle); //Compute the angles and the distance from target
-            compute_linear_angular_velocities(); //Using the angles and distance, compute the velocities needed (linear & angular)
-    
-            //pc.printf("\n\r X=%f", X);
-            //pc.printf("\n\r Y=%f", Y);
-    
-            //pc.printf("\n\r a_r=%f", angular_right);
-            //pc.printf("\n\r a_l=%f", angular_left);
-    
-            //Updating motor velocities
-            leftMotor(1,angular_left);
-            rightMotor(1,angular_right);
-    
-            wait(0.2);
-            //Timer stuff
-            t.stop();
-        }
-    } while(d2>1 && (abs(target_angle-theta)>0.01) && keep_going);
-
-    //Stop at the end
-    leftMotor(1,0);
-    rightMotor(1,0);
-}
-
-//Updates sonar values
-void update_sonar_values(float leftMm, float frontMm, float rightMm){
-    float currProba;
-    float i_in_orthonormal;
-    float j_in_orthonormal;
-    for(int i=0;i<NB_CELL_WIDTH;i++){
-        for(int j=0;j<NB_CELL_HEIGHT;j++){
-                //check if the point A(x,y) in the world frame is within the range of the sonar (which has the coordinates xs, ys in the world frame)
-            //check that again
-            //compute for front sonar
-            i_in_orthonormal=estimated_width_indice_in_orthonormal_x(i);
-            j_in_orthonormal=estimated_height_indice_in_orthonormal_y(j);
-
-            currProba=compute_probability_t(i_in_orthonormal,j_in_orthonormal,robot_sonar_front_x_in_orthonormal_x(),robot_sonar_front_y_in_orthonormal_y(),ANGLE_FRONT_TO_FRONT,frontMm/10);
-            map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j];//map is filled as map[0][0] get the data for the point closest to the origin
-            //compute for right sonar
-            currProba=compute_probability_t(i_in_orthonormal,j_in_orthonormal,robot_sonar_right_x_in_orthonormal_x(),robot_sonar_right_y_in_orthonormal_y(),ANGLE_FRONT_TO_RIGHT,rightMm/10);
-            map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j];
-             //compute for left sonar
-            currProba=compute_probability_t(i_in_orthonormal,j_in_orthonormal,robot_sonar_left_x_in_orthonormal_x(),robot_sonar_left_y_in_orthonormal_y(),ANGLE_FRONT_TO_LEFT,leftMm/10);
-            map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j];
-        }
-    }
-}
-
-//ODOMETRIA MUST HAVE BEEN CALLED
-//function that check if a cell A(x,y) is in the range of the front sonar S(xs,ys) (with an angle depending on the sonar used, front 0, left pi/3, right -pi/3) returns the probability it's occupied/empty [0;1]
-float compute_probability_t(float x, float y,float xs,float ys, float angleFromSonarPosition, float distanceObstacleDetected){
-
-    float alpha=compute_angle_between_vectors(x,y,xs,ys);//angle beetween the point and the sonar beam
-    float alphaBeforeAdjustment=alpha-theta-angleFromSonarPosition;
-    alpha=rad_angle_check(alphaBeforeAdjustment);//TODO I feel you don't need to do that but I m not sure
-    float distancePointToSonar=sqrt(pow(x-xs,2)+pow(y-ys,2));
-
-    //check if the distance between the cell and the robot is within the circle of range RADIUS_WHEELS
-    //check if absolute difference between the angles is no more than Omega/2
-    if( distancePointToSonar < (RANGE_SONAR)&& (alpha <= ANGLE_SONAR/2 || alpha >= rad_angle_check(-ANGLE_SONAR/2))){
-        if( distancePointToSonar < (distanceObstacleDetected - INCERTITUDE_SONAR)){
-        //point before obstacle, probably empty
-        /*****************************************************************************/
-            float Ea=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2);
-            float Er;
-            if(distancePointToSonar < RANGE_SONAR_MIN){
-                //point before minimum sonar range
-                Er=0.f;
-            }else{
-                //point after minimum sonar range
-                Er=1.f-pow((distancePointToSonar-RANGE_SONAR_MIN)/(distanceObstacleDetected-INCERTITUDE_SONAR-RANGE_SONAR_MIN),2);
-            }
-         /*****************************************************************************/
-            return (1.f-Er*Ea)/2.f;
-        }else{
-            //probably occupied
-        /*****************************************************************************/
-            float Oa=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2);
-            float Or;
-            if( distancePointToSonar <= (distanceObstacleDetected + INCERTITUDE_SONAR)){
-                //point between distanceObstacleDetected +- INCERTITUDE_SONAR
-                Or=1-pow((distancePointToSonar-distanceObstacleDetected)/(INCERTITUDE_SONAR),2);
-            }else{
-                //point after in range of the sonar but after the zone detected
-                Or=0;
-            }
-        /*****************************************************************************/
-            return (1+Or*Oa)/2;
-        }
-    }else{
-        //not checked by the sonar
-        return 0.5;
-    }
+    MiniExplorerCoimbra myRobot(0,0,0);   
+    return 0;
 }
-
-void print_final_map() {
-    float currProba;
-    pc.printf("\n\r");
-    for (int y = NB_CELL_HEIGHT -1; y>-1; y--) {
-        for (int x= 0; x<NB_CELL_WIDTH; x++) {
-                currProba=log_to_proba(map[x][y]);
-            if ( currProba < 0.5) {
-                pc.printf("   ");
-            } else {
-                if(currProba==0.5)
-                    pc.printf(" . ");
-                else
-                    pc.printf(" X ");
-            }
-        }
-        pc.printf("\n\r");
-    }
-}
-
-void print_final_map_with_robot_position() {
-    float currProba;
-    Odometria();
-    float Xrobot=robot_center_x_in_orthonormal_x();
-    float Yrobot=robot_center_y_in_orthonormal_y();
-    
-    float heightIndiceInOrthonormal;
-    float widthIndiceInOrthonormal;
-    
-    float widthMalus=-(3*sizeCellWidth/2);
-    float widthBonus=sizeCellWidth/2;
-    
-    float heightMalus=-(3*sizeCellHeight/2);
-    float heightBonus=sizeCellHeight/2;
-
-    pc.printf("\n\r");
-    for (int y = NB_CELL_HEIGHT -1; y>-1; y--) {
-        for (int x= 0; x<NB_CELL_WIDTH; x++) {
-            heightIndiceInOrthonormal=estimated_height_indice_in_orthonormal_y(y);
-            widthIndiceInOrthonormal=estimated_width_indice_in_orthonormal_x(x);
-            if(Yrobot >= (heightIndiceInOrthonormal+heightMalus) && Yrobot <= (heightIndiceInOrthonormal+heightBonus) && Xrobot >= (widthIndiceInOrthonormal+widthMalus) && Xrobot <= (widthIndiceInOrthonormal+widthBonus))                    
-                pc.printf(" R ");
-            else{
-                currProba=log_to_proba(map[x][y]);
-                if ( currProba < 0.5)
-                    pc.printf("   ");
-                else{
-                    if(currProba==0.5)
-                        pc.printf(" . ");
-                    else
-                        pc.printf(" X ");
-                } 
-            }
-        }
-        pc.printf("\n\r");
-    }
-}
-
-//MATHS heavy functions
-/**********************************************************************/
-//Distance computation function
-float dist(float robot_x, float robot_y, float target_x, float target_y){
-    return sqrt(pow(target_y-robot_y,2) + pow(target_x-robot_x,2));
-}
-
-//returns the probability [0,1] that the cell is occupied from the log valAue lt
-float log_to_proba(float lt){
-    return 1-1/(1+exp(lt));
-}
-
-//returns the log value that the cell is occupied from the probability value [0,1]
-float proba_to_log(float p){
-    return log(p/(1-p));
-}
-
-//returns the new log value
-float compute_log_estimation_lt(float previousLogValue,float currentProbability,float originalLogvalue ){
-    return previousLogValue+proba_to_log(currentProbability)-originalLogvalue;
-}
-
-//makes the angle inAngle between 0 and 2pi
-float rad_angle_check(float inAngle){
-    //cout<<"before :"<<inAngle;
-    if(inAngle > 0){
-        while(inAngle > (2*pi))
-            inAngle-=2*pi;
-    }else{
-        while(inAngle < 0)
-            inAngle+=2*pi;
-    }
-    //cout<<" after :"<<inAngle<<endl;
-    return inAngle;
-}
-
-//returns the angle between the vectors (x,y) and (xs,ys)
-float compute_angle_between_vectors(float x, float y,float xs,float ys){
-    //alpha angle between ->x and ->SA
-    //vector S to A ->SA
-    float vSAx=x-xs;
-    float vSAy=y-ys;
-    //norme SA
-    float normeSA=sqrt(pow(vSAx,2)+pow(vSAy,2));
-    //vector ->x (1,0)
-    float cosAlpha=1*vSAy/*+0*vSAx*//normeSA;;
-    //vector ->y (0,1)
-    float sinAlpha=/*0*vSAy+*/1*vSAx/normeSA;//+0*vSAx;
-    if (sinAlpha < 0)
-        return -acos(cosAlpha);
-    else
-        return acos(cosAlpha);
-}
-
-float robot_center_x_in_orthonormal_x(){
-    return NB_CELL_WIDTH*sizeCellWidth-Y;
-}
-
-float robot_center_y_in_orthonormal_y(){
-    return X;
-}
-
-float robot_sonar_front_x_in_orthonormal_x(){
-    return robot_center_x_in_orthonormal_x()+DISTANCE_SONAR_FRONT_X;
-}
-float robot_sonar_front_y_in_orthonormal_y(){
-    return robot_center_y_in_orthonormal_y()+DISTANCE_SONAR_FRONT_Y;
-}
-
-float robot_sonar_right_x_in_orthonormal_x(){
-    return robot_center_x_in_orthonormal_x()+DISTANCE_SONAR_RIGHT_X;
-}
-float robot_sonar_right_y_in_orthonormal_y(){
-    return robot_center_y_in_orthonormal_y()+DISTANCE_SONAR_RIGHT_Y;
-}
-
-float robot_sonar_left_x_in_orthonormal_x(){
-    return robot_center_x_in_orthonormal_x()+DISTANCE_SONAR_LEFT_X;
-}
-float robot_sonar_left_y_in_orthonormal_y(){
-    return robot_center_y_in_orthonormal_y()+DISTANCE_SONAR_LEFT_Y;
-}
-
-float estimated_width_indice_in_orthonormal_x(int i){
-    return sizeCellWidth/2+i*sizeCellWidth;
-}
-float estimated_height_indice_in_orthonormal_y(int j){
-    return sizeCellHeight/2+j*sizeCellHeight;
-}
-
-void compute_angles_and_distance(float target_x, float target_y, float target_angle){
-    alpha = atan2((target_y-Y),(target_x-X))-theta;
-    alpha = atan(sin(alpha)/cos(alpha));
-    rho = dist(X, Y, target_x, target_y);
-    d2 = rho;
-    beta = -alpha-theta+target_angle;        
-    
-    //Computing angle error and distance towards the target value
-    rho += dt*(-kRho*cos(alpha)*rho);
-    temp = alpha;
-    alpha += dt*(kRho*sin(alpha)-ka*alpha-kb*beta);
-    beta += dt*(-kRho*sin(temp));
-   //pc.printf("\n\r d2=%f", d2);
-    //pc.printf("\n\r dt=%f", dt);
-}
-
-void compute_linear_angular_velocities(){
-    //Computing linear and angular velocities
-    if(alpha>=-1.5708 && alpha<=1.5708){
-        linear=kRho*rho;
-        angular=ka*alpha+kb*beta;
-    }
-    else{
-        linear=-kRho*rho;
-        angular=-ka*alpha-kb*beta;
-    }
-    angular_left=(linear-0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS;
-    angular_right=(linear+0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS;
-    
-    //Slowing down at the end for more precision
-    // if (d2<25) {
-    //     speed = d2*30;
-    // }
-    
-    //Normalize speed for motors
-    if(angular_left>angular_right) {
-        angular_right=speed*angular_right/angular_left;
-        angular_left=speed;
-    } else {
-        angular_left=speed*angular_left/angular_right;
-        angular_right=speed;
-    }
-}
-
-
-void updateForce(int widthIndice, int heightIndice, float range, float* forceX, float* forceY, float xRobotOrtho, float yRobotOrtho ){
-    
-    //get the coordonate of the map and the robot in the ortonormal frame
-    float xCenterCell=estimated_width_indice_in_orthonormal_x(widthIndice);
-    float yCenterCell=estimated_height_indice_in_orthonormal_y(heightIndice);
-    //compute the distance beetween the cell and the robot
-    float distanceCellToRobot=sqrt(pow(xCenterCell-xRobotOrtho,2)+pow(yCenterCell-yRobotOrtho,2));
-    //check if the cell is in range
-    if(distanceCellToRobot <= (range)) {
-        float probaCell=log_to_proba(map[widthIndice][heightIndice]);
-        float xForceComputed=FORCE_CONSTANT_REPULSION*probaCell*(xCenterCell-xRobotOrtho)/pow(distanceCellToRobot,3);
-        float yForceComputed=FORCE_CONSTANT_REPULSION*probaCell*(yCenterCell-yRobotOrtho)/pow(distanceCellToRobot,3);
-        *forceX+=xForceComputed;
-        *forceY+=yForceComputed;
-    }
-}
-
-void compute_forceX_and_forceY(float targetX, float targetY,float forceX, float forceY){
-     float xRobotOrtho=robot_center_x_in_orthonormal_x();
-     float yRobotOrtho=robot_center_y_in_orthonormal_y();
-     for(int i=0;i<NB_CELL_WIDTH;i++){
-        for(int j=0;j<NB_CELL_HEIGHT;j++){
-            updateForce(i,j,RANGE_FORCE,&forceX,&forceY,xRobotOrtho,yRobotOrtho);
-        }
-    }
-    //update with attraction force  
-    forceX+=FORCE_CONSTANT_ATTRACTION*(targetX-xRobotOrtho)/sqrt(pow(targetX-xRobotOrtho,2)+pow(targetY-yRobotOrtho,2));
-    forceY+=FORCE_CONSTANT_ATTRACTION*(targetY-yRobotOrtho)/sqrt(pow(targetX-xRobotOrtho,2)+pow(targetY-yRobotOrtho,2));
-    float amplitude=sqrt(pow(forceX,2)+pow(forceY,2));
-    forceX=forceX/amplitude;
-    forceY=forceY/amplitude;
-}
\ No newline at end of file