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.
main.cpp
00001 #include "mbed.h" 00002 00003 #include "irpair.h" 00004 #include "main.h" 00005 #include "motor.h" 00006 00007 #include <stdlib.h> 00008 #include <stack> // std::stack 00009 #include <utility> // std::pair, std::make_pair 00010 00011 #include "ITG3200.h" 00012 #include "stm32f4xx.h" 00013 #include "QEI.h" 00014 00015 /*LEFT/RIGHT BOTH WALLS 00016 0.34 0.12 00017 00018 LEFT/RIGHT LEFT WALL GONE 00019 0.02 0.11 00020 00021 LEFT/RIGHT RIGTH WALL GONE 00022 0.33 0.008 00023 00024 LEFT/RIGHT BOTH WALLS GONE 00025 0.02 0.008 00026 00027 LEFT/RIGHT CLOSE TO RIGHT WALL 00028 0.14 0.47 00029 00030 LEFT/RIGHT CLOSE TO LEFT WALL 00031 0.89 0.05 00032 00033 FRONT IRS NEAR WALL (STOPPING DISTANCE) 00034 0.41 0.49 00035 00036 FRONT IRS NO WALL AHEAD (FOR ATLEAST 1 FULL CELL) 00037 0.07 0.06 00038 00039 */ 00040 00041 #define IP_CONSTANT 1.6 00042 #define II_CONSTANT 0.00001 00043 #define ID_CONSTANT 0.24 00044 00045 void pidOnEncoders(); 00046 00047 void moveBackwards(){ 00048 right_motor.move(-WHEEL_SPEED); 00049 left_motor.move(-WHEEL_SPEED); 00050 wait_ms(40); 00051 right_motor.brake(); 00052 left_motor.brake(); 00053 } 00054 00055 void moveForwardEncoder(double num) 00056 { 00057 int count0; 00058 int count1; 00059 count0 = encoder0.getPulses(); 00060 count1 = encoder1.getPulses(); 00061 int initial1 = count1; 00062 int initial0 = count0; 00063 int diff = count0 - count1; 00064 double kp = 0.00022; 00065 double kd = 0.00020; 00066 int prev = 0; 00067 00068 double speed0 = WHEEL_SPEED; 00069 double speed1 = WHEEL_SPEED; 00070 00071 receiverOneReading = IRP_1.getSamples(100); 00072 receiverFourReading = IRP_4.getSamples(100); 00073 right_motor.move(speed0); 00074 left_motor.move(speed1); 00075 wait_ms(150); 00076 00077 double distance_to_go = (oneCellCount)*num; 00078 00079 while( ((encoder0.getPulses() - initial0) <= distance_to_go && (encoder1.getPulses() - initial1) <= distance_to_go) && receiverOneReading < IRP_1.sensorAvg*frontStop && receiverFourReading < IRP_4.sensorAvg*frontStop) { 00080 00081 if( ( distance_to_go - count0 ) <= 900 || (distance_to_go - count1) <= 900 ) { 00082 left_motor.move( speed0/900 ); 00083 right_motor.move( speed1/900 ); 00084 } else { 00085 left_motor.move(speed0); 00086 right_motor.move(speed1); 00087 wait_us(16000); 00088 pidOnEncoders(); 00089 } 00090 00091 receiverOneReading = IRP_1.getSamples(100); 00092 receiverFourReading = IRP_4.getSamples(100); 00093 } 00094 00095 right_motor.brake(); 00096 left_motor.brake(); 00097 return; 00098 } 00099 00100 void encoderAfterTurn(double num) 00101 { 00102 int count0; 00103 int count1; 00104 count0 = encoder0.getPulses(); 00105 count1 = encoder1.getPulses(); 00106 int initial1 = count1; 00107 int initial0 = count0; 00108 int diff = count0 - count1; 00109 double kp = 0.00008; 00110 double kd = 0.0000; 00111 int prev = 0; 00112 00113 double speed0 = WHEEL_SPEED; // left wheel 00114 double speed1 = WHEEL_SPEED; 00115 receiverOneReading = IRP_1.getSamples(100); 00116 receiverFourReading = IRP_4.getSamples(100); 00117 00118 right_motor.move(speed0); 00119 left_motor.move(speed1); 00120 wait_us(150000); 00121 00122 double distance_to_go = (oneCellCount)*num; 00123 00124 while( ((encoder0.getPulses() - initial0) <= distance_to_go && (encoder1.getPulses() - initial1) <= distance_to_go) && receiverOneReading < IRP_1.sensorAvg*frontStop && receiverFourReading < IRP_4.sensorAvg*frontStop) { 00125 00126 if( ( distance_to_go - count0 ) <= 900 || (distance_to_go - count1) <= 900 ) { 00127 left_motor.move( speed0/900 ); 00128 right_motor.move( speed1/900 ); 00129 } else { 00130 left_motor.move(speed0); 00131 right_motor.move(speed1); 00132 wait_us(16000); 00133 pidOnEncoders(); 00134 } 00135 receiverOneReading = IRP_1.getSamples(100); 00136 receiverFourReading = IRP_4.getSamples(100); 00137 } 00138 00139 right_motor.brake(); 00140 left_motor.brake(); 00141 00142 double curr0 = encoder0.getPulses(); 00143 double curr1 = encoder1.getPulses(); 00144 if ((curr0 - initial0) >= distance_to_go*0.6 && (curr1 - initial1) >= distance_to_go*0.6) { 00145 if (currDir % 4 == 0) { 00146 mouseY += 1; 00147 } else if (currDir % 4 == 1) { 00148 mouseX += 1; 00149 } else if (currDir % 4 == 2) { 00150 mouseY -= 1; 00151 } else if (currDir % 4 == 3) { 00152 mouseX -= 1; 00153 } 00154 00155 // the mouse has moved forward, we need to update the wall map now 00156 receiverOneReading = IRP_1.getSamples(100); 00157 receiverTwoReading = IRP_2.getSamples(100); 00158 receiverThreeReading = IRP_3.getSamples(100); 00159 receiverFourReading = IRP_4.getSamples(100); 00160 00161 // serial.printf("R1: %f \t R4: %f \t R1Avg: %f \t R4Avg: %f\n", receiverOneReading, receiverFourReading, IRP_1.sensorAvg, IRP_4.sensorAvg); 00162 // serial.printf("R2: %f \t R3: %f \t R2Avg: %f \t R3Avg: %f\n", receiverTwoReading, receiverThreeReading, IRP_2.sensorAvg, IRP_3.sensorAvg); 00163 00164 if (receiverOneReading >= IRP_1.sensorAvg * 2.5 || receiverFourReading >= IRP_4.sensorAvg * 2.5) { 00165 // serial.printf("Front wall is there\n"); 00166 if (currDir % 4 == 0) { 00167 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= F_WALL; 00168 } else if (currDir % 4 == 1) { 00169 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= R_WALL; 00170 } else if (currDir % 4 == 2) { 00171 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= B_WALL; 00172 } else if (currDir % 4 == 3) { 00173 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= L_WALL; 00174 } 00175 } 00176 if((receiverThreeReading < IRP_3.sensorAvg/5) && (receiverTwoReading < IRP_2.sensorAvg/5)) { 00177 // do nothing, the walls are not there 00178 } else if (receiverThreeReading < IRP_3.sensorAvg/LRAvg) { // right wall gone, left wall is there RED 00179 // serial.printf("Left wall, mouseY: %d, mouseX: %d\n", mouseY, mouseX); 00180 if (currDir % 4 == 0) { 00181 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= L_WALL; 00182 } else if (currDir % 4 == 1) { 00183 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= F_WALL; 00184 } else if (currDir % 4 == 2) { 00185 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= R_WALL; 00186 } else if (currDir % 4 == 3) { 00187 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= B_WALL; 00188 } 00189 } else if (receiverTwoReading < IRP_2.sensorAvg/LRAvg) { // left wall gone, right wall is there 00190 // serial.printf("Right wall, mouseY: %d, mouseX: %d\n", mouseY, mouseX); 00191 if (currDir % 4 == 0) { 00192 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= R_WALL; 00193 } else if (currDir % 4 == 1) { 00194 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= B_WALL; 00195 } else if (currDir % 4 == 2) { 00196 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= L_WALL; 00197 } else if (currDir % 4 == 3) { 00198 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= F_WALL; 00199 } 00200 } else if ((receiverTwoReading > ((IRP_2.sensorAvg)*averageDivUpper)) && (receiverThreeReading > ((IRP_3.sensorAvg)*averageDivUpper))) { 00201 // serial.printf("Both walls \n"); 00202 if (currDir %4 == 0) { 00203 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= R_WALL; 00204 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= L_WALL; 00205 } else if (currDir %4 == 1) { 00206 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= F_WALL; 00207 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= B_WALL; 00208 } else if (currDir % 4 == 2) { 00209 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= R_WALL; 00210 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= L_WALL; 00211 } else if (currDir %4 == 3) { 00212 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= F_WALL; 00213 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= B_WALL; 00214 } 00215 } 00216 } 00217 } 00218 00219 void printDipFlag() 00220 { 00221 if (DEBUGGING) 00222 serial.printf("Flag value is %d", dipFlags); 00223 } 00224 00225 void enableButton1() 00226 { 00227 dipFlags |= BUTTON1_FLAG; 00228 printDipFlag(); 00229 } 00230 void enableButton2() 00231 { 00232 dipFlags |= BUTTON2_FLAG; 00233 printDipFlag(); 00234 } 00235 void enableButton3() 00236 { 00237 dipFlags |= BUTTON3_FLAG; 00238 printDipFlag(); 00239 } 00240 void enableButton4() 00241 { 00242 dipFlags |= BUTTON4_FLAG; 00243 printDipFlag(); 00244 } 00245 void disableButton1() 00246 { 00247 dipFlags &= ~BUTTON1_FLAG; 00248 printDipFlag(); 00249 } 00250 void disableButton2() 00251 { 00252 dipFlags &= ~BUTTON2_FLAG; 00253 printDipFlag(); 00254 } 00255 void disableButton3() 00256 { 00257 dipFlags &= ~BUTTON3_FLAG; 00258 printDipFlag(); 00259 } 00260 void disableButton4() 00261 { 00262 dipFlags &= ~BUTTON4_FLAG; 00263 printDipFlag(); 00264 } 00265 00266 void pidOnEncoders() 00267 { 00268 int count0; 00269 int count1; 00270 count0 = encoder0.getPulses(); 00271 count1 = encoder1.getPulses(); 00272 int diff = count0 - count1; 00273 double kp = 0.00016; 00274 double kd = 0.00016; 00275 int prev = 0; 00276 00277 int counter = 0; 00278 while(1) { 00279 count0 = encoder0.getPulses(); 00280 count1 = encoder1.getPulses(); 00281 int x = count0 - count1; 00282 //double d = kp * x + kd * ( x - prev ); 00283 double kppart = kp * x; 00284 double kdpart = kd * (x-prev); 00285 double d = kppart + kdpart; 00286 00287 //serial.printf( "x: %d,\t prev: %d,\t d: %f,\t kppart: %f,\t kdpart: %f\n", x, prev, d, kppart, kdpart ); 00288 if( x < diff - 60 ) { // count1 is bigger, right wheel pushed forward 00289 left_motor.move( -d ); 00290 right_motor.move( d ); 00291 } else if( x > diff + 60 ) { 00292 left_motor.move( -d ); 00293 right_motor.move( d ); 00294 } 00295 // else 00296 // { 00297 // left_motor.brake(); 00298 // right_motor.brake(); 00299 // } 00300 prev = x; 00301 counter++; 00302 if (counter == 10) 00303 break; 00304 } 00305 } 00306 00307 void nCellEncoderAndIR(double cellCount) 00308 { 00309 double currentError = 0; 00310 double previousError = 0; 00311 double derivError = 0; 00312 double sumError = 0; 00313 00314 double HIGH_PWM_VOLTAGE_R = WHEEL_SPEED; 00315 double HIGH_PWM_VOLTAGE_L = WHEEL_SPEED; 00316 00317 double rightSpeed = WHEEL_SPEED; 00318 double leftSpeed = WHEEL_SPEED; 00319 00320 int desiredCount0 = encoder0.getPulses() + oneCellCountMomentum*cellCount; 00321 int desiredCount1 = encoder1.getPulses() + oneCellCountMomentum*cellCount; 00322 00323 left_motor.forward(WHEEL_SPEED); 00324 right_motor.forward(WHEEL_SPEED); 00325 00326 float ir2 = IRP_2.getSamples( SAMPLE_NUM ); 00327 float ir3 = IRP_3.getSamples( SAMPLE_NUM ); 00328 00329 int state = 0; 00330 00331 int previousCount0 = 10000; 00332 int previousCount1 = 10000; 00333 00334 while (encoder0.getPulses() <= desiredCount0 && encoder1.getPulses() <= desiredCount1) { 00335 int currCount0 = encoder0.getPulses(); 00336 int currCount1 = encoder1.getPulses(); 00337 // serial.printf("currCount0 = %d, currCount1 =%d, previousCount0 = %d, previousCount1 = %d \n", currCount0, currCount1, previousCount0, previousCount1); 00338 // if (abs(currCount0 - previousCount0) <= 2 || abs(currCount1 - previousCount1) <= 2){ 00339 // moveBackwards(); 00340 // return; 00341 // } 00342 // serial.printf("The desiredCount0 is: %d \t The desiredCount1 is: %d\t the 0encoderval is :%d\t the 1encoderval is : %d\t\n", desiredCount0, desiredCount1, encoder0.getPulses(), encoder1.getPulses()); 00343 receiverTwoReading = IRP_2.getSamples( SAMPLE_NUM ); 00344 receiverThreeReading = IRP_3.getSamples( SAMPLE_NUM ); 00345 receiverOneReading = IRP_1.getSamples( SAMPLE_NUM ); 00346 receiverFourReading = IRP_4.getSamples( SAMPLE_NUM ); 00347 // serial.printf("IR2 = %f, IR2AVE = %f, IR3 = %f, IR3_AVE = %f\n", receiverTwoReading, IRP_2.sensorAvg, receiverThreeReading, IRP_3.sensorAvg); 00348 if( receiverOneReading > IRP_1.sensorAvg * frontStop || receiverFourReading > IRP_4.sensorAvg * frontStop ) { 00349 break; 00350 } 00351 00352 if((receiverThreeReading < IRP_3.sensorAvg/5) && (receiverTwoReading < IRP_2.sensorAvg/5)) { 00353 // both sides gone 00354 double prev0 = encoder0.getPulses(); 00355 double prev1 = encoder1.getPulses(); 00356 double diff0 = desiredCount0 - prev0; 00357 double diff1 = desiredCount1 - prev1; 00358 double valToPass = ((diff0 + diff1)/2)/(oneCellCountMomentum); 00359 redLed.write(1); 00360 greenLed.write(0); 00361 blueLed.write(0); 00362 // serial.printf("Going to go over to move forward with encoder, and passing %f\n", valToPass); 00363 moveForwardEncoder(valToPass); 00364 continue; 00365 } else if (receiverThreeReading < IRP_3.sensorAvg/LRAvg) { // right wall gone RED 00366 state = 1; 00367 // double prev0 = encoder0.getPulses(); 00368 // double prev1 = encoder1.getPulses(); 00369 // double diff0 = desiredCount0 - prev0; 00370 // double diff1 = desiredCount1 - prev1; 00371 // double valToPass = ((diff0 + diff1)/2)/(oneCellCountMomentum); 00372 redLed.write(0); 00373 greenLed.write(1); 00374 blueLed.write(1); 00375 // moveForwardEncoder(valToPass); 00376 // break; 00377 } else if (receiverTwoReading < IRP_2.sensorAvg/LRAvg) { // left wall gone 00378 // BLUE BLUE BLUE BLUE 00379 state = 2; 00380 // double prev0 = encoder0.getPulses(); 00381 // double prev1 = encoder1.getPulses(); 00382 // double diff0 = desiredCount0 - prev0; 00383 // double diff1 = desiredCount1 - prev1; 00384 // double valToPass = ((diff0 + diff1)/2)/(oneCellCountMomentum); 00385 redLed.write(1); 00386 greenLed.write(1); 00387 blueLed.write(0); 00388 // moveForwardEncoder(valToPass); 00389 // break; 00390 } else if ((receiverTwoReading > ((IRP_2.sensorAvg)*averageDivUpper)) && (receiverThreeReading > ((IRP_3.sensorAvg)*averageDivUpper))) { 00391 // both walls there 00392 state = 0; 00393 redLed.write(1); 00394 greenLed.write(0); 00395 blueLed.write(1); 00396 } 00397 00398 //serial.printf("Entering switch\n"); 00399 switch(state) { 00400 case(0): { // both walls there 00401 currentError = ( receiverTwoReading - IRP_2.sensorAvg) - ( receiverThreeReading - IRP_3.sensorAvg); 00402 break; 00403 } 00404 case(1): { // RED RED RED RED RED 00405 currentError = (receiverTwoReading - IRP_2.sensorAvg) - (IRP_3.sensorAvg*0.001); 00406 break; 00407 } 00408 case(2): { // blue 00409 currentError = (IRP_2.sensorAvg*0.001) - (receiverThreeReading - IRP_3.sensorAvg); 00410 break; 00411 } 00412 default: { 00413 currentError = ( receiverTwoReading - IRP_2.sensorAvg) - ( receiverThreeReading - IRP_3.sensorAvg); 00414 break; 00415 } 00416 } 00417 //serial.printf("Exiting switch"); 00418 00419 sumError += currentError; 00420 derivError = currentError - previousError; 00421 double PIDSum = IP_CONSTANT*currentError + II_CONSTANT*sumError + ID_CONSTANT*derivError; 00422 00423 double prev0 = encoder0.getPulses(); 00424 double prev1 = encoder1.getPulses(); 00425 double diff0 = desiredCount0 - prev0; 00426 double diff1 = desiredCount1 - prev1; 00427 double kp = .1/1000; 00428 00429 00430 rightSpeed = HIGH_PWM_VOLTAGE_R; 00431 leftSpeed = HIGH_PWM_VOLTAGE_L; 00432 if (diff1 < 1000 || diff0 < 1000) { 00433 rightSpeed = kp * HIGH_PWM_VOLTAGE_R; 00434 leftSpeed = kp * HIGH_PWM_VOLTAGE_L; 00435 } 00436 00437 if (PIDSum > 0) { // this means the leftWheel is faster than the right. So right speeds up, left slows down 00438 rightSpeed = rightSpeed - abs(PIDSum*HIGH_PWM_VOLTAGE_R); 00439 leftSpeed = leftSpeed + abs(PIDSum*HIGH_PWM_VOLTAGE_L); 00440 } else { // r is faster than L. speed up l, slow down r 00441 rightSpeed = rightSpeed + abs(PIDSum*HIGH_PWM_VOLTAGE_R); 00442 leftSpeed = leftSpeed - abs(PIDSum*HIGH_PWM_VOLTAGE_L); 00443 } 00444 00445 00446 //serial.printf("%f, %f\n", leftSpeed, rightSpeed); 00447 if (leftSpeed > 0.30) leftSpeed = 0.30; 00448 if (leftSpeed < 0) leftSpeed = 0; 00449 if (rightSpeed > 0.30) rightSpeed = 0.30; 00450 if (rightSpeed < 0) rightSpeed = 0; 00451 00452 right_motor.forward(rightSpeed); 00453 left_motor.forward(leftSpeed); 00454 pidOnEncoders(); 00455 00456 previousError = currentError; 00457 previousCount1 = currCount1; 00458 previousCount0 = currCount0; 00459 } 00460 00461 // GO BACK A BIT BEFORE BRAKING?? 00462 left_motor.backward(0.01); 00463 right_motor.backward(0.01); 00464 wait_us(150); 00465 // DELETE THIS IF IT DOES NOT WORK!! 00466 00467 left_motor.brake(); 00468 right_motor.brake(); 00469 if (encoder0.getPulses() >= 0.4*desiredCount0 && encoder1.getPulses() >= 0.4*desiredCount1) { 00470 if (currDir % 4 == 0) { 00471 mouseY += 1; 00472 } else if (currDir % 4 == 1) { 00473 mouseX += 1; 00474 } else if (currDir % 4 == 2) { 00475 mouseY -= 1; 00476 } else if (currDir % 4 == 3) { 00477 mouseX -= 1; 00478 } 00479 00480 // the mouse has moved forward, we need to update the wall map now 00481 receiverOneReading = IRP_1.getSamples(100); 00482 receiverTwoReading = IRP_2.getSamples(100); 00483 receiverThreeReading = IRP_3.getSamples(100); 00484 receiverFourReading = IRP_4.getSamples(100); 00485 00486 // serial.printf("R1: %f \t R4: %f \t R1Avg: %f \t R4Avg: %f\n", receiverOneReading, receiverFourReading, IRP_1.sensorAvg, IRP_4.sensorAvg); 00487 // serial.printf("R2: %f \t R3: %f \t R2Avg: %f \t R3Avg: %f\n", receiverTwoReading, receiverThreeReading, IRP_2.sensorAvg, IRP_3.sensorAvg); 00488 00489 if (receiverOneReading >= IRP_1.sensorAvg * 2.5 || receiverFourReading >= IRP_4.sensorAvg * 2.5) { 00490 // serial.printf("Front wall is there\n"); 00491 if (currDir % 4 == 0) { 00492 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= F_WALL; 00493 } else if (currDir % 4 == 1) { 00494 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= R_WALL; 00495 } else if (currDir % 4 == 2) { 00496 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= B_WALL; 00497 } else if (currDir % 4 == 3) { 00498 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= L_WALL; 00499 } 00500 } 00501 if((receiverThreeReading < IRP_3.sensorAvg/5) && (receiverTwoReading < IRP_2.sensorAvg/5)) { 00502 // do nothing, the walls are not there 00503 } else if (receiverThreeReading < IRP_3.sensorAvg/LRAvg) { // right wall gone, left wall is there RED 00504 // serial.printf("Left wall\n"); 00505 if (currDir % 4 == 0) { 00506 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= L_WALL; 00507 } else if (currDir % 4 == 1) { 00508 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= F_WALL; 00509 } else if (currDir % 4 == 2) { 00510 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= R_WALL; 00511 } else if (currDir % 4 == 3) { 00512 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= B_WALL; 00513 } 00514 } else if (receiverTwoReading < IRP_2.sensorAvg/LRAvg) { // left wall gone, right wall is there 00515 // serial.printf("Right wall\n"); 00516 if (currDir % 4 == 0) { 00517 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= R_WALL; 00518 } else if (currDir % 4 == 1) { 00519 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= B_WALL; 00520 } else if (currDir % 4 == 2) { 00521 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= L_WALL; 00522 } else if (currDir % 4 == 3) { 00523 wallArray[MAZE_LEN - 1 - (mouseY)][mouseX] |= F_WALL; 00524 } 00525 } else if ((receiverTwoReading > ((IRP_2.sensorAvg)*averageDivUpper)) && (receiverThreeReading > ((IRP_3.sensorAvg)*averageDivUpper))) { 00526 // serial.printf("Both walls \n"); 00527 if (currDir %4 == 0) { 00528 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= R_WALL; 00529 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= L_WALL; 00530 } else if (currDir %4 == 1) { 00531 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= F_WALL; 00532 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= B_WALL; 00533 } else if (currDir % 4 == 2) { 00534 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= R_WALL; 00535 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= L_WALL; 00536 } else if (currDir %4 == 3) { 00537 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= F_WALL; 00538 wallArray[MAZE_LEN - 1 - mouseY][mouseX] |= B_WALL; 00539 } 00540 } 00541 } 00542 } 00543 00544 bool isWallInFront(int x, int y) 00545 { 00546 return (wallArray[MAZE_LEN - y - 1][x] & F_WALL); 00547 } 00548 bool isWallInBack(int x, int y) 00549 { 00550 return (wallArray[MAZE_LEN - y - 1][x] & B_WALL); 00551 } 00552 bool isWallOnRight(int x, int y) 00553 { 00554 return (wallArray[MAZE_LEN - y - 1][x] & R_WALL); 00555 } 00556 bool isWallOnLeft(int x, int y) 00557 { 00558 return (wallArray[MAZE_LEN - y - 1][x] & L_WALL); 00559 } 00560 00561 int chooseNextMovement() 00562 { 00563 int currentDistance = manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX]; 00564 if (goingToCenter && (currentDistance == 0)) { 00565 goingToCenter = false; 00566 changeManhattanDistance(goingToCenter); 00567 } else if (!goingToCenter && (currentDistance == 0)) { 00568 goingToCenter = true; 00569 changeManhattanDistance(goingToCenter); 00570 } 00571 00572 visitedCells[MAZE_LEN - 1 - mouseY][mouseX] = 1; 00573 int currX = 0; 00574 int currY = 0; 00575 int currDist = 0; 00576 int dirToGo = 0; 00577 if (!justTurned) { 00578 cellsToVisit.push(make_pair(mouseX, mouseY)); 00579 while (!cellsToVisit.empty()) { 00580 pair<int, int> curr = cellsToVisit.top(); 00581 cellsToVisit.pop(); 00582 currX = curr.first; 00583 currY = curr.second; 00584 currDist = manhattanDistances[(MAZE_LEN - 1) - currY][currX]; 00585 int minDist = INT_MAX; 00586 00587 if (hasVisited(currX, currY)) { // then we want to actually see where the walls are, else we treat it as if there are no walls! 00588 if (currX + 1 < MAZE_LEN && !isWallOnRight(currX, currY)) { 00589 if (manhattanDistances[MAZE_LEN - 1 - currY][currX + 1] < minDist) { 00590 minDist = manhattanDistances[MAZE_LEN - 1 - currY][currX + 1]; 00591 } 00592 } 00593 if (currX - 1 >= 0 && !isWallOnLeft(currX, currY)) { 00594 if (manhattanDistances[MAZE_LEN - 1 - currY][currX - 1] < minDist) { 00595 minDist = manhattanDistances[MAZE_LEN - 1 - currY][currX - 1]; 00596 } 00597 } 00598 if (currY + 1 < MAZE_LEN && !isWallInFront( currX, currY)) { 00599 if (manhattanDistances[MAZE_LEN - 1 - (currY + 1)][currX] < minDist) { 00600 minDist = manhattanDistances[MAZE_LEN - 1 - (currY + 1)][currX]; 00601 } 00602 } 00603 if (currY - 1 >= 0 && !isWallInBack(currX, currY)) { 00604 if (manhattanDistances[MAZE_LEN - 1 - (currY - 1)][currX] < minDist) { 00605 minDist = manhattanDistances[MAZE_LEN - 1 - (currY - 1)][currX]; 00606 } 00607 } 00608 } else { 00609 if (currX + 1 < MAZE_LEN) { 00610 if (manhattanDistances[MAZE_LEN - 1 - currY][currX + 1] < minDist) { 00611 minDist = manhattanDistances[MAZE_LEN - 1 - currY][currX + 1]; 00612 } 00613 } 00614 if (currX - 1 >= 0) { 00615 if (manhattanDistances[MAZE_LEN - 1 - currY][currX - 1] < minDist) { 00616 minDist = manhattanDistances[MAZE_LEN - 1 - currY][currX - 1]; 00617 } 00618 } 00619 if (currY + 1 < MAZE_LEN) { 00620 if (manhattanDistances[MAZE_LEN - 1 - (currY + 1)][currX] < minDist) { 00621 minDist = manhattanDistances[MAZE_LEN - 1 - (currY + 1)][currX]; 00622 } 00623 } 00624 if (currY - 1 >= 0) { 00625 if (manhattanDistances[MAZE_LEN - 1 - (currY - 1)][currX] < minDist) { 00626 minDist = manhattanDistances[MAZE_LEN - 1 - (currY - 1)][currX]; 00627 } 00628 } 00629 } 00630 00631 if (minDist == INT_MAX) 00632 continue; 00633 if (currDist > minDist) 00634 continue; 00635 if (currDist <= minDist) { 00636 manhattanDistances[MAZE_LEN - 1 - currY][currX] = minDist + 1; 00637 } 00638 if (hasVisited(currX, currY)) { 00639 if (currY + 1 < MAZE_LEN && !isWallInFront(currX, currY)) { 00640 cellsToVisit.push(make_pair(currX, currY + 1)); 00641 } 00642 if (currX + 1 < MAZE_LEN && !isWallOnRight(currX, currY)) { 00643 cellsToVisit.push(make_pair(currX + 1, currY)); 00644 } 00645 if (currY - 1 >= 0 && !isWallInBack(currX, currY)) { 00646 cellsToVisit.push(make_pair(currX, currY - 1)); 00647 } 00648 if (currX - 1 >= 0 && !isWallOnLeft( currX, currY)) { 00649 cellsToVisit.push(make_pair(currX - 1, currY)); 00650 } 00651 } else { 00652 if (currY + 1 < MAZE_LEN) { 00653 cellsToVisit.push(make_pair(currX, currY + 1)); 00654 } 00655 if (currX + 1 < MAZE_LEN) { 00656 cellsToVisit.push(make_pair(currX + 1, currY)); 00657 } 00658 if (currY - 1 >= 0) { 00659 cellsToVisit.push(make_pair(currX, currY - 1)); 00660 } 00661 if (currX - 1 >= 0) { 00662 cellsToVisit.push(make_pair(currX - 1, currY)); 00663 } 00664 } 00665 } 00666 00667 int minDistance = INT_MAX; 00668 if (currDir % 4 == 0) { 00669 if (mouseX + 1 < MAZE_LEN && !isWallOnRight(mouseX, mouseY)) { 00670 if (manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX + 1] <= minDistance) { 00671 minDistance = manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX + 1]; 00672 dirToGo = 1; 00673 } 00674 } 00675 if (mouseX - 1 >= 0 && !isWallOnLeft(mouseX, mouseY)) { 00676 if (manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX - 1] <= minDistance) { 00677 minDistance = manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX - 1]; 00678 dirToGo = 2; 00679 } 00680 } 00681 if (mouseY + 1 < MAZE_LEN && !isWallInFront(mouseX, mouseY)) { 00682 if (manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX] <= minDistance) { 00683 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX]; 00684 dirToGo = 3; 00685 } 00686 } 00687 if (mouseY - 1 >= 0 && !isWallInBack(mouseX, mouseY)) { 00688 if (manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX] <= minDistance) { 00689 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX]; 00690 dirToGo = 4; 00691 } 00692 } 00693 } else if (currDir % 4 == 2) { 00694 if (mouseX - 1 >= 0 && !isWallOnLeft(mouseX, mouseY)) { 00695 if (manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX - 1] <= minDistance) { 00696 minDistance = manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX - 1]; 00697 dirToGo = 1; 00698 } 00699 } 00700 if (mouseX + 1 < MAZE_LEN && !isWallOnRight(mouseX, mouseY)) { 00701 if (manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX + 1] <= minDistance) { 00702 minDistance = manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX + 1]; 00703 dirToGo = 2; 00704 } 00705 } 00706 if (mouseY - 1 >= 0 && !isWallInBack(mouseX, mouseY)) { 00707 if (manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX] <= minDistance) { 00708 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX]; 00709 dirToGo = 3; 00710 } 00711 } 00712 if (mouseY + 1 < MAZE_LEN && !isWallInFront(mouseX, mouseY)) { 00713 if (manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX] <= minDistance) { 00714 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX]; 00715 dirToGo = 4; 00716 } 00717 } 00718 } else if (currDir % 4 == 1) { 00719 if (mouseY - 1 >= 0 && !isWallInBack(mouseX, mouseY)) { 00720 if (manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX] <= minDistance) { 00721 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX]; 00722 dirToGo = 1; 00723 } 00724 } 00725 if (mouseY + 1 < MAZE_LEN && !isWallInFront(mouseX, mouseY)) { 00726 if (manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX] <= minDistance) { 00727 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX]; 00728 // serial.printf("Looks like the left wall was not there\n"); 00729 dirToGo = 2; 00730 } 00731 } 00732 if (mouseX + 1 < MAZE_LEN && !isWallOnRight(mouseX, mouseY)) { 00733 if (manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX + 1] <= minDistance) { 00734 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY)][mouseX + 1]; 00735 dirToGo = 3; 00736 } 00737 } 00738 if (mouseX - 1 >= 0 && !isWallOnLeft(mouseX, mouseY)) { 00739 if (manhattanDistances[MAZE_LEN - 1 - (mouseY)][mouseX - 1] <= minDistance) { 00740 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY)][mouseX - 1]; 00741 dirToGo = 4; 00742 } 00743 } 00744 } else if (currDir % 4 == 3) { 00745 if (mouseY + 1 < MAZE_LEN && !isWallInFront(mouseX, mouseY)) { 00746 if (manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX] <= minDistance) { 00747 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY + 1)][mouseX]; 00748 dirToGo = 1; 00749 } 00750 } 00751 if (mouseY - 1 >= 0 && !isWallInBack(mouseX, mouseY)) { 00752 if (manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX] <= minDistance) { 00753 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY - 1)][mouseX]; 00754 dirToGo = 2; 00755 } 00756 } 00757 if (mouseX - 1 >= 0 && !isWallOnLeft(mouseX, mouseY)) { 00758 if (manhattanDistances[MAZE_LEN - 1 - mouseY][mouseX - 1] <= minDistance) { 00759 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY)][mouseX - 1]; 00760 dirToGo = 3; 00761 } 00762 } 00763 if (mouseX + 1 < MAZE_LEN && !isWallOnRight(mouseX, mouseY)) { 00764 if (manhattanDistances[MAZE_LEN - 1 - (mouseY)][mouseX + 1] <= minDistance) { 00765 minDistance = manhattanDistances[MAZE_LEN - 1 - (mouseY)][mouseX + 1]; 00766 dirToGo = 4; 00767 } 00768 } 00769 } 00770 } else { 00771 justTurned = false; 00772 dirToGo = 0; 00773 } 00774 00775 return dirToGo; 00776 } 00777 00778 bool hasVisited(int x, int y) 00779 { 00780 return visitedCells[MAZE_LEN - 1 - y][x]; 00781 } 00782 00783 void changeManhattanDistance(bool headCenter) 00784 { 00785 if (headCenter) { 00786 for (int i = 0; i < MAZE_LEN; i++) { 00787 for (int j = 0; j < MAZE_LEN; j++) { 00788 distanceToCenter[i][j] = manhattanDistances[i][j]; 00789 } 00790 } 00791 for (int i = 0; i < MAZE_LEN; i++) { 00792 for (int j = 0; j < MAZE_LEN; j++) { 00793 manhattanDistances[i][j] = distanceToStart[i][j]; 00794 } 00795 } 00796 } else { 00797 for (int i = 0; i < MAZE_LEN; i++) { 00798 for (int j = 0; j < MAZE_LEN; j++) { 00799 distanceToStart[i][j] = manhattanDistances[i][j]; 00800 } 00801 } 00802 for (int i = 0; i < MAZE_LEN; i++) { 00803 for (int j = 0; j < MAZE_LEN; j++) { 00804 manhattanDistances[i][j] = distanceToCenter[i][j]; 00805 } 00806 } 00807 } 00808 } 00809 00810 void initializeDistances() 00811 { 00812 for (int i = 0; i < MAZE_LEN / 2; i++) { 00813 for (int j = 0; j < MAZE_LEN / 2; j++) { 00814 distanceToStart[MAZE_LEN - 1 - j][i] = abs(0 - j) + abs(0 - i); 00815 } 00816 } 00817 for (int i = MAZE_LEN / 2; i < MAZE_LEN; i++) { 00818 for (int j = 0; j < MAZE_LEN / 2; j++) { 00819 distanceToStart[MAZE_LEN - 1 - j][i] = abs(0 - j) + abs(0 - i); 00820 } 00821 } 00822 for (int i = 0; i < MAZE_LEN / 2; i++) { 00823 for (int j = MAZE_LEN / 2; j < MAZE_LEN; j++) { 00824 distanceToStart[MAZE_LEN - 1 - j][i] = abs(0 - j) + abs(0 - i); 00825 } 00826 } 00827 for (int i = MAZE_LEN / 2; i < MAZE_LEN; i++) { 00828 for (int j = MAZE_LEN / 2; j < MAZE_LEN; j++) { 00829 distanceToStart[MAZE_LEN - 1 - j][i] = abs(0 - j) + abs(0 - i); 00830 } 00831 } 00832 } 00833 00834 void waitButton4() 00835 { 00836 //serial.printf("%d, %d, %d\n", dipFlags, BUTTON1_FLAG, dipFlags & BUTTON1_FLAG); 00837 int init_val = dipFlags & BUTTON4_FLAG; 00838 while( (dipFlags & BUTTON4_FLAG) == init_val ) { 00839 // do nothing until ready 00840 } 00841 //serial.printf("%d, %d, %d\n", dipFlags, BUTTON1_FLAG, dipFlags & BUTTON1_FLAG); 00842 wait( 3 ); 00843 } 00844 00845 int main() 00846 { 00847 //Set highest bandwidth. 00848 //gyro.setLpBandwidth(LPFBW_42HZ); 00849 initializeDistances(); 00850 serial.baud(9600); 00851 //serial.printf("The gyro's address is %s", gyro.getWhoAmI()); 00852 00853 wait (0.1); 00854 00855 redLed.write(1); 00856 greenLed.write(0); 00857 blueLed.write(1); 00858 00859 //left_motor.forward(0.1); 00860 //right_motor.forward(0.1); 00861 00862 // PA_1 is A of right 00863 // PA_0 is B of right 00864 // PA_5 is A of left 00865 // PB_3 is B of left 00866 //QEI encoder0( PA_5, PB_3, NC, PULSES, QEI::X4_ENCODING ); 00867 // QEI encoder1( PA_1, PA_0, NC, PULSES, QEI::X4_ENCODING ); 00868 00869 // TODO: Setting all the registers and what not for Quadrature Encoders 00870 /* RCC->APB1ENR |= 0x1001; // Enable clock for Tim2 (Bit 0) and Tim5 (Bit 3) 00871 RCC->AHB1ENR |= 0x11; // Enable GPIO port clock enables for Tim2(A) and Tim5(B) 00872 GPIOA->AFR[0] |= 0x10; // Set GPIO alternate function modes for Tim2 00873 GPIOB->AFR[0] |= 0x100; // Set GPIO alternate function modes for Tim5 00874 */ 00875 00876 // set GPIO pins to alternate for the pins corresponding to A/B for eacah encoder, and 2 alternate function registers need to be selected for each type 00877 // of alternate function specified 00878 // 4 modes sets AHB1ENR 00879 // Now TMR: enable clock with timer, APB1ENR 00880 // set period, autoreload value, ARR value 2^32-1, CR1 - TMR resets itself, ARPE and EN 00881 // 00882 // Encoder mode: disable timer before changing timer to encoder 00883 // CCMR1/2 1/2 depends on channel 1/2 or 3/4, depends on upper bits, depending which channels you use 00884 // CCMR sets sample rate and set the channel to input 00885 // CCER, which edge to trigger on, cannot be 11(not allowed for encoder mode), CCER for both channels 00886 // SMCR - encoder mode 00887 // CR1 reenabales 00888 // then read CNT reg of timer 00889 00890 dipButton1.rise(&enableButton1); 00891 dipButton2.rise(&enableButton2); 00892 dipButton3.rise(&enableButton3); 00893 dipButton4.rise(&enableButton4); 00894 00895 dipButton1.fall(&disableButton1); 00896 dipButton2.fall(&disableButton2); 00897 dipButton3.fall(&disableButton3); 00898 dipButton4.fall(&disableButton4); 00899 00900 //waitButton4(); 00901 00902 // init the wall, and mouse loc arrays: 00903 wallArray[MAZE_LEN - 1 - mouseY][mouseX] = 0xE; 00904 visitedCells[MAZE_LEN - 1 - mouseY][mouseX] = 1; 00905 00906 int prevEncoder0Count = 0; 00907 int prevEncoder1Count = 0; 00908 int currEncoder0Count = 0; 00909 int currEncoder1Count = 0; 00910 00911 bool overrideFloodFill = false; 00912 right_motor.forward( WHEEL_SPEED ); 00913 left_motor.forward( WHEEL_SPEED ); 00914 //turn180(); 00915 //wait_ms(1500); 00916 int nextMovement = 0; 00917 00918 // moveForwardEncoder(1); 00919 00920 while (1) { 00921 if (receiverOneReading < IRP_1.sensorAvg * frontStop && receiverFourReading < IRP_4.sensorAvg * frontStop ){ 00922 nCellEncoderAndIR(1); 00923 continue; 00924 } 00925 else if (receiverThreeReading < IRP_3.sensorAvg/LRAvg) { // right wall gone RED 00926 turnRight(); 00927 wait_ms(100); 00928 moveForwardEncoder(0.4); 00929 nCellEncoderAndIR(0.6); 00930 continue; 00931 } 00932 else if (receiverTwoReading < IRP_2.sensorAvg/LRAvg) { // left wall gone 00933 turnLeft(); 00934 wait_ms(100); 00935 moveForwardEncoder(0.4); 00936 nCellEncoderAndIR(0.6); 00937 continue; 00938 } 00939 else{ 00940 turn180(); 00941 wait_ms(100); 00942 moveForwardEncoder(0.4); 00943 nCellEncoderAndIR(0.6); 00944 continue; 00945 } 00946 00947 //////////////////////// TESTING CODE GOES BELOW /////////////////////////// 00948 00949 // encoderAfterTurn(1); 00950 // waitButton4(); 00951 // serial.printf("Encoder 0 is : %d \t Encoder 1 is %d\n",encoder0.getPulses(), encoder1.getPulses() ); 00952 // double currentError = ( (IRP_2.getSamples( SAMPLE_NUM ) - IRP_2.sensorAvg) ) - ( (IRP_3.getSamples( SAMPLE_NUM ) - IRP_3.sensorAvg) ) ; 00953 // serial.printf("IRS= >: %f, %f, %f, %f, %f \r\n", IRP_1.getSamples( 100 ), IRP_2.getSamples( 100 ), IRP_3.getSamples( 100 ), IRP_4.getSamples(100), currentError ); 00954 //encoderAfterTurn(1); 00955 //waitButton4(); 00956 } 00957 }
Generated on Tue Jul 12 2022 17:41:24 by
