function LTIsystem_Sfunction(block)
% Level-2 M file S-Function (linearni T-invariantni spojity system)

  setup(block); %povinna metoda, nastavuje zakladni parametry bloku definovaneho pomoci S-funkce
                %(pocet portu, pocet parametru,...)
                %block - objekt tridy Simulink.MSFcnRunTimeBlock … soustreduje vsechny dulezite 
                %        informace o bloku. Pri volani bloku s S-funkci Simulinkem je predavan jako argument do metod (callback methods)
  
%konec S-funkce

% definice tel funkci:

function setup(block)
  
  %% definice poctu parametru S-funkce
  block.NumDialogPrms = 4; %(matice A, B, C, x0)

  %% definice poctu vstupnich a vystupnich portu
  block.NumInputPorts  = 1;
  block.NumOutputPorts = 1; 

  %% Setup functional port properties to dynamically
  %% inherited.
  block.SetPreCompInpPortInfoToDynamic;
  block.SetPreCompOutPortInfoToDynamic;
 
  %nastaveni dimenze portu
  block.InputPort(1).Dimensions        = 1;
  block.InputPort(1).DirectFeedthrough = false; %vystup neni funkci vstupu - neexistuje prima vazba vstupu na vystup (rychla smycka)
  
  block.OutputPort(1).Dimensions       = 1;
  
  %% nastaveni spojiteho casu - blok vykazuje spojite chovani
  block.SampleTimes = [0 0]; %vzorkovaci cas, offset
  
  %% nastaveni poctu spojitych stavu bloku 
  block.NumContStates = 2; %(LTI model 2. radu)

  %% registrace pouzivanych metod (callback methods)
  block.RegBlockMethod('InitializeConditions',    @InitConditions); %pocatecni podminka x0
  block.RegBlockMethod('Outputs',                 @Output);  %vystupy (y = C*x)
  block.RegBlockMethod('Derivatives',             @Derivative);  %derivace dx/dt = A*x +B*u
  
%konec funkce setup


function InitConditions(block)

  %% inicializace stavu x na pocatecni hodnotu x0 danou 4. parametrem S-funkce
  block.ContStates.Data = block.DialogPrm(4).Data;
  
%konec funkce InitConditions

function Output(block)
  C = block.DialogPrm(3).Data;
  block.OutputPort(1).Data =  C * block.ContStates.Data;
  
%konec funkce Outputs

function Derivative(block)

     A = block.DialogPrm(1).Data; 
     B = block.DialogPrm(2).Data; 
     u =  block.InputPort(1).Data; 

     block.Derivatives.Data = A * block.ContStates.Data + B * u;
  
%konec funkce Derivative

