1 """PID Controller Simulation
2
3 This module implements some PID tuning methods for simulation, based on
4 the reaction curve. Take care to choose a total time after the system
5 stabilization. This issue will be fixed soon.
6
7 See: http://wikis.controltheorypro.com/index.php?title=PID_Control
8
9 """
10
11
12
13
14
15 __all__ = [
16 'ZieglerNichols',
17 'CohenCoon',
18 'ChienHronesReswick0',
19 'ChienHronesReswick20',
20 ]
21
22
24 """ZieglerNichols tuning method
25
26 Returns the 'kp', 'ki' and 'kd' gains to a PID controller, using
27 the Ziegler-Nichols tuning method, based on the reaction curve. For
28 example (using Euler to discretize):
29
30 >>> g = TransferFunction([1], [1, 2, 3])
31 >>> kp, ki, kd = ZieglerNichols(g, 0.01, 10, Euler)
32 >>> print kp
33 7.25920108978
34 >>> print ki
35 11.9003296554
36 >>> print kd
37 1.10702816619
38
39 """
40
41 t, y = n_method(g, sample_time, total_time)
42
43 k = y[-1]
44
45 t63 = get_time_near(t, y, 0.632*k)
46 t28 = get_time_near(t, y, 0.28*k)
47 tau = 1.5*(t63-t28)
48 L = 1.5*(t28-(t63/3))
49
50 kp = (1.2*tau)/(k*L)
51 Ti = 2*L
52 Td = L/2
53
54 ki = kp/Ti
55 kd = kp*Td
56
57 return kp, ki, kd
58
59
60 -def CohenCoon(g, sample_time, total_time, n_method):
61 """CohenCoon tuning method
62
63 Returns the 'kp', 'ki' and 'kd' gains to a PID controller, using
64 the Cohen-Coon tuning method, based on the reaction curve. For
65 example (using Euler to discretize):
66
67 >>> g = TransferFunction([1], [1, 2, 3])
68 >>> kp, ki, kd = CohenCoon(g, 0.01, 10, Euler)
69 >>> print kp
70 5.38204782425
71 >>> print ki
72 8.56051231163
73 >>> print kd
74 1.26879134141
75
76 """
77
78 t, y = n_method(g, sample_time, total_time)
79
80 k = y[-1]
81
82 t63 = get_time_near(t, y, 0.632*k)
83 t28 = get_time_near(t, y, 0.28*k)
84 tau = 1.5*(t63-t28)
85 L = 1.5*(t28-(t63/3))
86
87 R = L/tau
88 kp = tau/(k*L*((4/3)+(R/4)))
89 Ti = L*((32 + 6*R)/(13 + 8*R))
90 Td = 4/(13 + 8*R)
91
92 ki = kp/Ti
93 kd = kp*Td
94
95 return kp, ki, kd
96
97
99 """ChienHronesReswick0 tuning method
100
101 Returns the 'kp', 'ki' and 'kd' gains to a PID controller, using
102 the Chien-Hrones-Reswick (0%) tuning method, based on the reaction
103 curve. For example (using Euler to discretize):
104
105 >>> g = TransferFunction([1], [1, 2, 3])
106 >>> kp, ki, kd = ChienHronesReswick0(g, 0.01, 10, Euler)
107 >>> print kp
108 3.62960054489
109 >>> print ki
110 5.90178950389
111 >>> print kd
112 0.553514083096
113
114 """
115
116 t, y = n_method(g, sample_time, total_time)
117
118 k = y[-1]
119
120 t63 = get_time_near(t, y, 0.632*k)
121 t28 = get_time_near(t, y, 0.28*k)
122 tau = 1.5*(t63-t28)
123 L = 1.5*(t28-(t63/3))
124
125 kp = (0.6*tau)/(k*L)
126 Ti = tau
127 Td = L/2
128
129 ki = kp/Ti
130 kd = kp*Td
131
132 return kp, ki, kd
133
134
136 """ChienHronesReswick20 tuning method
137
138 Returns the 'kp', 'ki' and 'kd' gains to a PID controller, using
139 the Chien-Hrones-Reswick (20%) tuning method, based on the reaction
140 curve. For example (using Euler to discretize):
141
142 >>> g = TransferFunction([1], [1, 2, 3])
143 >>> kp, ki, kd = ChienHronesReswick20(g, 0.01, 10, Euler)
144 >>> print kp
145 5.74686752941
146 >>> print ki
147 6.6746428913
148 >>> print kd
149 0.823813460341
150
151 """
152
153 t, y = n_method(g, sample_time, total_time)
154
155 k = y[-1]
156
157 t63 = get_time_near(t, y, 0.632*k)
158 t28 = get_time_near(t, y, 0.28*k)
159 tau = 1.5*(t63-t28)
160 L = 1.5*(t28-(t63/3))
161
162 kp = (0.95*tau)/(k*L)
163 Ti = 1.4*tau
164 Td = 0.47*L
165
166 ki = kp/Ti
167 kd = kp*Td
168
169 return kp, ki, kd
170
171
173 """Get time near
174
175 Auxiliary function.
176 Returns the time 't' of the point 'y' more near of the desired
177 point 'point'.
178
179 """
180
181 tolerance_range = max(y) - min(y)
182
183 for i in range(len(y)):
184
185 tolerance = abs(y[i] - point)
186
187 if tolerance < tolerance_range:
188 my_t = t[i]
189 tolerance_range = tolerance
190
191 return my_t
192