2014-10-15 Arm 1 naar thuispositie. Eerste poging, fout in keep_in_range

Dependencies:   Encoder MODSERIAL TextLCD mbed mbed-dsp

Revision:
13:54ee98850a15
Parent:
12:996f9f8e3acc
Child:
14:e1816efa712d
--- a/main.cpp	Thu Oct 23 11:46:37 2014 +0000
+++ b/main.cpp	Fri Oct 24 11:06:15 2014 +0000
@@ -5,11 +5,48 @@
 
 //Constanten definiëren en waarde geven
 #define SAMPLETIME_REGELAAR         0.005       //Sampletijd ticker regelaar motor
-#define KP                          0.001       //Factor proprotionele regelaar
+#define KP_arm1                     0.3       //Factor proprotionele regelaar arm 1
+#define KI_arm1                     0         //Factor integraal regelaar arm 1
+#define KD_arm1                     0.02        //Factor afgeleide regelaar arm 1
+#define KP_arm2                     0.001       //Factor proprotionele regelaar arm 2
+#define KI_arm2                     0           //Factor integraal regelaar arm 2
+#define KD_arm2                     0           //Factor afgeleide regelaar arm 2
 #define SAMPLETIME_EMG              0.005       //Sampletijd ticker EMG meten
 #define PULS_ARM1_HOME_KALIBRATIE   180         //Aantal pulsen die de encoder moet tellen voordat de arm de goede positie heeft
 #define PULS_ARM2_HOME_KALIBRATIE   393         //Aantal pulsen die de encoder moet tellen voordat de arm de goede positie heeft
 
+//High Pass filter          Filtercoëfficiënten
+#define A1 1                    
+#define A2 -3.1806
+#define A3 3.8612
+#define A4 -2.1122
+#define A5 0.4383
+#define B1 4.1660E-4
+#define B2 0.0017
+#define B3 0.0025
+#define B4 0.0017
+#define B5 4.1660E-4
+
+//Notch filter          Filtercoëfficiënten
+#define C1 1
+#define C2 -1.1873E-16
+#define C3 0.9391
+#define D1 0.9695
+#define D2 -1.1873E-16
+#define D3 0.9695
+
+//Low pass filter           Filtercoëfficiënten
+#define E1 1
+#define E2 3.9179
+#define E3 5.7571
+#define E4 3.7603
+#define E5 0.9212
+#define F1 0.9598
+#define F2 3.8391
+#define F3 5.7587
+#define F4 3.8391
+#define F5 0.9598
+
 //Pinverdeling en naamgeving variabelen
 TextLCD         lcd(PTD2, PTB8, PTB9, PTB10, PTB11, PTE2);      //LCD scherm
 MODSERIAL       pc(USBTX, USBRX);                               //PC
@@ -27,7 +64,7 @@
 Ticker ticker_EMG;                      //Ticker voor EMG meten
 
 //States definiëren
-enum pipostate {RUST, KALIBRATIE_ARM1, KALIBRATIE_ARM2, KALIBRATIE_BICEPS, KALIBRATIE_TRICEPS};     //Alle states benoemen, ieder krijgt een getal beginnend met 0
+enum pipostate {RUST, KALIBRATIE_ARM1, KALIBRATIE_ARM2, EMG_OFFSET_BICEPS, EMG_BICEPS, KALIBRATIE_BICEPS, EMG_OFFSET_TRICEPS, EMG_TRICEPS, KALIBRATIE_TRICEPS};     //Alle states benoemen, ieder krijgt een getal beginnend met 0
 uint8_t state = RUST;                   //State is rust aan het begin
 
 //Gedefinieerde datatypen en naamgeving en beginwaarden
@@ -36,8 +73,72 @@
 
 float pwm_to_motor_arm1;                //PWM output naar motor arm 1
 float pwm_to_motor_arm2;                //PWM output naar motor arm 2
-float xbk;                              //Gemeten EMG waarde biceps in de kalibratie
-int i;                                  //Voor for-loop
+float error_arm1_kalibratie;            //Error in pulsen arm 1
+float vorige_error_arm1 = 0;            //Derivative actie van regelaar arm 1
+float integraal_arm1 = 0;               //Integraal actie van regelaar arm 1
+float afgeleide_arm1;                   //Afgeleide actie van regelaar arm 1
+float error_arm2_kalibratie;            //Error in pulsen arm 2
+float vorige_error_arm2 = 0;            //Derivative actie van regelaar arm 2
+float integraal_arm2 = 0;               //Integraal actie van regelaar arm 2
+float afgeleide_arm2;                   //Afgeleide actie van regelaar arm 2
+float xbk = 0;                          //Gemeten EMG waarde biceps in de kalibratie
+float xbk1 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk2 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk3 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk4 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk5 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk6 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk7 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk8 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk9 = 0;                         //Gemeten EMG waarde biceps in de kalibratie
+float xbk10 = 0;                        //Gemeten EMG waarde biceps in de kalibratie
+float meanxbk;                          //Offset van biceps kalibratie
+float xb;                               //Gemeten EMG waarde biceps
+float xbo;                              //Gemeten EMG waarde biceps min de offset, deze gaat in de filters
+
+//High Pass filter          Y(n-x) waarden instellen op nul en definiëren als float
+float xbhp;                             //Zelfde als xbo, maar makkelijker in notatie in filter
+float xbhp1 = 0;
+float xbhp2 = 0;
+float xbhp3 = 0;
+float xbhp4 = 0;
+float xbhp5 = 0;
+float ybhp;
+float ybhp1 = 0;
+float ybhp2 = 0;
+float ybhp3 = 0;
+float ybhp4 = 0;
+float ybhp5 = 0;
+
+//Notch filter
+float xbn;
+float xbn1 = 0;
+float xbn2 = 0;
+float ybn;
+float ybn1 = 0;
+float ybn2 = 0;
+
+//Rectifier
+float rb;
+float rbr;
+
+//Low pass filter
+float xblp;
+float xblp1 = 0;
+float xblp2 = 0;
+float xblp3 = 0;
+float xblp4 = 0;
+float xblp5 = 0;
+float yblp;
+float yblp1 = 0;
+float yblp2 = 0;
+float yblp3 = 0;
+float yblp4 = 0;
+float yblp5 = 0;
+
+//Gefilterde biceps EMG
+float xbf;
+float ybf;
 
 volatile bool regelaar_ticker_flag;     //Definiëren flag als bool die verandert kan worden in programma
 void setregelaar_ticker_flag()          //Setregelaar_ticker_flag zet de regelaar_ticker_flag op true
@@ -65,7 +166,10 @@
 
 void arm1_naar_thuispositie()
 {
-    pwm_to_motor_arm1 = (PULS_ARM1_HOME_KALIBRATIE - puls_motor_arm1.getPosition())*KP;        //PWM naar motor is het verschil tussen het voorgestelde aantal pulsen en de huidige positie maal een factor
+    error_arm1_kalibratie = (PULS_ARM1_HOME_KALIBRATIE - puls_motor_arm1.getPosition());        //PWM naar motor is het verschil tussen het voorgestelde aantal pulsen en de huidige positie maal een factor
+    integraal_arm1 = integraal_arm1 + error_arm1_kalibratie*SAMPLETIME_REGELAAR;              //Integraal deel van regelaar
+    afgeleide_arm1 = (error_arm1_kalibratie - vorige_error_arm1)/SAMPLETIME_REGELAAR;         //Afgeleide deel van regelaar
+    pwm_to_motor_arm1 = error_arm1_kalibratie*KP_arm1 + integraal_arm1*KI_arm1 + afgeleide_arm1*KD_arm1;      //Output naar motor na PID regelaar
     keep_in_range(&pwm_to_motor_arm1, -1, 1);                                       //PWM moet tussen 1 en -1 blijven (niet meer dan 100% dutycycle)
 
     if (pwm_to_motor_arm1 > 0) {                        //Als PWM is positief, dan richting 1
@@ -79,13 +183,16 @@
 
     if (pwm_to_motor_arm1 == 0) {                       //Als het verschil tussen de voorgestelde en huidige positie nul is wordt de while loop gestopt (condities kloppen niet meer)
         state = KALIBRATIE_ARM2;                        //State wordt kalibratie arm 2, zo daar naar volgende onderdeel
-        pc.printf("KALIBRATIE_ARM1 afgerond");          //Tekst voor controle Arm 1 naar thuispositie
+        pc.printf("KALIBRATIE_ARM1 afgerond\n");          //Tekst voor controle Arm 1 naar thuispositie
     }
 }
 
 void arm2_naar_thuispositie()
 {
-    pwm_to_motor_arm2 = (PULS_ARM2_HOME_KALIBRATIE - puls_motor_arm2.getPosition())*KP;        //PWM naar motor is het verschil tussen het voorgestelde aantal pulsen en de huidige positie maal een factor
+    error_arm2_kalibratie = (PULS_ARM2_HOME_KALIBRATIE - puls_motor_arm2.getPosition());        //PWM naar motor is het verschil tussen het voorgestelde aantal pulsen en de huidige positie maal een factor
+    integraal_arm2 = integraal_arm2 + error_arm2_kalibratie*SAMPLETIME_REGELAAR;              //Integraal deel van regelaar
+    afgeleide_arm2 = (error_arm2_kalibratie - vorige_error_arm2)/SAMPLETIME_REGELAAR;         //Afgeleide deel van regelaar
+    pwm_to_motor_arm2 = error_arm2_kalibratie*KP_arm2 + integraal_arm2*KI_arm2 + afgeleide_arm2*KD_arm2;      //Output naar motor na PID regelaar
     keep_in_range(&pwm_to_motor_arm2, -1, 1);                                       //PWM moet tussen 1 en -1 blijven (niet meer dan 100% dutycycle)
 
     if (pwm_to_motor_arm2 > 0) {                        //Als PWM is positief, dan richting 1
@@ -94,13 +201,67 @@
         dir_motor_arm2.write(0);
     }
     pwm_motor_arm2.write(fabs(pwm_to_motor_arm2));      //Output PWM naar motor is de absolute waarde van de berekende PWM
+    pc.printf("pulsmotorgetposition %d ", puls_motor_arm2.getPosition());
+    pc.printf("pwmmotor %f\n\r", pwm_to_motor_arm2);
 
     if (pwm_to_motor_arm2 == 0) {                       //Als het verschil tussen de voorgestelde en huidige positie nul is wordt de while loop gestopt (condities kloppen niet meer)
-        state = KALIBRATIE_BICEPS;                      //State wordt kalibratie arm 2, zo daar naar volgende onderdeel
-        pc.printf("KALIBRATIE_ARM2 afgerond");          //Tekst voor controle Arm 2 naar thuispositie
+        state = EMG_OFFSET_BICEPS;                      //State wordt kalibratie arm 2, zo daar naar volgende onderdeel
+        pc.printf("KALIBRATIE_ARM2 afgerond\n");          //Tekst voor controle Arm 2 naar thuispositie
     }
 }
 
+void filter_biceps()
+{
+    //High pass
+    xbhp = xbo;             //Input in filter
+    ybhp = -A2*ybhp1 - A3*ybhp2 - A4*ybhp3 - A5*ybhp4 + B1*xbhp + B2*xbhp1 + B3*xbhp2 + B4*xbhp3 + B5*xbhp4;        //Filterformule in z-domein
+    
+    //Waarden voor de volgende ronde benoemen
+    xbhp4 = xbhp3;
+    xbhp3 = xbhp2;
+    xbhp2 = xbhp1;
+    xbhp1 = xbhp;
+    xbn = xbhp;
+ 
+    ybhp4 = ybhp3;
+    ybhp3 = ybhp2;
+    ybhp2 = ybhp1;
+    ybhp1 = ybhp;
+    ybn1 = ybhp;        //De vorige waarde in het notchfilter is de waarde uit het high pass filter
+    
+    //Notch
+    ybn = -C2*ybn1 - C3*ybn2 + D1*xbn + D2*xbn1 + D3*xbn2;              //Filterfunctie in z-domein
+    
+    //Waarden voor de volgende ronde benoemen
+    xbn2 = xbn1;
+    xbn1 = xbn;
+    xblp = xbn;
+    
+    ybn2 = ybn1;
+    ybn1 = ybn;
+    rb = ybn;
+    
+    //Rectify
+    rbr = fabs(rb);             //Absolute waarde van de waarde uit notchfilter
+    
+    yblp1 = rbr;
+    
+    //Low pass
+    yblp = -E2*yblp1 - E3*yblp2 - E4*yblp3 - E5*yblp4 + F1*xblp + F2*xblp1 + F3*xblp2 + F4*xblp3 + F5*xblp4;        //Filterfunctie in z-domein
+    
+    xblp4 = xblp3;
+    xblp3 = xblp2;
+    xblp2 = xblp1;
+    xblp1 = xblp;
+    xbf = xblp;
+ 
+    yblp4 = yblp3;
+    yblp3 = yblp2;
+    yblp2 = yblp1;
+    yblp1 = yblp;
+    ybf = yblp;    
+}
+
 
 int main()
 {
@@ -114,13 +275,13 @@
                 lcd_r1 = " BMT M9   GR. 4 ";        //Tekst op eerste regel van LCD scherm
                 lcd_r2 = "Hoi! Ik ben PIPO";        //Tekst op tweede regel van LCD scherm
                 wait(2);                            //Twee seconden wachten
-                pc.printf("RUST afgerond");         //Tekst voor controle Aanzetten
+                pc.printf("RUST afgerond\n");         //Tekst voor controle Aanzetten
                 state = KALIBRATIE_ARM1;            //State wordt kalibratie arm 1, zo door naar volgende onderdeel
                 break;                              //Stopt acties in deze case
             }
 
             case KALIBRATIE_ARM1: {                 //Arm 1 naar thuispositie
-                pc.printf("kalibratie-arm1");
+                pc.printf("KALIBRATIE_ARM1\n");
                 wait(1);                            //Een seconde wachten
                 ticker_regelaar.attach(setregelaar_ticker_flag,SAMPLETIME_REGELAAR);       //Ticker iedere zoveel seconde de flag op laten steken
 
@@ -135,6 +296,7 @@
             }
 
             case KALIBRATIE_ARM2: {                 //Arm 2 naar thuispositie
+                pc.printf("KALIBRATIE_ARM1\n");
                 wait(1);                            //Een seconde wachten
 
                 //ticker_regelaar.attach(setregelaar_ticker_flag,SAMPLETIME_REGELAAR);       //Ticker iedere zoveel seconde de flag op laten steken
@@ -150,12 +312,13 @@
                 break;                              //Stopt acties in deze case
             }
 
-            case KALIBRATIE_BICEPS: {               //Kalibratie EMG signaal biceps
+            case EMG_OFFSET_BICEPS: {               //Kalibratie EMG signaal biceps
+                pc.printf("EMG_OFFSET_BICEPS\n");
                 wait(1);                            //Een seconde wachten
 
                 ticker_EMG.attach(setregelaar_EMG_flag,SAMPLETIME_EMG);     //Ticker iedere zoveel seconden de flag laten opsteken
 
-                pc.printf("Ticker voor kalibratie compleet");               //Tekst voor controle Ticker voor kalibratie
+                pc.printf("Ticker voor kalibratie compleet\n");               //Tekst voor controle Ticker voor kalibratie
 
                 //5 seconden EMG biceps meten
 
@@ -163,15 +326,48 @@
                 lcd_r1 = " EMG kalibratie ";        //Tekst op eerste regel van LCD scherm
                 lcd_r2 = " Span biceps aan";        //Tekst op tweede regel van LCD scherm
 
-                for (i=0; i<1000; i++) {
+                while(state == EMG_OFFSET_BICEPS){
                     while(regelaar_EMG_flag != true) ;              //Als geen flag opgestoken, dan niks doen, wel flag, dan uit de while loop en door naar volgende regel
                     regelaar_EMG_flag = false;                      //Flag weer naar beneden, zodat deze straks weer omhoog kan
+                    
+                    pc.printf("Ga EMG meten\n");
 
                     xbk = EMG_bi.read();            //EMG signaal uitlezen
+                    xbk10 = xbk9;
+                    xbk9 = xbk8;
+                    xbk8 = xbk7;
+                    xbk7 = xbk6;
+                    xbk6 = xbk5;
+                    xbk5 = xbk4;
+                    xbk4 = xbk3;
+                    xbk3 = xbk2;
+                    xbk2 = xbk1;
+                    xbk1 = xbk;
+                    pc.printf("xbk10 is %f\n", xbk10);
+                    
+                    if(xbk10 > 0){
+                        pc.printf("10 waarden gemeten\n");
+                        state = EMG_BICEPS;
+                    }  
                 }
                 break;
+            }
+            
+            case EMG_BICEPS:
+            {
+                pc.printf("EMG_BICEPS\n");
+                meanxbk = (xbk1 + xbk2 + xbk3 + xbk4 + xbk5 + xbk6 + xbk7 + xbk8 + xbk9 + xbk10)/10;        //Offset bepalen van de eerste 10 gemeten waarden
+                
+                while(regelaar_EMG_flag != true) ;              //Als geen flag opgestoken, dan niks doen, wel flag, dan uit de while loop en door naar volgende regel
+                regelaar_EMG_flag = false;                      //Flag weer naar beneden, zodat deze straks weer omhoog kan 
+                
+                xb = EMG_bi.read();         //EMG meten van biceps
+                xbo = xb - meanxbk;         //Gemeten waarden zonder offset
+                
+                filter_biceps();
 
             }
+            
             default: {                              //Default state, mocht er iets misgaan en het programma kan niet naar een volgende case
                 state = RUST;                       //Als dat gebeurt wordt de state rust en begint hij weer vooraan
             }