Working EMG signals Mode control Direction control Position control Speed control

Dependencies:   AnglePosition2 Encoder FastPWM HIDScope MODSERIAL Movement PIDController Servo SignalNumber2 biquadFilter mbed

Fork of kinematics_control_copyfds by Peter Knoben

Files at this revision

API Documentation at this revision

Comitter:
peterknoben
Date:
Tue Oct 31 14:35:52 2017 +0000
Parent:
3:c768a37620c9
Child:
5:b4abbd3c513c
Commit message:
sdfasdf

Changed in this revision

AnglePosition.lib Show annotated file Show diff for this revision Revisions of this file
Movement.lib Show annotated file Show diff for this revision Revisions of this file
SignalNumber.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/AnglePosition.lib	Mon Oct 30 10:43:26 2017 +0000
+++ b/AnglePosition.lib	Tue Oct 31 14:35:52 2017 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/peterknoben/code/AnglePosition/#d7e19af20f93
+https://os.mbed.com/users/peterknoben/code/AnglePosition2/#5c789825341d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Movement.lib	Tue Oct 31 14:35:52 2017 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/peterknoben/code/Movement/#9c61094ffaac
--- a/SignalNumber.lib	Mon Oct 30 10:43:26 2017 +0000
+++ b/SignalNumber.lib	Tue Oct 31 14:35:52 2017 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/peterknoben/code/SignalNumber2/#5f8dee4d4b09
+https://os.mbed.com/users/peterknoben/code/SignalNumber2/#15543c143a63
--- a/main.cpp	Mon Oct 30 10:43:26 2017 +0000
+++ b/main.cpp	Tue Oct 31 14:35:52 2017 +0000
@@ -3,123 +3,157 @@
 #include "PIDControl.h"
 #include "BiQuad.h"
 #include "signalnumber.h"
+#include "Movement.h"
 #include "mbed.h"
 #include "encoder.h"
 #include "Servo.h"
 #include "FastPWM.h"
 
+//This code is for Mbed 2
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 MODSERIAL pc(USBTX, USBRX);         //Establish connection
 Ticker MyControllerTicker1;         //Declare Ticker Motor 1
 Ticker MyControllerTicker2;         //Declare Ticker Motor 2
-Ticker MySampleTicker;                //Declare Ticker HIDscope
+Ticker MySampleTicker;              //Declare Ticker HIDscope
 Ticker MyTickerMean;                //Declare Ticker Signalprocessing
 
-InterruptIn But2(PTC6);             //Declare button for calibration
+InterruptIn But2(PTA4);             //Declare button for min calibration
+InterruptIn But1(PTC6);             //Declare button for max calibration
 
 AnglePosition Angle;                //Declare Angle calculater
 PIDControl PID;                     //Declare PID Controller
-SignalNumber Signal;                //Declare Signal determiner
+SignalNumber SignalLeft;            //Declare Signal determiner for Left arm
+SignalNumber SignalRight;           //Declare Signal determiner for Right arm
+Movement MoveLeft;                  //Declare Movement determiner
+Movement MoveRight;
 
-AnalogIn potmeter1(A5);
-AnalogIn potmeter5(A3);             //Set Inputpin
-AnalogIn potmeter2(A4);             //Set Inputpin
-AnalogIn    emg0( A0 );             //Set Inputpin
-AnalogIn    emg1( A1 );             //Set Inputpin
-
+AnalogIn    emg0( A0 );             //Set Inputpin for EMG 0 signal Left 
+AnalogIn    emg1( A1 );             //Set Inputpin for EMG 1 signal Left
+AnalogIn    emg2( A2 );             //Set Inputpin for EMG 2 signal Right
+AnalogIn    emg3( A3 );             //Set Inputpin for EMG 3 signal Right        
+AnalogIn    emg4( A4 );             //Set Inputpin for EMG 4 signal Mode
+AnalogIn    emg5( A5 );             //Set Inputpin for EMG 5 signal Mode
+DigitalOut     M( D9 );             //Set digital in for mode selection
+DigitalOut  Led_red(LED_RED);          
+DigitalOut  Led_green(LED_GREEN);
+DigitalOut  Led_blue(LED_BLUE);  
 
 const float CONTROLLER_TS = 0.02;   //Motor frequency
-const float MEAN_TS = 0.1;          //Mean value frequency
-const float SAMPLE_TS = 0.02;        //BiQuad frequency
+const float MEAN_TS = 0.002;        //Filter frequency
+
+//Testing methods
+/*
+AnalogIn potmeter1(A5);
+AnalogIn potmeter5(A3);             //Set Inputpin for x axis
+AnalogIn potmeter2(A4);             //Set Inputpin for y axis
+*/
+
+//------------------------------------------------------------------------------
+//---------------------------Mode selection-------------------------------------
+//------------------------------------------------------------------------------
+// From the other Mbed there will be send a signal to determine in which mode the system is in
+int mode =0;
+
+//Recieving mode selection from Mbed 1
+void mode_selection(){
+    if(mode ==6){
+        mode=1;   
+    }
+    else{
+        mode++;
+    }
+    pc.printf("mode = %i\r\n", mode);
+}
+
 
 
 //------------------------------------------------------------------------------
 //-----------------------------EMG Signals--------------------------------------
 //------------------------------------------------------------------------------
-const int n = 10;                   //Window size for the mean value, also adjust in signalnumber.cpp
+// Filtering the signal and getting the usefull information out of it.
+const int n = 400;                  //Window size for the mean value, also adjust in signalnumber.cpp
 const int action =50;               //Number of same mean values to change the signalnumber
-const int m = 10;                   //Number of samples for calibration
-int mode;
-float emg_offset;
-float meanx;
+const int m = 300;                  //Number of samples for calibration
+int CaseLeft;                           //Strength of the muscles Left
+int CaseRight;                           //Strength of the muscles Right
+float emg_offsetLeft;                   //Calibtarion value to get zero
+float emg_offsetmaxLeft;                //Calibration value to scale to 1
+float emg_offsetRight;                   //Calibtarion value to get zero
+float emg_offsetmaxRight;                //Calibration value to scale to 1
+float meanxL;                        //Temporary variable for mean value
+float meanxR;
+float kLeft;                      //Scaling factor mean value
+float kRight;                      //Scaling factor mean value
 
-//BiQuad filter
+//BiQuad filter variables
 BiQuad LP1( 0.6389437261127493, 1.2778874522254986, 0.6389437261127493, 1.1429772843080919, 0.4127976201429053 ); //Lowpass filter Biquad
 BiQuad HP2( 0.8370879899975344, -1.6741759799950688, 0.8370879899975344, -1.6474576182593796, 0.7008943417307579 ); //Highpass filter Biquad
 BiQuad NO3( 0.7063988100714527, -1.1429772843080923, 0.7063988100714527, -1.1429772843080923,  0.41279762014290533); //Notch filter Biquad 
 BiQuadChain BiQuad_filter;
 
-// Calibration function
-void calibration(){
-    emg_offset = Signal.calibrate(m, potmeter5);
-    pc.printf("offset = %f \r\n", emg_offset);
+void setled(){
+    Led_red=0;
+    Led_green=1;
+    Led_blue=1;
 }
 
-/*
-//Sample function
-void sample()
-{
-    float Signal=((emg0+emg1)/2)-emg_offset;
-    float Signal_filtered= BiQuad_filter.step(Signal);
-    /* scope
-    scope.set(0, emg0.read() );
-    scope.set(1, emg1.read() );
-    scope.set(2, Signal_filtered);
-    scope.send();
-    led = !led;
-    /
+// Calibration function
+void mincalibration(){
+    pc.printf("start cali \r\n");
+    emg_offsetLeft = SignalLeft.calibrate(m,((emg0+emg1)/2));
+    emg_offsetRight = SignalRight.calibrate(m,((emg2+emg3)/2));
+//    pc.printf("calibrated, offset = %f \r\n", emg_offset);
+    Led_green=0;
+    Led_red=0;
 }
-*/
 
+void maxcalibration(){
+    pc.printf("start cali max\r\n");
+    emg_offsetmaxLeft = SignalLeft.calibrate(m,((emg0+emg1)/2))-emg_offsetLeft;
+    emg_offsetmaxRight = SignalRight.calibrate(m,((emg2+emg3)/2))-emg_offsetRight;
+    kLeft = 1/emg_offsetmaxLeft;
+    kRight = 1/emg_offsetmaxRight;
+//    pc.printf("calibrated, offset = %f scale = %f \r\n",emg_offsetmax, k);
+    Led_red=1;
+}
+
+//Filter de EMG signals with a BiQuad filter
 float Filter(float input0, float input1, float offset){
-    float Signal=((input0+input1)/2)-offset;
+    float Signal=input0-offset; //((input0+input1)/2)
     float Signal_filtered= BiQuad_filter.step(Signal);
     return Signal_filtered;
 }
 
+
+//Determine the signalnumbers (i.e. speed) based on the EMG signals
 void signalnumber(){
-    float Signal_filtered = Filter(emg0, emg1, emg_offset);
-    meanx = Signal.getmean(n, Signal_filtered);
-    mode = Signal.getnumber(n, action, Signal_filtered);
-    pc.printf("pot = %d  after filtering = %f   mean = %f  Signalnumber = %i \r\n" , potmeter5,  meanx, mode);
+    //Left
+    float Signal_filteredLeft = fabs(Filter(emg0, emg1, emg_offsetLeft));
+    meanxL = SignalLeft.getmean(n, Signal_filteredLeft)*kLeft;          //Testing variable
+    CaseLeft = SignalLeft.getnumber(n, action, Signal_filteredLeft, kLeft);
+    pc.printf("m %f C %i \r\n",meanxL, CaseLeft);                       //Testing print
+    //Right
+    float Signal_filteredRight = fabs(Filter(emg2, emg3, emg_offsetRight));
+    meanxR = SignalRight.getmean(n, Signal_filteredRight)*kRight;          //Testing variable
+    CaseRight = SignalRight.getnumber(n, action, Signal_filteredRight, kRight);
+    pc.printf("m %f C %i \r\n",meanxR, CaseRight);                       //Testing print
 }
 
-
 //------------------------------------------------------------------------------
 //-------------------------Kinematic Constants----------------------------------
 //------------------------------------------------------------------------------
-const double RAD_PER_PULSE = 0.00074799825*2;
-const double PI = 3.14159265358979323846;
-const float max_rangex = 500.0;
-const float max_rangey = 300.0;
-const float x_offset = 156.15;
-const float y_offset = -76.97;
-const float alpha_offset = -(21.52/180)*PI;
-const float beta_offset  = 0.0;
-const float L1 = 450.0;
-const float L2 = 490.0;
-
-
-//------------------------------------------------------------------------------
-//--------------------------------Servo-----------------------------------------
-//------------------------------------------------------------------------------
-// This will be programmed on a different Mbed
-Servo MyServo(D9);                  //Declare button
-InterruptIn But1(D8);               //Declare used button
-int k=0;                            //Position flag
-
-void servo_control (){
-    if (k==0){
-        MyServo = 0;
-        k=1;
-    }
-    else{
-        MyServo = 2;
-        k=0;
-    }
-}
+const double RAD_PER_PULSE = 0.00074799825*2;       //Number of radials per pulse from the encoder
+const double PI = 3.14159265358979323846;           //Pi
+const float max_rangex = 500.0;                     //Max range on the x axis
+const float max_rangey = 300.0;                     //Max range on the y axis
+const float x_offset = 156.15;                      //Start x position from the shoulder joint
+const float y_offset = -76.97;                      //Start y position from the shoulder joint
+const float alpha_offset = -(21.52/180)*PI;         //Begin angle Alpha at zero zero
+const float beta_offset  = 0.0;                     //Begin angle Beta at zero zero
+const float L1 = 450.0;                             //Length of the first body
+const float L2 = 490.0;                             //Length of the second body
 
 
 //------------------------------------------------------------------------------
@@ -140,13 +174,14 @@
 
 
 void motor1_control(){
-    float reference_alpha = Angle.getbeta(max_rangex, max_rangey, x_offset, y_offset, beta_offset, L1, L2, potmeter1, potmeter2);
+    float *position_math;
+    position_math[0]= MoveLeft.getposition(CaseLeft, mode, 0, max_rangex);
+    position_math[1]= MoveRight.getposition(CaseRight, mode, 1, max_rangey);
+    float reference_alpha = Angle.getbeta(max_rangex, max_rangey, x_offset, y_offset, beta_offset, L1, L2, position_math[0], position_math[1]);
     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;
     motor1 = fabs(magnitude1);
-//    pc.printf("err_a = %f  alpha = %f   mag1 = %f\r\n", error_alpha, reference_alpha, magnitude1);
-//    pc.printf("\r\n");
     // Determine Motor Direction 
     if (magnitude1  < 0){
         motor1DirectionPin = 1;
@@ -175,13 +210,14 @@
 
 
 void motor2_control(){
-    float reference_beta = Angle.getalpha(max_rangex, max_rangey, x_offset, y_offset, alpha_offset, L1, L2, potmeter1, potmeter2);
+    float *position_math;
+    position_math[0]= MoveLeft.getposition(CaseLeft, mode, 0, max_rangex);
+    position_math[1]= MoveRight.getposition(CaseRight, mode, 1, max_rangey);
+    float reference_beta = Angle.getalpha(max_rangex, max_rangey, x_offset, y_offset, alpha_offset, L1, L2, position_math[0], position_math[1]);
     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;
     motor2 = fabs(magnitude2);
-//    pc.printf("err2 = %f  beta = %f   mag2 = %f\r\n", error_beta, reference_beta, magnitude2);
-//    pc.printf("\r\n");
     //Determine Motor Direction
     if (magnitude2 > 0){
         motor2DirectionPin = 1;
@@ -196,15 +232,17 @@
 
 int main(){
     pc.baud(115200);
+    setled(); 
     BiQuad_filter.add( &LP1 ).add( &HP2 ).add( &NO3);
+    But2.rise(&mincalibration);
+    But1.rise(&maxcalibration);
+//    M.rise(&mode_selection);
     motor1.period(0.0001f);
     motor2.period(0.0001f);
     MyControllerTicker1.attach(&motor1_control, CONTROLLER_TS); 
     MyControllerTicker2.attach(&motor2_control, CONTROLLER_TS);
     MyTickerMean.attach(&signalnumber, MEAN_TS);
-//  MySampleTicker.attach(&sample, SAMPLE_TS);
-    But1.rise(&servo_control);      
-    But2.rise(&calibration);
+
     while(1) {}   
 }