emlabcpp
modern opinionated embedded C++ library
pid.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./min_max.h"
27 
28 #ifdef EMLABCPP_USE_NLOHMANN_JSON
29 #include <nlohmann/json.hpp>
30 #endif
31 
32 namespace emlabcpp
33 {
34 
36 {
38  float p = 0;
39  float i = 0;
40  float d = 0;
41 };
42 
44 struct pid_config
45 {
46  pid_coefficients coefficients{ .p = 1.f, .i = 0.f, .d = 0.f };
47 
49  min_max< float > limits{ 0.f, 100.f };
50 };
51 
58 //
59 template < typename TimeType >
60 struct pid
61 {
62  using time_type = TimeType;
63  using config = pid_config;
64 
66  float i_sum = 0;
67  float last_measured = 0;
69  float output;
70 
71  pid( time_type now, config const& conf = config{} )
72  : cfg( conf )
73  , last_time( now )
74  , output( clamp( 0.f, cfg.limits ) )
75  {
76  }
77 };
78 
79 template < typename TimeType >
81 {
82  pid.cfg.limits = lim;
85 }
86 
87 template < typename TimeType >
88 void update_output( pid< TimeType >& pid, float output )
89 {
90  pid.output = clamp( output, pid.cfg.limits );
91 }
92 
106 template < typename TimeType >
107 float update( pid< TimeType >& pid, TimeType now, float measured, float desired )
108 {
109  if ( now == pid.last_time )
110  return pid.output;
111 
112  auto t_diff = static_cast< float >( now - pid.last_time );
113 
114  pid_coefficients const& coeff = pid.cfg.coefficients;
115 
116  float const error = desired - measured;
117  pid.i_sum += coeff.i * ( error * t_diff );
119 
120  float const measured_diff = ( measured - pid.last_measured ) / t_diff;
121  pid.output = coeff.p * error + pid.i_sum - coeff.d * measured_diff;
123 
124  pid.last_measured = measured;
125  pid.last_time = now;
126 
127  return pid.output;
128 }
129 
130 template < typename TimeType >
131 void reset( pid< TimeType >& pid, TimeType now, float last_measured )
132 {
133  pid.last_time = now;
134  pid.last_measured = last_measured;
135 }
136 
137 } // namespace emlabcpp
138 
139 #ifdef EMLABCPP_USE_NLOHMANN_JSON
140 
141 template <>
142 struct nlohmann::adl_serializer< emlabcpp::pid_coefficients >
143 {
144  using cfg_type = emlabcpp::pid_coefficients;
145 
146  static void to_json( nlohmann::json& j, cfg_type const& cfg )
147  {
148  j["p"] = cfg.p;
149  j["i"] = cfg.i;
150  j["d"] = cfg.d;
151  }
152 
153  static cfg_type from_json( nlohmann::json const& j )
154  {
155  cfg_type cfg;
156  cfg.p = j["p"];
157  cfg.i = j["i"];
158  cfg.d = j["d"];
159  return cfg;
160  }
161 };
162 
163 template <>
164 struct nlohmann::adl_serializer< emlabcpp::pid_config >
165 {
166  using cfg_type = emlabcpp::pid_config;
167 
168  static void to_json( nlohmann::json& j, cfg_type const& cfg )
169  {
170  j["coefficients"] = cfg.coefficients;
171  j["limits"] = cfg.limits;
172  }
173 
174  static cfg_type from_json( nlohmann::json const& j )
175  {
176  cfg_type cfg;
177  cfg.coefficients = j["coefficients"];
178  cfg.limits = j["limits"];
179  return cfg;
180  }
181 };
182 
183 #endif
MIT License.
Definition: impl.h:31
pid_coefficients coefficients
Definition: pid.h:46
min_max< float > limits
limits the output of the pid regulator and internal anti-windup mechanism
Definition: pid.h:49
float d
Definition: pid.h:40
float update(pid< TimeType > &pid, TimeType now, float measured, float desired)
Call this reularly, the meaning of time value 'now' is up to you, just be consistent.
Definition: pid.h:107
void reset(pid< TimeType > &pid, TimeType now, float last_measured)
Definition: pid.h:131
constexpr T const & clamp(T const &x, min_max< T > const &mm, Compare &&comp)
Definition: min_max.h:69
float i
Definition: pid.h:39
void update_limits(pid< TimeType > &pid, min_max< float > lim)
Definition: pid.h:80
float p
coeficients
Definition: pid.h:38
void update_output(pid< TimeType > &pid, float output)
Definition: pid.h:88
Definition: pid.h:36
Structure to configure the pid regulator.
Definition: pid.h:45
Implementation of PID regulator, the object should be constructed and populated with pid<T>::conf str...
Definition: pid.h:61
pid(time_type now, config const &conf=config{})
Definition: pid.h:71
TimeType time_type
Definition: pid.h:62
float last_measured
Definition: pid.h:67
time_type last_time
Definition: pid.h:68
float output
Definition: pid.h:69
config cfg
Definition: pid.h:65
float i_sum
Definition: pid.h:66