[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 909 2010-02-19 21:08:11Z arge $ |
---|
| 17 | *-------------------------------------------------------------------*# |
---|
| 18 | using "types"; |
---|
| 19 | |
---|
| 20 | |
---|
[683] | 21 | Model PID |
---|
| 22 | |
---|
[295] | 23 | ATTRIBUTES |
---|
[683] | 24 | Pallete = true; |
---|
| 25 | Icon = "icon/PID"; |
---|
[1] | 26 | |
---|
[683] | 27 | PARAMETERS |
---|
[1] | 28 | |
---|
[683] | 29 | 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"); |
---|
[909] | 30 | Action as Switcher (Brief="Controller action", Valid=["Direct","Reverse"], Default = "Reverse"); |
---|
| 31 | Mode as Switcher (Brief="Controller mode", Valid=["Automatic","Manual"], Default = "Automatic"); |
---|
| 32 | Clip as Switcher (Brief="Controller mode", Valid=["Clipped","Unclipped"], Default = "Clipped"); |
---|
[683] | 33 | |
---|
[909] | 34 | alpha as positive (Brief="Derivative term filter constant", Default=1); |
---|
| 35 | beta as positive (Brief="Proportional term setPoint change filter"); |
---|
| 36 | bias as control_signal (Brief="Previous scaled bias", Default=0.5); |
---|
| 37 | derivTime as time_sec (Brief="Derivative time constant"); |
---|
| 38 | intTime as time_sec (Brief="Integral time constant"); |
---|
| 39 | gain as positive (Brief="Controller gain", Default=0.5); |
---|
| 40 | gamma as positive (Brief="Derivative term SP change filter"); |
---|
| 41 | tau as time_sec (Brief="Input filter time constant"); |
---|
| 42 | tauSet as time_sec (Brief="Input filter time constant"); |
---|
| 43 | MinInput as control_signal (Default=0); |
---|
[683] | 44 | MaxInput as control_signal (Default=1000); |
---|
[909] | 45 | MinOutput as control_signal (Default=0); |
---|
| 46 | MaxOutput as control_signal (Default=1); |
---|
| 47 | |
---|
[683] | 48 | VARIABLES |
---|
[909] | 49 | in Input as control_signal (Protected=true, PosX=0, PosY=0.5); |
---|
| 50 | out Output as control_signal (Protected=true, PosX=0.54, PosY=1); |
---|
| 51 | SetPoint as control_signal; |
---|
[683] | 52 | |
---|
| 53 | #++++++++++++++++++++ PID Internal Variables ++++++++++++++++++++++++++++++++ |
---|
| 54 | PID_derivTerm as control_signal (Brief="Derivative term", Hidden =true , Default=0); |
---|
[909] | 55 | PID_dFilt as control_signal (Brief="Derivative term filtered", Hidden =true ,Default=0.5); |
---|
| 56 | PID_error as control_signal (Brief="Error definition for proportional term",Hidden =true ); |
---|
[683] | 57 | PID_errorD as control_signal (Brief="Error definition for derivative term", Hidden =true ); |
---|
[909] | 58 | PID_errorI as control_signal (Brief="Error definition for integral term", Hidden =true); |
---|
| 59 | PID_inputFilt as control_signal (Brief="Filtered input", Hidden =true); |
---|
[683] | 60 | PID_intTerm as control_signal (Brief="Integral term", Hidden =true , Default=0); |
---|
[909] | 61 | PID_outp as control_signal (Brief="Sum of proportional, integral and derivative terms", Hidden =true ); |
---|
| 62 | PID_outps as control_signal (Brief="Variable outp scaled between -1 and 1",Hidden =true); |
---|
[683] | 63 | PID_propTerm as control_signal (Brief="Proportional term", Default=0 , Hidden =true ); |
---|
[909] | 64 | PID_setPointFilt as control_signal (Brief="Filtered setPoint", Default=0, Hidden =true); |
---|
| 65 | PID_AWFactor as Real (Brief="Integral term multiplier used in anti-reset windup", Hidden=true); |
---|
| 66 | PID_action as Real (Protected=true, Hidden=true); |
---|
[295] | 67 | |
---|
[683] | 68 | PID_input as control_signal (Brief="Previous scaled input signal", Default=0.5, Hidden=true); |
---|
| 69 | PID_output as control_signal (Brief="Scaled output signal", Default=0.5, Hidden=true); |
---|
[909] | 70 | PID_setPoint as control_signal (Brief="Scaled setPoint",Default=0.5, Hidden=true); |
---|
[683] | 71 | #++++++++++++++++++++++++++++++++++++++++++++++++++++ |
---|
[1] | 72 | |
---|
[683] | 73 | EQUATIONS |
---|
[1] | 74 | |
---|
[683] | 75 | "Input " |
---|
| 76 | PID_input*(MaxInput - MinInput) = Input - MinInput; |
---|
[1] | 77 | |
---|
[683] | 78 | "Output " |
---|
[909] | 79 | Output = PID_output*(MaxOutput - MinOutput) + MinOutput; |
---|
[683] | 80 | |
---|
| 81 | "Set Point " |
---|
| 82 | PID_setPoint*(MaxInput - MinInput) = SetPoint - MinInput; |
---|
[1] | 83 | |
---|
[683] | 84 | INITIAL |
---|
[295] | 85 | |
---|
[683] | 86 | PID_intTerm = 0; |
---|
[295] | 87 | |
---|
[683] | 88 | diff(PID_dFilt) = 0/'s'; |
---|
[295] | 89 | |
---|
[683] | 90 | diff(PID_inputFilt) = 0/'s'; |
---|
[1] | 91 | |
---|
[683] | 92 | diff(PID_setPointFilt) = 0/'s'; |
---|
[295] | 93 | |
---|
[1] | 94 | EQUATIONS |
---|
| 95 | |
---|
[909] | 96 | if (tau < 1e-3*'s') then |
---|
[1] | 97 | "Input first order filter" |
---|
[683] | 98 | (tau + 1e-3*'s')*diff(PID_inputFilt)= PID_input - PID_inputFilt; |
---|
[1] | 99 | else |
---|
| 100 | "Input first order filter" |
---|
[683] | 101 | tau*diff(PID_inputFilt)= PID_input - PID_inputFilt; |
---|
[1] | 102 | end |
---|
| 103 | |
---|
[909] | 104 | if (tauSet < 1e-3*'s') then |
---|
[1] | 105 | "setPoint first order filter" |
---|
[683] | 106 | (tauSet + 1e-3*'s')*diff(PID_setPointFilt)= PID_setPoint - PID_setPointFilt; |
---|
[1] | 107 | else |
---|
| 108 | "setPoint first order filter" |
---|
[683] | 109 | tauSet*diff(PID_setPointFilt)= PID_setPoint - PID_setPointFilt; |
---|
[1] | 110 | end |
---|
| 111 | |
---|
[558] | 112 | switch Mode |
---|
| 113 | case "Manual": |
---|
[1] | 114 | "Error definition for proportional term" |
---|
[683] | 115 | PID_error = PID_inputFilt*(beta-1.0); |
---|
[1] | 116 | "Error definition for derivative term" |
---|
[683] | 117 | PID_errorD= PID_inputFilt*(gamma-1.0); |
---|
[1] | 118 | "Error definition for integral term" |
---|
[683] | 119 | PID_errorI= 0; |
---|
[558] | 120 | case "Automatic": |
---|
[1] | 121 | "Error definition for proportional term" |
---|
[683] | 122 | PID_error = beta*PID_setPointFilt - PID_inputFilt; |
---|
[1] | 123 | "Error definition for derivative term" |
---|
[683] | 124 | PID_errorD = gamma*PID_setPointFilt - PID_inputFilt; |
---|
[1] | 125 | "Error definition for integral term" |
---|
[683] | 126 | PID_errorI = PID_setPointFilt-PID_inputFilt; |
---|
[1] | 127 | end |
---|
| 128 | |
---|
| 129 | "Calculate proportional term" |
---|
[683] | 130 | PID_propTerm=PID_error; |
---|
[1] | 131 | |
---|
[909] | 132 | if (derivTime < 1e-3*'s') then |
---|
[1] | 133 | "Derivative term filter" |
---|
[683] | 134 | alpha*(derivTime + 1e-3*'s')*diff(PID_dFilt) = PID_errorD - PID_dFilt; |
---|
[1] | 135 | else |
---|
| 136 | "Derivative term filter" |
---|
[683] | 137 | alpha*(derivTime)*diff(PID_dFilt) = PID_errorD - PID_dFilt; |
---|
[1] | 138 | end |
---|
| 139 | |
---|
| 140 | "Calculate derivative term" |
---|
[683] | 141 | PID_derivTerm = derivTime*diff(PID_dFilt); |
---|
[1] | 142 | |
---|
| 143 | "Scale outp" |
---|
[683] | 144 | PID_outps=2*PID_outp-1; |
---|
[1] | 145 | |
---|
[558] | 146 | switch Clip |
---|
| 147 | case "Clipped": |
---|
[683] | 148 | if abs(PID_outps)>1 then |
---|
[909] | 149 | "Calculate clipped output when saturated" |
---|
| 150 | PID_output=(sign(PID_outps)+1)/2; |
---|
[1] | 151 | else |
---|
[909] | 152 | "Calculate clipped output when not saturated" |
---|
[683] | 153 | PID_output=PID_outp; |
---|
[1] | 154 | end |
---|
[558] | 155 | case "Unclipped": |
---|
[1] | 156 | "Calculate unclipped output" |
---|
[683] | 157 | PID_output=PID_outp; |
---|
[1] | 158 | end |
---|
| 159 | |
---|
[558] | 160 | switch Action |
---|
| 161 | case "Direct": |
---|
[683] | 162 | PID_action = -1.0; |
---|
[558] | 163 | case "Reverse": |
---|
[683] | 164 | PID_action = 1.0; |
---|
[558] | 165 | end |
---|
| 166 | |
---|
| 167 | |
---|
[295] | 168 | switch PID_Select |
---|
[1] | 169 | |
---|
[295] | 170 | case "Ideal_AW": |
---|
[1] | 171 | |
---|
| 172 | "Calculate integral term with anti-windup" |
---|
[683] | 173 | intTime*diff(PID_intTerm) = PID_AWFactor*PID_errorI; |
---|
[1] | 174 | |
---|
| 175 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 176 | PID_outp = bias + PID_action*gain*(PID_propTerm + PID_intTerm + PID_derivTerm); |
---|
[1] | 177 | |
---|
[683] | 178 | if abs(PID_outps)>1 and (PID_action*sign(PID_outps)*PID_errorI)>0 then |
---|
[1] | 179 | "Calculate AWFactor" |
---|
[683] | 180 | PID_AWFactor=-tanh(sign(PID_outps)*PID_outps*100-102); |
---|
[1] | 181 | else |
---|
| 182 | "Calculate AWFactor" |
---|
[683] | 183 | PID_AWFactor=1; |
---|
[1] | 184 | end |
---|
| 185 | |
---|
[295] | 186 | case "Parallel_AW": |
---|
[1] | 187 | |
---|
| 188 | "Calculate integral term with anti-windup" |
---|
[683] | 189 | intTime*diff(PID_intTerm) = PID_AWFactor*PID_errorI; |
---|
[1] | 190 | |
---|
| 191 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 192 | PID_outp = bias + PID_action*(gain*PID_propTerm + PID_intTerm + PID_derivTerm); |
---|
[1] | 193 | |
---|
[683] | 194 | if abs(PID_outps)>1 and (PID_action*sign(PID_outps)*PID_errorI)>0 then |
---|
[1] | 195 | "Calculate AWFactor" |
---|
[683] | 196 | PID_AWFactor=-tanh(sign(PID_outps)*PID_outps*100-102); |
---|
[1] | 197 | else |
---|
| 198 | "Calculate AWFactor" |
---|
[683] | 199 | PID_AWFactor=1; |
---|
[1] | 200 | end |
---|
| 201 | |
---|
[295] | 202 | |
---|
| 203 | case "Series_AW": |
---|
| 204 | |
---|
[1] | 205 | "Calculate integral term with anti-windup" |
---|
[683] | 206 | intTime*diff(PID_intTerm) = PID_AWFactor*PID_errorI; |
---|
[1] | 207 | |
---|
| 208 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 209 | PID_outp = bias + PID_action*(gain*(PID_propTerm + PID_intTerm)*(1 + PID_derivTerm)); |
---|
[1] | 210 | |
---|
[683] | 211 | if abs(PID_outps)>1 and (PID_action*sign(PID_outps)*PID_errorI)>0 then |
---|
[1] | 212 | "Calculate AWFactor" |
---|
[683] | 213 | PID_AWFactor=-tanh(sign(PID_outps)*PID_outps*100-102); |
---|
[1] | 214 | else |
---|
| 215 | "Calculate AWFactor" |
---|
[683] | 216 | PID_AWFactor=1; |
---|
[1] | 217 | end |
---|
| 218 | |
---|
[295] | 219 | case "Ideal": |
---|
[1] | 220 | |
---|
| 221 | "Calculate integral term" |
---|
[683] | 222 | intTime*diff(PID_intTerm) = PID_errorI; |
---|
[1] | 223 | |
---|
| 224 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 225 | PID_outp = bias + PID_action*gain*(PID_propTerm + PID_intTerm + PID_derivTerm); |
---|
[1] | 226 | |
---|
[295] | 227 | "Calculate AWFactor - Not in use in this mode" |
---|
[683] | 228 | PID_AWFactor=1; |
---|
[1] | 229 | |
---|
[295] | 230 | case "Parallel": |
---|
[1] | 231 | |
---|
| 232 | "Calculate integral term" |
---|
[683] | 233 | intTime*diff(PID_intTerm) = PID_errorI; |
---|
[1] | 234 | |
---|
| 235 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 236 | PID_outp = bias + PID_action*(gain*PID_propTerm + PID_intTerm + PID_derivTerm); |
---|
[1] | 237 | |
---|
[295] | 238 | "Calculate AWFactor - Not in use in this mode" |
---|
[683] | 239 | PID_AWFactor=1; |
---|
[1] | 240 | |
---|
[295] | 241 | case "Series": |
---|
[1] | 242 | |
---|
| 243 | "Calculate integral term" |
---|
[683] | 244 | intTime*diff(PID_intTerm) = PID_errorI; |
---|
[1] | 245 | |
---|
| 246 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 247 | PID_outp = bias + PID_action*(gain*(PID_propTerm + PID_intTerm)*(1 + PID_derivTerm)); |
---|
[1] | 248 | |
---|
[295] | 249 | "Calculate AWFactor - Not in use in this mode" |
---|
[683] | 250 | PID_AWFactor=1; |
---|
[1] | 251 | |
---|
[295] | 252 | case "Ideal_AWBT": |
---|
| 253 | |
---|
[1] | 254 | "Calculate integral term with anti-windup and bumpless transfer" |
---|
[683] | 255 | PID_action*gain*(intTime*diff(PID_intTerm)-PID_errorI) = PID_output-PID_outp; |
---|
[1] | 256 | |
---|
| 257 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 258 | PID_outp = bias + PID_action*gain*(PID_propTerm + PID_intTerm + PID_derivTerm); |
---|
[1] | 259 | |
---|
[295] | 260 | "Calculate AWFactor - Not in use in this mode" |
---|
[683] | 261 | PID_AWFactor=1; |
---|
[1] | 262 | |
---|
[295] | 263 | case "Parallel_AWBT": |
---|
| 264 | |
---|
[1] | 265 | "Calculate integral term with anti-windup and bumpless transfer" |
---|
[683] | 266 | PID_action*gain*(intTime*diff(PID_intTerm)-PID_errorI) = PID_output-PID_outp; |
---|
[1] | 267 | |
---|
| 268 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 269 | PID_outp = bias + PID_action*(gain*PID_propTerm + PID_intTerm + PID_derivTerm); |
---|
[1] | 270 | |
---|
[295] | 271 | "Calculate AWFactor - Not in use in this mode" |
---|
[683] | 272 | PID_AWFactor=1; |
---|
[1] | 273 | |
---|
[295] | 274 | case "Series_AWBT": |
---|
| 275 | |
---|
[1] | 276 | "Calculate integral term with anti-windup and bumpless transfer" |
---|
[683] | 277 | PID_action*gain*(intTime*diff(PID_intTerm)-PID_errorI) = PID_output-PID_outp; |
---|
[1] | 278 | |
---|
| 279 | "Sum of proportional, integral and derivative terms" |
---|
[683] | 280 | PID_outp = bias + PID_action*(gain*(PID_propTerm + PID_intTerm)*(1 + PID_derivTerm)); |
---|
[1] | 281 | |
---|
[295] | 282 | "Calculate AWFactor - Not in use in this mode" |
---|
[683] | 283 | PID_AWFactor=1; |
---|
[295] | 284 | |
---|
[1] | 285 | end |
---|
[295] | 286 | |
---|
| 287 | end |
---|
[558] | 288 | |
---|
| 289 | Model FirstOrder |
---|
| 290 | ATTRIBUTES |
---|
[771] | 291 | Pallete = false; |
---|
[558] | 292 | Icon = "icon/PIDIncr"; |
---|
| 293 | |
---|
| 294 | PARAMETERS |
---|
| 295 | tau as Real (Brief="Time Constant", Unit = 's', Default=4); |
---|
| 296 | A as Real (Unit='1/s'); |
---|
| 297 | B as Real (Unit='1/s'); |
---|
| 298 | C as Real; |
---|
| 299 | D as Real(Default=0); |
---|
| 300 | |
---|
| 301 | VARIABLES |
---|
| 302 | x as control_signal(Brief="State"); |
---|
| 303 | in u as control_signal(Brief="Input signal", PosX=0, PosY=0.5); |
---|
| 304 | out y as control_signal(Brief="Output signal", PosX=1, PosY=0.5); |
---|
| 305 | |
---|
| 306 | EQUATIONS |
---|
| 307 | diff(x) = A*x + B*u; |
---|
| 308 | y = C*x + D*u; |
---|
| 309 | end |
---|
| 310 | |
---|
| 311 | Model StepSignal |
---|
| 312 | ATTRIBUTES |
---|
| 313 | Pallete = true; |
---|
[590] | 314 | Icon = "icon/StepSignal"; |
---|
[558] | 315 | |
---|
| 316 | PARAMETERS |
---|
| 317 | StepTime as positive(Unit='s'); |
---|
| 318 | StartValue as control_signal; |
---|
| 319 | FinalValue as control_signal; |
---|
| 320 | |
---|
| 321 | VARIABLES |
---|
[591] | 322 | out OutSignal as control_signal(PosX=1, PosY=0.5); |
---|
[558] | 323 | |
---|
| 324 | EQUATIONS |
---|
| 325 | if(time < StepTime) then |
---|
| 326 | OutSignal = StartValue; |
---|
| 327 | else |
---|
| 328 | OutSignal = FinalValue; |
---|
| 329 | end |
---|
| 330 | end |
---|
| 331 | |
---|
| 332 | Model ConstantSignal |
---|
| 333 | ATTRIBUTES |
---|
| 334 | Pallete = true; |
---|
[589] | 335 | Icon = "icon/ConstSignal"; |
---|
[558] | 336 | |
---|
| 337 | PARAMETERS |
---|
| 338 | Value as control_signal; |
---|
| 339 | |
---|
| 340 | VARIABLES |
---|
[591] | 341 | out OutSignal as control_signal(PosX=1, PosY=0.5); |
---|
[558] | 342 | |
---|
| 343 | EQUATIONS |
---|
| 344 | OutSignal = Value; |
---|
| 345 | end |
---|