TinyRobotics
Loading...
Searching...
No Matches
PIDController.h
1#pragma once
2
3#include <assert.h>
4
5#include <cmath>
6
7namespace tinyrobotics {
8
9/**
10 * @class PIDController
11 * @ingroup control
12 * @brief Implements a simple, header-only Proportional-Integral-Derivative
13 * (PID) controller.
14 *
15 * This class provides a basic PID controller for closed-loop control of
16 * processes such as motors, temperature, position, and more. The controller
17 * computes a control output based on the error between a target setpoint and a
18 * measured process value, using configurable proportional, integral, and
19 * derivative gains.
20 *
21 * ## Features
22 * - Simple API: `begin()` to configure, `calculate()` to compute control output
23 * - Supports output clamping (min/max)
24 * - Suitable for real-time and embedded systems
25 * - All state is internal; no dynamic memory allocation
26 *
27 * ## Usage Example
28 * @code
29 * PIDController pid;
30 * pid.begin(0.01, 255, 0, 1.0, 0.5, 0.1); // dt, max, min, kp, ki, kd
31 * N control = pid.calculate(target, measured);
32 * @endcode
33 *
34 * ## Parameters
35 * - dt: Loop interval time (seconds)
36 * - max: Maximum output value
37 * - min: Minimum output value
38 * - kp: Proportional gain
39 * - ki: Integral gain
40 * - kd: Derivative gain
41 *
42 * ## Methods
43 * - begin(dt, max, min, kp, ki, kd): Initialize controller parameters
44 * - calculate(target, measured): Compute control output for current error
45 *
46 * ## Applications
47 * - Motor speed and position control
48 * - Temperature regulation
49 * - Robotics and automation
50 * - Any process requiring feedback control
51 *
52 * @author Phil Schatzmann
53 */
54
55template <class N = float>
56class PIDController {
57 public:
58 // dt - loop interval time
59 // min - minimum value of manipulated variable
60 // max - maximum value of manipulated variable
61 // kp - proportional gain
62 // ki - Integral gain
63 // kd - derivative gain
64 bool begin(N dt, N min, N max, N kp, N ki, N kd) {
65 this->dt = dt;
66 this->max = max;
67 this->min = min;
68 this->kp = kp;
69 this->kd = kd;
70 this->ki = ki;
71 this->integral = 0.0f;
72 this->preerror = 0.0f;
73 return true;
74 }
75
76 void setDt(N dt) { this->dt = dt; }
77
78 // target = desired process value
79 // measured = current process value:
80 // returns new process value
81 N calculate(N target, N measured) {
82 // Calculate error
83 N error = target - measured;
84
85 // Proportional term
86 N pout = kp * error;
87
88 // Integral term with anti-windup (clamp integral)
89 integral += error * dt;
90 // Clamp integral so that ki * integral stays within output limits
91 N Iout = ki * integral;
92 if (Iout > max) {
93 Iout = max;
94 integral = max / (ki != 0 ? ki : 1);
95 } else if (Iout < min) {
96 Iout = min;
97 integral = min / (ki != 0 ? ki : 1);
98 }
99
100 // Derivative term
101 assert(dt != 0.0f);
102 N derivative = (error - preerror) / dt;
103 N dout = kd * derivative;
104
105 // Calculate total output
106 N output = pout + Iout + dout;
107
108 // Restrict to max/min
109 if (output > max)
110 output = max;
111 else if (output < min)
112 output = min;
113
114 // Save error to previous error
115 preerror = error;
116
117 return output;
118 }
119
120 protected:
121 N dt = 1.0f;
122 N max = 0.0f;
123 N min = 0.0f;
124 N kp = 0.0f;
125 N kd = 0.0f;
126 N ki = 0.0f;
127 N preerror = 0.0f;
128 N integral = 0.0f;
129};
130
131} // namespace tinyrobotics
Implements a simple, header-only Proportional-Integral-Derivative (PID) controller.
Definition: PIDController.h:56