vaLLEY TRY
Dependencies: mbed
main.cpp@6:2cd6ae395c0f, 2019-04-05 (annotated)
- Committer:
- shut
- Date:
- Fri Apr 05 14:28:09 2019 +0000
- Revision:
- 6:2cd6ae395c0f
- Parent:
- 5:1649f59c37de
- Child:
- 7:3a755ebe4eaf
retwerwer
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jsobiecki | 0:719ea21609f1 | 1 | #include "mbed.h" |
jsobiecki | 0:719ea21609f1 | 2 | #include "Robot.h" |
jsobiecki | 0:719ea21609f1 | 3 | #include "math.h" |
jsobiecki | 4:5a892f5ab5a8 | 4 | #include "ActiveCell.h" |
jsobiecki | 4:5a892f5ab5a8 | 5 | #include "HistogramCell.h" |
jsobiecki | 0:719ea21609f1 | 6 | #define M_PI 3.14159265358979323846 |
jsobiecki | 0:719ea21609f1 | 7 | //EXERCICIO 1 |
jsobiecki | 0:719ea21609f1 | 8 | //Luis Cruz N2011164454 |
jsobiecki | 4:5a892f5ab5a8 | 9 | //Jacek Sobecki N2018319609 |
jsobiecki | 0:719ea21609f1 | 10 | Serial pc(SERIAL_TX, SERIAL_RX, 115200); |
jsobiecki | 0:719ea21609f1 | 11 | DigitalIn button(PC_13); |
jsobiecki | 0:719ea21609f1 | 12 | void poseEst(float p[], float radius, float enc_res, float b); |
jsobiecki | 0:719ea21609f1 | 13 | void SpeedLim(float w[]); |
jsobiecki | 4:5a892f5ab5a8 | 14 | void initializeArrays(); |
jsobiecki | 4:5a892f5ab5a8 | 15 | void calcForce(); |
shut | 6:2cd6ae395c0f | 16 | void sumForces(); |
shut | 6:2cd6ae395c0f | 17 | void updateActive(float xR, float yR); |
shut | 2:c507076bfd93 | 18 | //int ReadSensors(); |
jsobiecki | 5:1649f59c37de | 19 | //const int m = 200, n = 200, activeSize = 11; |
shut | 6:2cd6ae395c0f | 20 | //histogram size | aSize active region size |
shut | 6:2cd6ae395c0f | 21 | const int hSize = 80, aSize = 11; |
jsobiecki | 4:5a892f5ab5a8 | 22 | ActiveCell activeReg[aSize][aSize]; |
jsobiecki | 4:5a892f5ab5a8 | 23 | HistogramCell histogram[hSize][hSize]; |
jsobiecki | 5:1649f59c37de | 24 | //Repulsive force sums |
shut | 6:2cd6ae395c0f | 25 | float p[3], p_obj[3], p_final[3], fX, fY; |
shut | 6:2cd6ae395c0f | 26 | const float Fca=6;/*5*/ |
jsobiecki | 0:719ea21609f1 | 27 | int main(){ |
jsobiecki | 0:719ea21609f1 | 28 | |
jsobiecki | 0:719ea21609f1 | 29 | button.mode(PullUp); |
jsobiecki | 0:719ea21609f1 | 30 | getCountsAndReset(); |
jsobiecki | 0:719ea21609f1 | 31 | setSpeeds(0, 0); |
jsobiecki | 4:5a892f5ab5a8 | 32 | initializeArrays(); |
jsobiecki | 0:719ea21609f1 | 33 | while(button==1); |
shut | 6:2cd6ae395c0f | 34 | //w[0] = Omega | w[1] = Left | w[2] = Right |
jsobiecki | 0:719ea21609f1 | 35 | //p[0] = X | p[1] = Y | p[2] = Theta |
jsobiecki | 0:719ea21609f1 | 36 | //p_obj[0] = X | p_obj[1] = Y | p_obj[2] = Theta |
jsobiecki | 0:719ea21609f1 | 37 | //b = Distance between wheels, enc_res = Encoder Resolution, v = Calculated speed |
jsobiecki | 0:719ea21609f1 | 38 | //k_v = Speed gain, k_s = Curvature gain, wratio = Angular speed ratio control command |
shut | 2:c507076bfd93 | 39 | //Cells dim: 5x5cm | |
shut | 6:2cd6ae395c0f | 40 | float w[3], v, theta, theta_error, err, integral = 0.0, k_i = 0.01/*0.02*/; |
shut | 6:2cd6ae395c0f | 41 | const float radius = 3.5, b = 13.3, enc_res = 1440, k_v = 8/*7*/, |
shut | 6:2cd6ae395c0f | 42 | k_s = 12/*10*/, sample_time = 0.05, d_stalker = 7.5, k_f = 2.5; /*2.5*/ VFF |
jsobiecki | 0:719ea21609f1 | 43 | // =============================================================================== |
jsobiecki | 0:719ea21609f1 | 44 | // =================================== COORDS ==================================== |
shut | 2:c507076bfd93 | 45 | // =============================================================================== |
jsobiecki | 0:719ea21609f1 | 46 | //Target coordinates |
shut | 6:2cd6ae395c0f | 47 | p_final[0] = 150, p_final[1] = 200, p_final[2] = 0; |
shut | 6:2cd6ae395c0f | 48 | //p_obj[0] = 20, p_obj[1] = 20, p_obj[2] = 0; |
jsobiecki | 0:719ea21609f1 | 49 | //Initial coordinates: |
shut | 6:2cd6ae395c0f | 50 | p[0] = 95, p[1] = 20, p[2] = 0; |
jsobiecki | 0:719ea21609f1 | 51 | // =============================================================================== |
jsobiecki | 0:719ea21609f1 | 52 | // =================================== EXECUTION ================================= |
jsobiecki | 0:719ea21609f1 | 53 | // =============================================================================== |
jsobiecki | 0:719ea21609f1 | 54 | while(1){ |
jsobiecki | 0:719ea21609f1 | 55 | getCountsAndReset(); |
jsobiecki | 0:719ea21609f1 | 56 | pc.printf("Speeds: Left=%lf Right=%lf\n", w[1], w[2]); |
shut | 6:2cd6ae395c0f | 57 | pc.printf("OBJECTIVE X: %lf OBJECTIVE Y: %lf\n", p_obj[0], p_obj[1]); |
shut | 6:2cd6ae395c0f | 58 | pc.printf("Position: X=%lf Y=%lf Theta=%lf\n\n", p[0], p[1], p[2]); |
shut | 6:2cd6ae395c0f | 59 | pc.printf("Force (X): X=%lf Force(Y)=%lf\n", fX, fY); |
shut | 2:c507076bfd93 | 60 | |
jsobiecki | 0:719ea21609f1 | 61 | //Path calculation |
shut | 2:c507076bfd93 | 62 | poseEst(p, radius, enc_res, b); //Pose estimation |
shut | 6:2cd6ae395c0f | 63 | updateActive(p[0], p[1]); |
shut | 6:2cd6ae395c0f | 64 | p_obj[0] = p[0]+k_f*fX; // add parameter to relate chosen direction (VFH) to the point nearby of the robot |
shut | 6:2cd6ae395c0f | 65 | p_obj[1] = p[1]+k_f*fY; |
shut | 2:c507076bfd93 | 66 | //Control Law |
shut | 2:c507076bfd93 | 67 | err = sqrt(pow((p_obj[0]-p[0]),2)+pow((p_obj[1]-p[1]),2)) - d_stalker; //distance to the point |
jsobiecki | 0:719ea21609f1 | 68 | theta = atan2(p_obj[1]-p[1],p_obj[0]-p[0]); |
jsobiecki | 0:719ea21609f1 | 69 | theta = atan2(sin(theta),cos(theta)); |
jsobiecki | 0:719ea21609f1 | 70 | p[2] = atan2(sin(p[2]),cos(p[2])); |
jsobiecki | 0:719ea21609f1 | 71 | theta_error = theta-p[2]; |
shut | 2:c507076bfd93 | 72 | w[0] = k_s*(theta_error); //direction gain |
jsobiecki | 4:5a892f5ab5a8 | 73 | integral += err; |
shut | 6:2cd6ae395c0f | 74 | v = k_v*err+k_i*integral; //Speed calculation |
jsobiecki | 0:719ea21609f1 | 75 | w[1] = (v-(b/2)*w[0])/radius; |
jsobiecki | 0:719ea21609f1 | 76 | w[2] = (v+(b/2)*w[0])/radius; |
jsobiecki | 0:719ea21609f1 | 77 | SpeedLim(w); |
shut | 6:2cd6ae395c0f | 78 | //if((fabs(p[0]-p_final[0])+fabs(p[1]-p_final[1])) < 70) k_i = -0.005; |
shut | 6:2cd6ae395c0f | 79 | if((fabs(p[0]-p_final[0])+fabs(p[1]-p_final[1])) < 4){ |
jsobiecki | 0:719ea21609f1 | 80 | setSpeeds(0,0); |
jsobiecki | 0:719ea21609f1 | 81 | } |
jsobiecki | 0:719ea21609f1 | 82 | else{ |
jsobiecki | 0:719ea21609f1 | 83 | setSpeeds(w[1], w[2]); |
jsobiecki | 0:719ea21609f1 | 84 | } |
jsobiecki | 0:719ea21609f1 | 85 | wait(sample_time); |
jsobiecki | 0:719ea21609f1 | 86 | } |
jsobiecki | 0:719ea21609f1 | 87 | } |
jsobiecki | 0:719ea21609f1 | 88 | // =============================================================================== |
jsobiecki | 0:719ea21609f1 | 89 | // =================================== FUNCTIONS ================================= |
jsobiecki | 0:719ea21609f1 | 90 | // =============================================================================== |
jsobiecki | 0:719ea21609f1 | 91 | //Pose Estimation function |
jsobiecki | 0:719ea21609f1 | 92 | void poseEst(float p[], float radius, float enc_res, float b){ |
jsobiecki | 0:719ea21609f1 | 93 | float deltaDl, deltaDr, deltaD, deltaT; |
jsobiecki | 0:719ea21609f1 | 94 | deltaDl = ((float)countsLeft)*(2.0*M_PI*radius/enc_res); |
jsobiecki | 0:719ea21609f1 | 95 | deltaDr = ((float)countsRight)*(2.0*M_PI*radius/enc_res); |
jsobiecki | 0:719ea21609f1 | 96 | deltaD = (deltaDr + deltaDl)/2; |
jsobiecki | 0:719ea21609f1 | 97 | deltaT = (deltaDr - deltaDl)/b; |
jsobiecki | 0:719ea21609f1 | 98 | if(fabs(deltaT) == 0){ |
jsobiecki | 0:719ea21609f1 | 99 | p[0] = p[0] + deltaD*cos(p[2]) + deltaT/2; |
jsobiecki | 0:719ea21609f1 | 100 | p[1] = p[1] + deltaD*sin(p[2]) + deltaT/2; |
jsobiecki | 0:719ea21609f1 | 101 | return; |
jsobiecki | 0:719ea21609f1 | 102 | } |
jsobiecki | 0:719ea21609f1 | 103 | p[0] = p[0] + deltaD*(sin(deltaT/2.0f)/(deltaT/2.0f))*cos(p[2]+deltaT/2.0f); |
jsobiecki | 0:719ea21609f1 | 104 | p[1] = p[1] + deltaD*(sin(deltaT/2.0f)/(deltaT/2.0f))*sin(p[2]+deltaT/2.0f); |
jsobiecki | 0:719ea21609f1 | 105 | p[2] = p[2] + deltaT; |
jsobiecki | 0:719ea21609f1 | 106 | } |
jsobiecki | 0:719ea21609f1 | 107 | //Speed limiter function |
jsobiecki | 0:719ea21609f1 | 108 | void SpeedLim(float w[]){ |
jsobiecki | 0:719ea21609f1 | 109 | float wratio; |
shut | 6:2cd6ae395c0f | 110 | wratio = fabs(w[2]/w[1]); |
jsobiecki | 0:719ea21609f1 | 111 | if(w[2] > 150 || w[1] > 150){ |
jsobiecki | 0:719ea21609f1 | 112 | if(wratio < 1){ |
jsobiecki | 0:719ea21609f1 | 113 | w[1] = 150; |
jsobiecki | 0:719ea21609f1 | 114 | w[2] = w[1]*wratio; |
jsobiecki | 0:719ea21609f1 | 115 | } |
jsobiecki | 0:719ea21609f1 | 116 | else if(wratio > 1){ |
jsobiecki | 0:719ea21609f1 | 117 | w[2] = 150; |
jsobiecki | 0:719ea21609f1 | 118 | w[1] = w[2]/wratio; |
jsobiecki | 0:719ea21609f1 | 119 | } |
jsobiecki | 0:719ea21609f1 | 120 | else{ |
jsobiecki | 0:719ea21609f1 | 121 | w[2] = 150; |
jsobiecki | 0:719ea21609f1 | 122 | w[1] = 150; |
jsobiecki | 0:719ea21609f1 | 123 | } |
jsobiecki | 0:719ea21609f1 | 124 | } |
jsobiecki | 0:719ea21609f1 | 125 | if(w[2] < 50 || w[1] < 50){ |
jsobiecki | 0:719ea21609f1 | 126 | if(wratio < 1){ |
jsobiecki | 0:719ea21609f1 | 127 | w[1] = 50; |
jsobiecki | 0:719ea21609f1 | 128 | w[2] = w[1]*wratio; |
jsobiecki | 0:719ea21609f1 | 129 | } |
jsobiecki | 0:719ea21609f1 | 130 | else if(wratio > 1){ |
jsobiecki | 0:719ea21609f1 | 131 | w[2] = 50; |
jsobiecki | 0:719ea21609f1 | 132 | w[1] = w[2]/wratio; |
jsobiecki | 0:719ea21609f1 | 133 | } |
jsobiecki | 0:719ea21609f1 | 134 | else{ |
jsobiecki | 0:719ea21609f1 | 135 | w[2] = 50; |
jsobiecki | 0:719ea21609f1 | 136 | w[1] = 50; |
jsobiecki | 0:719ea21609f1 | 137 | } |
jsobiecki | 0:719ea21609f1 | 138 | } |
jsobiecki | 0:719ea21609f1 | 139 | } |
jsobiecki | 4:5a892f5ab5a8 | 140 | |
jsobiecki | 4:5a892f5ab5a8 | 141 | void initializeArrays() { |
jsobiecki | 4:5a892f5ab5a8 | 142 | for (int i = 0; i < hSize; i++) { |
jsobiecki | 4:5a892f5ab5a8 | 143 | for (int j = 0; j < hSize; j++) { |
jsobiecki | 4:5a892f5ab5a8 | 144 | histogram[i][j].calculate(i, j); |
shut | 6:2cd6ae395c0f | 145 | if(i>15 && i<25 && j > 15 && j<25) |
shut | 6:2cd6ae395c0f | 146 | histogram[i][j].cellVal=5; |
jsobiecki | 4:5a892f5ab5a8 | 147 | } |
jsobiecki | 4:5a892f5ab5a8 | 148 | } |
jsobiecki | 4:5a892f5ab5a8 | 149 | for (int i = 0; i < aSize; i++) { |
jsobiecki | 4:5a892f5ab5a8 | 150 | for (int j = 0; j < aSize; j++) { |
jsobiecki | 4:5a892f5ab5a8 | 151 | activeReg[i][j].calDist(i, j); |
jsobiecki | 4:5a892f5ab5a8 | 152 | } |
jsobiecki | 4:5a892f5ab5a8 | 153 | } |
jsobiecki | 4:5a892f5ab5a8 | 154 | } |
jsobiecki | 4:5a892f5ab5a8 | 155 | void calcForce(){ |
jsobiecki | 4:5a892f5ab5a8 | 156 | for (int i = 0; i < aSize; i++) { |
jsobiecki | 4:5a892f5ab5a8 | 157 | for (int j = 0; j < aSize; j++) { |
jsobiecki | 4:5a892f5ab5a8 | 158 | activeReg[i][j].calForce(); |
jsobiecki | 4:5a892f5ab5a8 | 159 | } |
jsobiecki | 4:5a892f5ab5a8 | 160 | } |
jsobiecki | 5:1649f59c37de | 161 | activeReg[5][5].forceX=0; |
jsobiecki | 5:1649f59c37de | 162 | activeReg[5][5].forceY=0; |
jsobiecki | 4:5a892f5ab5a8 | 163 | } |
jsobiecki | 5:1649f59c37de | 164 | //every time robot changes position we need to call this function to update active region and calculate forces |
jsobiecki | 4:5a892f5ab5a8 | 165 | //xR, yR - robots position in coordinates system |
shut | 6:2cd6ae395c0f | 166 | void updateActive(float xR, float yR) { |
jsobiecki | 4:5a892f5ab5a8 | 167 | int idXr = 0; |
jsobiecki | 4:5a892f5ab5a8 | 168 | int idYr = 0; |
jsobiecki | 4:5a892f5ab5a8 | 169 | for (int i = 0; i < hSize; i++) { |
jsobiecki | 4:5a892f5ab5a8 | 170 | for (int j = 0; j < hSize; j++) { |
shut | 6:2cd6ae395c0f | 171 | if (xR > histogram[i][j].x - 2.5f && xR < histogram[i][j].x + 2.5f && yR > histogram[i][j].y - 2.5f && |
shut | 6:2cd6ae395c0f | 172 | yR < histogram[i][j].y + 2.5f) { |
jsobiecki | 4:5a892f5ab5a8 | 173 | idXr = i; |
jsobiecki | 4:5a892f5ab5a8 | 174 | idYr = j; |
jsobiecki | 4:5a892f5ab5a8 | 175 | break; |
shut | 2:c507076bfd93 | 176 | } |
shut | 2:c507076bfd93 | 177 | } |
shut | 2:c507076bfd93 | 178 | } |
jsobiecki | 4:5a892f5ab5a8 | 179 | int m = idXr - aSize / 2; |
jsobiecki | 4:5a892f5ab5a8 | 180 | for (int k = 0; k < aSize; k++) { |
jsobiecki | 4:5a892f5ab5a8 | 181 | int n = idYr - aSize / 2; |
jsobiecki | 4:5a892f5ab5a8 | 182 | for (int l = 0; l < aSize; l++) { |
shut | 6:2cd6ae395c0f | 183 | if(m >= 0 && n >= 0 && m < hSize && n < hSize) { |
jsobiecki | 4:5a892f5ab5a8 | 184 | activeReg[k][l].cellVal = histogram[m][n].cellVal; |
jsobiecki | 4:5a892f5ab5a8 | 185 | } |
jsobiecki | 4:5a892f5ab5a8 | 186 | n++; |
jsobiecki | 4:5a892f5ab5a8 | 187 | } |
jsobiecki | 4:5a892f5ab5a8 | 188 | m++; |
jsobiecki | 4:5a892f5ab5a8 | 189 | } |
jsobiecki | 4:5a892f5ab5a8 | 190 | calcForce(); |
shut | 6:2cd6ae395c0f | 191 | sumForces(); |
jsobiecki | 5:1649f59c37de | 192 | } |
jsobiecki | 5:1649f59c37de | 193 | void sumForces(){ |
jsobiecki | 5:1649f59c37de | 194 | //attractive force |
shut | 6:2cd6ae395c0f | 195 | float rFx=0.0; |
shut | 6:2cd6ae395c0f | 196 | float rFy=0.0; |
shut | 6:2cd6ae395c0f | 197 | float distance = sqrt(pow((float)abs(p_final[1] - p[1]), 2) + pow((float)abs(p_final[0] - p[0]), 2)); |
shut | 6:2cd6ae395c0f | 198 | float aFx = Fca*(p_final[0]-p[0])/distance; |
shut | 6:2cd6ae395c0f | 199 | float aFy = Fca*(p_final[1]-p[1])/distance; |
jsobiecki | 5:1649f59c37de | 200 | //repulsive force |
jsobiecki | 5:1649f59c37de | 201 | for(int i=0;i<aSize;i++){ |
jsobiecki | 5:1649f59c37de | 202 | for(int j=0;j<aSize;j++){ |
jsobiecki | 5:1649f59c37de | 203 | rFx+=activeReg[i][j].forceX; |
jsobiecki | 5:1649f59c37de | 204 | rFy+=activeReg[i][j].forceY; |
jsobiecki | 5:1649f59c37de | 205 | } |
jsobiecki | 5:1649f59c37de | 206 | } |
jsobiecki | 5:1649f59c37de | 207 | //sum |
jsobiecki | 5:1649f59c37de | 208 | fX=aFx-rFx; |
jsobiecki | 5:1649f59c37de | 209 | fY=aFy-rFy; |
shut | 6:2cd6ae395c0f | 210 | pc.printf("Repulsive (X): X=%lf Force(Y)=%lf\n\n", rFx, rFy); |
shut | 2:c507076bfd93 | 211 | } |