First draft of Wii Robot Racing, a simple example of using Wii Remote connected via bluetooth to control an m3pi robot, plus RFID \"powerups\" to modify behaviour

Dependencies:   mbed m3pi ID12RFIDIRQ

Committer:
simon
Date:
Mon Apr 11 23:03:22 2011 +0000
Revision:
0:e2ef12467862

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:e2ef12467862 1 // mbed Robot Racing Wii example
simon 0:e2ef12467862 2 // Connects to Wii Wheel/Remote to get control input to drive m3pi robots
simon 0:e2ef12467862 3 // Also has RFID reader to trigger different powerups/slowdowns
simon 0:e2ef12467862 4 // Robot has a simple inertial model to give it a more natural car-like driving acceleration and deceleration
simon 0:e2ef12467862 5
simon 0:e2ef12467862 6 #include "mbed.h"
simon 0:e2ef12467862 7
simon 0:e2ef12467862 8 #include "USBHost.h" // Peter Barratt's USB Bluetooth Dongle code
simon 0:e2ef12467862 9 #include "m3pi.h" // m3pi robot controls
simon 0:e2ef12467862 10 #include "Wiimote.h" // Wii Remote message decoding
simon 0:e2ef12467862 11 #include "ID12RFID.h" // RFID reader
simon 0:e2ef12467862 12
simon 0:e2ef12467862 13 Serial pc(USBTX, USBRX);
simon 0:e2ef12467862 14 m3pi m3pi(p8,p9,p10);
simon 0:e2ef12467862 15
simon 0:e2ef12467862 16 ID12RFID rfid(p14);
simon 0:e2ef12467862 17
simon 0:e2ef12467862 18 #define ACCELERATE 0.02
simon 0:e2ef12467862 19 #define DECAY 0.01
simon 0:e2ef12467862 20
simon 0:e2ef12467862 21 static float clamp(float v, float mn, float mx) {
simon 0:e2ef12467862 22 return (v < mn) ? mn : (v > mx) ? mx : v;
simon 0:e2ef12467862 23 }
simon 0:e2ef12467862 24
simon 0:e2ef12467862 25 Timer banana;
simon 0:e2ef12467862 26
simon 0:e2ef12467862 27 // indicate a banana has been hit
simon 0:e2ef12467862 28 void banana_hit() {
simon 0:e2ef12467862 29 banana.reset();
simon 0:e2ef12467862 30 banana.start();
simon 0:e2ef12467862 31 }
simon 0:e2ef12467862 32
simon 0:e2ef12467862 33 // see if there is any impact from bananas!
simon 0:e2ef12467862 34 // returns 1.0 for full pain, decaying to 0.0 over time
simon 0:e2ef12467862 35 float banana_impact() {
simon 0:e2ef12467862 36 if(banana > 2.0) {
simon 0:e2ef12467862 37 banana.stop();
simon 0:e2ef12467862 38 banana.reset();
simon 0:e2ef12467862 39 }
simon 0:e2ef12467862 40 if(banana > 0) {
simon 0:e2ef12467862 41 return clamp(2.0 - banana, 0.0, 1.0);
simon 0:e2ef12467862 42 } else {
simon 0:e2ef12467862 43 return 0;
simon 0:e2ef12467862 44 }
simon 0:e2ef12467862 45 }
simon 0:e2ef12467862 46
simon 0:e2ef12467862 47 #define NORMAL_SPEED 0.3
simon 0:e2ef12467862 48
simon 0:e2ef12467862 49 volatile float max_speed = NORMAL_SPEED;
simon 0:e2ef12467862 50 volatile float velocity = 0;
simon 0:e2ef12467862 51
simon 0:e2ef12467862 52 Timer boost;
simon 0:e2ef12467862 53
simon 0:e2ef12467862 54 void boost_impact() {
simon 0:e2ef12467862 55 if(boost > 2.0) {
simon 0:e2ef12467862 56 boost.stop();
simon 0:e2ef12467862 57 boost.reset();
simon 0:e2ef12467862 58 max_speed = NORMAL_SPEED;
simon 0:e2ef12467862 59 }
simon 0:e2ef12467862 60 }
simon 0:e2ef12467862 61
simon 0:e2ef12467862 62 void boost_hit() {
simon 0:e2ef12467862 63 max_speed = .7;
simon 0:e2ef12467862 64 velocity = .7;
simon 0:e2ef12467862 65 boost.reset();
simon 0:e2ef12467862 66 boost.start();
simon 0:e2ef12467862 67 }
simon 0:e2ef12467862 68
simon 0:e2ef12467862 69 void slowmo_hit() {
simon 0:e2ef12467862 70 max_speed = 0.15;
simon 0:e2ef12467862 71 velocity = 0.0;
simon 0:e2ef12467862 72 boost.reset();
simon 0:e2ef12467862 73 boost.start();
simon 0:e2ef12467862 74 }
simon 0:e2ef12467862 75
simon 0:e2ef12467862 76 // this is called by the USB infrastructure when a wii message comes in
simon 0:e2ef12467862 77 void wii_data(char * data) {
simon 0:e2ef12467862 78
simon 0:e2ef12467862 79 Wiimote wii;
simon 0:e2ef12467862 80 wii.decode(data);
simon 0:e2ef12467862 81
simon 0:e2ef12467862 82 // temporary action triggers
simon 0:e2ef12467862 83 if(wii.up) { banana_hit(); }
simon 0:e2ef12467862 84 if(wii.down) { boost_hit(); }
simon 0:e2ef12467862 85 if(wii.left) { slowmo_hit(); }
simon 0:e2ef12467862 86
simon 0:e2ef12467862 87 if(wii.two) { // active acceleration
simon 0:e2ef12467862 88 velocity += ACCELERATE;
simon 0:e2ef12467862 89 if(velocity > max_speed) { velocity = max_speed; }
simon 0:e2ef12467862 90 } else if(wii.one) { // active deceleration/reverse
simon 0:e2ef12467862 91 velocity -= ACCELERATE;
simon 0:e2ef12467862 92 if(velocity < -max_speed) { velocity = -max_speed; }
simon 0:e2ef12467862 93 } else { // decay to zero
simon 0:e2ef12467862 94 if(velocity < 0) {
simon 0:e2ef12467862 95 velocity += DECAY;
simon 0:e2ef12467862 96 if(velocity > 0) { velocity = 0; }
simon 0:e2ef12467862 97 } else {
simon 0:e2ef12467862 98 velocity -= DECAY;
simon 0:e2ef12467862 99 if(velocity < 0) { velocity = 0; }
simon 0:e2ef12467862 100 }
simon 0:e2ef12467862 101 }
simon 0:e2ef12467862 102
simon 0:e2ef12467862 103 float factor = wii.wheel / 190.0f;
simon 0:e2ef12467862 104
simon 0:e2ef12467862 105 float left_factor = (factor >= 0.0) ? 1.0 : 1.0 - (-factor);
simon 0:e2ef12467862 106 float right_factor = (factor <= 0.0) ? 1.0 : 1.0 - factor;
simon 0:e2ef12467862 107
simon 0:e2ef12467862 108 boost_impact();
simon 0:e2ef12467862 109 float impact = banana_impact();
simon 0:e2ef12467862 110
simon 0:e2ef12467862 111 if(impact > 0.0) {
simon 0:e2ef12467862 112 m3pi.left_motor(1 * impact);
simon 0:e2ef12467862 113 m3pi.right_motor(-1 * impact);
simon 0:e2ef12467862 114 velocity = 0;
simon 0:e2ef12467862 115 } else {
simon 0:e2ef12467862 116 m3pi.left_motor(velocity * right_factor);
simon 0:e2ef12467862 117 m3pi.right_motor(velocity * left_factor);
simon 0:e2ef12467862 118 }
simon 0:e2ef12467862 119 }
simon 0:e2ef12467862 120
simon 0:e2ef12467862 121 DigitalOut led_active(LED4);
simon 0:e2ef12467862 122
simon 0:e2ef12467862 123 int main() {
simon 0:e2ef12467862 124 pc.baud(38400);
simon 0:e2ef12467862 125
simon 0:e2ef12467862 126 printf("Hello Wii Racing...\n");
simon 0:e2ef12467862 127
simon 0:e2ef12467862 128 USBInit();
simon 0:e2ef12467862 129
simon 0:e2ef12467862 130
simon 0:e2ef12467862 131 while (1) {
simon 0:e2ef12467862 132 USBLoop();
simon 0:e2ef12467862 133 led_active = !led_active;
simon 0:e2ef12467862 134 if(rfid.readable()) {
simon 0:e2ef12467862 135 int id = rfid.read();
simon 0:e2ef12467862 136 // ignore id for now
simon 0:e2ef12467862 137 banana_hit();
simon 0:e2ef12467862 138 }
simon 0:e2ef12467862 139 }
simon 0:e2ef12467862 140 }