source: branches/gui/eml/controllers/PIDs.mso @ 577

Last change on this file since 577 was 558, checked in by Rafael de Pelegrini Soares, 15 years ago

Added some simple PI controllers and another signal models

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.8 KB
RevLine 
[1]1#*-------------------------------------------------------------------
[74]2* EMSO Model Library (EML) Copyright (C) 2004 - 2007 ALSOC.
3*
4* This LIBRARY is free software; you can distribute it and/or modify
5* it under the therms of the ALSOC FREE LICENSE as available at
6* http://www.enq.ufrgs.br/alsoc.
7*
8* EMSO Copyright (C) 2004 - 2007 ALSOC, original code
9* from http://www.rps.eng.br Copyright (C) 2002-2004.
10* All rights reserved.
11*
12* EMSO is distributed under the therms of the ALSOC LICENSE as
13* available at http://www.enq.ufrgs.br/alsoc.
[1]14*--------------------------------------------------------------------
15* Author: Tiago Osório
16* $Id: PIDs.mso 558 2008-07-21 20:41:41Z rafael $
17*-------------------------------------------------------------------*#
18using "types";
19
20Model MPorts
21
[295]22ATTRIBUTES
23        Pallete         = false;
24        Brief           = "Model of Ports to be used with PIDs.";
25       
[1]26        VARIABLES
27       
28        input      as control_signal (Brief="Previous scaled input signal", Default=0.5);
29        output     as control_signal (Brief="Scaled output signal", Default=0.5);
30        setPoint   as control_signal (Brief="Scaled setPoint",Default=0.5);
31
32end
33
34Model MInternal_Variables
35       
[295]36        ATTRIBUTES
37        Pallete         = false;
38        Brief           = "Model of Internal Variables to be used with PIDs.";
39       
[1]40        VARIABLES
41
42        derivTerm  as control_signal (Brief="Derivative term", Default=0);
43        dFilt      as control_signal (Brief="Derivative term filtered", Default=0.5);
44        error      as control_signal (Brief="Error definition for proportional term");
45        errorD     as control_signal (Brief="Error definition for derivative term");
46        errorI     as control_signal (Brief="Error definition for integral term");
47        inputFilt  as control_signal (Brief="Filtered input");
48        intTerm    as control_signal (Brief="Integral term", Default=0);
49        outp       as control_signal (Brief="Sum of proportional, integral and derivative terms");
50        outps      as control_signal (Brief="Variable outp scaled between -1 and 1");
51        propTerm   as control_signal (Brief="Proportional term", Default=0);
52        setPointFilt  as control_signal (Brief="Filtered setPoint", Default=0);
53
54end
55
[295]56Model PID
[1]57
[295]58ATTRIBUTES
[558]59        Pallete         = false;
[306]60        Icon            = "icon/PID";
[295]61        Brief           = "Model of PIDs.";
62        Info            =
[354]63"== Inputs ==
64* scaled processs variable.
65* scaled bias.
66* scaled setpoint.
[295]67
[354]68== Outputs ==
69* scaled output.
70";
[295]71       
72        PARAMETERS
[558]73        PID_Select as Switcher (Brief="Type of PID Incremental", Valid=["Ideal","Parallel","Series","Ideal_AWBT","Parallel_AWBT","Series_AWBT","Ideal_AW","Parallel_AW","Series_AW"], Default = "Ideal");
74        Action     as Switcher (Brief="Controller action", Valid=["Direct","Reverse"], Default = "Reverse");
75        Mode       as Switcher (Brief="Controller mode", Valid=["Automatic","Manual"], Default = "Automatic");
76        Clip       as Switcher (Brief="Controller mode", Valid=["Clipped","Unclipped"], Default = "Clipped");
77
78        alpha      as positive (Brief="Derivative term filter constant", Default=1);
79        beta       as positive (Brief="Proportional term setPoint change filter");
80        bias       as control_signal (Brief="Previous scaled bias", Default=0.5);
81        derivTime  as time_sec (Brief="Derivative time constant");
82        intTime    as time_sec (Brief="Integral time constant");
83        gain       as positive (Brief="Controller gain", Default=0.5);
84        gamma      as positive (Brief="Derivative term SP change filter");
85        tau        as time_sec (Brief="Input filter time constant");
86        tauSet     as time_sec (Brief="Input filter time constant");
[295]87       
[1]88        VARIABLES
89        Internal           as MInternal_Variables;
90        Ports              as MPorts;
[295]91        AWFactor     as Real     (Brief="Integral term multiplier used in anti-reset windup");
[558]92        action       as Real(Protected=true);
[1]93       
[295]94        INITIAL
95        Internal.intTerm = 0;
96        diff(Internal.dFilt) = 0/'s';
97        diff(Internal.inputFilt) = 0/'s';
98        diff(Internal.setPointFilt) = 0/'s';
99       
[1]100        EQUATIONS
101
[558]102        if (tau equal 0) then
[1]103                "Input first order filter"
[558]104                (tau + 1e-3*'s')*diff(Internal.inputFilt)= Ports.input - Internal.inputFilt;
[1]105        else
106                "Input first order filter"
[558]107                tau*diff(Internal.inputFilt)= Ports.input - Internal.inputFilt;
[1]108        end
109
[558]110        if (tauSet equal 0) then
[1]111                "setPoint first order filter"
[558]112                (tauSet + 1e-3*'s')*diff(Internal.setPointFilt)= Ports.setPoint - Internal.setPointFilt;
[1]113        else
114                "setPoint first order filter"
[558]115                tauSet*diff(Internal.setPointFilt)= Ports.setPoint - Internal.setPointFilt;
[1]116        end
117       
[558]118        switch Mode
119        case "Manual":
[1]120                "Error definition for proportional term"
[558]121                Internal.error = Internal.inputFilt*(beta-1.0);
[1]122                "Error definition for derivative term"
[558]123                Internal.errorD= Internal.inputFilt*(gamma-1.0);
[1]124                "Error definition for integral term"           
125                Internal.errorI= 0;
[558]126        case "Automatic":
[1]127                "Error definition for proportional term"                       
[558]128                Internal.error = beta*Internal.setPointFilt - Internal.inputFilt;
[1]129                "Error definition for derivative term"
[558]130                Internal.errorD = gamma*Internal.setPointFilt - Internal.inputFilt;
[1]131                "Error definition for integral term"
132                Internal.errorI = Internal.setPointFilt-Internal.inputFilt;
133        end
134       
135        "Calculate proportional term"
136        Internal.propTerm=Internal.error;
137       
[558]138        if (derivTime equal 0) then
[1]139                "Derivative term filter"       
[558]140                alpha*(derivTime + 1e-3*'s')*diff(Internal.dFilt) = Internal.errorD - Internal.dFilt;
[1]141        else
142                "Derivative term filter"       
[558]143                alpha*(derivTime)*diff(Internal.dFilt) = Internal.errorD - Internal.dFilt;
[1]144        end
145
146        "Calculate derivative term"
[558]147        Internal.derivTerm = derivTime*diff(Internal.dFilt);
[1]148       
149        "Scale outp"
150        Internal.outps=2*Internal.outp-1;
151       
[558]152        switch Clip
153        case "Clipped":
[1]154                if abs(Internal.outps)>1 then
155                        "Calculate clipped output when it´s saturated"
156                        Ports.output=(sign(Internal.outps)*1+1)/2;
157                else
158                        "Calculate clipped output when it´s not saturated"
159                        Ports.output=Internal.outp;
160                end
[558]161        case "Unclipped":
[1]162                "Calculate unclipped output"
163                Ports.output=Internal.outp;
164        end
165
[558]166        switch Action
167        case "Direct":
168                action = -1.0;
169        case "Reverse":
170                action = 1.0;
171        end
172
173
[295]174switch PID_Select
[1]175       
[295]176case "Ideal_AW":
[1]177       
178        "Calculate integral term with anti-windup"
[558]179        intTime*diff(Internal.intTerm) = AWFactor*Internal.errorI;
[1]180       
181        "Sum of proportional, integral and derivative terms"
[558]182        Internal.outp = bias + action*gain*(Internal.propTerm + Internal.intTerm + Internal.derivTerm);
[1]183
[558]184        if abs(Internal.outps)>1 and (action*sign(Internal.outps)*Internal.errorI)>0 then
[1]185                "Calculate AWFactor"
186                AWFactor=-tanh(sign(Internal.outps)*Internal.outps*100-102);
187        else
188                "Calculate AWFactor"
189                AWFactor=1;
190        end
191
[295]192case "Parallel_AW":
[1]193       
194        "Calculate integral term with anti-windup"
[558]195        intTime*diff(Internal.intTerm) = AWFactor*Internal.errorI;
[1]196       
197        "Sum of proportional, integral and derivative terms"
[558]198        Internal.outp = bias + action*(gain*Internal.propTerm + Internal.intTerm + Internal.derivTerm);
[1]199
[558]200        if abs(Internal.outps)>1 and (action*sign(Internal.outps)*Internal.errorI)>0 then
[1]201                "Calculate AWFactor"
202                AWFactor=-tanh(sign(Internal.outps)*Internal.outps*100-102);
203        else
204                "Calculate AWFactor"
205                AWFactor=1;
206        end
207
[295]208
209case "Series_AW":
210
[1]211        "Calculate integral term with anti-windup"     
[558]212        intTime*diff(Internal.intTerm) = AWFactor*Internal.errorI;
[1]213       
214        "Sum of proportional, integral and derivative terms"
[558]215        Internal.outp = bias + action*(gain*(Internal.propTerm + Internal.intTerm)*(1 + Internal.derivTerm));
[1]216
[558]217        if abs(Internal.outps)>1 and (action*sign(Internal.outps)*Internal.errorI)>0 then
[1]218                "Calculate AWFactor"           
219                AWFactor=-tanh(sign(Internal.outps)*Internal.outps*100-102);
220        else
221                "Calculate AWFactor"
222                AWFactor=1;
223        end
224
[295]225case "Ideal":
[1]226       
227        "Calculate integral term"       
[558]228        intTime*diff(Internal.intTerm) = Internal.errorI;
[1]229       
230        "Sum of proportional, integral and derivative terms"   
[558]231        Internal.outp = bias + action*gain*(Internal.propTerm + Internal.intTerm + Internal.derivTerm);
[1]232
[295]233        "Calculate AWFactor - Not in use in this mode"
234        AWFactor=1;
[1]235       
[295]236case "Parallel":
[1]237       
238        "Calculate integral term"       
[558]239        intTime*diff(Internal.intTerm) = Internal.errorI;
[1]240       
241        "Sum of proportional, integral and derivative terms"   
[558]242        Internal.outp = bias + action*(gain*Internal.propTerm + Internal.intTerm + Internal.derivTerm);
[1]243
[295]244        "Calculate AWFactor - Not in use in this mode"
245        AWFactor=1;
[1]246       
[295]247case "Series":
[1]248       
249        "Calculate integral term"       
[558]250        intTime*diff(Internal.intTerm) = Internal.errorI;
[1]251       
252        "Sum of proportional, integral and derivative terms"
[558]253        Internal.outp = bias + action*(gain*(Internal.propTerm + Internal.intTerm)*(1 + Internal.derivTerm));
[1]254       
[295]255        "Calculate AWFactor - Not in use in this mode"
256        AWFactor=1;
[1]257       
[295]258case "Ideal_AWBT":
259       
[1]260        "Calculate integral term with anti-windup and bumpless transfer"       
[558]261        action*gain*(intTime*diff(Internal.intTerm)-Internal.errorI) = Ports.output-Internal.outp;     
[1]262       
263        "Sum of proportional, integral and derivative terms"   
[558]264        Internal.outp = bias + action*gain*(Internal.propTerm + Internal.intTerm + Internal.derivTerm);
[1]265       
[295]266        "Calculate AWFactor - Not in use in this mode"
267        AWFactor=1;
[1]268       
[295]269case "Parallel_AWBT":
270       
[1]271        "Calculate integral term with anti-windup and bumpless transfer"       
[558]272        action*gain*(intTime*diff(Internal.intTerm)-Internal.errorI) = Ports.output-Internal.outp;     
[1]273       
274        "Sum of proportional, integral and derivative terms"   
[558]275        Internal.outp = bias + action*(gain*Internal.propTerm + Internal.intTerm + Internal.derivTerm);
[1]276       
[295]277        "Calculate AWFactor - Not in use in this mode"
278        AWFactor=1;
[1]279       
[295]280case "Series_AWBT":
281       
[1]282        "Calculate integral term with anti-windup and bumpless transfer"
[558]283        action*gain*(intTime*diff(Internal.intTerm)-Internal.errorI) = Ports.output-Internal.outp;     
[1]284       
285        "Sum of proportional, integral and derivative terms"
[558]286        Internal.outp = bias + action*(gain*(Internal.propTerm + Internal.intTerm)*(1 + Internal.derivTerm));
[1]287
[295]288        "Calculate AWFactor - Not in use in this mode"
289        AWFactor=1;
290       
[1]291end
[295]292
293end
[558]294
295
296Model PID_gui as PID
297        ATTRIBUTES
298        Pallete         = true;
299        Icon            = "icon/PIDIncr";
300
301        PARAMETERS
302        MinInput as control_signal(Default=-1000);
303        MaxInput as control_signal(Default=1000);
304       
305        VARIABLES
306in      Input as control_signal(Protected=true, PosX=0, PosY=0.5);
307out     Output as control_signal(Protected=true, PosX=1, PosY=0.5);
308        SetPoint as control_signal;
309       
310        EQUATIONS
311        Ports.input*(MaxInput - MinInput) = Input - MinInput;
312        Ports.output = Output;
313        Ports.setPoint*(MaxInput - MinInput) = SetPoint - MinInput;
314end
315
316Model FirstOrder
317        ATTRIBUTES
318        Pallete         = true;
319        Icon            = "icon/PIDIncr";
320
321        PARAMETERS
322        tau    as Real (Brief="Time Constant", Unit = 's', Default=4);
323        A      as Real (Unit='1/s');
324        B      as Real (Unit='1/s');
325        C      as Real;
326        D      as Real(Default=0);
327
328        VARIABLES
329        x as control_signal(Brief="State");
330in      u as control_signal(Brief="Input signal", PosX=0, PosY=0.5);
331out     y as control_signal(Brief="Output signal", PosX=1, PosY=0.5);
332
333        EQUATIONS
334        diff(x) = A*x + B*u;
335        y = C*x + D*u;
336end
337
338
339Model StepSignal
340        ATTRIBUTES
341        Pallete         = true;
342        Icon            = "icon/PIDIncr";
343
344        PARAMETERS
345        StepTime as positive(Unit='s');
346        StartValue as control_signal;
347        FinalValue as control_signal;
348       
349        VARIABLES
350out     OutSignal as control_signal(PosX=1, PosY=0.5);
351
352        EQUATIONS
353        if(time < StepTime) then
354                OutSignal = StartValue;
355        else
356                OutSignal = FinalValue;
357        end
358end
359
360Model ConstantSignal
361        ATTRIBUTES
362        Pallete         = true;
363        Icon            = "icon/PIDIncr";
364
365        PARAMETERS
366        Value as control_signal;
367       
368        VARIABLES
369out     OutSignal as control_signal(PosX=1, PosY=0.5);
370
371        EQUATIONS
372        OutSignal = Value;
373end
Note: See TracBrowser for help on using the repository browser.