MODSERIAL PID controller edit
Dependencies: HIDScope MODSERIAL QEI biquadFilter mbed
Fork of PID_controller_Motor by
main.cpp@30:457e42514c47, 2016-10-28 (annotated)
- Committer:
- MBroek
- Date:
- Fri Oct 28 09:19:48 2016 +0000
- Revision:
- 30:457e42514c47
- Parent:
- 29:2b711fc9a5b2
robot testing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MBroek | 0:9e053ed05c69 | 1 | |
MBroek | 0:9e053ed05c69 | 2 | |
MBroek | 0:9e053ed05c69 | 3 | // HET DEFINIEREN VAN ALLES ========================================================================================== |
MBroek | 0:9e053ed05c69 | 4 | |
MBroek | 0:9e053ed05c69 | 5 | // Includen van alle libraries --------------------------------------- |
MBroek | 0:9e053ed05c69 | 6 | #include "mbed.h" |
MBroek | 0:9e053ed05c69 | 7 | #include "MODSERIAL.h" |
MBroek | 0:9e053ed05c69 | 8 | #include "QEI.h" |
MBroek | 0:9e053ed05c69 | 9 | #include "math.h" |
MBroek | 3:581c5918b590 | 10 | #include "HIDScope.h" |
MBroek | 24:ea6de9237cff | 11 | #include "BiQuad.h" |
MBroek | 3:581c5918b590 | 12 | |
MBroek | 3:581c5918b590 | 13 | // Definieren van de HIDscope ---------------------------------------- |
MBroek | 29:2b711fc9a5b2 | 14 | HIDScope scope(3); |
MBroek | 0:9e053ed05c69 | 15 | |
MBroek | 0:9e053ed05c69 | 16 | |
MBroek | 0:9e053ed05c69 | 17 | // Definieren van de Serial en Encoder ------------------------------- |
MBroek | 0:9e053ed05c69 | 18 | MODSERIAL pc(USBTX, USBRX); |
MBroek | 0:9e053ed05c69 | 19 | #define SERIALBAUD 115200 |
MBroek | 0:9e053ed05c69 | 20 | |
MBroek | 28:97b9e50c1180 | 21 | QEI encoder_motor1(D10,D11,NC,64, QEI::X4_ENCODING); |
MBroek | 28:97b9e50c1180 | 22 | QEI encoder_motor2(D12,D13,NC,64, QEI::X4_ENCODING); |
MBroek | 0:9e053ed05c69 | 23 | |
MBroek | 0:9e053ed05c69 | 24 | |
MBroek | 0:9e053ed05c69 | 25 | // Definieren van de Motorpins --------------------------------------- |
MBroek | 0:9e053ed05c69 | 26 | DigitalOut motor1_direction_pin(D7); |
MBroek | 0:9e053ed05c69 | 27 | PwmOut motor1_speed_pin(D6); |
MBroek | 0:9e053ed05c69 | 28 | |
MBroek | 0:9e053ed05c69 | 29 | DigitalOut motor2_direction_pin(D4); |
MBroek | 0:9e053ed05c69 | 30 | PwmOut motor2_speed_pin(D5); |
MBroek | 0:9e053ed05c69 | 31 | |
MBroek | 0:9e053ed05c69 | 32 | |
MBroek | 0:9e053ed05c69 | 33 | //Definieren van bord-elementen -------------------------------------- |
MBroek | 19:35f3da6c6969 | 34 | InterruptIn motor_switch_button(D3); |
MBroek | 19:35f3da6c6969 | 35 | InterruptIn state_switch_button(D2); |
MBroek | 17:525b785f007a | 36 | DigitalIn EMG_sim1(SW2); |
MBroek | 17:525b785f007a | 37 | DigitalIn EMG_sim2(SW3); |
MBroek | 17:525b785f007a | 38 | |
MBroek | 28:97b9e50c1180 | 39 | //AnalogIn pot1(A1); // Dit is de gesimuleerde emg1 |
MBroek | 28:97b9e50c1180 | 40 | //AnalogIn pot2(A2); // Dit is de gesimuleerde emg2 |
MBroek | 0:9e053ed05c69 | 41 | |
MBroek | 13:b0d3c547bf2f | 42 | |
MBroek | 13:b0d3c547bf2f | 43 | DigitalOut ledred(LED_RED, 1); |
MBroek | 13:b0d3c547bf2f | 44 | DigitalOut ledgreen(LED_GREEN, 1); |
MBroek | 16:5a749b319276 | 45 | DigitalOut ledblue(LED_BLUE, 1); |
MBroek | 13:b0d3c547bf2f | 46 | |
MBroek | 24:ea6de9237cff | 47 | AnalogIn emg0( A0 ); // right biceps |
MBroek | 24:ea6de9237cff | 48 | AnalogIn emg1( A1 ); // left biceps |
MBroek | 24:ea6de9237cff | 49 | |
MBroek | 28:97b9e50c1180 | 50 | AnalogIn init_pot(A3); // POT meter |
MBroek | 28:97b9e50c1180 | 51 | |
MBroek | 0:9e053ed05c69 | 52 | |
MBroek | 4:6524b198721f | 53 | //Definieren van de tickers ------------------------------------------ |
MBroek | 17:525b785f007a | 54 | Ticker motor_ticker; // Deze ticker activeert het motor_runs programma, dit leest motor pos en ref pos uit, rekent de PID uit en stuurt met dit de motoren |
MBroek | 4:6524b198721f | 55 | Ticker hidscope_ticker; |
MBroek | 4:6524b198721f | 56 | |
MBroek | 4:6524b198721f | 57 | |
MBroek | 24:ea6de9237cff | 58 | // Het definieren van de filters ---------------------------------------- |
MBroek | 24:ea6de9237cff | 59 | BiQuadChain bqc1; // Combined filter: high-pass (10Hz) and notch (50Hz) |
MBroek | 24:ea6de9237cff | 60 | BiQuad bq1( 9.21171e-01, -1.84234e+00, 9.21171e-01, -1.88661e+00, 8.90340e-01 ); |
MBroek | 24:ea6de9237cff | 61 | BiQuad bq2( 1.00000e+00, -2.00000e+00, 1.00000e+00, -1.94922e+00, 9.53070e-01 ); |
MBroek | 24:ea6de9237cff | 62 | BiQuad bq3( 9.93756e-01, -1.89024e+00, 9.93756e-01, -1.89024e+00, 9.87512e-01 ); |
MBroek | 24:ea6de9237cff | 63 | |
MBroek | 24:ea6de9237cff | 64 | BiQuadChain bqc2; |
MBroek | 24:ea6de9237cff | 65 | BiQuad bq4 = bq1; |
MBroek | 24:ea6de9237cff | 66 | BiQuad bq5 = bq2; |
MBroek | 24:ea6de9237cff | 67 | BiQuad bq6 = bq3; |
MBroek | 24:ea6de9237cff | 68 | |
MBroek | 24:ea6de9237cff | 69 | BiQuadChain bqc3; // Low-pass filter (5Hz) |
MBroek | 24:ea6de9237cff | 70 | BiQuad bq7( 5.84514e-08, 1.16903e-07, 5.84514e-08, -1.94264e+00, 9.43597e-01 ); |
MBroek | 24:ea6de9237cff | 71 | BiQuad bq8( 1.00000e+00, 2.00000e+00, 1.00000e+00, -1.97527e+00, 9.76245e-01 ); |
MBroek | 24:ea6de9237cff | 72 | |
MBroek | 24:ea6de9237cff | 73 | BiQuadChain bqc4; |
MBroek | 24:ea6de9237cff | 74 | BiQuad bq9 = bq7; |
MBroek | 24:ea6de9237cff | 75 | BiQuad bq10 = bq9; |
MBroek | 24:ea6de9237cff | 76 | |
MBroek | 28:97b9e50c1180 | 77 | BiQuadChain bqc5; // Low-pass filter (10Hz) voor PID |
MBroek | 28:97b9e50c1180 | 78 | BiQuad bq11( 1.32937e-05, 2.65875e-05, 1.32937e-05, -1.77831e+00, 7.92447e-01 ); |
MBroek | 28:97b9e50c1180 | 79 | BiQuad bq12( 1.00000e+00, 2.00000e+00, 1.00000e+00, -1.89342e+00, 9.08464e-01 ); |
MBroek | 28:97b9e50c1180 | 80 | |
MBroek | 28:97b9e50c1180 | 81 | |
MBroek | 28:97b9e50c1180 | 82 | |
MBroek | 28:97b9e50c1180 | 83 | |
MBroek | 24:ea6de9237cff | 84 | |
MBroek | 0:9e053ed05c69 | 85 | |
MBroek | 0:9e053ed05c69 | 86 | // HET VASTSTELLEN VAN ALLE TE GEBRUIKEN VARIABELEN EN CONSTANTEN ====================================================== |
MBroek | 4:6524b198721f | 87 | |
MBroek | 28:97b9e50c1180 | 88 | enum states_enum{off, init, init_fish, run}; // De states waar de main loop doorheen loopt, off is uit, init is intialiseren en run is het aanturen vd motoren met emg. |
MBroek | 14:f51d51395803 | 89 | states_enum states = off; |
MBroek | 14:f51d51395803 | 90 | |
MBroek | 21:3db3f2d56d56 | 91 | double ref_pos_prev_m1 = 0.0; // De initiele ref_pos_pref |
MBroek | 21:3db3f2d56d56 | 92 | double ref_pos_prev_m2 = 0.0; |
MBroek | 21:3db3f2d56d56 | 93 | |
MBroek | 4:6524b198721f | 94 | int counts1; // Pulses van motoren |
MBroek | 4:6524b198721f | 95 | int counts2; |
MBroek | 0:9e053ed05c69 | 96 | |
MBroek | 0:9e053ed05c69 | 97 | const double pi = 3.14159265358979323846264338327950288419716939937510; // pi |
MBroek | 15:3f3d87513a6b | 98 | const double rad_per_count = 2.0*pi/8400.0; // Aantal rad per puls uit encoder |
MBroek | 0:9e053ed05c69 | 99 | |
MBroek | 23:3902ee714281 | 100 | const double radius_tandwiel = 0.008; |
MBroek | 9:f735baee0c2b | 101 | const double meter_per_count = rad_per_count * radius_tandwiel; // Het aantal meter dat het karretje aflegt per puls, DIT IS NOG ONBEKEND!!! |
MBroek | 1:5b3fa8e47e8b | 102 | |
MBroek | 23:3902ee714281 | 103 | const double v_max_karretje = 8.4*radius_tandwiel; // Maximale snelheid karretje, gelimiteerd door de v_max vd motor |
MBroek | 23:3902ee714281 | 104 | |
MBroek | 4:6524b198721f | 105 | double error1_int = 0.00000; // Initiele error integral waardes |
MBroek | 4:6524b198721f | 106 | double error2_int = 0.00000; |
MBroek | 0:9e053ed05c69 | 107 | |
MBroek | 30:457e42514c47 | 108 | const double T_motor_function = 0.01; // Periode van de frequentie van het aanroepen van onder andere positiechecker (get_position) en de rest vd motor functie |
MBroek | 0:9e053ed05c69 | 109 | |
MBroek | 4:6524b198721f | 110 | volatile bool flag1 = false, flag2 = false; // De flags voor de functies aangeroepen door de tickers |
MBroek | 4:6524b198721f | 111 | |
MBroek | 30:457e42514c47 | 112 | const double Kp_1 = 0.2; // De PID variablen voor motor 1 |
MBroek | 30:457e42514c47 | 113 | const double Kd_1 = 0.01; |
MBroek | 30:457e42514c47 | 114 | const double Ki_1 = 0.01; |
MBroek | 4:6524b198721f | 115 | |
MBroek | 23:3902ee714281 | 116 | const double Kp_2 = 1.0; // De PID variablen voor motor 2 |
MBroek | 28:97b9e50c1180 | 117 | const double Kd_2 = 0.4; |
MBroek | 28:97b9e50c1180 | 118 | const double Ki_2 = 0.1; |
MBroek | 5:c510ab61af28 | 119 | |
MBroek | 28:97b9e50c1180 | 120 | const double vrijheid_m1_rad = 0.4*pi; // Dit is de uiterste postitie vd arm in radialen |
MBroek | 29:2b711fc9a5b2 | 121 | const double vrijheid_m2_meter = 0.25; // Dit is de helft vd arm, dit is wat het karretje heen en weer kan bewegen |
MBroek | 5:c510ab61af28 | 122 | |
MBroek | 21:3db3f2d56d56 | 123 | const double initial_pos_m1 = vrijheid_m1_rad; // Startin posities van de motoren |
MBroek | 28:97b9e50c1180 | 124 | const double initial_pos_m2 = vrijheid_m2_meter; |
MBroek | 28:97b9e50c1180 | 125 | |
MBroek | 28:97b9e50c1180 | 126 | double position_motor1; |
MBroek | 23:3902ee714281 | 127 | |
MBroek | 23:3902ee714281 | 128 | double position_motor2; |
MBroek | 23:3902ee714281 | 129 | double position_motor2_prev = initial_pos_m2; |
MBroek | 9:f735baee0c2b | 130 | |
MBroek | 13:b0d3c547bf2f | 131 | double PID_output_1 = 0.0; // De eerste PID_output, deze is nul anders gaan de motoren draaien |
MBroek | 13:b0d3c547bf2f | 132 | double PID_output_2 = 0.0; |
MBroek | 5:c510ab61af28 | 133 | |
MBroek | 13:b0d3c547bf2f | 134 | double error_prev_1 = 0.0; // De initiele previous error |
MBroek | 13:b0d3c547bf2f | 135 | double error_int_1 = 0.0; // De initiele intergral error |
MBroek | 10:755b9228cc42 | 136 | |
MBroek | 13:b0d3c547bf2f | 137 | double error_prev_2 = 0.0; |
MBroek | 13:b0d3c547bf2f | 138 | double error_int_2 = 0.0; |
MBroek | 5:c510ab61af28 | 139 | |
MBroek | 20:2fdb069ffcae | 140 | double reference_pos_m2; // De reference positie waar de motor heen wil afhankelijk van het EMG signaal |
MBroek | 20:2fdb069ffcae | 141 | double reference_pos_m1; |
MBroek | 20:2fdb069ffcae | 142 | |
MBroek | 17:525b785f007a | 143 | enum which_motor{motor1, motor2}; // enum van de motoren |
MBroek | 15:3f3d87513a6b | 144 | which_motor motor_that_runs = motor1; |
MBroek | 15:3f3d87513a6b | 145 | |
MBroek | 24:ea6de9237cff | 146 | int digital0; // Define digital signals fot EMG |
MBroek | 24:ea6de9237cff | 147 | int digital1; |
MBroek | 24:ea6de9237cff | 148 | |
MBroek | 24:ea6de9237cff | 149 | double threshold0 = 0.3; // Define thresholds (signal is normalized, so 0.3 = 30% of maximum value) fot EMG |
MBroek | 24:ea6de9237cff | 150 | double threshold1 = 0.3; |
MBroek | 24:ea6de9237cff | 151 | |
MBroek | 24:ea6de9237cff | 152 | double max_out0 = 0; // Set initial maximum values of the signals to 0, the code will check if there's a new maximum value every iteration |
MBroek | 24:ea6de9237cff | 153 | double max_out1 = 0; |
MBroek | 24:ea6de9237cff | 154 | |
MBroek | 9:f735baee0c2b | 155 | |
MBroek | 0:9e053ed05c69 | 156 | |
MBroek | 0:9e053ed05c69 | 157 | |
MBroek | 0:9e053ed05c69 | 158 | |
MBroek | 0:9e053ed05c69 | 159 | |
MBroek | 0:9e053ed05c69 | 160 | // ALLE FUNCTIES BUITEN DE MAIN-LOOP ==================================================================================== |
MBroek | 0:9e053ed05c69 | 161 | |
MBroek | 13:b0d3c547bf2f | 162 | |
MBroek | 15:3f3d87513a6b | 163 | // De statechanger ----------------------------------------------------------- |
MBroek | 15:3f3d87513a6b | 164 | void state_changer(){ |
MBroek | 15:3f3d87513a6b | 165 | if(states == off){ |
MBroek | 21:3db3f2d56d56 | 166 | states = init; |
MBroek | 16:5a749b319276 | 167 | } |
MBroek | 21:3db3f2d56d56 | 168 | else if(states == init){ |
MBroek | 28:97b9e50c1180 | 169 | states = init_fish; |
MBroek | 28:97b9e50c1180 | 170 | } |
MBroek | 28:97b9e50c1180 | 171 | else if(states == init_fish){ |
MBroek | 16:5a749b319276 | 172 | states = run; |
MBroek | 16:5a749b319276 | 173 | } |
MBroek | 16:5a749b319276 | 174 | else{ |
MBroek | 16:5a749b319276 | 175 | states = off; |
MBroek | 16:5a749b319276 | 176 | } |
MBroek | 16:5a749b319276 | 177 | } |
MBroek | 16:5a749b319276 | 178 | |
MBroek | 13:b0d3c547bf2f | 179 | |
MBroek | 9:f735baee0c2b | 180 | // Functie voor het switchen tussen de motors ------------------------------ |
MBroek | 9:f735baee0c2b | 181 | void motor_switch(){ |
MBroek | 15:3f3d87513a6b | 182 | if(motor_that_runs == motor1){ |
MBroek | 15:3f3d87513a6b | 183 | motor_that_runs = motor2; |
MBroek | 15:3f3d87513a6b | 184 | } |
MBroek | 15:3f3d87513a6b | 185 | else{ |
MBroek | 15:3f3d87513a6b | 186 | motor_that_runs = motor1; |
MBroek | 15:3f3d87513a6b | 187 | } |
MBroek | 16:5a749b319276 | 188 | } |
MBroek | 15:3f3d87513a6b | 189 | |
MBroek | 9:f735baee0c2b | 190 | |
MBroek | 1:5b3fa8e47e8b | 191 | // Functie voor het vinden van de positie van motor 1 --------------------- |
MBroek | 13:b0d3c547bf2f | 192 | double get_position_m1(const double radpercount){ //returned de positie van de motor in radialen (positie vd arm in radialen) |
MBroek | 0:9e053ed05c69 | 193 | counts1 = encoder_motor1.getPulses(); // Leest aantal pulses uit encoder af |
MBroek | 21:3db3f2d56d56 | 194 | return radpercount * counts1 + initial_pos_m1; // rekent positie motor1 uit en geeft deze als output vd functie |
MBroek | 1:5b3fa8e47e8b | 195 | } |
MBroek | 1:5b3fa8e47e8b | 196 | |
MBroek | 1:5b3fa8e47e8b | 197 | |
MBroek | 1:5b3fa8e47e8b | 198 | // Functie voor vinden van de positie van motor 2 ----------------------------- |
MBroek | 23:3902ee714281 | 199 | double get_position_m2(const double meterpercount, double mot_pos_prev){ // returned de positie van het karretje in meter |
MBroek | 23:3902ee714281 | 200 | double mot_pos; |
MBroek | 1:5b3fa8e47e8b | 201 | counts2 = encoder_motor2.getPulses(); // leest aantal pulses vd encoder af |
MBroek | 23:3902ee714281 | 202 | mot_pos = meterpercount * counts2 + mot_pos_prev; |
MBroek | 23:3902ee714281 | 203 | encoder_motor2.reset(); |
MBroek | 23:3902ee714281 | 204 | mot_pos_prev = mot_pos; |
MBroek | 23:3902ee714281 | 205 | return mot_pos_prev; // rekent de positie van het karretje uit en geeft dit als output vd functie |
MBroek | 1:5b3fa8e47e8b | 206 | } |
MBroek | 1:5b3fa8e47e8b | 207 | |
MBroek | 1:5b3fa8e47e8b | 208 | |
MBroek | 24:ea6de9237cff | 209 | // Functie voor het uitlezen van het EMG signaal ------------------------------------------ |
MBroek | 24:ea6de9237cff | 210 | int get_EMG() |
MBroek | 24:ea6de9237cff | 211 | { |
MBroek | 24:ea6de9237cff | 212 | double in0 = emg0.read(); // EMG signal 0 (right biceps) |
MBroek | 24:ea6de9237cff | 213 | double in1 = emg1.read(); // EMG signal 1 (left biceps) |
MBroek | 24:ea6de9237cff | 214 | |
MBroek | 24:ea6de9237cff | 215 | double filtered0 = bqc1.step(in0); // Filter signals (high pass and notch) |
MBroek | 24:ea6de9237cff | 216 | double filtered1 = bqc2.step(in1); |
MBroek | 24:ea6de9237cff | 217 | double abs_filtered0 = abs(filtered0); // Absolute value of filtered signals |
MBroek | 24:ea6de9237cff | 218 | double abs_filtered1 = abs(filtered1); |
MBroek | 24:ea6de9237cff | 219 | double out0 = bqc3.step(abs_filtered0); // Filter the signals again to remove trend (low pass) |
MBroek | 24:ea6de9237cff | 220 | double out1 = bqc4.step(abs_filtered1); |
MBroek | 24:ea6de9237cff | 221 | |
MBroek | 24:ea6de9237cff | 222 | if (out0 > max_out0) // Check if the signals have a new maximum value |
MBroek | 24:ea6de9237cff | 223 | { max_out0 = out0; } |
MBroek | 24:ea6de9237cff | 224 | if (out1 > max_out1) |
MBroek | 24:ea6de9237cff | 225 | { max_out1 = out1; } |
MBroek | 24:ea6de9237cff | 226 | |
MBroek | 24:ea6de9237cff | 227 | double normalized_out0 = out0 / max_out0; // Normalize the signals (divide by maximum value to scale from 0 to 1) |
MBroek | 24:ea6de9237cff | 228 | double normalized_out1 = out1 / max_out1; |
MBroek | 24:ea6de9237cff | 229 | |
MBroek | 24:ea6de9237cff | 230 | if (normalized_out0 > threshold0) // If the signal value is above the threshold, give an output of 1 |
MBroek | 24:ea6de9237cff | 231 | { digital0 = 1; } |
MBroek | 24:ea6de9237cff | 232 | else // If the signal value is below the threshold, give an output of 0 |
MBroek | 24:ea6de9237cff | 233 | { digital0 = 0; } |
MBroek | 24:ea6de9237cff | 234 | |
MBroek | 24:ea6de9237cff | 235 | if (normalized_out1 > threshold1) // Do the same for the second EMG signal |
MBroek | 24:ea6de9237cff | 236 | { digital1 = 1; } |
MBroek | 24:ea6de9237cff | 237 | else |
MBroek | 24:ea6de9237cff | 238 | { digital1 = 0; } |
MBroek | 24:ea6de9237cff | 239 | |
MBroek | 28:97b9e50c1180 | 240 | /* |
MBroek | 24:ea6de9237cff | 241 | scope.set(0,in0); // EMG signal 0 (right biceps) |
MBroek | 24:ea6de9237cff | 242 | scope.set(1,in1); // EMG signal 1 (left biceps) |
MBroek | 24:ea6de9237cff | 243 | scope.set(2,digital0); // Signal 0 after filtering, detrending, rectification, digitalization |
MBroek | 24:ea6de9237cff | 244 | scope.set(3,digital1); // Signal 1 after filtering, detrending, rectification, digitalization |
MBroek | 24:ea6de9237cff | 245 | scope.set(4,digital0 - digital1); // Final output signal |
MBroek | 24:ea6de9237cff | 246 | |
MBroek | 24:ea6de9237cff | 247 | scope.send(); // Send all channels to the PC at once |
MBroek | 28:97b9e50c1180 | 248 | */ |
MBroek | 24:ea6de9237cff | 249 | |
MBroek | 24:ea6de9237cff | 250 | return digital0 - digital1; // Subtract the digital signals (right arm gives positive values, left arm give negative values) |
MBroek | 24:ea6de9237cff | 251 | } |
MBroek | 24:ea6de9237cff | 252 | |
MBroek | 24:ea6de9237cff | 253 | |
MBroek | 24:ea6de9237cff | 254 | |
MBroek | 5:c510ab61af28 | 255 | // Functie voor het vinden van de reference position van motor 1 -------------------- |
MBroek | 21:3db3f2d56d56 | 256 | double get_reference_position_m1(double &ref_pos_prev, const double vrijheid_rad){ |
MBroek | 22:6dfe5554b96e | 257 | double ref_pos; |
MBroek | 28:97b9e50c1180 | 258 | // int final_signal = get_EMG(); // Het uiteindelijke signaal uit de emg als output zit is -1, 0 of 1. |
MBroek | 28:97b9e50c1180 | 259 | int final_signal = EMG_sim1.read() - EMG_sim2.read(); |
MBroek | 21:3db3f2d56d56 | 260 | switch(final_signal){ |
MBroek | 21:3db3f2d56d56 | 261 | case 0 : |
MBroek | 22:6dfe5554b96e | 262 | ref_pos = ref_pos_prev; |
MBroek | 21:3db3f2d56d56 | 263 | break; |
MBroek | 21:3db3f2d56d56 | 264 | case 1 : |
MBroek | 30:457e42514c47 | 265 | ref_pos = ref_pos_prev + T_motor_function*vrijheid_rad*0.3; // Dit dwingt af dat de ref pos veranderd met ong 0.5 rad/s |
MBroek | 21:3db3f2d56d56 | 266 | break; |
MBroek | 21:3db3f2d56d56 | 267 | case -1 : |
MBroek | 30:457e42514c47 | 268 | ref_pos = ref_pos_prev - T_motor_function*vrijheid_rad*0.3; |
MBroek | 21:3db3f2d56d56 | 269 | break; |
MBroek | 21:3db3f2d56d56 | 270 | } |
MBroek | 22:6dfe5554b96e | 271 | if(ref_pos >= vrijheid_rad){ |
MBroek | 22:6dfe5554b96e | 272 | ref_pos = vrijheid_rad; |
MBroek | 21:3db3f2d56d56 | 273 | } |
MBroek | 22:6dfe5554b96e | 274 | if(ref_pos <= -vrijheid_rad){ |
MBroek | 22:6dfe5554b96e | 275 | ref_pos = -vrijheid_rad; |
MBroek | 21:3db3f2d56d56 | 276 | } |
MBroek | 22:6dfe5554b96e | 277 | ref_pos_prev = ref_pos; |
MBroek | 21:3db3f2d56d56 | 278 | return ref_pos_prev; // vrijheid_rad is de uiterste positie vd arm in radialen |
MBroek | 5:c510ab61af28 | 279 | } |
MBroek | 5:c510ab61af28 | 280 | |
MBroek | 5:c510ab61af28 | 281 | |
MBroek | 5:c510ab61af28 | 282 | // Functie voor het vinden van de reference position van motor 2 -------------------- |
MBroek | 23:3902ee714281 | 283 | double get_reference_position_m2(double &ref_pos_prev, const double vrijheid_meter){ |
MBroek | 23:3902ee714281 | 284 | double ref_pos; |
MBroek | 23:3902ee714281 | 285 | int final_signal = EMG_sim1.read() - EMG_sim2.read(); // Het uiteindelijke signaal uit de emg als output zit is -1, 0 of 1. |
MBroek | 23:3902ee714281 | 286 | switch(final_signal){ |
MBroek | 23:3902ee714281 | 287 | case 0 : |
MBroek | 23:3902ee714281 | 288 | ref_pos = ref_pos_prev; |
MBroek | 23:3902ee714281 | 289 | break; |
MBroek | 23:3902ee714281 | 290 | case 1 : |
MBroek | 23:3902ee714281 | 291 | ref_pos = ref_pos_prev + T_motor_function*v_max_karretje; // Hierdoor veranderd de ref_pos met de maximale snelheid vd motor (karretje) |
MBroek | 23:3902ee714281 | 292 | break; |
MBroek | 23:3902ee714281 | 293 | case -1 : |
MBroek | 23:3902ee714281 | 294 | ref_pos = ref_pos_prev - T_motor_function*v_max_karretje; |
MBroek | 23:3902ee714281 | 295 | break; |
MBroek | 23:3902ee714281 | 296 | } |
MBroek | 23:3902ee714281 | 297 | if(ref_pos >= vrijheid_meter){ |
MBroek | 23:3902ee714281 | 298 | ref_pos = vrijheid_meter; |
MBroek | 23:3902ee714281 | 299 | } |
MBroek | 23:3902ee714281 | 300 | if(ref_pos <= 0){ |
MBroek | 23:3902ee714281 | 301 | ref_pos = 0; |
MBroek | 23:3902ee714281 | 302 | } |
MBroek | 23:3902ee714281 | 303 | ref_pos_prev = ref_pos; |
MBroek | 23:3902ee714281 | 304 | return ref_pos_prev; |
MBroek | 1:5b3fa8e47e8b | 305 | } |
MBroek | 23:3902ee714281 | 306 | |
MBroek | 3:581c5918b590 | 307 | |
MBroek | 3:581c5918b590 | 308 | // HIDScope functie ---------------------------------------------------------------------- |
MBroek | 7:435f984781ab | 309 | void set_scope(double input1, double input2, double input3){ |
MBroek | 7:435f984781ab | 310 | scope.set(0, input1); |
MBroek | 7:435f984781ab | 311 | scope.set(1, input2); |
MBroek | 7:435f984781ab | 312 | scope.set(2, input3); |
MBroek | 3:581c5918b590 | 313 | scope.send(); |
MBroek | 3:581c5918b590 | 314 | } |
MBroek | 3:581c5918b590 | 315 | |
MBroek | 0:9e053ed05c69 | 316 | |
MBroek | 1:5b3fa8e47e8b | 317 | // De PID-controller voor de motors ------------------------------------------------- |
MBroek | 6:e0857842e8cd | 318 | double PID_controller(double ref_pos, double mot_pos, double &e_prev, double &e_int, const double Kp, const double Kd, const double Ki){ |
MBroek | 0:9e053ed05c69 | 319 | double error = ref_pos - mot_pos; // error uitrekenen |
MBroek | 21:3db3f2d56d56 | 320 | double error_dif = (error-e_prev)/T_motor_function; // De error differentieren |
MBroek | 29:2b711fc9a5b2 | 321 | //scope.set(error_dif,0); |
MBroek | 29:2b711fc9a5b2 | 322 | //error_dif = bqc5.step(error_dif); // Filter biquad |
MBroek | 29:2b711fc9a5b2 | 323 | //scope.set(error_dif,1); scope.send(); |
MBroek | 6:e0857842e8cd | 324 | e_prev = error; // Hier wordt de error opgeslagen voor de volgende keer |
MBroek | 21:3db3f2d56d56 | 325 | e_int = e_int + T_motor_function*error; // De error integreren |
MBroek | 6:e0857842e8cd | 326 | return Kp*error + Ki*e_int + Kd*error_dif; // De uiteindelijke PID output |
MBroek | 0:9e053ed05c69 | 327 | } |
MBroek | 0:9e053ed05c69 | 328 | |
MBroek | 0:9e053ed05c69 | 329 | |
MBroek | 2:6bef5397e8a9 | 330 | // Motor 1 besturen --------------------------------------------------------------------- |
MBroek | 2:6bef5397e8a9 | 331 | void set_motor1(double motor_input){ // functie die de motor aanstuurt mt als input de PID-output |
MBroek | 2:6bef5397e8a9 | 332 | if (motor_input >= 0){ // Dit checkt welke kant de motor op moet draaien |
MBroek | 2:6bef5397e8a9 | 333 | motor1_direction_pin = 1; // Clockwise |
MBroek | 2:6bef5397e8a9 | 334 | } |
MBroek | 2:6bef5397e8a9 | 335 | else { |
MBroek | 2:6bef5397e8a9 | 336 | motor1_direction_pin = 0; // CounterClockwise |
MBroek | 2:6bef5397e8a9 | 337 | } |
MBroek | 2:6bef5397e8a9 | 338 | if (fabs(motor_input)>1){ // Dit fixed de PwmOutput op maximaal 1 |
MBroek | 2:6bef5397e8a9 | 339 | motor_input = 1; |
MBroek | 2:6bef5397e8a9 | 340 | } |
MBroek | 2:6bef5397e8a9 | 341 | motor1_speed_pin = fabs(motor_input); // Dit geeft de uiteindelijke input door aan de motor |
MBroek | 2:6bef5397e8a9 | 342 | } |
MBroek | 2:6bef5397e8a9 | 343 | |
MBroek | 2:6bef5397e8a9 | 344 | |
MBroek | 2:6bef5397e8a9 | 345 | // Motor 2 besturen --------------------------------------------------------------------- |
MBroek | 2:6bef5397e8a9 | 346 | void set_motor2(double motor_input){ // functie die de motor aanstuurt mt als input de PID-output |
MBroek | 2:6bef5397e8a9 | 347 | if (motor_input >= 0){ // Dit checkt welke kant de motor op moet draaien |
MBroek | 2:6bef5397e8a9 | 348 | motor2_direction_pin = 1; // Clockwise |
MBroek | 2:6bef5397e8a9 | 349 | } |
MBroek | 2:6bef5397e8a9 | 350 | else { |
MBroek | 2:6bef5397e8a9 | 351 | motor2_direction_pin = 0; // CounterClockwise |
MBroek | 2:6bef5397e8a9 | 352 | } |
MBroek | 2:6bef5397e8a9 | 353 | if (fabs(motor_input)>1){ // Dit fixed de PwmOutput op maximaal 1 |
MBroek | 2:6bef5397e8a9 | 354 | motor_input = 1; |
MBroek | 2:6bef5397e8a9 | 355 | } |
MBroek | 2:6bef5397e8a9 | 356 | motor2_speed_pin = fabs(motor_input); // Dit geeft de uiteindelijke input door aan de motor |
MBroek | 2:6bef5397e8a9 | 357 | } |
MBroek | 2:6bef5397e8a9 | 358 | |
MBroek | 0:9e053ed05c69 | 359 | |
MBroek | 4:6524b198721f | 360 | // De go-flag functies ----------------------------------------------------------------- |
MBroek | 4:6524b198721f | 361 | void flag1_activate(){flag1=true;} // Activeert de flag |
MBroek | 14:f51d51395803 | 362 | void flag2_activate(){flag2=true;} |
MBroek | 14:f51d51395803 | 363 | |
MBroek | 14:f51d51395803 | 364 | |
MBroek | 21:3db3f2d56d56 | 365 | // Dit doet de robot als hij niets doet ------------------------------------------------------ |
MBroek | 21:3db3f2d56d56 | 366 | void robot_is_off(){ |
MBroek | 21:3db3f2d56d56 | 367 | ledgreen.write(1); |
MBroek | 21:3db3f2d56d56 | 368 | ledred.write(0); // Indicator ik ben uit |
MBroek | 21:3db3f2d56d56 | 369 | motor1_speed_pin = 0; // Uitzetten vd motoren |
MBroek | 16:5a749b319276 | 370 | motor2_speed_pin = 0; |
MBroek | 16:5a749b319276 | 371 | } |
MBroek | 16:5a749b319276 | 372 | |
MBroek | 16:5a749b319276 | 373 | |
MBroek | 28:97b9e50c1180 | 374 | // De initialisatie functie -------------------------------------------------------------------- |
MBroek | 28:97b9e50c1180 | 375 | void initialise(){ |
MBroek | 28:97b9e50c1180 | 376 | ledred.write(1); |
MBroek | 28:97b9e50c1180 | 377 | ledblue.write(0); |
MBroek | 28:97b9e50c1180 | 378 | if (flag1){ |
MBroek | 28:97b9e50c1180 | 379 | double init_m2_speed = init_pot; |
MBroek | 28:97b9e50c1180 | 380 | set_motor2(init_m2_speed); |
MBroek | 28:97b9e50c1180 | 381 | } |
MBroek | 28:97b9e50c1180 | 382 | } |
MBroek | 28:97b9e50c1180 | 383 | |
MBroek | 28:97b9e50c1180 | 384 | |
MBroek | 28:97b9e50c1180 | 385 | // De initialiseren beeindigen functie ------------------------------------------------------------ |
MBroek | 28:97b9e50c1180 | 386 | void initialise_finish(){ // Deze functie laat de motor van een vaste uiterste positie (fysisch limiet) naar het middelpunt draaien. |
MBroek | 28:97b9e50c1180 | 387 | ledblue.write(1); |
MBroek | 21:3db3f2d56d56 | 388 | ref_pos_prev_m1 = initial_pos_m1; |
MBroek | 21:3db3f2d56d56 | 389 | ref_pos_prev_m2 = initial_pos_m2; |
MBroek | 28:97b9e50c1180 | 390 | position_motor1 = initial_pos_m1; |
MBroek | 28:97b9e50c1180 | 391 | position_motor2 = initial_pos_m2; |
MBroek | 28:97b9e50c1180 | 392 | position_motor2_prev = initial_pos_m2; |
MBroek | 30:457e42514c47 | 393 | PID_output_1 = 0.0; |
MBroek | 30:457e42514c47 | 394 | PID_output_2 = 0.0; |
MBroek | 16:5a749b319276 | 395 | ledgreen.write(0); |
MBroek | 28:97b9e50c1180 | 396 | ledred.write(0); |
MBroek | 21:3db3f2d56d56 | 397 | encoder_motor1.reset(); |
MBroek | 21:3db3f2d56d56 | 398 | encoder_motor2.reset(); |
MBroek | 16:5a749b319276 | 399 | motor1_speed_pin = 0; |
MBroek | 21:3db3f2d56d56 | 400 | } |
MBroek | 16:5a749b319276 | 401 | |
MBroek | 16:5a749b319276 | 402 | |
MBroek | 15:3f3d87513a6b | 403 | // De functie die de motoren aanstuurt ------------------------------------------------- |
MBroek | 17:525b785f007a | 404 | void running_motors(){ // Deze functie kijkt welke motor moet draaien en rekent dan de PID uit en geeft dit door aan de motor input functie |
MBroek | 15:3f3d87513a6b | 405 | if (flag1){ |
MBroek | 15:3f3d87513a6b | 406 | flag1 = false; |
MBroek | 16:5a749b319276 | 407 | ledred.write(1); |
MBroek | 15:3f3d87513a6b | 408 | switch (motor_that_runs){ |
MBroek | 15:3f3d87513a6b | 409 | case motor1 : // In deze case draait alleen motor 1 |
MBroek | 21:3db3f2d56d56 | 410 | reference_pos_m1 = get_reference_position_m1(ref_pos_prev_m1, vrijheid_m1_rad); |
MBroek | 28:97b9e50c1180 | 411 | position_motor1 = get_position_m1(rad_per_count); |
MBroek | 28:97b9e50c1180 | 412 | PID_output_1 = PID_controller(reference_pos_m1, position_motor1, error_prev_1, error_int_1, Kp_1, Kd_1, Ki_1); |
MBroek | 28:97b9e50c1180 | 413 | //PID_output_2 = PID_controller(-reference_pos_m1, get_position_m1(rad_per_count), error_prev_1, error_int_1, Kp_1, Kd_1, Ki_1); // Zorgt er voor dat motor2 meedraait met motor1 |
MBroek | 15:3f3d87513a6b | 414 | set_motor1(PID_output_1); |
MBroek | 28:97b9e50c1180 | 415 | //set_motor2(-PID_output_1); |
MBroek | 23:3902ee714281 | 416 | encoder_motor2.reset(); |
MBroek | 15:3f3d87513a6b | 417 | break; |
MBroek | 15:3f3d87513a6b | 418 | case motor2 : |
MBroek | 23:3902ee714281 | 419 | reference_pos_m2 = get_reference_position_m2(ref_pos_prev_m2, vrijheid_m2_meter); |
MBroek | 23:3902ee714281 | 420 | position_motor2 = get_position_m2(meter_per_count, position_motor2_prev); |
MBroek | 23:3902ee714281 | 421 | PID_output_2 = PID_controller(reference_pos_m2, position_motor2, error_prev_2, error_int_2, Kp_2, Kd_2, Ki_2); |
MBroek | 20:2fdb069ffcae | 422 | PID_output_1 = PID_controller(reference_pos_m1, get_position_m1(rad_per_count), error_prev_1, error_int_1, Kp_1, Kd_1, Ki_1); // Zorgt ervoor dat motor1 op de dezelfde positie blijft als motor 2 draait. |
MBroek | 15:3f3d87513a6b | 423 | set_motor2(PID_output_2); |
MBroek | 20:2fdb069ffcae | 424 | set_motor1(PID_output_1); |
MBroek | 23:3902ee714281 | 425 | position_motor2_prev = position_motor2; |
MBroek | 15:3f3d87513a6b | 426 | break; |
MBroek | 15:3f3d87513a6b | 427 | } |
MBroek | 15:3f3d87513a6b | 428 | } |
MBroek | 15:3f3d87513a6b | 429 | } |
MBroek | 15:3f3d87513a6b | 430 | |
MBroek | 15:3f3d87513a6b | 431 | |
MBroek | 15:3f3d87513a6b | 432 | // De HIDscope debug functie ---------------------------------------------------------------- |
MBroek | 17:525b785f007a | 433 | void call_HIDscope(double input_1, double input_2, double input_3){ // Deze functie roept de HIDscope aan |
MBroek | 15:3f3d87513a6b | 434 | if (flag2){ |
MBroek | 15:3f3d87513a6b | 435 | flag2 = false; |
MBroek | 15:3f3d87513a6b | 436 | set_scope(input_1, input_2, input_3); |
MBroek | 15:3f3d87513a6b | 437 | } |
MBroek | 15:3f3d87513a6b | 438 | } |
MBroek | 15:3f3d87513a6b | 439 | |
MBroek | 15:3f3d87513a6b | 440 | |
MBroek | 15:3f3d87513a6b | 441 | |
MBroek | 0:9e053ed05c69 | 442 | |
MBroek | 0:9e053ed05c69 | 443 | // DE MAIN ================================================================================================================= |
MBroek | 0:9e053ed05c69 | 444 | int main() |
MBroek | 0:9e053ed05c69 | 445 | { |
MBroek | 0:9e053ed05c69 | 446 | pc.baud(SERIALBAUD); |
MBroek | 0:9e053ed05c69 | 447 | |
MBroek | 28:97b9e50c1180 | 448 | bqc1.add( &bq1 ).add( &bq2 ).add( &bq3 ); |
MBroek | 28:97b9e50c1180 | 449 | bqc2.add( &bq4 ).add( &bq5 ).add( &bq6 ); |
MBroek | 28:97b9e50c1180 | 450 | bqc3.add( &bq7 ).add( &bq8 ); |
MBroek | 28:97b9e50c1180 | 451 | bqc4.add( &bq9 ).add( &bq10 ); |
MBroek | 28:97b9e50c1180 | 452 | bqc5.add( &bq11 ).add( &bq12 ); |
MBroek | 28:97b9e50c1180 | 453 | |
MBroek | 28:97b9e50c1180 | 454 | |
MBroek | 28:97b9e50c1180 | 455 | |
MBroek | 28:97b9e50c1180 | 456 | |
MBroek | 16:5a749b319276 | 457 | state_switch_button.fall(&state_changer); // Switcht states |
MBroek | 17:525b785f007a | 458 | motor_switch_button.fall(&motor_switch); // Switcht motors |
MBroek | 16:5a749b319276 | 459 | |
MBroek | 17:525b785f007a | 460 | |
MBroek | 13:b0d3c547bf2f | 461 | |
MBroek | 21:3db3f2d56d56 | 462 | motor_ticker.attach(&flag1_activate, T_motor_function); // Activeert de go-flag van motor positie |
MBroek | 17:525b785f007a | 463 | hidscope_ticker.attach(&flag2_activate,0.01); // Leest ref pos en mot pos uit, rekent PID uit en stuurt motoren aan. |
MBroek | 13:b0d3c547bf2f | 464 | |
MBroek | 16:5a749b319276 | 465 | while(1){ |
MBroek | 14:f51d51395803 | 466 | switch(states){ |
MBroek | 16:5a749b319276 | 467 | case off : // Dan staat het programma stil en gebeurt er niks |
MBroek | 16:5a749b319276 | 468 | robot_is_off(); |
MBroek | 14:f51d51395803 | 469 | break; |
MBroek | 21:3db3f2d56d56 | 470 | case init : // Hier voert hij alleen het initialiseren van motor 1 uit |
MBroek | 21:3db3f2d56d56 | 471 | initialise(); |
MBroek | 16:5a749b319276 | 472 | break; |
MBroek | 28:97b9e50c1180 | 473 | case init_fish : |
MBroek | 28:97b9e50c1180 | 474 | initialise_finish(); |
MBroek | 28:97b9e50c1180 | 475 | break; |
MBroek | 15:3f3d87513a6b | 476 | case run : |
MBroek | 17:525b785f007a | 477 | running_motors(); // Hier voert hij het programma voor het aansturen vd motors uit |
MBroek | 15:3f3d87513a6b | 478 | break; |
MBroek | 14:f51d51395803 | 479 | |
MBroek | 15:3f3d87513a6b | 480 | } |
MBroek | 28:97b9e50c1180 | 481 | call_HIDscope(PID_output_1, reference_pos_m1, position_motor1); |
MBroek | 15:3f3d87513a6b | 482 | } |
MBroek | 15:3f3d87513a6b | 483 | } |
MBroek | 14:f51d51395803 | 484 | |
MBroek | 14:f51d51395803 | 485 | |
MBroek | 14:f51d51395803 | 486 | |
MBroek | 14:f51d51395803 | 487 | |
MBroek | 14:f51d51395803 | 488 | |
MBroek | 14:f51d51395803 | 489 | |
MBroek | 14:f51d51395803 | 490 | |
MBroek | 14:f51d51395803 | 491 | |
MBroek | 0:9e053ed05c69 | 492 | |
MBroek | 0:9e053ed05c69 | 493 | |
MBroek | 0:9e053ed05c69 | 494 | |
MBroek | 0:9e053ed05c69 | 495 | |
MBroek | 0:9e053ed05c69 | 496 | |
MBroek | 0:9e053ed05c69 | 497 | |
MBroek | 0:9e053ed05c69 | 498 | |
MBroek | 0:9e053ed05c69 | 499 | |
MBroek | 0:9e053ed05c69 | 500 | |
MBroek | 0:9e053ed05c69 | 501 | |
MBroek | 0:9e053ed05c69 | 502 | |
MBroek | 0:9e053ed05c69 | 503 | |
MBroek | 0:9e053ed05c69 | 504 | |
MBroek | 0:9e053ed05c69 | 505 | |
MBroek | 0:9e053ed05c69 | 506 | |
MBroek | 0:9e053ed05c69 | 507 | |
MBroek | 0:9e053ed05c69 | 508 | |
MBroek | 0:9e053ed05c69 | 509 | |
MBroek | 0:9e053ed05c69 | 510 | |
MBroek | 0:9e053ed05c69 | 511 | |
MBroek | 0:9e053ed05c69 | 512 | |
MBroek | 0:9e053ed05c69 | 513 | |
MBroek | 0:9e053ed05c69 | 514 | |
MBroek | 0:9e053ed05c69 | 515 | |
MBroek | 0:9e053ed05c69 | 516 | |
MBroek | 0:9e053ed05c69 | 517 | |
MBroek | 0:9e053ed05c69 | 518 | |
MBroek | 0:9e053ed05c69 | 519 | |
MBroek | 0:9e053ed05c69 | 520 | |
MBroek | 0:9e053ed05c69 | 521 | |
MBroek | 0:9e053ed05c69 | 522 | |
MBroek | 0:9e053ed05c69 | 523 | |
MBroek | 0:9e053ed05c69 | 524 | |
MBroek | 0:9e053ed05c69 | 525 | |
MBroek | 0:9e053ed05c69 | 526 | |
MBroek | 0:9e053ed05c69 | 527 | |
MBroek | 0:9e053ed05c69 | 528 | |
MBroek | 0:9e053ed05c69 | 529 | |
MBroek | 0:9e053ed05c69 | 530 | |
MBroek | 0:9e053ed05c69 | 531 | |
MBroek | 0:9e053ed05c69 | 532 | |
MBroek | 0:9e053ed05c69 | 533 | |
MBroek | 0:9e053ed05c69 | 534 | |
MBroek | 0:9e053ed05c69 | 535 | |
MBroek | 0:9e053ed05c69 | 536 | |
MBroek | 0:9e053ed05c69 | 537 | |
MBroek | 0:9e053ed05c69 | 538 | |
MBroek | 0:9e053ed05c69 | 539 | |
MBroek | 0:9e053ed05c69 | 540 | |
MBroek | 0:9e053ed05c69 | 541 | |
MBroek | 0:9e053ed05c69 | 542 | |
MBroek | 0:9e053ed05c69 | 543 | |
MBroek | 0:9e053ed05c69 | 544 | |
MBroek | 0:9e053ed05c69 | 545 |