20 double kp; // (P)roportional Tuning Parameter |
20 double kp; // (P)roportional Tuning Parameter |
21 double ki; // (I)ntegral Tuning Parameter |
21 double ki; // (I)ntegral Tuning Parameter |
22 double kd; // (D)erivative Tuning Parameter |
22 double kd; // (D)erivative Tuning Parameter |
23 |
23 |
24 int controllerDirection; |
24 int controllerDirection; |
25 int pOn; |
|
26 |
25 |
27 double *myInput; // Pointers to the Input, Output, and Setpoint variables |
26 double *myInput; // Pointers to the Input, Output, and Setpoint variables |
28 double *myOutput; // This creates a hard link between the variables and the |
27 double *myOutput; // This creates a hard link between the variables and the |
29 double *mySetpoint; // PID, freeing the user from having to constantly tell us |
28 double *mySetpoint; // PID, freeing the user from having to constantly tell us |
30 // what these values are. with pointers we'll just know. |
29 // what these values are. with pointers we'll just know. |
32 unsigned long lastTime; ///< Last time of the time window. |
31 unsigned long lastTime; ///< Last time of the time window. |
33 double outputSum, lastInput; |
32 double outputSum, lastInput; |
34 |
33 |
35 unsigned long SampleTime; |
34 unsigned long SampleTime; |
36 double outMin, outMax; |
35 double outMin, outMax; |
37 bool inAuto, pOnE; |
36 bool inAuto; |
38 |
37 |
39 |
38 |
40 static const char *TAG = "pid"; |
39 static const char *TAG = "pid"; |
41 |
40 |
42 void PID_Initialize(void); |
41 void PID_Initialize(void); |
43 |
42 |
44 |
43 |
45 |
44 |
46 void PID(double* Input, double* Output, double* Setpoint, double Kp, double Ki, double Kd, PID_PON POn, PID_DIRECTION Direction) { |
45 void PID(double* Input, double* Output, double* Setpoint, double Kp, double Ki, double Kd, PID_DIRECTION Direction) { |
47 myOutput = Output; |
46 myOutput = Output; |
48 myInput = Input; |
47 myInput = Input; |
49 mySetpoint = Setpoint; |
48 mySetpoint = Setpoint; |
50 inAuto = false; |
49 inAuto = false; |
51 |
50 |
52 PID_SetOutputLimits(0, 255); |
51 PID_SetOutputLimits(0, 255); |
53 |
52 |
54 SampleTime = 100; |
53 SampleTime = 100; |
55 |
54 |
56 PID_SetControllerDirection(Direction); |
55 PID_SetControllerDirection(Direction); |
57 PID_SetTunings(Kp, Ki, Kd, POn); |
56 PID_SetTunings(Kp, Ki, Kd); |
58 |
57 |
59 lastTime = (xTaskGetTickCount() * portTICK_PERIOD_MS ) - SampleTime; |
58 lastTime = (xTaskGetTickCount() * portTICK_PERIOD_MS ) - SampleTime; |
60 } |
59 } |
61 |
60 |
62 |
61 |
78 /*Compute all the working error variables*/ |
77 /*Compute all the working error variables*/ |
79 double input = *myInput; |
78 double input = *myInput; |
80 double error = *mySetpoint - input; |
79 double error = *mySetpoint - input; |
81 double dInput = (input - lastInput); |
80 double dInput = (input - lastInput); |
82 outputSum+= (ki * error); |
81 outputSum+= (ki * error); |
83 |
82 outputSum-= kp * dInput; |
84 /*Add Proportional on Measurement, if P_ON_M is specified*/ |
|
85 if (!pOnE) |
|
86 outputSum-= kp * dInput; |
|
87 |
83 |
88 if (outputSum > outMax) |
84 if (outputSum > outMax) |
89 outputSum= outMax; |
85 outputSum= outMax; |
90 else if (outputSum < outMin) |
86 else if (outputSum < outMin) |
91 outputSum= outMin; |
87 outputSum= outMin; |
92 |
88 |
93 /*Add Proportional on Error, if P_ON_E is specified*/ |
89 double output = 0; |
94 double output; |
|
95 if (pOnE) |
|
96 output = kp * error; |
|
97 else |
|
98 output = 0; |
|
99 |
90 |
100 /*Compute Rest of PID Output*/ |
91 /*Compute Rest of PID Output*/ |
101 output += outputSum - kd * dInput; |
92 output += outputSum - kd * dInput; |
102 |
93 |
103 if (output > outMax) |
94 if (output > outMax) |
119 /* |
110 /* |
120 * This function allows the controller's dynamic performance to be adjusted. |
111 * This function allows the controller's dynamic performance to be adjusted. |
121 * it's called automatically from the constructor, but tunings can also |
112 * it's called automatically from the constructor, but tunings can also |
122 * be adjusted on the fly during normal operation |
113 * be adjusted on the fly during normal operation |
123 */ |
114 */ |
124 void PID_SetTunings(double Kp, double Ki, double Kd, PID_PON POn) |
115 void PID_SetTunings(double Kp, double Ki, double Kd) |
125 { |
116 { |
126 if (Kp<0 || Ki<0 || Kd<0) { |
117 if (Kp<0 || Ki<0 || Kd<0) { |
127 ESP_LOGE(TAG, "SetTunings negative input"); |
118 ESP_LOGE(TAG, "SetTunings negative input"); |
128 return; |
119 return; |
129 } |
120 } |
130 |
121 |
131 pOn = POn; |
|
132 pOnE = POn == PID_P_ON_E; |
|
133 |
|
134 dispKp = Kp; dispKi = Ki; dispKd = Kd; |
122 dispKp = Kp; dispKi = Ki; dispKd = Kd; |
135 |
123 |
136 ESP_LOGI(TAG, "SetTunings(%.3f, %.3f, %.3f, %s)", Kp, Ki, Kd, (POn) ? "P_ON_E":"P_ON_M"); |
124 ESP_LOGI(TAG, "SetTunings(%.3f, %.3f, %.3f)", Kp, Ki, Kd); |
137 double SampleTimeInSec = ((double)SampleTime)/1000; |
125 double SampleTimeInSec = ((double)SampleTime)/1000; |
138 kp = Kp; |
126 kp = Kp; |
139 ki = Ki * SampleTimeInSec; |
127 ki = Ki * SampleTimeInSec; |
140 kd = Kd / SampleTimeInSec; |
128 kd = Kd / SampleTimeInSec; |
141 |
129 |