Dependencies:   mbed QEI HIDScope biquadFilter MODSERIAL FXOS8700Q FastPWM

Revision:
20:0f6a88f29a71
Parent:
17:d1acb6888b82
Child:
21:a316452da8cd
--- a/main.cpp	Fri Oct 18 13:05:44 2019 +0000
+++ b/main.cpp	Mon Oct 21 12:09:28 2019 +0000
@@ -15,6 +15,8 @@
 PwmOut motor1_pwm(D6);
 AnalogIn    emg0( A0 );
 AnalogIn    emg1( A1 );
+QEI motor1 (D8, D9, NC, 32);
+QEI motor2 (D12, D13, NC, 32);
 
 Ticker ticktick;
 Timer state_time;
@@ -39,6 +41,36 @@
 enum states{Waiting,Position_calibration,EMG_calibration,Homing,Operating,Demo,Failure};
 states currentState=Waiting;
 
+static float v_refx; //reference speeds 
+static float v_refy;
+static float T = 0.002; //measuring period
+static float L = 0.35;  //distance between the motor axles, has to be checked
+volatile float theta1_old = 0.0; //feedback variables
+volatile float theta2_old = 0.0;
+
+int m1_count; 
+float m1_angle;
+int m2_count;
+float m2_angle;
+float pi = 3.14;
+
+float error_x;
+float error_y;
+
+//PID controller variables
+bool q = true;
+float error_prev;
+static float Kp = 8;
+static float Ki = 1.02;
+static float Kd = 0.1;
+float u;
+float u_p;
+float u_i;
+float u_d;
+float error_integral = 0.0;
+
+float u_1;
+float u_2;
 
 void read_emg()
 {
@@ -162,6 +194,80 @@
    motor2_pwm.write(ain1.read());
 }
 
+void error(void){
+    m1_count = motor1.getPulses();                                                                                  // Read out both motor counts and convert them to rads.
+    m1_angle = (float)m1_count / 4200.0f * (2.0f * pi);
+    m2_count = motor2.getPulses();
+    m2_angle = (float)m1_count / 4200.0f * (2.0f * pi);
+    
+    float dvd=L * (tan(m2_angle) * pow(tan(m1_angle),2) - tan(m1_angle) * pow(tan(m2_angle),2));
+
+    float a =  (  -pow(cos(m1_angle),2) * pow((tan(m1_angle)+tan(m2_angle)),2) * pow(tan(m1_angle),2)  )  / dvd;             // inverse matrix components of differential x and differential y
+    float b =  (   pow(cos(m1_angle),2) * pow((tan(m1_angle)+tan(m2_angle)),2) * tan(m1_angle)         )  / dvd; 
+    float c =  (   pow(cos(m2_angle),2) * pow((tan(m1_angle)+tan(m2_angle)),2) * pow(tan(m2_angle),2)  )  / dvd;
+    float d =  (   pow(cos(m2_angle),2) * pow((tan(m1_angle)+tan(m2_angle)),2) * pow(tan(m2_angle),2)  )  / dvd;
+    
+    float theta1_dot = a*v_refx + b*v_refy;
+    float theta2_dot = c*v_refx + d*v_refy;
+    
+    float theta1_ref = theta1_old+theta1_dot*T;
+    float theta2_ref = theta2_old+theta2_dot*T;
+    
+    error_x = m1_angle - theta1_ref;
+    error_y = m2_angle - theta2_ref;
+    
+    theta1_old = theta1_ref;
+    theta2_old = theta2_ref;
+    
+    }
+    
+float PID(float err){
+    //P action
+    u_p = Kp * fabs(err);
+    
+    //I action 
+    error_integral = error_integral + err * T;
+    u_i = Ki * error_integral;
+    
+/*    
+    //D action
+    if(q){
+        error_prev = err;
+        q=false;
+        }
+        
+    float error_derivative = (err - error_prev)/T;
+    float filtered_error_derivative = LowPassFilter.step(error_derivative);
+    u_d = Kd * filtered_error_derivative;
+    error_prev = err;
+    
+*/
+    
+    u = u_p + u_i;
+    
+    return u;
+    }
+    
+void setPWM_controller(void){
+    u_1 = PID(error_x);
+    u_2 = PID(error_y);
+    
+    if(u_1 < 0.0f){
+        dir1 = 1;
+    }else{
+        dir1 = 0;
+        }
+    motor1_pwm.write(fabs(u_1));
+    
+    if(u_2 < 0.0f){
+        dir2 = 1;
+    }else{
+        dir2 = 0;
+        }
+    motor2_pwm.write(fabs(u_1));
+    
+    }
+
 void sample()
 {
     switch(currentState)
@@ -263,4 +369,5 @@
     while (true) {
         wait(10);
     }
-}
+
+}
\ No newline at end of file