| 1 | within Modelica.Blocks; |
|---|
| 2 | package 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> |
|---|
| 18 | This package contains basic <b>continuous</b>Â input/output blocks |
|---|
| 19 | described by differential equations. |
|---|
| 20 | </p> |
|---|
| 21 | |
|---|
| 22 | <p> |
|---|
| 23 | All blocks of this package can be initialized in different |
|---|
| 24 | ways controlled by parameter <b>initType</b>. The possible |
|---|
| 25 | values 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> |
|---|
| 47 | For backward compatibility reasons the default of all blocks is |
|---|
| 48 | <b>Init.NoInit</b>, with the exception of Integrator and LimIntegrator |
|---|
| 49 | where the default is <b>Init.InitialState</b>Â (this was the initialization |
|---|
| 50 | defined in version 2.2 of the Modelica standard library). |
|---|
| 51 | </p> |
|---|
| 52 | |
|---|
| 53 | <p> |
|---|
| 54 | In many cases, the most useful initial condition is |
|---|
| 55 | <b>Init.SteadyState</b>Â because initial transients are then no longer |
|---|
| 56 | present. The drawback is that in combination with a non-linear |
|---|
| 57 | plant, non-linear algebraic equations occur that might be |
|---|
| 58 | difficult to solve if appropriate guess values for the |
|---|
| 59 | iteration variables are not provided (i.e. start values with fixed=false). |
|---|
| 60 | However, it is often already useful to just initialize |
|---|
| 61 | the linear blocks from the Continuous blocks library in SteadyState. |
|---|
| 62 | This is uncritical, because only linear algebraic equations occur. |
|---|
| 63 | If Init.NoInit is set, then the start values for the states are |
|---|
| 64 | interpreted as <b>guess</b>Â values and are propagated to the |
|---|
| 65 | states with fixed=<b>false</b>. |
|---|
| 66 | </p> |
|---|
| 67 | |
|---|
| 68 | <p> |
|---|
| 69 | Note, initialization with Init.SteadyState is usually difficult |
|---|
| 70 | for a block that contains an integrator |
|---|
| 71 | (Integrator, LimIntegrator, PI, PID, LimPID). |
|---|
| 72 | This 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> |
|---|
| 83 | The steady state equation leads to the condition that the input to the |
|---|
| 84 | integrator is zero. If the input u is already (directly or indirectly) defined |
|---|
| 85 | by another initial condition, then the initialization problem is <b>singular</b> |
|---|
| 86 | (has none or infinitely many solutions). This situation occurs often |
|---|
| 87 | for mechanical systems, where, e.g., u = desiredSpeed - measuredSpeed and |
|---|
| 88 | since speed is both a state and a derivative, it is always defined by |
|---|
| 89 | Init.InitialState or Init.SteadyState initializtion. |
|---|
| 90 | </p> |
|---|
| 91 | |
|---|
| 92 | <p> |
|---|
| 93 | In such a case, <b>Init.NoInit</b>Â has to be selected for the integrator |
|---|
| 94 | and an additional initial equation has to be added to the system |
|---|
| 95 | to which the integrator is connected. E.g., useful initial conditions |
|---|
| 96 | for 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> |
|---|
| 128 | This blocks computes output <b>y</b>Â (element-wise) as |
|---|
| 129 | <i>integral</i>Â of the input <b>u</b>Â multiplied with |
|---|
| 130 | the gain <i>k</i>: |
|---|
| 131 | </p> |
|---|
| 132 | <pre> |
|---|
| 133 | Â Â Â Â Â k |
|---|
| 134 | Â Â Â y = - u |
|---|
| 135 | Â Â Â Â Â s |
|---|
| 136 | </pre> |
|---|
| 137 | |
|---|
| 138 | <p> |
|---|
| 139 | It might be difficult to initialize the integrator in steady state. |
|---|
| 140 | This 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> |
|---|
| 216 | This blocks computes <b>y</b>Â (element-wise) as <i>integral</i> |
|---|
| 217 | of the input <b>u</b>Â multiplied with the gain <i>k</i>. If the |
|---|
| 218 | integral reaches a given upper or lower <i>limit</i>Â and the |
|---|
| 219 | input will drive the integral outside of this bound, the |
|---|
| 220 | integration is halted and only restarted if the input drives |
|---|
| 221 | the integral away from the bounds. |
|---|
| 222 | </p> |
|---|
| 223 | |
|---|
| 224 | <p> |
|---|
| 225 | It might be difficult to initialize the integrator in steady state. |
|---|
| 226 | This is discussed in the description of package |
|---|
| 227 | <a href=\"Modelica://Modelica.Blocks.Continuous#info\">Continuous</a>. |
|---|
| 228 | </p> |
|---|
| 229 | |
|---|
| 230 | <p> |
|---|
| 231 | If parameter <b>limitAtInit</b>Â = <b>false</b>, the limits of the |
|---|
| 232 | integrator are removed from the initialization problem which |
|---|
| 233 | leads to a much simpler equation system. After initialization has been |
|---|
| 234 | performed, it is checked via an assert whether the output is in the |
|---|
| 235 | defined limits. For backward compatibility reasons |
|---|
| 236 | <b>limitAtInit</b>Â = <b>true</b>. In most cases it is best |
|---|
| 237 | to 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> |
|---|
| 314 | This blocks defines the transfer function between the |
|---|
| 315 | input 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> |
|---|
| 324 | If you would like to be able to change easily between different |
|---|
| 325 | transfer functions (FirstOrder, SecondOrder, ... ) by changing |
|---|
| 326 | parameters, use the general block <b>TransferFunction</b>Â instead |
|---|
| 327 | and model a derivative block with parameters<br> |
|---|
| 328 | b = {k,0}, a = {T, 1}. |
|---|
| 329 | </p> |
|---|
| 330 | Â |
|---|
| 331 | <p> |
|---|
| 332 | If 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> |
|---|
| 410 | This blocks defines the transfer function between the input u |
|---|
| 411 | and 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> |
|---|
| 419 | If you would like to be able to change easily between different |
|---|
| 420 | transfer functions (FirstOrder, SecondOrder, ... ) by changing |
|---|
| 421 | parameters, use the general block <b>TransferFunction</b>Â instead |
|---|
| 422 | and model a first order SISO system with parameters<br> |
|---|
| 423 | b = {k}, a = {T, 1}. |
|---|
| 424 | </p> |
|---|
| 425 | <pre> |
|---|
| 426 | Example: |
|---|
| 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> |
|---|
| 518 | This blocks defines the transfer function between the input u and |
|---|
| 519 | the 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> |
|---|
| 527 | If you would like to be able to change easily between different |
|---|
| 528 | transfer functions (FirstOrder, SecondOrder, ... ) by changing |
|---|
| 529 | parameters, use the general model class <b>TransferFunction</b> |
|---|
| 530 | instead and model a second order SISO system with parameters<br> |
|---|
| 531 | b = {k}, a = {1/w^2, 2*D/w, 1}. |
|---|
| 532 | </p> |
|---|
| 533 | <pre> |
|---|
| 534 | Example: |
|---|
| 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 | Â Â Â |
|---|