All the lab works are here!
Dependencies: ISR_Mini-explorer mbed
Fork of VirtualForces by
main.cpp@52:54b3fe68a4f2, 2017-06-08 (annotated)
- Committer:
- geotsam
- Date:
- Thu Jun 08 16:13:59 2017 +0000
- Revision:
- 52:54b3fe68a4f2
- Parent:
- 51:b863fad80574
One File to rule them all, One File to find them,; One File to bring them all and in the darkness bind them.; ; This monster has everything inside, and more or less they all work.
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 | |
geotsam | 34:128fc7aed957 | 5 | using namespace std; |
AurelienBernier | 4:8c56c3ba6e54 | 6 | |
Ludwigfr | 51:b863fad80574 | 7 | //update angularLeft and angularRight |
Ludwigfr | 51:b863fad80574 | 8 | float get_error_angles(float x, float y,float theta); |
Ludwigfr | 51:b863fad80574 | 9 | void test_procedure_Lab_2(); |
Ludwigfr | 51:b863fad80574 | 10 | void procedure_Lab_3(); |
Ludwigfr | 51:b863fad80574 | 11 | void procedure_Lab_2(); |
Ludwigfr | 51:b863fad80574 | 12 | void turn_to_target(float angleToTarget); |
Ludwigfr | 39:dd8326ec75ce | 13 | void initialise_parameters(); |
Ludwigfr | 22:ebb37a249b5f | 14 | //fill initialLogValues with the values we already know (here the bordurs) |
Ludwigfr | 22:ebb37a249b5f | 15 | void fill_initial_log_values(); |
Ludwigfr | 22:ebb37a249b5f | 16 | //generate a position randomly and makes the robot go there while updating the map |
Ludwigfr | 22:ebb37a249b5f | 17 | void randomize_and_map(); |
geotsam | 29:224e9e686f7b | 18 | //make the robot do a pi/2 flip |
geotsam | 29:224e9e686f7b | 19 | void do_half_flip(); |
Ludwigfr | 22:ebb37a249b5f | 20 | //go the the given position while updating the map |
Ludwigfr | 22:ebb37a249b5f | 21 | void go_to_point_with_angle(float target_x, float target_y, float target_angle); |
Ludwigfr | 51:b863fad80574 | 22 | void compute_angles_and_distance(float target_x, float target_y, float target_angle); |
Ludwigfr | 51:b863fad80574 | 23 | void compute_linear_angular_velocities(); |
Ludwigfr | 43:ffd5a6d4dd48 | 24 | //Updates sonar values |
geotsam | 24:8f4b820d8de8 | 25 | void update_sonar_values(float leftMm, float frontMm, float rightMm); |
Ludwigfr | 22:ebb37a249b5f | 26 | //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 | 27 | float compute_probability_t(float x, float y,float xs,float ys, float angleFromSonarPosition, float distanceObstacleDetected); |
Ludwigfr | 22:ebb37a249b5f | 28 | //print the map |
Ludwigfr | 22:ebb37a249b5f | 29 | void print_final_map(); |
Ludwigfr | 25:572c9e9a8809 | 30 | //print the map with the robot marked on it |
Ludwigfr | 25:572c9e9a8809 | 31 | void print_final_map_with_robot_position(); |
Ludwigfr | 39:dd8326ec75ce | 32 | //print the map with the robot and the target marked on it |
Ludwigfr | 39:dd8326ec75ce | 33 | void print_final_map_with_robot_position_and_target(); |
Ludwigfr | 42:ab25bffdc32b | 34 | //go to a given line by updating angularLeft and angularRight |
Ludwigfr | 42:ab25bffdc32b | 35 | void go_to_line(float* angularLeft,float* angularRight,float line_a, float line_b, float line_c); |
geotsam | 33:78139f82ea74 | 36 | //calculate virtual force field and move |
Ludwigfr | 42:ab25bffdc32b | 37 | void vff(bool* reached); |
Ludwigfr | 43:ffd5a6d4dd48 | 38 | void test_got_to_line(bool* reached); |
geotsam | 52:54b3fe68a4f2 | 39 | //Go to a given X,Y position, regardless of the final angle |
geotsam | 52:54b3fe68a4f2 | 40 | void go_to_point(float target_x, float target_y); |
geotsam | 52:54b3fe68a4f2 | 41 | //go to line and follow it, from lab 1 |
geotsam | 52:54b3fe68a4f2 | 42 | void go_to_line_lab_1(float line_a, float line_b, float line_c); |
geotsam | 0:8bffb51cc345 | 43 | |
Ludwigfr | 22:ebb37a249b5f | 44 | //MATHS heavy functions |
Ludwigfr | 22:ebb37a249b5f | 45 | float dist(float robot_x, float robot_y, float target_x, float target_y); |
geotsam | 52:54b3fe68a4f2 | 46 | float distFromLine(float robot_x, float robot_y, float line_a, float line_b, float line_c); |
Ludwigfr | 22:ebb37a249b5f | 47 | //returns the probability [0,1] that the cell is occupied from the log value lt |
Ludwigfr | 22:ebb37a249b5f | 48 | float log_to_proba(float lt); |
Ludwigfr | 22:ebb37a249b5f | 49 | //returns the log value that the cell is occupied from the probability value [0,1] |
Ludwigfr | 22:ebb37a249b5f | 50 | float proba_to_log(float p); |
Ludwigfr | 22:ebb37a249b5f | 51 | //returns the new log value |
Ludwigfr | 22:ebb37a249b5f | 52 | float compute_log_estimation_lt(float previousLogValue,float currentProbability,float originalLogvalue ); |
Ludwigfr | 22:ebb37a249b5f | 53 | //makes the angle inAngle between 0 and 2pi |
Ludwigfr | 22:ebb37a249b5f | 54 | float rad_angle_check(float inAngle); |
Ludwigfr | 22:ebb37a249b5f | 55 | //returns the angle between the vectors (x,y) and (xs,ys) |
Ludwigfr | 22:ebb37a249b5f | 56 | float compute_angle_between_vectors(float x, float y,float xs,float ys); |
Ludwigfr | 39:dd8326ec75ce | 57 | float x_robot_in_orthonormal_x(float x, float y); |
Ludwigfr | 39:dd8326ec75ce | 58 | float y_robot_in_orthonormal_y(float x, float y); |
Ludwigfr | 25:572c9e9a8809 | 59 | float robot_center_x_in_orthonormal_x(); |
Ludwigfr | 25:572c9e9a8809 | 60 | float robot_center_y_in_orthonormal_y(); |
Ludwigfr | 25:572c9e9a8809 | 61 | float robot_sonar_front_x_in_orthonormal_x(); |
Ludwigfr | 25:572c9e9a8809 | 62 | float robot_sonar_front_y_in_orthonormal_y(); |
Ludwigfr | 25:572c9e9a8809 | 63 | float robot_sonar_right_x_in_orthonormal_x(); |
Ludwigfr | 25:572c9e9a8809 | 64 | float robot_sonar_right_y_in_orthonormal_y(); |
Ludwigfr | 25:572c9e9a8809 | 65 | float robot_sonar_left_x_in_orthonormal_x(); |
Ludwigfr | 25:572c9e9a8809 | 66 | float robot_sonar_left_y_in_orthonormal_y(); |
Ludwigfr | 25:572c9e9a8809 | 67 | float estimated_width_indice_in_orthonormal_x(int i); |
Ludwigfr | 25:572c9e9a8809 | 68 | float estimated_height_indice_in_orthonormal_y(int j); |
Ludwigfr | 32:d51928b58645 | 69 | //update foceX and forceY if necessary |
Ludwigfr | 43:ffd5a6d4dd48 | 70 | void update_force(int widthIndice, int heightIndice, float range, float* forceX, float* forceY, float xRobotOrtho, float yRobotOrtho ); |
Ludwigfr | 32:d51928b58645 | 71 | //compute the X and Y force |
Ludwigfr | 39:dd8326ec75ce | 72 | void compute_forceX_and_forceY(float* forceX, float* forceY); |
Ludwigfr | 42:ab25bffdc32b | 73 | //robotX and robotY are from Odometria, calculate line_a, line_b and line_c |
Ludwigfr | 42:ab25bffdc32b | 74 | void calculate_line(float forceX, float forceY, float robotX, float robotY,float *line_a, float *line_b, float *line_c); |
Ludwigfr | 43:ffd5a6d4dd48 | 75 | //return 1 if positiv, -1 if negativ |
Ludwigfr | 43:ffd5a6d4dd48 | 76 | float sign1(float value); |
Ludwigfr | 43:ffd5a6d4dd48 | 77 | //return 1 if positiv, 0 if negativ |
Ludwigfr | 43:ffd5a6d4dd48 | 78 | int sign2(float value); |
Ludwigfr | 45:fb07065a64a9 | 79 | //set target in ortho space, in reference to the robot (so if the robot is in the middle, you want to him to go 10cm down and 15 right, set_target_to(15,-10) |
Ludwigfr | 43:ffd5a6d4dd48 | 80 | void set_target_to(float x, float y); |
Ludwigfr | 44:e2bd06f94dc0 | 81 | void try_to_reach_target(); |
Ludwigfr | 51:b863fad80574 | 82 | void test_map_sonar(); |
AurelienBernier | 8:109314be5b68 | 83 | |
Ludwigfr | 50:a970cf7889d3 | 84 | //those target are in comparaison to the robot (for exemple a robot in 50,50 with a taget of 0,0 would not need to move) |
Ludwigfr | 50:a970cf7889d3 | 85 | float targetX;//this is in the robot space top left |
Ludwigfr | 50:a970cf7889d3 | 86 | float targetY;//this is in the robot space top left |
Ludwigfr | 50:a970cf7889d3 | 87 | //Ortho but for the map (i.e x and Y are > 0) |
Ludwigfr | 50:a970cf7889d3 | 88 | float targetXOrhto; |
Ludwigfr | 50:a970cf7889d3 | 89 | float targetYOrhto; |
Ludwigfr | 50:a970cf7889d3 | 90 | float targetXOrhtoNotMap; |
Ludwigfr | 50:a970cf7889d3 | 91 | float targetYOrhtoNotMap; |
Ludwigfr | 50:a970cf7889d3 | 92 | |
Ludwigfr | 22:ebb37a249b5f | 93 | const float pi=3.14159; |
Ludwigfr | 32:d51928b58645 | 94 | |
Ludwigfr | 22:ebb37a249b5f | 95 | //spec of the sonar |
Ludwigfr | 44:e2bd06f94dc0 | 96 | //TODO MEASURE THE DISTANCE on X and Y of the robot space, between each sonar and the center of the robot and add it to calculus in updateSonarValues |
geotsam | 24:8f4b820d8de8 | 97 | const float RANGE_SONAR=50;//cm |
geotsam | 24:8f4b820d8de8 | 98 | const float RANGE_SONAR_MIN=10;//Rmin cm |
geotsam | 24:8f4b820d8de8 | 99 | const float INCERTITUDE_SONAR=10;//cm |
geotsam | 24:8f4b820d8de8 | 100 | const float ANGLE_SONAR=pi/3;//Omega rad |
Ludwigfr | 22:ebb37a249b5f | 101 | |
Ludwigfr | 44:e2bd06f94dc0 | 102 | //those distance and angle are approximation in need of measurements, in the orthonormal space |
geotsam | 24:8f4b820d8de8 | 103 | const float ANGLE_FRONT_TO_LEFT=10*pi/36;//50 degrees |
Ludwigfr | 27:07bde633af72 | 104 | const float DISTANCE_SONAR_LEFT_X=-4; |
geotsam | 24:8f4b820d8de8 | 105 | const float DISTANCE_SONAR_LEFT_Y=4; |
Ludwigfr | 22:ebb37a249b5f | 106 | |
geotsam | 24:8f4b820d8de8 | 107 | const float ANGLE_FRONT_TO_RIGHT=-10*pi/36;//-50 degrees |
Ludwigfr | 27:07bde633af72 | 108 | const float DISTANCE_SONAR_RIGHT_X=4; |
geotsam | 24:8f4b820d8de8 | 109 | const float DISTANCE_SONAR_RIGHT_Y=4; |
AurelienBernier | 11:e641aa08c92e | 110 | |
Ludwigfr | 22:ebb37a249b5f | 111 | const float ANGLE_FRONT_TO_FRONT=0; |
Ludwigfr | 22:ebb37a249b5f | 112 | const float DISTANCE_SONAR_FRONT_X=0; |
Ludwigfr | 22:ebb37a249b5f | 113 | const float DISTANCE_SONAR_FRONT_Y=5; |
Ludwigfr | 22:ebb37a249b5f | 114 | |
Ludwigfr | 22:ebb37a249b5f | 115 | //TODO adjust the size of the map for computation time (25*25?) |
Ludwigfr | 51:b863fad80574 | 116 | const float WIDTH_ARENA=200;//cm |
Ludwigfr | 51:b863fad80574 | 117 | const float HEIGHT_ARENA=200;//cm |
geotsam | 24:8f4b820d8de8 | 118 | |
geotsam | 24:8f4b820d8de8 | 119 | //const int SIZE_MAP=25; |
Ludwigfr | 51:b863fad80574 | 120 | const int NB_CELL_WIDTH=20; |
Ludwigfr | 51:b863fad80574 | 121 | const int NB_CELL_HEIGHT=20; |
Ludwigfr | 22:ebb37a249b5f | 122 | |
geotsam | 24:8f4b820d8de8 | 123 | //used to create the map 250 represent the 250cm of the square where the robot is tested |
geotsam | 24:8f4b820d8de8 | 124 | //float sizeCell=250/(float)SIZE_MAP; |
Ludwigfr | 27:07bde633af72 | 125 | float sizeCellWidth=WIDTH_ARENA/(float)NB_CELL_WIDTH; |
Ludwigfr | 27:07bde633af72 | 126 | float sizeCellHeight=HEIGHT_ARENA/(float)NB_CELL_HEIGHT; |
geotsam | 24:8f4b820d8de8 | 127 | |
geotsam | 24:8f4b820d8de8 | 128 | float map[NB_CELL_WIDTH][NB_CELL_HEIGHT];//contains the log values for each cell |
geotsam | 24:8f4b820d8de8 | 129 | float initialLogValues[NB_CELL_WIDTH][NB_CELL_HEIGHT]; |
Ludwigfr | 22:ebb37a249b5f | 130 | |
Ludwigfr | 22:ebb37a249b5f | 131 | //Diameter of a wheel and distance between the 2 |
Ludwigfr | 22:ebb37a249b5f | 132 | const float RADIUS_WHEELS=3.25; |
Ludwigfr | 22:ebb37a249b5f | 133 | const float DISTANCE_WHEELS=7.2; |
Ludwigfr | 22:ebb37a249b5f | 134 | |
Ludwigfr | 47:f0fe58571e4a | 135 | //position and orientation of the robot when put on the map (ODOMETRY doesn't know those) it's in the robot space |
Ludwigfr | 47:f0fe58571e4a | 136 | //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 |
Ludwigfr | 51:b863fad80574 | 137 | const float DEFAULT_X=20; |
Ludwigfr | 47:f0fe58571e4a | 138 | const float DEFAULT_Y=WIDTH_ARENA/2; |
Ludwigfr | 47:f0fe58571e4a | 139 | //const float DEFAULT_X=20;//lower right |
Ludwigfr | 47:f0fe58571e4a | 140 | //const float DEFAULT_Y=20;//lower right |
Ludwigfr | 47:f0fe58571e4a | 141 | const float DEFAULT_THETA=0; |
Ludwigfr | 47:f0fe58571e4a | 142 | |
Ludwigfr | 51:b863fad80574 | 143 | const int MAX_SPEED=50;//TODO TWEAK THE SPEED SO IT DOES NOT FUCK UP |
Ludwigfr | 39:dd8326ec75ce | 144 | |
Ludwigfr | 47:f0fe58571e4a | 145 | const float KRHO=12, KA=30, KB=-13, KV=200, KH=200; //Kappa values |
Ludwigfr | 43:ffd5a6d4dd48 | 146 | |
Ludwigfr | 43:ffd5a6d4dd48 | 147 | //CONSTANT FORCE FIELD |
Ludwigfr | 51:b863fad80574 | 148 | const float FORCE_CONSTANT_REPULSION=10000;//TODO tweak it |
Ludwigfr | 51:b863fad80574 | 149 | const float FORCE_CONSTANT_ATTRACTION=1;//TODO tweak it |
Ludwigfr | 51:b863fad80574 | 150 | const float RANGE_FORCE=30;//TODO tweak it |
Ludwigfr | 51:b863fad80574 | 151 | |
Ludwigfr | 51:b863fad80574 | 152 | float alpha; //angle error |
Ludwigfr | 51:b863fad80574 | 153 | float rho; //distance from target |
Ludwigfr | 51:b863fad80574 | 154 | float beta; |
Ludwigfr | 51:b863fad80574 | 155 | float linear, angular, angular_left, angular_right; |
Ludwigfr | 51:b863fad80574 | 156 | float dt=0.5; |
Ludwigfr | 51:b863fad80574 | 157 | float temp; |
Ludwigfr | 51:b863fad80574 | 158 | float d2; |
Ludwigfr | 51:b863fad80574 | 159 | Timer t; |
geotsam | 33:78139f82ea74 | 160 | |
geotsam | 0:8bffb51cc345 | 161 | int main(){ |
Ludwigfr | 44:e2bd06f94dc0 | 162 | initialise_parameters(); |
geotsam | 52:54b3fe68a4f2 | 163 | procedure_Lab_3(); //uses force fields to reach target with set_terget |
geotsam | 52:54b3fe68a4f2 | 164 | //procedure_Lab_2(); //picks random targets and makes a map (SUCCESS - builds a more or less accurate map without colliding with obstacles) |
geotsam | 52:54b3fe68a4f2 | 165 | |
geotsam | 52:54b3fe68a4f2 | 166 | //theta=0; |
geotsam | 52:54b3fe68a4f2 | 167 | //X=0; |
geotsam | 52:54b3fe68a4f2 | 168 | //Y=0; |
geotsam | 52:54b3fe68a4f2 | 169 | |
geotsam | 52:54b3fe68a4f2 | 170 | //go_to_point(16.8, 78.6); //(x,y) in the global coordinates x cm on the x direction, y cm in the y direction form the 0,0 of the table |
geotsam | 52:54b3fe68a4f2 | 171 | //(SUCCESS - goes to the specified point) |
geotsam | 52:54b3fe68a4f2 | 172 | |
geotsam | 52:54b3fe68a4f2 | 173 | //go_to_line_lab_1(10, -10, 20); //a,b,c of a line: ax+by+c=0, again on the global coordinates of the table (SUCCESS - goes along the line) |
geotsam | 52:54b3fe68a4f2 | 174 | |
geotsam | 52:54b3fe68a4f2 | 175 | //go_to_point_with_angle(46.8, 78.6, 0);//(x,y,theta) in the global coordinates (SUCCESS - goes to the point, the angle is almost right as well) |
geotsam | 52:54b3fe68a4f2 | 176 | |
geotsam | 52:54b3fe68a4f2 | 177 | //test_procedure_Lab_2(); //starts from the middle of the arena, goes to a point with set_terget |
Ludwigfr | 51:b863fad80574 | 178 | } |
Ludwigfr | 51:b863fad80574 | 179 | |
Ludwigfr | 51:b863fad80574 | 180 | void procedure_Lab_3(){ |
Ludwigfr | 51:b863fad80574 | 181 | //try to reach the target is ortho space |
Ludwigfr | 51:b863fad80574 | 182 | set_target_to(0,80);// |
Ludwigfr | 44:e2bd06f94dc0 | 183 | print_final_map_with_robot_position_and_target(); |
Ludwigfr | 44:e2bd06f94dc0 | 184 | try_to_reach_target(); |
Ludwigfr | 47:f0fe58571e4a | 185 | //set_target_to(0,20);//lower right |
Ludwigfr | 47:f0fe58571e4a | 186 | //print_final_map_with_robot_position_and_target(); |
Ludwigfr | 47:f0fe58571e4a | 187 | //try_to_reach_target(); |
Ludwigfr | 47:f0fe58571e4a | 188 | //set_target_to(-20,-20);//up left |
Ludwigfr | 47:f0fe58571e4a | 189 | //print_final_map_with_robot_position_and_target(); |
Ludwigfr | 47:f0fe58571e4a | 190 | //try_to_reach_target(); |
Ludwigfr | 44:e2bd06f94dc0 | 191 | //print the map forever |
Ludwigfr | 44:e2bd06f94dc0 | 192 | while(1){ |
Ludwigfr | 44:e2bd06f94dc0 | 193 | print_final_map_with_robot_position_and_target(); |
Ludwigfr | 44:e2bd06f94dc0 | 194 | } |
Ludwigfr | 44:e2bd06f94dc0 | 195 | } |
Ludwigfr | 44:e2bd06f94dc0 | 196 | |
Ludwigfr | 51:b863fad80574 | 197 | void test_map_sonar(){ |
Ludwigfr | 51:b863fad80574 | 198 | float leftMm; |
Ludwigfr | 51:b863fad80574 | 199 | float frontMm; |
Ludwigfr | 51:b863fad80574 | 200 | float rightMm; |
Ludwigfr | 51:b863fad80574 | 201 | X=20; |
Ludwigfr | 51:b863fad80574 | 202 | Y=WIDTH_ARENA/2; |
Ludwigfr | 51:b863fad80574 | 203 | theta=0; |
Ludwigfr | 51:b863fad80574 | 204 | while(1){ |
Ludwigfr | 51:b863fad80574 | 205 | leftMm = get_distance_left_sensor(); |
Ludwigfr | 51:b863fad80574 | 206 | frontMm = get_distance_front_sensor(); |
Ludwigfr | 51:b863fad80574 | 207 | rightMm = get_distance_right_sensor(); |
Ludwigfr | 51:b863fad80574 | 208 | pc.printf("%f, %f, %f",leftMm,frontMm,rightMm); |
Ludwigfr | 51:b863fad80574 | 209 | //update the probabilities values |
Ludwigfr | 51:b863fad80574 | 210 | update_sonar_values(leftMm, frontMm, rightMm); |
Ludwigfr | 51:b863fad80574 | 211 | print_final_map(); |
Ludwigfr | 51:b863fad80574 | 212 | } |
Ludwigfr | 51:b863fad80574 | 213 | } |
Ludwigfr | 51:b863fad80574 | 214 | |
Ludwigfr | 51:b863fad80574 | 215 | void test_procedure_Lab_2(){ |
Ludwigfr | 51:b863fad80574 | 216 | X=HEIGHT_ARENA/2; |
Ludwigfr | 51:b863fad80574 | 217 | Y=WIDTH_ARENA/2; |
Ludwigfr | 51:b863fad80574 | 218 | set_target_to(-100,50); |
Ludwigfr | 51:b863fad80574 | 219 | print_final_map_with_robot_position_and_target(); |
Ludwigfr | 51:b863fad80574 | 220 | go_to_point_with_angle(targetX, targetY, pi/2); |
Ludwigfr | 51:b863fad80574 | 221 | print_final_map_with_robot_position_and_target(); |
Ludwigfr | 51:b863fad80574 | 222 | |
Ludwigfr | 51:b863fad80574 | 223 | } |
Ludwigfr | 51:b863fad80574 | 224 | void procedure_Lab_2(){ |
geotsam | 52:54b3fe68a4f2 | 225 | for(int i=0;i<15;i++){ |
Ludwigfr | 51:b863fad80574 | 226 | randomize_and_map(); |
Ludwigfr | 51:b863fad80574 | 227 | print_final_map_with_robot_position(); |
Ludwigfr | 51:b863fad80574 | 228 | wait(2); |
Ludwigfr | 51:b863fad80574 | 229 | } |
geotsam | 52:54b3fe68a4f2 | 230 | while(1){ |
geotsam | 52:54b3fe68a4f2 | 231 | print_final_map_with_robot_position(); |
geotsam | 52:54b3fe68a4f2 | 232 | wait(10); |
geotsam | 52:54b3fe68a4f2 | 233 | } |
Ludwigfr | 51:b863fad80574 | 234 | } |
Ludwigfr | 51:b863fad80574 | 235 | |
Ludwigfr | 51:b863fad80574 | 236 | |
Ludwigfr | 44:e2bd06f94dc0 | 237 | void try_to_reach_target(){ |
Ludwigfr | 51:b863fad80574 | 238 | //atan2 gives the angle beetween pi and -pi |
Ludwigfr | 51:b863fad80574 | 239 | float angleToTarget=atan2(targetYOrhtoNotMap,targetXOrhtoNotMap); |
Ludwigfr | 51:b863fad80574 | 240 | turn_to_target(angleToTarget); |
Ludwigfr | 44:e2bd06f94dc0 | 241 | bool reached=false; |
Ludwigfr | 44:e2bd06f94dc0 | 242 | int print=0; |
Ludwigfr | 39:dd8326ec75ce | 243 | while (!reached) { |
Ludwigfr | 43:ffd5a6d4dd48 | 244 | vff(&reached); |
Ludwigfr | 43:ffd5a6d4dd48 | 245 | //test_got_to_line(&reached); |
Ludwigfr | 51:b863fad80574 | 246 | if(print==10){ |
Ludwigfr | 44:e2bd06f94dc0 | 247 | leftMotor(1,0); |
Ludwigfr | 44:e2bd06f94dc0 | 248 | rightMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 249 | /* |
Ludwigfr | 44:e2bd06f94dc0 | 250 | pc.printf("\r\n theta=%f", theta); |
Ludwigfr | 44:e2bd06f94dc0 | 251 | pc.printf("\r\n IN ORTHO:"); |
Ludwigfr | 44:e2bd06f94dc0 | 252 | pc.printf("\r\n X Robot=%f", robot_center_x_in_orthonormal_x()); |
Ludwigfr | 44:e2bd06f94dc0 | 253 | pc.printf("\r\n Y Robot=%f", robot_center_y_in_orthonormal_y()); |
Ludwigfr | 44:e2bd06f94dc0 | 254 | pc.printf("\r\n X Target=%f", targetXOrhto); |
Ludwigfr | 44:e2bd06f94dc0 | 255 | pc.printf("\r\n Y Target=%f", targetYOrhto); |
Ludwigfr | 51:b863fad80574 | 256 | */ |
Ludwigfr | 44:e2bd06f94dc0 | 257 | print_final_map_with_robot_position_and_target(); |
Ludwigfr | 44:e2bd06f94dc0 | 258 | print=0; |
Ludwigfr | 44:e2bd06f94dc0 | 259 | }else |
Ludwigfr | 44:e2bd06f94dc0 | 260 | print+=1; |
Ludwigfr | 39:dd8326ec75ce | 261 | } |
Ludwigfr | 39:dd8326ec75ce | 262 | //Stop at the end |
Ludwigfr | 39:dd8326ec75ce | 263 | leftMotor(1,0); |
Ludwigfr | 39:dd8326ec75ce | 264 | rightMotor(1,0); |
Ludwigfr | 44:e2bd06f94dc0 | 265 | pc.printf("\r\n target reached"); |
Ludwigfr | 47:f0fe58571e4a | 266 | wait(3);// |
Ludwigfr | 39:dd8326ec75ce | 267 | } |
Ludwigfr | 39:dd8326ec75ce | 268 | |
Ludwigfr | 45:fb07065a64a9 | 269 | //target in ortho space |
Ludwigfr | 43:ffd5a6d4dd48 | 270 | void set_target_to(float x, float y){ |
Ludwigfr | 45:fb07065a64a9 | 271 | targetX=y; |
Ludwigfr | 45:fb07065a64a9 | 272 | targetY=-x; |
Ludwigfr | 43:ffd5a6d4dd48 | 273 | targetXOrhto=x_robot_in_orthonormal_x(targetX,targetY); |
Ludwigfr | 43:ffd5a6d4dd48 | 274 | targetYOrhto=y_robot_in_orthonormal_y(targetX,targetY); |
Ludwigfr | 47:f0fe58571e4a | 275 | targetXOrhtoNotMap=x; |
Ludwigfr | 47:f0fe58571e4a | 276 | targetYOrhtoNotMap=y; |
Ludwigfr | 43:ffd5a6d4dd48 | 277 | } |
Ludwigfr | 43:ffd5a6d4dd48 | 278 | |
Ludwigfr | 39:dd8326ec75ce | 279 | void initialise_parameters(){ |
geotsam | 13:41f75c132135 | 280 | i2c1.frequency(100000); |
AurelienBernier | 2:ea61e801e81f | 281 | initRobot(); //Initializing the robot |
geotsam | 0:8bffb51cc345 | 282 | pc.baud(9600); // baud for the pc communication |
geotsam | 0:8bffb51cc345 | 283 | |
Ludwigfr | 22:ebb37a249b5f | 284 | measure_always_on();//TODO check if needed |
geotsam | 24:8f4b820d8de8 | 285 | wait(0.5); |
Ludwigfr | 39:dd8326ec75ce | 286 | //fill the map with the initial log values |
Ludwigfr | 22:ebb37a249b5f | 287 | fill_initial_log_values(); |
geotsam | 13:41f75c132135 | 288 | |
Ludwigfr | 31:352be78e1aad | 289 | theta=DEFAULT_THETA; |
Ludwigfr | 35:c8f224ab153f | 290 | X=DEFAULT_X; |
Ludwigfr | 35:c8f224ab153f | 291 | Y=DEFAULT_Y; |
AurelienBernier | 8:109314be5b68 | 292 | } |
AurelienBernier | 8:109314be5b68 | 293 | |
Ludwigfr | 22:ebb37a249b5f | 294 | //fill initialLogValues with the values we already know (here the bordurs) |
Ludwigfr | 22:ebb37a249b5f | 295 | void fill_initial_log_values(){ |
Ludwigfr | 31:352be78e1aad | 296 | //Fill map, we know the border are occupied |
geotsam | 24:8f4b820d8de8 | 297 | for (int i = 0; i<NB_CELL_WIDTH; i++) { |
geotsam | 24:8f4b820d8de8 | 298 | for (int j = 0; j<NB_CELL_HEIGHT; j++) { |
geotsam | 24:8f4b820d8de8 | 299 | if(j==0 || j==NB_CELL_HEIGHT-1 || i==0 || i==NB_CELL_WIDTH-1) |
Ludwigfr | 22:ebb37a249b5f | 300 | initialLogValues[i][j] = proba_to_log(1); |
Ludwigfr | 22:ebb37a249b5f | 301 | else |
Ludwigfr | 22:ebb37a249b5f | 302 | initialLogValues[i][j] = proba_to_log(0.5); |
AurelienBernier | 21:62154d644531 | 303 | } |
Ludwigfr | 22:ebb37a249b5f | 304 | } |
AurelienBernier | 8:109314be5b68 | 305 | } |
AurelienBernier | 8:109314be5b68 | 306 | |
Ludwigfr | 22:ebb37a249b5f | 307 | //generate a position randomly and makes the robot go there while updating the map |
Ludwigfr | 22:ebb37a249b5f | 308 | void randomize_and_map() { |
geotsam | 24:8f4b820d8de8 | 309 | //TODO check that it's aurelien's work |
Ludwigfr | 51:b863fad80574 | 310 | float movementOnX=rand()%(int)(WIDTH_ARENA/2); |
Ludwigfr | 51:b863fad80574 | 311 | float movementOnY=rand()%(int)(HEIGHT_ARENA/2); |
Ludwigfr | 51:b863fad80574 | 312 | |
Ludwigfr | 51:b863fad80574 | 313 | float signOfX=rand()%2; |
Ludwigfr | 51:b863fad80574 | 314 | if(signOfX < 1) |
Ludwigfr | 51:b863fad80574 | 315 | signOfX=-1; |
Ludwigfr | 51:b863fad80574 | 316 | float signOfY=rand()%2; |
Ludwigfr | 51:b863fad80574 | 317 | if(signOfY < 1) |
Ludwigfr | 51:b863fad80574 | 318 | signOfY=-1; |
Ludwigfr | 51:b863fad80574 | 319 | |
Ludwigfr | 51:b863fad80574 | 320 | float x = movementOnX*signOfX; |
Ludwigfr | 51:b863fad80574 | 321 | float y = movementOnY*signOfY; |
geotsam | 30:95d8d3e2b81b | 322 | float target_angle = 2*((float)(rand()%31416)-15708)/10000.0; |
Ludwigfr | 51:b863fad80574 | 323 | set_target_to(x,y); |
Ludwigfr | 43:ffd5a6d4dd48 | 324 | go_to_point_with_angle(targetX, targetY, target_angle); |
AurelienBernier | 19:dbc5fbad4975 | 325 | } |
AurelienBernier | 19:dbc5fbad4975 | 326 | |
geotsam | 29:224e9e686f7b | 327 | |
geotsam | 29:224e9e686f7b | 328 | void do_half_flip(){ |
Ludwigfr | 28:f884979a02fa | 329 | Odometria(); |
geotsam | 29:224e9e686f7b | 330 | float theta_plus_h_pi=theta+pi/2;//theta is between -pi and pi |
geotsam | 29:224e9e686f7b | 331 | if(theta_plus_h_pi > pi) |
geotsam | 29:224e9e686f7b | 332 | theta_plus_h_pi=-(2*pi-theta_plus_h_pi); |
geotsam | 29:224e9e686f7b | 333 | leftMotor(0,100); |
geotsam | 29:224e9e686f7b | 334 | rightMotor(1,100); |
geotsam | 29:224e9e686f7b | 335 | while(abs(theta_plus_h_pi-theta)>0.05){ |
Ludwigfr | 28:f884979a02fa | 336 | Odometria(); |
geotsam | 29:224e9e686f7b | 337 | // pc.printf("\n\r diff=%f", abs(theta_plus_pi-theta)); |
Ludwigfr | 28:f884979a02fa | 338 | } |
Ludwigfr | 28:f884979a02fa | 339 | leftMotor(1,0); |
Ludwigfr | 28:f884979a02fa | 340 | rightMotor(1,0); |
Ludwigfr | 28:f884979a02fa | 341 | } |
Ludwigfr | 28:f884979a02fa | 342 | |
Ludwigfr | 25:572c9e9a8809 | 343 | //ODOMETRIA MUST HAVE BEEN CALLED |
Ludwigfr | 22:ebb37a249b5f | 344 | //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 | 345 | float compute_probability_t(float x, float y,float xs,float ys, float angleFromSonarPosition, float distanceObstacleDetected){ |
Ludwigfr | 22:ebb37a249b5f | 346 | |
Ludwigfr | 22:ebb37a249b5f | 347 | float distancePointToSonar=sqrt(pow(x-xs,2)+pow(y-ys,2)); |
Ludwigfr | 50:a970cf7889d3 | 348 | if( distancePointToSonar < RANGE_SONAR){ |
Ludwigfr | 50:a970cf7889d3 | 349 | float anglePointToSonar=compute_angle_between_vectors(x,y,xs,ys);//angle beetween the point and the sonar beam |
Ludwigfr | 50:a970cf7889d3 | 350 | float alphaBeforeAdjustment=anglePointToSonar-theta-angleFromSonarPosition; |
Ludwigfr | 50:a970cf7889d3 | 351 | anglePointToSonar=rad_angle_check(alphaBeforeAdjustment);//TODO I feel you don't need to do that but I m not sure |
Ludwigfr | 50:a970cf7889d3 | 352 | |
Ludwigfr | 50:a970cf7889d3 | 353 | if(alphaBeforeAdjustment>pi) |
Ludwigfr | 50:a970cf7889d3 | 354 | alphaBeforeAdjustment=alphaBeforeAdjustment-2*pi; |
Ludwigfr | 50:a970cf7889d3 | 355 | if(alphaBeforeAdjustment<-pi) |
Ludwigfr | 50:a970cf7889d3 | 356 | alphaBeforeAdjustment=alphaBeforeAdjustment+2*pi; |
Ludwigfr | 50:a970cf7889d3 | 357 | |
Ludwigfr | 50:a970cf7889d3 | 358 | //float anglePointToSonar2=atan2(y-ys,x-xs)-theta; |
Ludwigfr | 48:cd3463dcca04 | 359 | |
Ludwigfr | 50:a970cf7889d3 | 360 | //check if the distance between the cell and the robot is within the circle of range RADIUS_WHEELS |
Ludwigfr | 50:a970cf7889d3 | 361 | //check if absolute difference between the angles is no more than Omega/2 |
Ludwigfr | 50:a970cf7889d3 | 362 | if(anglePointToSonar <= ANGLE_SONAR/2 || anglePointToSonar >= rad_angle_check(-ANGLE_SONAR/2)){ |
Ludwigfr | 50:a970cf7889d3 | 363 | if( distancePointToSonar < (distanceObstacleDetected - INCERTITUDE_SONAR)){ |
Ludwigfr | 50:a970cf7889d3 | 364 | //point before obstacle, probably empty |
Ludwigfr | 50:a970cf7889d3 | 365 | /*****************************************************************************/ |
Ludwigfr | 50:a970cf7889d3 | 366 | float Ea=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2); |
Ludwigfr | 50:a970cf7889d3 | 367 | float Er; |
Ludwigfr | 50:a970cf7889d3 | 368 | if(distancePointToSonar < RANGE_SONAR_MIN){ |
Ludwigfr | 50:a970cf7889d3 | 369 | //point before minimum sonar range |
Ludwigfr | 50:a970cf7889d3 | 370 | Er=0.f; |
Ludwigfr | 50:a970cf7889d3 | 371 | }else{ |
Ludwigfr | 50:a970cf7889d3 | 372 | //point after minimum sonar range |
Ludwigfr | 50:a970cf7889d3 | 373 | Er=1.f-pow((distancePointToSonar-RANGE_SONAR_MIN)/(distanceObstacleDetected-INCERTITUDE_SONAR-RANGE_SONAR_MIN),2); |
Ludwigfr | 50:a970cf7889d3 | 374 | } |
Ludwigfr | 50:a970cf7889d3 | 375 | /*****************************************************************************/ |
Ludwigfr | 50:a970cf7889d3 | 376 | //if((1.f-Er*Ea)/2.f >1 || (1.f-Er*Ea)/2.f < 0) |
Ludwigfr | 50:a970cf7889d3 | 377 | // pc.printf("\n\r return value=%f,Er=%f,Ea=%f,alphaBeforeAdjustment=%f",(1.f-Er*Ea)/2.f,Er,Ea,alphaBeforeAdjustment); |
Ludwigfr | 50:a970cf7889d3 | 378 | return (1.f-Er*Ea)/2.f; |
Ludwigfr | 22:ebb37a249b5f | 379 | }else{ |
Ludwigfr | 50:a970cf7889d3 | 380 | //probably occupied |
Ludwigfr | 50:a970cf7889d3 | 381 | /*****************************************************************************/ |
Ludwigfr | 50:a970cf7889d3 | 382 | float Oa=1.f-pow((2*alphaBeforeAdjustment)/ANGLE_SONAR,2); |
Ludwigfr | 50:a970cf7889d3 | 383 | float Or; |
Ludwigfr | 50:a970cf7889d3 | 384 | if( distancePointToSonar <= (distanceObstacleDetected + INCERTITUDE_SONAR)){ |
Ludwigfr | 50:a970cf7889d3 | 385 | //point between distanceObstacleDetected +- INCERTITUDE_SONAR |
Ludwigfr | 50:a970cf7889d3 | 386 | Or=1-pow((distancePointToSonar-distanceObstacleDetected)/(INCERTITUDE_SONAR),2); |
Ludwigfr | 50:a970cf7889d3 | 387 | }else{ |
Ludwigfr | 50:a970cf7889d3 | 388 | //point after in range of the sonar but after the zone detected |
Ludwigfr | 50:a970cf7889d3 | 389 | Or=0; |
Ludwigfr | 50:a970cf7889d3 | 390 | } |
Ludwigfr | 50:a970cf7889d3 | 391 | /*****************************************************************************/ |
Ludwigfr | 50:a970cf7889d3 | 392 | //if((1+Or*Oa)/2 >1 || (1+Or*Oa)/2 < 0) |
Ludwigfr | 50:a970cf7889d3 | 393 | // pc.printf("\n\r return value=%f,Er=%f,Ea=%f,alphaBeforeAdjustment=%f",(1+Or*Oa)/2,Or,Oa,alphaBeforeAdjustment); |
Ludwigfr | 50:a970cf7889d3 | 394 | return (1+Or*Oa)/2; |
Ludwigfr | 22:ebb37a249b5f | 395 | } |
Ludwigfr | 50:a970cf7889d3 | 396 | } |
AurelienBernier | 19:dbc5fbad4975 | 397 | } |
Ludwigfr | 50:a970cf7889d3 | 398 | //not checked by the sonar |
Ludwigfr | 50:a970cf7889d3 | 399 | return 0.5; |
Ludwigfr | 22:ebb37a249b5f | 400 | } |
Ludwigfr | 22:ebb37a249b5f | 401 | |
Ludwigfr | 25:572c9e9a8809 | 402 | void print_final_map() { |
Ludwigfr | 22:ebb37a249b5f | 403 | float currProba; |
geotsam | 24:8f4b820d8de8 | 404 | pc.printf("\n\r"); |
geotsam | 24:8f4b820d8de8 | 405 | for (int y = NB_CELL_HEIGHT -1; y>-1; y--) { |
geotsam | 24:8f4b820d8de8 | 406 | for (int x= 0; x<NB_CELL_WIDTH; x++) { |
geotsam | 24:8f4b820d8de8 | 407 | currProba=log_to_proba(map[x][y]); |
geotsam | 24:8f4b820d8de8 | 408 | if ( currProba < 0.5) { |
geotsam | 29:224e9e686f7b | 409 | pc.printf(" "); |
Ludwigfr | 22:ebb37a249b5f | 410 | } else { |
Ludwigfr | 22:ebb37a249b5f | 411 | if(currProba==0.5) |
geotsam | 24:8f4b820d8de8 | 412 | pc.printf(" . "); |
Ludwigfr | 22:ebb37a249b5f | 413 | else |
geotsam | 29:224e9e686f7b | 414 | pc.printf(" X "); |
Ludwigfr | 22:ebb37a249b5f | 415 | } |
Ludwigfr | 22:ebb37a249b5f | 416 | } |
geotsam | 24:8f4b820d8de8 | 417 | pc.printf("\n\r"); |
Ludwigfr | 22:ebb37a249b5f | 418 | } |
Ludwigfr | 22:ebb37a249b5f | 419 | } |
Ludwigfr | 22:ebb37a249b5f | 420 | |
Ludwigfr | 25:572c9e9a8809 | 421 | void print_final_map_with_robot_position() { |
geotsam | 24:8f4b820d8de8 | 422 | float currProba; |
Ludwigfr | 25:572c9e9a8809 | 423 | Odometria(); |
Ludwigfr | 25:572c9e9a8809 | 424 | float Xrobot=robot_center_x_in_orthonormal_x(); |
Ludwigfr | 25:572c9e9a8809 | 425 | float Yrobot=robot_center_y_in_orthonormal_y(); |
Ludwigfr | 25:572c9e9a8809 | 426 | |
Ludwigfr | 25:572c9e9a8809 | 427 | float heightIndiceInOrthonormal; |
Ludwigfr | 25:572c9e9a8809 | 428 | float widthIndiceInOrthonormal; |
Ludwigfr | 25:572c9e9a8809 | 429 | |
Ludwigfr | 27:07bde633af72 | 430 | float widthMalus=-(3*sizeCellWidth/2); |
Ludwigfr | 27:07bde633af72 | 431 | float widthBonus=sizeCellWidth/2; |
Ludwigfr | 25:572c9e9a8809 | 432 | |
Ludwigfr | 27:07bde633af72 | 433 | float heightMalus=-(3*sizeCellHeight/2); |
Ludwigfr | 27:07bde633af72 | 434 | float heightBonus=sizeCellHeight/2; |
Ludwigfr | 25:572c9e9a8809 | 435 | |
geotsam | 24:8f4b820d8de8 | 436 | pc.printf("\n\r"); |
geotsam | 24:8f4b820d8de8 | 437 | for (int y = NB_CELL_HEIGHT -1; y>-1; y--) { |
geotsam | 24:8f4b820d8de8 | 438 | for (int x= 0; x<NB_CELL_WIDTH; x++) { |
Ludwigfr | 25:572c9e9a8809 | 439 | heightIndiceInOrthonormal=estimated_height_indice_in_orthonormal_y(y); |
Ludwigfr | 25:572c9e9a8809 | 440 | widthIndiceInOrthonormal=estimated_width_indice_in_orthonormal_x(x); |
Ludwigfr | 27:07bde633af72 | 441 | if(Yrobot >= (heightIndiceInOrthonormal+heightMalus) && Yrobot <= (heightIndiceInOrthonormal+heightBonus) && Xrobot >= (widthIndiceInOrthonormal+widthMalus) && Xrobot <= (widthIndiceInOrthonormal+widthBonus)) |
Ludwigfr | 27:07bde633af72 | 442 | pc.printf(" R "); |
Ludwigfr | 25:572c9e9a8809 | 443 | else{ |
Ludwigfr | 25:572c9e9a8809 | 444 | currProba=log_to_proba(map[x][y]); |
Ludwigfr | 25:572c9e9a8809 | 445 | if ( currProba < 0.5) |
geotsam | 29:224e9e686f7b | 446 | pc.printf(" "); |
Ludwigfr | 25:572c9e9a8809 | 447 | else{ |
Ludwigfr | 25:572c9e9a8809 | 448 | if(currProba==0.5) |
Ludwigfr | 27:07bde633af72 | 449 | pc.printf(" . "); |
Ludwigfr | 25:572c9e9a8809 | 450 | else |
geotsam | 29:224e9e686f7b | 451 | pc.printf(" X "); |
Ludwigfr | 25:572c9e9a8809 | 452 | } |
geotsam | 24:8f4b820d8de8 | 453 | } |
geotsam | 24:8f4b820d8de8 | 454 | } |
geotsam | 24:8f4b820d8de8 | 455 | pc.printf("\n\r"); |
geotsam | 24:8f4b820d8de8 | 456 | } |
geotsam | 24:8f4b820d8de8 | 457 | } |
Ludwigfr | 22:ebb37a249b5f | 458 | |
Ludwigfr | 39:dd8326ec75ce | 459 | void print_final_map_with_robot_position_and_target() { |
Ludwigfr | 39:dd8326ec75ce | 460 | float currProba; |
Ludwigfr | 39:dd8326ec75ce | 461 | Odometria(); |
Ludwigfr | 39:dd8326ec75ce | 462 | float Xrobot=robot_center_x_in_orthonormal_x(); |
Ludwigfr | 39:dd8326ec75ce | 463 | float Yrobot=robot_center_y_in_orthonormal_y(); |
Ludwigfr | 39:dd8326ec75ce | 464 | |
Ludwigfr | 39:dd8326ec75ce | 465 | float heightIndiceInOrthonormal; |
Ludwigfr | 39:dd8326ec75ce | 466 | float widthIndiceInOrthonormal; |
Ludwigfr | 39:dd8326ec75ce | 467 | |
Ludwigfr | 39:dd8326ec75ce | 468 | float widthMalus=-(3*sizeCellWidth/2); |
Ludwigfr | 39:dd8326ec75ce | 469 | float widthBonus=sizeCellWidth/2; |
Ludwigfr | 39:dd8326ec75ce | 470 | |
Ludwigfr | 39:dd8326ec75ce | 471 | float heightMalus=-(3*sizeCellHeight/2); |
Ludwigfr | 39:dd8326ec75ce | 472 | float heightBonus=sizeCellHeight/2; |
Ludwigfr | 39:dd8326ec75ce | 473 | |
Ludwigfr | 39:dd8326ec75ce | 474 | pc.printf("\n\r"); |
Ludwigfr | 39:dd8326ec75ce | 475 | for (int y = NB_CELL_HEIGHT -1; y>-1; y--) { |
Ludwigfr | 39:dd8326ec75ce | 476 | for (int x= 0; x<NB_CELL_WIDTH; x++) { |
Ludwigfr | 39:dd8326ec75ce | 477 | heightIndiceInOrthonormal=estimated_height_indice_in_orthonormal_y(y); |
Ludwigfr | 39:dd8326ec75ce | 478 | widthIndiceInOrthonormal=estimated_width_indice_in_orthonormal_x(x); |
Ludwigfr | 39:dd8326ec75ce | 479 | if(Yrobot >= (heightIndiceInOrthonormal+heightMalus) && Yrobot <= (heightIndiceInOrthonormal+heightBonus) && Xrobot >= (widthIndiceInOrthonormal+widthMalus) && Xrobot <= (widthIndiceInOrthonormal+widthBonus)) |
Ludwigfr | 39:dd8326ec75ce | 480 | pc.printf(" R "); |
Ludwigfr | 39:dd8326ec75ce | 481 | else{ |
Ludwigfr | 43:ffd5a6d4dd48 | 482 | if(targetYOrhto >= (heightIndiceInOrthonormal+heightMalus) && targetYOrhto <= (heightIndiceInOrthonormal+heightBonus) && targetXOrhto >= (widthIndiceInOrthonormal+widthMalus) && targetXOrhto <= (widthIndiceInOrthonormal+widthBonus)) |
Ludwigfr | 39:dd8326ec75ce | 483 | pc.printf(" T "); |
Ludwigfr | 39:dd8326ec75ce | 484 | else{ |
Ludwigfr | 39:dd8326ec75ce | 485 | currProba=log_to_proba(map[x][y]); |
Ludwigfr | 39:dd8326ec75ce | 486 | if ( currProba < 0.5) |
Ludwigfr | 39:dd8326ec75ce | 487 | pc.printf(" "); |
Ludwigfr | 39:dd8326ec75ce | 488 | else{ |
Ludwigfr | 39:dd8326ec75ce | 489 | if(currProba==0.5) |
Ludwigfr | 39:dd8326ec75ce | 490 | pc.printf(" . "); |
Ludwigfr | 39:dd8326ec75ce | 491 | else |
Ludwigfr | 39:dd8326ec75ce | 492 | pc.printf(" X "); |
Ludwigfr | 39:dd8326ec75ce | 493 | } |
Ludwigfr | 39:dd8326ec75ce | 494 | } |
Ludwigfr | 39:dd8326ec75ce | 495 | } |
Ludwigfr | 39:dd8326ec75ce | 496 | } |
Ludwigfr | 39:dd8326ec75ce | 497 | pc.printf("\n\r"); |
Ludwigfr | 39:dd8326ec75ce | 498 | } |
Ludwigfr | 39:dd8326ec75ce | 499 | } |
Ludwigfr | 39:dd8326ec75ce | 500 | |
Ludwigfr | 22:ebb37a249b5f | 501 | //MATHS heavy functions |
Ludwigfr | 22:ebb37a249b5f | 502 | /**********************************************************************/ |
Ludwigfr | 22:ebb37a249b5f | 503 | //Distance computation function |
Ludwigfr | 22:ebb37a249b5f | 504 | float dist(float robot_x, float robot_y, float target_x, float target_y){ |
Ludwigfr | 51:b863fad80574 | 505 | //pc.printf("%f, %f, %f, %f",robot_x,robot_y,target_x,target_y); |
Ludwigfr | 22:ebb37a249b5f | 506 | return sqrt(pow(target_y-robot_y,2) + pow(target_x-robot_x,2)); |
Ludwigfr | 22:ebb37a249b5f | 507 | } |
Ludwigfr | 22:ebb37a249b5f | 508 | |
geotsam | 24:8f4b820d8de8 | 509 | //returns the probability [0,1] that the cell is occupied from the log valAue lt |
Ludwigfr | 22:ebb37a249b5f | 510 | float log_to_proba(float lt){ |
Ludwigfr | 22:ebb37a249b5f | 511 | return 1-1/(1+exp(lt)); |
Ludwigfr | 22:ebb37a249b5f | 512 | } |
Ludwigfr | 22:ebb37a249b5f | 513 | |
Ludwigfr | 22:ebb37a249b5f | 514 | //returns the log value that the cell is occupied from the probability value [0,1] |
Ludwigfr | 22:ebb37a249b5f | 515 | float proba_to_log(float p){ |
Ludwigfr | 22:ebb37a249b5f | 516 | return log(p/(1-p)); |
Ludwigfr | 22:ebb37a249b5f | 517 | } |
Ludwigfr | 22:ebb37a249b5f | 518 | |
Ludwigfr | 22:ebb37a249b5f | 519 | //returns the new log value |
Ludwigfr | 22:ebb37a249b5f | 520 | float compute_log_estimation_lt(float previousLogValue,float currentProbability,float originalLogvalue ){ |
Ludwigfr | 22:ebb37a249b5f | 521 | return previousLogValue+proba_to_log(currentProbability)-originalLogvalue; |
Ludwigfr | 22:ebb37a249b5f | 522 | } |
Ludwigfr | 22:ebb37a249b5f | 523 | |
Ludwigfr | 22:ebb37a249b5f | 524 | //makes the angle inAngle between 0 and 2pi |
Ludwigfr | 22:ebb37a249b5f | 525 | float rad_angle_check(float inAngle){ |
Ludwigfr | 22:ebb37a249b5f | 526 | //cout<<"before :"<<inAngle; |
Ludwigfr | 22:ebb37a249b5f | 527 | if(inAngle > 0){ |
Ludwigfr | 22:ebb37a249b5f | 528 | while(inAngle > (2*pi)) |
Ludwigfr | 22:ebb37a249b5f | 529 | inAngle-=2*pi; |
Ludwigfr | 22:ebb37a249b5f | 530 | }else{ |
Ludwigfr | 22:ebb37a249b5f | 531 | while(inAngle < 0) |
Ludwigfr | 22:ebb37a249b5f | 532 | inAngle+=2*pi; |
Ludwigfr | 22:ebb37a249b5f | 533 | } |
Ludwigfr | 22:ebb37a249b5f | 534 | //cout<<" after :"<<inAngle<<endl; |
Ludwigfr | 22:ebb37a249b5f | 535 | return inAngle; |
Ludwigfr | 22:ebb37a249b5f | 536 | } |
Ludwigfr | 22:ebb37a249b5f | 537 | |
Ludwigfr | 22:ebb37a249b5f | 538 | //returns the angle between the vectors (x,y) and (xs,ys) |
Ludwigfr | 22:ebb37a249b5f | 539 | float compute_angle_between_vectors(float x, float y,float xs,float ys){ |
Ludwigfr | 22:ebb37a249b5f | 540 | //alpha angle between ->x and ->SA |
Ludwigfr | 22:ebb37a249b5f | 541 | //vector S to A ->SA |
Ludwigfr | 22:ebb37a249b5f | 542 | float vSAx=x-xs; |
Ludwigfr | 22:ebb37a249b5f | 543 | float vSAy=y-ys; |
Ludwigfr | 22:ebb37a249b5f | 544 | //norme SA |
Ludwigfr | 22:ebb37a249b5f | 545 | float normeSA=sqrt(pow(vSAx,2)+pow(vSAy,2)); |
Ludwigfr | 22:ebb37a249b5f | 546 | //vector ->x (1,0) |
Ludwigfr | 22:ebb37a249b5f | 547 | float cosAlpha=1*vSAy/*+0*vSAx*//normeSA;; |
Ludwigfr | 22:ebb37a249b5f | 548 | //vector ->y (0,1) |
Ludwigfr | 22:ebb37a249b5f | 549 | float sinAlpha=/*0*vSAy+*/1*vSAx/normeSA;//+0*vSAx; |
Ludwigfr | 22:ebb37a249b5f | 550 | if (sinAlpha < 0) |
Ludwigfr | 22:ebb37a249b5f | 551 | return -acos(cosAlpha); |
Ludwigfr | 22:ebb37a249b5f | 552 | else |
Ludwigfr | 22:ebb37a249b5f | 553 | return acos(cosAlpha); |
Ludwigfr | 25:572c9e9a8809 | 554 | } |
Ludwigfr | 51:b863fad80574 | 555 | |
Ludwigfr | 51:b863fad80574 | 556 | //return 1 if positiv, -1 if negativ |
Ludwigfr | 51:b863fad80574 | 557 | float sign1(float value){ |
Ludwigfr | 51:b863fad80574 | 558 | if(value>=0) |
Ludwigfr | 51:b863fad80574 | 559 | return 1; |
Ludwigfr | 51:b863fad80574 | 560 | else |
Ludwigfr | 51:b863fad80574 | 561 | return -1; |
Ludwigfr | 51:b863fad80574 | 562 | } |
Ludwigfr | 25:572c9e9a8809 | 563 | |
Ludwigfr | 51:b863fad80574 | 564 | //return 1 if positiv, 0 if negativ |
Ludwigfr | 51:b863fad80574 | 565 | int sign2(float value){ |
Ludwigfr | 51:b863fad80574 | 566 | if(value>=0) |
Ludwigfr | 51:b863fad80574 | 567 | return 1; |
Ludwigfr | 51:b863fad80574 | 568 | else |
Ludwigfr | 51:b863fad80574 | 569 | return 0; |
Ludwigfr | 51:b863fad80574 | 570 | } |
Ludwigfr | 38:3c9f8cbf5250 | 571 | |
Ludwigfr | 51:b863fad80574 | 572 | /* |
Ludwigfr | 44:e2bd06f94dc0 | 573 | Robot space: orthonormal space: |
Ludwigfr | 38:3c9f8cbf5250 | 574 | ^ ^ |
Ludwigfr | 38:3c9f8cbf5250 | 575 | |x |y |
Ludwigfr | 38:3c9f8cbf5250 | 576 | <- R O -> |
Ludwigfr | 38:3c9f8cbf5250 | 577 | y x |
Ludwigfr | 38:3c9f8cbf5250 | 578 | */ |
Ludwigfr | 38:3c9f8cbf5250 | 579 | //Odometria must bu up to date |
Ludwigfr | 36:c806c568720a | 580 | float x_robot_in_orthonormal_x(float x, float y){ |
Ludwigfr | 38:3c9f8cbf5250 | 581 | return robot_center_x_in_orthonormal_x()-y; |
Ludwigfr | 36:c806c568720a | 582 | } |
Ludwigfr | 36:c806c568720a | 583 | |
Ludwigfr | 38:3c9f8cbf5250 | 584 | //Odometria must bu up to date |
Ludwigfr | 36:c806c568720a | 585 | float y_robot_in_orthonormal_y(float x, float y){ |
Ludwigfr | 38:3c9f8cbf5250 | 586 | return robot_center_y_in_orthonormal_y()+x; |
Ludwigfr | 36:c806c568720a | 587 | } |
Ludwigfr | 36:c806c568720a | 588 | |
Ludwigfr | 25:572c9e9a8809 | 589 | float robot_center_x_in_orthonormal_x(){ |
Ludwigfr | 27:07bde633af72 | 590 | return NB_CELL_WIDTH*sizeCellWidth-Y; |
Ludwigfr | 25:572c9e9a8809 | 591 | } |
Ludwigfr | 25:572c9e9a8809 | 592 | |
Ludwigfr | 25:572c9e9a8809 | 593 | float robot_center_y_in_orthonormal_y(){ |
Ludwigfr | 27:07bde633af72 | 594 | return X; |
Ludwigfr | 25:572c9e9a8809 | 595 | } |
Ludwigfr | 25:572c9e9a8809 | 596 | |
Ludwigfr | 25:572c9e9a8809 | 597 | float robot_sonar_front_x_in_orthonormal_x(){ |
Ludwigfr | 27:07bde633af72 | 598 | return robot_center_x_in_orthonormal_x()+DISTANCE_SONAR_FRONT_X; |
Ludwigfr | 25:572c9e9a8809 | 599 | } |
Ludwigfr | 25:572c9e9a8809 | 600 | float robot_sonar_front_y_in_orthonormal_y(){ |
Ludwigfr | 27:07bde633af72 | 601 | return robot_center_y_in_orthonormal_y()+DISTANCE_SONAR_FRONT_Y; |
Ludwigfr | 25:572c9e9a8809 | 602 | } |
Ludwigfr | 25:572c9e9a8809 | 603 | |
Ludwigfr | 25:572c9e9a8809 | 604 | float robot_sonar_right_x_in_orthonormal_x(){ |
Ludwigfr | 27:07bde633af72 | 605 | return robot_center_x_in_orthonormal_x()+DISTANCE_SONAR_RIGHT_X; |
Ludwigfr | 25:572c9e9a8809 | 606 | } |
Ludwigfr | 25:572c9e9a8809 | 607 | float robot_sonar_right_y_in_orthonormal_y(){ |
Ludwigfr | 27:07bde633af72 | 608 | return robot_center_y_in_orthonormal_y()+DISTANCE_SONAR_RIGHT_Y; |
Ludwigfr | 25:572c9e9a8809 | 609 | } |
Ludwigfr | 25:572c9e9a8809 | 610 | |
Ludwigfr | 25:572c9e9a8809 | 611 | float robot_sonar_left_x_in_orthonormal_x(){ |
Ludwigfr | 27:07bde633af72 | 612 | return robot_center_x_in_orthonormal_x()+DISTANCE_SONAR_LEFT_X; |
Ludwigfr | 25:572c9e9a8809 | 613 | } |
Ludwigfr | 25:572c9e9a8809 | 614 | float robot_sonar_left_y_in_orthonormal_y(){ |
Ludwigfr | 27:07bde633af72 | 615 | return robot_center_y_in_orthonormal_y()+DISTANCE_SONAR_LEFT_Y; |
Ludwigfr | 25:572c9e9a8809 | 616 | } |
Ludwigfr | 25:572c9e9a8809 | 617 | |
Ludwigfr | 25:572c9e9a8809 | 618 | float estimated_width_indice_in_orthonormal_x(int i){ |
Ludwigfr | 27:07bde633af72 | 619 | return sizeCellWidth/2+i*sizeCellWidth; |
Ludwigfr | 25:572c9e9a8809 | 620 | } |
Ludwigfr | 25:572c9e9a8809 | 621 | float estimated_height_indice_in_orthonormal_y(int j){ |
Ludwigfr | 27:07bde633af72 | 622 | return sizeCellHeight/2+j*sizeCellHeight; |
geotsam | 26:b020cf253059 | 623 | } |
geotsam | 26:b020cf253059 | 624 | |
Ludwigfr | 43:ffd5a6d4dd48 | 625 | void update_force(int widthIndice, int heightIndice, float range, float* forceX, float* forceY, float xRobotOrtho, float yRobotOrtho ){ |
Ludwigfr | 44:e2bd06f94dc0 | 626 | //get the coordonate of the map and the robot in the ortonormal space |
Ludwigfr | 32:d51928b58645 | 627 | float xCenterCell=estimated_width_indice_in_orthonormal_x(widthIndice); |
Ludwigfr | 32:d51928b58645 | 628 | float yCenterCell=estimated_height_indice_in_orthonormal_y(heightIndice); |
Ludwigfr | 32:d51928b58645 | 629 | //compute the distance beetween the cell and the robot |
Ludwigfr | 32:d51928b58645 | 630 | float distanceCellToRobot=sqrt(pow(xCenterCell-xRobotOrtho,2)+pow(yCenterCell-yRobotOrtho,2)); |
Ludwigfr | 32:d51928b58645 | 631 | //check if the cell is in range |
Ludwigfr | 43:ffd5a6d4dd48 | 632 | if(distanceCellToRobot <= range) { |
Ludwigfr | 51:b863fad80574 | 633 | /*float anglePointToRobot=compute_angle_between_vectors(xCenterCell,yCenterCell,xRobotOrtho,yRobotOrtho);//angle beetween the point and the sonar |
Ludwigfr | 51:b863fad80574 | 634 | float alphaBeforeAdjustment=anglePointToRobot-theta; |
Ludwigfr | 51:b863fad80574 | 635 | anglePointToRobot=rad_angle_check(alphaBeforeAdjustment); |
Ludwigfr | 51:b863fad80574 | 636 | if(anglePointToRobot <= pi/2 || anglePointToRobot >= rad_angle_check(-pi/2)){ |
Ludwigfr | 51:b863fad80574 | 637 | */ |
Ludwigfr | 51:b863fad80574 | 638 | float probaCell=log_to_proba(map[widthIndice][heightIndice]); |
Ludwigfr | 51:b863fad80574 | 639 | float xForceComputed=FORCE_CONSTANT_REPULSION*probaCell*(xCenterCell-xRobotOrtho)/pow(distanceCellToRobot,3); |
Ludwigfr | 51:b863fad80574 | 640 | float yForceComputed=FORCE_CONSTANT_REPULSION*probaCell*(yCenterCell-yRobotOrtho)/pow(distanceCellToRobot,3); |
Ludwigfr | 51:b863fad80574 | 641 | *forceX+=xForceComputed; |
Ludwigfr | 51:b863fad80574 | 642 | *forceY+=yForceComputed; |
Ludwigfr | 51:b863fad80574 | 643 | //} |
Ludwigfr | 36:c806c568720a | 644 | } |
geotsam | 33:78139f82ea74 | 645 | } |
geotsam | 33:78139f82ea74 | 646 | |
Ludwigfr | 43:ffd5a6d4dd48 | 647 | void test_got_to_line(bool* reached){ |
Ludwigfr | 43:ffd5a6d4dd48 | 648 | float line_a=1; |
Ludwigfr | 43:ffd5a6d4dd48 | 649 | float line_b=2; |
Ludwigfr | 43:ffd5a6d4dd48 | 650 | float line_c=-140; |
Ludwigfr | 43:ffd5a6d4dd48 | 651 | //we update the odometrie |
Ludwigfr | 43:ffd5a6d4dd48 | 652 | Odometria(); |
Ludwigfr | 43:ffd5a6d4dd48 | 653 | float angularRight=0; |
Ludwigfr | 43:ffd5a6d4dd48 | 654 | float angularLeft=0; |
Ludwigfr | 43:ffd5a6d4dd48 | 655 | |
Ludwigfr | 43:ffd5a6d4dd48 | 656 | go_to_line(&angularLeft,&angularRight,line_a,line_b,line_c); |
Ludwigfr | 48:cd3463dcca04 | 657 | //pc.printf("\r\n line: %f x + %f y + %f =0", line_a, line_b, line_c); |
Ludwigfr | 43:ffd5a6d4dd48 | 658 | |
Ludwigfr | 43:ffd5a6d4dd48 | 659 | leftMotor(sign2(angularLeft),abs(angularLeft)); |
Ludwigfr | 43:ffd5a6d4dd48 | 660 | rightMotor(sign2(angularRight),abs(angularRight)); |
Ludwigfr | 43:ffd5a6d4dd48 | 661 | |
Ludwigfr | 43:ffd5a6d4dd48 | 662 | pc.printf("\r\n dist=%f", dist(robot_center_x_in_orthonormal_x(),robot_center_y_in_orthonormal_y(),targetXOrhto,targetYOrhto)); |
Ludwigfr | 43:ffd5a6d4dd48 | 663 | |
Ludwigfr | 43:ffd5a6d4dd48 | 664 | //wait(0.1); |
Ludwigfr | 43:ffd5a6d4dd48 | 665 | Odometria(); |
Ludwigfr | 43:ffd5a6d4dd48 | 666 | if(dist(robot_center_x_in_orthonormal_x(),robot_center_y_in_orthonormal_y(),targetXOrhto,targetYOrhto)<10) |
Ludwigfr | 43:ffd5a6d4dd48 | 667 | *reached=true; |
Ludwigfr | 43:ffd5a6d4dd48 | 668 | } |
Ludwigfr | 42:ab25bffdc32b | 669 | void vff(bool* reached){ |
Ludwigfr | 42:ab25bffdc32b | 670 | float line_a; |
Ludwigfr | 42:ab25bffdc32b | 671 | float line_b; |
Ludwigfr | 42:ab25bffdc32b | 672 | float line_c; |
geotsam | 33:78139f82ea74 | 673 | //Updating X,Y and theta with the odometry values |
geotsam | 37:462d19bb221f | 674 | float forceX=0; |
geotsam | 37:462d19bb221f | 675 | float forceY=0; |
Ludwigfr | 38:3c9f8cbf5250 | 676 | //we update the odometrie |
geotsam | 33:78139f82ea74 | 677 | Odometria(); |
Ludwigfr | 38:3c9f8cbf5250 | 678 | //we check the sensors |
Ludwigfr | 40:f5e212d9f900 | 679 | float leftMm = get_distance_left_sensor(); |
Ludwigfr | 40:f5e212d9f900 | 680 | float frontMm = get_distance_front_sensor(); |
Ludwigfr | 40:f5e212d9f900 | 681 | float rightMm = get_distance_right_sensor(); |
Ludwigfr | 42:ab25bffdc32b | 682 | float angularRight=0; |
Ludwigfr | 42:ab25bffdc32b | 683 | float angularLeft=0; |
Ludwigfr | 38:3c9f8cbf5250 | 684 | //update the probabilities values |
geotsam | 33:78139f82ea74 | 685 | update_sonar_values(leftMm, frontMm, rightMm); |
Ludwigfr | 38:3c9f8cbf5250 | 686 | //we compute the force on X and Y |
Ludwigfr | 39:dd8326ec75ce | 687 | compute_forceX_and_forceY(&forceX, &forceY); |
Ludwigfr | 38:3c9f8cbf5250 | 688 | //we compute a new ine |
Ludwigfr | 42:ab25bffdc32b | 689 | calculate_line(forceX, forceY, X, Y,&line_a,&line_b,&line_c); |
Ludwigfr | 42:ab25bffdc32b | 690 | go_to_line(&angularLeft,&angularRight,line_a,line_b,line_c); |
geotsam | 33:78139f82ea74 | 691 | |
geotsam | 33:78139f82ea74 | 692 | //Updating motor velocities |
Ludwigfr | 43:ffd5a6d4dd48 | 693 | |
Ludwigfr | 43:ffd5a6d4dd48 | 694 | leftMotor(sign2(angularLeft),abs(angularLeft)); |
Ludwigfr | 43:ffd5a6d4dd48 | 695 | rightMotor(sign2(angularRight),abs(angularRight)); |
geotsam | 33:78139f82ea74 | 696 | |
Ludwigfr | 40:f5e212d9f900 | 697 | //wait(0.1); |
geotsam | 33:78139f82ea74 | 698 | Odometria(); |
Ludwigfr | 43:ffd5a6d4dd48 | 699 | if(dist(robot_center_x_in_orthonormal_x(),robot_center_y_in_orthonormal_y(),targetXOrhto,targetYOrhto)<10) |
Ludwigfr | 42:ab25bffdc32b | 700 | *reached=true; |
geotsam | 33:78139f82ea74 | 701 | } |
geotsam | 33:78139f82ea74 | 702 | |
Ludwigfr | 44:e2bd06f94dc0 | 703 | //robotX and robotY are from Odometria, calculate line_a, line_b and line_c |
Ludwigfr | 44:e2bd06f94dc0 | 704 | void calculate_line(float forceX, float forceY, float robotX, float robotY,float *line_a, float *line_b, float *line_c){ |
Ludwigfr | 44:e2bd06f94dc0 | 705 | /* |
Ludwigfr | 44:e2bd06f94dc0 | 706 | in the teachers maths it is |
Ludwigfr | 44:e2bd06f94dc0 | 707 | |
Ludwigfr | 44:e2bd06f94dc0 | 708 | *line_a=forceY; |
Ludwigfr | 44:e2bd06f94dc0 | 709 | *line_b=-forceX; |
Ludwigfr | 44:e2bd06f94dc0 | 710 | |
Ludwigfr | 44:e2bd06f94dc0 | 711 | because a*x+b*y+c=0 |
Ludwigfr | 44:e2bd06f94dc0 | 712 | a impact the vertical and b the horizontal |
Ludwigfr | 44:e2bd06f94dc0 | 713 | and he has to put them like this because |
Ludwigfr | 44:e2bd06f94dc0 | 714 | Robot space: orthonormal space: |
Ludwigfr | 44:e2bd06f94dc0 | 715 | ^ ^ |
Ludwigfr | 44:e2bd06f94dc0 | 716 | |x |y |
Ludwigfr | 44:e2bd06f94dc0 | 717 | <- R O -> |
Ludwigfr | 44:e2bd06f94dc0 | 718 | y x |
Ludwigfr | 44:e2bd06f94dc0 | 719 | but since our forceX, forceY are already computed in the orthonormal space I m not sure we need to |
Ludwigfr | 44:e2bd06f94dc0 | 720 | */ |
Ludwigfr | 44:e2bd06f94dc0 | 721 | *line_a=forceX; |
Ludwigfr | 44:e2bd06f94dc0 | 722 | *line_b=forceY; |
Ludwigfr | 44:e2bd06f94dc0 | 723 | //TODO check that |
Ludwigfr | 44:e2bd06f94dc0 | 724 | //because the line computed always pass by the robot center we dont need lince_c |
Ludwigfr | 44:e2bd06f94dc0 | 725 | //float xRobotOrtho=robot_center_x_in_orthonormal_x(); |
Ludwigfr | 44:e2bd06f94dc0 | 726 | //float yRobotOrtho=robot_center_y_in_orthonormal_y(); |
Ludwigfr | 44:e2bd06f94dc0 | 727 | //*line_c=forceX*yRobotOrtho+forceY*xRobotOrtho; |
Ludwigfr | 44:e2bd06f94dc0 | 728 | *line_c=0; |
Ludwigfr | 51:b863fad80574 | 729 | } |
Ludwigfr | 51:b863fad80574 | 730 | |
Ludwigfr | 51:b863fad80574 | 731 | /*angleToTarget is obtained through atan2 so it s: |
Ludwigfr | 51:b863fad80574 | 732 | < 0 if the angle is bettween pi and 2pi on a trigo circle |
Ludwigfr | 51:b863fad80574 | 733 | > 0 if it is between 0 and pi |
Ludwigfr | 51:b863fad80574 | 734 | */ |
Ludwigfr | 51:b863fad80574 | 735 | void turn_to_target(float angleToTarget){ |
Ludwigfr | 51:b863fad80574 | 736 | Odometria(); |
Ludwigfr | 51:b863fad80574 | 737 | float theta_plus_h_pi=theta+pi/2;//theta is between -pi and pi |
Ludwigfr | 51:b863fad80574 | 738 | if(theta_plus_h_pi > pi) |
Ludwigfr | 51:b863fad80574 | 739 | theta_plus_h_pi=-(2*pi-theta_plus_h_pi); |
Ludwigfr | 51:b863fad80574 | 740 | if(angleToTarget>0){ |
Ludwigfr | 51:b863fad80574 | 741 | leftMotor(0,1); |
Ludwigfr | 51:b863fad80574 | 742 | rightMotor(1,1); |
Ludwigfr | 51:b863fad80574 | 743 | }else{ |
Ludwigfr | 51:b863fad80574 | 744 | leftMotor(1,1); |
Ludwigfr | 51:b863fad80574 | 745 | rightMotor(0,1); |
Ludwigfr | 51:b863fad80574 | 746 | } |
Ludwigfr | 51:b863fad80574 | 747 | while(abs(angleToTarget-theta_plus_h_pi)>0.05){ |
Ludwigfr | 51:b863fad80574 | 748 | Odometria(); |
Ludwigfr | 51:b863fad80574 | 749 | theta_plus_h_pi=theta+pi/2;//theta is between -pi and pi |
Ludwigfr | 51:b863fad80574 | 750 | if(theta_plus_h_pi > pi) |
Ludwigfr | 51:b863fad80574 | 751 | theta_plus_h_pi=-(2*pi-theta_plus_h_pi); |
Ludwigfr | 51:b863fad80574 | 752 | //pc.printf("\n\r diff=%f", abs(angleToTarget-theta_plus_h_pi)); |
Ludwigfr | 51:b863fad80574 | 753 | } |
Ludwigfr | 51:b863fad80574 | 754 | leftMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 755 | rightMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 756 | } |
Ludwigfr | 51:b863fad80574 | 757 | |
Ludwigfr | 51:b863fad80574 | 758 | //currently line_c is not used |
Ludwigfr | 51:b863fad80574 | 759 | void go_to_line(float* angularLeft,float* angularRight,float line_a, float line_b, float line_c){ |
Ludwigfr | 51:b863fad80574 | 760 | float lineAngle; |
Ludwigfr | 51:b863fad80574 | 761 | float angleError; |
Ludwigfr | 51:b863fad80574 | 762 | float linear; |
Ludwigfr | 51:b863fad80574 | 763 | float angular; |
Ludwigfr | 51:b863fad80574 | 764 | |
Ludwigfr | 51:b863fad80574 | 765 | bool direction=true; |
Ludwigfr | 51:b863fad80574 | 766 | |
Ludwigfr | 51:b863fad80574 | 767 | float angleToTarget=atan2(targetYOrhtoNotMap,targetXOrhtoNotMap); |
Ludwigfr | 51:b863fad80574 | 768 | bool inFront=true; |
Ludwigfr | 51:b863fad80574 | 769 | if(angleToTarget < 0)//the target is in front |
Ludwigfr | 51:b863fad80574 | 770 | inFront=false; |
Ludwigfr | 51:b863fad80574 | 771 | |
Ludwigfr | 51:b863fad80574 | 772 | if(theta > 0){ |
Ludwigfr | 51:b863fad80574 | 773 | //the robot is oriented to the left |
Ludwigfr | 51:b863fad80574 | 774 | if(theta > pi/2){ |
Ludwigfr | 51:b863fad80574 | 775 | //the robot is oriented lower left |
Ludwigfr | 51:b863fad80574 | 776 | if(inFront) |
Ludwigfr | 51:b863fad80574 | 777 | direction=false;//robot and target not oriented the same way |
Ludwigfr | 51:b863fad80574 | 778 | }else{ |
Ludwigfr | 51:b863fad80574 | 779 | //the robot is oriented upper left |
Ludwigfr | 51:b863fad80574 | 780 | if(!inFront) |
Ludwigfr | 51:b863fad80574 | 781 | direction=false;//robot and target not oriented the same way |
Ludwigfr | 51:b863fad80574 | 782 | } |
Ludwigfr | 51:b863fad80574 | 783 | }else{ |
Ludwigfr | 51:b863fad80574 | 784 | //the robot is oriented to the right |
Ludwigfr | 51:b863fad80574 | 785 | if(theta < -pi/2){ |
Ludwigfr | 51:b863fad80574 | 786 | //the robot is oriented lower right |
Ludwigfr | 51:b863fad80574 | 787 | if(inFront) |
Ludwigfr | 51:b863fad80574 | 788 | direction=false;//robot and target not oriented the same way |
Ludwigfr | 51:b863fad80574 | 789 | }else{ |
Ludwigfr | 51:b863fad80574 | 790 | //the robot is oriented upper right |
Ludwigfr | 51:b863fad80574 | 791 | if(!inFront) |
Ludwigfr | 51:b863fad80574 | 792 | direction=false;//robot and target not oriented the same way |
Ludwigfr | 51:b863fad80574 | 793 | } |
Ludwigfr | 51:b863fad80574 | 794 | } |
Ludwigfr | 51:b863fad80574 | 795 | //pc.printf("\r\n Target is in front"); |
Ludwigfr | 51:b863fad80574 | 796 | |
Ludwigfr | 51:b863fad80574 | 797 | if(line_b!=0){ |
Ludwigfr | 51:b863fad80574 | 798 | if(!direction) |
Ludwigfr | 51:b863fad80574 | 799 | lineAngle=atan(-line_a/line_b); |
Ludwigfr | 51:b863fad80574 | 800 | else |
Ludwigfr | 51:b863fad80574 | 801 | lineAngle=atan(line_a/-line_b); |
Ludwigfr | 51:b863fad80574 | 802 | } |
Ludwigfr | 51:b863fad80574 | 803 | else{ |
Ludwigfr | 51:b863fad80574 | 804 | lineAngle=1.5708; |
Ludwigfr | 51:b863fad80574 | 805 | } |
Ludwigfr | 51:b863fad80574 | 806 | |
Ludwigfr | 51:b863fad80574 | 807 | //Computing angle error |
Ludwigfr | 51:b863fad80574 | 808 | angleError = lineAngle-theta; |
Ludwigfr | 51:b863fad80574 | 809 | angleError = atan(sin(angleError)/cos(angleError)); |
Ludwigfr | 51:b863fad80574 | 810 | |
Ludwigfr | 51:b863fad80574 | 811 | //Calculating velocities |
Ludwigfr | 51:b863fad80574 | 812 | linear=KV*(3.1416); |
Ludwigfr | 51:b863fad80574 | 813 | angular=KH*angleError; |
Ludwigfr | 51:b863fad80574 | 814 | |
Ludwigfr | 51:b863fad80574 | 815 | *angularLeft=(linear-0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
Ludwigfr | 51:b863fad80574 | 816 | *angularRight=(linear+0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
Ludwigfr | 51:b863fad80574 | 817 | |
Ludwigfr | 51:b863fad80574 | 818 | float aL=*angularLeft; |
Ludwigfr | 51:b863fad80574 | 819 | float aR=*angularRight; |
Ludwigfr | 51:b863fad80574 | 820 | //Normalize speed for motors |
Ludwigfr | 51:b863fad80574 | 821 | if(abs(*angularLeft)>abs(*angularRight)) { |
Ludwigfr | 51:b863fad80574 | 822 | *angularRight=MAX_SPEED*abs(aR/aL)*sign1(aR); |
Ludwigfr | 51:b863fad80574 | 823 | *angularLeft=MAX_SPEED*sign1(aL); |
Ludwigfr | 51:b863fad80574 | 824 | } |
Ludwigfr | 51:b863fad80574 | 825 | else { |
Ludwigfr | 51:b863fad80574 | 826 | *angularLeft=MAX_SPEED*abs(aL/aR)*sign1(aL); |
Ludwigfr | 51:b863fad80574 | 827 | *angularRight=MAX_SPEED*sign1(aR); |
Ludwigfr | 51:b863fad80574 | 828 | } |
Ludwigfr | 51:b863fad80574 | 829 | pc.printf("\r\n X=%f; Y=%f", robot_center_x_in_orthonormal_x(),robot_center_y_in_orthonormal_y()); |
Ludwigfr | 51:b863fad80574 | 830 | } |
Ludwigfr | 51:b863fad80574 | 831 | |
Ludwigfr | 51:b863fad80574 | 832 | //compute the force on X and Y |
Ludwigfr | 51:b863fad80574 | 833 | void compute_forceX_and_forceY(float* forceX, float* forceY){ |
Ludwigfr | 51:b863fad80574 | 834 | //we put the position of the robot in an orthonormal space |
Ludwigfr | 51:b863fad80574 | 835 | float xRobotOrtho=robot_center_x_in_orthonormal_x(); |
Ludwigfr | 51:b863fad80574 | 836 | float yRobotOrtho=robot_center_y_in_orthonormal_y(); |
Ludwigfr | 51:b863fad80574 | 837 | |
Ludwigfr | 51:b863fad80574 | 838 | float forceRepulsionComputedX=0; |
Ludwigfr | 51:b863fad80574 | 839 | float forceRepulsionComputedY=0; |
Ludwigfr | 51:b863fad80574 | 840 | //for each cell of the map we compute a force of repulsion |
Ludwigfr | 51:b863fad80574 | 841 | for(int i=0;i<NB_CELL_WIDTH;i++){ |
Ludwigfr | 51:b863fad80574 | 842 | for(int j=0;j<NB_CELL_HEIGHT;j++){ |
Ludwigfr | 51:b863fad80574 | 843 | update_force(i,j,RANGE_FORCE,&forceRepulsionComputedX,&forceRepulsionComputedY,xRobotOrtho,yRobotOrtho); |
Ludwigfr | 51:b863fad80574 | 844 | } |
Ludwigfr | 51:b863fad80574 | 845 | } |
Ludwigfr | 51:b863fad80574 | 846 | //update with attraction force |
Ludwigfr | 51:b863fad80574 | 847 | *forceX=+forceRepulsionComputedX; |
Ludwigfr | 51:b863fad80574 | 848 | *forceY=+forceRepulsionComputedY; |
Ludwigfr | 51:b863fad80574 | 849 | float distanceTargetRobot=sqrt(pow(targetXOrhto-xRobotOrtho,2)+pow(targetYOrhto-yRobotOrtho,2)); |
Ludwigfr | 51:b863fad80574 | 850 | if(distanceTargetRobot != 0){ |
Ludwigfr | 51:b863fad80574 | 851 | *forceX-=FORCE_CONSTANT_ATTRACTION*(targetXOrhto-xRobotOrtho)/distanceTargetRobot; |
Ludwigfr | 51:b863fad80574 | 852 | *forceY-=FORCE_CONSTANT_ATTRACTION*(targetYOrhto-yRobotOrtho)/distanceTargetRobot; |
Ludwigfr | 51:b863fad80574 | 853 | } |
Ludwigfr | 51:b863fad80574 | 854 | float amplitude=sqrt(pow(*forceX,2)+pow(*forceY,2)); |
Ludwigfr | 51:b863fad80574 | 855 | if(amplitude!=0){//avoid division by 0 if forceX and forceY == 0 |
Ludwigfr | 51:b863fad80574 | 856 | *forceX=*forceX/amplitude; |
Ludwigfr | 51:b863fad80574 | 857 | *forceY=*forceY/amplitude; |
Ludwigfr | 51:b863fad80574 | 858 | } |
Ludwigfr | 51:b863fad80574 | 859 | } |
Ludwigfr | 51:b863fad80574 | 860 | |
Ludwigfr | 51:b863fad80574 | 861 | //x and y passed are TargetNotMap |
Ludwigfr | 51:b863fad80574 | 862 | float get_error_angles(float x, float y,float theta){ |
Ludwigfr | 51:b863fad80574 | 863 | float angleBeetweenRobotAndTarget=atan2(y,x); |
Ludwigfr | 51:b863fad80574 | 864 | if(y > 0){ |
Ludwigfr | 51:b863fad80574 | 865 | if(angleBeetweenRobotAndTarget < pi/2)//up right |
Ludwigfr | 51:b863fad80574 | 866 | angleBeetweenRobotAndTarget=-pi/2+angleBeetweenRobotAndTarget; |
Ludwigfr | 51:b863fad80574 | 867 | else//up right |
Ludwigfr | 51:b863fad80574 | 868 | angleBeetweenRobotAndTarget=angleBeetweenRobotAndTarget-pi/2; |
Ludwigfr | 51:b863fad80574 | 869 | }else{ |
Ludwigfr | 51:b863fad80574 | 870 | if(angleBeetweenRobotAndTarget > -pi/2)//lower right |
Ludwigfr | 51:b863fad80574 | 871 | angleBeetweenRobotAndTarget=angleBeetweenRobotAndTarget-pi/2; |
Ludwigfr | 51:b863fad80574 | 872 | else//lower left |
Ludwigfr | 51:b863fad80574 | 873 | angleBeetweenRobotAndTarget=2*pi+angleBeetweenRobotAndTarget-pi/2; |
Ludwigfr | 51:b863fad80574 | 874 | } |
Ludwigfr | 51:b863fad80574 | 875 | return angleBeetweenRobotAndTarget-theta; |
Ludwigfr | 51:b863fad80574 | 876 | } |
Ludwigfr | 51:b863fad80574 | 877 | |
Ludwigfr | 51:b863fad80574 | 878 | void compute_angles_and_distance(float target_x, float target_y, float target_angle){ |
Ludwigfr | 51:b863fad80574 | 879 | alpha = atan2((target_y-Y),(target_x-X))-theta; |
Ludwigfr | 51:b863fad80574 | 880 | alpha = atan(sin(alpha)/cos(alpha)); |
Ludwigfr | 51:b863fad80574 | 881 | rho = dist(X, Y, target_x, target_y); |
Ludwigfr | 51:b863fad80574 | 882 | d2 = rho; |
Ludwigfr | 51:b863fad80574 | 883 | beta = -alpha-theta+target_angle; |
Ludwigfr | 51:b863fad80574 | 884 | |
Ludwigfr | 51:b863fad80574 | 885 | //Computing angle error and distance towards the target value |
Ludwigfr | 51:b863fad80574 | 886 | rho += dt*(-KRHO*cos(alpha)*rho); |
Ludwigfr | 51:b863fad80574 | 887 | temp = alpha; |
Ludwigfr | 51:b863fad80574 | 888 | alpha += dt*(KRHO*sin(alpha)-KA*alpha-KB*beta); |
Ludwigfr | 51:b863fad80574 | 889 | beta += dt*(-KRHO*sin(temp)); |
Ludwigfr | 51:b863fad80574 | 890 | //pc.printf("\n\r d2=%f", d2); |
Ludwigfr | 51:b863fad80574 | 891 | //pc.printf("\n\r dt=%f", dt); |
Ludwigfr | 51:b863fad80574 | 892 | } |
Ludwigfr | 51:b863fad80574 | 893 | |
Ludwigfr | 51:b863fad80574 | 894 | void compute_linear_angular_velocities(){ |
Ludwigfr | 51:b863fad80574 | 895 | //Computing linear and angular velocities |
Ludwigfr | 51:b863fad80574 | 896 | if(alpha>=-1.5708 && alpha<=1.5708){ |
Ludwigfr | 51:b863fad80574 | 897 | linear=KRHO*rho; |
Ludwigfr | 51:b863fad80574 | 898 | angular=KA*alpha+KB*beta; |
Ludwigfr | 51:b863fad80574 | 899 | } |
Ludwigfr | 51:b863fad80574 | 900 | else{ |
Ludwigfr | 51:b863fad80574 | 901 | linear=-KRHO*rho; |
Ludwigfr | 51:b863fad80574 | 902 | angular=-KA*alpha-KB*beta; |
Ludwigfr | 51:b863fad80574 | 903 | } |
Ludwigfr | 51:b863fad80574 | 904 | angular_left=(linear-0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
Ludwigfr | 51:b863fad80574 | 905 | angular_right=(linear+0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
Ludwigfr | 51:b863fad80574 | 906 | |
Ludwigfr | 51:b863fad80574 | 907 | //Normalize speed for motors |
Ludwigfr | 51:b863fad80574 | 908 | if(angular_left>angular_right) { |
Ludwigfr | 51:b863fad80574 | 909 | angular_right=MAX_SPEED*angular_right/angular_left; |
Ludwigfr | 51:b863fad80574 | 910 | angular_left=MAX_SPEED; |
Ludwigfr | 51:b863fad80574 | 911 | } else { |
Ludwigfr | 51:b863fad80574 | 912 | angular_left=MAX_SPEED*angular_left/angular_right; |
Ludwigfr | 51:b863fad80574 | 913 | angular_right=MAX_SPEED; |
Ludwigfr | 51:b863fad80574 | 914 | } |
Ludwigfr | 51:b863fad80574 | 915 | } |
Ludwigfr | 51:b863fad80574 | 916 | |
Ludwigfr | 51:b863fad80574 | 917 | //go the the given position while updating the map |
Ludwigfr | 51:b863fad80574 | 918 | void go_to_point_with_angle(float target_x, float target_y, float target_angle) { |
Ludwigfr | 51:b863fad80574 | 919 | Odometria(); |
Ludwigfr | 51:b863fad80574 | 920 | alpha = atan2((target_y-Y),(target_x-X))-theta; |
Ludwigfr | 51:b863fad80574 | 921 | alpha = atan(sin(alpha)/cos(alpha)); |
Ludwigfr | 51:b863fad80574 | 922 | rho = dist(X, Y, target_x, target_y); |
Ludwigfr | 51:b863fad80574 | 923 | beta = -alpha-theta+target_angle; |
Ludwigfr | 51:b863fad80574 | 924 | //beta = atan(sin(beta)/cos(beta)); |
Ludwigfr | 51:b863fad80574 | 925 | bool keep_going=true; |
Ludwigfr | 51:b863fad80574 | 926 | float leftMm; |
Ludwigfr | 51:b863fad80574 | 927 | float frontMm; |
Ludwigfr | 51:b863fad80574 | 928 | float rightMm; |
Ludwigfr | 51:b863fad80574 | 929 | do { |
Ludwigfr | 51:b863fad80574 | 930 | //Timer stuff |
Ludwigfr | 51:b863fad80574 | 931 | dt = t.read(); |
Ludwigfr | 51:b863fad80574 | 932 | t.reset(); |
Ludwigfr | 51:b863fad80574 | 933 | t.start(); |
Ludwigfr | 51:b863fad80574 | 934 | |
Ludwigfr | 51:b863fad80574 | 935 | //Updating X,Y and theta with the odometry values |
Ludwigfr | 51:b863fad80574 | 936 | Odometria(); |
Ludwigfr | 51:b863fad80574 | 937 | leftMm = get_distance_left_sensor(); |
Ludwigfr | 51:b863fad80574 | 938 | frontMm = get_distance_front_sensor(); |
Ludwigfr | 51:b863fad80574 | 939 | rightMm = get_distance_right_sensor(); |
Ludwigfr | 51:b863fad80574 | 940 | |
Ludwigfr | 51:b863fad80574 | 941 | //pc.printf("\n\r leftMm=%f", leftMm); |
Ludwigfr | 51:b863fad80574 | 942 | //pc.printf("\n\r frontMm=%f", frontMm); |
Ludwigfr | 51:b863fad80574 | 943 | //pc.printf("\n\r rightMm=%f", rightMm); |
Ludwigfr | 51:b863fad80574 | 944 | |
Ludwigfr | 51:b863fad80574 | 945 | //if in dangerzone |
Ludwigfr | 51:b863fad80574 | 946 | if((frontMm < 150 && frontMm > 0)|| (leftMm <150 && leftMm > 0) || (rightMm <150 && rightMm > 0) ){ |
Ludwigfr | 51:b863fad80574 | 947 | leftMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 948 | rightMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 949 | update_sonar_values(leftMm, frontMm, rightMm); |
Ludwigfr | 51:b863fad80574 | 950 | //TODO Giorgos maybe you can also test the do_half_flip() function |
Ludwigfr | 51:b863fad80574 | 951 | Odometria(); |
Ludwigfr | 51:b863fad80574 | 952 | //do a flip TODO |
Ludwigfr | 51:b863fad80574 | 953 | keep_going=false; |
Ludwigfr | 51:b863fad80574 | 954 | do_half_flip(); |
Ludwigfr | 51:b863fad80574 | 955 | }else{ |
Ludwigfr | 51:b863fad80574 | 956 | //if not in danger zone continue as usual |
Ludwigfr | 51:b863fad80574 | 957 | update_sonar_values(leftMm, frontMm, rightMm); |
Ludwigfr | 51:b863fad80574 | 958 | compute_angles_and_distance(target_x, target_y, target_angle); //Compute the angles and the distance from target |
Ludwigfr | 51:b863fad80574 | 959 | compute_linear_angular_velocities(); //Using the angles and distance, compute the velocities needed (linear & angular) |
Ludwigfr | 51:b863fad80574 | 960 | |
Ludwigfr | 51:b863fad80574 | 961 | //pc.printf("\n\r X=%f", X); |
Ludwigfr | 51:b863fad80574 | 962 | //pc.printf("\n\r Y=%f", Y); |
Ludwigfr | 51:b863fad80574 | 963 | |
Ludwigfr | 51:b863fad80574 | 964 | //pc.printf("\n\r a_r=%f", angular_right); |
Ludwigfr | 51:b863fad80574 | 965 | //pc.printf("\n\r a_l=%f", angular_left); |
Ludwigfr | 51:b863fad80574 | 966 | |
Ludwigfr | 51:b863fad80574 | 967 | //Updating motor velocities |
Ludwigfr | 51:b863fad80574 | 968 | leftMotor(1,angular_left); |
Ludwigfr | 51:b863fad80574 | 969 | rightMotor(1,angular_right); |
Ludwigfr | 51:b863fad80574 | 970 | |
Ludwigfr | 51:b863fad80574 | 971 | wait(0.2); |
Ludwigfr | 51:b863fad80574 | 972 | //Timer stuff |
Ludwigfr | 51:b863fad80574 | 973 | t.stop(); |
Ludwigfr | 51:b863fad80574 | 974 | pc.printf("\n\r dist to target= %f",d2); |
Ludwigfr | 51:b863fad80574 | 975 | } |
Ludwigfr | 51:b863fad80574 | 976 | } while(d2>1 && (abs(target_angle-theta)>0.01) && keep_going); |
Ludwigfr | 51:b863fad80574 | 977 | |
Ludwigfr | 51:b863fad80574 | 978 | //Stop at the end |
Ludwigfr | 51:b863fad80574 | 979 | leftMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 980 | rightMotor(1,0); |
Ludwigfr | 51:b863fad80574 | 981 | } |
Ludwigfr | 51:b863fad80574 | 982 | |
Ludwigfr | 51:b863fad80574 | 983 | //Updates sonar values |
Ludwigfr | 51:b863fad80574 | 984 | void update_sonar_values(float leftMm, float frontMm, float rightMm){ |
Ludwigfr | 51:b863fad80574 | 985 | if(leftMm==0) |
Ludwigfr | 51:b863fad80574 | 986 | pc.printf("\n\r leftMm==0"); |
Ludwigfr | 51:b863fad80574 | 987 | if(frontMm==0) |
Ludwigfr | 51:b863fad80574 | 988 | pc.printf("\n\r frontMm==0"); |
Ludwigfr | 51:b863fad80574 | 989 | if(rightMm==0) |
Ludwigfr | 51:b863fad80574 | 990 | pc.printf("\n\r rightMm==0"); |
Ludwigfr | 51:b863fad80574 | 991 | float currProba; |
Ludwigfr | 51:b863fad80574 | 992 | float i_in_orthonormal; |
Ludwigfr | 51:b863fad80574 | 993 | float j_in_orthonormal; |
Ludwigfr | 51:b863fad80574 | 994 | for(int i=0;i<NB_CELL_WIDTH;i++){ |
Ludwigfr | 51:b863fad80574 | 995 | for(int j=0;j<NB_CELL_HEIGHT;j++){ |
Ludwigfr | 51:b863fad80574 | 996 | //check if the point A(x,y) in the world space is within the range of the sonar (which has the coordinates xs, ys in the world space) |
Ludwigfr | 51:b863fad80574 | 997 | //check that again |
Ludwigfr | 51:b863fad80574 | 998 | //compute for front sonar |
Ludwigfr | 51:b863fad80574 | 999 | i_in_orthonormal=estimated_width_indice_in_orthonormal_x(i); |
Ludwigfr | 51:b863fad80574 | 1000 | j_in_orthonormal=estimated_height_indice_in_orthonormal_y(j); |
Ludwigfr | 51:b863fad80574 | 1001 | |
Ludwigfr | 51:b863fad80574 | 1002 | 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); |
Ludwigfr | 51:b863fad80574 | 1003 | 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 | 51:b863fad80574 | 1004 | //compute for right sonar |
Ludwigfr | 51:b863fad80574 | 1005 | 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); |
Ludwigfr | 51:b863fad80574 | 1006 | map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j]; |
Ludwigfr | 51:b863fad80574 | 1007 | //compute for left sonar |
Ludwigfr | 51:b863fad80574 | 1008 | 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); |
Ludwigfr | 51:b863fad80574 | 1009 | map[i][j]=map[i][j]+proba_to_log(currProba)+initialLogValues[i][j]; |
Ludwigfr | 51:b863fad80574 | 1010 | } |
Ludwigfr | 51:b863fad80574 | 1011 | } |
geotsam | 52:54b3fe68a4f2 | 1012 | } |
geotsam | 52:54b3fe68a4f2 | 1013 | |
geotsam | 52:54b3fe68a4f2 | 1014 | |
geotsam | 52:54b3fe68a4f2 | 1015 | //Go to a given X,Y position, regardless of the final angle |
geotsam | 52:54b3fe68a4f2 | 1016 | void go_to_point(float target_x, float target_y){ |
geotsam | 52:54b3fe68a4f2 | 1017 | float angle_error; //angle error |
geotsam | 52:54b3fe68a4f2 | 1018 | float d; //distance from target |
geotsam | 52:54b3fe68a4f2 | 1019 | float k_linear=10, k_angular=200; |
geotsam | 52:54b3fe68a4f2 | 1020 | |
geotsam | 52:54b3fe68a4f2 | 1021 | do { |
geotsam | 52:54b3fe68a4f2 | 1022 | //Updating X,Y and theta with the odometry values |
geotsam | 52:54b3fe68a4f2 | 1023 | Odometria(); |
geotsam | 52:54b3fe68a4f2 | 1024 | |
geotsam | 52:54b3fe68a4f2 | 1025 | //Computing angle error and distance towards the target value |
geotsam | 52:54b3fe68a4f2 | 1026 | angle_error = atan2((target_y-Y),(target_x-X))-theta; |
geotsam | 52:54b3fe68a4f2 | 1027 | angle_error = atan(sin(angle_error)/cos(angle_error)); |
geotsam | 52:54b3fe68a4f2 | 1028 | d=dist(X, Y, target_x, target_y); |
geotsam | 52:54b3fe68a4f2 | 1029 | |
geotsam | 52:54b3fe68a4f2 | 1030 | //Computing linear and angular velocities |
geotsam | 52:54b3fe68a4f2 | 1031 | linear=k_linear*d; |
geotsam | 52:54b3fe68a4f2 | 1032 | angular=k_angular*angle_error; |
geotsam | 52:54b3fe68a4f2 | 1033 | angular_left=(linear-0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
geotsam | 52:54b3fe68a4f2 | 1034 | angular_right=(linear+0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
geotsam | 52:54b3fe68a4f2 | 1035 | |
geotsam | 52:54b3fe68a4f2 | 1036 | |
geotsam | 52:54b3fe68a4f2 | 1037 | //Normalize speed for motors |
geotsam | 52:54b3fe68a4f2 | 1038 | if(angular_left>angular_right) { |
geotsam | 52:54b3fe68a4f2 | 1039 | angular_right=MAX_SPEED*angular_right/angular_left; |
geotsam | 52:54b3fe68a4f2 | 1040 | angular_left=MAX_SPEED; |
geotsam | 52:54b3fe68a4f2 | 1041 | } else { |
geotsam | 52:54b3fe68a4f2 | 1042 | angular_left=MAX_SPEED*angular_left/angular_right; |
geotsam | 52:54b3fe68a4f2 | 1043 | angular_right=MAX_SPEED; |
geotsam | 52:54b3fe68a4f2 | 1044 | } |
geotsam | 52:54b3fe68a4f2 | 1045 | |
geotsam | 52:54b3fe68a4f2 | 1046 | pc.printf("\n\r X=%f", X); |
geotsam | 52:54b3fe68a4f2 | 1047 | pc.printf("\n\r Y=%f", Y); |
geotsam | 52:54b3fe68a4f2 | 1048 | |
geotsam | 52:54b3fe68a4f2 | 1049 | //Updating motor velocities |
geotsam | 52:54b3fe68a4f2 | 1050 | leftMotor(1,angular_left); |
geotsam | 52:54b3fe68a4f2 | 1051 | rightMotor(1,angular_right); |
geotsam | 52:54b3fe68a4f2 | 1052 | |
geotsam | 52:54b3fe68a4f2 | 1053 | wait(0.5); |
geotsam | 52:54b3fe68a4f2 | 1054 | } while(d>1); |
geotsam | 52:54b3fe68a4f2 | 1055 | |
geotsam | 52:54b3fe68a4f2 | 1056 | //Stop at the end |
geotsam | 52:54b3fe68a4f2 | 1057 | leftMotor(1,0); |
geotsam | 52:54b3fe68a4f2 | 1058 | rightMotor(1,0); |
geotsam | 52:54b3fe68a4f2 | 1059 | } |
geotsam | 52:54b3fe68a4f2 | 1060 | |
geotsam | 52:54b3fe68a4f2 | 1061 | //go to line and follow it, from lab 1 |
geotsam | 52:54b3fe68a4f2 | 1062 | void go_to_line_lab_1(float line_a, float line_b, float line_c){ |
geotsam | 52:54b3fe68a4f2 | 1063 | |
geotsam | 52:54b3fe68a4f2 | 1064 | float angle_error; //angle error |
geotsam | 52:54b3fe68a4f2 | 1065 | float d; //distance from line |
geotsam | 52:54b3fe68a4f2 | 1066 | float kd=5, kh=200, kv=200; |
geotsam | 52:54b3fe68a4f2 | 1067 | float linear, angular, angular_left, angular_right; |
geotsam | 52:54b3fe68a4f2 | 1068 | float line_angle; |
geotsam | 52:54b3fe68a4f2 | 1069 | |
geotsam | 52:54b3fe68a4f2 | 1070 | //Check if b=0, if yes line_angle=90 |
geotsam | 52:54b3fe68a4f2 | 1071 | if(line_b!=0){ |
geotsam | 52:54b3fe68a4f2 | 1072 | line_angle=atan(-line_a/line_b); |
geotsam | 52:54b3fe68a4f2 | 1073 | } |
geotsam | 52:54b3fe68a4f2 | 1074 | else{ |
geotsam | 52:54b3fe68a4f2 | 1075 | line_angle=1.5708; |
geotsam | 52:54b3fe68a4f2 | 1076 | } |
geotsam | 52:54b3fe68a4f2 | 1077 | |
geotsam | 52:54b3fe68a4f2 | 1078 | do { |
geotsam | 52:54b3fe68a4f2 | 1079 | pc.printf("\n\n\r entered while"); |
geotsam | 52:54b3fe68a4f2 | 1080 | |
geotsam | 52:54b3fe68a4f2 | 1081 | //Updating X,Y and theta with the odometry values |
geotsam | 52:54b3fe68a4f2 | 1082 | Odometria(); |
geotsam | 52:54b3fe68a4f2 | 1083 | |
geotsam | 52:54b3fe68a4f2 | 1084 | //Computing angle error and distance from the target line |
geotsam | 52:54b3fe68a4f2 | 1085 | angle_error = line_angle-theta; |
geotsam | 52:54b3fe68a4f2 | 1086 | angle_error = atan(sin(angle_error)/cos(angle_error)); |
geotsam | 52:54b3fe68a4f2 | 1087 | d=distFromLine(X, Y, line_a, line_b, line_c); |
geotsam | 52:54b3fe68a4f2 | 1088 | pc.printf("\n\r d=%f", d); |
geotsam | 52:54b3fe68a4f2 | 1089 | |
geotsam | 52:54b3fe68a4f2 | 1090 | //Calculating velocities |
geotsam | 52:54b3fe68a4f2 | 1091 | linear=kv*(3.1416-angle_error); |
geotsam | 52:54b3fe68a4f2 | 1092 | angular=-kd*d+kh*angle_error; |
geotsam | 52:54b3fe68a4f2 | 1093 | angular_left=(linear-0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
geotsam | 52:54b3fe68a4f2 | 1094 | angular_right=(linear+0.5*DISTANCE_WHEELS*angular)/RADIUS_WHEELS; |
geotsam | 52:54b3fe68a4f2 | 1095 | |
geotsam | 52:54b3fe68a4f2 | 1096 | //Normalize MAX_SPEED for motors |
geotsam | 52:54b3fe68a4f2 | 1097 | if(angular_left>angular_right) { |
geotsam | 52:54b3fe68a4f2 | 1098 | angular_right=MAX_SPEED*angular_right/angular_left; |
geotsam | 52:54b3fe68a4f2 | 1099 | angular_left=MAX_SPEED; |
geotsam | 52:54b3fe68a4f2 | 1100 | } |
geotsam | 52:54b3fe68a4f2 | 1101 | else { |
geotsam | 52:54b3fe68a4f2 | 1102 | angular_left=MAX_SPEED*angular_left/angular_right; |
geotsam | 52:54b3fe68a4f2 | 1103 | angular_right=MAX_SPEED; |
geotsam | 52:54b3fe68a4f2 | 1104 | } |
geotsam | 52:54b3fe68a4f2 | 1105 | |
geotsam | 52:54b3fe68a4f2 | 1106 | //Updating motor velocities |
geotsam | 52:54b3fe68a4f2 | 1107 | if(angular_left>0){ |
geotsam | 52:54b3fe68a4f2 | 1108 | leftMotor(1,angular_left); |
geotsam | 52:54b3fe68a4f2 | 1109 | } |
geotsam | 52:54b3fe68a4f2 | 1110 | else{ |
geotsam | 52:54b3fe68a4f2 | 1111 | leftMotor(0,-angular_left); |
geotsam | 52:54b3fe68a4f2 | 1112 | } |
geotsam | 52:54b3fe68a4f2 | 1113 | |
geotsam | 52:54b3fe68a4f2 | 1114 | if(angular_right>0){ |
geotsam | 52:54b3fe68a4f2 | 1115 | rightMotor(1,angular_right); |
geotsam | 52:54b3fe68a4f2 | 1116 | } |
geotsam | 52:54b3fe68a4f2 | 1117 | else{ |
geotsam | 52:54b3fe68a4f2 | 1118 | rightMotor(0,-angular_right); |
geotsam | 52:54b3fe68a4f2 | 1119 | } |
geotsam | 52:54b3fe68a4f2 | 1120 | |
geotsam | 52:54b3fe68a4f2 | 1121 | wait(0.5); |
geotsam | 52:54b3fe68a4f2 | 1122 | } while(1); |
geotsam | 52:54b3fe68a4f2 | 1123 | } |
geotsam | 52:54b3fe68a4f2 | 1124 | |
geotsam | 52:54b3fe68a4f2 | 1125 | float distFromLine(float robot_x, float robot_y, float line_a, float line_b, float line_c){ |
geotsam | 52:54b3fe68a4f2 | 1126 | return abs((line_a*robot_x+line_b*robot_y+line_c)/sqrt(line_a*line_a+line_b*line_b)); |
geotsam | 24:8f4b820d8de8 | 1127 | } |