Project of Biorobotics

Dependencies:   HIDScope MODSERIAL QEI mbed biquadFilter

Fork of TutorialPES by Jurriën Bos

Revision:
9:355dd95199c3
Parent:
8:e8734a254818
Child:
10:05ad15c48388
diff -r e8734a254818 -r 355dd95199c3 main.cpp
--- a/main.cpp	Mon Oct 29 14:02:21 2018 +0000
+++ b/main.cpp	Tue Oct 30 13:57:00 2018 +0000
@@ -11,13 +11,16 @@
 DigitalIn Knop1(D2);
 DigitalIn Knop2(D3);
 DigitalIn Knop3(PTA4);
+DigitalIn Knop4(PTC6);
 AnalogIn pot1 (A5);
 AnalogIn pot2 (A4);
 AnalogIn emg0( A0 );
 AnalogIn emg1( A1 );
 AnalogIn emg2( A2 );
 AnalogIn emg3( A3 );
-DigitalOut led(LED_GREEN);
+DigitalOut led_G(LED_GREEN);
+DigitalOut led_R(LED_RED);
+DigitalOut led_B(LED_BLUE);
 
 QEI Encoder1(D12,D13,NC,64,QEI::X4_ENCODING);
 QEI Encoder2(D10,D11,NC,64,QEI::X4_ENCODING);
@@ -32,13 +35,17 @@
 volatile float Tricep_Right         = 0.0;
 volatile float Tricep_Left          = 0.0;
 
-volatile const float maxVelocity    = 8.4; // in rad/s
 volatile const float pi             = 3.1415926; 
-volatile const float rad_count      = 0.0007479; // 2pi/8400;
+volatile const float rad_count      = 0.0007479;                                // 2pi/8400;
+volatile const float maxVelocity    = 2.0f * pi;                                // in rad/s
 
-volatile float referenceVelocity1   = 0.5; //dit is de gecentreerde waarde en dus de nulstand
+volatile float referenceVelocity1   = 0.5;                                      // dit is de gecentreerde waarde en dus de nulstand
 volatile float referenceVelocity2   = 0.5;
 
+volatile int i   = 0;                                                           // Led blink status
+volatile int ii  = 0;                                                           // Calibratie timer
+volatile int iii = 0;                                                           // Start up timer
+
 volatile float q_1;
 volatile float q_2;
 volatile float r_1;
@@ -51,12 +58,17 @@
 volatile float Flex_Bi_L;
 volatile float Flex_Tri_R;
 volatile float Flex_Tri_L;
-
+volatile float Threshold_Bi_R;
+volatile float Threshold_Bi_L;
+volatile float Threshold_Tri_R;
+volatile float Threshold_Tri_L;
 
 enum states{Starting, Calibration, Homing, Function};
     
 volatile states Active_State = Starting;
 
+volatile float vx;
+volatile float vy;
 volatile int counts1 ;
 volatile int counts2 ;
 volatile float rad_m1;
@@ -72,6 +84,53 @@
     rad_m2 = rad_count * (float)counts2;
 }
 
+void BlinkLed()
+{
+    if(i==1)
+    {
+            static int rr = 0;
+            rr++;
+            if (rr == 1)
+            {
+                led_R = !led_R;
+            }
+            else if (rr == 100)
+            {
+                rr = 0;
+            }
+    }     
+    else if(i==2)
+    {        
+            static int gg = 0;
+            gg++;
+            if (gg == 1)
+            {
+                led_G = !led_G;
+            }
+            else if (gg == 100)
+            { 
+                gg = 0;
+            }
+    }
+    else if (i==3)
+    {            
+            static int bb = 0;
+            bb++;
+            if (bb == 1)
+            {
+                led_B = !led_B;
+            }
+            else if (bb == 100)
+            {
+                bb = 0;
+            }
+    }
+    else 
+    {
+        led_R=led_G=led_B=1;
+    }  
+}
+
 void EMG_Read()
 {
     Bicep_Right     =   emg0.read();
@@ -93,8 +152,8 @@
 
 void Inverse()
 {
-    q_1= rad_m1;                                          // uit Encoder
-    q_2= rad_m2+(pi/2.0f);                                          // uit Encoder
+    q_1= rad_m1;                                                                // uit Encoder
+    q_2= rad_m2+(pi/2.0f);                                                      // uit Encoder
     r_1= -0.2f;
     r_2= -0.2f;
     
@@ -102,26 +161,26 @@
         float z = 2.0f*(r_2*cos(q_1)*cos(q_2))-r_3;
         float y = r_2*cos(q_1)*cos(q_2)-r_2*sin(q_1)*sin(q_2)+2.0f*(r_1*cos(q_1))-r_3;
         float x = (-2.0f)*r_2*sin(q_1)*cos(q_2);
-        float D = 1.0f/(u*z-x*y);                         // Determinant
-        printf("Determinant is %f\n", D);
+        float D = 1.0f/(u*z-x*y);                                               // Determinant
+        printf("Determinant is %f\r\n", D);
         
-        float a = D*z;                                  // Inverse jacobian a,b,c,d vormen 2 bij 2 matrix
-        float b = -D*x;                                 // Inverse jacobian
-        float c = -D*y;                                 // Inverse jacobian
-        float d = D*u;                                  // Inverse jacobian
+        float a = D*z;                                                          // Inverse jacobian a,b,c,d vormen 2 bij 2 matrix
+        float b = -D*x;                                                         // Inverse jacobian
+        float c = -D*y;                                                         // Inverse jacobian
+        float d = D*u;                                                          // Inverse jacobian
         
-        float vx = 0.01f;                                // uit emg data
-        float vy = 0.0f;                                 // uit emg data
+        float vx = pot1.read();//0.01f;                                                       // uit emg data
+        float vy = pot2.read();//0.0f;                                                        // uit emg data
         
         w_1 = vx*a+vy*b;
         w_2 = vx*c+vy*d;
         
         /*
-        printf("%f\n", w_1);
-        printf("%f\n", w_2);
+        printf("%f\r\n", w_1);
+        printf("%f\r\n", w_2);
         */     
 }
-   
+/*   
 void velocity1()
     {
             if (pot1.read()>0.5f)
@@ -161,7 +220,7 @@
                 referenceVelocity2 = 2.0f * (pot2.read()-0.5f) ;
                 }
     }    
-    
+*/    
 void motor1()
     {          
         float u_v1 = w_1; //referenceVelocity1       
@@ -177,60 +236,128 @@
         DirectionPin2 = u > 0.0f;
         PwmPin2 = fabs(u);
     }
-    
+   
 void Calibrating()
 {
     static float n = 0.0;
     static float m = 0.0;
     static float l = 0.0;
     static float k = 0.0;
- 
-    for(int ii=0; ii<=20000; ii++)
-    {
-            if (ii <2500)
+    
+    //static int ii; 
+    ii++;
+    
+            if (ii<=2500)
             {
-                n = n + emg0.read();
+                if (ii == 0)
+                {
+                    pc.printf("Relax your muscles please. \r\n");
+                }
+                else if (ii == 2250)
+                {
+                    pc.printf("Flex your right bicep now please.\r\n");
+                }
+                //chillen
             }
-            else if (ii == 2500)
+            else if (ii>2500 && ii<5000) //
+            {
+                n = n + emg0.read();// dit wordt de variable naam na het filter
+            }
+            else if (ii == 5000)
             {
                 Flex_Bi_R = n / 2500.0f;
+                pc.printf("You can relax your right bicep, thank you. \r\nYour mean flexing value was %f\r\n\r\n", Flex_Bi_R);
             }
-            else if (ii>2500 && ii<=3500)
+            else if (ii>5000 && ii<=6000)
             {
+                if (ii == 5750)
+                {
+                    pc.printf("Flex your left bicep now please. \r\n");
+                }
                 //chillen
             }
-            else if(ii>3500 && ii<6000)
+            else if(ii>6000 && ii<8500)
             {
                 m = m + emg1.read();
             }
-            else if (ii == 6000)
+            else if (ii == 8500)
             {
                 Flex_Bi_L = m / 2500.0f;
+                pc.printf("You can relax your left bicep, thank you. \r\nYour mean flexing value was %f\r\n\r\n", Flex_Bi_L);
             }
-            else if (ii>6000 && ii<=7000)
+            else if (ii>8500 && ii<=9500)
             {
+                if (ii == 9250)
+                {
+                    pc.printf("Flex your right tricep now please. \r\n");
+                }
                 //chillen
             }
-            else if (ii>7000 && ii<9500)
+            else if (ii>9500 && ii<12000)
             {
                 l = l + emg2.read();
             }
-            else if (ii == 9500)
+            else if (ii == 12000)
             {
                 Flex_Tri_R = l / 2500.0f;
+                pc.printf("You can relax your right tricep, thank you. \r\nYour mean flexing value was %f\r\n\r\n", Flex_Tri_R);
             }
-            else if (ii>9500 && ii <=10500)
+            else if (ii>12000 && ii <=13000)
             {
+                if (ii == 12750)
+                {
+                    pc.printf("Flex your left tricep now please. \r\n");
+                }
                 //chillen
             }
-            else if (ii>10500 && ii<13000)
+            else if (ii>13000 && ii<15500)
             {
                 k = k + emg3.read();
             }
-            else if (ii == 13000)
+            else if (ii == 15500)
             {
                 Flex_Tri_L = k / 2500.0f;
-            }          
+                pc.printf("You can relax your left tricep, thank you. \r\nYour mean flexing value was %f\r\n\r\nThe calibration has been completed, the system is now operatable. \r\n",Flex_Tri_L);
+            }
+            
+Threshold_Bi_R  = 0.75f * Flex_Bi_R;
+Threshold_Bi_L  = 0.75f * Flex_Bi_L;
+Threshold_Tri_R = 0.75f * Flex_Tri_R;
+Threshold_Tri_L = 0.75f * Flex_Tri_L;                  
+
+            if (ii == 16500)
+            {
+                pc.printf("\r\nThreshold value right bicep  = %f\r\nThreshold value left bicep   = %f\r\nThreshold value right tricep = %f\r\nThreshold value left tricep  = %f\r\n\r\n",Threshold_Bi_R,Threshold_Bi_L,Threshold_Tri_R,Threshold_Tri_L);
+            }
+            else if (ii == 20000)
+            {
+                pc.printf("\r\nAutomatic switch to Homing State\r\n");
+                Active_State = Homing;
+            }
+}
+
+void Start_Up()
+{
+    i++;
+    iii++;
+    if (iii == 1)
+    {
+        pc.printf("System is starting...\r\nWaiting for further input...\r\n");
+    }
+    
+    else if (iii == 30000)
+    {
+        pc.printf("1 minute without input..\r\nReseting start-up...\r\n");
+        iii = 0;
+    }    
+    else if (iii == 40001)                                                      // sleeping state is only added for designing purposes and will most likely never be used
+    {                                                                           // when working with patients. Furthermore it cannot be reached automaticly
+        pc.printf("Sleeping... Press button 4 to wake me up!\r\n\r\n");
+        iii++;
+    }
+    else if (iii == 45000)
+    {
+        iii = 40000;
     }
 }
 
@@ -239,12 +366,58 @@
     PwmPin1 = PwmPin2 = 0;
 }
 
+void Going_Home()
+{
+    //Here we will reset the position of the arm back to the home state
+    
+    if (counts1 == 0)                                                           // this 0 is a filler value and can later be determined to the angle of the 
+    {                                                                           // 0-state of the arm
+        PwmPin1=0.0f;
+    }
+    else if (counts1 > 0)
+    {
+        DirectionPin1 = true;                                                   //uitzoeken of dit klopt, is afhankelijk welke richting opgedraaid moet worden..
+        PwmPin1 = 0.6f;
+    }
+    else if (counts1 < 0)
+    {
+        DirectionPin1 = false;
+        PwmPin1 = 0.6f;
+    }
+    
+    if (counts2 == 0)                                                           //Homing for M1 naar begin staat
+    {
+        PwmPin2=0.0f;
+    }
+    else if (counts2 > 0)
+    {
+        DirectionPin2 = true;                                                   //uitzoeken of dit klopt, is afhankelijk welke richting opgedraaid moet worden..
+        PwmPin2 = 0.6f;
+    }
+    else if (counts2 < 0)
+    {
+        DirectionPin2 = false;
+        PwmPin2 = 0.6f;
+    } 
+    
+    if (counts1 == 0 && counts2 == 0)
+    {
+        pc.printf("Homing is completed\r\nAutomatic switch to the Functioning State\r\n");
+        Active_State = Function;
+    }
+}
+
 void Printing()
 {
     float v1 = PwmPin1 * maxVelocity;
     float v2 = PwmPin2 * maxVelocity;
-
-    pc.printf("q1 = %f [rad] \n q2 = %f [rad] \n q1dot = %f [rad/s] \n q2dot = %f [rad/s] \n\n\n\n\n", rad_m1, rad_m2, v1, v2);
+    
+        if (Active_State == Function)
+        {
+            pc.printf("q1    = %f [rad] \r\nq2    = %f [rad] \r\nq1dot = %f [rad/s] \r\nq2dot = %f [rad/s] \r\n\r\n\r\n\r\n\r\n", rad_m1, rad_m2, v1, v2);
+        }
+        
+    pc.printf("%f %f",vx, vy);
 }
 
 void StateMachine() 
@@ -253,21 +426,20 @@
     {
         case Starting:   
         OFF();            
-            for (int i = 0; i<=20; i++)
-            {
-                led = !led;
-                wait(0.05);
-                
-                if (i == 0)
-                {
-                    pc.printf("Starting up..\n");
-                }    
-                else if (i == 20)
-                {    
-                    Active_State = Calibration;
-                    pc.printf("Entering Calibration state \n");
-                }
-            }                           
+        Start_Up();
+        BlinkLed();
+        
+        if (!Knop4 == true)
+        {
+            Active_State = Calibration;
+            pc.printf("Entering Calibration State \r\n");
+        }
+        else if (!Knop3 == true)
+        {
+            Active_State = Homing;
+            pc.printf("Entering Homing State \r\n");
+        }
+                                   
         break;
         
         case Calibration:
@@ -276,11 +448,20 @@
                 
                 Calibrating();
                 OFF();
-                if (Knop1==false)
+                
+                if (!Knop1 && !Knop2)
                 {
-                    pc.printf("Entering Homing state \n");
+                    pc.printf("Switched to Sleeping State\r\n");
+                    Active_State = Starting;
+                    iii = 40001;
+                }
+                else if (Knop1==false)
+                {
+                    pc.printf("Manual switch to Homing state \r\n");
                     Active_State = Homing;
                 }
+
+                    
                 
                 sample();
                 EMG_Read();
@@ -290,11 +471,25 @@
         case Homing:
                 //Homing actions
                 //pc.printf("Homing State");
-                if (Knop2==false)
+                Going_Home();
+                
+                if (!Knop1 && !Knop2)
                 {
-                    pc.printf("Entering Funtioning State \n");
+                    pc.printf("Switched to Sleeping State\r\n");
+                    Active_State = Starting;
+                    iii = 40000;
+                }
+                else if (Knop2==false)
+                {
+                    pc.printf("Manual switch to Funtioning State \r\n");
                     Active_State = Function;
                 }
+                else if (Knop3==false)
+                {
+                    Active_State = Calibration;
+                    pc.printf("Re-entering Calibration State \r\n");
+                }
+                
                 
                 sample();
                 EMG_Read();
@@ -304,17 +499,29 @@
         case Function:
             //pc.printf("Funtioning State");
                 
-                if (Knop3==false)
+                if (Knop4==false)
                 { 
-                    pc.printf("Re-entering Calibration State \n");
+                    pc.printf("Re-entering Calibration State \r\n");
                     Active_State = Calibration;
+                    ii=0;
+                }
+                else if (Knop3==false)
+                {
+                    pc.printf("Re-entering Homing State \r\n");
+                    Active_State = Homing;
+                }
+                else if (!Knop1 && !Knop2)
+                {
+                    pc.printf("Switched to Sleeping State\r\n");
+                    Active_State = Starting;
+                    iii = 40000;
                 }
                
                 sample();
                 EMG_Read();
                 Encoding();
-                velocity1();
-                velocity2();
+                //velocity1();
+                //velocity2();
                 motor1();
                 motor2();                
         break;