forked from modelica/ModelicaStandardLibrary
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Discrete.mo
469 lines (447 loc) · 16.2 KB
/
Discrete.mo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
within Modelica.Blocks;
package Discrete
"Library of discrete input/output blocks with fixed sample period"
extends Modelica.Icons.Package;
block Sampler "Ideal sampling of continuous signals"
extends Interfaces.DiscreteSISO(y(start=0, fixed=true));
equation
when {sampleTrigger, initial()} then
y = if time>=startTime then u else pre(y);
end when;
annotation (
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Ellipse(lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{25.0,-10.0},{45.0,10.0}}),
Line(points={{-100.0,0.0},{-45.0,0.0}},
color={0,0,127}),
Line(points={{45.0,0.0},{100.0,0.0}},
color={0,0,127}),
Line(points={{-35.0,0.0},{30.0,35.0}},
color={0,0,127}),
Ellipse(lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{-45.0,-10.0},{-25.0,10.0}})}),
Documentation(info="<html>
<p>
Samples the continues input signal with a sampling rate defined
via parameter <strong>samplePeriod</strong>.
</p>
</html>"));
end Sampler;
block ZeroOrderHold "Zero order hold of a sampled-data system"
extends Interfaces.DiscreteSISO;
output Real ySample(start=0, fixed=true);
equation
when {sampleTrigger, initial()} then
ySample = if time>=startTime then u else pre(ySample);
end when;
/* Define y=ySample with an infinitesimal delay to break potential
algebraic loops if both the continuous and the discrete part have
direct feedthrough
*/
y = pre(ySample);
annotation (
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Line(points={{-78.0,-42.0},{-52.0,-42.0},{-52.0,0.0},{-26.0,0.0},{-26.0,24.0},{-6.0,24.0},{-6.0,64.0},{18.0,64.0},{18.0,20.0},{38.0,20.0},{38.0,0.0},{44.0,0.0},{44.0,0.0},{62.0,0.0}},
color={0,0,127})}),
Documentation(info="<html>
<p>
The output is identical to the sampled input signal at sample
time instants and holds the output at the value of the last
sample instant during the sample points.
</p>
</html>"));
end ZeroOrderHold;
block FirstOrderHold "First order hold of a sampled-data system"
extends Modelica.Blocks.Interfaces.DiscreteSISO;
protected
SI.Time tSample;
Real uSample;
Real pre_uSample;
Real c;
initial equation
pre(tSample) = time;
pre(uSample) = u;
pre(pre_uSample) = u;
pre(c) = 0.0;
equation
when sampleTrigger then
tSample = time;
uSample = u;
pre_uSample = pre(uSample);
c = if firstTrigger then 0 else (uSample - pre_uSample)/samplePeriod;
end when;
/* Use pre_uSample and pre(c) to break potential algebraic loops by an
infinitesimal delay if both the continuous and the discrete part
have direct feedthrough.
*/
y = pre_uSample + pre(c)*(time - tSample);
annotation (
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Line(points={{-79.0,-41.0},{-59.0,-33.0},{-40.0,1.0},{-20.0,9.0},{0.0,63.0},{21.0,20.0},{41.0,10.0},{60.0,20.0}},
color={0,0,127}),
Line(points={{60.0,20.0},{81.0,10.0}},
color={0,0,127})}),
Documentation(info="<html>
<p>
The output signal is the extrapolation through the
values of the last two sampled input signals.
</p>
</html>"));
end FirstOrderHold;
block UnitDelay "Unit Delay Block"
parameter Real y_start=0 "Initial value of output signal";
extends Interfaces.DiscreteSISO;
equation
when sampleTrigger then
y = pre(u);
end when;
initial equation
y = y_start;
annotation (
Documentation(info="<html>
<p>
This block describes a unit delay:
</p>
<blockquote><pre>
1
y = --- * u
z
</pre></blockquote>
<p>
that is, the output signal y is the input signal u of the
previous sample instant. Before the second sample instant,
the output y is identical to parameter yStart.
</p>
</html>"), Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Line(points={{-30.0,0.0},{30.0,0.0}},
color={0,0,127}),
Text(textColor={0,0,127},
extent={{-90.0,10.0},{90.0,90.0}},
textString="1"),
Text(textColor={0,0,127},
extent={{-90.0,-90.0},{90.0,-10.0}},
textString="z")}));
end UnitDelay;
block TransferFunction "Discrete Transfer Function block"
parameter Real b[:]={1} "Numerator coefficients of transfer function.";
parameter Real a[:]={1} "Denominator coefficients of transfer function.";
extends Interfaces.DiscreteSISO;
output Real x[size(a, 1) - 1](each start=0, each fixed=true)
"State of transfer function from controller canonical form";
protected
parameter Integer nb=size(b, 1) "Size of Numerator of transfer function";
parameter Integer na=size(a, 1) "Size of Denominator of transfer function";
Real x1(start=0,fixed=true);
Real xext[size(a, 1)](each start=0, each fixed=true);
equation
when sampleTrigger then
/* State variables x are defined according to
controller canonical form. */
x1 = (u - a[2:size(a, 1)]*pre(x))/a[1];
xext = vector([x1; pre(x)]);
x = xext[1:size(x, 1)];
y = vector([zeros(na - nb, 1); b])*xext;
end when;
/* This is a non-sampled equation and above there are two separate
when-clauses. This breaks feedback loops without direct terms,
since in that case y will be independent of x1 (and only dependent
on pre(x)).
*/
/* Corresponding (simpler) version using when-semantics of Modelica 1.3:
equation
when sampleTrigger then
[x; xn] = [x1; pre(x)];
[u] = transpose([a])*[x1; pre(x)];
[y] = transpose([zeros(na - nb, 1); b])*[x1; pre(x)];
end when;
*/
annotation (
Documentation(info="<html>
<p>The <strong>discrete transfer function</strong> block defines the
transfer function between the input signal u and the output
signal y. The numerator has the order nb-1, the denominator
has the order na-1.</p>
<blockquote><pre>
b(1)*z^(nb-1) + b(2)*z^(nb-2) + ... + b(nb)
y(z) = -------------------------------------------- * u(z)
a(1)*z^(na-1) + a(2)*z^(na-2) + ... + a(na)
</pre></blockquote>
<p>State variables <strong>x</strong> are defined according to
<strong>controller canonical</strong> form. Initial values of the
states can be set as start values of <strong>x</strong>.</p>
<p>Example:</p>
<blockquote><pre>
Blocks.Discrete.TransferFunction g(b = {2,4}, a = {1,3});
</pre></blockquote>
<p>results in the following transfer function:</p>
<blockquote><pre>
2*z + 4
y = --------- * u
z + 3
</pre></blockquote>
</html>", revisions="<html>
<p><strong>Release Notes:</strong></p>
<ul>
<li><em>November 15, 2000</em>
by <a href=\"http://www.dynasim.se\">Hans Olsson</a>:<br>
Converted to when-semantics of Modelica 1.4 with special
care to avoid unnecessary algebraic loops.</li>
<li><em>June 18, 2000</em>
by <a href=\"http://www.robotic.dlr.de/Martin.Otter/\">Martin Otter</a>:<br>
Realized based on a corresponding model of Dieter Moormann
and Hilding Elmqvist.</li>
</ul>
</html>"),
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Line(points={{82.0,0.0},{-84.0,0.0}},
color={0,0,127}),
Text(textColor={0,0,127},
extent={{-92.0,12.0},{86.0,92.0}},
textString="b(z)"),
Text(textColor={0,0,127},
extent={{-90.0,-90.0},{90.0,-12.0}},
textString="a(z)")}));
end TransferFunction;
block StateSpace "Discrete State Space block"
parameter Real A[:, size(A, 1)]=[1, 0; 0, 1]
"Matrix A of state space model";
parameter Real B[size(A, 1), :]=[1; 1] "Matrix B of state space model";
parameter Real C[:, size(A, 1)]=[1, 1] "Matrix C of state space model";
parameter Real D[size(C, 1), size(B, 2)]=zeros(size(C, 1), size(B, 2))
"Matrix D of state space model";
extends Interfaces.DiscreteMIMO(final nin=size(B, 2), final nout=size(C, 1));
output Real x[size(A, 1)] "State vector";
equation
when sampleTrigger then
x = A*pre(x) + B*u;
y = C*pre(x) + D*u;
end when;
annotation (
Documentation(info="<html>
<p>
The <strong>discrete state space</strong> block defines the relation
between the input u and the output y in state space form:
</p>
<blockquote><pre>
x = A * pre(x) + B * u
y = C * pre(x) + D * u
</pre></blockquote>
<p>
where pre(x) is the value of the discrete state x at
the previous sample time instant.
The input is a vector of length nu, the output is a vector
of length ny and nx is the number of states. Accordingly
</p>
<blockquote><pre>
A has the dimension: A(nx,nx),
B has the dimension: B(nx,nu),
C has the dimension: C(ny,nx),
D has the dimension: D(ny,nu)
</pre></blockquote>
<p>
Example:
</p>
<blockquote><pre>
parameter: A = [0.12, 2;3, 1.5]
parameter: B = [2, 7;3, 1]
parameter: C = [0.1, 2]
parameter: D = zeros(ny,nu)
results in the following equations:
[x[1]] [0.12 2.00] [pre(x[1])] [2.0 7.0] [u[1]]
[ ] = [ ]*[ ] + [ ]*[ ]
[x[2]] [3.00 1.50] [pre(x[2])] [0.1 2.0] [u[2]]
[pre(x[1])] [u[1]]
y[1] = [0.1 2.0] * [ ] + [0 0] * [ ]
[pre(x[2])] [u[2]]
</pre></blockquote>
</html>"), Icon(coordinateSystem(
preserveAspectRatio=true,
extent={{-100,-100},{100,100}}), graphics={
Text(
extent={{-90,15},{-15,90}},
textString="A",
textColor={0,0,127}),
Text(
extent={{15,15},{90,90}},
textString="B",
textColor={0,0,127}),
Text(
extent={{-52,28},{54,-20}},
textString="z",
textColor={0,0,127}),
Text(
extent={{-90,-15},{-15,-90}},
textString="C",
textColor={0,0,127}),
Text(
extent={{15,-15},{90,-90}},
textString="D",
textColor={0,0,127})}));
end StateSpace;
block TriggeredSampler "Triggered sampling of continuous signals"
extends Modelica.Blocks.Icons.DiscreteBlock;
parameter Real y_start=0 "Initial value of output signal";
Modelica.Blocks.Interfaces.RealInput u "Connector with a Real input signal"
annotation (Placement(
transformation(extent={{-140,-20},{-100,20}})));
Modelica.Blocks.Interfaces.RealOutput y
"Connector with a Real output signal" annotation (Placement(
transformation(extent={{100,-10},{120,10}})));
Modelica.Blocks.Interfaces.BooleanInput trigger "Trigger input" annotation (Placement(
transformation(
origin={0,-118},
extent={{-20,-20},{20,20}},
rotation=90)));
equation
when trigger then
y = u;
end when;
initial equation
y = y_start;
annotation (
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Ellipse(lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{25.0,-10.0},{45.0,10.0}}),
Line(points={{-100.0,0.0},{-45.0,0.0}},
color={0,0,127}),
Line(points={{45.0,0.0},{100.0,0.0}},
color={0,0,127}),
Line(points={{0.0,-100.0},{0.0,-26.0}},
color={255,0,255}),
Line(points={{-35.0,0.0},{28.0,-48.0}},
color={0,0,127}),
Ellipse(lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{-45.0,-10.0},{-25.0,10.0}})}),
Documentation(info="<html>
<p>
Samples the continuous input signal whenever the trigger input
signal is rising (i.e., trigger changes from <strong>false</strong> to
<strong>true</strong>) and provides the sampled input signal as output.
Before the first sampling, the output signal is equal to
the initial value defined via parameter <strong>y0</strong>.
</p>
</html>"));
end TriggeredSampler;
block TriggeredMax
"Compute maximum, absolute value of continuous signal at trigger instants"
extends Modelica.Blocks.Icons.DiscreteBlock;
Modelica.Blocks.Interfaces.RealInput u "Connector with a Real input signal"
annotation (Placement(transformation(
extent={{-140,-20},{-100,20}})));
Modelica.Blocks.Interfaces.RealOutput y
"Connector with a Real output signal" annotation (Placement(
transformation(extent={{100,-10},{120,10}})));
Modelica.Blocks.Interfaces.BooleanInput trigger annotation (Placement(
transformation(
origin={0,-118},
extent={{-20,-20},{20,20}},
rotation=90)));
equation
when trigger then
y = max(pre(y), abs(u));
end when;
initial equation
y = 0;
annotation (
Icon(
coordinateSystem(preserveAspectRatio=true,
extent={{-100.0,-100.0},{100.0,100.0}}),
graphics={
Ellipse(lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{25.0,-10.0},{45.0,10.0}}),
Line(points={{-100.0,0.0},{-45.0,0.0}},
color={0,0,127}),
Line(points={{45.0,0.0},{100.0,0.0}},
color={0,0,127}),
Line(points={{0.0,-100.0},{0.0,-26.0}},
color={255,0,255}),
Line(points={{-35.0,0.0},{28.0,-48.0}},
color={0,0,127}),
Text(extent={{-86.0,24.0},{82.0,82.0}},
textColor={0,0,127},
textString="max"),
Ellipse(lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{-45.0,-10.0},{-25.0,10.0}})}),
Documentation(info="<html>
<p>
Samples the continuous input signal whenever the trigger input
signal is rising (i.e., trigger changes from <strong>false</strong> to
<strong>true</strong>). The maximum, absolute value of the input signal
at the sampling point is provided as output signal.
</p>
</html>"));
end TriggeredMax;
annotation (Documentation(info="<html>
<p>
This package contains <strong>discrete control blocks</strong>
with <strong>fixed sample period</strong>.
Every component of this package is structured in the following way:
</p>
<ol>
<li> A component has <strong>continuous real</strong> input and output signals.</li>
<li> The <strong>input</strong> signals are <strong>sampled</strong> by the given sample period
defined via parameter <strong>samplePeriod</strong>.
The first sample instant is defined by parameter <strong>startTime</strong>.</li>
<li> The <strong>output</strong> signals are computed from the sampled input signals.</li>
</ol>
<p>
A <strong>sampled data system</strong> may consist of components of package <strong>Discrete</strong>
and of every other purely <strong>algebraic</strong> input/output block, such
as the components of packages <strong>Modelica.Blocks.Math</strong>,
<strong>Modelica.Blocks.Nonlinear</strong> or <strong>Modelica.Blocks.Sources</strong>.
</p>
</html>", revisions="<html>
<ul>
<li><em>October 21, 2002</em>
by <a href=\"http://www.robotic.dlr.de/Martin.Otter/\">Martin Otter</a>:<br>
New components TriggeredSampler and TriggeredMax added.</li>
<li><em>June 18, 2000</em>
by <a href=\"http://www.robotic.dlr.de/Martin.Otter/\">Martin Otter</a>:<br>
Realized based on a corresponding library of Dieter Moormann and
Hilding Elmqvist.</li>
</ul>
</html>"), Icon(graphics={
Line(points={{-88,0},{-45,0}}, color={95,95,95}),
Ellipse(
lineColor={95,95,95},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{-45,-10},{-25,10}}),
Line(points={{-35,0},{24,52}}, color={95,95,95}),
Ellipse(
lineColor={95,95,95},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
extent={{25,-10},{45,10}}),
Line(points={{45,0},{82,0}}, color={95,95,95})}));
end Discrete;