Basic but robust PID library
Dependents: ESP8266_pid_mtrPos_webserver_SDcard_v2 ESP8266_pid_mtrSpeed_Webserver_SDcard ESP8266_pid_spd_and_pos_webserver_SDcard ESP8266_pid_redbot_webserver ... more
PID.h@2:07397aa513c6, 2015-11-24 (annotated)
- Committer:
- electromotivated
- Date:
- Tue Nov 24 00:17:55 2015 +0000
- Revision:
- 2:07397aa513c6
- Parent:
- 0:9a6f7aafe531
- Child:
- 5:0cf2f6d13c71
Added new prototypes to header;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
electromotivated | 0:9a6f7aafe531 | 1 | #ifndef PID_H |
electromotivated | 0:9a6f7aafe531 | 2 | #define PID_H |
electromotivated | 0:9a6f7aafe531 | 3 | #include "mbed.h" |
electromotivated | 0:9a6f7aafe531 | 4 | #include <algorithm> |
electromotivated | 0:9a6f7aafe531 | 5 | |
electromotivated | 0:9a6f7aafe531 | 6 | /* |
electromotivated | 0:9a6f7aafe531 | 7 | Bryce Williams 11/19/2015 |
electromotivated | 0:9a6f7aafe531 | 8 | |
electromotivated | 0:9a6f7aafe531 | 9 | PID Controller Class based on Brett Beauregard's Arduino PID Library |
electromotivated | 0:9a6f7aafe531 | 10 | and PID blog post. |
electromotivated | 0:9a6f7aafe531 | 11 | |
electromotivated | 0:9a6f7aafe531 | 12 | Brett Beauregard's blog post explains the PID code implementation very well |
electromotivated | 0:9a6f7aafe531 | 13 | and discusses why the actual equation is a bit different than the classical |
electromotivated | 0:9a6f7aafe531 | 14 | equation, i.e. he explains and implements how to overcome windup, dervative |
electromotivated | 0:9a6f7aafe531 | 15 | kick, etc. This class uses the same implementation, but adds interrupt |
electromotivated | 0:9a6f7aafe531 | 16 | driven computation. |
electromotivated | 0:9a6f7aafe531 | 17 | |
electromotivated | 0:9a6f7aafe531 | 18 | Reference Links: |
electromotivated | 0:9a6f7aafe531 | 19 | 1. Arduion Library: |
electromotivated | 0:9a6f7aafe531 | 20 | (http://playground.arduino.cc/Code/PIDLibrary) |
electromotivated | 0:9a6f7aafe531 | 21 | 2. Brett Beauregard's PID Blog: |
electromotivated | 0:9a6f7aafe531 | 22 | (http://brettbeauregard.com/blog/2011/04/improving-the-beginners- |
electromotivated | 0:9a6f7aafe531 | 23 | pid-introduction/) |
electromotivated | 0:9a6f7aafe531 | 24 | */ |
electromotivated | 0:9a6f7aafe531 | 25 | |
electromotivated | 0:9a6f7aafe531 | 26 | class PID{ |
electromotivated | 0:9a6f7aafe531 | 27 | public: |
electromotivated | 0:9a6f7aafe531 | 28 | /* |
electromotivated | 0:9a6f7aafe531 | 29 | Constructor for PID objects. |
electromotivated | 0:9a6f7aafe531 | 30 | |
electromotivated | 0:9a6f7aafe531 | 31 | Note: PID objects use given pointers, ie setpoint, |
electromotivated | 0:9a6f7aafe531 | 32 | feedback, output inside interrupts. When reading/ modifying |
electromotivated | 0:9a6f7aafe531 | 33 | these vars make sure we don't have possible read/write |
electromotivated | 0:9a6f7aafe531 | 34 | conflicts if the interrupt fires. Either ensure reads/writes |
electromotivated | 0:9a6f7aafe531 | 35 | are atomic operations, or call the stop() method perform the |
electromotivated | 0:9a6f7aafe531 | 36 | read/write and then call the start() method. |
electromotivated | 0:9a6f7aafe531 | 37 | */ |
electromotivated | 0:9a6f7aafe531 | 38 | PID(float* setpoint, float* feedback, float* output, |
electromotivated | 0:9a6f7aafe531 | 39 | float output_lower, float output_upper, |
electromotivated | 0:9a6f7aafe531 | 40 | float kp, float ki, float kd, float Ts); |
electromotivated | 0:9a6f7aafe531 | 41 | /* |
electromotivated | 0:9a6f7aafe531 | 42 | Starts PID Controller; Attaches sample() as callback to Ticker |
electromotivated | 0:9a6f7aafe531 | 43 | sample_timer and starts the interrupt |
electromotivated | 0:9a6f7aafe531 | 44 | */ |
electromotivated | 0:9a6f7aafe531 | 45 | void start(); |
electromotivated | 0:9a6f7aafe531 | 46 | /* |
electromotivated | 0:9a6f7aafe531 | 47 | Stops PID Contoller; detaches callback from Ticker sample_timer. |
electromotivated | 0:9a6f7aafe531 | 48 | Allows manual setting of output. |
electromotivated | 0:9a6f7aafe531 | 49 | */ |
electromotivated | 0:9a6f7aafe531 | 50 | void stop(); |
electromotivated | 0:9a6f7aafe531 | 51 | /* |
electromotivated | 0:9a6f7aafe531 | 52 | Increments/ decrements Gain values and Sample time |
electromotivated | 0:9a6f7aafe531 | 53 | by the given value. Gives a simple method to |
electromotivated | 0:9a6f7aafe531 | 54 | programatically step through different values; just put in a |
electromotivated | 0:9a6f7aafe531 | 55 | loop and go |
electromotivated | 0:9a6f7aafe531 | 56 | @param delta_"name" The value that will be added to its currently set value |
electromotivated | 0:9a6f7aafe531 | 57 | */ |
electromotivated | 0:9a6f7aafe531 | 58 | // void adjust_parameters(float delta_kp, float delta_ki, float delta_kd, float delta Ts); |
electromotivated | 0:9a6f7aafe531 | 59 | /* |
electromotivated | 0:9a6f7aafe531 | 60 | Overwrite Gain and Sample Time parameters with new |
electromotivated | 0:9a6f7aafe531 | 61 | values |
electromotivated | 0:9a6f7aafe531 | 62 | Note: sample_timer interrupt is disabled during update |
electromotivated | 0:9a6f7aafe531 | 63 | to avoid synch issues. |
electromotivated | 0:9a6f7aafe531 | 64 | |
electromotivated | 0:9a6f7aafe531 | 65 | */ |
electromotivated | 0:9a6f7aafe531 | 66 | void set_parameters(float kp, float ki, float kd, float Ts); |
electromotivated | 0:9a6f7aafe531 | 67 | |
electromotivated | 2:07397aa513c6 | 68 | float getKp(); |
electromotivated | 2:07397aa513c6 | 69 | float getKi(); |
electromotivated | 2:07397aa513c6 | 70 | float getKd(); |
electromotivated | 2:07397aa513c6 | 71 | float getTs(); |
electromotivated | 2:07397aa513c6 | 72 | |
electromotivated | 0:9a6f7aafe531 | 73 | /* |
electromotivated | 0:9a6f7aafe531 | 74 | returns current error |
electromotivated | 0:9a6f7aafe531 | 75 | */ |
electromotivated | 0:9a6f7aafe531 | 76 | float getError(); |
electromotivated | 0:9a6f7aafe531 | 77 | |
electromotivated | 0:9a6f7aafe531 | 78 | private: |
electromotivated | 0:9a6f7aafe531 | 79 | float _kp, _ki, _kd; // PID Gain values |
electromotivated | 0:9a6f7aafe531 | 80 | float _Ts; // Sample time is seconds |
electromotivated | 0:9a6f7aafe531 | 81 | float* _setpoint; // Pointer to setpoint value |
electromotivated | 0:9a6f7aafe531 | 82 | float* _feedback; // Pointer to sensor feedback value (sensor input) |
electromotivated | 0:9a6f7aafe531 | 83 | float* _output; // Pointer to control output value |
electromotivated | 0:9a6f7aafe531 | 84 | float _output_lower; // Ouput Lower Limit |
electromotivated | 0:9a6f7aafe531 | 85 | float _output_upper; // Output Upper Limit |
electromotivated | 0:9a6f7aafe531 | 86 | |
electromotivated | 0:9a6f7aafe531 | 87 | float i_accumulator; // Integral Term accumulator |
electromotivated | 0:9a6f7aafe531 | 88 | float last_feedback; // Previous feedback value |
electromotivated | 0:9a6f7aafe531 | 89 | float error; // Feedback error term |
electromotivated | 0:9a6f7aafe531 | 90 | Ticker sample_timer; // Generates the sample time interrupt and calls sample() |
electromotivated | 0:9a6f7aafe531 | 91 | /* |
electromotivated | 0:9a6f7aafe531 | 92 | sample() performs next sample calculationand updates command value |
electromotivated | 0:9a6f7aafe531 | 93 | */ |
electromotivated | 0:9a6f7aafe531 | 94 | void sample(); |
electromotivated | 0:9a6f7aafe531 | 95 | /* |
electromotivated | 0:9a6f7aafe531 | 96 | Clips value to lower/ uppper |
electromotivated | 0:9a6f7aafe531 | 97 | @param value The value to clip |
electromotivated | 0:9a6f7aafe531 | 98 | @param lower The mininum allowable value |
electromotivated | 0:9a6f7aafe531 | 99 | @param upper The maximum allowable value |
electromotivated | 0:9a6f7aafe531 | 100 | @return The resulting clipped value |
electromotivated | 0:9a6f7aafe531 | 101 | */ |
electromotivated | 0:9a6f7aafe531 | 102 | float clip(float value, float lower, float upper); |
electromotivated | 0:9a6f7aafe531 | 103 | }; |
electromotivated | 0:9a6f7aafe531 | 104 | |
electromotivated | 0:9a6f7aafe531 | 105 | #endif |