Code for the sword component of Clash!, a motion controlled pair of input devices for the game Chivalry: Medieval Warfare.
Dependencies: DebounceIn L3GD20 MMA8451Q USBDevice mbed
Fork of idd_hw3_ddrew73_fil_clashSword by
main.cpp
- Committer:
- ddrew73
- Date:
- 2017-06-12
- Revision:
- 1:bb8f49838af8
- Parent:
- 0:a7b02bcbe5fc
File content as of revision 1:bb8f49838af8:
/* CS294 Interactive Device Design - Homework 3 CLASH! Sword Daniel Drew Filip Maksimovic */ #include "mbed.h" #include "MMA8451Q.h" #include "DebounceIn.h" #include "L3GD20.h" #include "USBMouse.h" //FOR GESTURE DEBUGGING! Make sure to uncomment the object below! //#include "USBKeyboard.h" //Define I2C stuff for Accel, Gyro PinName const SDA1 = PTE25; PinName const SCL1 = PTE24; PinName const SDA2 = PTE0; PinName const SCL2 = PTE1; #define MMA8451_I2C_ADDRESS (0x1d<<1) int main() { //Object Instantiation Serial pc(USBTX, USBRX); // tx, rx USBMouse mouse; MMA8451Q acc(SDA1, SCL1, MMA8451_I2C_ADDRESS); DigitalOut myred(LED1); DigitalOut mygreen(LED2); DigitalOut myblue(LED3); L3GD20 gyro(SDA2, SCL2); //USBKeyboard key; //Variable Instantiation int i=0; int upcount = 0, totcount = 0, overready = 0, blocked = 0, struck = 0, restcount = 0, overheaded = 0; float gx_d, gy_d, gz_d; float gx, gy, gz; float gx_zero = 0.0, gy_zero = 0.0, gz_zero = 0.0; double ts = 0.1 , norm = 0; double q0 = 1, q1 = 0, q2 = 0, q3 = 0; double q0dot = 0, q1dot = 0, q2dot = 0, q3dot = 0; double theta = 0, phi = 0, psi = 0; //Begin main program loop while(1){ //Start-up gyro "calibration" - LED turns red when it is complete myred = 1; mygreen = 1; myblue = 0; while(i < 10000){ gyro.read(&gx, &gy, &gz); gx_zero = gx_zero + gx; gy_zero = gy_zero + gy; gz_zero = gz_zero + gz; i = i+1; } myred = 0; mygreen = 1; myblue = 1; //Gyro quaternion stuff gyro.read(&gx, &gy, &gz); gx_d = gx - (gx_zero / 10000 ); gy_d = gy - (gy_zero / 10000 ); gz_d = gz - (gz_zero / 10000 ); gx_d = (double)gx_d; gy_d = (double)gy_d; gz_d = (double)gz_d; gx_d = (3.14/180) * (gx_d); gy_d = (3.14/180) * (gy_d); gz_d = (3.14/180) * (gz_d); //FOR DEBUGGING: //pc.printf("\n%1.3f %1.3f %1.3f \n", gx_d, gy_d, gz_d); q0dot = -q1*gx_d/2 - q2*gy_d/2 - q3*gz_d/2; q1dot = q0*gx_d/2 + q2*gz_d/2 - q3*gy_d/2; q2dot = q0*gy_d/2 - q1*gz_d/2 + q3*gx_d/2; q3dot = q0*gz_d/2 + q1*gy_d/2 - q2*gx_d/2; q0 += q0dot*ts; q1 += q1dot*ts; q2 += q2dot*ts; q3 += q3dot*ts; norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3); q0 = q0/norm; q1 = q1/norm; q2 = q2/norm; q3 = q3/norm; theta = 180.0/3.14*atan2(2*(q0*q1 +q2*q3),1-2*(q1*q1+q2*q2)); phi = 180.0/3.14*asin(2*(q0*q2-q1*q3)); psi = 180.0/3.14*atan2(2*(q0*q3+q1*q2),1-2*(q2*q2+q3*q3)); pc.printf("%1.3f %1.3f %1.3f \n", theta, phi, psi); //Gestures defined: if (phi < -30){ float x, y, z; z = (acc.getAccZ()); if (overready == 1){ //key.printf("OVERHEAD! "); mouse.scroll(1); overready = 0; overheaded = 1; } if (z > 0.3 && totcount <5 && overheaded == 0){ upcount = upcount +1; totcount = totcount+1; } if (upcount > 2){ //key.printf("STAB! "); mouse.scroll(-1); totcount = 0; upcount = 0; } } if (phi > 25){ overready =1 ; } if (theta > 55 && blocked ==0 && phi > - 20){ //key.printf("BLOCK! "); mouse.press(MOUSE_RIGHT); mouse.release(MOUSE_RIGHT); blocked = 1; } if (theta < -25 && psi > 30 && struck == 0){ //key.printf("STRIKE! "); mouse.press(MOUSE_LEFT); mouse.release(MOUSE_LEFT); struck = 1; } if (theta < -30 && psi < 20){ struck = 0; } //Rest reset for gyros: float x, y, z; x = abs(acc.getAccX()); y = abs(acc.getAccY()); z = abs(acc.getAccZ()); pc.printf("%1.3f %1.3f %1.3f \n", x, y, z); if (z > 0.9 && x < 0.3 && y < 0.3){ restcount = restcount + 1; } else restcount = 0; if (restcount > 1){ q0 = 1, q1 = 0, q2 = 0, q3 = 0; q0dot = 0, q1dot = 0, q2dot = 0, q3dot = 0; theta = 0; phi = 0; psi = 0; blocked = 0; overheaded = 0; } //Update interval; must be synced with gyro timestep! wait(0.1); } }