Control up to two motors using filtered EMG signals and a PID controller

Dependencies:   FastPWM HIDScope MODSERIAL QEI Matrix biquadFilter controller errorFetch mbed motorConfig refGen MatrixMath inverseKinematics

Fork of Minor_test_serial by First Last

Revision:
38:f1d2d42a4bdc
Parent:
37:633dd1901681
Child:
39:d065ad7a978d
--- a/main.cpp	Mon Oct 23 13:50:49 2017 +0000
+++ b/main.cpp	Tue Oct 24 13:17:42 2017 +0000
@@ -14,7 +14,7 @@
 
 // ADJUSTABLE PARAMETERS
 // controller ticker time interval
-const float Ts = 0.1;
+const float Ts = 0.01;
 
 // EMG filter parameters
 // calibration time
@@ -68,7 +68,7 @@
 InterruptIn sw3(SW3);
 InterruptIn button1(D2);
 InterruptIn button2(D3);
-//AnalogIn pot2(A3);
+//AnalogIn pot2(A2);
 //AnalogIn emg0( A0 );
 //AnalogIn emg1( A1 );
 
@@ -101,22 +101,22 @@
 
 
 // REFERENCE PARAMETERS
-int posRevRange = 2; // describes the ends of the position range in complete motor output shaft revolutions in both directions
+int posRevRange = 5; // describes the ends of the position range in complete motor output shaft revolutions in both directions
 const float maxAngle = 2*3.14*posRevRange; // max angle in radians
 
 
 // Function getReferencePosition returns reference angle based on potmeter 1
 refGen ref1(A1, maxAngle);
-//refGen ref2(A2, maxAngle);
+refGen ref2(A1, maxAngle);
 
 // readEncoder reads counts and revs and logs results to serial window
 errorFetch e1(gearRatio, Ts);
-//errorFetch e2(gearRatio, Ts);
+errorFetch e2(gearRatio, Ts);
 
 // Generate a PID controller with the specified values of k_p, k_d and k_i
 controller motorController1(k_p, k_d, k_i);
-    
-// setMotor1 sets the direction and magnitude pins of motor1 depending on the given motorValue. Negative motorValue means clockwise rotation
+controller motorController2(k_p, k_d, k_i);
+
 motorConfig motor1(D4,D5);
 motorConfig motor2(D7,D6);
 
@@ -126,8 +126,12 @@
     m1counts = Encoder1.getPulses();
     m2counts = Encoder2.getPulses();
     float r1_uf = ref1.getReference();
-    //float r2_uf = ref2.getReference();
+    float r2_uf = ref2.getReference();
     pc.printf("In controller ticker \r\n");
+    
+    float r1 = r1_uf;
+    float r2 = r2_uf;
+    
     // Finite state machine
     switch(currentState){
             case KILLED:
@@ -135,13 +139,12 @@
                 // Initialization of KILLED state: cut power to both motors
                 if(stateChanged){
                     motor1.kill();
-                    //motor2.kill();
+                    motor2.kill();
                     pc.printf("Killed state \r\n");
                     stateChanged = false;               
                     }
 
                 // Send reference data to pc
-                sendDataToPc(r1_uf, r1_uf, r1_uf, r1_uf, r1_uf); // just send the EMG signal value to HIDscope
                 
                 // Set LED to red
                 ledR = 0;
@@ -149,6 +152,11 @@
                 ledB = 1;
                 // need something here to check if "killswitch" has been pressed (?)
                 // NOTE: state transition is handled using buttons triggering functions motorConfig::kill() and motorConfig::turnMotorOn
+                e1.fetchError(m1counts, r1);
+                e2.fetchError(m2counts, r2);
+
+                sendDataToPc(r1, r2, e1.e_pos, e2.e_pos, 0.0); // just send the EMG signal value to HIDscope
+                
                 break;
                 }
             case ACTIVE:
@@ -161,21 +169,24 @@
                 r1 = fabs(r1);
                 r1 = LPbqc.applyFilter(r1);
 
-                //float r2 = HPbqc.applyFilter(r2_uf);
-                //r2 = fabs(r2);
-                //r2 = LPbqc.applyFilter(r2);
+                float r2 = HPbqc.applyFilter(r2_uf);
+                r2 = fabs(r2);
+                r2 = LPbqc.applyFilter(r2);
 
                 
+                
                 // Compute error
                 e1.fetchError(m1counts, r1);
-                //e2.fetchError(m2counts, r2);
+                e2.fetchError(m2counts, r2);
                 
                 // Compute motor value using controller and set motor
-                float motorValue = motorController1.control(e1.e_pos, e1.e_int, e1.e_der);
-                motor1.setMotor(motorValue);
+                float motorValue1 = motorController1.control(e1.e_pos, e1.e_int, e1.e_der);
+                float motorValue2 = motorController2.control(e2.e_pos, e2.e_int, e2.e_der);
+                motor1.setMotor(motorValue1);
+                motor2.setMotor(motorValue2);
                 
                 // Send data to HIDscope
-                sendDataToPc(r1_uf, r1, e1.e_pos, e1.e_der, motorValue);
+                sendDataToPc(r1, r2, e1.e_pos, e2.e_pos, 0.0);
                 
                 // Set LED to blue
                 ledR = 1;
@@ -199,7 +210,7 @@
                     // Kill motors
                     pc.printf("Calibrate state \r\n");
                     motor1.kill();
-                    //motor2.kill();
+                    motor2.kill();
                     
                     // Clear sample value vector and reset counter variable
                     EMGsamples.clear();
@@ -230,7 +241,7 @@
                 ledR = 1;
                 ledG = 0;
                 ledB = 1;
-                sendDataToPc(r1_uf, r1_uf, r1_uf, r1_uf, r1_uf);
+                sendDataToPc(r1_uf, r2_uf, 0.0, 0.0, 0.0);
                 break;
                 }
         }
@@ -239,10 +250,15 @@
     
     }
 
-void rSwitchDirection(){
+void r1SwitchDirection(){
     ref1.r_direction = !ref1.r_direction;
     pc.printf("Switched reference direction! \r\n");
     }
+    
+void r2SwitchDirection(){
+    ref2.r_direction = !ref2.r_direction;
+    pc.printf("Switched reference direction! \r\n");
+    }
 
 void killSwitch(){
     currentState = KILLED;
@@ -266,8 +282,8 @@
     // Attaching state change functions to buttons;
     sw2.fall(&killSwitch);
     sw3.fall(&activateRobot);
-    button1.rise(&calibrateRobot);
-    button2.rise(&rSwitchDirection);
+    button1.rise(&r1SwitchDirection);
+    button2.rise(&calibrateRobot);
     
     controllerTicker.attach(measureAndControl, Ts);
     pc.printf("Encoder ticker attached and baudrate set");