function PID = d2d(PID,Ts,options)
% Resample discrete time PID to new sampling interval Ts.

%   Author(s): Rong Chen
%   Copyright 2009-2010 MathWorks, Inc.

Ts0 = PID.Ts;
IF0 = PID.IFormula;
DF0 = PID.DFormula;
if isa(PID,'ltipack.piddata2')
    % 2-DOF
    objFcn = @pidstd2;
else
    % 1-DOF
    objFcn = @pidstd;
end
switch lower(options.Method)
    case 'tustin'
        % first convert to PID with tustin formulas
        try
            PID = objFcn(PID,struct('IFormula','T','DFormula','T'));
        catch ME
            ctrlMsgUtils.error('Control:transformation:pidConversionFailed','d2d');
        end
        % set Ts to new value
        PID.Ts = Ts;
        % adjust Ti Td when prewarping is present
        w = options.PrewarpFrequency;
        if w ~= 0
            Tsw0 = Ts0 * w / 2;
            Tsw = Ts * w / 2;
            Ratio = (tan(Tsw) * Tsw0) / (tan(Tsw0) * Tsw);
            PID.Ti = PID.Ti*Ratio;
            PID.Td = PID.Td*Ratio;
        end        
    case 'zoh'
        % first convert to PID with ForwardEuler formulas
        PID = objFcn(PID,struct('IFormula','F','DFormula','F'));
        % adjust Td only when derivative term is present
        if PID.Td~=0 
            Tf0 = PID.Td/PID.N;
            Tf = Ts/(1-(1-Ts0/Tf0)^(Ts/Ts0));
            if isreal(Tf) && Tf>0
                PID.Td = Tf*PID.N;
            else
                % error when improper or real negative pole is transformed to complex pole
                ctrlMsgUtils.error('Control:transformation:pidConversionFailed','d2d');
            end
        end
        % set Ts
        PID.Ts = Ts;
end
% convert to PID with original formulas
try
    PID = objFcn(PID,struct('IFormula',IF0,'DFormula',DF0));
catch ME
    ctrlMsgUtils.error('Control:transformation:pidConversionFailed','d2d');
end



