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