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

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