classdef (Hidden = true) piddataP < ltipack.piddata & ltipack.parallelPID
    % Class definition for @piddataP (pidp object data)
    
    %   Author(s): Rong Chen
    %   Copyright 2009-2010 The MathWorks, Inc.
    
    % Formula: Kp + Ki*(1/s) + Kd*s/(Tf*s+1)) or Kp + Ki*(1/s) + Kd/(Tf+1/s))
    % Discretization means replace integrators above with discretizers
    %   for 'ForwardEuler':     1/s --> Ts/(z-1)
    %   for 'BackwardEuler':    1/s --> Ts*z/(z-1)
    %   for 'Trapezoidal':      1/s --> Ts*(z+1)/2/(z-1)
    % Delay structure is initialized as 0 and remains 0
    
    properties
    end
    
    %% Public methods
    methods
        
        % constructor
        function this = piddataP(Kp,Ki,Kd,Tf,Ts)
            if nargin == 5
                % parameters
                this.Kp = Kp;
                this.Ki = Ki;
                this.Kd = Kd;
                this.Tf = Tf;
                this.Ts = Ts;
                this.Delay = ltipack.utDelayStruct(1,1,false);
            end
        end
        
        function PIDS = pidstd(PID,varargin)
            % Parallel to standard conversion
            % When specified, OPTIONS is a struct/object containing the fields IFormula and DFormula.
            Ts = PID.Ts;
            % convert to PID with desired formulas
            PID = pid(PID,varargin{:});
            % transform to PIDSTD coefficients
            [Kp,Ti,Td,N] = ltipack.piddata.convertPIDF('Parallel','Standard',PID.Kp,PID.Ki,PID.Kd,PID.Tf); %#ok<*PROP>
            % return piddataS
            PIDS = ltipack.piddataS(Kp,Ti,Td,N,Ts);
            if Ts~=0
                PIDS.IFormula = PID.IFormula;
                PIDS.DFormula = PID.DFormula;
            end
        end
        
        function PID = pid(PID,Options)
            % Parallel to parallel conversion.
            % When specified, OPTIONS is a struct/object with fields IFormula and DFormula.
            Ts = PID.Ts;
            if nargin>1 && Ts~=0
                [IF,DF,newForm] = ltipack.piddata.getTargetFormulas(PID.IFormula,PID.DFormula,Options);
                if newForm
                    [PID.Kp,PID.Ki,PID.Kd,PID.Tf] = PID.utChangeIFDF(PID.Kp,PID.Ki,PID.Kd,PID.Tf,Ts,PID.IFormula,PID.DFormula,IF,DF);
                    PID.IFormula = IF;
                    PID.DFormula = DF;
                end
            end
        end
        
        function PID2 = make2DOF(PID,bval,cval)
            % 1-dof -> 2-dof conversion by adding b, c
            b = 1;
            c = 1;
            if nargin >= 2
                b = bval;
            end
            if nargin == 3
                c = cval;
            end
            Ts = PID.Ts;
            % return piddataP2
            PID2 = ltipack.piddataP2(PID.Kp,PID.Ki,PID.Kd,PID.Tf,b,c,Ts);
                
            if Ts~=0
                PID2.IFormula = PID.IFormula;
                PID2.DFormula = PID.DFormula;
            end
        end
        
        function D = scaleTime(D,sf)
            % Time vector scaling tnew = sf * told
            
            % scale Delay and Ts
            D = scaleTime@ltipack.ltidata(D,sf);
            % scale controller coefficients
            D = scaleTime@ltipack.parallelPID(D,sf);
        end
    end
    
    methods(Static)
        
        function D = loadobj(S)
            % Load filter for @piddataP
            if isstruct(S)
                % R2013b: Tags removed
                D = ltipack.transferData(ltipack.piddataP,S);
            else
                D = S;
            end
        end
        
        function D = array(size)
            % Create a pid array of a given size
            D = ltipack.piddataP.newarray(size);
        end
        
    end
    
end