Inverse kinematics, PID controller and motor control

Dependencies:   Encoder HIDScope MODSERIAL mbed QEI

Fork of Inverse_kinematics by Casper Kroon

Files at this revision

API Documentation at this revision

Comitter:
CasperK
Date:
Wed Oct 31 16:15:56 2018 +0000
Parent:
12:9a2d3d544426
Commit message:
P controller now works

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 9a2d3d544426 -r 2d2763be031c main.cpp
--- a/main.cpp	Tue Oct 30 09:22:44 2018 +0000
+++ b/main.cpp	Wed Oct 31 16:15:56 2018 +0000
@@ -9,14 +9,16 @@
 PwmOut pwmpin2(D5);
 DigitalOut directionpin2(D4);
 DigitalOut directionpin1(D7);
-QEI motor2(D13,D12,NC, 32);
-QEI motor1(D11,D10,NC, 32);
+QEI motor1(D13,D12,NC, 32);
+QEI motor2(D11,D10,NC, 32);
 DigitalOut ledred(LED_RED);
 
 DigitalIn KillSwitch(SW2);
 DigitalIn button(SW3);
 MODSERIAL pc(USBTX, USBRX);
 HIDScope scope(6);
+DigitalIn buttonleft(D2);
+DigitalIn buttonright(D3);
 
 //values of inverse kinematics
 volatile bool emg0Bool = false;
@@ -28,7 +30,7 @@
 const float C1 = 3.0; //motor 1 gear ratio
 const float C2 = 0.013; //motor 2 gear ratio/radius of the circular gear in m
 const float length = 0.300; //length in m (placeholder)
-const float Timestep = 0.1;
+const float Timestep = 0.01;
 
 volatile float x_position = length;
 volatile float y_position = 0.0;
@@ -42,27 +44,35 @@
 volatile char c;
 
 //values of PID controller
-const float Kp = 1;
-const float Ki = 0.2;
+const float Kp = 0.05;
+const float Ki = 0.01;
 const float Kd = 0;
-float Output1 = 0 ;      //Starting value
-float Output2 = 0 ;      //Starting value
-float P1 = 0;           //encoder value
-float P2 = 0;
-float e1 = 0 ;          //Starting value 
-float e2 = 0 ;          //Starting value
-float e3;  
-float f1 = 0 ;          //Starting value 
-float f2 = 0 ;          //Starting value
-float f3;     
-float Output_Last1;      // Remember previous position
-float Output_Last2;      // Remember previous position
-float Y1;               // Value that is outputted to motor control
-float Y2;               // Value that is outputted to motor control
-float pwm1;
-float pwm2;
-float P_Last = 0;       // Starting position
-      
+volatile float Output1 = 0 ;      //Starting value
+volatile float Output2 = 0 ;      //Starting value
+volatile float P1 = 0;           //encoder value
+volatile float P2 = 0;
+volatile float e1 = 0 ;          //Starting value 
+volatile float e2 = 0 ;          //Starting value
+volatile float e3 = 0;  
+volatile float f1 = 0 ;          //Starting value 
+volatile float f2 = 0 ;          //Starting value
+volatile float f3 = 0; 
+volatile float df3 = 0;
+volatile float if3 = 0;
+volatile float de3 = 0;
+volatile float ie3 = 0;
+    
+volatile float Output_Last1;      // Remember previous position
+volatile float Output_Last2;      // Remember previous position
+volatile float Y1 = 0;               // Value that is outputted to motor control
+volatile float Y2 = 0;               // Value that is outputted to motor control
+volatile float pwm_value1 = 0;
+volatile float pwm_value2 = 0;
+volatile float P_Last = 0;       // Starting position
+
+Ticker pwm_ticker; 
+Ticker mainticker;; 
+    
 void yDirection() {
     //direction of the motion
     if (emg0Bool && !emg1Bool) { //if a is pressed and not d, move to the left
@@ -98,21 +108,21 @@
     //if the button is pressed, reverse the y direction
     if (!button) {
         x_direction = !x_direction;
-        wait(0.5f);
+        //wait(0.5f);
         }     
         
     if (emg2Bool) { //if w is pressed, move up/down
         //direction of the motion
         if (x_direction) { 
-            direction = 1.0;
+            direction = 1.0f;
         }
         else if (!x_direction) {
-            direction = -1.0;
+            direction = -1.0f;
         }
         
         //calculating the motion
         old_x_position = x_position;
-        x_position = old_x_position + (0.01f * direction);
+        x_position = old_x_position + (0.0001f * direction);
         old_motor1_angle = motor1_angle;
         motor1_angle = old_motor1_angle + ( x_position - length ) / C2; // sawtooth-gear motor angle in rad
         
@@ -123,14 +133,14 @@
 
 volatile float Plek1;
 void PIDController1() { 
-    Plek1 = motor1.getPulses();  
-    P1 = motor1.getPulses() / 8400 * 2*PI;    //actual motor angle in rad  
+    //Plek1 = motor1.getPulses();  
+    P1 = motor1.getPulses() / 8400.0f * 2.0f*PI;    //actual motor angle in rad  
     e1 = e2;
     e2 = e3;
     e3 = motor1_angle - P1;
-    float de3 = (e3-e2)/Timestep;
-    float ie3 = ie3 + e3*Timestep;
-    Output2 = Kp * e3 + Ki * ie3 + Kd * de3;
+    de3 = (e3-e2)/Timestep;
+    ie3 = ie3 + e3*Timestep;
+    Output1 = Kp * e3 + Ki * ie3 + Kd * de3;
     
 //    Output_Last1 = Output1;
 //    Output1 = Kp * (e3 - e2) + Output_Last1 +Ki * e3 + Kd * (e3 - 2*e2 + e1);
@@ -142,15 +152,16 @@
     else if (Y1 <= -1){
         Y1 = -1;
     }    
+    
 }
 volatile float Plek2;
 void PIDController2() {   
-    Plek2 = motor2.getPulses();
+    //Plek2 = motor2.getPulses();
     P2 = motor2.getPulses() / 8400.0f * 2.0f*PI; // actual motor angle in rad
     f2 = f3;
     f3 = motor2_angle - P2;
-    float df3 = (f3-f2)/Timestep;
-    float if3 = if3 + f3*Timestep;
+    df3 = (f3-f2)/Timestep;
+    if3 = if3 + f3*Timestep;
     Output2 = Kp * f3 + Ki * if3 + Kd * df3;
   //  Output_Last2 = Output2;
   //  Output2 = Kp * (f3 - f2) + Output_Last2 +Ki * f3 + Kd * (f3 - 2*f2 + f1);
@@ -162,101 +173,97 @@
     else if (Y2 <= -1){
         Y2 = -1;
     }   
+    
 }
 
 void ControlMotor1() {
-    if (Y1 > 0) {
-        Y1 = 0.6f * Y1 + 0.4f;
-        directionpin1 = true;
+    if (Y1 > 0.0f) {
+        Y1 = 0.4f * Y1 + 0.2f;
+        directionpin1 = false;
     } 
-    else if(Y1 < 0){
-        Y1 = 0.6f - 0.4f * Y1;
-        directionpin1 = false;
+    else if(Y1 < -0.0f){
+        Y1 = -0.2f + 0.4f * Y1;
+        directionpin1 = true;
     }    
-    pwmpin2 = abs(Y1);
+
+    pwm_value1 = fabs(Y1);
 }
 
 void ControlMotor2() {
-    if (Y2 > 0) {
-        Y2 = 0.5f * Y2 + 0.5f;
+    if (Y2 > 0.1f) {
+        Y2 = 0.3f * Y2 + 0.2f;
         directionpin2 = true;
     } 
-    else if(Y2 < 0){
-        Y2 = 0.5f - 0.5f * Y2;
+    else if(Y2 < -0.1f){
+        Y2 = -0.2f + 0.3f * Y2;
         directionpin2 = false;
     }
-    pwmpin1 = abs(Y2);
+    else {
+        Y2 = 0;
+    }
+    pwm_value2 = fabs(Y2);
+}
+
+void motorPWM() {
+    pwmpin1 = pwm_value1;
+    pwmpin2 = pwm_value2;
+} 
+
+void tickermain() {
+    if(!buttonleft){
+        emg0Bool = true;
+    }
+    else if(!buttonright) {
+        emg2Bool = true;
+    }
+    xDirection(); //call the function to move in the y direction
+    yDirection(); //call the function to move in the x direction
+    PIDController1();
+    PIDController2();
+    ControlMotor1();
+    ControlMotor2();
+    
+    if (!KillSwitch) { //even in mekaar gebeund voor het hebben van een stop knop
+        ledred = false;
+        pwm_value1 = 0;
+        pwm_value2 = 0;
+        //for fun blink sos maybe???
+        wait(2.0f);
+        bool u = true;
+
+        while(u) {
+            if (!KillSwitch) {
+                u = false;
+                ledred = true;
+                wait(1.0f);
+            }
+        }
+    }
+    scope.set(0, pwm_value1);
+    scope.set(1, P1);
+    scope.set(2, Y2);
+    scope.set(3, P2);
+    scope.set(4, motor1_angle);
+    scope.set(5, motor2_angle);
+    scope.send(); 
+                  
+    //pwm_value1 = 0;
+    //pwm_value2 = 0;
+    //Y1 = 0;
+    //Y2 = 0;
+    
+    emg0Bool = false;
+    emg1Bool = false;
+    emg2Bool = false;
 }
 
 int main() {
-    pc.baud(115200);
-    pc.printf(" ** program reset **\n\r");
+    //pc.baud(115200);
+    //pc.printf(" ** program reset **\n\r");
+    mainticker.attach(&tickermain, Timestep);
+    pwm_ticker.attach(&motorPWM, Timestep);
     ledred = true;
     
     while (true) {
-        
-        //testing the code from keyboard imputs: a-d: left to right, w: forward/backwards
-        a = pc.readable();
-        if (a) {
-            c = pc.getc();
-            switch (c){
-                case 'a': //move to the left
-                    emg0Bool = true; 
-                    break;           
-                case 'd': //move to the right
-                    emg1Bool = true;
-                    break;            
-                case 'w': //move up/down
-                    emg2Bool = true;
-                    break;
-            }
-        }
-        xDirection(); //call the function to move in the y direction
-        yDirection(); //call the function to move in the x direction
-        PIDController1();
-        PIDController2();
-        ControlMotor1();
-        ControlMotor2();
-        
-        if (!KillSwitch) { //even in mekaar gebeund voor het hebben van een stop knop
-            ledred = false;
-            pwmpin1 = 0;
-            pwmpin2 = 0;
-            //for fun blink sos maybe???
-            wait(2.0f);
-            bool u = true;
-
-            while(u) {
-                if (!KillSwitch) {
-                    u = false;
-                    ledred = true;
-                    wait(1.0f);
-                }
-            }
-        }
-        scope.set(0, Y1);
-        scope.set(1, Y2);
-        scope.set(2, motor1_angle);
-        scope.set(3, motor2_angle);
-        scope.set(4, x_position);
-        scope.set(5, y_position);
-        scope.send(); 
-                      
-        // print the motor angles and coordinates
-        pc.printf("position: (%f, %f)\n\r", x_position, y_position);
-        pc.printf("motor1 angle: %f\n\r", motor1_angle);
-        pc.printf("motor2 angle: %f\n\r", motor2_angle);
-        pc.printf("output1: %f\r\n", Output1);
-        pc.printf("output2: %f\r\n", Output2);
-        pc.printf("P1: %f\r\n", P1);
-        pc.printf("P2: %f\r\n", P2);
-    
-        pc.printf("dirctionpin: %f\r\n\n", (float)directionpin1);
-        pc.printf("plek1: %f\r\n", Plek1);
-        pc.printf("plek2: %f\r\n", Plek2);
-
-        wait(Timestep); //can also be done with ticker, to be sure that it happens exactly every 0.5 seconds
-        pwmpin1 = 0;
-        pwmpin2 = 0;
     }
 }
\ No newline at end of file