fancy lampje

Dependencies:   mbed QEI HIDScope biquadFilter MODSERIAL FXOS8700Q FastPWM

Revision:
25:2cc29fa67345
Parent:
24:3c9ac44890f0
Child:
26:88639564e3af
--- a/main.cpp	Fri Oct 25 12:25:48 2019 +0000
+++ b/main.cpp	Tue Oct 29 14:37:55 2019 +0000
@@ -25,12 +25,14 @@
 Timeout EMG_peaky;
 Timeout turny;
 Ticker      sample_timer;
-HIDScope    scope( 4);
+HIDScope    scope( 6);
 DigitalOut  ledred(LED_RED);
 DigitalOut  ledblue(LED_BLUE);
 DigitalOut  ledgreen(LED_GREEN);
 InterruptIn err(SW2);
 InterruptIn button(SW3);
+InterruptIn left_button(D3);
+InterruptIn right_button(D2);
 
 volatile float P0;
 volatile float P1;
@@ -58,13 +60,15 @@
 
 float error_1;
 float error_2;
+volatile float filtered_error_derivativex;
+volatile float filtered_error_derivativey;
 
 //PID controller variables
 bool q = true;
 float error_prev;
 static float Kp = 24.6;
 static float Ki = 28.3;
-static float Kd = 0.1;
+static float Kd = 20;
 float u;
 float u_p;
 float u_i;
@@ -79,6 +83,8 @@
 const double pi=3.1415926535897932384626;
 volatile float theta1;
 volatile float theta2;
+volatile float theta1_ref;
+volatile float theta2_ref;
 
 void read_emg()
 {
@@ -230,11 +236,11 @@
 void set_v_refxy(void)
 {
    static bool motorx_on=false;
-   static float signx=0.15;
+   static float signx=0.075;
    float Q0;
    Q0=2.0f*(P0-(EMG_min0+EMG_max0)/2.0f)/(EMG_max0-EMG_min0);
    static bool motory_on=false;
-   static float signy=0.15;
+   static float signy=0.075;
    float Q1;
    Q1=2.0f*(P1-(EMG_min1+EMG_max1)/2.0f)/(EMG_max1-EMG_min1);
    if (Q0>-0.2f && !ignore_peaksx)
@@ -261,7 +267,7 @@
         {
             signx=-1.0*signx;
             v_refx=1.0*signx;
-            EMG_peakx.attach(unignore_peaksx,1.5);
+            EMG_peakx.attach(unignore_peaksx,0.8);
             ignore_peaksx=true;
             motorx_on=true;
         } 
@@ -290,7 +296,7 @@
         {
             signy=-1.0*signy;
             v_refy=1.0*signy;
-            EMG_peaky.attach(unignore_peaksy,1.5);
+            EMG_peaky.attach(unignore_peaksy,0.8);
             ignore_peaksy=true;
             motory_on=true;
         } 
@@ -315,39 +321,157 @@
     }
 }
 
+void left_fake_emg(void)
+{
+    static bool motorx_on=false;
+    static float signx=0.075;
+    if (!ignore_peaksx)
+   {
+        if (motorx_on)
+        {
+            v_refx=0;
+            EMG_peakx.attach(unignore_peaksx,0.8);
+            turnx.attach(start_ignore_turnx,1);
+            ignore_turnx=false;
+            ignore_peaksx=true;
+            motorx_on=false;
+        }
+        else if(ignore_turnx)
+        {
+            v_refx=1.0*signx;
+            EMG_peakx.attach(unignore_peaksx,0.8);
+            turnx.attach(start_ignore_turnx,1);
+            ignore_turnx=false;
+            ignore_peaksx=true;
+            motorx_on=true;
+        }
+        else
+        {
+            signx=-1.0*signx;
+            v_refx=1.0*signx;
+            EMG_peakx.attach(unignore_peaksx,0.8);
+            ignore_peaksx=true;
+            motorx_on=true;
+        } 
+    }
+}
+
+void right_fake_emg(void)
+{
+    static bool motory_on=false;
+    static float signy=0.075;
+    if (!ignore_peaksy)
+   {
+        if (motory_on)
+        {
+            v_refy=0;
+            EMG_peaky.attach(unignore_peaksy,0.8);
+            turny.attach(start_ignore_turny,1);
+            ignore_turny=false;
+            ignore_peaksy=true;
+            motory_on=false;
+        }
+        else if(ignore_turny)
+        {
+            v_refy=1.0*signy;
+            EMG_peaky.attach(unignore_peaksy,0.8);
+            turny.attach(start_ignore_turny,1);
+            ignore_turny=false;
+            ignore_peaksy=true;
+            motory_on=true;
+        }
+        else
+        {
+            signy=-1.0*signy;
+            v_refy=1.0*signy;
+            EMG_peaky.attach(unignore_peaksy,0.8);
+            ignore_peaksy=true;
+            motory_on=true;
+        } 
+    }
+}
+
+void set_ref_fake_emg(void)
+{
+    float x_pos=0.35*tan(theta2)/(tan(theta1)+tan(theta2));
+    float y_pos=tan(theta1)*x_pos;
+    if(x_pos>=0.35&&v_refx>0)
+    {
+        v_refx=0;
+    }
+    else if(x_pos<=0.0&&v_refx<0)
+    {
+        v_refx=0;
+    }
+    if(y_pos>=0.45&&v_refy>0)
+    {
+        v_refy=0;
+    }
+    else if(y_pos<=0.07&&v_refy<0)
+    {
+        v_refy=0;
+    }
+}
+
 void error(void){
-    
+    float x_pos=0.35*tan(theta2)/(tan(theta1)+tan(theta2));
+    float y_pos=tan(theta1)*x_pos;
+    float r1=sqrt(pow(x_pos,2)+pow(y_pos,2));
+    float r2=sqrt(pow(0.35-x_pos,2)+pow(y_pos,2));
+    float J11=-r1*cos(theta2)/sin(theta1+theta2);
+    float J21=r1*sin(theta2)/sin(theta1+theta2);
+    float J12=r2*cos(theta1)/sin(theta1+theta2);
+    float J22=r2*sin(theta1)/sin(theta1+theta2);
+    float a=J22/(J11*J22-J12*J21);
+    float b=-J12/(J11*J22-J12*J21);
+    float c=-J21/(J11*J22-J12*J21);
+    float d=J11/(J11*J22-J12*J21);
+    /*
     float dvd=L * (tan(theta2) * pow(tan(theta1),2) + tan(theta1) * pow(tan(theta2),2));//+ is aangepast
 
     float a =  (  -pow(cos(theta1),2) * pow((tan(theta1)+tan(theta2)),2) * pow(tan(theta1),2)  )  / dvd;             // inverse matrix components of differential x and differential y
     float b =  (   pow(cos(theta1),2) * pow((tan(theta1)+tan(theta2)),2) * tan(theta1)         )  / dvd; 
     float c =  (   pow(cos(theta2),2) * pow((tan(theta1)+tan(theta2)),2) * pow(tan(theta2),2)  )  / dvd;
     float d =  (   pow(cos(theta2),2) * pow((tan(theta1)+tan(theta2)),2) * pow(tan(theta2),2)  )  / dvd;
-    
+    */
     float theta1_dot = a*v_refx + b*v_refy;
     float theta2_dot = c*v_refx + d*v_refy;
     
-    float theta1_ref;
-    float theta2_ref;
     if(currentState==Operating)
     {
         theta1_ref = theta1_old+theta1_dot*T;
         theta2_ref = theta2_old+theta2_dot*T;
+        if(theta1_ref<theta1-0.2)
+        {
+            theta1_ref=theta1-0.2;
+        }
+        else if(theta1_ref>theta1+0.2)
+        {
+            theta1_ref=theta1+0.2;
+        }
+        if(theta2_ref<theta2-0.2)
+        {
+            theta2_ref=theta2-0.2;
+        }
+        else if(theta2_ref>theta2+0.2)
+        {
+            theta2_ref=theta2+0.2;
+        }
         if(theta1_ref<0.1f)
         {
             theta1_ref=0.1f;
         }
-        else if(theta1_ref<1.6f)
+        else if(theta1_ref>1.8f)
         {
-            theta1_ref=1.6f;
+            theta1_ref=1.8f;
         }
         if(theta2_ref<0.1f)
         {
             theta2_ref=0.1f;
         }
-        else if(theta2_ref<1.6f)
+        else if(theta2_ref>1.8f)
         {
-            theta2_ref=1.6f;
+            theta2_ref=1.8f;
         }
     }
     else if(currentState==Homing)
@@ -376,22 +500,22 @@
     error_integral1 = error_integral1 + err * T;
     u_i = Ki * error_integral1;
     
-/*    
     //D action
-    if(q){
-        error_prev = err;
-        q=false;
-        }
+    static float error_prevx=0;
+    static float error_derivativex;
+    static BiQuad LowPassFilterx(0.1311f,0.2622f,0.1311f,-0.7478,0.2722f);
+    
         
-    float error_derivative = (err - error_prev)/T;
-    float filtered_error_derivative = LowPassFilter.step(error_derivative);
-    u_d = Kd * filtered_error_derivative;
-    error_prev = err;
+    error_derivativex = (err - error_prevx)/T;
+    filtered_error_derivativex = LowPassFilterx.step(error_derivativex);
+    u_d = Kd * filtered_error_derivativex;
+    error_prevx = err;
     
-*/
-    
-    u = u_p + u_i;
-    
+    u = u_p + u_i+u_d;
+    if(filtered_error_derivativex>0.3)
+    {
+        u=0;
+    }
     return u;
     }
     
@@ -403,48 +527,125 @@
     error_integral2 = error_integral2 + err * T;
     u_i = Ki * error_integral2;
     
-/*    
+
     //D action
-    if(q){
-        error_prev = err;
-        q=false;
-        }
+    static float error_prevy=0;
+    static float error_derivativey;
+    static BiQuad LowPassFiltery(0.1311f,0.2622f,0.1311f,-0.7478,0.2722f);
+    
         
-    float error_derivative = (err - error_prev)/T;
-    float filtered_error_derivative = LowPassFilter.step(error_derivative);
-    u_d = Kd * filtered_error_derivative;
-    error_prev = err;
+    error_derivativey = (err - error_prevy)/T;
+    filtered_error_derivativey = LowPassFiltery.step(error_derivativey);
+    u_d = Kd * filtered_error_derivativey;
+    error_prevy = err;
     
-*/
     
-    u = u_p + u_i;
-    
+    u = u_p + u_i+u_d;
     return u;
     }
 void set_refxy(void)
 {
     float t=state_time.read();
     int tfloor=floor(t)/1;
-    if(tfloor%8==0||tfloor%8==1)
+    /* Rectangle
+    if(tfloor%12==0||tfloor%12==1||tfloor%12==2)
     {
-        x_ref=0.075+0.05*(t-tfloor+tfloor%8);
-        y_ref=0.2-0.05*(t-tfloor+tfloor%8);
+        x_ref=0.025+0.1*(t-tfloor+tfloor%12);
+        y_ref=0.2;
     }
-    else if(tfloor%8==2||tfloor%8==3)
+    else if(tfloor%12==3||tfloor%12==4||tfloor%12==5)
     {
-        x_ref=0.175+0.05*(t-tfloor+tfloor%8-2);
-        y_ref=0.1+0.05*(t-tfloor+tfloor%8-2);
+        x_ref=0.325;
+        y_ref=0.2+0.05*(t-tfloor+tfloor%12-3);
     }
-    else if(tfloor%8==4||tfloor%8==5)
+    else if(tfloor%12==6||tfloor%12==7||tfloor%12==8)
     {
-        x_ref=0.275-0.05*(t-tfloor+tfloor%8-4);
-        y_ref=0.2+0.05*(t-tfloor+tfloor%8-4);
+        x_ref=0.325-0.1*(t-tfloor+tfloor%12-6);
+        y_ref=0.35;
     }
     else
     {
-        x_ref=0.175-0.05*(t-tfloor+tfloor%8-6);
-        y_ref=0.3-0.05*(t-tfloor+tfloor%8-6);
+        x_ref=0.025;
+        y_ref=0.35-0.05*(t-tfloor+tfloor%12-9);
+    }
+    */
+    /* Circle
+    x_ref=0.175f+0.15*cos(t/2.5f);
+    y_ref=0.275f+0.15*sin(t/2.5f);
+    */
+    if(tfloor<3)
+    {
+        x_ref=0.025;
+        y_ref=0.1;
+    }
+    else if(tfloor>=3&&tfloor<=8)
+    {
+        x_ref=0.025;
+        y_ref=0.1+0.05*(t-3);
+    }
+    else if(tfloor==9)
+    {
+        x_ref=0.025+0.05*(t-9);
+        y_ref=0.4;
+    }
+    else if(tfloor>=10&&tfloor<=15)
+    {
+        x_ref=0.075;
+        y_ref=0.4-0.05*(t-10);
+    }
+    else if(tfloor==16)
+    {
+        x_ref=0.075+0.05*(t-16);
+        y_ref=0.1;
+    }
+    else if(tfloor>=17&&tfloor<=22)
+    {
+        x_ref=0.125;
+        y_ref=0.1+0.05*(t-17);
     }
+    else if(tfloor==23)
+    {
+        x_ref=0.125+0.05*(t-23);
+        y_ref=0.4;
+    }
+    else if(tfloor>=24&&tfloor<=29)
+    {
+        x_ref=0.175;
+        y_ref=0.4-0.05*(t-24);
+    }
+    else if(tfloor==30)
+    {
+        x_ref=0.175+0.05*(t-25);
+        y_ref=0.1;
+    }
+    else if(tfloor>=31&&tfloor<=36)
+    {
+        x_ref=0.225;
+        y_ref=0.1+0.05*(t-31);
+    }
+    else if(tfloor==37)
+    {
+        x_ref=0.225+0.05*(t-37);
+        y_ref=0.4;
+    }
+    else if(tfloor>=38&&tfloor<=43)
+    {
+        x_ref=0.275;
+        y_ref=0.4-0.05*(t-38);
+    }
+    else if(tfloor==44)
+    {
+        x_ref=0.275+0.05*(t-44);
+        y_ref=0.1;
+    }
+    else if(tfloor>=45&&tfloor<=50)
+    {
+        x_ref=0.325;
+        y_ref=0.1+0.05*(t-45);
+    }
+    //float asdfgh=x_ref;
+    //x_ref=y_ref-0.075;
+    //y_ref=asdfgh+0.125;
 }
  
 void setPWM_controller(void){
@@ -457,24 +658,26 @@
     }else{
         dir1 = 1;
         }
-    motor1_pwm.write(min(fabs(u_1),1.0f));
+    motor1_pwm.write(min(0.5f+0.5f*fabs(u_1),1.0f));
     
     if(u_2 < 0.0f){
         dir2 = 0;
     }else{
         dir2 = 1;
         }
-    motor2_pwm.write(min(fabs(u_2),1.0f));
+    motor2_pwm.write(min(0.5f+0.5f*fabs(u_2),1.0f));
     
     }
 
 void sample()
 {
     get_angles();
-    scope.set(0,P0);
-    scope.set(1,P1);
+    scope.set(0,theta1);
+    scope.set(1,theta2);
     scope.set(2,v_refx);
     scope.set(3,v_refy);
+    scope.set(4,theta1_ref);
+    scope.set(5,theta2_ref);
     scope.send(); 
     switch(currentState)
     {
@@ -504,7 +707,8 @@
             break;
         case Operating:
             read_emg();
-            set_v_refxy();
+            //set_v_refxy();
+            set_ref_fake_emg();
             setPWM_controller();
             ledred=1;
             ledgreen=0;
@@ -569,10 +773,16 @@
             break;
         case Operating:
             currentState=Demo;
+            Kp=24.6;
+            Ki=28.3;
+            Kd=20;
             wait(1);
             break;
         case Demo:
             currentState=Operating;
+            Kp=15;
+            Ki=38.3;
+            Kd=20;
             wait(1);
             break;
     }
@@ -586,6 +796,10 @@
     sample_timer.attach(&sample, 0.002);
     err.fall(error_occur);
     button.fall(button_press);
+    left_button.fall(left_fake_emg);
+    left_button.rise(left_fake_emg);
+    right_button.fall(right_fake_emg);
+    right_button.rise(right_fake_emg);
     int frequency_pwm=10000;
     motor1_pwm.period(1.0/frequency_pwm);
     motor2_pwm.period(1.0/frequency_pwm);