root/branches/maintenance/2.2.2/Modelica/Blocks/Continuous.mo

Revision 572, 63.3 kB (checked in by otter, 15 months ago)

Replaced <td> by <td valign="top">
(OpenOffice does not support css-style files and therefore ignores the
attribute to have all table entries aligned on top. To fix this, all
table cells are explicitly defined with valign="top")

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1within Modelica.Blocks;
2package Continuous "Library of continuous control blocks with internal states" 
3 
4  import Modelica.Blocks.Interfaces;
5  import Modelica.SIunits;
6  extends Modelica.Icons.Library;
7 
8  annotation(preferedView="info",
9    Window(
10      x=0.05,
11      y=0.09,
12      width=0.35,
13      height=0.74,
14      library=1,
15      autolayout=1),
16    Documentation(info="<html>
17<p>
18This package contains basic <b>continuous</b> input/output blocks
19described by differential equations.
20</p>
21
22<p>
23All blocks of this package can be initialized in different
24ways controlled by parameter <b>initType</b>. The possible
25values of initType are defined in
26<a href=\"Modelica://Modelica.Blocks.Types.Init\">Modelica.Blocks.Types.Init</a>:
27</p>
28
29<table border=1 cellspacing=0 cellpadding=2>
30  <tr><td valign=\"top\"><b>Name</b></td>
31      <td valign=\"top\"><b>Description</b></td></tr>
32
33  <tr><td valign=\"top\"><b>Init.NoInit</b></td>
34      <td valign=\"top\">no initialization (start values are used as guess values with fixed=false)</td></tr>
35
36  <tr><td valign=\"top\"><b>Init.SteadyState</b></td>
37      <td valign=\"top\">steady state initialization (derivatives of states are zero)</td></tr>
38
39  <tr><td valign=\"top\"><b>Init.InitialState</b></td>
40      <td valign=\"top\">Initialization with initial states</td></tr>
41
42  <tr><td valign=\"top\"><b>Init.InitialOutput</b></td>
43      <td valign=\"top\">Initialization with initial outputs (and steady state of the states if possibles)</td></tr>
44</table>
45
46<p>
47For backward compatibility reasons the default of all blocks is
48<b>Init.NoInit</b>, with the exception of Integrator and LimIntegrator
49where the default is <b>Init.InitialState</b> (this was the initialization
50defined in version 2.2 of the Modelica standard library).
51</p>
52
53<p>
54In many cases, the most useful initial condition is
55<b>Init.SteadyState</b> because initial transients are then no longer
56present. The drawback is that in combination with a non-linear
57plant, non-linear algebraic equations occur that might be
58difficult to solve if appropriate guess values for the
59iteration variables are not provided (i.e. start values with fixed=false).
60However, it is often already useful to just initialize
61the linear blocks from the Continuous blocks library in SteadyState.
62This is uncritical, because only linear algebraic equations occur.
63If Init.NoInit is set, then the start values for the states are
64interpreted as <b>guess</b> values and are propagated to the
65states with fixed=<b>false</b>.
66</p>
67
68<p>
69Note, initialization with Init.SteadyState is usually difficult
70for a block that contains an integrator
71(Integrator, LimIntegrator, PI, PID, LimPID).
72This is due to the basic equation of an integrator:
73</p>
74
75<pre>
76  <b>initial equation</b>
77     <b>der</b>(y) = 0;   // Init.SteadyState
78  <b>equation</b>
79     <b>der</b>(y) = k*u;
80</pre>
81
82<p>
83The steady state equation leads to the condition that the input to the
84integrator is zero. If the input u is already (directly or indirectly) defined
85by another initial condition, then the initialization problem is <b>singular</b>
86(has none or infinitely many solutions). This situation occurs often
87for mechanical systems, where, e.g., u = desiredSpeed - measuredSpeed and
88since speed is both a state and a derivative, it is always defined by
89Init.InitialState or Init.SteadyState initializtion.
90</p>
91
92<p>
93In such a case, <b>Init.NoInit</b> has to be selected for the integrator
94and an additional initial equation has to be added to the system
95to which the integrator is connected. E.g., useful initial conditions
96for a 1-dim. rotational inertia controlled by a PI controller are that
97<b>angle</b>, <b>speed</b>, and <b>acceleration</b> of the inertia are zero.
98</p>
99
100</html>
101"));
102  block Integrator "Output the integral of the input signal" 
103    import Modelica.Blocks.Types.Init;
104    parameter Real k=1 "Integrator gain";
105   
106    /* InitialState is the default, because it was the default in Modelica 2.2
107     and therefore this setting is backward compatible
108  */
109    parameter Init.Temp initType=Modelica.Blocks.Types.Init.InitialState 
110      "Type of initialization (InitialState and InitialOutput are identical)"         annotation(Evaluate=true,
111        Dialog(group="Initialization"));
112    parameter Real y_start=0 "Initial or guess value of output (= state)" 
113      annotation (Dialog(group="Initialization"));
114    extends Interfaces.SISO(y(start=y_start));
115   
116    annotation (
117      Coordsys(
118        extent=[-100, -100; 100, 100],
119        grid=[2, 2],
120        component=[20, 20]),
121      Window(
122        x=0.29,
123        y=0.05,
124        width=0.53,
125        height=0.54),
126      Documentation(info="<html>
127<p>
128This blocks computes output <b>y</b> (element-wise) as
129<i>integral</i> of the input <b>u</b> multiplied with
130the gain <i>k</i>:
131</p>
132<pre>
133         k
134     y = - u
135         s
136</pre>
137
138<p>
139It might be difficult to initialize the integrator in steady state.
140This is discussed in the description of package
141<a href=\"Modelica://Modelica.Blocks.Continuous#info\">Continuous</a>.
142</p>
143
144</html>
145"),   Icon(
146        Line(points=[-80, 78; -80, -90], style(color=8)),
147        Polygon(points=[-80, 90; -88, 68; -72, 68; -80, 90], style(
148            color=8,
149            fillColor=8,
150            fillPattern=1)),
151        Line(points=[-90, -80; 82, -80], style(color=8)),
152        Polygon(points=[90, -80; 68, -72; 68, -88; 90, -80], style(
153            color=8,
154            fillColor=8,
155            fillPattern=1)),
156        Text(
157          extent=[0, -10; 60, -70],
158          string="I",
159          style(color=8)),
160        Text(
161          extent=[-150, -150; 150, -110],
162          string="k=%k",
163          style(color=0)),
164        Line(points=[-80, -80; 80, 80])),
165      Diagram(
166        Rectangle(extent=[-60, 60; 60, -60]),
167        Line(points=[-100, 0; -60, 0]),
168        Line(points=[60, 0; 100, 0]),
169        Text(
170          extent=[-36, 60; 32, 2],
171          string="k",
172          style(color=0)),
173        Text(
174          extent=[-32, 0; 36, -58],
175          string="s",
176          style(color=0)),
177        Line(points=[-46, 0; 46, 0], style(color=0))));
178  initial equation 
179    if initType == Init.SteadyState then
180       der(y) = 0;
181    elseif initType == Init.InitialState or 
182           initType == Init.InitialOutput then
183      y = y_start;
184    end if;
185  equation 
186    der(y) = k*u;
187  end Integrator;
188 
189  block LimIntegrator "Integrator with limited value of the output" 
190    import Modelica.Blocks.Types.Init;
191    parameter Real k=1 "Integrator gain";
192    parameter Real outMax=1 "Upper limit of output";
193    parameter Real outMin=-outMax "Lower limit of output";
194    parameter Init.Temp initType=Modelica.Blocks.Types.Init.InitialState 
195      "Type of initialization" 
196      annotation(Evaluate=true, Dialog(group="Initialization"));
197    parameter Boolean limitsAtInit = true 
198      "= false, if limits are ignored during initializiation (i.e., der(y)=k*u)"
199      annotation(Evaluate=true, Dialog(group="Initialization"));
200    parameter Real y_start=0 
201      "Initial or guess value of output (must be in the limits outMin .. outMax)"
202      annotation (Dialog(group="Initialization"));
203    extends Interfaces.SISO(y(start=y_start));
204    annotation (
205      Coordsys(
206        extent=[-100, -100; 100, 100],
207        grid=[2, 2],
208        component=[20, 20]),
209      Window(
210        x=0.31,
211        y=0.09,
212        width=0.54,
213        height=0.6),
214      Documentation(info="<html>
215<p>
216This blocks computes <b>y</b> (element-wise) as <i>integral</i>
217of the input <b>u</b> multiplied with the gain <i>k</i>. If the
218integral reaches a given upper or lower <i>limit</i> and the
219input will drive the integral outside of this bound, the
220integration is halted and only restarted if the input drives
221the integral away from the bounds.
222</p>
223
224<p>
225It might be difficult to initialize the integrator in steady state.
226This is discussed in the description of package
227<a href=\"Modelica://Modelica.Blocks.Continuous#info\">Continuous</a>.
228</p>
229
230<p>
231If parameter <b>limitAtInit</b> = <b>false</b>, the limits of the
232integrator are removed from the initialization problem which
233leads to a much simpler equation system. After initialization has been
234performed, it is checked via an assert whether the output is in the
235defined limits. For backward compatibility reasons
236<b>limitAtInit</b> = <b>true</b>. In most cases it is best
237to use <b>limitAtInit</b> = <b>false</b>.
238</p>
239</html>
240"),   Icon(
241        Line(points=[-80, 78; -80, -90], style(color=8)),
242        Polygon(points=[-80, 90; -88, 68; -72, 68; -80, 90], style(color=8,
243               fillColor=8)),
244        Line(points=[-90, -80; 82, -80], style(color=8)),
245        Polygon(points=[90, -80; 68, -72; 68, -88; 90, -80], style(color=8,
246               fillColor=8)),
247        Line(points=[-80, -80; 20, 20; 80, 20]),
248        Text(
249          extent=[0, -10; 60, -70],
250          string="I",
251          style(color=8)),
252        Text(
253          extent=[-150, -150; 150, -110],
254          string="k=%k",
255          style(color=0))),
256      Diagram(
257        Rectangle(extent=[-60, 60; 60, -60]),
258        Text(
259          extent=[-54, 46; -4, -48],
260          string="lim",
261          style(color=0)),
262        Line(points=[-100, 0; -60, 0]),
263        Line(points=[60, 0; 100, 0]),
264        Text(
265          extent=[-8, 60; 60, 2],
266          string="k",
267          style(color=0)),
268        Text(
269          extent=[-8, -2; 60, -60],
270          string="s",
271          style(color=0)),
272        Line(points=[4, 0; 46, 0], style(color=0))));
273  initial equation 
274    if initType == Init.SteadyState then
275       der(y) = 0;
276    elseif initType == Init.InitialState or 
277           initType == Init.InitialOutput then
278      y = y_start;
279    end if;
280  equation 
281    if initial() and not limitsAtInit then
282       der(y) = k*u;
283       assert(y >= outMin - 0.01*abs(outMin) and 
284              y <= outMax + 0.01*abs(outMax),
285             "LimIntegrator: During initialization the limits have been ignored.\n"+
286             "However, the result is that the output y is not within the required limits:\n"+
287             "  y = " + String(y) + ", outMin = " + String(outMin) + ", outMax = " + String(outMax));
288    else
289       der(y) = if y < outMin and u < 0 or y > outMax and u > 0 then 0 else k*u;
290    end if;
291  end LimIntegrator;
292 
293  block Derivative "Approximated derivative block" 
294    import Modelica.Blocks.Types.Init;
295    parameter Real k=1 "Gains";
296    parameter SIunits.Time T(min=Modelica.Constants.small) = 0.01 
297      "Time constants (T>0 required; T=0 is ideal derivative block)";
298    parameter Init.Temp initType=Modelica.Blocks.Types.Init.NoInit 
299      "Type of initialization"                                                        annotation(Evaluate=true,
300        Dialog(group="Initialization"));
301    parameter Real x_start=0 "Initial or guess value of state" 
302      annotation (Dialog(group="Initialization"));
303    parameter Real y_start=0 "Initial value of output (= state)" 
304      annotation(Dialog(enable=initType == Init.InitialOutput, group=
305            "Initialization"));
306    extends Interfaces.SISO;
307   
308    output Real x(start=x_start) "State of block";
309   
310    annotation (
311      Documentation(info="
312<HTML>
313<p>
314This blocks defines the transfer function between the
315input u and the output y
316(element-wise) as <i>approximated derivative</i>:
317</p>
318<pre>
319             k * s
320     y = ------------ * u
321            T * s + 1
322</pre>
323<p>
324If you would like to be able to change easily between different
325transfer functions (FirstOrder, SecondOrder, ... ) by changing
326parameters, use the general block <b>TransferFunction</b> instead
327and model a derivative block with parameters<br>
328b = {k,0}, a = {T, 1}.
329</p>
330 
331<p>
332If k=0, the block reduces to y=0.
333</p>
334</HTML>
335"),   Icon(
336        Line(points=[-80, 78; -80, -90], style(color=8)),
337        Polygon(points=[-80, 90; -88, 68; -72, 68; -80, 90], style(color=8,
338               fillColor=8)),
339        Line(points=[-90, -80; 82, -80], style(color=8)),
340        Polygon(points=[90, -80; 68, -72; 68, -88; 90, -80], style(color=8,
341               fillColor=8)),
342        Line(points=[-80, -80; -80, 60; -70, 17.95; -60, -11.46; -50, -32.05;
343               -40, -46.45; -30, -56.53; -20, -63.58; -10, -68.51; 0, -71.96;
344               10, -74.37; 20, -76.06; 30, -77.25; 40, -78.07; 50, -78.65;
345              60, -79.06]),
346        Text(
347          extent=[-30,14; 86,60],
348          string="DT1",
349          style(color=8)),
350        Text(
351          extent=[-150, -150; 150, -110],
352          string="k=%k",
353          style(color=0))),
354      Diagram(
355        Text(
356          extent=[-54, 52; 50, 10],
357          string="k s",
358          style(color=0)),
359        Text(
360          extent=[-54, -6; 52, -52],
361          string="T s + 1",
362          style(color=0)),
363        Line(points=[-50, 0; 50, 0], style(color=0)),
364        Rectangle(extent=[-60, 60; 60, -60]),
365        Line(points=[-100, 0; -60, 0]),
366        Line(points=[60, 0; 100, 0])),
367      Coordsys(
368        extent=[-100, -100; 100, 100],
369        grid=[2, 2],
370        component=[20, 20]),
371      Window(
372        x=0.17,
373        y=0.03,
374        width=0.5,
375        height=0.61));
376  protected 
377    parameter Boolean zeroGain = abs(k) < Modelica.Constants.eps;
378  initial equation 
379    if initType == Init.SteadyState then
380      der(x) = 0;
381    elseif initType == Init.InitialState then
382      x = x_start;
383    elseif initType == Init.InitialOutput then
384      if zeroGain then
385         x = u;
386      else
387         y = y_start;
388      end if;
389    end if;
390  equation 
391    der(x) = if zeroGain then 0 else (u - x)/T;
392    y = if zeroGain then 0 else (k/T)*(u - x);
393  end Derivative;
394 
395  block FirstOrder "First order transfer function block (= 1 pole)" 
396    import Modelica.Blocks.Types.Init;
397    parameter Real k=1 "Gain";
398    parameter SIunits.Time T=1 "Time Constant";
399    parameter Init.Temp initType=Modelica.Blocks.Types.Init.NoInit 
400      "Type of initialization (InitialState and InitialOutput are identical)"         annotation(Evaluate=true,
401        Dialog(group="Initialization"));
402    parameter Real y_start=0 "Initial or guess value of output (= state)" 
403      annotation (Dialog(group="Initialization"));
404   
405    extends Interfaces.SISO(y(start=y_start));
406   
407    annotation (
408      Documentation(info="<HTML>
409<p>
410This blocks defines the transfer function between the input u
411and the output y (element-wise) as <i>first order</i> system:
412</p>
413<pre>
414               k
415     y = ------------ * u
416            T * s + 1
417</pre>
418<p>
419If you would like to be able to change easily between different
420transfer functions (FirstOrder, SecondOrder, ... ) by changing
421parameters, use the general block <b>TransferFunction</b> instead
422and model a first order SISO system with parameters<br>
423b = {k}, a = {T, 1}.
424</p>
425<pre>
426Example:
427   parameter: k = 0.3, T = 0.4
428   results in:
429             0.3
430      y = ----------- * u
431          0.4 s + 1.0
432</pre>
433
434</HTML>
435"),   Icon(
436        Line(points=[-80, 78; -80, -90], style(color=8)),
437        Polygon(points=[-80, 90; -88, 68; -72, 68; -80, 88; -80, 90], style(
438            color=8,
439            fillColor=8,
440            fillPattern=1)),
441        Line(points=[-90, -80; 82, -80], style(color=8)),
442        Polygon(points=[90, -80; 68, -72; 68, -88; 90, -80], style(
443            color=8,
444            fillColor=8,
445            fillPattern=1)),
446        Line(points=[-80, -80; -70, -45.11; -60, -19.58; -50, -0.9087; -40,
447               12.75; -30, 22.75; -20, 30.06; -10, 35.41; 0, 39.33; 10,
448              42.19; 20, 44.29; 30, 45.82; 40, 46.94; 50, 47.76; 60, 48.36;
449               70, 48.8; 80, 49.12]),
450        Text(
451          extent=[0, 0; 60, -60],
452          string="PT1",
453          style(color=8)),
454        Text(
455          extent=[-150, -150; 150, -110],
456          string="T=%T",
457          style(color=0))),
458      Diagram(
459        Text(
460          extent=[-48, 52; 50, 8],
461          string="k",
462          style(color=0)),
463        Text(
464          extent=[-54, -6; 56, -56],
465          string="T s + 1",
466          style(color=0)),
467        Line(points=[-50, 0; 50, 0], style(color=0)),
468        Rectangle(extent=[-60, 60; 60, -60]),
469        Line(points=[-100, 0; -60, 0]),
470        Line(points=[60, 0; 100, 0])),
471      Coordsys(
472        extent=[-100, -100; 100, 100],
473        grid=[2, 2],
474        component=[20, 20]),
475      Window(
476        x=0.15,
477        y=0.04,
478        width=0.52,
479        height=0.55));
480  initial equation 
481    if initType == Init.SteadyState then
482      der(y) = 0;
483    elseif initType == Init.InitialState or initType == Init.InitialOutput then
484      y = y_start;
485    end if;
486  equation 
487    der(y) = (k*u - y)/T;
488  end FirstOrder;
489 
490  block SecondOrder "Second order transfer function block (= 2 poles)" 
491    import Modelica.Blocks.Types.Init;
492    parameter Real k=1 "Gain";
493    parameter Real w=1 "Angular frequency";
494    parameter Real D=1 "Damping";
495    parameter Init.Temp initType=Modelica.Blocks.Types.Init.NoInit 
496      "Type of initialization (InitialState and InitialOutput are identical)"         annotation(Evaluate=true,
497        Dialog(group="Initialization"));
498    parameter Real y_start=0 "Initial or guess value of output (= state)" 
499      annotation (Dialog(group="Initialization"));
500    parameter Real yd_start=0 
501      "Initial or guess value of derivative of output (= state)" 
502      annotation (Dialog(group="Initialization"));
503   
504    extends Interfaces.SISO(y(start=y_start));
505    output Real yd(start=yd_start) "Derivative of y";
506    annotation (
507      Coordsys(
508        extent=[-100, -100; 100, 100],
509        grid=[2, 2],
510        component=[20, 20]),
511      Window(
512        x=0.23,
513        y=0.1,
514        width=0.54,
515        height=0.49),
516      Documentation(info="<HTML>
517<p>
518This blocks defines the transfer function between the input u and
519the output y (element-wise) as <i>second order</i> system:
520</p>
521<pre>
522                             k
523     y = ---------------------------------------- * u
524            ( s / w )^2 + 2*D*( s / w ) + 1
525</pre>
526<p>
527If you would like to be able to change easily between different
528transfer functions (FirstOrder, SecondOrder, ... ) by changing
529parameters, use the general model class <b>TransferFunction</b>
530instead and model a second order SISO system with parameters<br>
531b = {k}, a = {1/w^2, 2*D/w, 1}.
532</p>
533<pre>
534Example:
535
536   parameter: k =  0.3,  w = 0.5,  D = 0.4
537   results in:
538                  0.3
539      y = ------------------- * u
540          4.0 s^2 + 1.6 s + 1
541</pre>
542
543</HTML>
544"),   Icon(
545        Line(points=[-80, 78; -80, -90], style(color=8)),
546        Polygon(points=[-80, 90; -88, 68; -72, 68; -80, 88; -80, 90], style(
547            color=8,
548            fillColor=8,
549            fillPattern=1)),
550        Line(points=[-90, -80; 82, -80], style(color=8)),
551        Polygon(points=[90, -80; 68, -72; 68, -88; 90, -80], style(
552            color=8,
553            fillColor=8,
554            fillPattern=1)),
555        Line(points=[-80, -80; -72, -68.53; -64, -39.5; -56, -2.522; -48,
556              32.75; -40, 58.8; -32, 71.51; -24, 70.49; -16, 58.45; -8,
557              40.06; 0, 20.55; 8, 4.459; 16, -5.271; 24, -7.629; 32, -3.428;
558               40, 5.21; 48, 15.56; 56, 25.03; 64, 31.66; 72, 34.5; 80,
559              33.61]),
560        Text(
561          extent=[0, -10; 60, -70],
562          string="PT2",
563          style(color=8)),
564        Text(
565          extent=[-150, -150; 150, -110],
566          string="w=%w",
567          style(color=0))),
568      Diagram(
569        Rectangle(extent=[-60, 60; 60, -60]),
570        Text(
571          extent=[-60, 60; 60, 14],
572          string="k",
573          style(color=0)),
574        Text(
575          extent=[-60, 8; -32, -20],
576          string="s",
577          style(color=0)),
578        Line(points=[-100, 0; -60, 0]),
579        Line(points=[60, 0; 100, 0]),
580        Line(points=[-50, 14; 50, 14], style(color=0)),
581        Line(points=[-54, -20; -38, -20], style(color=0)),
582        Text(
583          extent=[-52, -26; -36, -48],
584          string="w",
585          style(color=0)),
586        Line(points=[-50, 2; -56, -8; -56, -28; -52, -46], style(color=0)),
587        Line(points=[-40, 2; -34, -10; -34, -30; -38, -46], style(color=0)),
588        Text(
589          extent=[-34, 8; -22, -10],
590          string="2",
591          style(color=0)),
592        Text(
593          extent=[-34, -6; 6, -36],
594          string="+2D",
595          style(color=0)),
596        Text(
597          extent=[2, 8; 30, -20],
598          string="s",
599          style(color=0)),
600        Line(points=[8, -20; 24, -20], style(color=0)),
601        Text(
602    Â