8 option EMG

Dependencies:   HIDScope MODSERIAL QEI biquadFilter mbed

Files at this revision

API Documentation at this revision

Comitter:
ralphg_92
Date:
Fri Nov 03 08:38:14 2017 +0000
Parent:
42:3aa03b5cefb0
Commit message:
revisiting old memories

Changed in this revision

PID.lib Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 3aa03b5cefb0 -r a6fbcada47aa PID.lib
--- a/PID.lib	Fri Nov 03 03:52:30 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://os.mbed.com/users/aberk/code/PID/#6e12a3e5af19
diff -r 3aa03b5cefb0 -r a6fbcada47aa main.cpp
--- a/main.cpp	Fri Nov 03 03:52:30 2017 +0000
+++ b/main.cpp	Fri Nov 03 08:38:14 2017 +0000
@@ -2,7 +2,7 @@
 #include "HIDScope.h"
 #include "MODSERIAL.h"
 #include "BiQuad.h"
-#include "QEI.h"
+//#include "QEI.h"
 
 //Define Objects
     AnalogIn    emg1_in( A0 ); // Read Out The Signal
@@ -16,21 +16,21 @@
     PwmOut motor1pwm( D5);
     PwmOut motor2pwm( D6 );
     DigitalOut motor2direction( D7 );
-    QEI Encoder1(D10, D11, NC, 64); // Encoder
-    QEI Encoder2(D12, D13, NC, 64); 
+    //QEI Encoder1(D10, D11, NC, 32); // Encoder
+    //QEI Encoder2(D12, D13, NC, 32); 
 
     Ticker      main_timer;
     Ticker      max_read1;
     Ticker      max_read3;
     Ticker      Motorcontrol;
-    Ticker      tencoder;
-    HIDScope    scope( 4 );
+    HIDScope    scope( 6 );
     DigitalOut  red(LED_RED);
     DigitalOut  blue(LED_BLUE);
     DigitalOut  green(LED_GREEN);
-    Serial      pc(USBTX, USBRX);
+    MODSERIAL   pc(USBTX, USBRX);
 
-// EMG Variables & Constants
+
+// EMG Variables
     //Right Biceps
     double emg1;
     double emg1highfilter;
@@ -63,7 +63,7 @@
     double emg4lowfilter;
     double max4;
     double maxpart4;
-    // Moving Average Floats
+// Moving Average Floats
     // Right Biceps Movavg
     float RB0, RB1, RB2, RB3, RB4, RB5, RB6, RB7, RB8, RB9, RB10, RB11, RB12, 
      RB13, RB14, RB15, RB16, RB17, RB18, RB19, RB20, RB21, RB22, RB23, RB24, 
@@ -102,48 +102,10 @@
      RL85, RL86, RL87, MOVAVG_RL;    
     float AV = 0.02; //multiplication value for adding each movavg value
     // This value also adds a very slight gain to every value
-
-// RKI Variables & Constants
-    double setpoint1 = 2.35;
-    double setpoint2 = 0.785;
-    double x = 10.77;
-    double y = 15.73;
-    float pi = 3.14159265359;
-    float a = 22.25;             //originally 22.25, makes for xinitial=10.766874   // length of arm 1
-    float b = 26.5;             //originally 16.48   makes for yinitial=15.733      // length of arm 2
-    double alpha_old = 2.35;     //INITIAL ANGLES IN RADIANS
-    double beta_old = 0.785;
-    float delta1;
-    float delta2;
-    float diffmotor_a;
-    float diffmotor_b;
-
-// PID Variables & Constants
-    double Kp = 0.5;// you can set these constants however you like depending on trial & error
-    double Ki = 0.1;
-    double Kd = 0.1;
-
-    float last_error1 = 0;
-    float new_error1 = 0;
-    float change_error1 = 0;
-    float total_error1 = 0;
-    float pid_term1 = 0;
-    float pid_term_scaled1 = 0;
     
-    float last_error2 = 0;
-    float new_error2 = 0;
-    float change_error2 = 0;
-    float total_error2 = 0;
-    float pid_term2 = 0;
-    float pid_term_scaled2 = 0;
-    
-// Motor Variables & Constants
-    //float MV1 = 0;
-    //float MV2 = 0;
-    double count1 = 0;
-    double count2 = 0;
-    double angle1 = 2.35;
-    double angle2 = 0.785;
+// Motor Variables
+    float MV1 = 0;
+    float MV2 = 0;
    
 // BiQuad Filter Settings
     // Right Biceps
@@ -164,32 +126,9 @@
     BiQuad filterlow4(1.368e-03,2.737e-03,1.369e-03,-1.9219,9.274e-01);
     //
 
-// RKI Calculations
-//
-//
+// Finding max values for correct motor switch if the button is pressed
+// calibration of both biceps
 
-float inversekinematics1(float x, float y){
-    // cosine law:
-    float c = sqrtf(x*x + y*y);                             // here comes the relevant math, see my inverse kinematics explaination using cosine law
-    float alpha1 = acosf((a*a + c*c - b*b)/(2*a*c));
-    
-    // remaining parts of alpha:
-    float alpha2 = atan2f(y,x);
-    float alpha = alpha1 + alpha2;
-    return alpha;
-}
-
-float inversekinematics2(float x, float y){
-    // cosine law:
-    float c = sqrtf(x*x + y*y);                             // here comes the relevant math, see my inverse kinematics explaination using cosine law
-    float beta = acosf((a*a + b*b - c*c)/(2*a*b));
-    return beta;
-}
-
-// Finding max values for correct motor switch if the button is pressed
-//
-//
-// calibration of both biceps
 void get_max1(){
     if (max_reader12==0){
             green = !green;
@@ -279,6 +218,7 @@
 }
 
 // calibration of both lower arms
+
 void get_max3(){
     if (max_reader34==0){
             green = 1;
@@ -367,10 +307,8 @@
     maxpart4 = 0.17*max4; // set cut off voltage at 15% of max for right lower arm
 }
 
-// EMG Filtering & Scope
-//
-//
-void filter(/*double setpoint1, double setpoint2*/) {
+// Filtering & Scope
+void filter() {
     // Right Biceps
     emg1 = emg1_in.read();
     emg1highfilter = filterhigh1.step(emg1);
@@ -508,117 +446,81 @@
  // Compare measurement to the calibrated value to decide actions
  // more options could be added if the callibration is well defined enough
     // This part checks for right biceps contractions only
-/*    if (maxpart1<MOVAVG_RB || maxpart2<MOVAVG_LB || maxpart3<MOVAVG_LL || maxpart4<MOVAVG_RL){
-    wait(0.15f);*/
-        if (maxpart1<MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4>MOVAVG_RL){
+    if (maxpart1<MOVAVG_RB || maxpart2<MOVAVG_LB || maxpart3<MOVAVG_LL || maxpart4<MOVAVG_RL){
+    
+    if (maxpart1<MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4>MOVAVG_RL){
             red = 1;
             blue = 1;
             green = 0;
-            //MV1 = 0.5;
-            //MV2 = 0;
-            x = x + 0.1;
-            if (x > 16) {
-            x = 16;
-            }
-            double alpha = inversekinematics1(x,y); //calculate alpha and beta for current x,y
-            double beta = inversekinematics2(x,y);
-            setpoint1 = alpha;
-            setpoint2 = beta;
-            wait(0.1f);
-            
-        }            
-        // This part checks for left biceps contractions only  
-        else if (maxpart1>MOVAVG_RB && maxpart2<MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4>MOVAVG_RL){
+            MV1 = 0.08;
+            MV2 = 0;
+    }            
+    // This part checks for left biceps contractions only  
+    else if (maxpart1>MOVAVG_RB && maxpart2<MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4>MOVAVG_RL){
             red = 0;
             blue = 1;
             green = 1;
-            //MV1 = -0.5;
-            //MV2 = 0;
-            x = x - 0.1;
-            if (x < 10.77){
-            x = 10.87;
-            }
-            double alpha = inversekinematics1(x,y);
-            double beta = inversekinematics2(x,y);
-            setpoint1 = alpha;
-            setpoint2 = beta;
-            wait(0.1f);
-        }
-        // This part checks for left lower arm contractions only  
-        else if (maxpart1>MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3<MOVAVG_LL && maxpart4>MOVAVG_RL){
+            MV1 = -0.08;
+            MV2 = 0;
+    }
+    // This part checks for left lower arm contractions only  
+    else if (maxpart1>MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3<MOVAVG_LL && maxpart4>MOVAVG_RL){
             red = 1;
             blue = 0;
             green = 1;
-            //MV1 = 0;
-            //MV2 = 0.5;
-            y = y + 0.1;
-            if (y > 19.5) {
-            y = 19.5;
-            }
-            double alpha = inversekinematics1(x,y);
-            double beta = inversekinematics2(x,y);
-            setpoint1 = alpha;
-            setpoint2 = beta;
-            wait(0.1f);
-        }
-        // This part checks for right lower arm contractions only
-        else if (maxpart1>MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4<MOVAVG_RL){
+            MV1 = 0;
+            MV2 = 0.08;
+    }
+    // This part checks for right lower arm contractions only
+    else if (maxpart1>MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4<MOVAVG_RL){
             red = 0;
             blue = 1;
             green = 0;
-            //MV1 = 0;
-            //MV2 = -0.5;
-            y = y - 0.1;
-            if (y < 15.73) {
-            y = 15.83;
-            }
-            double alpha = inversekinematics1(x,y);
-            double beta = inversekinematics2(x,y);
-            setpoint1 = alpha;
-            setpoint2 = beta;
-            wait(0.1f);
-        }           
-/*        // This part checks for both lower arm contractions only 
-        else if (maxpart1>MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3<MOVAVG_LL && maxpart4<MOVAVG_RL){
+            MV1 = 0;
+            MV2 = -0.08;
+    }           
+    // This part checks for both lower arm contractions only 
+    else if (maxpart1>MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3<MOVAVG_LL && maxpart4<MOVAVG_RL){
+            red = 0;
+            blue = 0;
+            green = 0;
+            MV1 = -0.08;
+            MV2 = -0.08;
+    }
+    // This part checks for both biceps contractions only 
+    else if (maxpart1<MOVAVG_RB && maxpart2<MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4>MOVAVG_RL){
             red = 0;
             blue = 0;
             green = 0;
-            //MV1 = -0.5;
-            //MV2 = -0.5;
-        }
-        // This part checks for both biceps contractions only 
-        else if (maxpart1<MOVAVG_RB && maxpart2<MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4>MOVAVG_RL){
-            red = 0;
-            blue = 0;
-            green = 0;
-            //MV1 = 0.5;
-            //MV2 = 0.5;
-        }
-        // This part checks for right lower arm & left biceps contractions only
-        else if (maxpart1>MOVAVG_RB && maxpart2<MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4<MOVAVG_RL){
+            MV1 = 0.08;
+            MV2 = 0.08;
+    }
+    // This part checks for right lower arm & left biceps contractions only
+    else if (maxpart1>MOVAVG_RB && maxpart2<MOVAVG_LB && maxpart3>MOVAVG_LL && maxpart4<MOVAVG_RL){
             red = 0;
             blue = 0;
             green = 0;
-            //MV1 = 0.5;
-            //MV2 = -0.5;
-        }  
-        // This part checks for left lower arm & right biceps contractions only
-        else if (maxpart1<MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3<MOVAVG_LL && maxpart4>MOVAVG_RL){
+            MV1 = 0.08;
+            MV2 = -0.08;
+    }  
+    // This part checks for left lower arm & right biceps contractions only
+    else if (maxpart1<MOVAVG_RB && maxpart2>MOVAVG_LB && maxpart3<MOVAVG_LL && maxpart4>MOVAVG_RL){
             red = 0;
             blue = 0;
             green = 0;
-            //MV1 = -0.5;
-            //MV2 = 0.5;
-        }*/
-    //}                                 
-        else {
-            red = 1; // Shut down all led colors if no movement is registered
-            blue = 1;
-            green = 1;
-            //MV1 = 0;
-            //MV2 = 0;
-        }
-    
+            MV1 = -0.08;
+            MV2 = 0.08;
+    }
+    }                                 
+    else {
+        red = 1; // Shut down all led colors if no movement is registered
+        blue = 1;
+        green = 1;
+        MV1 = 0;
+        MV2 = 0;
+        //pc.printf( "No contraction registered\n");
+    }
+
     // Set the sampled emg values in channel 0 (the first channel) and 1 (the second channel) in the 'HIDScope' instance named 'scope'
     scope.set(0, MOVAVG_RB ); // plot Right biceps voltage 
     scope.set(1, MOVAVG_LB ); // Plot Left biceps voltage 
@@ -628,141 +530,42 @@
     
 }
 
-void encoders(){
-        count1 = Encoder1.getPulses();
-        count2 = Encoder2.getPulses();
-}
-
-/*
-
-// PID calculations
-//
-//
-void PIDcalculation1() {
-//PID calculation for motor 1
-    filter();
-    count1 = Encoder1.getPulses();
-    angle1 += (0.000748 * count1);
-    new_error1 = setpoint1 - angle1;
-    
-    change_error1 = new_error1 - last_error1;
-    total_error1 += new_error1;
-    pid_term1 = (Kp * new_error1) + (Ki * total_error1) + (Kd * change_error1);
-    if (pid_term1<-255) {
-    pid_term1 = -255;
-    }
-    if (pid_term1>255) {
-    pid_term1 = 255;
-    }
-    pid_term_scaled1 = abs(pid_term1);
-    
-    last_error1 = new_error1;
-}
-void PIDcalculation2() {    
-//PID calculation for motor 2
-    filter();
-    count2 = Encoder2.getPulses();
-    angle2 += (0.000748 * count2);
-    new_error2 = setpoint2 - angle2;
-    
-    change_error2 = new_error2 - last_error2;
-    total_error2 += new_error2;
-    pid_term2 = (Kp * new_error2) + (Ki * total_error2) + (Kd * change_error2);
-    if (pid_term2<-255) {
-    pid_term2 = -255;
-    }
-    if (pid_term2>255) {
-    pid_term2 = 255;
+// check MV1 to see if motor1 needs to be activated
+void SetMotor1(float MV1) {
+    motor1pwm = fabs(MV1); // motor speed 
+    if (MV1 >=0) {
+    motor1direction = 1; // clockwise rotation 
     }
-    pid_term_scaled2 = abs(pid_term2);
-    
-    last_error2 = new_error2;
-}
- */ 
-// Motor control
-//
-//
-// check to see if motor1 needs to be activated
-void SetMotor1() {
-    //PIDcalculation1();
-    //filter();
-    while (angle1<setpoint1 || angle1>setpoint1 || angle2<setpoint2 || angle2>setpoint2) {
-        encoders();
-        float count1;
-        float count2;
-        angle1 += (0.0981 * count1);
-        angle2 += (0.0981 * count2);
-        if (angle1<setpoint1 && angle2<setpoint2) {
-        motor1direction = 1; // counterclockwise rotation
-        motor2direction = 1;
-        }
-        else if (angle1>setpoint1 && angle2<setpoint2) {
-        motor1direction = 0; // clockwise rotation
-        motor2direction = 1;
-        }
-        else if (angle1<setpoint1 && angle2>setpoint2) {
-        motor1direction = 1;
-        motor2direction = 0;
-        }
-        else if (angle1>setpoint1 && angle2>setpoint2) {
-        motor1direction = 0;
-        motor2direction = 0;
-        }
-        if ((angle1<setpoint1 || angle1>setpoint1) && (angle2<setpoint2 || angle2>setpoint2)) {
-        motor1pwm = 0.2;
-        motor2pwm = 0.2;
-        }
-        else if ((angle1<setpoint1 || angle1>setpoint1) && (angle2 == setpoint2)) {
-        motor1pwm = 0.2;
-        motor2pwm = 0;
-        }
-        else if ((angle1 == setpoint1) && (angle2<setpoint2 || angle2>setpoint2)) {
-        motor1pwm = 0;
-        motor2pwm = 0.2;
-        }
-        else if ((angle1 == setpoint1) && (angle2 == setpoint2)){
-        motor1pwm = 0;
-        motor2pwm = 0;
-        }
+    else {
+    motor1direction = 0; // counterclockwise rotation 
     }
 }
-/*
-// check if motor1 needs to be activated
-void SetMotor2() {
-    filter();
-    //PIDcalculation2();
-    while (angle2<setpoint2 || angle2>setpoint2) {
-        count2 = Encoder2.getPulses();
-        angle2 += (0.0981 * count2);
-        if (angle2<setpoint2){
-        motor1direction = 0; // counterclockwise rotation
-        }
-        else  if (angle2>setpoint2){
-        motor1direction = 1; // clockwise rotation
-        }
-        if (angle2<setpoint2 || angle2>setpoint2) {
-        motor2pwm = 0.5;
-        }
-        else if (angle2 == setpoint2){
-        motor2pwm = 0;
-        }
+// check MV2 if motor1 needs to be activated
+void SetMotor2(float MV2) {
+    motor2pwm = fabs(MV2); // motor speed 
+    if (MV2 >=0) {
+    motor2direction = 1; // clockwise rotation
+    }
+    else {
+    motor2direction = 0; // counterclockwise rotation
     }
 }
 
-void MeasureAndControl(void) {
-    SetMotor1();
-    //SetMotor2();
+void MeasureAndControl(void)
+{
+    // This function measures the potmeter position, extracts a
+    // reference velocity from it, and controls the motor with 
+    // a simple FeedForward controller. Call this from a Ticker.
+    SetMotor1(MV1);
+    SetMotor2(MV2);
 }
-*/
+
     
 int main(){   
-    pc.baud(115200);
+
     main_timer.attach(&filter, 0.001); // set frequency for the filters at 1000Hz
     max_read1.attach(&get_max1, 2); // set the frequency of the calibration loop at 0.5Hz
     max_read3.attach(&get_max3, 2);
-    tencoder.attach(&encoders, 0.001);
-    Motorcontrol.attach(&SetMotor1,0.1);
-    //PIDtimer.attach(&PIDcalculation1, 0.005);
-    //PIDtimer.attach(&PIDcalculation2, 0.005);
+    Motorcontrol.attach(&MeasureAndControl,0.5);
     while(1) {}
 }
\ No newline at end of file