HoloLib
High-performance holonomic (X-Drive) control library for VEX V5
Loading...
Searching...
No Matches
PID.h
Go to the documentation of this file.
1#pragma once
2#include "pros/rtos.hpp"
3#include <cmath>
4
5/**
6 * @brief Structure holding PID controller gains and parameters.
7 */
8struct PIDGains {
9 double kP; /**< Proportional gain */
10 double kI; /**< Integral gain */
11 double kD; /**< Derivative gain */
12 double kF; /**< Feed-forward gain */
13 double slew = 0; /**< Maximum allowed change in output per update (slew rate) */
14};
15
16/**
17 * @brief A standard PID controller with advanced features.
18 *
19 * Includes support for windup range limits, sign-flip resets, slew rate limits,
20 * filtered derivatives, and integral limits.
21 */
22class PID {
23private:
24 PIDGains m_gains;
25 double m_windupRange;
26 bool m_signFlipReset;
27
28 double m_previousError = 0;
29 double m_previousMeasurement = 0;
30 double m_integral = 0;
31 double m_filteredDerivative = 0;
32 uint32_t m_previousTime = 0;
33 bool m_initialized = false;
34 double m_previousOutput = 0;
35
36 double m_alpha = 0.2;
37 double m_integralLimit = 0.0;
38 double m_staticThreshold = 3.0;
39
40 template <typename T> inline int sgn(T val) {
41 return (T(0) < val) - (val < T(0));
42 }
43
44public:
45 /**
46 * @brief Construct a new PID controller.
47 *
48 * @param kP Proportional gain.
49 * @param kI Integral gain.
50 * @param kD Derivative gain.
51 * @param kF Feed-forward gain.
52 * @param windupRange Range within which the integral term accumulates.
53 * @param signFlipReset If true, resets the integral when the error sign flips.
54 * @param slew Maximum change in output per update.
55 */
56 PID(double kP, double kI, double kD, double kF = 0, double windupRange = 0,
57 bool signFlipReset = false, double slew = 0);
58
59 /**
60 * @brief Construct a new PID controller from a PIDGains struct.
61 *
62 * @param gains A struct containing the Kp, Ki, Kd, Kf, and slew rate.
63 * @param windupRange Range within which the integral term accumulates.
64 * @param signFlipReset If true, resets the integral when the error sign flips.
65 */
66 PID(const PIDGains &gains, double windupRange = 0,
67 bool signFlipReset = false);
68
69 /**
70 * @brief Get the current gains of the PID controller.
71 *
72 * @return PIDGains The current gains.
73 */
75
76 /**
77 * @brief Set new gains for the PID controller.
78 *
79 * @param gains The new gains to apply.
80 */
81 void setGains(PIDGains gains);
82
83 /**
84 * @brief Update the PID controller based on the current error.
85 *
86 * @param error The current error (target - measurement).
87 * @return double The computed output from the PID controller.
88 */
89 double update(double error);
90
91 /**
92 * @brief Update the PID controller based on error and actual measurement (to prevent derivative kick).
93 *
94 * @param error The current error.
95 * @param measurement The current measurement/sensor value.
96 * @return double The computed output from the PID controller.
97 */
98 double update(double error, double measurement);
99
100 /**
101 * @brief Reset the PID controller's internal state (integral, previous error, etc.).
102 */
103 void reset();
104
105 /**
106 * @brief Enable or disable resetting the integral term when the error sign flips.
107 *
108 * @param signFlipReset True to enable, false to disable.
109 */
110 void setSignFlipReset(bool signFlipReset);
111
112 /**
113 * @brief Check if sign-flip integral reset is enabled.
114 *
115 * @return true if enabled, false otherwise.
116 */
118
119 /**
120 * @brief Set the windup range within which the integral term is allowed to accumulate.
121 *
122 * @param windupRange The windup range.
123 */
124 void setWindupRange(double windupRange);
125
126 /**
127 * @brief Get the current windup range.
128 *
129 * @return double The windup range.
130 */
132
133 /**
134 * @brief Set the alpha value for the derivative filter.
135 *
136 * @param alpha The filter constant (0.0 to 1.0).
137 */
138 void setAlpha(double alpha) { m_alpha = alpha; }
139
140 /**
141 * @brief Get the alpha value for the derivative filter.
142 *
143 * @return double The current alpha value.
144 */
145 double getAlpha() { return m_alpha; }
146
147 /**
148 * @brief Set the maximum absolute value for the integral term.
149 *
150 * @param limit The maximum integral value.
151 */
152 void setIntegralLimit(double limit) { m_integralLimit = limit; }
153
154 /**
155 * @brief Get the integral limit.
156 *
157 * @return double The integral limit.
158 */
159 double getIntegralLimit() { return m_integralLimit; }
160
161 /**
162 * @brief Set the static threshold error value.
163 *
164 * @param threshold The threshold value.
165 */
166 void setStaticThreshold(double threshold) { m_staticThreshold = threshold; }
167
168 /**
169 * @brief Get the static threshold error value.
170 *
171 * @return double The static threshold value.
172 */
173 double getStaticThreshold() { return m_staticThreshold; }
174};
A standard PID controller with advanced features.
Definition PID.h:22
PID(const PIDGains &gains, double windupRange=0, bool signFlipReset=false)
Construct a new PID controller from a PIDGains struct.
void setWindupRange(double windupRange)
Set the windup range within which the integral term is allowed to accumulate.
double getStaticThreshold()
Get the static threshold error value.
Definition PID.h:173
void setStaticThreshold(double threshold)
Set the static threshold error value.
Definition PID.h:166
PIDGains getGains()
Get the current gains of the PID controller.
double update(double error)
Update the PID controller based on the current error.
double getAlpha()
Get the alpha value for the derivative filter.
Definition PID.h:145
double getIntegralLimit()
Get the integral limit.
Definition PID.h:159
void setGains(PIDGains gains)
Set new gains for the PID controller.
double getWindupRange()
Get the current windup range.
void setSignFlipReset(bool signFlipReset)
Enable or disable resetting the integral term when the error sign flips.
void setAlpha(double alpha)
Set the alpha value for the derivative filter.
Definition PID.h:138
PID(double kP, double kI, double kD, double kF=0, double windupRange=0, bool signFlipReset=false, double slew=0)
Construct a new PID controller.
bool getSignFlipReset()
Check if sign-flip integral reset is enabled.
double update(double error, double measurement)
Update the PID controller based on error and actual measurement (to prevent derivative kick).
void reset()
Reset the PID controller's internal state (integral, previous error, etc.).
void setIntegralLimit(double limit)
Set the maximum absolute value for the integral term.
Definition PID.h:152
Structure holding PID controller gains and parameters.
Definition PID.h:8
double kF
Feed-forward gain.
Definition PID.h:12
double slew
Maximum allowed change in output per update (slew rate)
Definition PID.h:13
double kP
Proportional gain.
Definition PID.h:9
double kI
Integral gain.
Definition PID.h:10
double kD
Derivative gain.
Definition PID.h:11