Contents

function hybNcsMdl = genHybNcsModel(ncs)
% genHybNcsModel Generates the matrices needed to express an NCS in the
%                hybrid model framwork.
%
%   HYBMDLVARS = genHybNcsModel(NCS) Generates the  matrices HYBMDLVARS
%   used in the hybrid systems framework from the properties of in NCS.
%   The matrices in HYBMDLVARS are A11, A12, A21, A22 which are used to
%   describe how the plant dynamics and network induced-error dynamics
%   are coupled, i.e.,
%
%        |\dot{x}| = |A11 A12| |x|
%        |\dot{e}|   |A21 A22| |e|
%
%   where x is the state of the plant and e is the network-induced error.
%   The above eqn is the linear version of the nonlinear functions f(x,e)
%   and g(x,e) in eqn (7a) of [Heemels et. al., Trans. Autom. Control, 2011].
%
%   INPUTS
%   ------------------------------------------------------
%      NCS       - NCS object created with the ncsEditor
%
%   OUTPUTS
%   ------------------------------------------------------
%      HYBNCSMDL - structure containing variables needed for
%                  analyzeHybNcs.m
%                  ~~~~Fields~~~~
%                  HYBNCSMDL.A11 - A11 matrix assoc. with hybrid model
%                  HYBNCSMDL.A12 - A12 matrix assoc. with hybrid model
%                  HYBNCSMDL.A21 - A21 matrix assoc. with hybrid model
%                  HYBNCSMDL.A22 - A22 matrix assoc. with hybrid model
%

Display System Information

    disp('SYSTEM DATA:')

    % Total number of nodes
    nrNodes = length(ncs.getNetwork.gammaU);
    disp(['  Number of Nodes:  ' num2str(nrNodes)])
    disp(['  Protocol:         ' ncs.getNetwork.protocol])
SYSTEM DATA:
Error using genHybNcsModel (line 38)
Not enough input arguments.

Pick Model

    warning('off','YALMIP:strict')
    if strcmp(ncs.getController.ctrlType,'Static Feedback')
        disp('  Controller:           Static Feedback');
        hybNcsMdl = staticFb(ncs);
    elseif strcmp(ncs.getController.ctrlType,'C-LTI Dynamic Feedback')
        disp('  Controller:           Continuous-time Dynamic Feedback');
        hybNcsMdl = ctDynamicFb(ncs,0);
    elseif strcmp(ncs.getController.ctrlType,'C-LTI Dynamic Feedback (uWired)')
        disp('  Controller:           Continuous-time Dynamic Feedback (uWired)');
        hybNcsMdl = ctDynamicFb(ncs,1);
    else
        error('genHybNcsModel.m: Controller type not available in hybrid framwork.')
    end
end

function hybNcsMdl = staticFb(ncs)
    Ap = ncs.getPlant.A;
    Bp = ncs.getPlant.B;
    Cp = ncs.getPlant.C;
    K  = -ncs.getController.K{1};

    %if uWired==1
    %    disp('  Channels Transmitted: Only outputs')
    %    Su = zeros(size(Bp,2),1);
    %    Sy = ones(size(Cp,1),1);
    %else
    %    disp('  Channels Transmitted: All inputs and outputs')
        Su = ones(size(Bp,2),1);
        Sy = ones(size(Cp,1),1);
    %end

    l = size(ncs.getNetwork.gammaU,2);   % number of nodes

    %tic

    % global variables (now in function call)
    % global L_0 L_1 gamma_0 gamma_1 lambda phi10

    % check sizes of system matrices
    [mAp,nAp] = size(Ap);
    [mBp,nBp] = size(Bp);
    [mCp,nCp] = size(Cp);
    [mDc,nDc] = size(K);
    [mSy,nSy] = size(Sy);
    [mSu,nSu] = size(Su);

    if (mSy ~= 1)
        Sy = Sy.';
        [mSy,nSy] = size(Sy);
    end
    if (mSu ~= 1)
        Su = Su.';
        [mSu,nSu] = size(Su);
    end

    if mAp ~= nAp
        error('Ap should be square');
    elseif mAp ~= mBp
        error('dimensions Ap and Bp do not match');
    elseif nAp ~= nCp
        error('dimensions Ap and Cp do not match');
    elseif mDc ~= nBp
        error('dimensions Dc and Bp do not match');
    elseif nDc ~= mCp
        error('dimensions Dc and Cc do not match');
    elseif (mSy ~= 1)
        error('Sy should be a vector');
    elseif (mSu ~= 1)
        error('Su should be a vector');
    elseif nSy ~= mCp
        error('dimensions Sy and Cp do not match');
    elseif nSu ~= nBp
        error('dimensions Su and Bp do not match');
    elseif l < 1
        error('There should be at least one node (sampled data)')
    end


    % ==========
    % program calculating system matrices
    % ==========

    % Smatrices determining network configuration
    Syu = Sy;
    p = length(Syu);
    q = length(find(Syu == 1));
    if l > q
        error('number of error signals is smaller then the number of nodes')
    end
    r = 0;
    S = zeros(p,q);
    for s = 1:p
        if Syu(s) == 1
            r = r+1;
            S(s,r) = 1;
        end
    end

    % System matrices according to [2], multiplied with Smatrices for  network
    % configuration of nodes
    hybNcsMdl.A11 = Ap+Bp*K*Cp;
    A12x = Bp*K;
    A21x = -blkdiag(Cp)*hybNcsMdl.A11;
    A22x = -blkdiag(Cp)*A12x;
    hybNcsMdl.A12 = A12x*S;
    hybNcsMdl.A21 = S.'*A21x;
    hybNcsMdl.A22 = S.'*A22x*S;

    % test closed loop stability without network
    test_A11 = eig(hybNcsMdl.A11);
    if any(test_A11 > 0)
        error('Closed loop system without network is unstable: reconsider controller; if Ac = 0, use a small negative constant or use the static controller function')
    end

end

function hybNcsMdl = ctDynamicFb(ncs,uWired)

    Ap = ncs.getPlant.A;
    Bp = ncs.getPlant.B;
    Cp = ncs.getPlant.C;

    Ac = ncs.getController.A{1};
    Bc = ncs.getController.B{1};
    Cc = ncs.getController.C{1};
    Dc = ncs.getController.D{1};

    if uWired==1
        disp('  Channels Transmitted: Only outputs')
        Su = zeros(size(Bp,2),1);
        Sy = ones(size(Cp,1),1);
    else
        disp('  Channels Transmitted: All inputs and outputs')
        Su = ones(size(Bp,2),1);
        Sy = ones(size(Cp,1),1);
    end


    l = size(ncs.getNetwork.gammaU,2);   % number of nodes

    % ==========
    % program checking system matrices
    % ==========

    %tic

    % global variables (now in function call)
    % global L_0 L_1 gamma_0 gamma_1 lambda phi10

    % check sizes of system matrices
    [mAp,nAp] = size(Ap);
    [mBp,nBp] = size(Bp);
    [mCp,nCp] = size(Cp);
    [mAc,nAc] = size(Ac);
    [mBc,nBc] = size(Bc);
    [mCc,nCc] = size(Cc);
    [mDc,nDc] = size(Dc);
    [mSy,nSy] = size(Sy);
    [mSu,nSu] = size(Su);

    if (mSy ~= 1)
        Sy = Sy.';
        [mSy,nSy] = size(Sy);
    end
    if (mSu ~= 1)
        Su = Su.';
        [mSu,nSu] = size(Su);
    end

    if mAp ~= nAp
        error('Ap should be square');
    elseif mAp ~= mBp
        error('dimensions Ap and Bp do not match');
    elseif nAp ~= nCp
        error('dimensions Ap and Cp do not match');
    elseif mAc ~= nAc
        error('Ac should be square');
    elseif mAc ~= mBc
        error('dimensions Ac and Bc do not match');
    elseif nAc ~= nCc
        error('dimensions Ac and Cc do not match');
    elseif mDc ~= mCc
        error('dimensions Dc and Cc do not match');
    elseif nDc ~= nBc
        error('dimensions Dc and Bc do not match');
    elseif mDc ~= nBp
        error('dimensions Dc and Bp do not match');
    elseif nDc ~= mCp
        error('dimensions Dc and Cp do not match');
    elseif (mSy ~= 1)
        error('Sy should be a vector');
    elseif (mSu ~= 1)
        error('Su should be a vector');
    elseif nSy ~= mCp
        error('dimensions Sy and Cp do not match');
    elseif nSu ~= nBp
        error('dimensions Su and Bp do not match');
        % elseif Ac >= 0  EIGENVALUES, not needed since A11 is tested later.
        % error('Ac should be negative definite, use small constant and make Cc
        % 0 for no controller state xc');
    elseif l < 1
        error('There should be at least one node (sampled data)')
    else
        %disp(strvcat('System matrices have matching dimensions',' '));
    end

    % ==========
    % program calculating system matrices
    % ==========

    % Smatrices determining network configuration
    Syu = [Sy Su];
    p = length(Syu);
    q = length(find(Syu == 1));
    if l > q
        error('number of error signals is smaller then the number of nodes')
    end
    r = 0;
    S = zeros(p,q);
    for s = 1:p
        if Syu(s) == 1
            r = r+1;
            S(s,r) = 1;
        end
    end

    % System matrices according to [2], multiplied with Smatrices for  network
    % configuration of nodes
    hybNcsMdl.A11 = [Ap+Bp*Dc*Cp Bp*Cc; Bc*Cp Ac];
    A12x = [Bp*Dc Bp; Bc zeros(mBc,nBp)];
    A21x = -blkdiag(Cp,Cc)*hybNcsMdl.A11;
    A22x = -blkdiag(Cp,Cc)*A12x;
    hybNcsMdl.A12 = A12x*S;
    hybNcsMdl.A21 = S.'*A21x;
    hybNcsMdl.A22 = S.'*A22x*S;

    % test closed loop stability without network
    test_A11 = eig(hybNcsMdl.A11);
    if any(test_A11 > 0)
        error('Closed loop system without network is unstable: reconsider controller; if Ac = 0, use a small negative constant or use the static controller function')
    end

end