Dependencies: mbed
main.cpp
- Committer:
- jsobiecki
- Date:
- 2019-04-05
- Revision:
- 7:3a755ebe4eaf
- Parent:
- 6:2cd6ae395c0f
- Child:
- 8:ed59eb8437c4
File content as of revision 7:3a755ebe4eaf:
#include "mbed.h" #include "Robot.h" #include "math.h" #include "ActiveCell.h" #include "HistogramCell.h" #define M_PI 3.14159265358979323846 //EXERCICIO 1 //Luis Cruz N2011164454 //Jacek Sobecki N2018319609 Serial pc(SERIAL_TX, SERIAL_RX, 115200); DigitalIn button(PC_13); void poseEst(float p[], float radius, float enc_res, float b); void SpeedLim(float w[]); void initializeArrays(); void calcSectors(); void sumForces(); void updateActive(float xR, float yR); //int ReadSensors(); //const int m = 200, n = 200, activeSize = 11; //histogram size | aSize active region size const int hSize = 80, aSize = 11; ActiveCell activeReg[aSize][aSize]; HistogramCell histogram[hSize][hSize]; //Repulsive force sums float p[3], p_obj[3], p_final[3], fX, fY; const float Fca=6;/*5*/ //VFH const int L=2; float secVal[30]; float smooth[30]; int main(){ button.mode(PullUp); getCountsAndReset(); setSpeeds(0, 0); initializeArrays(); while(button==1); //w[0] = Omega | w[1] = Left | w[2] = Right //p[0] = X | p[1] = Y | p[2] = Theta //p_obj[0] = X | p_obj[1] = Y | p_obj[2] = Theta //b = Distance between wheels, enc_res = Encoder Resolution, v = Calculated speed //k_v = Speed gain, k_s = Curvature gain, wratio = Angular speed ratio control command //Cells dim: 5x5cm | float w[3], v, theta, theta_error, err, integral = 0.0, k_i = 0.01/*0.02*/; const float radius = 3.5, b = 13.3, enc_res = 1440, k_v = 8/*7*/, k_s = 12/*10*/, sample_time = 0.05, d_stalker = 7.5, k_f = 2.5; /*2.5*/ //VFF // =============================================================================== // =================================== COORDS ==================================== // =============================================================================== //Target coordinates p_final[0] = 150, p_final[1] = 200, p_final[2] = 0; //p_obj[0] = 20, p_obj[1] = 20, p_obj[2] = 0; //Initial coordinates: p[0] = 95, p[1] = 20, p[2] = 0; // =============================================================================== // =================================== EXECUTION ================================= // =============================================================================== while(1){ getCountsAndReset(); pc.printf("Speeds: Left=%lf Right=%lf\n", w[1], w[2]); pc.printf("OBJECTIVE X: %lf OBJECTIVE Y: %lf\n", p_obj[0], p_obj[1]); pc.printf("Position: X=%lf Y=%lf Theta=%lf\n\n", p[0], p[1], p[2]); pc.printf("Force (X): X=%lf Force(Y)=%lf\n", fX, fY); //Path calculation poseEst(p, radius, enc_res, b); //Pose estimation updateActive(p[0], p[1]); p_obj[0] = p[0]+k_f*fX; // add parameter to relate chosen direction (VFH) to the point nearby of the robot p_obj[1] = p[1]+k_f*fY; //Control Law err = sqrt(pow((p_obj[0]-p[0]),2)+pow((p_obj[1]-p[1]),2)) - d_stalker; //distance to the point theta = atan2(p_obj[1]-p[1],p_obj[0]-p[0]); theta = atan2(sin(theta),cos(theta)); p[2] = atan2(sin(p[2]),cos(p[2])); theta_error = theta-p[2]; w[0] = k_s*(theta_error); //direction gain integral += err; v = k_v*err+k_i*integral; //Speed calculation w[1] = (v-(b/2)*w[0])/radius; w[2] = (v+(b/2)*w[0])/radius; SpeedLim(w); //if((fabs(p[0]-p_final[0])+fabs(p[1]-p_final[1])) < 70) k_i = -0.005; if((fabs(p[0]-p_final[0])+fabs(p[1]-p_final[1])) < 4){ setSpeeds(0,0); } else{ setSpeeds(w[1], w[2]); } wait(sample_time); } } // =============================================================================== // =================================== FUNCTIONS ================================= // =============================================================================== //Pose Estimation function void poseEst(float p[], float radius, float enc_res, float b){ float deltaDl, deltaDr, deltaD, deltaT; deltaDl = ((float)countsLeft)*(2.0*M_PI*radius/enc_res); deltaDr = ((float)countsRight)*(2.0*M_PI*radius/enc_res); deltaD = (deltaDr + deltaDl)/2; deltaT = (deltaDr - deltaDl)/b; if(fabs(deltaT) == 0){ p[0] = p[0] + deltaD*cos(p[2]) + deltaT/2; p[1] = p[1] + deltaD*sin(p[2]) + deltaT/2; return; } p[0] = p[0] + deltaD*(sin(deltaT/2.0f)/(deltaT/2.0f))*cos(p[2]+deltaT/2.0f); p[1] = p[1] + deltaD*(sin(deltaT/2.0f)/(deltaT/2.0f))*sin(p[2]+deltaT/2.0f); p[2] = p[2] + deltaT; } //Speed limiter function void SpeedLim(float w[]){ float wratio; wratio = fabs(w[2]/w[1]); if(w[2] > 150 || w[1] > 150){ if(wratio < 1){ w[1] = 150; w[2] = w[1]*wratio; } else if(wratio > 1){ w[2] = 150; w[1] = w[2]/wratio; } else{ w[2] = 150; w[1] = 150; } } if(w[2] < 50 || w[1] < 50){ if(wratio < 1){ w[1] = 50; w[2] = w[1]*wratio; } else if(wratio > 1){ w[2] = 50; w[1] = w[2]/wratio; } else{ w[2] = 50; w[1] = 50; } } } void initializeArrays() { for (int i = 0; i < hSize; i++) { for (int j = 0; j < hSize; j++) { histogram[i][j].calculate(i, j); if(i>15 && i<25 && j > 15 && j<25) histogram[i][j].cellVal=5; } } for (int i = 0; i < aSize; i++) { for (int j = 0; j < aSize; j++) { activeReg[i][j].calDist(i, j); } } } //every time robot changes position we need to call this function to update active region and calculate forces //xR, yR - robots position in coordinates system void updateActive(float xR, float yR) { int idXr = 0; int idYr = 0; for (int i = 0; i < hSize; i++) { for (int j = 0; j < hSize; j++) { if (xR > histogram[i][j].x - 2.5f && xR < histogram[i][j].x + 2.5f && yR > histogram[i][j].y - 2.5f && yR < histogram[i][j].y + 2.5f) { idXr = i; idYr = j; break; } } } int m = idXr - aSize / 2; for (int k = 0; k < aSize; k++) { int n = idYr - aSize / 2; for (int l = 0; l < aSize; l++) { if(m >= 0 && n >= 0 && m < hSize && n < hSize) { activeReg[k][l].cellVal = histogram[m][n].cellVal; } n++; } m++; } for (int i = 0; i < aSize; i++) { for (int j = 0; j < aSize; j++) { activeReg[i][j].calForce(); } } activeReg[5][5].amplitude=0; activeReg[5][5].amplitude=0; calcSectors(); } void calcSectors(){ for (int k = 0; k < 30; ++k) { for (int i = 0; i < aSize; ++i) { for (int j = 0; j < aSize; ++j) { if(activeReg[i][j].sectorK==k) secVal[k]+=activeReg[i][j].amplitude; } } } smooth[0]=(secVal[28]+2*secVal[29]+2*secVal[0]+2*secVal[1]+secVal[2])/5; smooth[1]=(secVal[29]+2*secVal[0]+2*secVal[1]+2*secVal[2]+secVal[3])/5; smooth[28]=(secVal[26]+2*secVal[27]+2*secVal[28]+2*secVal[29]+secVal[0])/5; smooth[29]=(secVal[27]+2*secVal[28]+2*secVal[29]+2*secVal[0]+secVal[1])/5; for (int i = 2; i < 28; ++i) { smooth[i]=(secVal[i-L]+2*secVal[i-L+1]+2*secVal[i]+2*secVal[i+L-1]+secVal[i+L])/5; } }