Final Version

Dependencies:   AnglePosition2 Encoder FastPWM MovementClean PIDController Servo SignalNumberClean biquadFilter mbed

Fork of ShowItv2 by Peter Knoben

Revision:
14:a8a69fee3fad
Parent:
12:0765ea2c4c85
Child:
15:a73b5abd0696
--- a/main.cpp	Thu Nov 02 13:23:01 2017 +0000
+++ b/main.cpp	Thu Nov 02 15:11:19 2017 +0000
@@ -1,4 +1,3 @@
-#include "MODSERIAL.h"
 #include "AnglePosition.h"
 #include "PIDControl.h"
 #include "BiQuad.h"
@@ -8,55 +7,57 @@
 #include "encoder.h"
 #include "Servo.h"
 #include "FastPWM.h"
-//#include "HIDScope.h"
 
-//This code is for Mbed 2
+//This code is for the main Mbed
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
-MODSERIAL pc(USBTX, USBRX);         //Establish connection
-Ticker MyControllerTicker;          //Declare Ticker for Motors
+Ticker MyTickerController;          //Declare Ticker for Motors
 Ticker MyTickerServo;               //Declare Ticker Servo control
 Ticker MyTickerMean;                //Declare Ticker Signalprocessing
+Ticker MyTickerFilter;              //Declare Ticker Filtering
 
-InterruptIn But1(PTA4);             //Declare button for min calibration
-InterruptIn Mode(PTC6);             //Declare button for max calibration
+InterruptIn But1(PTA4);             //Declare button for emg calibration
+InterruptIn Mode(PTC6);             //Declare button for mode selection
 
 AnglePosition Angle;                //Declare Angle calculater
 PIDControl PID;                     //Declare PID Controller
 SignalNumber SignalLeft;            //Declare Signal determiner for Left arm
 SignalNumber SignalRight;           //Declare Signal determiner for Right arm
-SignalNumber SignalMode;
-Movement MoveLeft;                  //Declare Movement determiner
-Movement MoveRight;
+Movement MoveLeft;                  //Declare Left Movement determiner
+Movement MoveRight;                 //Declare Right movement determiner
 
 AnalogIn    emg0( A0 );             //Set Inputpin for EMG 0 signal Left 
 AnalogIn    emg2( A2 );             //Set Inputpin for EMG 2 signal Right
-AnalogIn    emg4( A4 );             //Set Inputpin for EMG 4 signal Mode
-DigitalOut     Up( D9 );             //Set digital in for mode selection
-DigitalOut   Down( D8 );
-DigitalOut  Led_red(LED_RED);          
+DigitalOut     Up( D9 );            //Set digital out for raising the pen off the board
+DigitalOut   Down( D8 );            //Set digital out for lowering the pen off the board
+
+//Setting LEDs
+DigitalOut  Led_red(LED_RED);       
 DigitalOut  Led_green(LED_GREEN);
 DigitalOut  Led_blue(LED_BLUE);  
 DigitalOut  Led_calibration(D2);
 
 const float CONTROLLER_TS = 0.02;   //Motor frequency
-const float MEAN_TS = 0.002;        //Filter frequency
+const float MEAN_TS = 0.002;        //Moving average frequency
+const float FILTER_TS = 1e3;        //Filter frequency
+const float SERVO_TS = 0.01;        //Servo frequency
 
+void setled(){
+    Led_red=1; Led_green=1; Led_blue=1; Led_calibration=0;
+}
 //------------------------------------------------------------------------------
 //-----------------------------EMG Signals--------------------------------------
 //------------------------------------------------------------------------------
+
 // Filtering the signal and getting the usefull information out of it.
-const int n = 500;                  //Window size for the mean value, also adjust in signalnumber.cpp
-const int action =100;               //Number of same mean values to change the signalnumber
-const int m = 500;                  //Number of samples for calibration
-int CaseLeft, CaseRight, CaseMode;           //Strength of the muscles 
-float emg_offsetLeft, emg_offsetmaxLeft;     //Calibration offsets from zero to one for the left arm
-float emg_offsetRight, emg_offsetmaxRight;   //Calibration offsets from zero to one for the right arm
-float emg_offsetMode, emg_offsetmaxMode;
-float mean_value_left, mean_value_right, mean_value_mode;   //Mean value of the filtered system
-float kLeft, kRight, kMode;            //Scaling factors
-float Signal_filteredLeft, Signal_filteredRight, Signal_filteredMode;
+const int n = 500;                                  //Window size for the mean value, also adjust in signalnumber.cpp
+const int action =100;                              //Number of same mean values to change the signalnumber
+const int m = 500;                                  //Number of samples for calibration
+int SpeedLeft, SpeedRight;                            //Strength of the muscles 
+float emg_offsetLeft, emg_offsetRight;              //Calibration offsets from zero to one for the right arm
+float kLeft, kRight;                                //Scaling factors
+float Signal_filteredLeft, Signal_filteredRight;    //Variables to store the filterd signals
 
 //BiQuad filter variables
 BiQuad LP1L( 0.6389437261127493, 1.2778874522254986, 0.6389437261127493, 1.1429772843080919, 0.4127976201429053 ); //Lowpass filter Biquad
@@ -65,148 +66,108 @@
 BiQuad LP1R( 0.6389437261127493, 1.2778874522254986, 0.6389437261127493, 1.1429772843080919, 0.4127976201429053 ); //Lowpass filter Biquad
 BiQuad HP2R( 0.8370879899975344, -1.6741759799950688, 0.8370879899975344, -1.6474576182593796, 0.7008943417307579 ); //Highpass filter Biquad
 BiQuad NO3R( 0.7063988100714527, -1.1429772843080923, 0.7063988100714527, -1.1429772843080923,  0.41279762014290533); //Notch filter Biquad 
-BiQuad LP1M( 0.6389437261127493, 1.2778874522254986, 0.6389437261127493, 1.1429772843080919, 0.4127976201429053 ); //Lowpass filter Biquad
-BiQuad HP2M( 0.8370879899975344, -1.6741759799950688, 0.8370879899975344, -1.6474576182593796, 0.7008943417307579 ); //Highpass filter Biquad
-BiQuad NO3M( 0.7063988100714527, -1.1429772843080923, 0.7063988100714527, -1.1429772843080923,  0.41279762014290533); //Notch filter Biquad 
 BiQuadChain BiQuad_filter_Left;
 BiQuadChain BiQuad_filter_Right;
-BiQuadChain BiQuad_filter_Mode;
 
+//Filters-----------------------------------------------------------------------
+
+// Filter for the left signal
 float FilterLeft(float input){
     float Signal_filtered= BiQuad_filter_Left.step(input);
     return Signal_filtered;
 }
+// Filter for the right signal
 float FilterRight(float input){
     float Signal_filtered= BiQuad_filter_Right.step(input);
     return Signal_filtered;
 }
-float FilterMode(float input){
-    float Signal_filtered= BiQuad_filter_Mode.step(input);
-    return Signal_filtered;
-}
 
 //Calibration-------------------------------------------------------------------
-void setled(){
-    Led_red=1; Led_green=1; Led_blue=1; Led_calibration=0;
+
+// Calibrating the EMG signals. This function needs to be ativated when the 
+// muscles are flexed for over a second
+void calibration(){
+    emg_offsetLeft = SignalLeft.calibrate(m, FilterLeft(emg0));
+    emg_offsetRight = SignalRight.calibrate(m, FilterRight(emg2));
+    //Setting the emg scaling constants to reed between zero and one.
+    kLeft = 1/emg_offsetLeft;
+    kRight = 1/emg_offsetRight;
+    //Set led to Green to indicate if calibration is done
+    Led_calibration = 1;
 }
 
-// One calibration
-void maxcalibration(){
-    pc.printf("start max calibration \r\n");
-    emg_offsetmaxLeft = SignalLeft.calibrate(m, FilterLeft(emg0));
-    emg_offsetmaxRight = SignalRight.calibrate(m, FilterRight(emg2));
-    emg_offsetmaxMode = SignalMode.calibrate(m, FilterMode(emg4));
-    kLeft = 1/emg_offsetmaxLeft;
-    kRight = 1/emg_offsetmaxRight;
-    kMode = 1/emg_offsetmaxMode;
-    Led_calibration = 1;   //Set led to Green
+//Speedcontrol------------------------------------------------------------------
+//Determine the signalnumbers (i.e. speed) based on the strenght of the EMG signals
+void Speedcontrol(){
+    //Left Signals
+    Signal_filteredLeft = fabs(FilterLeft(emg0)*kLeft);//*kLeft
+    SpeedLeft = SignalLeft.getspeedLeft(n, action, Signal_filteredLeft);
+    //Right Signals
+    Signal_filteredRight = fabs(FilterRight(emg2)*kRight);//*kRight
+    SpeedRight = SignalRight.getspeedRight(n, action, Signal_filteredRight);
 }
 
 //------------------------------------------------------------------------------
 //---------------------------------Servo----------------------------------------
 //------------------------------------------------------------------------------
+//Sending a pulse to the other Mbed to raise the pen
 void up(){
-    Up = 1;
-    Up = 0;
-    Up = 1;
+    Up = 1; Up = 0; Up = 1;
 }
+//Sending a pulse to the other Mbed to lower the pen
 void down(){
-    Down = 1;
-    Down = 0;
-    Down = 1;
+    Down = 1; Down = 0; Down = 1;
 }
 
+//Setting the begin mode to zero
 int mode =0;
+// Enable the servo function when mode 3 or mode 6 is activated.
+// If the mean value for the Left arm stays long enough high the servo will raise
+// If the mean value for the Right arm stays long enough high the servo will lower 
 void servo(){
      if(mode==3||mode==6){   
-        Signal_filteredLeft = fabs(FilterLeft(emg0)*kLeft);//*kLeft
-        CaseLeft = SignalLeft.getnumberLeft(n, action, Signal_filteredLeft);
-        Signal_filteredRight = fabs(FilterRight(emg2)*kRight);//*kRight
-        CaseRight = SignalRight.getnumberRight(n, action, Signal_filteredRight);
-        if (CaseLeft == 2){
+        Signal_filteredLeft = fabs(FilterLeft(emg0)*kLeft);
+        Signal_filteredRight = fabs(FilterRight(emg2)*kRight);
+        SpeedLeft = SignalLeft.getspeedLeft(n, action, Signal_filteredLeft);
+        SpeedRight = SignalRight.getspeedRight(n, action, Signal_filteredRight);
+        if (SpeedLeft == 2){
             up();
         }
-        else if (CaseRight == 2){
+        if (SpeedRight == 2){
             down();
         }
     }
 }
-
-
 //------------------------------------------------------------------------------
 //---------------------------Mode selection-------------------------------------
 //------------------------------------------------------------------------------
 
-//Recieving mode selection from EMG mode signal
+//Function is called when the mode button is pressed and switches modes and led indication 
 void mode_selection(){
-    if(mode ==6){
+    //Switching to the next mode. (Total of 6 modes)
+    if(mode == 6){
         mode=1;
     }
     else{
         mode++;
-    }    
-    pc.printf("\r\n mode = %i \r\n", mode); 
-    
-    
+    }
+    //Setting the LED colour to indicate the operating mode    
     if((mode==3) || (mode==6)) {
-        Led_red = 0;
-        Led_green = 0;
-        Led_blue = 0;
+        Led_red = 0, Led_green = 0, Led_blue = 0;   //Set Led Mode to White
     }
     else if (mode==1) {
-        Led_red = 0;
-        Led_green = 1;
-        Led_blue = 1;
+        Led_red = 0, Led_green = 1, Led_blue = 1;   //Set Led Mode to Red
     }
     else if (mode==2) {
-        Led_red = 1;
-        Led_green = 0;
-        Led_blue = 1;
+        Led_red = 1, Led_green = 0, Led_blue = 1;   //Set Led Mode to Green
     }
     else if (mode==4) {
-        Led_red = 1;
-        Led_green = 1;
-        Led_blue = 0;
+        Led_red = 1, Led_green = 1, Led_blue = 0;   //Set Led Mode to Blue
         }
     else if (mode==5) {
-        Led_red = 0;
-        Led_green = 0;
-        Led_blue = 1;
+        Led_red = 0, Led_green = 0, Led_blue = 1;   //Set Led Mode to Yellow
     }
-    
 }
-
-// Control mode selection-------------------------------------------------------
-
-//Determine the signalnumbers (i.e. speed) based on the strenght of the EMG signals
-void signalnumber(){
-    //Left
-    Signal_filteredLeft = fabs(FilterLeft(emg0)*kLeft);//*kLeft
-//    mean_value_left = SignalLeft.getmeanLeft(n, Signal_filteredLeft);  
-    mean_value_left = SignalLeft.getmeanLeft(n, fabs(FilterLeft(emg0.read())*kLeft));        
-    CaseLeft = SignalLeft.getnumberLeft(n, action, Signal_filteredLeft);
-    //Right
-    Signal_filteredRight = fabs(FilterRight(emg2)*kRight);//*kRight
-//    mean_value_right = SignalRight.getmeanRight(n, Signal_filteredRight);
-    mean_value_right = SignalRight.getmeanRight(n, fabs(FilterRight(emg2.read())*kRight)); 
-    CaseRight = SignalRight.getnumberRight(n, action, Signal_filteredRight);
-    //Mode
-    /*
-    Signal_filteredMode = fabs(FilterMode(emg4));//*kMode
-    mean_value_mode = SignalMode.getmeanMode(n, Signal_filteredMode);
-    CaseMode = SignalMode.getnumberMode(n, action, Signal_filteredMode);
-    if(CaseMode >= 3){
-        milli ++;
-        if(milli>=150){
-            mode_selection();
-            milli=0;
-        }
-    }
-    else{
-        milli=0;
-    }*/
-}
-
 //------------------------------------------------------------------------------
 //-------------------------Kinematic Constants----------------------------------
 //------------------------------------------------------------------------------
@@ -239,7 +200,6 @@
     float position_alpha = RAD_PER_PULSE * encoder1.getPosition();
     float error_alpha = reference_alpha-position_alpha;
     float magnitude1 = PID.get(error_alpha, MOTOR1_KP, MOTOR1_KI, MOTOR1_KD, CONTROLLER_TS, M1_N, M1_v1, M1_v2) / motor1_gain;
-            
     //Determine Motor Magnitude
     if (fabs(magnitude1)>1) {
         motor1 = 1;
@@ -247,8 +207,6 @@
     else {
         motor1 = fabs(magnitude1);
     }
-    
-    
     // Determine Motor Direction 
     if (magnitude1  < 0){
         motor1DirectionPin = 1;
@@ -257,7 +215,6 @@
         motor1DirectionPin = 0;
     }
 }
-
 //------------------------------------------------------------------------------
 //--------------------------------Motor2----------------------------------------
 //------------------------------------------------------------------------------
@@ -278,7 +235,6 @@
     float position_beta = RAD_PER_PULSE * -encoder2.getPosition();
     float error_beta = reference_beta-position_beta;
     float magnitude2 = PID.get(error_beta, MOTOR2_KP, MOTOR2_KI, MOTOR2_KD, CONTROLLER_TS, M2_N, M1_v1, M1_v2) / motor2_gain;
-        
     //Determine Motor Magnitude
     if (fabs(magnitude2)>1) {
         motor2 = 1;
@@ -286,8 +242,6 @@
     else {
         motor2 = fabs(magnitude2);
     }
-    
-    
     //Determine Motor Direction
     if (magnitude2 > 0){
         motor2DirectionPin = 1;
@@ -296,67 +250,55 @@
         motor2DirectionPin = 0;
     }
 }
-
 //------------------------------------------------------------------------------
 //----------------------------Motor controller----------------------------------
 //------------------------------------------------------------------------------
-int direction_l, direction_r;
-float magnitude1, magnitude2;
+int direction_l, direction_r;           //Variables to store the directions
+float magnitude1, magnitude2;           //Variables to store the magnitude signal
 
 void motor_control(){
     direction_l = MoveLeft.getdirectionLeft(mode);                              //x-direction
     direction_r = MoveRight.getdirectionRight(mode);                            //y-direction
-    position_math_l= MoveLeft.getpositionLeft(CaseLeft, mode, max_rangex);      //x-direction
-    position_math_r= MoveRight.getpositionRight(CaseRight, mode, max_rangey);   //y-direction
-    motor1_control(); //magnitude1 = 
-    motor2_control(); // magnitude2 = 
-  
+    position_math_l= MoveLeft.getpositionLeft(SpeedLeft, mode, max_rangex);      //x-direction
+    position_math_r= MoveRight.getpositionRight(SpeedRight, mode, max_rangey);   //y-direction
+    motor1_control(); 
+    motor2_control();
 }
 //------------------------------------------------------------------------------
-//-------------------------------HID Scope--------------------------------------
+//-----------------------------Filter Update------------------------------------
 //------------------------------------------------------------------------------
 
-//HIDScope scope(4);
-//Ticker scopeTimer;
-Ticker FilterTimer;
-
+//Updating Filter values
 void FilterUpdate(){
     FilterLeft(emg0.read());
     FilterRight(emg2.read());
     SignalLeft.getmeanLeft(n, fabs(FilterLeft(emg0.read())));
     SignalRight.getmeanRight(n, fabs(FilterRight(emg2.read())));    
 }
-
-//Working
-//SignalLeft.getmeanLeft(n, fabs(FilterLeft(emg0.read())))
-//SignalRight.getmeanRight(n, fabs(FilterRight(emg2.read())))
-
 //------------------------------------------------------------------------------
 //------------------------------Main--------------------------------------------
 //------------------------------------------------------------------------------
 
 int main(){
-    pc.baud(115200);
     setled(); 
+    
+    //Creating Filters
     BiQuad_filter_Left.add( &LP1L ).add( &HP2L ).add( &NO3L);
     BiQuad_filter_Right.add( &LP1R ).add( &HP2R ).add( &NO3R);
-    BiQuad_filter_Mode.add( &LP1M ).add( &HP2M ).add( &NO3M);
-    But1.rise(&maxcalibration);
+    
+    //Button detection
+    But1.rise(&calibration);
     Mode.rise(&mode_selection);
+    
+    //Setting motor periods
     motor1.period(0.0001f); motor2.period(0.0001f);
-    MyControllerTicker.attach(&motor_control, CONTROLLER_TS); //Determining motorposiitons
-    MyTickerMean.attach(&signalnumber, MEAN_TS);  //Detemining the signalnumbers
-    MyTickerServo.attach(&servo, 0.1f);
-
-    //Scope
-    //scopeTimer.attach_us(&scope, &HIDScope::send, 2e4);
-    FilterTimer.attach_us(&FilterUpdate, 1e3);
+    
+    //Tickers
+    MyTickerController.attach(&motor_control, CONTROLLER_TS);
+    MyTickerMean.attach(&Speedcontrol, MEAN_TS);  
+    MyTickerServo.attach(&servo, SERVO_TS);
+    MyTickerFilter.attach_us(&FilterUpdate, FILTER_TS);
     
     while(1) {
-        //pc.printf(" direction  %i , %i  Signal numbers  %i  %i Position %f  %f  \r\n", direction_l, direction_r, CaseLeft, CaseRight, position_math_l, position_math_r); 
-        pc.printf("direction  %i , %i  Signal numbers  %i  %i Position %f  %f  magnitude1 =%f   magnitude2=%f \r\n",direction_l, direction_r, CaseLeft, CaseRight, position_math_l, position_math_r, magnitude1, magnitude2);
-        wait(0.1f);
     }
-}
-
-
+}
\ No newline at end of file