NXP Group 13 / Mbed 2 deprecated Car3

Dependencies:   camera mbed tsi_sensor

Fork of Car2 by Zach Matthews

Committer:
lmstthomas
Date:
Tue Apr 18 17:50:55 2017 +0000
Revision:
25:74c12b0acf0c
Parent:
24:6219b8ce421f
Child:
26:4afa8c5c5156
added speed range using slider

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zamatthews 0:b761ef827157 1 #include "mbed.h"
zamatthews 6:971236e48adc 2 #include "Camera.h"
lmstthomas 22:9ef4a01e5038 3 #include "tsi_sensor.h"
zamatthews 17:846417c48571 4 #define STRAIGHT 0.00092f
lmstthomas 4:f4852befd69c 5 #define FULLRIGHT 0.0013f
zamatthews 14:c6f0a3c4e222 6 #define FULLLEFT 0.0005
zamatthews 14:c6f0a3c4e222 7 #define MIN_TURN_RATIO 0
zamatthews 14:c6f0a3c4e222 8 #define MAX_TURN_RATIO 1
lmstthomas 25:74c12b0acf0c 9 #define MIN_SPEED 0.13 //.15 seems to be optimal
lmstthomas 25:74c12b0acf0c 10 #define MAX_SPEED 0.4 //.5
lmstthomas 25:74c12b0acf0c 11 #define SPEED_TRIAL_MIN 0.25
lmstthomas 25:74c12b0acf0c 12 #define SPEED_TRIAL_MAX 0.55
zamatthews 17:846417c48571 13 #define TURN_TIME 0
lmstthomas 24:6219b8ce421f 14 #define STRAIGHT_TIME 20
lmstthomas 24:6219b8ce421f 15 #define START_FINISH_TIME 60
zamatthews 16:60e70bef7828 16 #define DEFAULT_THRESHOLD 65
zamatthews 17:846417c48571 17 #define BLIND_LENGTH 30
zamatthews 17:846417c48571 18 #define DIFF_RATIO 0.5
zamatthews 3:dadfc15fc2d1 19
lmstthomas 22:9ef4a01e5038 20 #if defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
lmstthomas 22:9ef4a01e5038 21 #define ELEC0 9
lmstthomas 22:9ef4a01e5038 22 #define ELEC1 10
lmstthomas 22:9ef4a01e5038 23 #elif defined (TARGET_KL05Z)
lmstthomas 22:9ef4a01e5038 24 #define ELEC0 9
lmstthomas 22:9ef4a01e5038 25 #define ELEC1 8
lmstthomas 22:9ef4a01e5038 26 #else
lmstthomas 22:9ef4a01e5038 27 #error TARGET NOT DEFINED
lmstthomas 22:9ef4a01e5038 28 #endif
lmstthomas 22:9ef4a01e5038 29
lmstthomas 25:74c12b0acf0c 30 float turn_speed = MIN_SPEED;
lmstthomas 25:74c12b0acf0c 31 float straight_speed = MAX_SPEED;
zamatthews 3:dadfc15fc2d1 32 PwmOut servo(PTE20);
zamatthews 5:137dfb3e692f 33 PwmOut motor_left(PTA5);
zamatthews 5:137dfb3e692f 34 PwmOut motor_right(PTC8);
zamatthews 3:dadfc15fc2d1 35 DigitalOut DIR_L(PTD4);
zamatthews 3:dadfc15fc2d1 36 DigitalOut DIR_R(PTA4);
zamatthews 9:644102f863a5 37 Serial pc(USBTX, USBRX);
zamatthews 9:644102f863a5 38 Camera cam(PTE23, PTE21, PTB3);
lmstthomas 22:9ef4a01e5038 39 TSIAnalogSlider tsi(ELEC0, ELEC1, 40);
zamatthews 11:45f345aad8ba 40 int turnCounter = 0;
zamatthews 16:60e70bef7828 41 int threshold = DEFAULT_THRESHOLD;
zamatthews 11:45f345aad8ba 42 float wheelPos = STRAIGHT;
zamatthews 19:25f22034a3e2 43 bool idle = true;
zamatthews 16:60e70bef7828 44 int leftBlind = 0;
zamatthews 16:60e70bef7828 45 int rightBlind = 0;
lmstthomas 22:9ef4a01e5038 46 float lastSlide;
zamatthews 20:ebdfeb37309c 47 int numDarks = 0;
lmstthomas 24:6219b8ce421f 48 int minLightGap = 1;
lmstthomas 24:6219b8ce421f 49 int maxLightGap = 55;
lmstthomas 24:6219b8ce421f 50 int minDarkBlock = 4;
lmstthomas 24:6219b8ce421f 51 int maxDarkBlock = 40;
lmstthomas 24:6219b8ce421f 52 int positionOffThreshold = 3;
lmstthomas 24:6219b8ce421f 53 struct darkBlock *darkBlockHead;
zamatthews 20:ebdfeb37309c 54 PwmOut led(LED_GREEN);
lmstthomas 22:9ef4a01e5038 55 PwmOut redLed(LED_RED);
zamatthews 0:b761ef827157 56
zamatthews 12:4ccf304800fe 57 /*
zamatthews 12:4ccf304800fe 58 Function: setAccel
zamatthews 12:4ccf304800fe 59 Description: Sets the speed for the right and left motors individually based
zamatthews 12:4ccf304800fe 60 on the turning angle.
zamatthews 12:4ccf304800fe 61 */
zamatthews 19:25f22034a3e2 62 void setAccel(float turnAngle){
zamatthews 20:ebdfeb37309c 63 //idle = false;
zamatthews 19:25f22034a3e2 64 if(!idle){
zamatthews 19:25f22034a3e2 65 turnAngle -= STRAIGHT; //this gets a value from -0.00035 and +0.00035
zamatthews 19:25f22034a3e2 66 float turnRatio = abs(turnAngle)/ (FULLRIGHT - STRAIGHT);
lmstthomas 25:74c12b0acf0c 67 float newSpeed = ((straight_speed - turn_speed)*(1-turnRatio)/3)+turn_speed;
zamatthews 19:25f22034a3e2 68 motor_left.write(newSpeed + DIFF_RATIO * newSpeed * (turnAngle / (STRAIGHT - FULLLEFT)));
zamatthews 19:25f22034a3e2 69 motor_right.write(newSpeed - DIFF_RATIO * newSpeed * (turnAngle / (FULLRIGHT - STRAIGHT)));
zamatthews 19:25f22034a3e2 70 }
zamatthews 19:25f22034a3e2 71 else{
zamatthews 19:25f22034a3e2 72 motor_left.write(0);
zamatthews 19:25f22034a3e2 73 motor_right.write(0);
zamatthews 19:25f22034a3e2 74 }
zamatthews 12:4ccf304800fe 75 }//end setAccel
zamatthews 3:dadfc15fc2d1 76
zamatthews 12:4ccf304800fe 77 /*
zamatthews 12:4ccf304800fe 78 Function: turnWheels
zamatthews 12:4ccf304800fe 79 Description: Turns the wheels in order to stay between two black lines seen
zamatthews 12:4ccf304800fe 80 by the camera
zamatthews 12:4ccf304800fe 81 */
zamatthews 14:c6f0a3c4e222 82 void turnWheels(int frame[]){
zamatthews 10:246782426144 83 int positionSum = 0;
zamatthews 20:ebdfeb37309c 84 numDarks = 0;
zamatthews 10:246782426144 85 for(int i = 0; i < 128; i++){
zamatthews 16:60e70bef7828 86 if(frame[i] < threshold){
zamatthews 10:246782426144 87 positionSum += i;
zamatthews 10:246782426144 88 numDarks++;
zamatthews 10:246782426144 89 }
zamatthews 10:246782426144 90 }
zamatthews 10:246782426144 91 float averagePos = 0;
zamatthews 12:4ccf304800fe 92
zamatthews 14:c6f0a3c4e222 93 if (numDarks == 0) {
zamatthews 15:50d5cfa98425 94 if(turnCounter >= (STRAIGHT_TIME)){
zamatthews 15:50d5cfa98425 95 wheelPos = STRAIGHT;
zamatthews 15:50d5cfa98425 96 turnCounter = TURN_TIME;
zamatthews 16:60e70bef7828 97 leftBlind = 0;
zamatthews 16:60e70bef7828 98 rightBlind = 0;
zamatthews 15:50d5cfa98425 99 }
zamatthews 11:45f345aad8ba 100 }
zamatthews 12:4ccf304800fe 101
zamatthews 12:4ccf304800fe 102 else {
zamatthews 12:4ccf304800fe 103 averagePos = positionSum / numDarks;
zamatthews 16:60e70bef7828 104
zamatthews 16:60e70bef7828 105 if(((averagePos <= 64 - leftBlind)) && ((wheelPos >= STRAIGHT) || turnCounter >= TURN_TIME)){
zamatthews 16:60e70bef7828 106 float powerRatio = (averagePos / (64 - leftBlind)) * MAX_TURN_RATIO + MIN_TURN_RATIO;
zamatthews 15:50d5cfa98425 107 powerRatio = sqrt(powerRatio);
zamatthews 12:4ccf304800fe 108 wheelPos = STRAIGHT + (FULLRIGHT - STRAIGHT) * powerRatio;
zamatthews 12:4ccf304800fe 109 turnCounter = 0;
zamatthews 16:60e70bef7828 110 leftBlind = 0;
zamatthews 16:60e70bef7828 111 rightBlind = BLIND_LENGTH;
zamatthews 11:45f345aad8ba 112 }
zamatthews 12:4ccf304800fe 113
zamatthews 16:60e70bef7828 114 else if((averagePos >= 64 + rightBlind) && (wheelPos <= STRAIGHT || turnCounter >= TURN_TIME)){
zamatthews 16:60e70bef7828 115 float powerRatio = (1 - (averagePos - 64 - rightBlind) / (64 - rightBlind)) * MAX_TURN_RATIO + MIN_TURN_RATIO;
zamatthews 15:50d5cfa98425 116 powerRatio = sqrt(powerRatio);
zamatthews 12:4ccf304800fe 117 wheelPos = STRAIGHT - (STRAIGHT - FULLLEFT) * powerRatio;
zamatthews 12:4ccf304800fe 118 turnCounter = 0;
zamatthews 16:60e70bef7828 119 leftBlind = BLIND_LENGTH;
zamatthews 16:60e70bef7828 120 rightBlind = 0;
zamatthews 11:45f345aad8ba 121 }
zamatthews 14:c6f0a3c4e222 122 }
zamatthews 12:4ccf304800fe 123 turnCounter++;
zamatthews 10:246782426144 124 servo.pulsewidth(wheelPos);
zamatthews 3:dadfc15fc2d1 125 }
zamatthews 3:dadfc15fc2d1 126
lmstthomas 24:6219b8ce421f 127 struct darkBlock{
lmstthomas 24:6219b8ce421f 128 int position;
lmstthomas 24:6219b8ce421f 129 int length;
lmstthomas 24:6219b8ce421f 130 int TTL; //time to live
lmstthomas 24:6219b8ce421f 131 struct darkBlock *next;
lmstthomas 24:6219b8ce421f 132 struct darkBlock *prev;
lmstthomas 24:6219b8ce421f 133 };
lmstthomas 24:6219b8ce421f 134
zamatthews 19:25f22034a3e2 135 /*
zamatthews 19:25f22034a3e2 136 Function: detectStartFinish
zamatthews 19:25f22034a3e2 137 Description: detects the mark on the track that represents the start/finish line and toggles RUNNING
zamatthews 19:25f22034a3e2 138 */
zamatthews 19:25f22034a3e2 139 void detectStartFinish(int frame[]){
lmstthomas 24:6219b8ce421f 140
lmstthomas 24:6219b8ce421f 141 //idle override by touching the slider
lmstthomas 22:9ef4a01e5038 142 if(tsi.readPercentage() != lastSlide){
lmstthomas 22:9ef4a01e5038 143 idle = !idle;
lmstthomas 22:9ef4a01e5038 144 led = 0.0;
lmstthomas 25:74c12b0acf0c 145 turn_speed = MIN_SPEED + (SPEED_TRIAL_MIN - MIN_SPEED) * tsi.readPercentage();
lmstthomas 25:74c12b0acf0c 146 straight_speed = MAX_SPEED + (SPEED_TRIAL_MAX - MAX_SPEED) * tsi.readPercentage();
lmstthomas 22:9ef4a01e5038 147 wait(0.5);
lmstthomas 25:74c12b0acf0c 148
lmstthomas 22:9ef4a01e5038 149 }
lmstthomas 25:74c12b0acf0c 150 return;
lmstthomas 22:9ef4a01e5038 151 if(numDarks <= 15) return;
zamatthews 19:25f22034a3e2 152 for(int i = 0; i < 128; i++){
lmstthomas 24:6219b8ce421f 153
lmstthomas 24:6219b8ce421f 154 }
lmstthomas 24:6219b8ce421f 155
lmstthomas 24:6219b8ce421f 156 idle = !idle; //toggle idle
lmstthomas 24:6219b8ce421f 157 if(!idle){
lmstthomas 24:6219b8ce421f 158 led = 1.0 - led;
lmstthomas 24:6219b8ce421f 159 servo.pulsewidth(STRAIGHT);
lmstthomas 24:6219b8ce421f 160 wait(3);
lmstthomas 21:18f2dc256df2 161 }
lmstthomas 24:6219b8ce421f 162 else led = 1.0;
zamatthews 19:25f22034a3e2 163 }
zamatthews 19:25f22034a3e2 164
lmstthomas 23:6e1e142b7baf 165 /*
lmstthomas 23:6e1e142b7baf 166 Function: display
lmstthomas 23:6e1e142b7baf 167 Description: This function is used to display what the camera sees to a
lmstthomas 23:6e1e142b7baf 168 computer.
lmstthomas 23:6e1e142b7baf 169 *Before using this function, the car should be connected to the
lmstthomas 23:6e1e142b7baf 170 computer. The car should also not be running. This is necessary because
lmstthomas 23:6e1e142b7baf 171 printing while the car is running will slow it way down and potentially
lmstthomas 23:6e1e142b7baf 172 cause it to crash.
lmstthomas 23:6e1e142b7baf 173
lmstthomas 23:6e1e142b7baf 174 */
zamatthews 12:4ccf304800fe 175 void display(int frame[]){
zamatthews 12:4ccf304800fe 176 char draw = 'x';
zamatthews 12:4ccf304800fe 177 for(int i = 0; i< 128; i++){
zamatthews 17:846417c48571 178
zamatthews 17:846417c48571 179 if (frame[i] < threshold) draw = '|';
zamatthews 12:4ccf304800fe 180 else draw = '-';
zamatthews 12:4ccf304800fe 181 pc.printf("%c", draw);
zamatthews 12:4ccf304800fe 182 draw = 'x';
zamatthews 12:4ccf304800fe 183 }
zamatthews 20:ebdfeb37309c 184 pc.printf("\r");
zamatthews 3:dadfc15fc2d1 185 }
zamatthews 16:60e70bef7828 186
lmstthomas 23:6e1e142b7baf 187 /*
lmstthomas 23:6e1e142b7baf 188 Function: setThreshold
lmstthomas 23:6e1e142b7baf 189 Description: This function is used when the car first starts. It checks the
lmstthomas 23:6e1e142b7baf 190 lightest value and the darkest value it can find, averages them and uses
lmstthomas 23:6e1e142b7baf 191 that as the light/dark threshold.
lmstthomas 23:6e1e142b7baf 192 */
zamatthews 16:60e70bef7828 193 void setThreshold(){
zamatthews 16:60e70bef7828 194 cam.capture();
zamatthews 16:60e70bef7828 195 int low = 99;
zamatthews 16:60e70bef7828 196 int high = 0;
zamatthews 16:60e70bef7828 197 for(int i = 0; i < 128; i++){
zamatthews 16:60e70bef7828 198 if(cam.imageData[i] > high) high = cam.imageData[i];
zamatthews 16:60e70bef7828 199 if(cam.imageData[i] < low) low = cam.imageData[i];
zamatthews 16:60e70bef7828 200 }
lmstthomas 25:74c12b0acf0c 201 threshold = ((2 * low) + high) / 3;
zamatthews 16:60e70bef7828 202 }
zamatthews 16:60e70bef7828 203
zamatthews 2:0db7cc5ad6db 204 int main() {
zamatthews 16:60e70bef7828 205 setThreshold();
zamatthews 5:137dfb3e692f 206 motor_left.period_us(50);
zamatthews 5:137dfb3e692f 207 motor_right.period_us(50);
zamatthews 5:137dfb3e692f 208 DIR_R = 1;
zamatthews 2:0db7cc5ad6db 209 DIR_L = 0;
zamatthews 3:dadfc15fc2d1 210 servo.period(0.020f);
zamatthews 20:ebdfeb37309c 211 led = 1.0;
lmstthomas 22:9ef4a01e5038 212 redLed = 1.0;
lmstthomas 22:9ef4a01e5038 213 idle = true;
lmstthomas 22:9ef4a01e5038 214 lastSlide = tsi.readPercentage();
zamatthews 2:0db7cc5ad6db 215 while(1){
lmstthomas 24:6219b8ce421f 216 wait_ms(1);
zamatthews 9:644102f863a5 217 cam.capture();
zamatthews 12:4ccf304800fe 218 //display(cam.imageData);
zamatthews 19:25f22034a3e2 219 turnWheels(cam.imageData);
zamatthews 19:25f22034a3e2 220 setAccel(wheelPos);
lmstthomas 22:9ef4a01e5038 221 detectStartFinish(cam.imageData);
zamatthews 12:4ccf304800fe 222 }
zamatthews 12:4ccf304800fe 223 }