Calibratie motor, demo, (EMG calibratie en movement werkt niet)

Dependencies:   mbed QEI HIDScope biquadFilter MODSERIAL Encoder FastPWM

Committer:
S1933191
Date:
Thu Oct 31 15:56:07 2019 +0000
Revision:
5:810892d669f9
Parent:
4:7d0df890e801
Child:
6:91cdad4e00e8
Robotcode tot nu toe zonder rki en emg

Who changed what in which revision?

UserRevisionLine numberNew contents of line
S1933191 2:5093b66c9b26 1 #include <math.h>
RobertoO 0:67c50348f842 2 #include "mbed.h"
RobertoO 1:b862262a9d14 3 #include "MODSERIAL.h"
S1933191 2:5093b66c9b26 4 #include "QEI.h"
S1933191 2:5093b66c9b26 5 #include "FastPWM.h"
S1933191 2:5093b66c9b26 6
S1933191 2:5093b66c9b26 7 const double PI = 3.1415926535897;
S1933191 2:5093b66c9b26 8
S1933191 3:16df793da2be 9 InterruptIn but1(D1);
S1933191 3:16df793da2be 10 InterruptIn but2(D0);
S1933191 4:7d0df890e801 11 DigitalIn butsw2(SW3);
S1933191 4:7d0df890e801 12 DigitalIn butsw3(SW2);
S1933191 5:810892d669f9 13 AnalogIn potMeter1(A5);
S1933191 5:810892d669f9 14 AnalogIn potMeter2(A4);
S1933191 2:5093b66c9b26 15
S1933191 5:810892d669f9 16 DigitalOut motor1_direction(D4); //richting van motor1
S1933191 5:810892d669f9 17 FastPWM motor1_pwm(D5); //Motor 1 PWM controle van de snelheid
S1933191 5:810892d669f9 18 DigitalOut motor2_direction(D7); //richting van motor2
S1933191 5:810892d669f9 19 FastPWM motor2_pwm(D6); //Motor 2 PWM controle van de snelheid
S1933191 2:5093b66c9b26 20
S1933191 2:5093b66c9b26 21 Ticker loop_ticker;
S1933191 2:5093b66c9b26 22 // SERIAL COMMUNICATION WITH PC.................................................
S1933191 2:5093b66c9b26 23 Serial pc(USBTX, USBRX);
S1933191 2:5093b66c9b26 24
S1933191 5:810892d669f9 25 enum States {s_idle, s_calibratie_encoder, s_demonstratie, s_EMGcalibratie};
S1933191 2:5093b66c9b26 26 States state;
S1933191 2:5093b66c9b26 27
S1933191 2:5093b66c9b26 28 // ENCODER .....................................................................
S1933191 4:7d0df890e801 29 QEI enc1 (D13, D12, NC, 4200); //encoder 1 gebruiken
S1933191 4:7d0df890e801 30 QEI enc2 (D9, D8, NC, 4200); //encoder 2 gebruiken
S1933191 2:5093b66c9b26 31
S1933191 5:810892d669f9 32 const float dt = 0.001;
S1933191 2:5093b66c9b26 33 double e_int = 0;
S1933191 2:5093b66c9b26 34 double e_int2 = 0;
S1933191 5:810892d669f9 35 double theta1;
S1933191 5:810892d669f9 36 double theta2;
S1933191 5:810892d669f9 37 int enc1_zero = 0;
S1933191 5:810892d669f9 38 int enc2_zero = 0;
S1933191 2:5093b66c9b26 39 int enc1_value;
S1933191 2:5093b66c9b26 40 int enc2_value;
S1933191 5:810892d669f9 41 const int maxwaarde = 400;
S1933191 5:810892d669f9 42
S1933191 5:810892d669f9 43 volatile double Huidigepositie1=0;
S1933191 5:810892d669f9 44 volatile double Huidigepositie2=0;
S1933191 3:16df793da2be 45 volatile double motorValue1;
S1933191 3:16df793da2be 46 volatile double motorValue2;
S1933191 3:16df793da2be 47 volatile double refP;
S1933191 3:16df793da2be 48 volatile double refP2;
S1933191 3:16df793da2be 49 volatile double error1;
S1933191 3:16df793da2be 50 volatile double error2;
S1933191 5:810892d669f9 51
S1933191 2:5093b66c9b26 52 bool state_changed = false;
S1933191 3:16df793da2be 53 volatile bool A=true;
S1933191 3:16df793da2be 54 volatile bool B=true;
S1933191 2:5093b66c9b26 55 volatile bool but1_pressed = false;
S1933191 2:5093b66c9b26 56 volatile bool but2_pressed = false;
S1933191 3:16df793da2be 57 volatile bool butsw2_pressed = false;
S1933191 3:16df793da2be 58 volatile bool butsw3_pressed = false;
S1933191 2:5093b66c9b26 59 volatile bool failure_occurred = false;
S1933191 2:5093b66c9b26 60
S1933191 3:16df793da2be 61 const bool clockwise = true;
S1933191 3:16df793da2be 62 volatile bool direction1 = clockwise;
S1933191 3:16df793da2be 63 volatile bool direction2 = clockwise;
S1933191 3:16df793da2be 64
S1933191 5:810892d669f9 65 // RKI VARIABELEN...............................................................
S1933191 5:810892d669f9 66 // Lengtes zijn in meters
S1933191 5:810892d669f9 67 // Vaste variabelen:
S1933191 5:810892d669f9 68 const double L0 = 0.30; // lengte arm 1 --> moet nog goed worden opgemeten!
S1933191 5:810892d669f9 69 const double L2 = 0.30; // Lengte arm 2 --> moet ook nog goed opgemeten worden!
S1933191 5:810892d669f9 70 const double r_trans = 0.035; // gebruiken voor translation naar shaft rotation
S1933191 5:810892d669f9 71
S1933191 5:810892d669f9 72 // Variërende variabelen:
S1933191 5:810892d669f9 73 double q1 = 0; // Motorhoek van joint 1 op beginpositie
S1933191 5:810892d669f9 74 double q2 = PI/2; // Motorhoek van joint 2 op beginpositie
S1933191 5:810892d669f9 75 double v_x; // Snelheid van end effector in x richting --> Door EMG signals
S1933191 5:810892d669f9 76 double v_y; // Snelheid van end effector in y richting --> Door EMG signals
S1933191 5:810892d669f9 77
S1933191 5:810892d669f9 78 double Lq1; // Translatieafstand als gevolg van motor rotation joint 1
S1933191 5:810892d669f9 79 double Cq2; // Joint angle van het systeem (gecorrigeerd voor gear ratio 1:1.1)
S1933191 5:810892d669f9 80
S1933191 5:810892d669f9 81 double q1_dot; // Benodigde hoeksnelheid van motor 1
S1933191 5:810892d669f9 82 double q2_dot; // Benodigde hoeksnelheid van motor 2
S1933191 5:810892d669f9 83
S1933191 5:810892d669f9 84 double q1_ii; // Referentie signaal voor motorhoek q1
S1933191 5:810892d669f9 85 double q2_ii; // Referentie signaal voor motorhoek q2
S1933191 5:810892d669f9 86
S1933191 5:810892d669f9 87 //PI VARIABELEN................................................................
S1933191 5:810892d669f9 88 const double kp=0.002; // Soort van geschaald --> meer onderzoek nodig
S1933191 5:810892d669f9 89 const double ki=0.0001;
S1933191 5:810892d669f9 90 const double kp2=0.002;
S1933191 5:810892d669f9 91 const double ki2=0.0001;
S1933191 5:810892d669f9 92
S1933191 3:16df793da2be 93 void rest()
S1933191 5:810892d669f9 94 // Rust. Hier wordt niets uitgevoerd. Wanneer button1
S1933191 5:810892d669f9 95 { // wordt ingedrukt gaan we naar de volgende state waar
S1933191 5:810892d669f9 96 if (but1_pressed) { // de encoders worden gekalibreerd.
S1933191 2:5093b66c9b26 97 state_changed = true;
S1933191 3:16df793da2be 98 state = s_calibratie_encoder;
S1933191 2:5093b66c9b26 99 but1_pressed = false;
S1933191 2:5093b66c9b26 100 }
S1933191 2:5093b66c9b26 101 }
RobertoO 0:67c50348f842 102
S1933191 5:810892d669f9 103 void calibratie_encoder() // calibratie encoder. Hier worden de encoders gekalibreerd en op
S1933191 5:810892d669f9 104 { // 0 gezet. Wanneer op button 1 wordt gedrukt gaan we naar de
S1933191 5:810892d669f9 105 if (state_changed) { // demo modus, wanneer op button 2 wordt gedruk gaan we naar
S1933191 5:810892d669f9 106 pc.printf("Started encoder calibration\r\n"); // de EMG calibratie
S1933191 2:5093b66c9b26 107 state_changed = false;
S1933191 2:5093b66c9b26 108 }
S1933191 2:5093b66c9b26 109 if (but1_pressed) {
S1933191 2:5093b66c9b26 110 pc.printf("Encoder has been calibrated \r\n");
S1933191 4:7d0df890e801 111 enc1_value = enc1.getPulses();
S1933191 4:7d0df890e801 112 enc2_value = enc2.getPulses();
S1933191 5:810892d669f9 113 //enc1_value -= enc1_zero;
S1933191 5:810892d669f9 114 //enc2_value -= enc2_zero;
S1933191 4:7d0df890e801 115 theta1 = (float)(enc1_value)/(float)(4200)*2*PI;
S1933191 4:7d0df890e801 116 theta2 = (float)(enc2_value)/(float)(4200)*2*PI;
S1933191 2:5093b66c9b26 117 enc1_zero = enc1_value;
S1933191 2:5093b66c9b26 118 enc2_zero = enc2_value;
S1933191 2:5093b66c9b26 119 but1_pressed = false;
S1933191 2:5093b66c9b26 120 state_changed = true;
S1933191 5:810892d669f9 121 state = s_demonstratie;
S1933191 2:5093b66c9b26 122 pc.printf("enc01: %i\r\n", enc1_zero);
S1933191 2:5093b66c9b26 123 pc.printf("enc1value: %i\r\n", enc1_value);
S1933191 2:5093b66c9b26 124 pc.printf("enc02: %i\r\n",enc2_zero);
S1933191 2:5093b66c9b26 125 pc.printf("enc2value: %i\r\n", enc2_value);
S1933191 2:5093b66c9b26 126 pc.printf("hoek 1: %f\r\n",theta1);
S1933191 2:5093b66c9b26 127 pc.printf("hoek 2: %f\r\n",theta2);
S1933191 3:16df793da2be 128 }
S1933191 2:5093b66c9b26 129
S1933191 5:810892d669f9 130 if (but2_pressed) {
S1933191 5:810892d669f9 131 pc.printf("Encoder has been calibrated \r\n");
S1933191 5:810892d669f9 132 enc1_value = enc1.getPulses();
S1933191 5:810892d669f9 133 enc2_value = enc2.getPulses();
S1933191 5:810892d669f9 134 //enc1_value -= enc1_zero;
S1933191 5:810892d669f9 135 //enc2_value -= enc2_zero;
S1933191 5:810892d669f9 136 theta1 = (float)(enc1_value)/(float)(4200)*2*PI;
S1933191 5:810892d669f9 137 theta2 = (float)(enc2_value)/(float)(4200)*2*PI;
S1933191 5:810892d669f9 138 enc1_zero = enc1_value;
S1933191 5:810892d669f9 139 enc2_zero = enc2_value;
S1933191 5:810892d669f9 140 but2_pressed = false;
S1933191 3:16df793da2be 141 state_changed = true;
S1933191 5:810892d669f9 142 state = s_EMGcalibratie;
S1933191 5:810892d669f9 143 pc.printf("enc01: %i\r\n", enc1_zero);
S1933191 5:810892d669f9 144 pc.printf("enc1value: %i\r\n", enc1_value);
S1933191 5:810892d669f9 145 pc.printf("enc02: %i\r\n",enc2_zero);
S1933191 5:810892d669f9 146 pc.printf("enc2value: %i\r\n", enc2_value);
S1933191 5:810892d669f9 147 pc.printf("hoek 1: %f\r\n",theta1);
S1933191 5:810892d669f9 148 pc.printf("hoek 2: %f\r\n",theta2);
S1933191 5:810892d669f9 149 }
S1933191 5:810892d669f9 150 }
S1933191 5:810892d669f9 151
S1933191 5:810892d669f9 152 void demonstratie()
S1933191 5:810892d669f9 153 {
S1933191 5:810892d669f9 154 if (state_changed) { //
S1933191 5:810892d669f9 155 pc.printf("Demonstratie gestart\r\n") ; //
S1933191 3:16df793da2be 156 state_changed = false;
S1933191 2:5093b66c9b26 157 }
S1933191 5:810892d669f9 158 }
S1933191 5:810892d669f9 159 void EMGcalibratie()
S1933191 5:810892d669f9 160 {
S1933191 5:810892d669f9 161
S1933191 5:810892d669f9 162 }
S1933191 5:810892d669f9 163
S1933191 5:810892d669f9 164 void RKI()
S1933191 5:810892d669f9 165 {
S1933191 5:810892d669f9 166 Lq1 = q1*r_trans;
S1933191 5:810892d669f9 167 Cq2 = q2/1.1; //1.1 is gear ratio
S1933191 5:810892d669f9 168
S1933191 5:810892d669f9 169 q1_dot = (v_x + (v_y*(/*L1+*/L2*sin(q2/1.1)))/(L0 + q1*r_trans + L2*cos(q2/1.1)))/r_trans;
S1933191 5:810892d669f9 170 q2_dot = (1.1*v_y)/(L0 + q1*r_trans + L2*cos(q2/1.1));
S1933191 5:810892d669f9 171
S1933191 5:810892d669f9 172 q1_ii = q1 + q1_dot*dt;
S1933191 5:810892d669f9 173 q2_ii = q2 + q2_dot*dt;
S1933191 5:810892d669f9 174
S1933191 5:810892d669f9 175 q1 = q1_ii;
S1933191 5:810892d669f9 176 q2 = q2_ii;
S1933191 5:810892d669f9 177
S1933191 2:5093b66c9b26 178 }
S1933191 3:16df793da2be 179
S1933191 2:5093b66c9b26 180 double GetReferencePosition()
S1933191 2:5093b66c9b26 181 {
S1933191 5:810892d669f9 182 double Potmeterwaarde = potMeter2.read();
S1933191 5:810892d669f9 183
S1933191 2:5093b66c9b26 184 double refP = Potmeterwaarde*maxwaarde;
S1933191 5:810892d669f9 185 return refP;
S1933191 2:5093b66c9b26 186 }
S1933191 2:5093b66c9b26 187
S1933191 2:5093b66c9b26 188 double GetReferencePosition2()
S1933191 2:5093b66c9b26 189 {
S1933191 5:810892d669f9 190 double potmeterwaarde2 = potMeter1.read();
S1933191 5:810892d669f9 191 double refP2 = potmeterwaarde2*maxwaarde;
S1933191 5:810892d669f9 192 return refP2;
S1933191 2:5093b66c9b26 193 }
S1933191 5:810892d669f9 194
S1933191 5:810892d669f9 195 double FeedBackControl(double error, double &e_int)
S1933191 2:5093b66c9b26 196 {
S1933191 3:16df793da2be 197 double Proportional= kp*error1;
S1933191 5:810892d669f9 198
S1933191 3:16df793da2be 199 e_int = e_int+dt*error1;
S1933191 2:5093b66c9b26 200 double Integrator = ki*e_int;
S1933191 2:5093b66c9b26 201
S1933191 3:16df793da2be 202 motorValue1 = Proportional + Integrator ;
S1933191 3:16df793da2be 203 return motorValue1;
S1933191 2:5093b66c9b26 204 }
S1933191 2:5093b66c9b26 205
S1933191 5:810892d669f9 206 double FeedBackControl2(double error2, double &e_int2)
S1933191 5:810892d669f9 207 {
S1933191 2:5093b66c9b26 208 double Proportional2= kp2*error2;
S1933191 5:810892d669f9 209
S1933191 2:5093b66c9b26 210 e_int2 = e_int2+dt*error2;
S1933191 2:5093b66c9b26 211 double Integrator2 = ki2*e_int2;
S1933191 2:5093b66c9b26 212
S1933191 2:5093b66c9b26 213 double motorValue2 = Proportional2 + Integrator2 ;
S1933191 2:5093b66c9b26 214 return motorValue2;
S1933191 3:16df793da2be 215 }
S1933191 3:16df793da2be 216
S1933191 5:810892d669f9 217
S1933191 3:16df793da2be 218 void SetMotor1(float motorValue1) {
S1933191 5:810892d669f9 219 // gegeven motorValue1 <=1, schrijft snelheid naar pwm.
S1933191 5:810892d669f9 220 // MotorValues buiten range worden afgekapt dat ze binnen de range vallen.
S1933191 3:16df793da2be 221 motor1_pwm.write(fabs(motorValue1) > 1 ? 1 : fabs(motorValue1));
S1933191 2:5093b66c9b26 222 }
S1933191 3:16df793da2be 223
S1933191 3:16df793da2be 224 void SetMotor2(float motorValue2) {
S1933191 3:16df793da2be 225 motor2_pwm.write(fabs(motorValue2) > 1 ? 1 : fabs(motorValue2));
S1933191 3:16df793da2be 226 }
S1933191 2:5093b66c9b26 227
S1933191 5:810892d669f9 228 void MeasureAndControl()
S1933191 2:5093b66c9b26 229 {
S1933191 2:5093b66c9b26 230 // RKI aanroepen
S1933191 2:5093b66c9b26 231 //RKI();
S1933191 2:5093b66c9b26 232 // hier the control of the 1st control system
S1933191 5:810892d669f9 233 refP = GetReferencePosition(); //moet eigenlijk nog met RKI
S1933191 4:7d0df890e801 234 Huidigepositie1 = enc1.getPulses();
S1933191 3:16df793da2be 235 error1 = (refP - Huidigepositie1);// make an error
S1933191 3:16df793da2be 236 motorValue1 = FeedBackControl(error1, e_int);
S1933191 3:16df793da2be 237 SetMotor1(motorValue1);
S1933191 2:5093b66c9b26 238 // hier the control of the 2nd control system
S1933191 3:16df793da2be 239 refP2 = GetReferencePosition2();
S1933191 4:7d0df890e801 240 Huidigepositie2 = enc2.getPulses();
S1933191 3:16df793da2be 241 error2 = (refP2 - Huidigepositie2);// make an error
S1933191 3:16df793da2be 242 motorValue2 = FeedBackControl2(error2, e_int2);
S1933191 2:5093b66c9b26 243 SetMotor2(motorValue2);
S1933191 5:810892d669f9 244 pc.printf("refP = %d, huidigepos = %d, motorvalue = %d, refP2 = %d, huidigepos2 = %d, motorvalue2 = %d \r\n", refP, Huidigepositie1, motorValue1, refP2, Huidigepositie2, Huidigepositie2);
S1933191 3:16df793da2be 245
S1933191 2:5093b66c9b26 246 }
S1933191 3:16df793da2be 247
S1933191 3:16df793da2be 248 void direction()
S1933191 3:16df793da2be 249 {
S1933191 3:16df793da2be 250 if (butsw2==0) {
S1933191 3:16df793da2be 251 if (A==true){// zodat het knopje 1 x wordt afgelezen
S1933191 5:810892d669f9 252 // richting veranderen
S1933191 3:16df793da2be 253 motor1_direction.write(direction1 = !direction1);
S1933191 3:16df793da2be 254 pc.printf("direction: %s\r\n\n", direction1 ? "clockwise" : "counter clockwise");
S1933191 3:16df793da2be 255 A=false;
S1933191 3:16df793da2be 256 }
S1933191 3:16df793da2be 257 }
S1933191 3:16df793da2be 258 else{
S1933191 3:16df793da2be 259 A=true;
S1933191 3:16df793da2be 260 }
S1933191 2:5093b66c9b26 261
S1933191 3:16df793da2be 262 if (butsw3==0){
S1933191 3:16df793da2be 263 if (B==true){
S1933191 3:16df793da2be 264 motor2_direction.write(direction2 = !direction2);
S1933191 3:16df793da2be 265 pc.printf("direction: %s\r\n\n", direction2 ? "clockwise" : "counter clockwise");
S1933191 3:16df793da2be 266 B=false;
S1933191 3:16df793da2be 267 }
S1933191 3:16df793da2be 268 }
S1933191 3:16df793da2be 269 else{
S1933191 5:810892d669f9 270 B=true;}
S1933191 5:810892d669f9 271
S1933191 5:810892d669f9 272
S1933191 3:16df793da2be 273 }
S1933191 5:810892d669f9 274
S1933191 2:5093b66c9b26 275 void state_machine()
S1933191 2:5093b66c9b26 276 {
S1933191 2:5093b66c9b26 277 //run current state
S1933191 2:5093b66c9b26 278 switch (state) {
S1933191 5:810892d669f9 279 case s_idle: // in deze state gebeurd niets. Als op knop 1 wordt gedrukt
S1933191 5:810892d669f9 280 rest(); // gaan we over naar s_calibratie_encoder
S1933191 5:810892d669f9 281 break;
S1933191 5:810892d669f9 282 case s_calibratie_encoder: // in deze state worden de encoders gekalibreerd. knop 1 -> s_demonstratie
S1933191 5:810892d669f9 283 calibratie_encoder(); // knop 2 -> s_EMGcalibratie
S1933191 5:810892d669f9 284 break;
S1933191 5:810892d669f9 285 case s_demonstratie: // in deze state kunnen de motors worden bestuurd met de potmeters
S1933191 5:810892d669f9 286 MeasureAndControl(); // en switch 2 en 3( pot1,sw2->motor1 / pot2,sw3->motor2
S1933191 5:810892d669f9 287 direction(); // als op knop 2 wordt gedrukt komen we in de s_idle state
S1933191 5:810892d669f9 288 if (but2_pressed) {
S1933191 5:810892d669f9 289 pc.printf("fail. \r\n");
S1933191 5:810892d669f9 290 but2_pressed = false;
S1933191 5:810892d669f9 291 state_changed = true;
S1933191 5:810892d669f9 292 state = s_idle;
S1933191 5:810892d669f9 293 }
S1933191 5:810892d669f9 294 break;
S1933191 5:810892d669f9 295 case s_EMGcalibratie:
S1933191 3:16df793da2be 296 rest();
S1933191 2:5093b66c9b26 297 break;
S1933191 2:5093b66c9b26 298
S1933191 2:5093b66c9b26 299 }
S1933191 2:5093b66c9b26 300 }
RobertoO 0:67c50348f842 301
S1933191 2:5093b66c9b26 302 void but1_interrupt()
S1933191 2:5093b66c9b26 303 {
S1933191 2:5093b66c9b26 304 if(but2.read()) {//both buttons are pressed
S1933191 2:5093b66c9b26 305 failure_occurred = true;
S1933191 2:5093b66c9b26 306 }
S1933191 2:5093b66c9b26 307 but1_pressed = true;
S1933191 3:16df793da2be 308 pc.printf("Button 1 pressed \n\r");
S1933191 2:5093b66c9b26 309 }
S1933191 2:5093b66c9b26 310
S1933191 2:5093b66c9b26 311 void but2_interrupt()
S1933191 2:5093b66c9b26 312 {
S1933191 2:5093b66c9b26 313 if(but1.read()) {//both buttons are pressed
S1933191 2:5093b66c9b26 314 failure_occurred = true;
S1933191 2:5093b66c9b26 315 }
S1933191 2:5093b66c9b26 316 but2_pressed = true;
S1933191 2:5093b66c9b26 317 pc.printf("Button 2 pressed \n\r");
S1933191 2:5093b66c9b26 318 }
S1933191 3:16df793da2be 319
S1933191 2:5093b66c9b26 320 void main_loop()
S1933191 2:5093b66c9b26 321 {
S1933191 2:5093b66c9b26 322 state_machine();
S1933191 2:5093b66c9b26 323 }
RobertoO 0:67c50348f842 324
RobertoO 0:67c50348f842 325 int main()
RobertoO 0:67c50348f842 326 {
RobertoO 0:67c50348f842 327 pc.baud(115200);
S1933191 2:5093b66c9b26 328 pc.printf("Executing main()... \r\n");
S1933191 2:5093b66c9b26 329 state = s_idle;
S1933191 2:5093b66c9b26 330
RobertoO 0:67c50348f842 331
S1933191 2:5093b66c9b26 332 but1.fall(&but1_interrupt);
S1933191 2:5093b66c9b26 333 but2.fall(&but2_interrupt);
S1933191 2:5093b66c9b26 334 loop_ticker.attach(&main_loop, dt);
S1933191 2:5093b66c9b26 335 pc.printf("main_loop is running\n\r");
S1933191 5:810892d669f9 336
S1933191 5:810892d669f9 337 }
S1933191 5:810892d669f9 338
S1933191 2:5093b66c9b26 339