source: branches/gui/eml/controllers/PIDIncr.mso @ 609

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

Sample Flowsheet working with the new interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.5 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: PIDIncr.mso 560 2008-07-23 17:13:20Z rafael $
17*-------------------------------------------------------------------*#
18using "types";
19
20Model MPorts
21
[294]22ATTRIBUTES
23        Pallete         = false;
24        Brief           = "Model of Ports to be used with incremental PIDs.";
[295]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       
[294]36        ATTRIBUTES
37        Pallete         = false;
38        Brief           = "Model of Internal Variables to be used with incremental PIDs.";
[295]39       
[1]40        VARIABLES
41
[176]42        dderivTerm    as control_signal (Brief="Derivative term",Unit='1/s', Default=0);
43        dFilt         as control_signal (Brief="Derivative term filtered", Default=0.5,Unit='1/s');
44        error         as control_signal (Brief="Error definition for proportional term",Unit='1/s');
45        errorD        as control_signal (Brief="Error definition for derivative term",Unit='1/s');
[1]46        errorI        as control_signal (Brief="Error definition for integral term");
47        inputFilt     as control_signal (Brief="Filtered input");
[176]48        dintTerm      as control_signal (Brief="Integral term", Default=0,Unit='1/s');
49        doutp         as control_signal (Brief="Sum of proportional, integral and derivative terms",Unit='1/s');
[1]50        outps         as control_signal (Brief="Variable outp scaled between -1 and 1");
51        outp          as control_signal (Brief="Variable outp");
[176]52        dpropTerm     as control_signal (Brief="Proportional term", Default=0,Unit='1/s');
[1]53        setPointFilt  as control_signal (Brief="Filtered setPoint", Default=0);
54
55end
56
[294]57Model PIDIncr
[1]58
[294]59ATTRIBUTES
60        Pallete         = true;
[306]61        Icon            = "icon/PIDIncr";
[294]62        Brief           = "Model of incremental PIDs.";
63        Info            =
[354]64"== Inputs ==
65* scaled processs variable.
66* scaled bias.
67* scaled setpoint.
[294]68
[354]69== Outputs ==
70* a scaled output.
71";
[294]72       
73        PARAMETERS
74       
75        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");
[555]76        Action     as Switcher (Brief="Controller action", Valid=["Direct","Reverse"], Default = "Reverse");
77        Mode       as Switcher (Brief="Controller mode", Valid=["Automatic","Manual"], Default = "Automatic");
78        Clip       as Switcher (Brief="Controller mode", Valid=["Clipped","Unclipped"], Default = "Clipped");
[294]79       
[555]80        alpha      as positive (Brief="Derivative term filter constant", Default=1);
81        beta       as positive (Brief="Proportional term setPoint change filter");
82        bias       as control_signal (Brief="Previous scaled bias", Default=0.5);
83        derivTime  as time_sec (Brief="Derivative time constant");
84        intTime    as time_sec (Brief="Integral time constant");
85        gain       as positive (Brief="Controller gain", Default=0.5);
86        gamma      as positive (Brief="Derivative term SP change filter");
87        tau        as time_sec (Brief="Input filter time constant");
88        tauSet     as time_sec (Brief="Input filter time constant");
89       
[1]90        VARIABLES
91        Internal           as MInternal_Variables;
92        Ports              as MPorts;
[555]93        AWFactor     as Real(Brief="Integral term multiplier used in anti-reset windup", Hidden=true);
94        action       as Real(Hidden=true);
[1]95       
96        EQUATIONS
97
[560]98        if (tau < 1e-6) then
[1]99                "Input first order filter"
[555]100                (tau + 1e-3*'s')*diff(Internal.inputFilt)= Ports.input - Internal.inputFilt;
[1]101        else
102                "Input first order filter"
[555]103                tau*diff(Internal.inputFilt)= Ports.input - Internal.inputFilt;
[1]104        end
105
[560]106        if (tauSet < 1e-6) then
[1]107                "setPoint first order filter"
[555]108                (tauSet + 1e-3*'s')*diff(Internal.setPointFilt)= Ports.setPoint - Internal.setPointFilt;
[1]109        else
110                "setPoint first order filter"
[555]111                tauSet*diff(Internal.setPointFilt)= Ports.setPoint - Internal.setPointFilt;
[1]112        end
113
[555]114        switch Mode
115        case "Manual":
[1]116                "Error definition for proportional term"
[555]117                Internal.error*'s' = Internal.inputFilt*(beta-1.0);
[1]118                "Error definition for derivative term"
[555]119                Internal.errorD*'s'= Internal.inputFilt*(gamma-1.0);
[1]120                "Error definition for integral term"           
121                Internal.errorI= 0;
[555]122        case "Automatic":
[1]123                "Error definition for proportional term"                       
[555]124                Internal.error = beta*diff(Internal.setPointFilt) - diff(Internal.inputFilt);
[1]125                "Error definition for derivative term"
[555]126                Internal.errorD = gamma*diff(Internal.setPointFilt) - diff(Internal.inputFilt);
[1]127                "Error definition for integral term"
128                Internal.errorI = Internal.setPointFilt-Internal.inputFilt;     
129        end
130       
131        "Calculate proportional term"
132        Internal.dpropTerm=Internal.error; 
133       
[555]134        if (derivTime equal 0) then
[1]135                "Derivative term filter"       
[555]136                alpha*(derivTime + 1e-3*'s')*diff(Internal.dFilt) = Internal.errorD - Internal.dFilt;
[1]137        else
138                "Derivative term filter"       
[555]139                alpha*(derivTime)*diff(Internal.dFilt) = Internal.errorD - Internal.dFilt;
[1]140        end
141
142        "Calculate derivative term"
[555]143        Internal.dderivTerm = derivTime*diff(Internal.dFilt);
[1]144       
145    "Unscaled output"
146        diff(Internal.outp)=Internal.doutp;
147
148        "Scale outp"
149        Internal.outps=2*Internal.outp-1;
150
[555]151        switch Clip
152        case "Clipped":
[560]153                #if abs(Internal.outps)>1 then
154                #       "Calculate clipped output when it's saturated"
155                #       Ports.output=(sign(Internal.outps)*1+1)/2;
156                #else
157                #       "Calculate clipped output when it's not saturated"
158                #       Ports.output=Internal.outps;
159                #end
160                Ports.output = max([0, Internal.outp]);
[555]161        case "Unclipped":
[1]162                "Calculate unclipped output"
163                Ports.output=Internal.outp;
164        end
[555]165       
166        switch Action
167        case "Direct":
[558]168                action = -1.0;
169        case "Reverse":
[555]170                action = 1.0;
171        end
[1]172
[294]173switch PID_Select
[1]174       
[294]175case "Ideal":
[1]176       
177        "Calculate integral term"
[555]178        intTime*Internal.dintTerm = Internal.errorI;
[1]179       
180        "Sum of proportional, integral and derivative terms"
[555]181        Internal.doutp = action*gain*(Internal.dpropTerm + Internal.dintTerm + Internal.dderivTerm);
[1]182
[294]183        "Calculate AWFactor - Not in use in this mode"
184        AWFactor=1;
[1]185       
[294]186case "Parallel":
[1]187       
188        "Calculate integral term"
[555]189        intTime*Internal.dintTerm = Internal.errorI;   
[1]190       
191        "Sum of proportional, integral and derivative terms"
[555]192        Internal.doutp = action*(gain*Internal.dpropTerm + Internal.dintTerm + Internal.dderivTerm);
[1]193
[294]194"Calculate AWFactor - Not in use in this mode"
195        AWFactor=1;
[1]196       
[294]197case "Series":
198       
[1]199        "Calculate integral term"
[555]200        intTime*Internal.dintTerm = Internal.errorI;   
[1]201       
202        "Sum of proportional, integral and derivative terms"
[555]203        Internal.doutp = action*(gain*(Internal.dpropTerm + Internal.dintTerm)*(1/'s' + Internal.dderivTerm)*'s');
[1]204       
[294]205        "Calculate AWFactor - Not in use in this mode"
206        AWFactor=1;
[1]207       
[294]208case "Ideal_AWBT":
[1]209       
210        "Calculate integral term with anti-windup and bumpless transfer"
[555]211        action*gain*(intTime*Internal.dintTerm-Internal.errorI) = Ports.output-Internal.outp;
[1]212
213        "Sum of proportional, integral and derivative terms"
[555]214        Internal.doutp = action*gain*(Internal.dpropTerm + Internal.dintTerm + Internal.dderivTerm);
[1]215
[294]216        "Calculate AWFactor - Not in use in this mode"
217        AWFactor=1;
[1]218       
[294]219case "Parallel_AWBT":
[1]220       
221        "Calculate integral term with anti-windup and bumpless transfer"
[555]222        action*gain*(intTime*Internal.dintTerm-Internal.errorI) = Ports.output-Internal.outp;
[1]223       
224        "Sum of proportional, integral and derivative terms"
[555]225        Internal.doutp = action*(gain*Internal.dpropTerm + Internal.dintTerm + Internal.dderivTerm);
[1]226
[294]227"Calculate AWFactor - Not in use in this mode"
228        AWFactor=1;
[1]229
[294]230case "Series_AWBT":
[1]231       
232        "Calculate integral term with anti-windup and bumpless transfer"
[555]233        action*gain*(intTime*Internal.dintTerm-Internal.errorI) = Ports.output-Internal.outp;
[1]234
235        "Sum of proportional, integral and derivative terms"
[555]236        Internal.doutp = action*(gain*(Internal.dpropTerm + Internal.dintTerm)*(1/'s' + Internal.dderivTerm)*'s');
[1]237
[294]238"Calculate AWFactor - Not in use in this mode"
239        AWFactor=1;
[1]240       
[294]241case "Ideal_AW":
242       
[1]243        "Calculate integral term with anti-windup"
[555]244        intTime*Internal.dintTerm = AWFactor*Internal.errorI;
[1]245       
246        "Sum of proportional, integral and derivative terms"
[555]247        Internal.doutp = action*gain*(Internal.dpropTerm + Internal.dintTerm + Internal.dderivTerm);
[1]248       
[555]249        if abs(Internal.outps)>1 and (action*sign(Internal.outps)*Internal.errorI)>0 then
[1]250                "Calculate AWFactor"
251                AWFactor=-tanh(sign(Internal.outps)*Internal.outps*100-102);
252        else
253                "Calculate AWFactor"
254                AWFactor=1;
255        end
256
[294]257case "Parallel_AW":
[1]258       
259        "Calculate integral term with anti-windup"
[555]260        intTime*Internal.dintTerm = AWFactor*Internal.errorI;
[1]261       
262        "Sum of proportional, integral and derivative terms"
[555]263        Internal.doutp = action*(gain*Internal.dpropTerm + Internal.dintTerm + Internal.dderivTerm);
[1]264       
[555]265        if abs(Internal.outps)>1 and (action*sign(Internal.outps)*Internal.errorI)>0 then
[1]266                "Calculate AWFactor"
267                AWFactor=-tanh(sign(Internal.outps)*Internal.outps*100-102);
268        else
269                "Calculate AWFactor"
270                AWFactor=1;
271        end
272
[294]273case "Series_AW":
[1]274       
275        "Calculate integral term with anti-windup"
[555]276        intTime*Internal.dintTerm = AWFactor*Internal.errorI;
[1]277       
278        "Sum of proportional, integral and derivative terms"
[555]279        Internal.doutp = action*(gain*(Internal.dpropTerm + Internal.dintTerm)*(1/'s' + Internal.dderivTerm)*'s');
[1]280       
[555]281        if abs(Internal.outps)>1 and (action*sign(Internal.outps)*Internal.errorI)>0 then
[1]282                "Calculate AWFactor"
283                AWFactor=-tanh(sign(Internal.outps)*Internal.outps*100-102);
284        else
285                "Calculate AWFactor"
286                AWFactor=1;
287        end
288
289end
290
[294]291        INITIAL
[555]292        Ports.output = bias;   
[294]293        diff(Internal.dFilt) = 0/'s^2';
294        diff(Internal.inputFilt)=0/'s';
295        diff(Internal.setPointFilt)=0/'s';
296       
297end
Note: See TracBrowser for help on using the repository browser.