function rsys = remove_positive_numerator_time_constants(sys, tauc) % REMOVE_POSITIVE_NUMERATOR_TIME_CONSTANTS Cancels positive % numerator time constants in LTI models against neighboring denominator % terms in the model by applying the SIMC model reduction rules for such % systems. % % RSYS = REMOVE_POSITIVE_NUMERATOR_TIME_CONSTANTS(SYS, TAUC) returns the % simplified model, RSYS, where SYS is the original process model and TAUC % is the tuning parameter (desired closed-loop time constant). % % See also REDUCE_PLANT_MODEL. % Author(s): Bora Eryilmaz, The MathWorks, Inc. [Z,P] = zpkdata(sys, 'v'); % Positive numerator time constants in decreasing order. Zrealneg = Z(real(Z)<0 & ~imag(Z)); Tj0 = sort(-1./Zrealneg, 'descend'); % Lag time constants in descreasing order. Prealneg = P(real(P)<0 & ~imag(P)); taui0 = sort(-1./Prealneg, 'descend'); % Remove positive numerator time constants. rsys = zpk(sys); for ct = 1:length(Tj0) T0 = Tj0(ct); % Find tau0a & tau0b such that tau0a >= T0 >= tau0b. tau0a = taui0(find(T0 <= taui0,1,'last')); tau0b = taui0(find(T0 >= taui0,1)); % Find closest denominator time constant if isempty(tau0a) && isempty(tau0b) % No denominator term to cancel against. warning('SIMC:incomplete', ... 'Not all positive numerator time constants were removed.') break; elseif isempty(tau0a) || (~isempty(tau0b) && ... ((T0 < sqrt(tau0a*tau0b)) && (T0 < 1.6*tau0b))) % T0/tau0b < tau0a/T0 and T0/tau0b < 1.6 tau0 = tau0b; else tau0 = tau0a; end % Add approximation term and remove lead-lag term from the model. taut0 = []; if (T0 >= tau0) && (tau0 >= tauc) % Rule T1 Gpz = zpk(-1/tau0,-1/T0,1); elseif (T0 >= tauc) && (tauc >= tau0) % Rule T1a Gpz = zpk(-1/tau0,-1/T0,tau0/tauc); elseif (tauc >= T0) && (T0 >= tau0) % Rule T1b Gpz = zpk(-1/tau0,-1/T0,tau0/T0); elseif (tau0 >= T0) && (T0 >= 5*tauc) % Rule T2 Gpz = zpk(-1/tau0,-1/T0,1); elseif min(tau0,5*tauc) >= T0 % Rule T3 taut = min(tau0,5*tauc); Gpz = zpk(-1/tau0,[-1/T0 -1/(taut-T0)],taut/T0/(taut-T0)); taut0 = taut-T0; else error('Unsupported case for a positive numerator time constant.') end % New model with positive time constant removed. rsys = minreal(rsys*Gpz); % Remove tau0 from the list of lag time constants, taui0, and % add the new time constant (from Rule T3) if needed. idx = find(tau0==taui0,1); taui0(idx) = []; taui0 = sort([taui0; taut0], 'descend'); end end