libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
pid.hpp
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5
6#include "cycle_value.hpp"
7#include "libxr_def.hpp"
8
9namespace LibXR
10{
11using DefaultScalar = LIBXR_DEFAULT_SCALAR;
12
13constexpr DefaultScalar PID_SIGMA = 1e-6f;
14
25template <typename Scalar = DefaultScalar>
26class PID
27{
28 public:
33 struct Param
34 {
35 Scalar k = 1.0;
36 Scalar p = 0.0;
37 Scalar i = 0.0;
38 Scalar d = 0.0;
39 Scalar i_limit = 0.0;
40 Scalar out_limit = 0.0;
41 bool cycle = false;
42 };
43
60 template <typename Param>
61 PID(Param&& PARAM) : param_(std::forward<Param>(PARAM))
62 {
63 Reset();
64 }
65
76 Scalar Calculate(Scalar sp, Scalar fb, Scalar dt)
77 {
78 if (!std::isfinite(sp) || !std::isfinite(fb) || !std::isfinite(dt))
79 {
80 return last_out_;
81 }
82
83 // Compute error
84 Scalar err = param_.cycle ? CycleValue<Scalar>(sp) - fb : sp - fb;
85 Scalar k_err = err * param_.k;
86
87 // Derivative from feedback change
88 fb *= param_.k;
89 Scalar d = (fb - last_fb_) / dt;
90 if (!std::isfinite(d))
91 {
92 d = 0;
93 }
94
95 // Compute PD
96 Scalar output = (k_err * param_.p) - (d * param_.d);
97
98 // Integrate if within limits
99 Scalar i_term = i_ + k_err * dt;
100 Scalar i_out = i_term * param_.i;
101
102 if (param_.i > PID_SIGMA && std::isfinite(i_term))
103 {
104 if (std::abs(output + i_out) <= param_.out_limit &&
105 std::abs(i_term) <= param_.i_limit)
106 {
107 i_ = i_term;
108 }
109 }
110
111 // Apply output limits
112 output += i_out;
113 output += feed_forward_;
114 if (std::isfinite(output) && param_.out_limit > PID_SIGMA)
115 {
116 output = std::clamp(output, -param_.out_limit, param_.out_limit);
117 }
118
119 // Store states
120 last_err_ = err;
121 last_fb_ = fb;
122 last_out_ = output;
123 last_der_ = d;
124 return output;
125 }
126
138 Scalar Calculate(Scalar sp, Scalar fb, Scalar fb_dot, Scalar dt)
139 {
140 if (!std::isfinite(sp) || !std::isfinite(fb) || !std::isfinite(fb_dot) ||
141 !std::isfinite(dt))
142 {
143 return last_out_;
144 }
145
146 // Compute error
147 Scalar err = param_.cycle ? CycleValue<Scalar>(sp) - fb : sp - fb;
148 Scalar k_err = err * param_.k;
149
150 // Use externally provided derivative
151 Scalar d = fb_dot;
152 if (!std::isfinite(d))
153 {
154 d = 0;
155 }
156
157 // Compute PD
158 Scalar output = (k_err * param_.p) - (d * param_.d);
159
160 // Integrate if within limits
161 Scalar i_term = i_ + k_err * dt;
162 Scalar i_out = i_term * param_.i;
163
164 if (param_.i > PID_SIGMA && std::isfinite(i_term))
165 {
166 if (std::abs(output + i_out) <= param_.out_limit &&
167 std::abs(i_term) <= param_.i_limit)
168 {
169 i_ = i_term;
170 }
171 }
172
173 // Apply output limits
174 output += i_out;
175 output += feed_forward_;
176 if (std::isfinite(output) && param_.out_limit > PID_SIGMA)
177 {
178 output = std::clamp(output, -param_.out_limit, param_.out_limit);
179 }
180
181 // Store states
182 last_err_ = err;
183 last_fb_ = fb;
184 last_out_ = output;
185 last_der_ = d;
186 return output;
187 }
188
190 void SetK(Scalar k) { param_.k = k; }
192 void SetP(Scalar p) { param_.p = p; }
194 void SetI(Scalar i) { param_.i = i; }
196 void SetD(Scalar d) { param_.d = d; }
198 void SetILimit(Scalar limit) { param_.i_limit = limit; }
200 void SetOutLimit(Scalar limit) { param_.out_limit = limit; }
201
203 Scalar K() const { return param_.k; }
205 Scalar P() const { return param_.p; }
207 Scalar I() const { return param_.i; }
209 Scalar D() const { return param_.d; }
211 Scalar ILimit() const { return param_.i_limit; }
213 Scalar OutLimit() const { return param_.out_limit; }
215 Scalar LastError() const { return last_err_; }
217 Scalar LastFeedback() const { return last_fb_; }
219 Scalar LastOutput() const { return last_out_; }
221 Scalar LastDerivative() const { return last_der_; }
222
227 void Reset()
228 {
229 i_ = 0;
230 last_err_ = 0;
231 last_fb_ = 0;
232 last_out_ = 0;
233 last_der_ = 0;
234 }
235
241 void SetIntegralError(Scalar err) { i_ = err; }
242
248 Scalar GetIntegralError() const { return i_; }
249
255 void SetFeedForward(Scalar feed_forward) { feed_forward_ = feed_forward; }
256
263 Scalar GetFeedForward() const { return feed_forward_; }
264
265 private:
267 Scalar i_ = 0;
268 Scalar last_err_ = 0;
269 Scalar last_fb_ = 0;
270 Scalar last_der_ = 0;
271 Scalar last_out_ = 0;
272 Scalar feed_forward_ = 0;
273};
274
275} // namespace LibXR
角度循环处理类,用于处理周期性角度计算。 A cyclic angle handling class for periodic angle calculations.
通用 PID 控制器类。 Generic PID controller.
Definition pid.hpp:27
Scalar D() const
获取 D 项系数 Get derivative gain
Definition pid.hpp:209
void SetOutLimit(Scalar limit)
设置输出限幅 Set output limit
Definition pid.hpp:200
Scalar ILimit() const
获取积分限幅 Get integral limit
Definition pid.hpp:211
Scalar LastFeedback() const
获取上一次反馈值 Get last feedback
Definition pid.hpp:217
Scalar last_err_
上次误差 Last error
Definition pid.hpp:268
Scalar GetFeedForward() const
获取前馈项 Get feedforward
Definition pid.hpp:263
Scalar P() const
获取 P 项系数 Get proportional gain
Definition pid.hpp:205
Scalar LastDerivative() const
获取上一次导数 Get last derivative
Definition pid.hpp:221
Scalar LastOutput() const
获取上一次输出 Get last output
Definition pid.hpp:219
void SetD(Scalar d)
设置 D 项系数 Set derivative gain
Definition pid.hpp:196
void Reset()
重置控制器状态。 Reset all internal states.
Definition pid.hpp:227
Scalar last_fb_
上次反馈 Last feedback
Definition pid.hpp:269
void SetP(Scalar p)
设置 P 项系数 Set proportional gain
Definition pid.hpp:192
Scalar last_der_
上次导数 Last derivative
Definition pid.hpp:270
Scalar Calculate(Scalar sp, Scalar fb, Scalar dt)
使用反馈值计算 PID 输出。 Compute output from feedback only. out = k(p*err + i*∫err*dt - d*(fb-last_fb)/dt)
Definition pid.hpp:76
void SetILimit(Scalar limit)
设置积分限幅 Set integral limit
Definition pid.hpp:198
Scalar I() const
获取 I 项系数 Get integral gain
Definition pid.hpp:207
Scalar OutLimit() const
获取输出限幅 Get output limit
Definition pid.hpp:213
Scalar Calculate(Scalar sp, Scalar fb, Scalar fb_dot, Scalar dt)
使用外部导数计算 PID 输出。 Compute output using external feedback derivative. out = k(p*err + i*∫err*dt - d*fb_...
Definition pid.hpp:138
Scalar last_out_
上次输出 Last output
Definition pid.hpp:271
void SetIntegralError(Scalar err)
设置累计误差 Set integral error
Definition pid.hpp:241
Scalar GetIntegralError() const
获取累计误差 Get integral error
Definition pid.hpp:248
void SetI(Scalar i)
设置 I 项系数 Set integral gain
Definition pid.hpp:194
void SetK(Scalar k)
设置全局比例系数 Set global proportional gain
Definition pid.hpp:190
Scalar i_
积分状态 Integral state
Definition pid.hpp:267
Param param_
PID 参数 PID parameter set.
Definition pid.hpp:266
Scalar feed_forward_
前馈项 Feedforward term
Definition pid.hpp:272
Scalar LastError() const
获取上一次误差 Get last error
Definition pid.hpp:215
Scalar K() const
获取全局比例系数 Get global proportional gain
Definition pid.hpp:203
PID(Param &&PARAM)
构造 PID 控制器。 Construct a PID controller.
Definition pid.hpp:61
void SetFeedForward(Scalar feed_forward)
设置前馈项 Set feedforward
Definition pid.hpp:255
LibXR 命名空间
Definition ch32_gpio.hpp:9
PID 参数结构体。 Structure holding PID parameters.
Definition pid.hpp:34
Scalar i_limit
积分限幅 Integral limit
Definition pid.hpp:39
Scalar out_limit
输出限幅 Output limit
Definition pid.hpp:40
Scalar p
比例项 Proportional gain
Definition pid.hpp:36
bool cycle
是否处理周期误差 Whether input is cyclic
Definition pid.hpp:41
Scalar k
全局比例因子 Global gain
Definition pid.hpp:35
Scalar i
积分项 Integral gain
Definition pid.hpp:37
Scalar d
微分项 Derivative gain
Definition pid.hpp:38