This is with minumum of 10 milliseconds threshold delay 00:53
Dependencies: biquadFilter MODSERIAL QEI Servo mbed
Fork of StateMachine_EMg_RKI_PID_MOTOR_metklikenalles by
main.cpp@15:6ad7abc5c691, 2018-11-01 (annotated)
- Committer:
- gastongab
- Date:
- Thu Nov 01 21:23:12 2018 +0000
- Revision:
- 15:6ad7abc5c691
- Parent:
- 14:fb5d8064830d
- Child:
- 16:438b330f5312
met clicker en demo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cmaas | 9:40c9a18c3430 | 1 | // EMG + KINEMATICS + PID + MOTOR CONTROL |
cmaas | 9:40c9a18c3430 | 2 | |
cmaas | 9:40c9a18c3430 | 3 | //----------------~INITIATING------------------------- |
aschut | 0:90750f158475 | 4 | #include "mbed.h" |
cmaas | 9:40c9a18c3430 | 5 | |
cmaas | 9:40c9a18c3430 | 6 | // EMG -- DEPENDENCIES |
aschut | 0:90750f158475 | 7 | #include <iostream> |
gastongab | 2:0a8622662f6d | 8 | #include "BiQuad.h" |
gastongab | 2:0a8622662f6d | 9 | #include "BiQuadchains_zelfbeun.h" |
gastongab | 2:0a8622662f6d | 10 | #include "MODSERIAL.h" |
gastongab | 2:0a8622662f6d | 11 | |
cmaas | 9:40c9a18c3430 | 12 | // KINEMATICS -- DEPENDENCIES |
cmaas | 9:40c9a18c3430 | 13 | #include "stdio.h" |
cmaas | 9:40c9a18c3430 | 14 | #define _USE_MATH_DEFINES |
cmaas | 9:40c9a18c3430 | 15 | #include <math.h> |
cmaas | 9:40c9a18c3430 | 16 | #define M_PI 3.14159265358979323846 /* pi */ |
cmaas | 9:40c9a18c3430 | 17 | |
cmaas | 9:40c9a18c3430 | 18 | // PID CONTROLLER -- DEPENDENCIES |
cmaas | 9:40c9a18c3430 | 19 | #include "BiQuad.h" |
cmaas | 9:40c9a18c3430 | 20 | #include "QEI.h" |
cmaas | 9:40c9a18c3430 | 21 | //#include "HIDScope.h" |
cmaas | 9:40c9a18c3430 | 22 | |
gastongab | 15:6ad7abc5c691 | 23 | //Clicker servo library |
gastongab | 15:6ad7abc5c691 | 24 | #include "Servo.h" |
gastongab | 15:6ad7abc5c691 | 25 | Servo myservo(A5); |
gastongab | 15:6ad7abc5c691 | 26 | |
cmaas | 9:40c9a18c3430 | 27 | |
cmaas | 9:40c9a18c3430 | 28 | // GENERAL PIN DEFENITIONS |
gastongab | 2:0a8622662f6d | 29 | MODSERIAL pc(USBTX, USBRX); |
gastongab | 2:0a8622662f6d | 30 | |
gastongab | 15:6ad7abc5c691 | 31 | // EMG -- PIN DEFENITIONS |
aschut | 0:90750f158475 | 32 | DigitalOut gpo(D0); |
aschut | 0:90750f158475 | 33 | |
gastongab | 15:6ad7abc5c691 | 34 | DigitalIn button2(SW3); |
aschut | 0:90750f158475 | 35 | DigitalIn button1(SW2); //or SW2 |
aschut | 0:90750f158475 | 36 | |
aschut | 0:90750f158475 | 37 | DigitalOut led1(LED_GREEN); |
aschut | 0:90750f158475 | 38 | DigitalOut led2(LED_RED); |
aschut | 0:90750f158475 | 39 | DigitalOut led3(LED_BLUE); |
aschut | 0:90750f158475 | 40 | |
gastongab | 2:0a8622662f6d | 41 | //EMG tickers, these tickers are called in the mainscript with fsample 500Hz, also sends to HIDscope with same fsample |
gastongab | 2:0a8622662f6d | 42 | Ticker sample_ticker; //ticker for filtering pref. with 1000Hz, define in tick.attach |
gastongab | 4:c7be673eb4a1 | 43 | Ticker threshold_check_ticker; |
gastongab | 2:0a8622662f6d | 44 | Timer t; //timer try out for Astrid |
gastongab | 2:0a8622662f6d | 45 | Timer timer_calibration; //timer for EMG calibration |
gastongab | 2:0a8622662f6d | 46 | |
gastongab | 2:0a8622662f6d | 47 | //Input system |
gastongab | 2:0a8622662f6d | 48 | AnalogIn emg1(A0); //right biceps |
gastongab | 2:0a8622662f6d | 49 | AnalogIn emg2(A1); //right triceps |
gastongab | 2:0a8622662f6d | 50 | AnalogIn emg3(A2); //left biceps |
gastongab | 2:0a8622662f6d | 51 | AnalogIn emg4(A3); //left triceps |
gastongab | 2:0a8622662f6d | 52 | |
cmaas | 9:40c9a18c3430 | 53 | |
gastongab | 15:6ad7abc5c691 | 54 | // PID CONTROLLER -- PIN DEFENITIONS |
cmaas | 12:99e29b8d4155 | 55 | //AnalogIn button3(A4); |
cmaas | 12:99e29b8d4155 | 56 | //AnalogIn button4(A5); |
cmaas | 9:40c9a18c3430 | 57 | |
cmaas | 9:40c9a18c3430 | 58 | DigitalOut directionpin1(D7); // motor 1 |
cmaas | 9:40c9a18c3430 | 59 | DigitalOut directionpin2(D4); // motor 2 |
cmaas | 9:40c9a18c3430 | 60 | DigitalOut directionpin3(D13); // motor 3 |
cmaas | 9:40c9a18c3430 | 61 | PwmOut pwmpin1(D6); // motor 1 |
cmaas | 9:40c9a18c3430 | 62 | PwmOut pwmpin2(D5); // motor 2 |
cmaas | 9:40c9a18c3430 | 63 | PwmOut pwmpin3(D12); // motor 3 |
cmaas | 9:40c9a18c3430 | 64 | |
cmaas | 9:40c9a18c3430 | 65 | QEI encoder1 (D9, D8, NC, 8400, QEI::X4_ENCODING); |
cmaas | 9:40c9a18c3430 | 66 | QEI encoder2 (D11, D10, NC, 8400, QEI::X4_ENCODING); // motor 2 |
cmaas | 9:40c9a18c3430 | 67 | QEI encoder3 (D3, D2, NC, 8400, QEI::X4_ENCODING); // motor 3 |
cmaas | 9:40c9a18c3430 | 68 | // HIDScope scope(2); |
cmaas | 9:40c9a18c3430 | 69 | |
cmaas | 9:40c9a18c3430 | 70 | // PID - TICKERS |
cmaas | 9:40c9a18c3430 | 71 | Ticker ref_rot; |
cmaas | 9:40c9a18c3430 | 72 | Ticker show_counts; |
cmaas | 9:40c9a18c3430 | 73 | Ticker Scope_Data; |
cmaas | 9:40c9a18c3430 | 74 | |
cmaas | 10:2325e545ce11 | 75 | //------------------------GLOBALS----------------------------- |
cmaas | 9:40c9a18c3430 | 76 | // GLOBALS EMG |
gastongab | 2:0a8622662f6d | 77 | //Filtered EMG signals from the end of the chains |
gastongab | 4:c7be673eb4a1 | 78 | volatile double emg1_filtered, emg2_filtered, emg3_filtered, emg4_filtered; |
gastongab | 4:c7be673eb4a1 | 79 | int i = 0; |
gastongab | 2:0a8622662f6d | 80 | |
cmaas | 9:40c9a18c3430 | 81 | //Define doubles for calibration and ticker |
cmaas | 9:40c9a18c3430 | 82 | double ts = 0.001; //tijdsstap |
cmaas | 9:40c9a18c3430 | 83 | double calibration_time = 55; //time EMG calibration should take |
cmaas | 9:40c9a18c3430 | 84 | |
cmaas | 9:40c9a18c3430 | 85 | volatile double temp_highest_emg1 = 0; //highest detected value right biceps |
cmaas | 9:40c9a18c3430 | 86 | volatile double temp_highest_emg2 = 0; |
cmaas | 9:40c9a18c3430 | 87 | volatile double temp_highest_emg3 = 0; |
cmaas | 9:40c9a18c3430 | 88 | volatile double temp_highest_emg4 = 0; |
cmaas | 9:40c9a18c3430 | 89 | |
cmaas | 9:40c9a18c3430 | 90 | //Doubles for calculation threshold |
cmaas | 9:40c9a18c3430 | 91 | double biceps_p_t = 0.4; //set threshold at percentage of highest value |
cmaas | 9:40c9a18c3430 | 92 | double triceps_p_t = 0.5; //set threshold at percentage of highest value |
cmaas | 9:40c9a18c3430 | 93 | volatile double threshold1; |
cmaas | 9:40c9a18c3430 | 94 | volatile double threshold2; |
cmaas | 9:40c9a18c3430 | 95 | volatile double threshold3; |
cmaas | 9:40c9a18c3430 | 96 | volatile double threshold4; |
cmaas | 9:40c9a18c3430 | 97 | |
cmaas | 9:40c9a18c3430 | 98 | // thresholdreads bools |
cmaas | 9:40c9a18c3430 | 99 | int bicepsR; |
cmaas | 9:40c9a18c3430 | 100 | int tricepsR; |
cmaas | 9:40c9a18c3430 | 101 | int bicepsL; |
cmaas | 9:40c9a18c3430 | 102 | int tricepsL; |
cmaas | 9:40c9a18c3430 | 103 | |
cmaas | 9:40c9a18c3430 | 104 | // VARIABLES ROBOT KINEMATICS |
cmaas | 9:40c9a18c3430 | 105 | // constants |
cmaas | 9:40c9a18c3430 | 106 | const float la = 0.256; // lengte actieve arm |
cmaas | 9:40c9a18c3430 | 107 | const float lp = 0.21; // lengte passieve arm |
cmaas | 9:40c9a18c3430 | 108 | const float rp = 0.052; // straal van midden end effector tot hoekpunt |
cmaas | 9:40c9a18c3430 | 109 | const float rm = 0.23; // straal van global midden tot motor |
cmaas | 9:40c9a18c3430 | 110 | const float a = 0.09; // zijde van de driehoek |
cmaas | 9:40c9a18c3430 | 111 | const float xas = 0.40; // afstand van motor 1 tot motor 3 |
cmaas | 9:40c9a18c3430 | 112 | const float yas = 0.346; // afstand van xas tot motor 2 |
cmaas | 9:40c9a18c3430 | 113 | const float thetap = 0; // rotatiehoek van de end effector |
cmaas | 9:40c9a18c3430 | 114 | |
cmaas | 9:40c9a18c3430 | 115 | |
cmaas | 9:40c9a18c3430 | 116 | // motor locatie |
cmaas | 9:40c9a18c3430 | 117 | const int a1x = 0; //x locatie motor 1 |
cmaas | 9:40c9a18c3430 | 118 | const int a1y = 0; //y locatie motor 1 |
cmaas | 9:40c9a18c3430 | 119 | const float a2x = (0.5)*xas; // x locatie motor 2 |
cmaas | 9:40c9a18c3430 | 120 | const float a2y = yas; // y locatie motor 2 |
cmaas | 9:40c9a18c3430 | 121 | const float a3x = xas; // x locatie motor 3 |
cmaas | 9:40c9a18c3430 | 122 | const int a3y = 0; // y locatie motor 3 |
cmaas | 9:40c9a18c3430 | 123 | |
cmaas | 9:40c9a18c3430 | 124 | // script voor het bepalen van de desired position aan de hand van emg (1/0) |
cmaas | 9:40c9a18c3430 | 125 | |
cmaas | 9:40c9a18c3430 | 126 | // EMG OUTPUT |
cmaas | 9:40c9a18c3430 | 127 | int EMGxplus; |
cmaas | 9:40c9a18c3430 | 128 | int EMGxmin ; |
cmaas | 9:40c9a18c3430 | 129 | int EMGyplus; |
cmaas | 9:40c9a18c3430 | 130 | int EMGymin ; |
cmaas | 9:40c9a18c3430 | 131 | |
cmaas | 9:40c9a18c3430 | 132 | // Dit moet experimenteel geperfectioneerd worden |
cmaas | 9:40c9a18c3430 | 133 | float tijdstap = 0.005; //nu wss heel langzaam, kan miss omhoog KEER V GEEFT VERANDERING IN POSITIE |
cmaas | 9:40c9a18c3430 | 134 | float v = 0.1; // snelheid kan wss ook hoger |
cmaas | 9:40c9a18c3430 | 135 | |
cmaas | 9:40c9a18c3430 | 136 | float px = 0.2; //starting x // BOUNDARIES |
cmaas | 9:40c9a18c3430 | 137 | float py = 0.155; // starting y // BOUNDARIES |
cmaas | 9:40c9a18c3430 | 138 | |
cmaas | 9:40c9a18c3430 | 139 | // verschil horizontale as met de actieve arm |
cmaas | 9:40c9a18c3430 | 140 | float da1 = 1.619685; // verschil a1 hoek en motor |
cmaas | 9:40c9a18c3430 | 141 | float da2 = -0.609780; |
cmaas | 9:40c9a18c3430 | 142 | float da3 = 3.372859; |
cmaas | 9:40c9a18c3430 | 143 | |
cmaas | 9:40c9a18c3430 | 144 | // limits (since no forward kinematics) |
cmaas | 9:40c9a18c3430 | 145 | float upperxlim = 0.275; //36, 0.04, 0.315, -0.085niet helemaal naar requierments ff kijken of ie groter kan |
cmaas | 9:40c9a18c3430 | 146 | float lowerxlim = 0.10; |
cmaas | 9:40c9a18c3430 | 147 | float upperylim = 0.225; |
cmaas | 9:40c9a18c3430 | 148 | float lowerylim = 0.03; //0.03 is goed |
cmaas | 9:40c9a18c3430 | 149 | |
cmaas | 9:40c9a18c3430 | 150 | // VARIABLES PID CONTROLLER |
cmaas | 9:40c9a18c3430 | 151 | double PI = M_PI;// CHANGE THIS INTO M_PI |
cmaas | 9:40c9a18c3430 | 152 | double Kp = 14; //200 , 50 |
cmaas | 9:40c9a18c3430 | 153 | double Ki = 0; //1, 0.5 |
cmaas | 9:40c9a18c3430 | 154 | double Kd = 3; //200, 10 |
cmaas | 9:40c9a18c3430 | 155 | double Ts = 0.1; // Sample time in seconds |
cmaas | 9:40c9a18c3430 | 156 | double reference_rotation; //define as radians |
cmaas | 9:40c9a18c3430 | 157 | double motor_position; |
cmaas | 9:40c9a18c3430 | 158 | bool AlwaysTrue; |
cmaas | 9:40c9a18c3430 | 159 | |
cmaas | 9:40c9a18c3430 | 160 | //----------------FUNCTIONS-------------------------- |
cmaas | 9:40c9a18c3430 | 161 | |
cmaas | 9:40c9a18c3430 | 162 | // ~~~~~~~~~~~~~~~~~~~EMG FUNCTIONS~~~~~~~~~~~~~~~~~~ |
gastongab | 7:88fa84742b3c | 163 | void emgsample() |
gastongab | 7:88fa84742b3c | 164 | { |
gastongab | 2:0a8622662f6d | 165 | //All EMG signal through Highpass |
gastongab | 2:0a8622662f6d | 166 | double emgread1 = emg1.read(); |
gastongab | 2:0a8622662f6d | 167 | double emgread2 = emg2.read(); |
gastongab | 2:0a8622662f6d | 168 | double emgread3 = emg3.read(); |
gastongab | 2:0a8622662f6d | 169 | double emgread4 = emg4.read(); |
gastongab | 7:88fa84742b3c | 170 | |
gastongab | 2:0a8622662f6d | 171 | double emg1_highpassed = highp1.step(emgread1); |
gastongab | 2:0a8622662f6d | 172 | double emg2_highpassed = highp2.step(emgread2); |
gastongab | 2:0a8622662f6d | 173 | double emg3_highpassed = highp3.step(emgread3); |
gastongab | 2:0a8622662f6d | 174 | double emg4_highpassed = highp4.step(emgread4); |
gastongab | 7:88fa84742b3c | 175 | |
gastongab | 2:0a8622662f6d | 176 | //All EMG highpassed through Notch |
gastongab | 2:0a8622662f6d | 177 | double emg1_notched = notch1.step(emg1_highpassed); |
gastongab | 2:0a8622662f6d | 178 | double emg2_notched = notch2.step(emg2_highpassed); |
gastongab | 2:0a8622662f6d | 179 | double emg3_notched = notch3.step(emg3_highpassed); |
gastongab | 2:0a8622662f6d | 180 | double emg4_notched = notch4.step(emg4_highpassed); |
gastongab | 7:88fa84742b3c | 181 | |
gastongab | 2:0a8622662f6d | 182 | //All EMG notched rectify |
gastongab | 2:0a8622662f6d | 183 | double emg1_abs = abs(emg1_notched); |
gastongab | 2:0a8622662f6d | 184 | double emg2_abs = abs(emg2_notched); |
gastongab | 2:0a8622662f6d | 185 | double emg3_abs = abs(emg3_notched); |
gastongab | 2:0a8622662f6d | 186 | double emg4_abs = abs(emg4_notched); |
gastongab | 7:88fa84742b3c | 187 | |
gastongab | 2:0a8622662f6d | 188 | //All EMG abs into lowpass |
gastongab | 2:0a8622662f6d | 189 | emg1_filtered = lowp1.step(emg1_abs); |
gastongab | 2:0a8622662f6d | 190 | emg2_filtered = lowp2.step(emg2_abs); |
gastongab | 2:0a8622662f6d | 191 | emg3_filtered = lowp3.step(emg3_abs); |
gastongab | 2:0a8622662f6d | 192 | emg4_filtered = lowp4.step(emg4_abs); |
gastongab | 15:6ad7abc5c691 | 193 | |
cmaas | 14:fb5d8064830d | 194 | |
cmaas | 14:fb5d8064830d | 195 | |
gastongab | 7:88fa84742b3c | 196 | } |
gastongab | 7:88fa84742b3c | 197 | |
gastongab | 7:88fa84742b3c | 198 | void CalibrationEMG() |
gastongab | 7:88fa84742b3c | 199 | { |
gastongab | 7:88fa84742b3c | 200 | //static float samples = calibration_time/ts; |
gastongab | 7:88fa84742b3c | 201 | while(timer_calibration<55) { |
gastongab | 7:88fa84742b3c | 202 | if(timer_calibration>0 && timer_calibration<10) { |
gastongab | 7:88fa84742b3c | 203 | led1=!led1; |
gastongab | 7:88fa84742b3c | 204 | if(emg1_filtered>temp_highest_emg1) { |
gastongab | 7:88fa84742b3c | 205 | temp_highest_emg1= emg1_filtered; |
cmaas | 13:0e25698dce40 | 206 | //pc.printf("Temp1 = %f \r\n",temp_highest_emg1); |
gastongab | 7:88fa84742b3c | 207 | } |
gastongab | 7:88fa84742b3c | 208 | } |
gastongab | 7:88fa84742b3c | 209 | if(timer_calibration>10 && timer_calibration<15) { |
gastongab | 7:88fa84742b3c | 210 | led1=0; |
gastongab | 7:88fa84742b3c | 211 | led2=0; |
gastongab | 7:88fa84742b3c | 212 | led3=0; |
gastongab | 7:88fa84742b3c | 213 | } |
gastongab | 7:88fa84742b3c | 214 | if(timer_calibration>15 && timer_calibration<25) { |
gastongab | 7:88fa84742b3c | 215 | led2=!led2; |
gastongab | 7:88fa84742b3c | 216 | if(emg2_filtered>temp_highest_emg2) { |
gastongab | 7:88fa84742b3c | 217 | temp_highest_emg2= emg2_filtered; |
cmaas | 13:0e25698dce40 | 218 | //pc.printf("Temp2 = %f \r\n",temp_highest_emg2); |
gastongab | 7:88fa84742b3c | 219 | } |
gastongab | 7:88fa84742b3c | 220 | } |
gastongab | 7:88fa84742b3c | 221 | if(timer_calibration>25 && timer_calibration<30) { |
gastongab | 7:88fa84742b3c | 222 | led1=0; |
gastongab | 7:88fa84742b3c | 223 | led2=0; |
gastongab | 7:88fa84742b3c | 224 | led3=0; |
gastongab | 7:88fa84742b3c | 225 | } |
gastongab | 7:88fa84742b3c | 226 | if(timer_calibration>30 && timer_calibration<40) { |
gastongab | 7:88fa84742b3c | 227 | led3=!led3; |
gastongab | 7:88fa84742b3c | 228 | if(emg3_filtered>temp_highest_emg3) { |
gastongab | 7:88fa84742b3c | 229 | temp_highest_emg3= emg3_filtered; |
cmaas | 13:0e25698dce40 | 230 | //pc.printf("Temp3 = %f \r\n",temp_highest_emg3); |
gastongab | 7:88fa84742b3c | 231 | } |
gastongab | 7:88fa84742b3c | 232 | } |
gastongab | 7:88fa84742b3c | 233 | if(timer_calibration>40 && timer_calibration<45) { |
gastongab | 7:88fa84742b3c | 234 | led1=0; |
gastongab | 7:88fa84742b3c | 235 | led2=0; |
gastongab | 7:88fa84742b3c | 236 | led3=0; |
gastongab | 7:88fa84742b3c | 237 | } |
gastongab | 7:88fa84742b3c | 238 | if(timer_calibration>45 && timer_calibration<55) { |
gastongab | 7:88fa84742b3c | 239 | led2=!led2; |
gastongab | 7:88fa84742b3c | 240 | led3=!led3; |
gastongab | 7:88fa84742b3c | 241 | if(emg4_filtered>temp_highest_emg4) { |
gastongab | 7:88fa84742b3c | 242 | temp_highest_emg4= emg4_filtered; |
cmaas | 13:0e25698dce40 | 243 | //pc.printf("Temp4 = %f \r\n",temp_highest_emg4); |
gastongab | 7:88fa84742b3c | 244 | } |
gastongab | 7:88fa84742b3c | 245 | } |
gastongab | 7:88fa84742b3c | 246 | led1=1; |
gastongab | 7:88fa84742b3c | 247 | led2=1; |
gastongab | 7:88fa84742b3c | 248 | led3=1; |
cmaas | 14:fb5d8064830d | 249 | |
cmaas | 14:fb5d8064830d | 250 | |
gastongab | 2:0a8622662f6d | 251 | } |
cmaas | 14:fb5d8064830d | 252 | |
cmaas | 14:fb5d8064830d | 253 | //pc.printf("Highest value right biceps= %f \r\n", temp_highest_emg1); |
cmaas | 14:fb5d8064830d | 254 | //pc.printf("Highest value right triceps= %f \r\n", temp_highest_emg2); |
cmaas | 14:fb5d8064830d | 255 | //pc.printf("Highest value left biceps= %f \r\n", temp_highest_emg3); |
cmaas | 14:fb5d8064830d | 256 | //pc.printf("Highest value left triceps= %f \r\n", temp_highest_emg4); |
cmaas | 14:fb5d8064830d | 257 | |
gastongab | 7:88fa84742b3c | 258 | |
gastongab | 6:f55ab7e38a7f | 259 | threshold1 = temp_highest_emg1*biceps_p_t; //Right Biceps |
gastongab | 6:f55ab7e38a7f | 260 | threshold2 = temp_highest_emg2*triceps_p_t; //Right Triceps |
gastongab | 6:f55ab7e38a7f | 261 | threshold3 = temp_highest_emg3*biceps_p_t; //Left Biceps |
gastongab | 7:88fa84742b3c | 262 | threshold4 = temp_highest_emg4*triceps_p_t; //Left Triceps |
gastongab | 2:0a8622662f6d | 263 | } |
gastongab | 2:0a8622662f6d | 264 | |
gastongab | 4:c7be673eb4a1 | 265 | //Check if emg_filtered has reached their threshold |
gastongab | 7:88fa84742b3c | 266 | void threshold_check() |
gastongab | 7:88fa84742b3c | 267 | { |
gastongab | 7:88fa84742b3c | 268 | |
gastongab | 2:0a8622662f6d | 269 | //EMG1 threshold check |
gastongab | 7:88fa84742b3c | 270 | if(emg1_filtered>threshold1) { |
gastongab | 4:c7be673eb4a1 | 271 | bicepsR = 1; |
gastongab | 7:88fa84742b3c | 272 | } else { |
gastongab | 4:c7be673eb4a1 | 273 | bicepsR= 0; |
gastongab | 7:88fa84742b3c | 274 | } |
gastongab | 2:0a8622662f6d | 275 | //EMG2 threshold check |
gastongab | 7:88fa84742b3c | 276 | if(emg2_filtered>threshold2) { |
gastongab | 4:c7be673eb4a1 | 277 | tricepsR = 1; |
gastongab | 7:88fa84742b3c | 278 | } else { |
gastongab | 4:c7be673eb4a1 | 279 | tricepsR= 0; |
gastongab | 7:88fa84742b3c | 280 | } |
gastongab | 2:0a8622662f6d | 281 | //EMG3 threshold check |
gastongab | 7:88fa84742b3c | 282 | if(emg3_filtered>threshold3) { |
gastongab | 4:c7be673eb4a1 | 283 | bicepsL = 1; |
gastongab | 7:88fa84742b3c | 284 | } else { |
gastongab | 4:c7be673eb4a1 | 285 | bicepsL= 0; |
gastongab | 7:88fa84742b3c | 286 | } |
gastongab | 2:0a8622662f6d | 287 | //EMG4 threshold check |
gastongab | 7:88fa84742b3c | 288 | if(emg4_filtered>threshold4) { |
gastongab | 4:c7be673eb4a1 | 289 | tricepsL = 1; |
gastongab | 7:88fa84742b3c | 290 | } else { |
gastongab | 4:c7be673eb4a1 | 291 | tricepsL= 0; |
gastongab | 7:88fa84742b3c | 292 | } |
gastongab | 7:88fa84742b3c | 293 | |
gastongab | 7:88fa84742b3c | 294 | /* |
gastongab | 4:c7be673eb4a1 | 295 | pc.printf("Biceps Right = %i", bicepsR); |
gastongab | 7:88fa84742b3c | 296 | pc.printf("Triceps Right = %i",tricepsR); |
gastongab | 4:c7be673eb4a1 | 297 | pc.printf("Biceps Left = %i", bicepsL); |
gastongab | 4:c7be673eb4a1 | 298 | pc.printf("Triceps Left = %i", tricepsL); |
gastongab | 4:c7be673eb4a1 | 299 | */ |
cmaas | 14:fb5d8064830d | 300 | |
cmaas | 14:fb5d8064830d | 301 | |
gastongab | 2:0a8622662f6d | 302 | } |
aschut | 0:90750f158475 | 303 | |
gastongab | 15:6ad7abc5c691 | 304 | //-----------------------------DEMO PART--------------------------------------- |
gastongab | 15:6ad7abc5c691 | 305 | |
gastongab | 15:6ad7abc5c691 | 306 | // DEMO COORDINATES |
gastongab | 15:6ad7abc5c691 | 307 | float px1 = 0.2; |
gastongab | 15:6ad7abc5c691 | 308 | float py1 = 0.15; |
gastongab | 15:6ad7abc5c691 | 309 | float px2 = 0.15; |
gastongab | 15:6ad7abc5c691 | 310 | float py2 =0.15; |
gastongab | 15:6ad7abc5c691 | 311 | float px3 = 0.25; |
gastongab | 15:6ad7abc5c691 | 312 | float py3 = 0.15; |
gastongab | 15:6ad7abc5c691 | 313 | float px5 = 0.2; |
gastongab | 15:6ad7abc5c691 | 314 | float py5 = 0.2; |
gastongab | 15:6ad7abc5c691 | 315 | float px6 = 0.2; |
gastongab | 15:6ad7abc5c691 | 316 | float py6 = 0.1; |
gastongab | 15:6ad7abc5c691 | 317 | |
gastongab | 15:6ad7abc5c691 | 318 | void demomodus() |
gastongab | 15:6ad7abc5c691 | 319 | { |
gastongab | 15:6ad7abc5c691 | 320 | if(t==2) { |
gastongab | 15:6ad7abc5c691 | 321 | px = px1; |
gastongab | 15:6ad7abc5c691 | 322 | py = py1; |
gastongab | 15:6ad7abc5c691 | 323 | } else if(t==4) { |
gastongab | 15:6ad7abc5c691 | 324 | px = px2; |
gastongab | 15:6ad7abc5c691 | 325 | py = py2; |
gastongab | 15:6ad7abc5c691 | 326 | } else if(t==6) { |
gastongab | 15:6ad7abc5c691 | 327 | px = px3; |
gastongab | 15:6ad7abc5c691 | 328 | py = py3; |
gastongab | 15:6ad7abc5c691 | 329 | } else if(t==8) { |
gastongab | 15:6ad7abc5c691 | 330 | px = px1; |
gastongab | 15:6ad7abc5c691 | 331 | py = py1; |
gastongab | 15:6ad7abc5c691 | 332 | } else if(t==10) { |
gastongab | 15:6ad7abc5c691 | 333 | px = px5; |
gastongab | 15:6ad7abc5c691 | 334 | py = py5; |
gastongab | 15:6ad7abc5c691 | 335 | } else if(t==12) { |
gastongab | 15:6ad7abc5c691 | 336 | px = px6; |
gastongab | 15:6ad7abc5c691 | 337 | py = py6; |
gastongab | 15:6ad7abc5c691 | 338 | } else if(t==14) { |
gastongab | 15:6ad7abc5c691 | 339 | px = px1; |
gastongab | 15:6ad7abc5c691 | 340 | py = py1; |
gastongab | 15:6ad7abc5c691 | 341 | } else if(t==16) { |
gastongab | 15:6ad7abc5c691 | 342 | px = px3; |
gastongab | 15:6ad7abc5c691 | 343 | py = py3; |
gastongab | 15:6ad7abc5c691 | 344 | } else if(t==18) { |
gastongab | 15:6ad7abc5c691 | 345 | px = px5; |
gastongab | 15:6ad7abc5c691 | 346 | py = py5; |
gastongab | 15:6ad7abc5c691 | 347 | } else if(t==20) { |
gastongab | 15:6ad7abc5c691 | 348 | px = px2; |
gastongab | 15:6ad7abc5c691 | 349 | py = py2; |
gastongab | 15:6ad7abc5c691 | 350 | } else if(t==22) { |
gastongab | 15:6ad7abc5c691 | 351 | px = px6; |
gastongab | 15:6ad7abc5c691 | 352 | py = py6; |
gastongab | 15:6ad7abc5c691 | 353 | } else if(t==24) { |
gastongab | 15:6ad7abc5c691 | 354 | px = px1; |
gastongab | 15:6ad7abc5c691 | 355 | py = py1; |
gastongab | 15:6ad7abc5c691 | 356 | } |
gastongab | 15:6ad7abc5c691 | 357 | |
gastongab | 15:6ad7abc5c691 | 358 | } |
gastongab | 15:6ad7abc5c691 | 359 | |
gastongab | 15:6ad7abc5c691 | 360 | |
gastongab | 15:6ad7abc5c691 | 361 | |
gastongab | 15:6ad7abc5c691 | 362 | //----------------------------------------------------------------------------- |
gastongab | 15:6ad7abc5c691 | 363 | |
gastongab | 15:6ad7abc5c691 | 364 | |
gastongab | 15:6ad7abc5c691 | 365 | |
cmaas | 13:0e25698dce40 | 366 | |
cmaas | 9:40c9a18c3430 | 367 | // ~~~~~~~~~~~~~~ROBOT KINEMATICS ~~~~~~~~~~~~~~~~~~ |
cmaas | 9:40c9a18c3430 | 368 | |
cmaas | 9:40c9a18c3430 | 369 | // functie x positie |
cmaas | 9:40c9a18c3430 | 370 | float positionx(int EMGxplus,int EMGxmin) |
cmaas | 9:40c9a18c3430 | 371 | { |
cmaas | 9:40c9a18c3430 | 372 | float EMGx = EMGxplus - EMGxmin; |
cmaas | 9:40c9a18c3430 | 373 | |
cmaas | 9:40c9a18c3430 | 374 | float verplaatsingx = EMGx * tijdstap * v; |
cmaas | 9:40c9a18c3430 | 375 | float pxnieuw = px + verplaatsingx; |
cmaas | 9:40c9a18c3430 | 376 | // x limit |
cmaas | 9:40c9a18c3430 | 377 | if (pxnieuw <= upperxlim && pxnieuw >= lowerxlim) { |
cmaas | 9:40c9a18c3430 | 378 | px = pxnieuw; |
cmaas | 9:40c9a18c3430 | 379 | } else { |
cmaas | 9:40c9a18c3430 | 380 | if (pxnieuw >= lowerxlim) { |
cmaas | 9:40c9a18c3430 | 381 | px = upperxlim; |
cmaas | 9:40c9a18c3430 | 382 | } else { |
cmaas | 9:40c9a18c3430 | 383 | px = lowerxlim; |
cmaas | 9:40c9a18c3430 | 384 | } |
cmaas | 9:40c9a18c3430 | 385 | } |
cmaas | 9:40c9a18c3430 | 386 | //printf("X eindpunt (%f) en verplaatsing: (%f)\n\r",px,verplaatsingx); |
cmaas | 9:40c9a18c3430 | 387 | return px; |
cmaas | 9:40c9a18c3430 | 388 | } |
cmaas | 9:40c9a18c3430 | 389 | |
cmaas | 9:40c9a18c3430 | 390 | |
cmaas | 9:40c9a18c3430 | 391 | // functie y positie |
cmaas | 9:40c9a18c3430 | 392 | float positiony(int EMGyplus,int EMGymin) |
cmaas | 9:40c9a18c3430 | 393 | { |
cmaas | 9:40c9a18c3430 | 394 | float EMGy = EMGyplus - EMGymin; |
cmaas | 9:40c9a18c3430 | 395 | |
cmaas | 9:40c9a18c3430 | 396 | float verplaatsingy = EMGy * tijdstap * v; |
cmaas | 9:40c9a18c3430 | 397 | float pynieuw = py + verplaatsingy; |
cmaas | 9:40c9a18c3430 | 398 | |
cmaas | 9:40c9a18c3430 | 399 | // y limit |
cmaas | 9:40c9a18c3430 | 400 | if (pynieuw <= upperylim && pynieuw >= lowerylim) { |
cmaas | 9:40c9a18c3430 | 401 | py = pynieuw; |
cmaas | 9:40c9a18c3430 | 402 | } else { |
cmaas | 9:40c9a18c3430 | 403 | if (pynieuw >= lowerylim) { |
cmaas | 9:40c9a18c3430 | 404 | py = upperylim; |
cmaas | 9:40c9a18c3430 | 405 | } else { |
cmaas | 9:40c9a18c3430 | 406 | py = lowerylim; |
cmaas | 9:40c9a18c3430 | 407 | } |
cmaas | 9:40c9a18c3430 | 408 | } |
cmaas | 9:40c9a18c3430 | 409 | //printf("Y eindpunt (%f) en verplaatsing: (%f) \n\r",py,verplaatsingy); |
cmaas | 9:40c9a18c3430 | 410 | return (py); |
cmaas | 9:40c9a18c3430 | 411 | } |
cmaas | 9:40c9a18c3430 | 412 | |
cmaas | 9:40c9a18c3430 | 413 | |
cmaas | 9:40c9a18c3430 | 414 | //~~~~~~~~~~~~CALCULATIING MOTOR ANGLES ~~~~~~~~ |
cmaas | 9:40c9a18c3430 | 415 | // arm 1 --> reference angle motor 1 |
gastongab | 15:6ad7abc5c691 | 416 | float hoek1(float px, float py) // input: ref x, ref y |
cmaas | 9:40c9a18c3430 | 417 | { |
cmaas | 9:40c9a18c3430 | 418 | float c1x = px - rp * cos(thetap +(M_PI/6)); // x locatie hoekpunt end-effector |
cmaas | 9:40c9a18c3430 | 419 | float c1y = py - rp*sin(thetap+(M_PI/6)); // y locatie hoekpunt end-effector |
cmaas | 9:40c9a18c3430 | 420 | float alpha1 = atan2((c1y-a1y),(c1x-a1x)); // hoek tussen horizontaal en lijn van motor naar bijbehorende end-effector punt |
cmaas | 9:40c9a18c3430 | 421 | float psi1 = acos(( pow(la,2)-pow(lp,2)+pow((c1x-a1x),2)+pow((c1y-a1y),2))/(2*la*sqrt(pow ((c1x-a1x),2)+pow((c1y-a1y),2) ))); //Hoek tussen lijn van motor naar bijbehorende end=effector punt en actieve arm |
cmaas | 9:40c9a18c3430 | 422 | float a1 = alpha1 + psi1 - da1; //hoek tussen horizontaal en actieve arm |
cmaas | 9:40c9a18c3430 | 423 | //printf("arm 1 = %f \n\r",a1); |
cmaas | 9:40c9a18c3430 | 424 | return a1; |
cmaas | 9:40c9a18c3430 | 425 | } |
cmaas | 9:40c9a18c3430 | 426 | |
cmaas | 9:40c9a18c3430 | 427 | // arm 2 --> reference angle motor 2 |
cmaas | 9:40c9a18c3430 | 428 | float hoek2(float px, float py) |
cmaas | 9:40c9a18c3430 | 429 | { |
cmaas | 9:40c9a18c3430 | 430 | float c2x = px - rp * cos(thetap -(M_PI/2)); |
cmaas | 9:40c9a18c3430 | 431 | float c2y = py - rp*sin(thetap-(M_PI/2)); |
cmaas | 9:40c9a18c3430 | 432 | float alpha2 = atan2((c2y-a2y),(c2x-a2x)); |
cmaas | 9:40c9a18c3430 | 433 | float psi2 = acos(( pow(la,2)-pow(lp,2)+pow((c2x-a2x),2)+pow((c2y-a2y),2))/(2*la*sqrt(pow ((c2x-a2x),2)+pow((c2y-a2y),2) ))); |
cmaas | 9:40c9a18c3430 | 434 | float a2 = alpha2 + psi2 - da2; |
cmaas | 9:40c9a18c3430 | 435 | //printf("arm 2 = %f \n\r",a2); |
cmaas | 9:40c9a18c3430 | 436 | return a2; |
cmaas | 9:40c9a18c3430 | 437 | } |
cmaas | 9:40c9a18c3430 | 438 | |
cmaas | 9:40c9a18c3430 | 439 | //arm 3 --> reference angle motor 3 |
cmaas | 9:40c9a18c3430 | 440 | float hoek3(float px, float py) |
cmaas | 9:40c9a18c3430 | 441 | { |
cmaas | 9:40c9a18c3430 | 442 | float c3x = px - rp * cos(thetap +(5*M_PI/6)); |
cmaas | 9:40c9a18c3430 | 443 | float c3y = py - rp*sin(thetap+(5*M_PI/6)); |
cmaas | 9:40c9a18c3430 | 444 | float alpha3 = atan2((c3y-a3y),(c3x-a3x)); |
cmaas | 9:40c9a18c3430 | 445 | float psi3 = acos(( pow(la,2)-pow(lp,2)+pow((c3x-a3x),2)+pow((c3y-a3y),2))/(2*la*sqrt(pow ((c3x-a3x),2)+pow((c3y-a3y),2) ))); |
cmaas | 9:40c9a18c3430 | 446 | float a3 = alpha3 + psi3 - da3; |
cmaas | 9:40c9a18c3430 | 447 | //printf("arm 3 = %f \n\r",a3); |
cmaas | 9:40c9a18c3430 | 448 | return a3; |
cmaas | 9:40c9a18c3430 | 449 | } |
cmaas | 9:40c9a18c3430 | 450 | |
cmaas | 9:40c9a18c3430 | 451 | // ~~~~~~~~~~~~~~PID CONTROLLER~~~~~~~~~~~~~~~~~~ |
cmaas | 9:40c9a18c3430 | 452 | |
cmaas | 9:40c9a18c3430 | 453 | double PID_controller(double error) |
cmaas | 9:40c9a18c3430 | 454 | { |
cmaas | 9:40c9a18c3430 | 455 | static double error_integral = 0; |
cmaas | 9:40c9a18c3430 | 456 | static double error_prev = error; // initialization with this value only done once! |
cmaas | 9:40c9a18c3430 | 457 | static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); |
cmaas | 9:40c9a18c3430 | 458 | |
cmaas | 9:40c9a18c3430 | 459 | // Proportional part: |
cmaas | 9:40c9a18c3430 | 460 | double u_k = Kp * error; |
cmaas | 9:40c9a18c3430 | 461 | |
cmaas | 9:40c9a18c3430 | 462 | // Integral part |
cmaas | 9:40c9a18c3430 | 463 | error_integral = error_integral + error * Ts; |
cmaas | 9:40c9a18c3430 | 464 | double u_i = Ki * error_integral; |
cmaas | 9:40c9a18c3430 | 465 | |
cmaas | 9:40c9a18c3430 | 466 | // Derivative part |
cmaas | 9:40c9a18c3430 | 467 | double error_derivative = (error - error_prev)/Ts; |
cmaas | 9:40c9a18c3430 | 468 | double filtered_error_derivative = LowPassFilter.step(error_derivative); |
cmaas | 9:40c9a18c3430 | 469 | double u_d = Kd * filtered_error_derivative; |
cmaas | 9:40c9a18c3430 | 470 | error_prev = error; |
cmaas | 9:40c9a18c3430 | 471 | |
cmaas | 9:40c9a18c3430 | 472 | // Sum all parts and return it |
cmaas | 9:40c9a18c3430 | 473 | return u_k + u_i + u_d; |
cmaas | 9:40c9a18c3430 | 474 | } |
cmaas | 9:40c9a18c3430 | 475 | |
cmaas | 9:40c9a18c3430 | 476 | |
cmaas | 9:40c9a18c3430 | 477 | // DIRECTON AND SPEED CONTROL |
cmaas | 9:40c9a18c3430 | 478 | void moter_control(double u) |
cmaas | 9:40c9a18c3430 | 479 | { |
cmaas | 9:40c9a18c3430 | 480 | |
cmaas | 9:40c9a18c3430 | 481 | directionpin1= u > 0.0f; //eithertrueor false |
cmaas | 9:40c9a18c3430 | 482 | if (fabs(u)> 0.7f) { |
cmaas | 9:40c9a18c3430 | 483 | u = 0.7f; |
cmaas | 9:40c9a18c3430 | 484 | } else { |
cmaas | 9:40c9a18c3430 | 485 | u= u; |
cmaas | 9:40c9a18c3430 | 486 | } |
cmaas | 9:40c9a18c3430 | 487 | pwmpin1= fabs(u); //pwmduty cycle canonlybepositive, floatingpoint absolute value |
cmaas | 9:40c9a18c3430 | 488 | } |
cmaas | 9:40c9a18c3430 | 489 | |
cmaas | 9:40c9a18c3430 | 490 | void moter2_control(double u) |
cmaas | 9:40c9a18c3430 | 491 | { |
cmaas | 9:40c9a18c3430 | 492 | directionpin2= u > 0.0f; //eithertrueor false |
cmaas | 9:40c9a18c3430 | 493 | if (fabs(u)> 0.7f) { |
cmaas | 9:40c9a18c3430 | 494 | u = 0.7f; |
cmaas | 9:40c9a18c3430 | 495 | } else { |
cmaas | 9:40c9a18c3430 | 496 | u= u; |
cmaas | 9:40c9a18c3430 | 497 | } |
cmaas | 9:40c9a18c3430 | 498 | pwmpin2= fabs(u); //pwmduty cycle canonlybepositive, floatingpoint absolute value |
cmaas | 9:40c9a18c3430 | 499 | } |
cmaas | 9:40c9a18c3430 | 500 | |
cmaas | 9:40c9a18c3430 | 501 | void moter3_control(double u) |
cmaas | 9:40c9a18c3430 | 502 | { |
cmaas | 9:40c9a18c3430 | 503 | directionpin3= u > 0.0f; //eithertrueor false |
cmaas | 9:40c9a18c3430 | 504 | if (fabs(u)> 0.7f) { |
cmaas | 9:40c9a18c3430 | 505 | u = 0.7f; |
cmaas | 9:40c9a18c3430 | 506 | } else { |
cmaas | 9:40c9a18c3430 | 507 | u= u; |
cmaas | 9:40c9a18c3430 | 508 | } |
cmaas | 9:40c9a18c3430 | 509 | pwmpin3 = fabs(u); //pwmduty cycle canonlybepositive, floatingpoint absolute value |
cmaas | 9:40c9a18c3430 | 510 | } |
cmaas | 9:40c9a18c3430 | 511 | |
cmaas | 9:40c9a18c3430 | 512 | // CONTROLLING THE MOTOR |
cmaas | 9:40c9a18c3430 | 513 | void Motor_mover() |
cmaas | 9:40c9a18c3430 | 514 | { |
cmaas | 13:0e25698dce40 | 515 | float px = positionx(bicepsR,bicepsL); // EMG: +x, -x |
gastongab | 15:6ad7abc5c691 | 516 | float py = positiony(tricepsR,tricepsL); // EMG: +y, -y |
gastongab | 15:6ad7abc5c691 | 517 | |
cmaas | 9:40c9a18c3430 | 518 | double motor_position = encoder1.getPulses(); //output in counts |
cmaas | 9:40c9a18c3430 | 519 | double reference_rotation = hoek1(px, py); |
cmaas | 9:40c9a18c3430 | 520 | double error = reference_rotation - motor_position*(2*PI)/8400; |
cmaas | 9:40c9a18c3430 | 521 | double u = PID_controller(error); |
cmaas | 9:40c9a18c3430 | 522 | moter_control(u); |
cmaas | 9:40c9a18c3430 | 523 | |
cmaas | 9:40c9a18c3430 | 524 | double motor_position2 = encoder2.getPulses(); //output in counts |
cmaas | 9:40c9a18c3430 | 525 | double reference_rotation2 = hoek2(px, py); |
cmaas | 9:40c9a18c3430 | 526 | double error_2 = reference_rotation2 - motor_position2*(2*PI)/8400; |
cmaas | 9:40c9a18c3430 | 527 | double u_2 = PID_controller(error_2); |
cmaas | 9:40c9a18c3430 | 528 | moter2_control(u_2); |
cmaas | 9:40c9a18c3430 | 529 | |
cmaas | 9:40c9a18c3430 | 530 | double motor_position3 = encoder3.getPulses(); //output in counts |
cmaas | 9:40c9a18c3430 | 531 | double reference_rotation3 = hoek3(px, py); |
cmaas | 9:40c9a18c3430 | 532 | double error_3 = reference_rotation3 - motor_position3*(2*PI)/8400; |
cmaas | 9:40c9a18c3430 | 533 | double u_3 = PID_controller(error_3); |
cmaas | 9:40c9a18c3430 | 534 | moter3_control(u_3); |
cmaas | 9:40c9a18c3430 | 535 | } |
cmaas | 9:40c9a18c3430 | 536 | |
cmaas | 13:0e25698dce40 | 537 | //Activate ticker for Movement state, filtering and Threshold checking |
cmaas | 13:0e25698dce40 | 538 | void movement_ticker_activator() |
cmaas | 13:0e25698dce40 | 539 | { |
cmaas | 13:0e25698dce40 | 540 | sample_ticker.attach(&emgsample, ts); |
cmaas | 14:fb5d8064830d | 541 | threshold_check_ticker.attach(&threshold_check, ts); |
cmaas | 13:0e25698dce40 | 542 | } |
cmaas | 13:0e25698dce40 | 543 | void movement_ticker_deactivator() |
cmaas | 13:0e25698dce40 | 544 | { |
cmaas | 13:0e25698dce40 | 545 | sample_ticker.detach(); |
cmaas | 14:fb5d8064830d | 546 | threshold_check_ticker.detach(); |
cmaas | 13:0e25698dce40 | 547 | } |
cmaas | 9:40c9a18c3430 | 548 | |
cmaas | 14:fb5d8064830d | 549 | |
cmaas | 9:40c9a18c3430 | 550 | //-------------------- STATE MACHINE -------------------------- |
gastongab | 7:88fa84742b3c | 551 | enum states {MOTORS_OFF,CALIBRATION,HOMING,DEMO,MOVEMENT,CLICK}; |
gastongab | 2:0a8622662f6d | 552 | states currentState = MOTORS_OFF; //Chosen startingposition for states |
aschut | 0:90750f158475 | 553 | bool stateChanged = true; // Make sure the initialization of first state is executed |
aschut | 0:90750f158475 | 554 | |
aschut | 0:90750f158475 | 555 | void ProcessStateMachine(void) |
aschut | 0:90750f158475 | 556 | { |
gastongab | 7:88fa84742b3c | 557 | switch (currentState) { |
gastongab | 7:88fa84742b3c | 558 | case MOTORS_OFF: |
gastongab | 7:88fa84742b3c | 559 | // Actions |
gastongab | 7:88fa84742b3c | 560 | if (stateChanged) { |
gastongab | 7:88fa84742b3c | 561 | // state initialization: rood |
gastongab | 7:88fa84742b3c | 562 | led1 = 1; |
gastongab | 7:88fa84742b3c | 563 | led2 = 0; |
gastongab | 7:88fa84742b3c | 564 | led3 = 1; |
gastongab | 7:88fa84742b3c | 565 | wait (1); |
gastongab | 7:88fa84742b3c | 566 | stateChanged = false; |
gastongab | 7:88fa84742b3c | 567 | } |
gastongab | 7:88fa84742b3c | 568 | |
gastongab | 7:88fa84742b3c | 569 | // State transition logic: Als button 1 word ingedrukt --> calibratie, anders motor uithouden |
gastongab | 7:88fa84742b3c | 570 | if (!button1) { |
gastongab | 7:88fa84742b3c | 571 | currentState = CALIBRATION; |
gastongab | 7:88fa84742b3c | 572 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 573 | } else if (!button2) { |
gastongab | 7:88fa84742b3c | 574 | currentState = HOMING ; |
gastongab | 7:88fa84742b3c | 575 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 576 | } else { |
gastongab | 7:88fa84742b3c | 577 | currentState = MOTORS_OFF; |
gastongab | 7:88fa84742b3c | 578 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 579 | } |
gastongab | 7:88fa84742b3c | 580 | |
gastongab | 7:88fa84742b3c | 581 | break; |
gastongab | 7:88fa84742b3c | 582 | |
gastongab | 7:88fa84742b3c | 583 | case CALIBRATION: |
gastongab | 7:88fa84742b3c | 584 | // Actions |
gastongab | 7:88fa84742b3c | 585 | if (stateChanged) { |
gastongab | 7:88fa84742b3c | 586 | // state initialization: oranje |
gastongab | 7:88fa84742b3c | 587 | temp_highest_emg1 = 0; //highest detected value right biceps |
gastongab | 7:88fa84742b3c | 588 | temp_highest_emg2 = 0; |
gastongab | 7:88fa84742b3c | 589 | temp_highest_emg3 = 0; |
gastongab | 7:88fa84742b3c | 590 | temp_highest_emg4 = 0; |
gastongab | 7:88fa84742b3c | 591 | |
gastongab | 7:88fa84742b3c | 592 | timer_calibration.reset(); |
gastongab | 7:88fa84742b3c | 593 | timer_calibration.start(); |
gastongab | 7:88fa84742b3c | 594 | |
gastongab | 15:6ad7abc5c691 | 595 | sample_ticker.attach(&emgsample, ts); |
gastongab | 7:88fa84742b3c | 596 | CalibrationEMG(); |
cmaas | 14:fb5d8064830d | 597 | sample_ticker.detach(); |
gastongab | 7:88fa84742b3c | 598 | timer_calibration.stop(); |
aschut | 0:90750f158475 | 599 | |
gastongab | 7:88fa84742b3c | 600 | |
gastongab | 7:88fa84742b3c | 601 | stateChanged = false; |
gastongab | 7:88fa84742b3c | 602 | } |
gastongab | 7:88fa84742b3c | 603 | |
gastongab | 7:88fa84742b3c | 604 | // State transition logic: automatisch terug naar motors off. |
gastongab | 7:88fa84742b3c | 605 | |
gastongab | 7:88fa84742b3c | 606 | currentState = MOTORS_OFF; |
gastongab | 7:88fa84742b3c | 607 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 608 | break; |
gastongab | 7:88fa84742b3c | 609 | |
gastongab | 7:88fa84742b3c | 610 | case HOMING: |
gastongab | 7:88fa84742b3c | 611 | // Actions |
gastongab | 7:88fa84742b3c | 612 | if (stateChanged) { |
gastongab | 7:88fa84742b3c | 613 | // state initialization: green |
gastongab | 7:88fa84742b3c | 614 | t.reset(); |
gastongab | 7:88fa84742b3c | 615 | t.start(); |
gastongab | 7:88fa84742b3c | 616 | led1 = 0; |
gastongab | 7:88fa84742b3c | 617 | led2 = 1; |
gastongab | 7:88fa84742b3c | 618 | led3 = 1; |
gastongab | 7:88fa84742b3c | 619 | wait (1); |
gastongab | 7:88fa84742b3c | 620 | |
gastongab | 7:88fa84742b3c | 621 | stateChanged = false; |
gastongab | 7:88fa84742b3c | 622 | } |
gastongab | 7:88fa84742b3c | 623 | |
gastongab | 7:88fa84742b3c | 624 | // State transition logic: naar DEMO (button1), naar MOVEMENT(button2) |
gastongab | 7:88fa84742b3c | 625 | if (!button1) { |
gastongab | 7:88fa84742b3c | 626 | currentState = DEMO; |
gastongab | 7:88fa84742b3c | 627 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 628 | } else if (!button2) { |
gastongab | 7:88fa84742b3c | 629 | currentState = MOVEMENT ; |
gastongab | 7:88fa84742b3c | 630 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 631 | } else if (t>300) { |
gastongab | 7:88fa84742b3c | 632 | t.stop(); |
gastongab | 7:88fa84742b3c | 633 | t.reset(); |
gastongab | 7:88fa84742b3c | 634 | currentState = MOTORS_OFF ; |
gastongab | 7:88fa84742b3c | 635 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 636 | } else { |
gastongab | 7:88fa84742b3c | 637 | currentState = HOMING ; |
gastongab | 7:88fa84742b3c | 638 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 639 | } |
gastongab | 7:88fa84742b3c | 640 | break; |
gastongab | 7:88fa84742b3c | 641 | |
aschut | 0:90750f158475 | 642 | case DEMO: |
gastongab | 7:88fa84742b3c | 643 | // Actions |
gastongab | 7:88fa84742b3c | 644 | if (stateChanged) { |
gastongab | 7:88fa84742b3c | 645 | // state initialization: light blue |
gastongab | 7:88fa84742b3c | 646 | led1 = 0; |
gastongab | 7:88fa84742b3c | 647 | led2 = 1; |
gastongab | 7:88fa84742b3c | 648 | led3 = 0; |
cmaas | 14:fb5d8064830d | 649 | wait (1); |
gastongab | 15:6ad7abc5c691 | 650 | t.reset(); |
gastongab | 15:6ad7abc5c691 | 651 | t.start(); |
gastongab | 15:6ad7abc5c691 | 652 | demomodus(); |
gastongab | 15:6ad7abc5c691 | 653 | if(t>=26) { |
gastongab | 15:6ad7abc5c691 | 654 | t.stop(); |
gastongab | 15:6ad7abc5c691 | 655 | } |
gastongab | 7:88fa84742b3c | 656 | stateChanged = false; |
gastongab | 7:88fa84742b3c | 657 | } |
gastongab | 7:88fa84742b3c | 658 | |
gastongab | 7:88fa84742b3c | 659 | // State transition logic: automatisch terug naar HOMING |
gastongab | 7:88fa84742b3c | 660 | currentState = HOMING; |
gastongab | 7:88fa84742b3c | 661 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 662 | break; |
gastongab | 7:88fa84742b3c | 663 | |
gastongab | 7:88fa84742b3c | 664 | case MOVEMENT: |
gastongab | 7:88fa84742b3c | 665 | // Actions |
gastongab | 7:88fa84742b3c | 666 | if (stateChanged) { |
gastongab | 7:88fa84742b3c | 667 | // state initialization: purple |
gastongab | 7:88fa84742b3c | 668 | //t.reset(); |
gastongab | 7:88fa84742b3c | 669 | //t.start(); |
gastongab | 7:88fa84742b3c | 670 | |
gastongab | 7:88fa84742b3c | 671 | led1 = 1; |
gastongab | 7:88fa84742b3c | 672 | led2 = 0; |
gastongab | 7:88fa84742b3c | 673 | led3 = 0; |
gastongab | 7:88fa84742b3c | 674 | wait(2); |
gastongab | 7:88fa84742b3c | 675 | |
gastongab | 7:88fa84742b3c | 676 | movement_ticker_activator(); |
gastongab | 7:88fa84742b3c | 677 | |
gastongab | 7:88fa84742b3c | 678 | led1 = 0; |
gastongab | 7:88fa84742b3c | 679 | led2 = 0; |
gastongab | 7:88fa84742b3c | 680 | led3 = 0; |
gastongab | 7:88fa84742b3c | 681 | wait(2); |
gastongab | 7:88fa84742b3c | 682 | |
gastongab | 7:88fa84742b3c | 683 | |
gastongab | 7:88fa84742b3c | 684 | stateChanged = false; |
gastongab | 7:88fa84742b3c | 685 | } |
gastongab | 7:88fa84742b3c | 686 | |
gastongab | 7:88fa84742b3c | 687 | // State transition logic: naar CLICK (button1), naar MOTORS_OFF(button2) anders naar MOVEMENT |
gastongab | 7:88fa84742b3c | 688 | if (!button1) { |
gastongab | 7:88fa84742b3c | 689 | movement_ticker_deactivator(); |
gastongab | 7:88fa84742b3c | 690 | currentState = CLICK; |
gastongab | 7:88fa84742b3c | 691 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 692 | } else if (!button2) { |
gastongab | 7:88fa84742b3c | 693 | movement_ticker_deactivator(); |
gastongab | 7:88fa84742b3c | 694 | currentState = MOTORS_OFF ; |
gastongab | 7:88fa84742b3c | 695 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 696 | } else if (bicepsR==0 && tricepsR==0 && bicepsL==0 && tricepsL==0) { //this check if person is idle for more than 300seconds |
gastongab | 7:88fa84742b3c | 697 | t.start(); |
gastongab | 7:88fa84742b3c | 698 | } else if (bicepsR==1 || tricepsR==1 || bicepsL==1 || tricepsL==1) { |
gastongab | 7:88fa84742b3c | 699 | t.stop(); |
gastongab | 7:88fa84742b3c | 700 | t.reset(); |
gastongab | 7:88fa84742b3c | 701 | } |
gastongab | 7:88fa84742b3c | 702 | |
gastongab | 7:88fa84742b3c | 703 | if(t>20) { |
gastongab | 7:88fa84742b3c | 704 | movement_ticker_deactivator(); |
gastongab | 7:88fa84742b3c | 705 | t.stop(); |
gastongab | 7:88fa84742b3c | 706 | t.reset(); |
gastongab | 7:88fa84742b3c | 707 | currentState = HOMING ; |
gastongab | 7:88fa84742b3c | 708 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 709 | } |
gastongab | 7:88fa84742b3c | 710 | // here ends the idle checking mode |
gastongab | 15:6ad7abc5c691 | 711 | else { |
gastongab | 7:88fa84742b3c | 712 | //For every muscle a different colour if threshold is passed |
gastongab | 7:88fa84742b3c | 713 | if(bicepsR==1) { |
gastongab | 7:88fa84742b3c | 714 | led1 = 0; |
gastongab | 7:88fa84742b3c | 715 | led2 = 1; |
gastongab | 7:88fa84742b3c | 716 | led3 = 1; |
gastongab | 7:88fa84742b3c | 717 | } else if (bicepsR==0 && tricepsR==0 && bicepsL==0 && tricepsL==0 ) { |
gastongab | 7:88fa84742b3c | 718 | led1 = 1; |
gastongab | 7:88fa84742b3c | 719 | led2 = 1; |
gastongab | 7:88fa84742b3c | 720 | led3 = 1; |
gastongab | 7:88fa84742b3c | 721 | } |
gastongab | 7:88fa84742b3c | 722 | if(tricepsR==1) { |
gastongab | 7:88fa84742b3c | 723 | led1 = 1; |
gastongab | 7:88fa84742b3c | 724 | led2 = 0; |
gastongab | 7:88fa84742b3c | 725 | led3 = 1; |
gastongab | 7:88fa84742b3c | 726 | } else if (bicepsR==0 && tricepsR==0 && bicepsL==0 && tricepsL==0 ) { |
gastongab | 7:88fa84742b3c | 727 | led1 = 1; |
gastongab | 7:88fa84742b3c | 728 | led2 = 1; |
gastongab | 7:88fa84742b3c | 729 | led3 = 1; |
gastongab | 7:88fa84742b3c | 730 | } |
gastongab | 7:88fa84742b3c | 731 | if(bicepsL==1) { |
gastongab | 7:88fa84742b3c | 732 | led1 = 1; |
gastongab | 7:88fa84742b3c | 733 | led2 = 1; |
gastongab | 7:88fa84742b3c | 734 | led3 = 0; |
gastongab | 7:88fa84742b3c | 735 | } else if (bicepsR==0 && tricepsR==0 && bicepsL==0 && tricepsL==0 ) { |
gastongab | 7:88fa84742b3c | 736 | led1 = 1; |
gastongab | 7:88fa84742b3c | 737 | led2 = 1; |
gastongab | 7:88fa84742b3c | 738 | led3 = 1; |
gastongab | 7:88fa84742b3c | 739 | } |
gastongab | 7:88fa84742b3c | 740 | if(tricepsL==1) { |
gastongab | 7:88fa84742b3c | 741 | led1 = 1; |
gastongab | 7:88fa84742b3c | 742 | led2 = 0; |
gastongab | 7:88fa84742b3c | 743 | led3 = 0; |
gastongab | 7:88fa84742b3c | 744 | } else if (bicepsR==0 && tricepsR==0 && bicepsL==0 && tricepsL==0 ) { |
gastongab | 7:88fa84742b3c | 745 | led1 = 1; |
gastongab | 7:88fa84742b3c | 746 | led2 = 1; |
gastongab | 7:88fa84742b3c | 747 | led3 = 1; |
gastongab | 7:88fa84742b3c | 748 | } |
cmaas | 14:fb5d8064830d | 749 | //currentState = MOVEMENT ; |
cmaas | 14:fb5d8064830d | 750 | //stateChanged = false; |
gastongab | 7:88fa84742b3c | 751 | } |
gastongab | 7:88fa84742b3c | 752 | |
gastongab | 7:88fa84742b3c | 753 | break; |
gastongab | 7:88fa84742b3c | 754 | |
aschut | 0:90750f158475 | 755 | case CLICK: |
gastongab | 7:88fa84742b3c | 756 | // Actions |
gastongab | 7:88fa84742b3c | 757 | if (stateChanged) { |
gastongab | 7:88fa84742b3c | 758 | // state initialization: blue |
gastongab | 7:88fa84742b3c | 759 | led1 = 1; |
gastongab | 7:88fa84742b3c | 760 | led2 = 1; |
gastongab | 7:88fa84742b3c | 761 | led3 = 0; |
gastongab | 15:6ad7abc5c691 | 762 | for(float p=1; p>0; p -= 0.1) { |
gastongab | 15:6ad7abc5c691 | 763 | myservo = p; |
gastongab | 15:6ad7abc5c691 | 764 | wait(0.1); |
gastongab | 15:6ad7abc5c691 | 765 | } |
aschut | 0:90750f158475 | 766 | |
gastongab | 7:88fa84742b3c | 767 | stateChanged = false; |
gastongab | 7:88fa84742b3c | 768 | } |
gastongab | 7:88fa84742b3c | 769 | |
gastongab | 7:88fa84742b3c | 770 | // State transition logic: automatisch terug naar MOVEMENT. |
gastongab | 7:88fa84742b3c | 771 | |
gastongab | 7:88fa84742b3c | 772 | currentState = MOVEMENT; |
gastongab | 7:88fa84742b3c | 773 | stateChanged = true; |
gastongab | 7:88fa84742b3c | 774 | break; |
gastongab | 7:88fa84742b3c | 775 | |
gastongab | 4:c7be673eb4a1 | 776 | } |
aschut | 0:90750f158475 | 777 | } |
gastongab | 7:88fa84742b3c | 778 | |
cmaas | 9:40c9a18c3430 | 779 | // --------------------------MAIN-------------------- |
cmaas | 9:40c9a18c3430 | 780 | |
cmaas | 9:40c9a18c3430 | 781 | |
aschut | 0:90750f158475 | 782 | int main() |
aschut | 0:90750f158475 | 783 | { |
gastongab | 15:6ad7abc5c691 | 784 | |
gastongab | 4:c7be673eb4a1 | 785 | //BiQuad Chain add |
gastongab | 4:c7be673eb4a1 | 786 | highp1.add( &highp1_1 ).add( &highp1_2 ); |
gastongab | 4:c7be673eb4a1 | 787 | notch1.add( ¬ch1_1 ).add( ¬ch1_2 ); |
gastongab | 4:c7be673eb4a1 | 788 | lowp1.add( &lowp1_1 ).add(&lowp1_2); |
gastongab | 7:88fa84742b3c | 789 | |
gastongab | 4:c7be673eb4a1 | 790 | highp2.add( &highp2_1 ).add( &highp2_2 ); |
gastongab | 4:c7be673eb4a1 | 791 | notch2.add( ¬ch2_1 ).add( ¬ch2_2 ); |
gastongab | 7:88fa84742b3c | 792 | lowp2.add( &lowp2_1 ).add(&lowp2_2); |
gastongab | 7:88fa84742b3c | 793 | |
gastongab | 4:c7be673eb4a1 | 794 | highp3.add( &highp3_1 ).add( &highp3_2 ); |
gastongab | 4:c7be673eb4a1 | 795 | notch3.add( ¬ch3_1 ).add( ¬ch3_2 ); |
gastongab | 4:c7be673eb4a1 | 796 | lowp3.add( &lowp3_1 ).add(&lowp3_2); |
gastongab | 7:88fa84742b3c | 797 | |
gastongab | 4:c7be673eb4a1 | 798 | highp4.add( &highp4_1 ).add( &highp4_2 ); |
gastongab | 4:c7be673eb4a1 | 799 | notch4.add( ¬ch4_1 ).add( ¬ch4_2 ); |
gastongab | 4:c7be673eb4a1 | 800 | lowp4.add( &lowp4_1 ).add(&lowp4_2); |
gastongab | 7:88fa84742b3c | 801 | |
gastongab | 2:0a8622662f6d | 802 | pc.baud(115200); |
aschut | 0:90750f158475 | 803 | led1 = 1; |
aschut | 0:90750f158475 | 804 | led2 = 1; |
aschut | 0:90750f158475 | 805 | led3 = 1; |
gastongab | 15:6ad7abc5c691 | 806 | |
cmaas | 9:40c9a18c3430 | 807 | pwmpin1.period_us(60); // setup motor |
cmaas | 14:fb5d8064830d | 808 | ref_rot.attach(Motor_mover, 0.01f);// HAS TO GO TO STATE MACHINE |
cmaas | 13:0e25698dce40 | 809 | //movement_ticker_activator(); |
cmaas | 14:fb5d8064830d | 810 | //emg_sample_ticker(); |
gastongab | 7:88fa84742b3c | 811 | while (true) { |
cmaas | 13:0e25698dce40 | 812 | ProcessStateMachine(); |
cmaas | 13:0e25698dce40 | 813 | |
gastongab | 15:6ad7abc5c691 | 814 | /* |
gastongab | 15:6ad7abc5c691 | 815 | if (button2 == false) { |
gastongab | 15:6ad7abc5c691 | 816 | wait(0.01f); |
cmaas | 10:2325e545ce11 | 817 | |
gastongab | 15:6ad7abc5c691 | 818 | // berekenen positie |
gastongab | 15:6ad7abc5c691 | 819 | float px = positionx(1,0); // EMG: +x, -x |
gastongab | 15:6ad7abc5c691 | 820 | float py = positiony(0,0); // EMG: +y, -y |
gastongab | 15:6ad7abc5c691 | 821 | //printf("positie (%f,%f)\n\r",px,py); |
gastongab | 15:6ad7abc5c691 | 822 | } |
cmaas | 10:2325e545ce11 | 823 | |
gastongab | 15:6ad7abc5c691 | 824 | if (button1 == false) { |
gastongab | 15:6ad7abc5c691 | 825 | wait(0.01f); |
gastongab | 15:6ad7abc5c691 | 826 | // berekenen positie |
gastongab | 15:6ad7abc5c691 | 827 | float px = positionx(0,1); // EMG: +x, -x |
gastongab | 15:6ad7abc5c691 | 828 | float py = positiony(0,0); // EMG: +y, -y |
gastongab | 15:6ad7abc5c691 | 829 | //printf("positie (%f,%f)\n\r",px,py); |
gastongab | 15:6ad7abc5c691 | 830 | } |
gastongab | 15:6ad7abc5c691 | 831 | /* |
gastongab | 15:6ad7abc5c691 | 832 | if (button3 == false) { |
gastongab | 15:6ad7abc5c691 | 833 | wait(0.01f); |
gastongab | 15:6ad7abc5c691 | 834 | // berekenen positie |
gastongab | 15:6ad7abc5c691 | 835 | float px = positionx(0,0); // EMG: +x, -x |
gastongab | 15:6ad7abc5c691 | 836 | float py = positiony(1,0); // EMG: +y, -y |
gastongab | 15:6ad7abc5c691 | 837 | //printf("positie (%f,%f)\n\r",px,py); |
gastongab | 15:6ad7abc5c691 | 838 | } |
cmaas | 10:2325e545ce11 | 839 | |
gastongab | 15:6ad7abc5c691 | 840 | if (button4 == false) { |
gastongab | 15:6ad7abc5c691 | 841 | wait(0.01f); |
gastongab | 15:6ad7abc5c691 | 842 | // berekenen positie |
gastongab | 15:6ad7abc5c691 | 843 | float px = positionx(0,0); // EMG: +x, -x |
gastongab | 15:6ad7abc5c691 | 844 | float py = positiony(0,1); // EMG: +y, -y |
gastongab | 15:6ad7abc5c691 | 845 | //printf("positie (%f,%f)\n\r",px,py); |
gastongab | 15:6ad7abc5c691 | 846 | } |
gastongab | 15:6ad7abc5c691 | 847 | */ |
aschut | 0:90750f158475 | 848 | } |
gastongab | 7:88fa84742b3c | 849 | |
aschut | 0:90750f158475 | 850 | } |
aschut | 0:90750f158475 | 851 | |
aschut | 0:90750f158475 | 852 | |
aschut | 0:90750f158475 | 853 | |
aschut | 0:90750f158475 | 854 | |
aschut | 0:90750f158475 | 855 | |
aschut | 0:90750f158475 | 856 |