1
1
"""
2
- Integrator(;name, k= 1, x_start= 0.0)
2
+ Integrator(;name, k = 1, x = 0.0)
3
3
4
4
Outputs `y = ∫k*u dt`, corresponding to the transfer function `1/s`.
5
5
@@ -11,20 +11,23 @@ Outputs `y = ∫k*u dt`, corresponding to the transfer function `1/s`.
11
11
# Parameters:
12
12
13
13
- `k`: Gain of integrator
14
- - `x_start `: Initial value of integrator
14
+ - `x `: Initial value of integrator
15
15
"""
16
- @component function Integrator (; name, k = 1 , x_start = 0.0 )
17
- @named siso = SISO ()
18
- @unpack u, y = siso
19
- sts = @variables x (t)= x_start [description = " State of Integrator $name " ]
20
- pars = @parameters k= k [description = " Gain of Integrator $name " ]
21
- eqs = [D (x) ~ k * u
22
- y ~ x]
23
- extend (ODESystem (eqs, t, sts, pars; name = name), siso)
16
+ @mtkmodel Integrator begin
17
+ @extend u, y = siso = SISO ()
18
+ @variables begin
19
+ x (t) = 0.0 , [description = " State of Integrator" ]
20
+ end
21
+ @parameters begin
22
+ k = 1 , [description = " Gain of Integrator" ]
23
+ end
24
+ @equations begin
25
+ D (x) ~ k * u
26
+ y ~ x
27
+ end
24
28
end
25
-
26
29
"""
27
- Derivative(; name, k= 1, T, x_start= 0.0)
30
+ Derivative(; name, k = 1, T, x = 0.0)
28
31
29
32
Outputs an approximate derivative of the input. The transfer function of this block is
30
33
@@ -44,28 +47,36 @@ A smaller `T` leads to a more ideal approximation of the derivative.
44
47
45
48
- `k`: Gain
46
49
- `T`: [s] Time constants (T>0 required; T=0 is ideal derivative block)
47
- - `x_start `: Initial value of state
50
+ - `x `: Initial value of state
48
51
49
52
# Connectors:
50
53
51
54
- `input`
52
55
- `output`
53
56
"""
54
- @component function Derivative (; name, k = 1 , T, x_start = 0.0 )
55
- @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
56
- @named siso = SISO ()
57
- @unpack u, y = siso
58
- sts = @variables x (t)= x_start [description = " State of Derivative $name " ]
59
- pars = @parameters T= T [description = " Time constant of Derivative $name " ] k= k [
60
- description = " Gain of Derivative $name " ,
61
- ]
62
- eqs = [D (x) ~ (u - x) / T
63
- y ~ (k / T) * (u - x)]
64
- extend (ODESystem (eqs, t, sts, pars; name = name), siso)
57
+ @mtkmodel Derivative begin
58
+ begin
59
+ @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
60
+ end
61
+ @extend u, y = siso = SISO ()
62
+ @variables begin
63
+ x (t) = 0.0 , [description = " State of Derivative $name " ]
64
+ end
65
+ @parameters begin
66
+ T= T, [description = " Time constant of Derivative $name " ]
67
+ k = 1 , [description = " Gain of Derivative $name " ]
68
+ end
69
+ begin
70
+ @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
71
+ end
72
+ @equations begin
73
+ D (x) ~ (u - x) / T
74
+ y ~ (k / T) * (u - x)
75
+ end
65
76
end
66
77
67
78
"""
68
- FirstOrder(; name, k=1, T, x_start= 0.0, lowpass=true)
79
+ FirstOrder(; name, k=1, T, x = 0.0, lowpass=true)
69
80
70
81
A first-order filter with a single real pole in `s = -T` and gain `k`. If `lowpass=true` (default), the transfer function
71
82
is given by `Y(s)/U(s) = `
@@ -88,7 +99,7 @@ sT + 1 - k
88
99
89
100
- `k`: Gain
90
101
- `T`: [s] Time constants (T>0 required)
91
- - `x_start `: Initial value of state
102
+ - `x `: Initial value of state
92
103
93
104
# Connectors:
94
105
@@ -97,21 +108,27 @@ sT + 1 - k
97
108
98
109
See also [`SecondOrder`](@ref)
99
110
"""
100
- @component function FirstOrder (; name, k = 1 , T, x_start = 0.0 , lowpass = true )
101
- @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
102
- @named siso = SISO ()
103
- @unpack u, y = siso
104
- sts = @variables x (t)= x_start [description = " State of FirstOrder filter $name " ]
105
- pars = @parameters T= T [description = " Time constant of FirstOrder filter $name " ] k= k [
106
- description = " Gain of FirstOrder $name " ,
107
- ]
108
- eqs = [D (x) ~ (k * u - x) / T
109
- lowpass ? y ~ x : y ~ k * u - x]
110
- extend (ODESystem (eqs, t, sts, pars; name = name), siso)
111
+ @mtkmodel FirstOrder begin
112
+ @extend u, y = siso = SISO ()
113
+ @variables begin
114
+ x (t) = 0.0 , [description = " State of FirstOrder filter $name " ]
115
+ end
116
+ @parameters begin
117
+ lowpass = true
118
+ T = T, [description = " Time constant of FirstOrder filter $name " ]
119
+ k = 1 , [description = " Gain of FirstOrder $name " ]
120
+ end
121
+ begin
122
+ @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
123
+ end
124
+ @equations begin
125
+ D (x) ~ (k * u - x) / T
126
+ getdefault (lowpass) ? y ~ x : y ~ k * u - x
127
+ end
111
128
end
112
129
113
130
"""
114
- SecondOrder(; name, k= 1, w, d, x_start= 0.0, xd_start= 0.0)
131
+ SecondOrder(; name, k = 1, w, d, x = 0.0, xd = 0.0)
115
132
116
133
A second-order filter with gain `k`, a bandwidth of `w` rad/s and relative damping `d`. The transfer function
117
134
is given by `Y(s)/U(s) = `
@@ -130,38 +147,42 @@ Critical damping corresponds to `d=1`, which yields the fastest step response wi
130
147
- `k`: Gain
131
148
- `w`: [`rad/s`] Angular frequency
132
149
- `d`: Damping
133
- - `x_start `: Initial value of state (output)
134
- - `xd_start `: Initial value of derivative of state (output)
150
+ - `x `: Initial value of state (output)
151
+ - `xd `: Initial value of derivative of state (output)
135
152
136
153
# Connectors:
137
154
138
155
- `input`
139
156
- `output`
140
157
"""
141
- @component function SecondOrder (; name, k = 1 , w, d, x_start = 0.0 , xd_start = 0.0 )
142
- @named siso = SISO ()
143
- @unpack u, y = siso
144
- @variables x (t)= x_start [description = " State of SecondOrder filter $name " ]
145
- @variables xd (t)= xd_start [description = " Derivative state of SecondOrder filter $name " ]
146
- @parameters k= k [description = " Gain of SecondOrder $name " ]
147
- @parameters w= w [description = " Bandwidth of SecondOrder $name " ]
148
- @parameters d= d [description = " Relative damping of SecondOrder $name " ]
149
- eqs = [D (x) ~ xd
158
+ @mtkmodel SecondOrder begin
159
+ @extend u, y = siso = SISO ()
160
+ @variables begin
161
+ x (t) = 0.0 , [description = " State of SecondOrder filter" ]
162
+ xd (t) = 0.0 , [description = " Derivative state of SecondOrder filter" ]
163
+ end
164
+ @parameters begin
165
+ k = 1 , [description = " Gain of SecondOrder" ]
166
+ w, [description = " Bandwidth of SecondOrder" ]
167
+ d, [description = " Relative damping of SecondOrder" ]
168
+ end
169
+ @equations begin
170
+ D (x) ~ xd
150
171
D (xd) ~ w * (w * (k * u - x) - 2 * d * xd)
151
- y ~ x]
152
- extend ( ODESystem (eqs, t; name = name), siso)
172
+ y ~ x
173
+ end
153
174
end
154
175
155
176
"""
156
- PI(;name, k= 1, T, x_start= 0.0)
177
+ PI(;name, gainPI.k = 1, T, int.x = 0.0)
157
178
158
179
Textbook version of a PI-controller without actuator saturation and anti-windup measure.
159
180
160
181
# Parameters:
161
182
162
183
- `k`: Gain
163
184
- `T`: [s] Integrator time constant (T>0 required)
164
- - `x_start `: Initial value for the integrator
185
+ - `x `: Initial value for the integrator
165
186
166
187
# Connectors:
167
188
@@ -170,22 +191,27 @@ Textbook version of a PI-controller without actuator saturation and anti-windup
170
191
171
192
See also [`LimPI`](@ref)
172
193
"""
173
- @component function PI (; name, k = 1 , T, x_start = 0.0 )
174
- @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
175
- @named err_input = RealInput () # control error
176
- @named ctr_output = RealOutput () # control signal
177
- @named gainPI = Gain (k)
178
- @named addPI = Add ()
179
- @named int = Integrator (k = 1 / T, x_start = x_start)
180
- sys = [err_input, ctr_output, gainPI, addPI, int]
181
- eqs = [
182
- connect (err_input, addPI. input1),
183
- connect (addPI. output, gainPI. input),
184
- connect (gainPI. output, ctr_output),
185
- connect (err_input, int. input),
186
- connect (int. output, addPI. input2),
187
- ]
188
- ODESystem (eqs, t, [], []; name = name, systems = sys)
194
+ @mtkmodel PI begin
195
+ @parameters begin
196
+ T
197
+ end
198
+ begin
199
+ @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
200
+ end
201
+ @components begin
202
+ err_input = RealInput () # control error
203
+ ctr_output = RealOutput () # control signal
204
+ gainPI = Gain (; k = 1.0 )
205
+ addPI = Add ()
206
+ int = Integrator (k = 1 / T, x = 0.0 )
207
+ end
208
+ @equations begin
209
+ connect (err_input, addPI. input1)
210
+ connect (addPI. output, gainPI. input)
211
+ connect (gainPI. output, ctr_output)
212
+ connect (err_input, int. input)
213
+ connect (int. output, addPI. input2)
214
+ end
189
215
end
190
216
191
217
"""
@@ -224,12 +250,12 @@ See also [`LimPID`](@ref)
224
250
@named gainPID = Gain (k)
225
251
@named addPID = Add3 ()
226
252
if with_I
227
- @named int = Integrator (k = 1 / Ti, x_start = xi_start)
253
+ @named int = Integrator (k = 1 / Ti, x = xi_start)
228
254
else
229
255
@named Izero = Constant (k = 0 )
230
256
end
231
257
if with_D
232
- @named der = Derivative (k = Td, T = 1 / Nd, x_start = xd_start)
258
+ @named der = Derivative (k = Td, T = 1 / Nd, x = xd_start)
233
259
else
234
260
@named Dzero = Constant (k = 0 )
235
261
end
@@ -274,42 +300,51 @@ Text-book version of a PI-controller with actuator saturation and anti-windup me
274
300
- `k`: Gain
275
301
- `T`: [s] Integrator time constant (T>0 required)
276
302
- `Ta`: [s] Tracking time constant (Ta>0 required)
277
- - `x_start `: Initial value for the integrator
303
+ - `x `: Initial value for the integrator
278
304
279
305
# Connectors:
280
306
281
307
- `err_input`
282
308
- `ctr_output`
283
309
"""
284
- @component function LimPI (; name, k = 1 , T, u_max, u_min = - u_max, Ta, x_start = 0.0 )
285
- @symcheck Ta > 0 ||
286
- throw (ArgumentError (" Time constant `Ta` has to be strictly positive" ))
287
- @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
288
- @symcheck u_max ≥ u_min || throw (ArgumentError (" u_min must be smaller than u_max" ))
289
- @named err_input = RealInput () # control error
290
- @named ctr_output = RealOutput () # control signal
291
- @named gainPI = Gain (k)
292
- @named addPI = Add ()
293
- @named addTrack = Add ()
294
- @named int = Integrator (k = 1 / T, x_start = x_start)
295
- @named limiter = Limiter (y_max = u_max, y_min = u_min)
296
- @named addSat = Add (k1 = 1 , k2 = - 1 )
297
- @named gainTrack = Gain (1 / Ta)
298
- sys = [err_input, ctr_output, gainPI, addPI, int, addTrack, limiter, addSat, gainTrack]
299
- eqs = [
300
- connect (err_input, addPI. input1),
301
- connect (addPI. output, gainPI. input),
302
- connect (gainPI. output, limiter. input),
303
- connect (limiter. output, ctr_output),
304
- connect (limiter. input, addSat. input2),
305
- connect (limiter. output, addSat. input1),
306
- connect (addSat. output, gainTrack. input),
307
- connect (err_input, addTrack. input1),
308
- connect (gainTrack. output, addTrack. input2),
309
- connect (addTrack. output, int. input),
310
- connect (int. output, addPI. input2),
311
- ]
312
- ODESystem (eqs, t, [], []; name = name, systems = sys)
310
+ @mtkmodel LimPI begin
311
+ @parameters begin
312
+ T
313
+ u_max
314
+ u_min = - u_max
315
+ Ta
316
+ x = 0.0
317
+ end
318
+ begin
319
+ @symcheck Ta > 0 ||
320
+ throw (ArgumentError (" Time constant `Ta` has to be strictly positive" ))
321
+ @symcheck T > 0 || throw (ArgumentError (" Time constant `T` has to be strictly positive" ))
322
+ @symcheck u_max ≥ u_min || throw (ArgumentError (" u_min must be smaller than u_max" ))
323
+ end
324
+ @components begin
325
+ err_input = RealInput () # control error
326
+ ctr_output = RealOutput () # control signal
327
+ gainPI = Gain (k = 1 )
328
+ addPI = Add ()
329
+ addTrack = Add ()
330
+ int = Integrator (k = 1 / T, x = x)
331
+ limiter = Limiter (y_max = u_max, y_min = u_min)
332
+ addSat = Add (k1 = 1 , k2 = - 1 )
333
+ gainTrack = Gain (k = 1 / Ta)
334
+ end
335
+ @equations begin
336
+ connect (err_input, addPI. input1)
337
+ connect (addPI. output, gainPI. input)
338
+ connect (gainPI. output, limiter. input)
339
+ connect (limiter. output, ctr_output)
340
+ connect (limiter. input, addSat. input2)
341
+ connect (limiter. output, addSat. input1)
342
+ connect (addSat. output, gainTrack. input)
343
+ connect (err_input, addTrack. input1)
344
+ connect (gainTrack. output, addTrack. input2)
345
+ connect (addTrack. output, int. input)
346
+ connect (int. output, addPI. input2)
347
+ end
313
348
end
314
349
315
350
"""
@@ -376,7 +411,7 @@ where the transfer function for the derivative includes additional filtering, se
376
411
@named measurement = RealInput ()
377
412
@named ctr_output = RealOutput () # control signal
378
413
@named addP = Add (k1 = wp, k2 = - 1 )
379
- @named gainPID = Gain (k)
414
+ @named gainPID = Gain (; k)
380
415
@named addPID = Add3 ()
381
416
@named limiter = Limiter (y_max = u_max, y_min = u_min)
382
417
if with_I
@@ -387,12 +422,12 @@ where the transfer function for the derivative includes additional filtering, se
387
422
else
388
423
@named addI = Add (k1 = 1 , k2 = - 1 )
389
424
end
390
- @named int = Integrator (k = 1 / Ti, x_start = xi_start)
425
+ @named int = Integrator (k = 1 / Ti, x = xi_start)
391
426
else
392
427
@named Izero = Constant (k = 0 )
393
428
end
394
429
if with_D
395
- @named der = Derivative (k = Td, T = 1 / Nd, x_start = xd_start)
430
+ @named der = Derivative (k = Td, T = 1 / Nd, x = xd_start)
396
431
@named addD = Add (k1 = wd, k2 = - 1 )
397
432
else
398
433
@named Dzero = Constant (k = 0 )
0 commit comments