Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp@4:5a892f5ab5a8, 2019-03-24 (annotated)
- Committer:
- jsobiecki
- Date:
- Sun Mar 24 01:11:20 2019 +0000
- Revision:
- 4:5a892f5ab5a8
- Parent:
- 2:c507076bfd93
- Child:
- 5:1649f59c37de
arrays added
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(); | 
| jsobiecki | 4:5a892f5ab5a8 | 16 | void updateActive(double xR, double yR); | 
| shut | 2:c507076bfd93 | 17 | //int ReadSensors(); | 
| jsobiecki | 4:5a892f5ab5a8 | 18 | //void updateHist(int hist[][], int active[][],int x,int y); | 
| jsobiecki | 4:5a892f5ab5a8 | 19 | const int m = 200, n = 200, activeSize = 11; | 
| jsobiecki | 4:5a892f5ab5a8 | 20 | const int hSize = 200; | 
| jsobiecki | 4:5a892f5ab5a8 | 21 | const int aSize = 11; | 
| jsobiecki | 4:5a892f5ab5a8 | 22 | ActiveCell activeReg[aSize][aSize]; | 
| jsobiecki | 4:5a892f5ab5a8 | 23 | HistogramCell histogram[hSize][hSize]; | 
| jsobiecki | 4:5a892f5ab5a8 | 24 | |
| jsobiecki | 0:719ea21609f1 | 25 | int main(){ | 
| jsobiecki | 0:719ea21609f1 | 26 | |
| jsobiecki | 0:719ea21609f1 | 27 | button.mode(PullUp); | 
| jsobiecki | 0:719ea21609f1 | 28 | getCountsAndReset(); | 
| jsobiecki | 0:719ea21609f1 | 29 | setSpeeds(0, 0); | 
| jsobiecki | 4:5a892f5ab5a8 | 30 | initializeArrays(); | 
| jsobiecki | 0:719ea21609f1 | 31 | while(button==1); | 
| jsobiecki | 0:719ea21609f1 | 32 | |
| jsobiecki | 0:719ea21609f1 | 33 | //w[0] = Omega | w[1] = X | w[2] = Y | 
| jsobiecki | 0:719ea21609f1 | 34 | //p[0] = X | p[1] = Y | p[2] = Theta | 
| jsobiecki | 0:719ea21609f1 | 35 | //p_obj[0] = X | p_obj[1] = Y | p_obj[2] = Theta | 
| jsobiecki | 0:719ea21609f1 | 36 | //b = Distance between wheels, enc_res = Encoder Resolution, v = Calculated speed | 
| jsobiecki | 0:719ea21609f1 | 37 | //k_v = Speed gain, k_s = Curvature gain, wratio = Angular speed ratio control command | 
| shut | 2:c507076bfd93 | 38 | //Cells dim: 5x5cm | | 
| shut | 2:c507076bfd93 | 39 | int hist[m][n] , active[activeSize][activeSize]; | 
| shut | 2:c507076bfd93 | 40 | float w[3], v, p[3], p_obj[3], theta, theta_error, err, integral = 0.0; | 
| shut | 2:c507076bfd93 | 41 | const float radius = 3.5, b = 13.3, enc_res = 1440, k_v = 7, | 
| shut | 2:c507076bfd93 | 42 | k_s = 60, k_i = 1, sample_time = 0.05, Fcr = 1.0, d_stalker = 5.0; | 
| jsobiecki | 0:719ea21609f1 | 43 | // =============================================================================== | 
| jsobiecki | 0:719ea21609f1 | 44 | // =================================== COORDS ==================================== | 
| shut | 2:c507076bfd93 | 45 | // =============================================================================== | 
| jsobiecki | 0:719ea21609f1 | 46 | //Target coordinates | 
| shut | 2:c507076bfd93 | 47 | p_obj[0] = 400, p_obj[1] = 400, p_obj[2] = 0; | 
| jsobiecki | 0:719ea21609f1 | 48 | //Initial coordinates: | 
| shut | 2:c507076bfd93 | 49 | p[0] = 100, p[1] = 100, p[2] = 0; | 
| jsobiecki | 0:719ea21609f1 | 50 | // =============================================================================== | 
| jsobiecki | 0:719ea21609f1 | 51 | // =================================== EXECUTION ================================= | 
| jsobiecki | 0:719ea21609f1 | 52 | // =============================================================================== | 
| jsobiecki | 0:719ea21609f1 | 53 | while(1){ | 
| jsobiecki | 0:719ea21609f1 | 54 | getCountsAndReset(); | 
| jsobiecki | 0:719ea21609f1 | 55 | pc.printf("Speeds: Left=%lf Right=%lf\n", w[1], w[2]); | 
| shut | 2:c507076bfd93 | 56 | pc.printf("Odometer: X=%lf Y=%lf Theta=%lf\n", p[0], p[1], p[2]); | 
| jsobiecki | 0:719ea21609f1 | 57 | pc.printf("Position: X=%lf Y=%lf Theta=%lf\n", p[0], p[1], p[2]); | 
| shut | 2:c507076bfd93 | 58 | |
| jsobiecki | 0:719ea21609f1 | 59 | //Path calculation | 
| shut | 2:c507076bfd93 | 60 | poseEst(p, radius, enc_res, b); //Pose estimation | 
| shut | 2:c507076bfd93 | 61 | //Control Law | 
| shut | 2:c507076bfd93 | 62 | 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 | 63 | theta = atan2(p_obj[1]-p[1],p_obj[0]-p[0]); | 
| jsobiecki | 0:719ea21609f1 | 64 | theta = atan2(sin(theta),cos(theta)); | 
| jsobiecki | 0:719ea21609f1 | 65 | p[2] = atan2(sin(p[2]),cos(p[2])); | 
| jsobiecki | 0:719ea21609f1 | 66 | theta_error = theta-p[2]; | 
| shut | 2:c507076bfd93 | 67 | w[0] = k_s*(theta_error); //direction gain | 
| jsobiecki | 4:5a892f5ab5a8 | 68 | integral += err; | 
| shut | 2:c507076bfd93 | 69 | v = k_v*err+k_i*integral; //Speed gain | 
| jsobiecki | 0:719ea21609f1 | 70 | w[1] = (v-(b/2)*w[0])/radius; | 
| jsobiecki | 0:719ea21609f1 | 71 | w[2] = (v+(b/2)*w[0])/radius; | 
| jsobiecki | 0:719ea21609f1 | 72 | SpeedLim(w); | 
| jsobiecki | 0:719ea21609f1 | 73 | if((fabs(p[0]-p_obj[0])+fabs(p[1]-p_obj[1])) < 1){ | 
| jsobiecki | 0:719ea21609f1 | 74 | setSpeeds(0,0); | 
| jsobiecki | 0:719ea21609f1 | 75 | } | 
| jsobiecki | 0:719ea21609f1 | 76 | else{ | 
| jsobiecki | 0:719ea21609f1 | 77 | setSpeeds(w[1], w[2]); | 
| jsobiecki | 0:719ea21609f1 | 78 | } | 
| jsobiecki | 0:719ea21609f1 | 79 | wait(sample_time); | 
| jsobiecki | 0:719ea21609f1 | 80 | } | 
| jsobiecki | 0:719ea21609f1 | 81 | } | 
| jsobiecki | 0:719ea21609f1 | 82 | // =============================================================================== | 
| jsobiecki | 0:719ea21609f1 | 83 | // =================================== FUNCTIONS ================================= | 
| jsobiecki | 0:719ea21609f1 | 84 | // =============================================================================== | 
| jsobiecki | 0:719ea21609f1 | 85 | //Pose Estimation function | 
| jsobiecki | 0:719ea21609f1 | 86 | void poseEst(float p[], float radius, float enc_res, float b){ | 
| jsobiecki | 0:719ea21609f1 | 87 | float deltaDl, deltaDr, deltaD, deltaT; | 
| jsobiecki | 0:719ea21609f1 | 88 | deltaDl = ((float)countsLeft)*(2.0*M_PI*radius/enc_res); | 
| jsobiecki | 0:719ea21609f1 | 89 | deltaDr = ((float)countsRight)*(2.0*M_PI*radius/enc_res); | 
| jsobiecki | 0:719ea21609f1 | 90 | deltaD = (deltaDr + deltaDl)/2; | 
| jsobiecki | 0:719ea21609f1 | 91 | deltaT = (deltaDr - deltaDl)/b; | 
| jsobiecki | 0:719ea21609f1 | 92 | if(fabs(deltaT) == 0){ | 
| jsobiecki | 0:719ea21609f1 | 93 | p[0] = p[0] + deltaD*cos(p[2]) + deltaT/2; | 
| jsobiecki | 0:719ea21609f1 | 94 | p[1] = p[1] + deltaD*sin(p[2]) + deltaT/2; | 
| jsobiecki | 0:719ea21609f1 | 95 | return; | 
| jsobiecki | 0:719ea21609f1 | 96 | } | 
| jsobiecki | 0:719ea21609f1 | 97 | p[0] = p[0] + deltaD*(sin(deltaT/2.0f)/(deltaT/2.0f))*cos(p[2]+deltaT/2.0f); | 
| jsobiecki | 0:719ea21609f1 | 98 | p[1] = p[1] + deltaD*(sin(deltaT/2.0f)/(deltaT/2.0f))*sin(p[2]+deltaT/2.0f); | 
| jsobiecki | 0:719ea21609f1 | 99 | p[2] = p[2] + deltaT; | 
| jsobiecki | 0:719ea21609f1 | 100 | } | 
| jsobiecki | 0:719ea21609f1 | 101 | //Speed limiter function | 
| jsobiecki | 0:719ea21609f1 | 102 | void SpeedLim(float w[]){ | 
| jsobiecki | 0:719ea21609f1 | 103 | float wratio; | 
| jsobiecki | 0:719ea21609f1 | 104 | wratio = w[2]/w[1]; | 
| jsobiecki | 0:719ea21609f1 | 105 | if(w[2] > 150 || w[1] > 150){ | 
| jsobiecki | 0:719ea21609f1 | 106 | if(wratio < 1){ | 
| jsobiecki | 0:719ea21609f1 | 107 | w[1] = 150; | 
| jsobiecki | 0:719ea21609f1 | 108 | w[2] = w[1]*wratio; | 
| jsobiecki | 0:719ea21609f1 | 109 | } | 
| jsobiecki | 0:719ea21609f1 | 110 | else if(wratio > 1){ | 
| jsobiecki | 0:719ea21609f1 | 111 | w[2] = 150; | 
| jsobiecki | 0:719ea21609f1 | 112 | w[1] = w[2]/wratio; | 
| jsobiecki | 0:719ea21609f1 | 113 | } | 
| jsobiecki | 0:719ea21609f1 | 114 | else{ | 
| jsobiecki | 0:719ea21609f1 | 115 | w[2] = 150; | 
| jsobiecki | 0:719ea21609f1 | 116 | w[1] = 150; | 
| jsobiecki | 0:719ea21609f1 | 117 | } | 
| jsobiecki | 0:719ea21609f1 | 118 | } | 
| jsobiecki | 0:719ea21609f1 | 119 | if(w[2] < 50 || w[1] < 50){ | 
| jsobiecki | 0:719ea21609f1 | 120 | if(wratio < 1){ | 
| jsobiecki | 0:719ea21609f1 | 121 | w[1] = 50; | 
| jsobiecki | 0:719ea21609f1 | 122 | w[2] = w[1]*wratio; | 
| jsobiecki | 0:719ea21609f1 | 123 | } | 
| jsobiecki | 0:719ea21609f1 | 124 | else if(wratio > 1){ | 
| jsobiecki | 0:719ea21609f1 | 125 | w[2] = 50; | 
| jsobiecki | 0:719ea21609f1 | 126 | w[1] = w[2]/wratio; | 
| jsobiecki | 0:719ea21609f1 | 127 | } | 
| jsobiecki | 0:719ea21609f1 | 128 | else{ | 
| jsobiecki | 0:719ea21609f1 | 129 | w[2] = 50; | 
| jsobiecki | 0:719ea21609f1 | 130 | w[1] = 50; | 
| jsobiecki | 0:719ea21609f1 | 131 | } | 
| jsobiecki | 0:719ea21609f1 | 132 | } | 
| jsobiecki | 0:719ea21609f1 | 133 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 134 | |
| jsobiecki | 4:5a892f5ab5a8 | 135 | void initializeArrays() { | 
| jsobiecki | 4:5a892f5ab5a8 | 136 | for (int i = 0; i < hSize; i++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 137 | for (int j = 0; j < hSize; j++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 138 | histogram[i][j].calculate(i, j); | 
| jsobiecki | 4:5a892f5ab5a8 | 139 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 140 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 141 | for (int i = 0; i < aSize; i++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 142 | for (int j = 0; j < aSize; j++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 143 | activeReg[i][j].calDist(i, j); | 
| jsobiecki | 4:5a892f5ab5a8 | 144 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 145 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 146 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 147 | void calcForce(){ | 
| jsobiecki | 4:5a892f5ab5a8 | 148 | for (int i = 0; i < aSize; i++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 149 | for (int j = 0; j < aSize; j++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 150 | activeReg[i][j].calForce(); | 
| jsobiecki | 4:5a892f5ab5a8 | 151 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 152 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 153 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 154 | //every time robot changes position we need to call this function to update active region | 
| jsobiecki | 4:5a892f5ab5a8 | 155 | //and calculate forces | 
| jsobiecki | 4:5a892f5ab5a8 | 156 | //xR, yR - robots position in coordinates system | 
| jsobiecki | 4:5a892f5ab5a8 | 157 | void updateActive(double xR, double yR) { | 
| jsobiecki | 4:5a892f5ab5a8 | 158 | int idXr = 0; | 
| jsobiecki | 4:5a892f5ab5a8 | 159 | int idYr = 0; | 
| jsobiecki | 4:5a892f5ab5a8 | 160 | for (int i = 0; i < hSize; i++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 161 | for (int j = 0; j < hSize; j++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 162 | if (xR > histogram[i][j].x - 2.5 && xR < histogram[i][j].x + 2.5 && yR > histogram[i][j].y - 2.5 && | 
| jsobiecki | 4:5a892f5ab5a8 | 163 | yR < histogram[i][j].y + 2.5) { | 
| jsobiecki | 4:5a892f5ab5a8 | 164 | idXr = i; | 
| jsobiecki | 4:5a892f5ab5a8 | 165 | idYr = j; | 
| jsobiecki | 4:5a892f5ab5a8 | 166 | break; | 
| shut | 2:c507076bfd93 | 167 | } | 
| shut | 2:c507076bfd93 | 168 | } | 
| shut | 2:c507076bfd93 | 169 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 170 | int m = idXr - aSize / 2; | 
| jsobiecki | 4:5a892f5ab5a8 | 171 | for (int k = 0; k < aSize; k++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 172 | int n = idYr - aSize / 2; | 
| jsobiecki | 4:5a892f5ab5a8 | 173 | for (int l = 0; l < aSize; l++) { | 
| jsobiecki | 4:5a892f5ab5a8 | 174 | if (m > 0 && n > 0 && m < hSize && n < hSize) { | 
| jsobiecki | 4:5a892f5ab5a8 | 175 | activeReg[k][l].cellVal = histogram[m][n].cellVal; | 
| jsobiecki | 4:5a892f5ab5a8 | 176 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 177 | n++; | 
| jsobiecki | 4:5a892f5ab5a8 | 178 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 179 | m++; | 
| jsobiecki | 4:5a892f5ab5a8 | 180 | } | 
| jsobiecki | 4:5a892f5ab5a8 | 181 | calcForce(); | 
| shut | 2:c507076bfd93 | 182 | } |