Cantera  2.0
PID_Controller.h
Go to the documentation of this file.
1 /**
2  * @file PID_Controller.h
3  */
4 
5 // Copyright 2001 California Institute of Technology
6 
7 #ifndef CT_PID_H
8 #define CT_PID_H
9 
10 namespace Cantera
11 {
12 
13 class PID_Controller
14 {
15 
16 public:
17 
18  /// Default constructor.
19  PID_Controller() : m_v0(Undef), m_p(Undef), m_i(Undef), m_d(Undef),
20  m_setpoint(Undef), m_last(Undef), m_time(Undef),
21  m_xint(Undef), m_out(Undef), m_dt(Undef) {}
22 
23  /**
24  * Copy constructor. Gains and setpoint are copied, but not
25  * the internal parameters defining the state of the
26  * controller. Method 'reset' must be called for the copy
27  * before using it.
28  */
29  PID_Controller(const PID_Controller& pid)
30  : m_v0(pid.m_v0), m_p(pid.m_p), m_i(pid.m_i), m_d(pid.m_d),
31  m_setpoint(pid.m_setpoint),
32  m_last(Undef), m_time(Undef), m_xint(Undef) {}
33 
34  /**
35  * Assignment operator. @see Copy constructor.
36  */
37  PID_Controller& operator=(const PID_Controller& pid) {
38  if (this == &pid) {
39  return *this;
40  }
41  m_v0 = pid.m_v0;
42  m_p = pid.m_p;
43  m_i = pid.m_i;
44  m_d = pid.m_d;
45  m_setpoint = pid.m_setpoint;
46  m_last = Undef;
47  m_time = Undef;
48  m_xint = Undef;
49  return *this;
50  }
51 
52  /**
53  * Reset the start time to time, and the current value of
54  * the input to input. Sets the integrated error signal to zero.
55  */
56  void reset(doublereal time = 0.0, doublereal input = 0.0) {
57  m_time = time;
58  m_last = input;
59  m_xint = 0.0;
60  m_out = m_v0;
61  m_dt = 1.0;
62  m_maxerr = 0.0;
63  }
64 
65  doublereal setpoint(doublereal y = Undef) {
66  if (y != Undef) {
67  m_setpoint = y;
68  }
69  return m_setpoint;
70  }
71 
72  bool getGains(vector_fp& gains) {
73  gains.resize(4);
74  return getGains(4, gains.begin());
75  }
76 
77  bool getGains(int n, doublereal* gains) {
78  if (n < 4) {
79  return false;
80  }
81  gains[0] = m_v0;
82  gains[1] = m_p;
83  gains[2] = m_i;
84  gains[3] = m_d;
85  return true;
86  }
87 
88  bool setGains(const vector_fp& gains) {
89  return setGains(int(gains.size()), gains.begin());
90  }
91 
92  bool setGains(int n, const doublereal* gains) {
93  if (n < 4) {
94  return false;
95  }
96  m_v0 = gains[0];
97  m_p = gains[1];
98  m_i = gains[2];
99  m_d = gains[3];
100  if (m_p < 0.0 || m_i < 0.0 || m_d < 0.0) {
101  return false;
102  }
103  return true;
104  }
105 
106  void update(doublereal time, doublereal input) {
107  if (time <= m_time) {
108  return;
109  }
110  doublereal err = input - m_setpoint;
111  if (fabs(err) > m_maxerr) {
112  m_maxerr = fabs(err);
113  }
114  m_dt = time - m_time;
115  m_xint += (0.5*(input + m_last) - m_setpoint) * m_dt;
116  m_last = input;
117  m_time = time;
118  doublereal xdot = (input - m_last)/m_dt;
119  m_out = m_v0 - m_p*(input - m_setpoint) - m_i*m_xint
120  - m_d*xdot;
121  }
122 
123  doublereal output(doublereal input) {
124  return fmaxx(0.0,
125  m_out - (m_p + m_d/m_dt + 0.5*m_i*m_dt)*(input - m_last));
126  }
127 
128  doublereal maxError() {
129  return m_maxerr;
130  }
131 
132  bool ready() {
133  return (m_time != Undef
134  && m_setpoint != Undef
135  && m_v0 != Undef);
136  }
137 
138 protected:
139 
140  doublereal
141  m_v0,
142  m_p,
143  m_i,
144  m_d,
145  m_setpoint,
146  m_maxerr,
147  m_last,
148  m_time,
149  m_xint,
150  m_out,
151  m_dt;
152 };
153 
154 }
155 
156 #endif
157