single player mbedKart

Dependencies:   Motor

(notes)

Committer:
sli425
Date:
Mon Dec 10 05:12:07 2018 +0000
Revision:
12:4fec6ed886ab
Parent:
11:8d4b7702ac06
Child:
13:583181de031e
Added item logic to main branch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DerekW2015 0:a9a4c0fd5f8a 1 #include "mbed.h"
DerekW2015 0:a9a4c0fd5f8a 2 #include "Motor.h"
DerekW2015 0:a9a4c0fd5f8a 3 #include "rgbled.h"
DerekW2015 0:a9a4c0fd5f8a 4 #include "rgbSensor.h"
DerekW2015 0:a9a4c0fd5f8a 5
DerekW2015 11:8d4b7702ac06 6 // Define threads and mutexes
DerekW2015 11:8d4b7702ac06 7 Thread thread1;
DerekW2015 11:8d4b7702ac06 8 Thread thread2;
DerekW2015 11:8d4b7702ac06 9 Mutex motors_lock;
DerekW2015 11:8d4b7702ac06 10
DerekW2015 0:a9a4c0fd5f8a 11 // Define devices
DerekW2015 0:a9a4c0fd5f8a 12 Motor left(p22, p16, p15); // pwm, fwd, rev
DerekW2015 0:a9a4c0fd5f8a 13 Motor right(p23, p19, p20); // pwm, fwd, rev
DerekW2015 0:a9a4c0fd5f8a 14 BusOut myled(LED1,LED2,LED3,LED4);
DerekW2015 0:a9a4c0fd5f8a 15 RGBLed myRGBled(p26, p25, p24); // red, green, blue
DerekW2015 0:a9a4c0fd5f8a 16 rgbSensor rgbsensor(p28, p27);
DerekW2015 0:a9a4c0fd5f8a 17 Serial blue(p13, p14); // serial tx, serial rx
DerekW2015 11:8d4b7702ac06 18 enum speed_state { accelerating, braking, coasting };
DerekW2015 0:a9a4c0fd5f8a 19
sli425 3:6c749bff51aa 20 //Game state variables
sli425 3:6c749bff51aa 21 int progress = 0;
DerekW2015 11:8d4b7702ac06 22 int current_item = 0;
sli425 12:4fec6ed886ab 23 bool holding_item = false;
sli425 12:4fec6ed886ab 24 bool itembox = false;
DerekW2015 11:8d4b7702ac06 25 float speed_cmd = 0.0;
DerekW2015 11:8d4b7702ac06 26 float max_speed = 1.0;
DerekW2015 11:8d4b7702ac06 27 float acceleration_rate = 0.04;
DerekW2015 11:8d4b7702ac06 28 float brake_rate = 0.1;
DerekW2015 11:8d4b7702ac06 29 float coast_rate = 0.02;
sli425 3:6c749bff51aa 30 int cstate;
DerekW2015 11:8d4b7702ac06 31 speed_state sstate = coasting;
DerekW2015 6:57a0323bb6b7 32 bool collide = false;
sli425 3:6c749bff51aa 33
DerekW2015 0:a9a4c0fd5f8a 34 // Global game actions
DerekW2015 8:92bf0cc337b5 35 bool paused = false;
DerekW2015 8:92bf0cc337b5 36 void check_unpause() {
DerekW2015 8:92bf0cc337b5 37 char bnum=0;
DerekW2015 8:92bf0cc337b5 38 char bhit=0;
DerekW2015 8:92bf0cc337b5 39 while (true) {
DerekW2015 8:92bf0cc337b5 40 if (blue.getc()=='B') { //button data packet
DerekW2015 8:92bf0cc337b5 41 bnum = blue.getc(); //button number
DerekW2015 8:92bf0cc337b5 42 bhit = blue.getc(); //1=hit, 0=release
DerekW2015 8:92bf0cc337b5 43 if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
DerekW2015 8:92bf0cc337b5 44 if (bnum == '1') { //number button 1, pause
DerekW2015 8:92bf0cc337b5 45 if (bhit=='1') paused = false;
DerekW2015 8:92bf0cc337b5 46 }
DerekW2015 8:92bf0cc337b5 47 }
DerekW2015 8:92bf0cc337b5 48 }
DerekW2015 8:92bf0cc337b5 49 }
DerekW2015 8:92bf0cc337b5 50 }
sli425 12:4fec6ed886ab 51
DerekW2015 8:92bf0cc337b5 52 void game_paused() {
DerekW2015 8:92bf0cc337b5 53 // Cycle through LEDs
DerekW2015 8:92bf0cc337b5 54 Thread pause_thread;
DerekW2015 8:92bf0cc337b5 55 pause_thread.start(check_unpause);
DerekW2015 8:92bf0cc337b5 56 while (paused) {
DerekW2015 8:92bf0cc337b5 57 int num = 1;
DerekW2015 8:92bf0cc337b5 58 for (int i = 0; i < 3; i++) {
DerekW2015 8:92bf0cc337b5 59 num *= 2;
DerekW2015 8:92bf0cc337b5 60 myled = num;
DerekW2015 8:92bf0cc337b5 61 ThisThread::sleep_for(100);
DerekW2015 8:92bf0cc337b5 62 }
DerekW2015 8:92bf0cc337b5 63 ThisThread::sleep_for(500);
DerekW2015 8:92bf0cc337b5 64 for (int i = 3; i > 0; i--) {
DerekW2015 8:92bf0cc337b5 65 num /= 2;
DerekW2015 8:92bf0cc337b5 66 myled = num;
DerekW2015 8:92bf0cc337b5 67 ThisThread::sleep_for(100);
DerekW2015 8:92bf0cc337b5 68 }
DerekW2015 8:92bf0cc337b5 69 ThisThread::sleep_for(500);
DerekW2015 8:92bf0cc337b5 70 }
DerekW2015 11:8d4b7702ac06 71 }
DerekW2015 11:8d4b7702ac06 72
DerekW2015 11:8d4b7702ac06 73 // Thread to control speed
DerekW2015 11:8d4b7702ac06 74 void speed_control() {
DerekW2015 11:8d4b7702ac06 75 // The kart has to be in one of three states at all times
DerekW2015 11:8d4b7702ac06 76 while(1) {
DerekW2015 11:8d4b7702ac06 77 while(sstate == coasting) {
DerekW2015 11:8d4b7702ac06 78 if (speed_cmd > 0.0) {
DerekW2015 11:8d4b7702ac06 79 speed_cmd -= coast_rate;
DerekW2015 11:8d4b7702ac06 80 left.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 81 right.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 82 }
DerekW2015 11:8d4b7702ac06 83 ThisThread::sleep_for(200);
DerekW2015 11:8d4b7702ac06 84 }
DerekW2015 11:8d4b7702ac06 85 while(sstate == accelerating) {
DerekW2015 11:8d4b7702ac06 86 if (speed_cmd < 1.0) {
DerekW2015 11:8d4b7702ac06 87 speed_cmd += acceleration_rate;
DerekW2015 11:8d4b7702ac06 88 left.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 89 right.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 90 }
DerekW2015 11:8d4b7702ac06 91 ThisThread::sleep_for(200);
DerekW2015 11:8d4b7702ac06 92 }
DerekW2015 11:8d4b7702ac06 93 while(sstate == braking) {
DerekW2015 11:8d4b7702ac06 94 if (speed_cmd > 0.0) {
DerekW2015 11:8d4b7702ac06 95 speed_cmd -= brake_rate;
DerekW2015 11:8d4b7702ac06 96 left.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 97 right.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 98 }
DerekW2015 11:8d4b7702ac06 99 ThisThread::sleep_for(200);
DerekW2015 11:8d4b7702ac06 100 }
DerekW2015 11:8d4b7702ac06 101 }
DerekW2015 11:8d4b7702ac06 102 }
DerekW2015 11:8d4b7702ac06 103
DerekW2015 11:8d4b7702ac06 104 // Thread to brake
DerekW2015 11:8d4b7702ac06 105 void brake() {
DerekW2015 11:8d4b7702ac06 106 motors_lock.lock();
DerekW2015 11:8d4b7702ac06 107 myled = 8;
DerekW2015 11:8d4b7702ac06 108 while(1) {
DerekW2015 11:8d4b7702ac06 109 if (speed_cmd > 0.0) {
DerekW2015 11:8d4b7702ac06 110 speed_cmd -= brake_rate;
DerekW2015 11:8d4b7702ac06 111 left.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 112 right.speed(speed_cmd);
DerekW2015 11:8d4b7702ac06 113 }
DerekW2015 11:8d4b7702ac06 114 ThisThread::sleep_for(200);
DerekW2015 11:8d4b7702ac06 115 }
DerekW2015 11:8d4b7702ac06 116 }
DerekW2015 0:a9a4c0fd5f8a 117
sli425 3:6c749bff51aa 118 // Thread for checking rgb sensor values and updating game variables
sli425 3:6c749bff51aa 119 // Change later depending on behavior of RGB sensor and colors used
sli425 3:6c749bff51aa 120 int thresh = 150; //change this depending on RGB values
sli425 3:6c749bff51aa 121 void check_RGB() {
sli425 12:4fec6ed886ab 122 while(true){
sli425 12:4fec6ed886ab 123 rgbsensor.update();
sli425 12:4fec6ed886ab 124 int C_value = rgbsensor.get_C();
sli425 12:4fec6ed886ab 125 int R_value = rgbsensor.get_R();
sli425 12:4fec6ed886ab 126 int G_value = rgbsensor.get_G();
sli425 12:4fec6ed886ab 127 int B_value = rgbsensor.get_B();
sli425 12:4fec6ed886ab 128 if(C_value > thresh && R_value > thresh && G_value > thresh && B_value > thresh && current_item == 0) { //Check for if cart runs over an item box
sli425 12:4fec6ed886ab 129 itembox = true;
sli425 12:4fec6ed886ab 130 cstate = 0;
sli425 12:4fec6ed886ab 131 }
sli425 12:4fec6ed886ab 132 else if(C_value > thresh && R_value > thresh && G_value > thresh && B_value > thresh) { //Check for if cart runs over a speed boost panel
sli425 12:4fec6ed886ab 133 max_speed = 1; //change this depending on speed up panel algs
sli425 12:4fec6ed886ab 134 cstate = 0;
sli425 12:4fec6ed886ab 135 }
sli425 12:4fec6ed886ab 136 else if(C_value > thresh && R_value > thresh && G_value > thresh && B_value > thresh) { //Check if cart collides with wall
sli425 12:4fec6ed886ab 137 collide = true;
sli425 12:4fec6ed886ab 138 }
sli425 12:4fec6ed886ab 139 else if(C_value > thresh && R_value > thresh && G_value > thresh && B_value > thresh) { //Check if cart reaches next checkpoint. cstate is set to 1 upon seeing first color of checkpoint
sli425 12:4fec6ed886ab 140 cstate = 1;
sli425 12:4fec6ed886ab 141 }
sli425 12:4fec6ed886ab 142 else if(C_value > thresh && R_value > thresh && G_value > thresh && B_value > thresh && cstate == 1) {
sli425 12:4fec6ed886ab 143 //Second part of checking if cart reaches next checkpoint. If the previous color was passed through previously, updates checkpoint progress
sli425 12:4fec6ed886ab 144 cstate = 0;
sli425 12:4fec6ed886ab 145 progress++;
sli425 12:4fec6ed886ab 146 }
sli425 12:4fec6ed886ab 147 else {
sli425 12:4fec6ed886ab 148 cstate = 0;
sli425 12:4fec6ed886ab 149 }
sli425 12:4fec6ed886ab 150 ThisThread::sleep_for(500);
sli425 3:6c749bff51aa 151 }
sli425 3:6c749bff51aa 152 }
sli425 3:6c749bff51aa 153
sli425 12:4fec6ed886ab 154 void set_item() {
sli425 12:4fec6ed886ab 155 while(true){
sli425 12:4fec6ed886ab 156 if(itembox && current_item == 0) {
sli425 12:4fec6ed886ab 157 //playsound
sli425 12:4fec6ed886ab 158 for(int n = 0, n < 10, n++){ //flash the led to simulate slot machine effect
sli425 12:4fec6ed886ab 159 myRGBled(1.0,0.0,0.0);
sli425 12:4fec6ed886ab 160 ThisThread::sleep_for(50);
sli425 12:4fec6ed886ab 161 myRGBled(0.0,1.0,0.0);
sli425 12:4fec6ed886ab 162 ThisThread::sleep_for(50);
sli425 12:4fec6ed886ab 163 myRGBled(0.0,0.0,1.0);
sli425 12:4fec6ed886ab 164 ThisThread::sleep_for(50);
sli425 12:4fec6ed886ab 165 myRGBled(1.0,1.0,0.0);
sli425 12:4fec6ed886ab 166 ThisThread::sleep_for(50);
sli425 12:4fec6ed886ab 167 }
sli425 12:4fec6ed886ab 168 current_item = rand() % 4 + 1; //change this depending on items implemented and random item alg
sli425 12:4fec6ed886ab 169 if(current_item == 1){ //mushroom
sli425 12:4fec6ed886ab 170 myRGBled(1.0,0.0,0.0);
sli425 12:4fec6ed886ab 171 }
sli425 12:4fec6ed886ab 172 if(current_item == 2){ //green shell
sli425 12:4fec6ed886ab 173 myRGBled(0.0,1.0,0.0);
sli425 12:4fec6ed886ab 174 }
sli425 12:4fec6ed886ab 175 if(current_item == 3){ //blue shell
sli425 12:4fec6ed886ab 176 myRGBled(0.0,0.0,1.0);
sli425 12:4fec6ed886ab 177 }
sli425 12:4fec6ed886ab 178 if(current_item == 4){ //banana
sli425 12:4fec6ed886ab 179 myRGBled(1.0,1.0,0.0);
sli425 12:4fec6ed886ab 180 }
sli425 12:4fec6ed886ab 181 itembox = false;
sli425 12:4fec6ed886ab 182 }
sli425 12:4fec6ed886ab 183 ThisThread::sleep_for(500);
sli425 12:4fec6ed886ab 184 }
sli425 12:4fec6ed886ab 185 }
sli425 12:4fec6ed886ab 186
sli425 12:4fec6ed886ab 187 void hold_item() {
sli425 12:4fec6ed886ab 188 if(current_item == 0){
sli425 12:4fec6ed886ab 189 return;
sli425 12:4fec6ed886ab 190 }
sli425 12:4fec6ed886ab 191 if(current_item == 1){
sli425 12:4fec6ed886ab 192 max_speed = 1;
sli425 12:4fec6ed886ab 193 current_item = 0;
sli425 12:4fec6ed886ab 194 }
sli425 12:4fec6ed886ab 195 else{
sli425 12:4fec6ed886ab 196 holding_item = true;
sli425 12:4fec6ed886ab 197 }
sli425 12:4fec6ed886ab 198 return;
sli425 12:4fec6ed886ab 199 }
sli425 12:4fec6ed886ab 200
sli425 12:4fec6ed886ab 201 void release_item(){
sli425 12:4fec6ed886ab 202 holding_item = false;
sli425 12:4fec6ed886ab 203 if(current_item == 2){
sli425 12:4fec6ed886ab 204 //hit player in front
sli425 12:4fec6ed886ab 205 return;
sli425 12:4fec6ed886ab 206 }
sli425 12:4fec6ed886ab 207 if(current_item == 3){
sli425 12:4fec6ed886ab 208 //hit player in first
sli425 12:4fec6ed886ab 209 return;
sli425 12:4fec6ed886ab 210 }
sli425 12:4fec6ed886ab 211 if(current_item == 4){
sli425 12:4fec6ed886ab 212 //hit player behind
sli425 12:4fec6ed886ab 213 return;
sli425 12:4fec6ed886ab 214 }
sli425 12:4fec6ed886ab 215 }
sli425 12:4fec6ed886ab 216
sli425 12:4fec6ed886ab 217
DerekW2015 0:a9a4c0fd5f8a 218 int main() {
DerekW2015 0:a9a4c0fd5f8a 219 // Start threads
DerekW2015 9:6649141315be 220 thread1.start(check_RGB);
DerekW2015 11:8d4b7702ac06 221 thread2.start(speed_control); // Since we're stopped, this won't do anything
DerekW2015 0:a9a4c0fd5f8a 222
DerekW2015 0:a9a4c0fd5f8a 223 // Bluetooth controller code
DerekW2015 0:a9a4c0fd5f8a 224 char bnum=0;
DerekW2015 0:a9a4c0fd5f8a 225 char bhit=0;
DerekW2015 0:a9a4c0fd5f8a 226 while(1) {
DerekW2015 0:a9a4c0fd5f8a 227 if (blue.getc()=='!') {
DerekW2015 0:a9a4c0fd5f8a 228 if (blue.getc()=='B') { //button data packet
DerekW2015 0:a9a4c0fd5f8a 229 bnum = blue.getc(); //button number
DerekW2015 0:a9a4c0fd5f8a 230 bhit = blue.getc(); //1=hit, 0=release
DerekW2015 0:a9a4c0fd5f8a 231 if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
DerekW2015 0:a9a4c0fd5f8a 232 switch (bnum) {
DerekW2015 0:a9a4c0fd5f8a 233 case '1': //number button 1, pause
DerekW2015 0:a9a4c0fd5f8a 234 if (bhit=='1') {
DerekW2015 0:a9a4c0fd5f8a 235 //myled = bnum - '0'; //current button number will appear on LEDs
DerekW2015 8:92bf0cc337b5 236 paused = true;
DerekW2015 8:92bf0cc337b5 237 game_paused();
DerekW2015 0:a9a4c0fd5f8a 238 }
DerekW2015 0:a9a4c0fd5f8a 239 break;
DerekW2015 0:a9a4c0fd5f8a 240 case '2': //number button 2, accelerate
DerekW2015 0:a9a4c0fd5f8a 241 if (bhit=='1') {
DerekW2015 11:8d4b7702ac06 242 sstate = accelerating;
DerekW2015 0:a9a4c0fd5f8a 243 } else {
DerekW2015 11:8d4b7702ac06 244 sstate = coasting;
DerekW2015 0:a9a4c0fd5f8a 245 }
DerekW2015 0:a9a4c0fd5f8a 246 break;
DerekW2015 0:a9a4c0fd5f8a 247 case '3': //number button 3
DerekW2015 0:a9a4c0fd5f8a 248 if (bhit=='1') {
sli425 12:4fec6ed886ab 249 hold_item(); //holds item to protect player from incoming hazards
DerekW2015 0:a9a4c0fd5f8a 250 } else {
sli425 12:4fec6ed886ab 251 release_item(); //release item to attack
DerekW2015 0:a9a4c0fd5f8a 252 }
DerekW2015 0:a9a4c0fd5f8a 253 break;
DerekW2015 0:a9a4c0fd5f8a 254 case '4': //number button 4, brakes
DerekW2015 0:a9a4c0fd5f8a 255 if (bhit=='1') {
DerekW2015 0:a9a4c0fd5f8a 256 //myled = bnum - '0'; //current button number will appear on LEDs
DerekW2015 11:8d4b7702ac06 257 sstate = braking;
DerekW2015 0:a9a4c0fd5f8a 258 } else {
DerekW2015 11:8d4b7702ac06 259 sstate = coasting;
DerekW2015 0:a9a4c0fd5f8a 260 }
DerekW2015 0:a9a4c0fd5f8a 261 break;
DerekW2015 0:a9a4c0fd5f8a 262 case '5': //button 5 up arrow
DerekW2015 0:a9a4c0fd5f8a 263 if (bhit=='1') {
DerekW2015 0:a9a4c0fd5f8a 264 //myled = bnum - '0'; //current button number will appear on LEDs
DerekW2015 0:a9a4c0fd5f8a 265 //throw_item();
DerekW2015 0:a9a4c0fd5f8a 266 //item_box();
DerekW2015 0:a9a4c0fd5f8a 267 } else {
DerekW2015 0:a9a4c0fd5f8a 268
DerekW2015 0:a9a4c0fd5f8a 269 }
DerekW2015 0:a9a4c0fd5f8a 270 break;
DerekW2015 0:a9a4c0fd5f8a 271 case '6': //button 6 down arrow
DerekW2015 0:a9a4c0fd5f8a 272 if (bhit=='1') {
DerekW2015 11:8d4b7702ac06 273 //myled = bnum - '0'; //current button number will appear on LEDs
DerekW2015 0:a9a4c0fd5f8a 274 left.speed(-1.0);
DerekW2015 0:a9a4c0fd5f8a 275 right.speed(-1.0);
DerekW2015 0:a9a4c0fd5f8a 276 } else {
DerekW2015 0:a9a4c0fd5f8a 277 left.speed(0.0);
DerekW2015 0:a9a4c0fd5f8a 278 right.speed(0.0);
DerekW2015 0:a9a4c0fd5f8a 279 }
DerekW2015 0:a9a4c0fd5f8a 280 break;
DerekW2015 0:a9a4c0fd5f8a 281 case '7': //button 7 left arrow
DerekW2015 0:a9a4c0fd5f8a 282 if (bhit=='1') {
DerekW2015 0:a9a4c0fd5f8a 283 //myled = bnum - '0'; //current button number will appear on LEDs
DerekW2015 0:a9a4c0fd5f8a 284 left.speed(0.3);
DerekW2015 0:a9a4c0fd5f8a 285 right.speed(1.0);
DerekW2015 0:a9a4c0fd5f8a 286 } else {
DerekW2015 0:a9a4c0fd5f8a 287 left.speed(0.0);
DerekW2015 0:a9a4c0fd5f8a 288 right.speed(0.0);
DerekW2015 0:a9a4c0fd5f8a 289 }
DerekW2015 0:a9a4c0fd5f8a 290 break;
DerekW2015 0:a9a4c0fd5f8a 291 case '8': //button 8 right arrow
DerekW2015 0:a9a4c0fd5f8a 292 if (bhit=='1') {
DerekW2015 0:a9a4c0fd5f8a 293 //myled = bnum - '0'; //current button number will appear on LEDs
DerekW2015 0:a9a4c0fd5f8a 294 left.speed(1.0);
DerekW2015 0:a9a4c0fd5f8a 295 right.speed(0.3);
DerekW2015 0:a9a4c0fd5f8a 296 } else {
DerekW2015 0:a9a4c0fd5f8a 297 left.speed(0.0);
DerekW2015 0:a9a4c0fd5f8a 298 right.speed(0.0);
DerekW2015 0:a9a4c0fd5f8a 299 }
DerekW2015 0:a9a4c0fd5f8a 300 break;
DerekW2015 0:a9a4c0fd5f8a 301 default:
DerekW2015 0:a9a4c0fd5f8a 302 break;
DerekW2015 0:a9a4c0fd5f8a 303 }
DerekW2015 0:a9a4c0fd5f8a 304 }
DerekW2015 0:a9a4c0fd5f8a 305 }
DerekW2015 0:a9a4c0fd5f8a 306 }
DerekW2015 0:a9a4c0fd5f8a 307 }
DerekW2015 0:a9a4c0fd5f8a 308 }