David's dead reckoning code for the LVBots competition on March 6th. Uses the mbed LPC1768, DRV8835, QTR-3RC, and two DC motors with encoders.
Dependencies: PololuEncoder Pacer mbed GeneralDebouncer
test.cpp
00001 // A file for testing routines that will not be used in the final firmware. 00002 00003 #include <mbed.h> 00004 #include "motors.h" 00005 #include <Pacer.h> 00006 00007 #include "main.h" 00008 #include "test.h" 00009 #include "leds.h" 00010 #include "encoders.h" 00011 #include "pc_serial.h" 00012 #include "line_sensors.h" 00013 #include "l3g.h" 00014 #include "turn_sensor.h" 00015 #include "reckoner.h" 00016 #include "buttons.h" 00017 00018 void __attribute__((noreturn)) infiniteReckonerReportLoop(); 00019 void printBar(const char * name, uint16_t adcResult); 00020 00021 void testLogger() 00022 { 00023 led1 = 1; 00024 while(!button1DefinitelyPressed()) 00025 { 00026 led3 = logger.isFull(); 00027 00028 updateReckoner(); 00029 loggerService(); 00030 } 00031 led2 = 1; 00032 loggerReportLoop(); 00033 } 00034 00035 void testCloseness() 00036 { 00037 doGyroCalibration(); 00038 turnSensor.start(); 00039 led1 = 1; 00040 while(1) 00041 { 00042 updateReckoner(); 00043 float magn = magnitude(); 00044 00045 led3 = magn < (1 << 5); 00046 led4 = magn < (1 << 7); 00047 } 00048 } 00049 00050 void showOrientationWithLeds34() 00051 { 00052 led3 = reckoner.cosv > 0; 00053 led4 = reckoner.sinv > 0; 00054 } 00055 00056 void testTurnInPlace() 00057 { 00058 doGyroCalibration(); 00059 turnSensor.start(); 00060 00061 led1 = 1; 00062 while(!button1DefinitelyPressed()) 00063 { 00064 updateReckoner(); 00065 showOrientationWithLeds34(); 00066 } 00067 led2 = 1; 00068 00069 Pacer motorUpdatePacer(10000); 00070 Timer timer; 00071 timer.start(); 00072 motorsSpeedSet(-300, 300); 00073 while(timer.read_ms() < 4000) 00074 { 00075 updateReckoner(); 00076 showOrientationWithLeds34(); 00077 } 00078 timer.reset(); 00079 00080 float integral = 0; 00081 while (timer.read_ms() < 4000) 00082 { 00083 if (motorUpdatePacer.pace()) 00084 { 00085 int16_t rotationSpeed; 00086 float s = (float)reckoner.sinv / (1 << RECKONER_LOG_UNIT); 00087 integral += s; 00088 rotationSpeed = -(s * 2400 + integral * 20); 00089 00090 if (rotationSpeed > 450) 00091 { 00092 rotationSpeed = 450; 00093 } 00094 if (rotationSpeed < -450) 00095 { 00096 rotationSpeed = -450; 00097 } 00098 00099 int16_t speedLeft = -rotationSpeed; 00100 int16_t speedRight = rotationSpeed; 00101 motorsSpeedSet(speedLeft, speedRight); 00102 } 00103 } 00104 00105 infiniteReckonerReportLoop(); 00106 } 00107 00108 // This also tests the LineTracker by printing out a lot of data from it. 00109 void testLineFollowing() 00110 { 00111 loadLineCalibration(); 00112 doGyroCalibration(); 00113 turnSensor.start(); 00114 00115 led1 = 1; 00116 while (!button1DefinitelyPressed()) 00117 { 00118 updateReckoner(); 00119 } 00120 00121 Pacer reportPacer(200000); 00122 00123 uint16_t loopCount = 0; 00124 while(1) 00125 { 00126 updateReckoner(); 00127 bool lineVisiblePrevious = lineTracker.getLineVisible(); 00128 lineTracker.read(); 00129 updateMotorsToFollowLine(); 00130 00131 loopCount += 1; 00132 00133 led2 = lineTracker.calibratedValues[0] > 500; 00134 led3 = lineTracker.calibratedValues[1] > 500; 00135 led4 = lineTracker.calibratedValues[2] > 500; 00136 00137 if (lineVisiblePrevious != lineTracker.getLineVisible()) 00138 { 00139 pc.printf("%5d ! %1d %4d | %5d %5d | %4d %4d %4d\r\n", 00140 loopCount, lineTracker.getLineVisible(), lineTracker.getLinePosition(), 00141 motorLeftSpeed, motorRightSpeed, 00142 lineTracker.calibratedValues[0], lineTracker.calibratedValues[1], lineTracker.calibratedValues[2] 00143 ); 00144 } 00145 00146 if (reportPacer.pace()) 00147 { 00148 pc.printf("%5d %1d %4d | %5d %5d | %4d %4d %4d\r\n", 00149 loopCount, lineTracker.getLineVisible(), lineTracker.getLinePosition(), 00150 motorLeftSpeed, motorRightSpeed, 00151 lineTracker.calibratedValues[0], lineTracker.calibratedValues[1], lineTracker.calibratedValues[2] 00152 ); 00153 } 00154 } 00155 } 00156 00157 void testDriveHome() 00158 { 00159 doGyroCalibration(); 00160 turnSensor.start(); 00161 led1 = 1; 00162 while(!button1DefinitelyPressed()) 00163 { 00164 updateReckoner(); 00165 } 00166 00167 setLeds(1, 0, 1, 0); 00168 driveHomeAlmost(); 00169 00170 //setLeds(0, 1, 1, 0); 00171 //finalSettleIn(); 00172 00173 setLeds(1, 1, 1, 1); 00174 infiniteReckonerReportLoop(); 00175 } 00176 00177 void testFinalSettleIn() 00178 { 00179 doGyroCalibration(); 00180 turnSensor.start(); 00181 led1 = 1; 00182 while(!button1DefinitelyPressed()) 00183 { 00184 updateReckoner(); 00185 } 00186 finalSettleIn(); 00187 infiniteReckonerReportLoop(); 00188 } 00189 00190 00191 void testButtons() 00192 { 00193 led1 = 1; 00194 00195 while(!button1DefinitelyReleased()); 00196 while(!button1DefinitelyPressed()); 00197 led2 = 1; 00198 00199 while(!button1DefinitelyReleased()); 00200 while(!button1DefinitelyPressed()); 00201 led3 = 1; 00202 00203 while(!button1DefinitelyReleased()); 00204 while(!button1DefinitelyPressed()); 00205 led4 = 1; 00206 00207 while(1){}; 00208 } 00209 00210 void testReckoner() 00211 { 00212 doGyroCalibration(); 00213 turnSensor.start(); 00214 led1 = 1; 00215 Pacer reportPacer(100000); 00216 while(1) 00217 { 00218 updateReckoner(); 00219 00220 led1 = reckoner.x > 0; 00221 led2 = reckoner.y > 0; 00222 showOrientationWithLeds34(); 00223 00224 if (reportPacer.pace()) 00225 { 00226 pc.printf("%6d %6d %11d %11d | %8d %8d %10f\r\n", 00227 reckoner.cosv, reckoner.sinv, reckoner.x, reckoner.y, 00228 encoderLeft.getCount(), encoderRight.getCount(), determinant()); 00229 } 00230 } 00231 } 00232 00233 void testTurnSensor() 00234 { 00235 pc.printf("Test turn sensor\r\n"); 00236 doGyroCalibration(); 00237 led1 = 1; 00238 //Pacer reportPacer(200000); // 0.2 s 00239 Pacer reportPacer(10000000); // 10 s 00240 Timer timer; 00241 timer.start(); 00242 turnSensor.start(); 00243 while(1) 00244 { 00245 turnSensor.update(); 00246 if (reportPacer.pace()) 00247 { 00248 pc.printf("%u, %d, %d\r\n", 00249 timer.read_ms(), 00250 turnSensor.getAngleDegrees(), 00251 turnSensor.getAngleMillidegrees()); 00252 } 00253 } 00254 } 00255 00256 void testL3gAndShowAverage() 00257 { 00258 wait_ms(2000); 00259 Pacer reportPacer(750000); 00260 Pacer readingPacer(2000); 00261 int32_t total = 0; 00262 int32_t readingCount = 0; 00263 while(1) 00264 { 00265 if (readingPacer.pace()) 00266 { 00267 int32_t result = l3gZAvailable(); 00268 if (result == 1) 00269 { 00270 int32_t gz = l3gZRead(); 00271 if (gz < -500000) 00272 { 00273 pc.printf("l3gZRead error: %d\n", gz); 00274 } 00275 else 00276 { 00277 total += gz; 00278 readingCount += 1; 00279 } 00280 } 00281 else if (result != 0) 00282 { 00283 pc.printf("l3gZAvailable error: %d\n", result); 00284 } 00285 } 00286 00287 if (reportPacer.pace()) 00288 { 00289 float average = (float)total / readingCount; 00290 pc.printf("%d, %d, %f\r\n", total, readingCount, average); 00291 } 00292 } 00293 00294 // Gyro calibration results get hardcoded into TurnSensor::update() 00295 // for now until we figure out something better. 00296 } 00297 00298 void testL3g() 00299 { 00300 Pacer reportPacer(750000); 00301 Timer timer; 00302 timer.start(); 00303 int32_t gz = 0; 00304 bool reportedReading = false; 00305 while(1) 00306 { 00307 int32_t result = l3gZAvailable(); 00308 if (result == 1) 00309 { 00310 gz = l3gZRead(); 00311 reportedReading = false; 00312 if (gz > 100 || gz < -100) 00313 { 00314 pc.printf("%u, %d\r\n", timer.read_us(), gz); 00315 reportedReading = true; 00316 } 00317 } 00318 else if (result != 0) 00319 { 00320 pc.printf("l3gZAvailable error: %d\n", result); 00321 } 00322 00323 if (reportPacer.pace() && !reportedReading) 00324 { 00325 pc.printf("%u, %d\r\n", timer.read_us(), gz); 00326 reportedReading = true; 00327 } 00328 } 00329 } 00330 00331 void testLineSensorsAndCalibrate() 00332 { 00333 Pacer reportPacer(100000); 00334 00335 const uint16_t * values = lineTracker.rawValues; 00336 const uint16_t * min = lineTracker.calibratedMinimum; 00337 const uint16_t * max = lineTracker.calibratedMaximum; 00338 const uint16_t * calValues = lineTracker.calibratedValues; 00339 00340 // Comment this out, and hold down button 1 while exposing the line sensor 00341 // to its typical surfaces to do calibration. 00342 loadLineCalibration(); 00343 00344 const bool printBarGraph = true; 00345 while (1) 00346 { 00347 lineTracker.read(); 00348 00349 if (button1DefinitelyPressed()) 00350 { 00351 led1 = 0; 00352 lineTracker.updateCalibration(); 00353 } 00354 else 00355 { 00356 led1 = 1; 00357 } 00358 00359 led2 = calValues[0] > 500; 00360 led3 = calValues[1] > 500; 00361 led4 = calValues[2] > 500; 00362 00363 if (reportPacer.pace()) 00364 { 00365 if (printBarGraph) 00366 { 00367 pc.printf("\x1B[0;0H"); // VT100 command for "go to 0,0" 00368 printBar("L", values[0]); 00369 printBar("M", values[1]); 00370 printBar("R", values[2]); 00371 pc.printf("%4d %4d \r\n", min[0], max[0]); 00372 pc.printf("%4d %4d \r\n", min[1], max[1]); 00373 pc.printf("%4d %4d \r\n", min[2], max[2]); 00374 } 00375 else 00376 { 00377 pc.printf("%8d %8d %8d\r\n", values[0], values[1], values[2]); 00378 } 00379 } 00380 } 00381 } 00382 00383 void testMotorSpeed() 00384 { 00385 led1 = 1; 00386 motorsSpeedSet(400, 400); 00387 wait_ms(4000); 00388 uint32_t left = encoderLeft.getCount(); 00389 uint32_t right = encoderRight.getCount(); 00390 motorsSpeedSet(0, 0); 00391 Pacer reportPacer(500000); 00392 while (1) 00393 { 00394 if (reportPacer.pace()) 00395 { 00396 led2 = 1; 00397 pc.printf("%8d %8d\r\n", left, right); 00398 led2 = 0; 00399 } 00400 } 00401 } 00402 00403 void testEncoders() 00404 { 00405 Pacer reportPacer(500000); 00406 led1 = 1; 00407 while(1) 00408 { 00409 while(encoderBuffer.hasEvents()) 00410 { 00411 PololuEncoderEvent event = encoderBuffer.readEvent(); 00412 } 00413 00414 if(reportPacer.pace()) 00415 { 00416 led2 = 1; 00417 pc.printf("%8d %8d\r\n", encoderLeft.getCount(), encoderRight.getCount()); 00418 led2 = 0; 00419 } 00420 } 00421 } 00422 00423 void testMotors() 00424 { 00425 led1 = 1; 00426 led2 = 0; 00427 led3 = 0; 00428 while(1) 00429 { 00430 motorsSpeedSet(0, 0); 00431 led2 = 0; 00432 led3 = 0; 00433 wait(2); 00434 00435 motorsSpeedSet(300, 300); 00436 wait(2); 00437 00438 motorsSpeedSet(-300, 300); 00439 wait(2); 00440 00441 motorsSpeedSet(0, 0); 00442 led2 = 1; 00443 wait(2); 00444 00445 motorsSpeedSet(600, 600); 00446 wait(2); 00447 00448 motorsSpeedSet(0, 0); 00449 led3 = 1; 00450 wait(2); 00451 00452 motorsSpeedSet(1200, 1200); 00453 wait(2); 00454 } 00455 } 00456 00457 void infiniteReckonerReportLoop() 00458 { 00459 Pacer reportPacer(200000); 00460 while(1) 00461 { 00462 showOrientationWithLeds34(); 00463 if(reportPacer.pace()) 00464 { 00465 pc.printf("%6d %6d %11d %11d | %11f %11f\r\n", 00466 reckoner.cosv, reckoner.sinv, reckoner.x, reckoner.y, 00467 determinant(), dotProduct()); 00468 } 00469 } 00470 } 00471 00472 // with should be between 0 and 63 00473 void printBar(const char * name, uint16_t result) 00474 { 00475 pc.printf("%-2s %5d |", name, result); 00476 uint16_t width = result >> 4; 00477 if (width > 63) { width = 63; } 00478 uint8_t i; 00479 for(i = 0; i < width; i++){ pc.putc('#'); } 00480 for(; i < 63; i++){ pc.putc(' '); } 00481 pc.putc('|'); 00482 pc.putc('\r'); 00483 pc.putc('\n'); 00484 }
Generated on Sun Jul 17 2022 15:45:15 by 1.7.2