AutotunerPID Toolkit | ![]() ![]() |
PID_ISATD Discrete time ISA-PID (implemented as an S-function) The PID closely resemble the structure of a real industrial PID and has the following features: - filter on the derivative action - set-point weight (but not the weight of the derivative action which is fixed to 0) - antiwindup on lower and higher saturation limits of the actuator - bumpless auto-manual switch It also implements the logic to perform the identification experiment: - step response identification (with user-defined step amplitude) - relay identification (with user-defined relay amplitude and hysteresis level) Author: William Spinelli (wspinell@elet.polimi.it) Copyright 2004 W.Spinelli $Revision: 1.0 $ $Date: 2004/02/27 12:00:00 $
0001 function [sys,x0,str,ts] = pid_isatd(t,x,u,flag,Ts,umin,umax,As,hystLevel) 0002 %PID_ISATD Discrete time ISA-PID (implemented as an S-function) 0003 % 0004 % The PID closely resemble the structure of a real industrial PID and has 0005 % the following features: 0006 % - filter on the derivative action 0007 % - set-point weight (but not the weight of the derivative action which 0008 % is fixed to 0) 0009 % - antiwindup on lower and higher saturation limits of the actuator 0010 % - bumpless auto-manual switch 0011 % 0012 % It also implements the logic to perform the identification experiment: 0013 % - step response identification (with user-defined step amplitude) 0014 % - relay identification (with user-defined relay amplitude and 0015 % hysteresis level) 0016 % 0017 % Author: William Spinelli (wspinell@elet.polimi.it) 0018 % Copyright 2004 W.Spinelli 0019 % $Revision: 1.0 $ $Date: 2004/02/27 12:00:00 $ 0020 0021 persistent stato; % internal state variable 0022 0023 CVBlock = 'ManValue'; 0024 switch flag, 0025 case 0, 0026 [sys,x0,str,ts,stato] = mdlInitializeSizes(Ts); 0027 case 3, 0028 [sys,stato] = mdlOutputs(t,x,u,stato,Ts,umin,umax,As,hystLevel); 0029 case { 1, 2, 4, 9 } 0030 sys=[]; 0031 otherwise 0032 error(['Unhandled flag = ', num2str(flag)]); 0033 end 0034 % end pid_isatd 0035 0036 0037 %============================================================================= 0038 % mdlInitializeSizes 0039 % Return the sizes, initial conditions, and sample times for the S-function. 0040 %============================================================================= 0041 function [sys,x0,str,ts,stato] = mdlInitializeSizes(Ts) 0042 % set up S-function 0043 sizes = simsizes; 0044 0045 sizes.NumContStates = 0; 0046 sizes.NumDiscStates = 0; 0047 sizes.NumOutputs = 1; 0048 sizes.NumInputs = 4; 0049 sizes.DirFeedthrough = 1; 0050 sizes.NumSampleTimes = 1; % at least one sample time is needed 0051 0052 sys = simsizes(sizes); 0053 0054 x0 = []; 0055 str = []; 0056 ts = [Ts 0]; 0057 stato = [0 0 0 0 0]; 0058 % end mdlInitializeSizes 0059 0060 %============================================================================= 0061 % mdlOutputs 0062 % Return the block outputs. 0063 %============================================================================= 0064 function [sys,stato] = mdlOutputs(t,x,u,stato,Ts,umin,umax,As,hystLevel) 0065 global CVVALUE % control variable (used for M/A commutation) 0066 global IDENTIFICATION_METHOD 0067 global TUNING_METHOD 0068 global PIDPARAMETERS 0069 0070 % measured signals 0071 sp = u(1); % setpoint value 0072 pv = u(2); % process value 0073 0074 % control signals 0075 auto = u(3); % auto/man switch (MANUAL=0; AUTO=1) 0076 autotune = u(4); % true when autotuning 0077 0078 % PID parameters (c=0) 0079 K = PIDPARAMETERS(1); 0080 Ti = PIDPARAMETERS(2); 0081 Td = PIDPARAMETERS(3); 0082 N = PIDPARAMETERS(4); 0083 b = PIDPARAMETERS(5); 0084 0085 % translation of the vector stato (for simplicity) 0086 % state variable 0087 ui = stato(1); % integral action 0088 ud = stato(2); % derivative action (filter) 0089 0090 % auxiliary variable 0091 pvold = stato(3); % old process value 0092 cvold = stato(4); % old control variable 0093 atold = stato(5); % old autotune state (to ensure bumpless switch) 0094 0095 % PID algorithm 0096 % compute the constants (made each time since PID parameters may change) 0097 if Ti 0098 a1 = K*Ts/Ti; 0099 else 0100 % when Ti = 0 turn off the integral action 0101 a1 = 0; 0102 end 0103 b1 = Td/(Td + N*Ts); 0104 b2 = K*Td*N/(Td + N*Ts); 0105 0106 % compute control actions 0107 up = K*(b*sp - pv); 0108 0109 ud = b1*ud - b2*(pv-pvold); 0110 0111 if ~autotune & atold 0112 % ensure bumpless switch after a change in the regulator parameters 0113 ui = cvold - up - ud; 0114 end 0115 0116 if autotune 0117 if strcmp(IDENTIFICATION_METHOD,'STEP') 0118 % increment the value of the control variable 0119 cv = CVVALUE+As; 0120 elseif strcmp(IDENTIFICATION_METHOD,'RELAY') 0121 if ~atold 0122 cv = CVVALUE+As; 0123 else 0124 if pv >= sp+hystLevel 0125 cv = CVVALUE-As; 0126 elseif pv <= sp-hystLevel 0127 cv = CVVALUE+As; 0128 else 0129 cv = cvold; 0130 end 0131 end 0132 end 0133 else 0134 if ~auto 0135 % manual mode 0136 cv = CVVALUE; 0137 else 0138 % automatic regulation 0139 cv = up + ui + ud; 0140 end 0141 0142 if cv > umax 0143 % saturation on maximum value (note that the state of the integrator is 0144 % not updated) 0145 cv = umax; 0146 elseif cv < umin 0147 % saturation on minimum value 0148 cv = umin; 0149 else 0150 % update the state of the integrator 0151 if auto 0152 ui = ui + a1*(sp-pv); 0153 else 0154 ui = cv - up - ud; 0155 end 0156 end 0157 % update control variable value 0158 CVVALUE = cv; 0159 end 0160 0161 % update internal state vector 0162 stato = [ui ud pv cv autotune]; 0163 % generate control variable 0164 sys = cv; 0165 % end mdlOutputs
![]() | pid_autotuner | pid_structure | ![]() |