![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Navigate to a given point using the OGM and virtual forces
Dependencies: ISR_Mini-explorer mbed
Fork of VirtualForces by
main.cpp@23:901fc468b8a7, 2017-04-19 (annotated)
- Committer:
- geotsam
- Date:
- Wed Apr 19 10:45:09 2017 +0000
- Revision:
- 23:901fc468b8a7
- Parent:
- 22:ebb37a249b5f
- Child:
- 24:8f4b820d8de8
cleaned up and shortened the go_to_point_with_angle method
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
geotsam | 0:8bffb51cc345 | 1 | #include "mbed.h" |
geotsam | 0:8bffb51cc345 | 2 | #include "robot.h" // Initializes the robot. This include should be used in all main.cpp! |
geotsam | 0:8bffb51cc345 | 3 | #include "math.h" |
Ludwigfr | 22:ebb37a249b5f | 4 | |
Ludwigfr | 22:ebb37a249b5f | 5 | using namespace std; |
AurelienBernier | 4:8c56c3ba6e54 | 6 | |
Ludwigfr | 22:ebb37a249b5f | 7 | //fill initialLogValues with the values we already know (here the bordurs) |
Ludwigfr | 22:ebb37a249b5f | 8 | void fill_initial_log_values(); |
Ludwigfr | 22:ebb37a249b5f | 9 | //generate a position randomly and makes the robot go there while updating the map |
Ludwigfr | 22:ebb37a249b5f | 10 | void randomize_and_map(); |
Ludwigfr | 22:ebb37a249b5f | 11 | //go the the given position while updating the map |
Ludwigfr | 22:ebb37a249b5f | 12 | void go_to_point_with_angle(float target_x, float target_y, float target_angle); |
Ludwigfr | 22:ebb37a249b5f | 13 | //Updates sonar values |
Ludwigfr | 22:ebb37a249b5f | 14 | void update_sonar_values(); |
Ludwigfr | 22:ebb37a249b5f | 15 | //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] |
Ludwigfr | 22:ebb37a249b5f | 16 | float compute_probability_t(float x, float y,float xs,float ys, float angleFromSonarPosition, float distanceObstacleDetected); |
Ludwigfr | 22:ebb37a249b5f | 17 | //print the map |
Ludwigfr | 22:ebb37a249b5f | 18 | void print_final_map(); |
geotsam | 23:901fc468b8a7 | 19 | //compute the angles and distance used for the velocities |
geotsam | 23:901fc468b8a7 | 20 | void compute_angles_and_distance(float target_x, float target_y, float target_angle); |
geotsam | 23:901fc468b8a7 | 21 | //compute the linear and 2 angular velocities |
geotsam | 23:901fc468b8a7 | 22 | void compute_linear_angular_velocities(); |
geotsam | 23:901fc468b8a7 | 23 | |
geotsam | 0:8bffb51cc345 | 24 | |
Ludwigfr | 22:ebb37a249b5f | 25 | //MATHS heavy functions |
Ludwigfr | 22:ebb37a249b5f | 26 | float dist(float robot_x, float robot_y, float target_x, float target_y); |
Ludwigfr | 22:ebb37a249b5f | 27 | //returns the probability [0,1] that the cell is occupied from the log value lt |
Ludwigfr | 22:ebb37a249b5f | 28 | float log_to_proba(float lt); |
Ludwigfr | 22:ebb37a249b5f | 29 | //returns the log value that the cell is occupied from the probability value [0,1] |
Ludwigfr | 22:ebb37a249b5f | 30 | float proba_to_log(float p); |
Ludwigfr | 22:ebb37a249b5f | 31 | //returns the new log value |
Ludwigfr | 22:ebb37a249b5f | 32 | float compute_log_estimation_lt(float previousLogValue,float currentProbability,float originalLogvalue ); |
Ludwigfr | 22:ebb37a249b5f | 33 | //makes the angle inAngle between 0 and 2pi |
Ludwigfr | 22:ebb37a249b5f | 34 | float rad_angle_check(float inAngle); |
Ludwigfr | 22:ebb37a249b5f | 35 | //returns the angle between the vectors (x,y) and (xs,ys) |
Ludwigfr | 22:ebb37a249b5f | 36 | float compute_angle_between_vectors(float x, float y,float xs,float ys); |
AurelienBernier | 8:109314be5b68 | 37 | |
Ludwigfr | 22:ebb37a249b5f | 38 | const float pi=3.14159; |
Ludwigfr | 22:ebb37a249b5f | 39 | //spec of the sonar |
Ludwigfr | 22:ebb37a249b5f | 40 | //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 |
Ludwigfr | 22:ebb37a249b5f | 41 | const float RANGE_SONAR=50;//RADIUS_WHEELS |
Ludwigfr | 22:ebb37a249b5f | 42 | const float RANGE_SONAR_MIN=10;//Rmin |
Ludwigfr | 22:ebb37a249b5f | 43 | const float INCERTITUDE_SONAR=10; |
Ludwigfr | 22:ebb37a249b5f | 44 | const float ANGLE_SONAR=pi/3;//Omega |
Ludwigfr | 22:ebb37a249b5f | 45 | |
Ludwigfr | 22:ebb37a249b5f | 46 | //those distance and angle are approximation in need of measurements |
Ludwigfr | 22:ebb37a249b5f | 47 | const float ANGLE_FRONT_TO_LEFT=pi/3; |
Ludwigfr | 22:ebb37a249b5f | 48 | const float DISTANCE_SONAR_LEFT_X=5; |
Ludwigfr | 22:ebb37a249b5f | 49 | const float DISTANCE_SONAR_LEFT_Y=5; |
Ludwigfr | 22:ebb37a249b5f | 50 | float leftMm; |
Ludwigfr | 22:ebb37a249b5f | 51 | |
Ludwigfr | 22:ebb37a249b5f | 52 | const float ANGLE_FRONT_TO_RIGHT=-pi/3; |
Ludwigfr | 22:ebb37a249b5f | 53 | const float DISTANCE_SONAR_RIGHT_X=-5; |
Ludwigfr | 22:ebb37a249b5f | 54 | const float DISTANCE_SONAR_RIGHT_Y=5; |
Ludwigfr | 22:ebb37a249b5f | 55 | float rightMm; |
AurelienBernier | 11:e641aa08c92e | 56 | |
Ludwigfr | 22:ebb37a249b5f | 57 | const float ANGLE_FRONT_TO_FRONT=0; |
Ludwigfr | 22:ebb37a249b5f | 58 | const float DISTANCE_SONAR_FRONT_X=0; |
Ludwigfr | 22:ebb37a249b5f | 59 | const float DISTANCE_SONAR_FRONT_Y=5; |
Ludwigfr | 22:ebb37a249b5f | 60 | float frontMm; |
Ludwigfr | 22:ebb37a249b5f | 61 | |
Ludwigfr | 22:ebb37a249b5f | 62 | //TODO adjust the size of the map for computation time (25*25?) |
Ludwigfr | 22:ebb37a249b5f | 63 | const int SIZE_MAP=25; |
Ludwigfr | 22:ebb37a249b5f | 64 | |
Ludwigfr | 22:ebb37a249b5f | 65 | //position and orientation of the robot when put on the map (ODOMETRY doesn't know those) |
Ludwigfr | 22:ebb37a249b5f | 66 | const float DEFAULT_X=0; |
Ludwigfr | 22:ebb37a249b5f | 67 | const float DEFAULT_Y=0; |
Ludwigfr | 22:ebb37a249b5f | 68 | const float DEFAULT_THETA=pi/2; |
Ludwigfr | 22:ebb37a249b5f | 69 | |
Ludwigfr | 22:ebb37a249b5f | 70 | //used to create the map 250 represent the 250cm of the table where the robot is tested |
Ludwigfr | 22:ebb37a249b5f | 71 | float sizeCell=250/(float)SIZE_MAP; |
Ludwigfr | 22:ebb37a249b5f | 72 | float map[SIZE_MAP][SIZE_MAP];//contains the log values for each cell |
Ludwigfr | 22:ebb37a249b5f | 73 | float initialLogValues[SIZE_MAP][SIZE_MAP]; |
Ludwigfr | 22:ebb37a249b5f | 74 | |
Ludwigfr | 22:ebb37a249b5f | 75 | //Diameter of a wheel and distance between the 2 |
Ludwigfr | 22:ebb37a249b5f | 76 | const float RADIUS_WHEELS=3.25; |
Ludwigfr | 22:ebb37a249b5f | 77 | const float DISTANCE_WHEELS=7.2; |
Ludwigfr | 22:ebb37a249b5f | 78 | |
AurelienBernier | 8:109314be5b68 | 79 | float alpha; //angle error |
AurelienBernier | 8:109314be5b68 | 80 | float rho; //distance from target |
AurelienBernier | 8:109314be5b68 | 81 | float beta; |
AurelienBernier | 11:e641aa08c92e | 82 | float kRho=12, ka=30, kb=-13; //Kappa values |
AurelienBernier | 8:109314be5b68 | 83 | float linear, angular, angular_left, angular_right; |
AurelienBernier | 8:109314be5b68 | 84 | float dt=0.5; |
AurelienBernier | 8:109314be5b68 | 85 | float temp; |
AurelienBernier | 8:109314be5b68 | 86 | float d2; |
Ludwigfr | 22:ebb37a249b5f | 87 | Timer t; |
AurelienBernier | 8:109314be5b68 | 88 | |
AurelienBernier | 8:109314be5b68 | 89 | int speed=999; // Max speed at beggining of movement |
AurelienBernier | 8:109314be5b68 | 90 | |
geotsam | 0:8bffb51cc345 | 91 | int main(){ |
geotsam | 17:caf393b63e27 | 92 | |
geotsam | 13:41f75c132135 | 93 | i2c1.frequency(100000); |
AurelienBernier | 2:ea61e801e81f | 94 | initRobot(); //Initializing the robot |
geotsam | 0:8bffb51cc345 | 95 | pc.baud(9600); // baud for the pc communication |
geotsam | 0:8bffb51cc345 | 96 | |
Ludwigfr | 22:ebb37a249b5f | 97 | measure_always_on();//TODO check if needed |
AurelienBernier | 19:dbc5fbad4975 | 98 | |
Ludwigfr | 22:ebb37a249b5f | 99 | fill_initial_log_values(); |
geotsam | 13:41f75c132135 | 100 | |
AurelienBernier | 21:62154d644531 | 101 | for (int i = 0; i<25; i++) { |
Ludwigfr | 22:ebb37a249b5f | 102 | randomize_and_map(); |
geotsam | 17:caf393b63e27 | 103 | } |
AurelienBernier | 8:109314be5b68 | 104 | //Stop at the end |
AurelienBernier | 8:109314be5b68 | 105 | leftMotor(1,0); |
AurelienBernier | 8:109314be5b68 | 106 | rightMotor(1,0); |
AurelienBernier | 8:109314be5b68 | 107 | |
AurelienBernier | 21:62154d644531 | 108 | //pc.printf("\n\r %f -- arrived!", rho); |
Ludwigfr | 22:ebb37a249b5f | 109 | print_final_map(); |
AurelienBernier | 8:109314be5b68 | 110 | } |
AurelienBernier | 8:109314be5b68 | 111 | |
Ludwigfr | 22:ebb37a249b5f | 112 | //fill initialLogValues with the values we already know (here the bordurs) |
Ludwigfr | 22:ebb37a249b5f | 113 | void fill_initial_log_values(){ |
Ludwigfr | 22:ebb37a249b5f | 114 | //Fill map, we know the border are occupied |
Ludwigfr | 22:ebb37a249b5f | 115 | for (int i = 0; i<SIZE_MAP; i++) { |
Ludwigfr | 22:ebb37a249b5f | 116 | for (int j = 0; j<SIZE_MAP; j++) { |
Ludwigfr | 22:ebb37a249b5f | 117 | if(j==0 || j==SIZE_MAP-1 || i==0 || i==SIZE_MAP-1) |
Ludwigfr | 22:ebb37a249b5f | 118 | initialLogValues[i][j] = proba_to_log(1); |
Ludwigfr | 22:ebb37a249b5f | 119 | else |
Ludwigfr | 22:ebb37a249b5f | 120 | initialLogValues[i][j] = proba_to_log(0.5); |
AurelienBernier | 21:62154d644531 | 121 | } |
Ludwigfr | 22:ebb37a249b5f | 122 | } |
AurelienBernier | 8:109314be5b68 | 123 | } |
AurelienBernier | 8:109314be5b68 | 124 | |
Ludwigfr | 22:ebb37a249b5f | 125 | //generate a position randomly and makes the robot go there while updating the map |
Ludwigfr | 22:ebb37a249b5f | 126 | void randomize_and_map() { |
Ludwigfr | 22:ebb37a249b5f | 127 | float target_x = (rand()%2500)/10;//for decimal precision |
Ludwigfr | 22:ebb37a249b5f | 128 | float target_y = (rand()%2500)/10; |
Ludwigfr | 22:ebb37a249b5f | 129 | float target_angle = ((float)(rand()%31416)-15708)/10000.0; |
Ludwigfr | 22:ebb37a249b5f | 130 | /* |
AurelienBernier | 19:dbc5fbad4975 | 131 | pc.printf("\n\r targ_X=%f", target_x); |
AurelienBernier | 19:dbc5fbad4975 | 132 | pc.printf("\n\r targ_Y=%f", target_y); |
AurelienBernier | 19:dbc5fbad4975 | 133 | pc.printf("\n\r targ_Angle=%f", target_angle); |
Ludwigfr | 22:ebb37a249b5f | 134 | */ |
Ludwigfr | 22:ebb37a249b5f | 135 | go_to_point_with_angle(target_x, target_y, target_angle); |
AurelienBernier | 19:dbc5fbad4975 | 136 | } |
AurelienBernier | 19:dbc5fbad4975 | 137 | |
Ludwigfr | 22:ebb37a249b5f | 138 | //go the the given position while updating the map |
Ludwigfr | 22:ebb37a249b5f | 139 | //TODO clean this procedure it's ugly as hell and too long |
Ludwigfr | 22:ebb37a249b5f | 140 | void go_to_point_with_angle(float target_x, float target_y, float target_angle) { |
geotsam | 23:901fc468b8a7 | 141 | bool tooClose=false; //binary variable to know if an obstacle is <10cm away |
AurelienBernier | 8:109314be5b68 | 142 | do { |
geotsam | 0:8bffb51cc345 | 143 | pc.printf("\n\n\r entered while"); |
AurelienBernier | 2:ea61e801e81f | 144 | |
AurelienBernier | 6:afde4b08166b | 145 | //Timer stuff |
AurelienBernier | 6:afde4b08166b | 146 | dt = t.read(); |
AurelienBernier | 6:afde4b08166b | 147 | t.reset(); |
AurelienBernier | 6:afde4b08166b | 148 | t.start(); |
AurelienBernier | 6:afde4b08166b | 149 | |
geotsam | 14:d58f2bdbf42e | 150 | //Updating X,Y and theta with the odometry values |
geotsam | 14:d58f2bdbf42e | 151 | Odometria(); |
geotsam | 14:d58f2bdbf42e | 152 | |
geotsam | 23:901fc468b8a7 | 153 | //Updare the values from the sonar |
Ludwigfr | 22:ebb37a249b5f | 154 | update_sonar_values(); |
Ludwigfr | 22:ebb37a249b5f | 155 | |
geotsam | 23:901fc468b8a7 | 156 | //Check if one of the sonars finds an obstacle that is too close |
AurelienBernier | 11:e641aa08c92e | 157 | if (leftMm < 100 || frontMm < 100 || rightMm < 100) { |
AurelienBernier | 21:62154d644531 | 158 | tooClose = true; |
geotsam | 14:d58f2bdbf42e | 159 | break; |
AurelienBernier | 11:e641aa08c92e | 160 | } |
AurelienBernier | 11:e641aa08c92e | 161 | |
geotsam | 23:901fc468b8a7 | 162 | compute_angles_and_distance(target_x, target_y, target_angle); //Compute the angles and the distance from target |
geotsam | 23:901fc468b8a7 | 163 | compute_linear_angular_velocities(); //Using the angles and distance, compute the velocities needed (linear & angular) |
geotsam | 0:8bffb51cc345 | 164 | |
geotsam | 23:901fc468b8a7 | 165 | //Printing values for debugging purposes |
geotsam | 0:8bffb51cc345 | 166 | pc.printf("\n\r X=%f", X); |
geotsam | 0:8bffb51cc345 | 167 | pc.printf("\n\r Y=%f", Y); |
AurelienBernier | 15:44ab4626f1ad | 168 | pc.printf("\n\r leftMm=%f", leftMm); |
AurelienBernier | 15:44ab4626f1ad | 169 | pc.printf("\n\r frontMm=%f", frontMm); |
AurelienBernier | 15:44ab4626f1ad | 170 | pc.printf("\n\r rightMm=%f", rightMm); |
geotsam | 0:8bffb51cc345 | 171 | |
AurelienBernier | 2:ea61e801e81f | 172 | //Updating motor velocities |
AurelienBernier | 1:f0807d5c5a4b | 173 | leftMotor(1,angular_left); |
AurelienBernier | 1:f0807d5c5a4b | 174 | rightMotor(1,angular_right); |
geotsam | 0:8bffb51cc345 | 175 | |
AurelienBernier | 7:c94070f9af78 | 176 | wait(0.2); |
AurelienBernier | 6:afde4b08166b | 177 | //Timer stuff |
AurelienBernier | 6:afde4b08166b | 178 | t.stop(); |
Ludwigfr | 22:ebb37a249b5f | 179 | } while(d2>1 && tooClose==false); |
Ludwigfr | 22:ebb37a249b5f | 180 | } |
Ludwigfr | 22:ebb37a249b5f | 181 | |
Ludwigfr | 22:ebb37a249b5f | 182 | //Updates sonar values |
Ludwigfr | 22:ebb37a249b5f | 183 | void update_sonar_values(){ |
Ludwigfr | 22:ebb37a249b5f | 184 | |
Ludwigfr | 22:ebb37a249b5f | 185 | float leftMm = get_distance_left_sensor(); |
Ludwigfr | 22:ebb37a249b5f | 186 | float frontMm = get_distance_front_sensor(); |
Ludwigfr | 22:ebb37a249b5f | 187 | float rightMm = get_distance_right_sensor(); |
Ludwigfr | 22:ebb37a249b5f | 188 | |
Ludwigfr | 22:ebb37a249b5f | 189 | float currProba; |
Ludwigfr | 22:ebb37a249b5f | 190 | for(int i=0;i<SIZE_MAP;i++){ |
Ludwigfr | 22:ebb37a249b5f | 191 | for(int j=0;j<SIZE_MAP;j++){ |
Ludwigfr | 22:ebb37a249b5f | 192 | //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) |
Ludwigfr | 22:ebb37a249b5f | 193 | |
Ludwigfr | 22:ebb37a249b5f | 194 | //compute for front sonar |
Ludwigfr | 22:ebb37a249b5f | 195 | currProba=compute_probability_t(sizeCell/2+i*sizeCell,sizeCell/2+j*sizeCell,SIZE_MAP*sizeCell-X+DEFAULT_X+DISTANCE_SONAR_FRONT_X,Y+DEFAULT_Y+DISTANCE_SONAR_FRONT_Y,ANGLE_FRONT_TO_FRONT,frontMm/10); |
Ludwigfr | 22:ebb37a249b5f | 196 | 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 |
Ludwigfr | 22:ebb37a249b5f | 197 | //compute for right sonar |
Ludwigfr | 22:ebb37a249b5f | 198 | currProba=compute_probability_t(sizeCell/2+i*sizeCell,sizeCell/2+j*sizeCell,SIZE_MAP*sizeCell-X+DEFAULT_X+DISTANCE_SONAR_RIGHT_X,Y+DEFAULT_Y+DISTANCE_SONAR_RIGHT_Y,ANGLE_FRONT_TO_RIGHT,rightMm/10); |
Ludwigfr | 22:ebb37a249b5f | 199 | map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j]; |
Ludwigfr | 22:ebb37a249b5f | 200 | //compute for left sonar |
Ludwigfr | 22:ebb37a249b5f | 201 | currProba=compute_probability_t(sizeCell/2+i*sizeCell,sizeCell/2+j*sizeCell,SIZE_MAP*sizeCell-X+DEFAULT_X+DISTANCE_SONAR_LEFT_X,Y+DEFAULT_Y+DISTANCE_SONAR_LEFT_Y,ANGLE_FRONT_TO_LEFT,leftMm/10); |
Ludwigfr | 22:ebb37a249b5f | 202 | map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j]; |
Ludwigfr | 22:ebb37a249b5f | 203 | } |
Ludwigfr | 22:ebb37a249b5f | 204 | } |
Ludwigfr | 22:ebb37a249b5f | 205 | } |
Ludwigfr | 22:ebb37a249b5f | 206 | |
Ludwigfr | 22:ebb37a249b5f | 207 | //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] |
Ludwigfr | 22:ebb37a249b5f | 208 | float compute_probability_t(float x, float y,float xs,float ys, float angleFromSonarPosition, float distanceObstacleDetected){ |
Ludwigfr | 22:ebb37a249b5f | 209 | |
Ludwigfr | 22:ebb37a249b5f | 210 | float alpha=compute_angle_between_vectors(x,y,xs,ys);//angle beetween the point and the sonar beam |
Ludwigfr | 22:ebb37a249b5f | 211 | float alphaBeforeAdjustment=alpha-theta-DEFAULT_THETA-angleFromSonarPosition; |
Ludwigfr | 22:ebb37a249b5f | 212 | alpha=rad_angle_check(alphaBeforeAdjustment);//TODO I feel you don't need to do that but I m not sure |
Ludwigfr | 22:ebb37a249b5f | 213 | float distancePointToSonar=sqrt(pow(x-xs,2)+pow(y-ys,2)); |
Ludwigfr | 22:ebb37a249b5f | 214 | |
Ludwigfr | 22:ebb37a249b5f | 215 | //check if the distance between the cell and the robot is within the circle of range RADIUS_WHEELS |
Ludwigfr | 22:ebb37a249b5f | 216 | //check if absolute difference between the angles is no more than Omega/2 |
Ludwigfr | 22:ebb37a249b5f | 217 | if( distancePointToSonar < (RANGE_SONAR)&& (alpha <= ANGLE_SONAR/2 || alpha >= rad_angle_check(-ANGLE_SONAR/2))){ |
Ludwigfr | 22:ebb37a249b5f | 218 | if( distancePointToSonar < (distanceObstacleDetected - INCERTITUDE_SONAR)){ |
Ludwigfr | 22:ebb37a249b5f | 219 | //point before obstacle, probably empty |
Ludwigfr | 22:ebb37a249b5f | 220 | /*****************************************************************************/ |
Ludwigfr | 22:ebb37a249b5f | 221 | float Ea=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2); |
Ludwigfr | 22:ebb37a249b5f | 222 | float Er; |
Ludwigfr | 22:ebb37a249b5f | 223 | if(distancePointToSonar < RANGE_SONAR_MIN){ |
Ludwigfr | 22:ebb37a249b5f | 224 | //point before minimum sonar range |
Ludwigfr | 22:ebb37a249b5f | 225 | Er=0.f; |
Ludwigfr | 22:ebb37a249b5f | 226 | }else{ |
Ludwigfr | 22:ebb37a249b5f | 227 | //point after minimum sonar range |
Ludwigfr | 22:ebb37a249b5f | 228 | Er=1.f-pow((distancePointToSonar-RANGE_SONAR_MIN)/(distanceObstacleDetected-INCERTITUDE_SONAR-RANGE_SONAR_MIN),2); |
Ludwigfr | 22:ebb37a249b5f | 229 | } |
Ludwigfr | 22:ebb37a249b5f | 230 | /*****************************************************************************/ |
Ludwigfr | 22:ebb37a249b5f | 231 | return (1.f-Er*Ea)/2.f; |
Ludwigfr | 22:ebb37a249b5f | 232 | }else{ |
Ludwigfr | 22:ebb37a249b5f | 233 | //probably occupied |
Ludwigfr | 22:ebb37a249b5f | 234 | /*****************************************************************************/ |
Ludwigfr | 22:ebb37a249b5f | 235 | float Oa=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2); |
Ludwigfr | 22:ebb37a249b5f | 236 | float Or; |
Ludwigfr | 22:ebb37a249b5f | 237 | if( distancePointToSonar <= (distanceObstacleDetected + INCERTITUDE_SONAR)){ |
Ludwigfr | 22:ebb37a249b5f | 238 | //point between distanceObstacleDetected +- INCERTITUDE_SONAR |
Ludwigfr | 22:ebb37a249b5f | 239 | Or=1-pow((distancePointToSonar-distanceObstacleDetected)/(INCERTITUDE_SONAR),2); |
Ludwigfr | 22:ebb37a249b5f | 240 | }else{ |
Ludwigfr | 22:ebb37a249b5f | 241 | //point after in range of the sonar but after the zone detected |
Ludwigfr | 22:ebb37a249b5f | 242 | Or=0; |
Ludwigfr | 22:ebb37a249b5f | 243 | } |
Ludwigfr | 22:ebb37a249b5f | 244 | /*****************************************************************************/ |
Ludwigfr | 22:ebb37a249b5f | 245 | return (1+Or*Oa)/2; |
Ludwigfr | 22:ebb37a249b5f | 246 | } |
Ludwigfr | 22:ebb37a249b5f | 247 | }else{ |
Ludwigfr | 22:ebb37a249b5f | 248 | //not in range of the sonar |
Ludwigfr | 22:ebb37a249b5f | 249 | return 0.5; |
AurelienBernier | 19:dbc5fbad4975 | 250 | } |
Ludwigfr | 22:ebb37a249b5f | 251 | } |
Ludwigfr | 22:ebb37a249b5f | 252 | |
Ludwigfr | 22:ebb37a249b5f | 253 | void print_final_map() { |
Ludwigfr | 22:ebb37a249b5f | 254 | float currProba; |
Ludwigfr | 22:ebb37a249b5f | 255 | for (int x = 0; x<SIZE_MAP; x++) { |
Ludwigfr | 22:ebb37a249b5f | 256 | for (int y = 0; y<SIZE_MAP; y++) { |
Ludwigfr | 22:ebb37a249b5f | 257 | currProba=log_to_proba(map[SIZE_MAP-1-x][y]); |
Ludwigfr | 22:ebb37a249b5f | 258 | if ( currProba < 0.5) {//by default [0][0] would be top left, we want it bottom left |
Ludwigfr | 22:ebb37a249b5f | 259 | pc.printf("0"); |
Ludwigfr | 22:ebb37a249b5f | 260 | } else { |
Ludwigfr | 22:ebb37a249b5f | 261 | if(currProba==0.5) |
Ludwigfr | 22:ebb37a249b5f | 262 | pc.printf("."); |
Ludwigfr | 22:ebb37a249b5f | 263 | else |
Ludwigfr | 22:ebb37a249b5f | 264 | pc.printf("+"); |
Ludwigfr | 22:ebb37a249b5f | 265 | } |
Ludwigfr | 22:ebb37a249b5f | 266 | } |
Ludwigfr | 22:ebb37a249b5f | 267 | } |
Ludwigfr | 22:ebb37a249b5f | 268 | } |
Ludwigfr | 22:ebb37a249b5f | 269 | |
Ludwigfr | 22:ebb37a249b5f | 270 | |
Ludwigfr | 22:ebb37a249b5f | 271 | |
Ludwigfr | 22:ebb37a249b5f | 272 | |
Ludwigfr | 22:ebb37a249b5f | 273 | //MATHS heavy functions |
Ludwigfr | 22:ebb37a249b5f | 274 | /**********************************************************************/ |
Ludwigfr | 22:ebb37a249b5f | 275 | //Distance computation function |
Ludwigfr | 22:ebb37a249b5f | 276 | float dist(float robot_x, float robot_y, float target_x, float target_y){ |
Ludwigfr | 22:ebb37a249b5f | 277 | return sqrt(pow(target_y-robot_y,2) + pow(target_x-robot_x,2)); |
Ludwigfr | 22:ebb37a249b5f | 278 | } |
Ludwigfr | 22:ebb37a249b5f | 279 | |
Ludwigfr | 22:ebb37a249b5f | 280 | //returns the probability [0,1] that the cell is occupied from the log value lt |
Ludwigfr | 22:ebb37a249b5f | 281 | float log_to_proba(float lt){ |
Ludwigfr | 22:ebb37a249b5f | 282 | return 1-1/(1+exp(lt)); |
Ludwigfr | 22:ebb37a249b5f | 283 | } |
Ludwigfr | 22:ebb37a249b5f | 284 | |
Ludwigfr | 22:ebb37a249b5f | 285 | //returns the log value that the cell is occupied from the probability value [0,1] |
Ludwigfr | 22:ebb37a249b5f | 286 | float proba_to_log(float p){ |
Ludwigfr | 22:ebb37a249b5f | 287 | return log(p/(1-p)); |
Ludwigfr | 22:ebb37a249b5f | 288 | } |
Ludwigfr | 22:ebb37a249b5f | 289 | |
Ludwigfr | 22:ebb37a249b5f | 290 | //returns the new log value |
Ludwigfr | 22:ebb37a249b5f | 291 | float compute_log_estimation_lt(float previousLogValue,float currentProbability,float originalLogvalue ){ |
Ludwigfr | 22:ebb37a249b5f | 292 | return previousLogValue+proba_to_log(currentProbability)-originalLogvalue; |
Ludwigfr | 22:ebb37a249b5f | 293 | } |
Ludwigfr | 22:ebb37a249b5f | 294 | |
Ludwigfr | 22:ebb37a249b5f | 295 | //makes the angle inAngle between 0 and 2pi |
Ludwigfr | 22:ebb37a249b5f | 296 | float rad_angle_check(float inAngle){ |
Ludwigfr | 22:ebb37a249b5f | 297 | //cout<<"before :"<<inAngle; |
Ludwigfr | 22:ebb37a249b5f | 298 | if(inAngle > 0){ |
Ludwigfr | 22:ebb37a249b5f | 299 | while(inAngle > (2*pi)) |
Ludwigfr | 22:ebb37a249b5f | 300 | inAngle-=2*pi; |
Ludwigfr | 22:ebb37a249b5f | 301 | }else{ |
Ludwigfr | 22:ebb37a249b5f | 302 | while(inAngle < 0) |
Ludwigfr | 22:ebb37a249b5f | 303 | inAngle+=2*pi; |
Ludwigfr | 22:ebb37a249b5f | 304 | } |
Ludwigfr | 22:ebb37a249b5f | 305 | //cout<<" after :"<<inAngle<<endl; |
Ludwigfr | 22:ebb37a249b5f | 306 | return inAngle; |
Ludwigfr | 22:ebb37a249b5f | 307 | } |
Ludwigfr | 22:ebb37a249b5f | 308 | |
Ludwigfr | 22:ebb37a249b5f | 309 | //returns the angle between the vectors (x,y) and (xs,ys) |
Ludwigfr | 22:ebb37a249b5f | 310 | float compute_angle_between_vectors(float x, float y,float xs,float ys){ |
Ludwigfr | 22:ebb37a249b5f | 311 | //alpha angle between ->x and ->SA |
Ludwigfr | 22:ebb37a249b5f | 312 | //vector S to A ->SA |
Ludwigfr | 22:ebb37a249b5f | 313 | float vSAx=x-xs; |
Ludwigfr | 22:ebb37a249b5f | 314 | float vSAy=y-ys; |
Ludwigfr | 22:ebb37a249b5f | 315 | //norme SA |
Ludwigfr | 22:ebb37a249b5f | 316 | float normeSA=sqrt(pow(vSAx,2)+pow(vSAy,2)); |
Ludwigfr | 22:ebb37a249b5f | 317 | //vector ->x (1,0) |
Ludwigfr | 22:ebb37a249b5f | 318 | float cosAlpha=1*vSAy/*+0*vSAx*//normeSA;; |
Ludwigfr | 22:ebb37a249b5f | 319 | //vector ->y (0,1) |
Ludwigfr | 22:ebb37a249b5f | 320 | float sinAlpha=/*0*vSAy+*/1*vSAx/normeSA;//+0*vSAx; |
Ludwigfr | 22:ebb37a249b5f | 321 | if (sinAlpha < 0) |
Ludwigfr | 22:ebb37a249b5f | 322 | return -acos(cosAlpha); |
Ludwigfr | 22:ebb37a249b5f | 323 | else |
Ludwigfr | 22:ebb37a249b5f | 324 | return acos(cosAlpha); |
Ludwigfr | 22:ebb37a249b5f | 325 | } |
Ludwigfr | 22:ebb37a249b5f | 326 | |
geotsam | 23:901fc468b8a7 | 327 | void compute_angles_and_distance(float target_x, float target_y, float target_angle){ |
geotsam | 23:901fc468b8a7 | 328 | alpha = atan2((target_y-Y),(target_x-X))-theta; |
geotsam | 23:901fc468b8a7 | 329 | alpha = atan(sin(alpha)/cos(alpha)); |
geotsam | 23:901fc468b8a7 | 330 | rho = dist(X, Y, target_x, target_y); |
geotsam | 23:901fc468b8a7 | 331 | d2 = rho; |
geotsam | 23:901fc468b8a7 | 332 | beta = -alpha-theta+target_angle; |
geotsam | 23:901fc468b8a7 | 333 | |
geotsam | 23:901fc468b8a7 | 334 | //Computing angle error and distance towards the target value |
geotsam | 23:901fc468b8a7 | 335 | rho += dt*(-kRho*cos(alpha)*rho); |
geotsam | 23:901fc468b8a7 | 336 | temp = alpha; |
geotsam | 23:901fc468b8a7 | 337 | alpha += dt*(kRho*sin(alpha)-ka*alpha-kb*beta); |
geotsam | 23:901fc468b8a7 | 338 | beta += dt*(-kRho*sin(temp)); |
geotsam | 23:901fc468b8a7 | 339 | pc.printf("\n\r d2=%f", d2); |
geotsam | 23:901fc468b8a7 | 340 | pc.printf("\n\r dt=%f", dt); |
geotsam | 23:901fc468b8a7 | 341 | } |
geotsam | 23:901fc468b8a7 | 342 | |
geotsam | 23:901fc468b8a7 | 343 | void compute_linear_angular_velocities(){ |
geotsam | 23:901fc468b8a7 | 344 | //Computing linear and angular velocities |
geotsam | 23:901fc468b8a7 | 345 | if(alpha>=-1.5708 && alpha<=1.5708){ |
geotsam | 23:901fc468b8a7 | 346 | linear=kRho*rho; |
geotsam | 23:901fc468b8a7 | 347 | angular=ka*alpha+kb*beta; |
geotsam | 23:901fc468b8a7 | 348 | } |
geotsam | 23:901fc468b8a7 | 349 | else{ |
geotsam | 23:901fc468b8a7 | 350 | linear=-kRho*rho; |
geotsam | 23:901fc468b8a7 | 351 | angular=-ka*alpha-kb*beta; |
geotsam | 23:901fc468b8a7 | 352 | } |
geotsam | 23:901fc468b8a7 | 353 | angular_left=(linear-0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
geotsam | 23:901fc468b8a7 | 354 | angular_right=(linear+0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
geotsam | 23:901fc468b8a7 | 355 | |
geotsam | 23:901fc468b8a7 | 356 | //Slowing down at the end for more precision |
geotsam | 23:901fc468b8a7 | 357 | if (d2<25) { |
geotsam | 23:901fc468b8a7 | 358 | speed = d2*30; |
geotsam | 23:901fc468b8a7 | 359 | } |
geotsam | 23:901fc468b8a7 | 360 | |
geotsam | 23:901fc468b8a7 | 361 | //Normalize speed for motors |
geotsam | 23:901fc468b8a7 | 362 | if(angular_left>angular_right) { |
geotsam | 23:901fc468b8a7 | 363 | angular_right=speed*angular_right/angular_left; |
geotsam | 23:901fc468b8a7 | 364 | angular_left=speed; |
geotsam | 23:901fc468b8a7 | 365 | } else { |
geotsam | 23:901fc468b8a7 | 366 | angular_left=speed*angular_left/angular_right; |
geotsam | 23:901fc468b8a7 | 367 | angular_right=speed; |
geotsam | 23:901fc468b8a7 | 368 | } |
geotsam | 23:901fc468b8a7 | 369 | } |