Leon Klute / Mbed 2 deprecated EMG_Controller_6

Dependencies:   HIDScope QEI biquadFilter mbed

Fork of EMG_Controller_5 by Nahuel Manterola

Committer:
LeeJon
Date:
Mon Oct 31 12:39:41 2016 +0000
Revision:
17:80316a7a917a
Parent:
16:58b0df053d45
Child:
18:7178416f2db5
wordt nu gecomment

Who changed what in which revision?

UserRevisionLine numberNew contents of line
NahuelM 0:46582bba07d2 1 #include "mbed.h"
NahuelM 0:46582bba07d2 2 #include "QEI.h"
NahuelM 3:1d43dd4f37eb 3
NahuelM 4:e59a99c5aa08 4 #include "servoController.h"
NahuelM 2:57523bb4e9c6 5 #include "emg.h"
NahuelM 2:57523bb4e9c6 6
NahuelM 1:83fccd7d8483 7 #define pi 3.14159265359;
NahuelM 0:46582bba07d2 8
NahuelM 0:46582bba07d2 9 PwmOut Motor1_pwm(D5);
NahuelM 1:83fccd7d8483 10 DigitalOut SlideMotor_Direction(D4);
NahuelM 1:83fccd7d8483 11 PwmOut Motor2_pwm(D6);
NahuelM 1:83fccd7d8483 12 DigitalOut LiftMotor_Direction(D7);
NahuelM 1:83fccd7d8483 13 AnalogIn Potmeter(A0);
NahuelM 2:57523bb4e9c6 14 AnalogIn Potmeter2(A1);
NahuelM 1:83fccd7d8483 15 QEI Slide_Encoder(D12,D13,NC,64);
NahuelM 1:83fccd7d8483 16 QEI Lift_Encoder(D10,D11,NC,64);
NahuelM 11:c8b6a2b314c3 17
NahuelM 11:c8b6a2b314c3 18 BiQuadChain Hz_1;
NahuelM 11:c8b6a2b314c3 19 BiQuad bq0(0.05852855368, 0.11705710736, 0.05852855368,-1.05207469728, 0.28586907478);
NahuelM 11:c8b6a2b314c3 20 BiQuad bq1(0.06463239794, 0.12926479589, 0.06463239794,-1.16338171052, 0.42191097989);
NahuelM 11:c8b6a2b314c3 21 BiQuad bq2(0.07902502847, 0.15805005694, 0.07902502847,-1.42439823874, 0.7409311811);
NahuelM 11:c8b6a2b314c3 22
LeeJon 17:80316a7a917a 23 Serial pc(USBTX,USBRX);
NahuelM 0:46582bba07d2 24 Ticker Controller;
NahuelM 0:46582bba07d2 25
NahuelM 1:83fccd7d8483 26 bool Controller_Flag=0;
LeeJon 7:eed677b636d3 27 float Frequency = 30;
NahuelM 0:46582bba07d2 28 float Frequency_PWM = 10000;
NahuelM 1:83fccd7d8483 29
NahuelM 1:83fccd7d8483 30 float Slide_Radius = 12.5;
NahuelM 1:83fccd7d8483 31 float Slide_Multiplier = 1;
NahuelM 1:83fccd7d8483 32 float k1 = 1;
NahuelM 12:12c162dc8893 33 float k2 = 0.1f;
NahuelM 1:83fccd7d8483 34 float k3 = 0.1f;
NahuelM 1:83fccd7d8483 35 float Start_slow = 40;
NahuelM 1:83fccd7d8483 36 float Start_lock = 0;
NahuelM 1:83fccd7d8483 37 float End_slow = 340;
NahuelM 1:83fccd7d8483 38 float End_lock = 380;
NahuelM 1:83fccd7d8483 39 float Slide_Counts;
NahuelM 1:83fccd7d8483 40 float Slide_Revolutions;
NahuelM 1:83fccd7d8483 41 float Slide_Angle;
NahuelM 1:83fccd7d8483 42 float Slide_Position;
NahuelM 0:46582bba07d2 43
NahuelM 1:83fccd7d8483 44 float Slide_Input_force = 0;
NahuelM 1:83fccd7d8483 45 float Slide_Curr_speed = 0;
NahuelM 1:83fccd7d8483 46 float Slide_Desired_speed;
NahuelM 1:83fccd7d8483 47 float Slide_Delta_speed;
NahuelM 1:83fccd7d8483 48 float Slide_Int_delta_speed;
NahuelM 1:83fccd7d8483 49 float Slide_Deriv_delta_speed = 0;
NahuelM 1:83fccd7d8483 50 float Slide_Prev_delta_speed = 0;
NahuelM 1:83fccd7d8483 51 float Slide_PI;
NahuelM 1:83fccd7d8483 52
NahuelM 1:83fccd7d8483 53 float Lift_Radius = 10;
NahuelM 1:83fccd7d8483 54 float Lift_Multiplier = 1;
NahuelM 11:c8b6a2b314c3 55 float Lift_k1 = 0.2;
NahuelM 1:83fccd7d8483 56 float Lift_k2 = 0.05;
NahuelM 1:83fccd7d8483 57 float Lift_k3 = 0.01;
NahuelM 1:83fccd7d8483 58 float Lift_Start = 0;
NahuelM 1:83fccd7d8483 59 float Lift_End = 50;
NahuelM 1:83fccd7d8483 60 float Lift_Counts;
NahuelM 1:83fccd7d8483 61 float Lift_Revolutions;
NahuelM 1:83fccd7d8483 62 float Lift_Angle;
NahuelM 1:83fccd7d8483 63 float Lift_Position;
NahuelM 1:83fccd7d8483 64
NahuelM 1:83fccd7d8483 65 float Lift_Input_force = 0;
NahuelM 1:83fccd7d8483 66 float Lift_Desired_position;
NahuelM 1:83fccd7d8483 67 float Lift_Delta_position;
NahuelM 1:83fccd7d8483 68 float Lift_Int_delta_position;
NahuelM 1:83fccd7d8483 69 float Lift_Deriv_delta_position = 0;
NahuelM 1:83fccd7d8483 70 float Lift_Prev_delta_position = 0;
NahuelM 1:83fccd7d8483 71 float Lift_PI;
NahuelM 12:12c162dc8893 72 bool Lift_Switch = false;
NahuelM 12:12c162dc8893 73 Timeout Lift_Timeout;
NahuelM 12:12c162dc8893 74 bool Lift_Timeout_Switch = true;
NahuelM 0:46582bba07d2 75
LeeJon 17:80316a7a917a 76 // state machine variables
LeeJon 15:4cd14d429ad8 77 float statechange_threshold = 0.6;
LeeJon 13:0adbf6a5de37 78 bool binary_norm_emg_2 = 0;
LeeJon 13:0adbf6a5de37 79 bool binary_norm_emg_2_previous = 0;
LeeJon 17:80316a7a917a 80 states scoopstate = STATE_MOVE; // all states are defined in one place in emg.h
LeeJon 13:0adbf6a5de37 81 bool state_resettime_value = 1;
LeeJon 13:0adbf6a5de37 82 Timeout state_resettime;
LeeJon 13:0adbf6a5de37 83 DigitalOut LED_STATE_MOVE(D15);
LeeJon 13:0adbf6a5de37 84 DigitalOut LED_STATE_GRAB(D14);
LeeJon 13:0adbf6a5de37 85 Timeout controlstarterTimeout;
LeeJon 13:0adbf6a5de37 86
LeeJon 17:80316a7a917a 87 //callable functions
LeeJon 15:4cd14d429ad8 88 void Slide_Controller();
LeeJon 15:4cd14d429ad8 89 void Lift_Controller();
LeeJon 15:4cd14d429ad8 90 void Ticker_Flag();
LeeJon 15:4cd14d429ad8 91 void set2true();
LeeJon 15:4cd14d429ad8 92 void change_scoopstate();
LeeJon 15:4cd14d429ad8 93 void start_controlling();
LeeJon 13:0adbf6a5de37 94
NahuelM 0:46582bba07d2 95 int main()
NahuelM 0:46582bba07d2 96 {
NahuelM 0:46582bba07d2 97 Motor1_pwm.period(1.0/Frequency_PWM);//T=1/f
NahuelM 1:83fccd7d8483 98 Motor2_pwm.period(1.0/Frequency_PWM);//T=1/f
LeeJon 13:0adbf6a5de37 99
NahuelM 0:46582bba07d2 100 pc.baud(9600);
NahuelM 2:57523bb4e9c6 101
pbaardwijk 6:6cb7c0247560 102 led.write(1);
NahuelM 3:1d43dd4f37eb 103 Lift_Input_force = Potmeter.read();
NahuelM 3:1d43dd4f37eb 104 Slide_Input_force = Potmeter2.read();
NahuelM 3:1d43dd4f37eb 105
LeeJon 17:80316a7a917a 106 // define the filters used in main
NahuelM 12:12c162dc8893 107 notch_50_0.add( &bq03 ).add( &bq04 ).add( &bq05 );
NahuelM 12:12c162dc8893 108 notch_50_1.add( &bq13 ).add( &bq14 ).add( &bq15 );
NahuelM 12:12c162dc8893 109 notch_50_2.add( &bq23 ).add( &bq24 ).add( &bq25 );
NahuelM 12:12c162dc8893 110 high_pass_0.add( &bq06 ).add( &bq07 );
NahuelM 12:12c162dc8893 111 high_pass_1.add( &bq16 ).add( &bq17 );
NahuelM 12:12c162dc8893 112 high_pass_2.add( &bq26 ).add( &bq27 );
NahuelM 12:12c162dc8893 113 low_pass_0.add( &bq9 ).add( &bq10 ).add( &bq11 );
NahuelM 12:12c162dc8893 114 low_pass_1.add( &bq19 ).add( &bq110 ).add( &bq111 );
NahuelM 12:12c162dc8893 115 low_pass_2.add( &bq29 ).add( &bq210 ).add( &bq211 );
NahuelM 3:1d43dd4f37eb 116
LeeJon 17:80316a7a917a 117 //call the timeouts for the startup states and the tickers for reading the emgs
NahuelM 11:c8b6a2b314c3 118 change_state.attach( &calibrate,1);
NahuelM 11:c8b6a2b314c3 119 change_state2.attach( &run,11);
LeeJon 16:58b0df053d45 120 controlstarterTimeout.attach(&start_controlling,11);
pbaardwijk 9:1cb2d5ab51e6 121 emgSampleTicker.attach( &emgSample, 0.005); //200Hz
NahuelM 4:e59a99c5aa08 122 ServoPWMpin.period(0.01f); // 0.01 second period
NahuelM 4:e59a99c5aa08 123
NahuelM 0:46582bba07d2 124 while (true) {
pbaardwijk 6:6cb7c0247560 125 // pc.printf("\n\r%f", Norm_EMG_0);
NahuelM 3:1d43dd4f37eb 126 if (go_emgSample == true){
NahuelM 3:1d43dd4f37eb 127 EMG_filter();
NahuelM 3:1d43dd4f37eb 128 }
NahuelM 1:83fccd7d8483 129
NahuelM 1:83fccd7d8483 130 if (Controller_Flag == true){
LeeJon 13:0adbf6a5de37 131 if(Norm_EMG_2 > statechange_threshold){
LeeJon 13:0adbf6a5de37 132 binary_norm_emg_2 = 1;
LeeJon 13:0adbf6a5de37 133 }else{
LeeJon 13:0adbf6a5de37 134 binary_norm_emg_2 = 0;
LeeJon 13:0adbf6a5de37 135 }
LeeJon 13:0adbf6a5de37 136 if((binary_norm_emg_2 != binary_norm_emg_2_previous)&&binary_norm_emg_2&&state_resettime_value){
LeeJon 13:0adbf6a5de37 137 change_scoopstate();
LeeJon 13:0adbf6a5de37 138 }
LeeJon 13:0adbf6a5de37 139 binary_norm_emg_2_previous = binary_norm_emg_2;
NahuelM 4:e59a99c5aa08 140
LeeJon 13:0adbf6a5de37 141 switch(scoopstate){
LeeJon 13:0adbf6a5de37 142 case STATE_MOVE:
LeeJon 13:0adbf6a5de37 143 Slide_Controller();
LeeJon 13:0adbf6a5de37 144 LED_STATE_MOVE = 1;
LeeJon 13:0adbf6a5de37 145 LED_STATE_GRAB = 0;
LeeJon 13:0adbf6a5de37 146 break;
LeeJon 13:0adbf6a5de37 147 case STATE_GRAB:
LeeJon 13:0adbf6a5de37 148 Lift_Controller();
NahuelM 14:a27de0ddf09f 149 control_servo(Norm_EMG_1);
LeeJon 13:0adbf6a5de37 150 LED_STATE_GRAB = 1;
LeeJon 13:0adbf6a5de37 151 LED_STATE_MOVE = 0;
LeeJon 13:0adbf6a5de37 152 break;
LeeJon 16:58b0df053d45 153 }
NahuelM 2:57523bb4e9c6 154 Controller_Flag = false;
NahuelM 1:83fccd7d8483 155 }
NahuelM 0:46582bba07d2 156 }
NahuelM 0:46582bba07d2 157 return 0;
NahuelM 0:46582bba07d2 158 }
LeeJon 5:bb77e2a6c1e8 159
LeeJon 15:4cd14d429ad8 160 void set2true(){
LeeJon 15:4cd14d429ad8 161 state_resettime_value = 1;
LeeJon 15:4cd14d429ad8 162 }
LeeJon 15:4cd14d429ad8 163
LeeJon 15:4cd14d429ad8 164 void change_scoopstate(){
LeeJon 15:4cd14d429ad8 165 Motor1_pwm.write(0);
LeeJon 15:4cd14d429ad8 166 Motor2_pwm.write(0);
LeeJon 15:4cd14d429ad8 167 switch(scoopstate){
LeeJon 15:4cd14d429ad8 168 case STATE_MOVE:
LeeJon 15:4cd14d429ad8 169 scoopstate = STATE_GRAB;
LeeJon 15:4cd14d429ad8 170 break;
LeeJon 15:4cd14d429ad8 171 case STATE_GRAB:
LeeJon 15:4cd14d429ad8 172 scoopstate = STATE_MOVE;
LeeJon 15:4cd14d429ad8 173 break;
LeeJon 15:4cd14d429ad8 174 }
LeeJon 15:4cd14d429ad8 175 state_resettime.attach(&set2true, 1);
LeeJon 15:4cd14d429ad8 176 state_resettime_value = 0;
LeeJon 15:4cd14d429ad8 177 }
LeeJon 15:4cd14d429ad8 178
LeeJon 15:4cd14d429ad8 179 void start_controlling(){
LeeJon 15:4cd14d429ad8 180 Controller.attach(&Ticker_Flag,1/Frequency);
LeeJon 15:4cd14d429ad8 181 }
LeeJon 15:4cd14d429ad8 182
NahuelM 1:83fccd7d8483 183 void Ticker_Flag(){
NahuelM 1:83fccd7d8483 184 Controller_Flag = true;
NahuelM 0:46582bba07d2 185 }
NahuelM 0:46582bba07d2 186
NahuelM 0:46582bba07d2 187 void Slide_Controller(){ // Dit ding moet keihard geloopt worden op minstens 30 Hz (Frequency)
NahuelM 2:57523bb4e9c6 188
NahuelM 2:57523bb4e9c6 189 Slide_Counts = Slide_Encoder.getPulses();
NahuelM 2:57523bb4e9c6 190 Slide_Revolutions = Slide_Counts /(32*131);
NahuelM 2:57523bb4e9c6 191 Slide_Angle = Slide_Revolutions*2*pi;
NahuelM 2:57523bb4e9c6 192 Slide_Position = Slide_Angle*Slide_Radius + 135;
NahuelM 2:57523bb4e9c6 193
NahuelM 12:12c162dc8893 194 Slide_Desired_speed= (-Norm_EMG_1+Norm_EMG_0)*Slide_Multiplier;
NahuelM 11:c8b6a2b314c3 195
NahuelM 11:c8b6a2b314c3 196
NahuelM 1:83fccd7d8483 197 if (Slide_Position < Start_slow && Slide_Desired_speed > 0){
NahuelM 1:83fccd7d8483 198 Slide_Desired_speed *= (Slide_Position-Start_lock)/(Start_slow-Start_lock);
NahuelM 1:83fccd7d8483 199
NahuelM 0:46582bba07d2 200 }
NahuelM 1:83fccd7d8483 201 if (Slide_Position > End_slow && Slide_Desired_speed < 0){
NahuelM 1:83fccd7d8483 202 Slide_Desired_speed *= (End_lock-Slide_Position)/(End_lock-End_slow);
NahuelM 0:46582bba07d2 203 }
NahuelM 11:c8b6a2b314c3 204
NahuelM 1:83fccd7d8483 205 Slide_Prev_delta_speed = Slide_Delta_speed;
NahuelM 1:83fccd7d8483 206 Slide_Delta_speed = Slide_Desired_speed-Slide_Curr_speed; // P
NahuelM 1:83fccd7d8483 207 Slide_Int_delta_speed += Slide_Delta_speed/Frequency; // I
NahuelM 11:c8b6a2b314c3 208 if (Slide_Int_delta_speed > 1){Slide_Int_delta_speed = 1;}
NahuelM 11:c8b6a2b314c3 209 if (Slide_Int_delta_speed < -1){Slide_Int_delta_speed = -1;}
NahuelM 11:c8b6a2b314c3 210 Slide_Int_delta_speed *= 1/1.3;
NahuelM 12:12c162dc8893 211 pc.printf("%f - %f - %f \r\n",Norm_EMG_0, Norm_EMG_1, Slide_Delta_speed);
NahuelM 12:12c162dc8893 212 Slide_PI = k1*Slide_Delta_speed + k2*Slide_Int_delta_speed;
NahuelM 1:83fccd7d8483 213 if (Slide_PI<0){
NahuelM 1:83fccd7d8483 214 SlideMotor_Direction = 0;
NahuelM 1:83fccd7d8483 215 }else{
NahuelM 1:83fccd7d8483 216 SlideMotor_Direction = 1;
NahuelM 1:83fccd7d8483 217 }
NahuelM 1:83fccd7d8483 218
NahuelM 1:83fccd7d8483 219 Motor1_pwm.write(abs(Slide_PI));
NahuelM 1:83fccd7d8483 220 //return k1*Delta_speed + k2*Int_delta_speed;
NahuelM 1:83fccd7d8483 221 }
NahuelM 1:83fccd7d8483 222
NahuelM 12:12c162dc8893 223 void Lift_Timeout_Return(){
NahuelM 12:12c162dc8893 224 Lift_Timeout_Switch = true;
NahuelM 12:12c162dc8893 225 }
NahuelM 12:12c162dc8893 226
NahuelM 1:83fccd7d8483 227 void Lift_Controller(){ // Dit ding moet keihard geloopt worden op minstens 30 Hz (Frequency)
NahuelM 1:83fccd7d8483 228
NahuelM 2:57523bb4e9c6 229 Lift_Counts = Lift_Encoder.getPulses();
NahuelM 2:57523bb4e9c6 230 Lift_Revolutions = Lift_Counts /(32*131);
NahuelM 2:57523bb4e9c6 231 Lift_Angle = Lift_Revolutions*2*pi;
NahuelM 2:57523bb4e9c6 232 Lift_Position = Lift_Angle*Lift_Radius;
NahuelM 2:57523bb4e9c6 233
NahuelM 12:12c162dc8893 234 if(Norm_EMG_0 > 0.6 && Lift_Timeout_Switch == true){
LeeJon 13:0adbf6a5de37 235 Lift_Switch = !Lift_Switch;
NahuelM 12:12c162dc8893 236 Lift_Timeout_Switch = false;
NahuelM 12:12c162dc8893 237 Lift_Timeout.attach(Lift_Timeout_Return, 1);
NahuelM 12:12c162dc8893 238 }
NahuelM 12:12c162dc8893 239
NahuelM 12:12c162dc8893 240 Lift_Desired_position = Lift_Switch*150;
NahuelM 3:1d43dd4f37eb 241 //pc.printf("\n\r%f - %f", Lift_Desired_position, Lift_Position);
NahuelM 1:83fccd7d8483 242 Lift_Prev_delta_position = Lift_Delta_position;
NahuelM 1:83fccd7d8483 243 Lift_Delta_position = Lift_Desired_position-Lift_Position; // P
NahuelM 1:83fccd7d8483 244 Lift_Int_delta_position += Lift_Delta_position/Frequency; // I
NahuelM 1:83fccd7d8483 245
NahuelM 11:c8b6a2b314c3 246 Lift_Deriv_delta_position = (Lift_Delta_position-Lift_Prev_delta_position)*Frequency; //D
NahuelM 11:c8b6a2b314c3 247 if (Lift_Int_delta_position > 1){Lift_Int_delta_position = 1;}
NahuelM 11:c8b6a2b314c3 248 if (Lift_Int_delta_position < -1){Lift_Int_delta_position = -1;}
NahuelM 12:12c162dc8893 249
NahuelM 11:c8b6a2b314c3 250 Lift_PI = Lift_k1*Lift_Delta_position + 0*Lift_Int_delta_position + Lift_k3*Lift_Deriv_delta_position;
NahuelM 1:83fccd7d8483 251 if (Lift_PI<0){
NahuelM 1:83fccd7d8483 252 LiftMotor_Direction = 1;
NahuelM 1:83fccd7d8483 253 }else{
NahuelM 1:83fccd7d8483 254 LiftMotor_Direction = 0;
NahuelM 1:83fccd7d8483 255 }
NahuelM 1:83fccd7d8483 256
NahuelM 1:83fccd7d8483 257 Motor2_pwm.write(abs(Lift_PI));
NahuelM 1:83fccd7d8483 258 //return k1*Delta_speed + k2*Int_delta_speed;
NahuelM 0:46582bba07d2 259 }