Bryce Williams / Mbed 2 deprecated pid_encoder_speed_demo

Dependencies:   PID QEI mbed

Files at this revision

API Documentation at this revision

Comitter:
electromotivated
Date:
Tue Aug 14 17:14:36 2018 +0000
Commit message:
Init;

Changed in this revision

PID.lib Show annotated file Show diff for this revision Revisions of this file
QEI.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 929eee0b13f2 PID.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PID.lib	Tue Aug 14 17:14:36 2018 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/electromotivated/code/PID/#0cf2f6d13c71
diff -r 000000000000 -r 929eee0b13f2 QEI.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI.lib	Tue Aug 14 17:14:36 2018 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/electromotivated/code/QEI/#50aae578cb89
diff -r 000000000000 -r 929eee0b13f2 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Aug 14 17:14:36 2018 +0000
@@ -0,0 +1,142 @@
+#include "mbed.h"
+#include "PID.h"
+#include "QEI.h"
+
+/*
+    Demo of setting motor speed using encoder in pid feedback. 
+    
+    Parts used for this demo:
+    HN-GH12-1634T Gear Motor
+    LMD18200 H-Bridge Breakout Board
+    E4P-100-079 Quadrature Encoder
+    
+    TODO: Implement a "rolling"/"moving" average in callback 
+    for speed feedback
+*/
+
+float clip(float value, float lower, float upper);
+
+static float setpoint, feedback, output;
+const float output_lower_limit = -1.0;          
+const float output_upper_limit = 1.0;
+const float FEEDBACK_SCALE = 1.0/3000.0;        // Scale feedback to 1rev/3000cnts
+
+const float kp = 0.01;
+const float ki = 0.01;
+const float kd = 0.0;
+const float Ts = 0.04;                          // 25Hz Sample Freq (40ms Sample Time);
+                                                // Used for PID Sample time and used
+                                                // to calculate callback() interrupt
+                                                // time                                                
+
+PID pid(&setpoint, &feedback, &output, output_lower_limit, output_upper_limit,
+        kp, ki,  kd, Ts);
+QEI encoder(p15, p16);
+PwmOut mtr_pwm(p25);
+DigitalOut mtr_dir(p24);
+void pid_callback();                               // Updates encoder feedback and motor output
+Ticker motor;
+
+int main() {
+    // Wait for me to plug in motor battery
+    wait(5);
+    
+    // Clear encoder count
+    encoder.reset();
+    
+    // Init the motor
+    mtr_dir = 0;            // CW
+    mtr_pwm = 0.0;   // Quarter speed
+    
+    // Update sensors and feedback twice as fast as PID sample time;
+    // this makes pid react in real-time avoiding errors due to 
+    // missing counts etc. 
+    motor.attach(&pid_callback, Ts/2.0);
+    
+    // Init the pid
+    /*TODO: Implement PID Change Param Method in the PID class
+    and use it to init gains here*/
+    setpoint = 0.0;
+    feedback = encoder.read();
+    output = 0.0;
+    pid.start();
+
+    while(1){
+        int flag;
+        float userInput;
+        do{ 
+            printf("Enter Speed/RPM (-100.0 to 100.0)\r\n");
+            flag = scanf("%f", &userInput);
+        }while(flag == EOF);
+        setpoint = userInput;
+        do{   
+            printf("Setpoint: %1.2f\t\tFeedback: %1.2f\t\tError: %1.2f\t\tOuput: %1.2f\r\n", 
+                    setpoint, feedback, pid.getError(), output);
+            wait(0.25);
+        }while(pid.getError() < -0.006 || 0.006 < pid.getError());
+        printf("Speed Reached!\r\n");
+        printf("Setpoint: %1.2f\t\tFeedback: %1.2f\t\tError: %1.2f\t\tOuput: %1.2f\r\n", 
+                setpoint, feedback, pid.getError(), output);
+    }
+}
+
+/*
+    Updates feedback and output, interrupt driven so that paramaters
+    are updated in real-time, i.e. avoids update lag due to main
+    code overhead and printfs which can be slow.
+*/
+void pid_callback(){
+    // Update motor
+    if(setpoint >= 0.0) mtr_dir = 1;       // Set motor direction based on setpoint
+    else mtr_dir = 0;
+    if(-0.001 < setpoint && setpoint < 0.001){ 
+        /* Setpoint = 0 is a special case, we allow output to control speed AND 
+        direction to fight intertia and/or downhill roll. */
+        if(output >= 0.0) mtr_dir = 1;
+        else mtr_dir = 0;
+        mtr_pwm = abs(output);
+    }
+    else{    
+        if(mtr_dir == 1){                      // If CW then apply positive outputs
+            if(output >= 0.0) mtr_pwm = output;
+            else mtr_pwm = 0.0;
+        }
+        else{                                // If CCW then apply negative outputs
+            if(output <= 0.0) mtr_pwm = abs(output);
+            else mtr_pwm = 0.0;
+        }                          
+    } 
+//    if(mtr_dir == 1){                     // If CW then apply positive outputs
+//        if(output >= 0.0) mtr_pwm = output;
+//        else mtr_pwm = mtr_pwm.read() - abs(output); // Take negative output value out of full range
+//                                          // helps avoid bumpiness in motor
+//    }
+//    else{                                // If CCW then apply negative outputs
+//        if(output <= 0.0) mtr_pwm = abs(output);
+//        else mtr_pwm = mtr_pwm.read() - abs(output);
+//    }                          
+//        
+    // Running average
+    float k = Ts/2.0;                        // Discrete time, (Ts/2 because this callback is called
+                                             // at interval of Ts/2... or twice as fast as pid controller)
+    
+    /* TODO: Implement a "rolling"/"moving" average */
+    static int last_count = 0;
+    int count = encoder.read();
+    float raw_speed = ((count - last_count)*FEEDBACK_SCALE) / k; 
+    float rpm_speed = raw_speed * 60.0;     // Convert speed to RPM
+    
+    last_count = count;                     // Save last count
+    feedback = rpm_speed;              
+}
+
+/*
+    Clips value to lower/ uppper
+    @param value    The value to clip
+    @param lower    The mininum allowable value
+    @param upper    The maximum allowable value
+    @return         The resulting clipped value
+*/
+float clip(float value, float lower, float upper){
+    return std::max(lower, std::min(value, upper));
+}
\ No newline at end of file
diff -r 000000000000 -r 929eee0b13f2 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Aug 14 17:14:36 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11
\ No newline at end of file