
#define S_FUNCTION_NAME  PSD   //zde se definuje nazev s-funkce, ktery musi odpovidat nazvu souboru
#define S_FUNCTION_LEVEL 2


#include "simstruc.h"   //definovani knihoven, ktere chceme pouzivat
#include "math.h"

static double K,Ti,Td,Ts,e,sum,zasah,zasahMin,zasahMax,ds;

#define K_PARAM(S) ssGetSFcnParam(S,0) //definovani vstupnich parametru, ktere jsou do s-funkce predavany
#define Ti_PARAM(S) ssGetSFcnParam(S,1)
#define Td_PARAM(S) ssGetSFcnParam(S,2)
#define Ts_PARAM(S) ssGetSFcnParam(S,3)
 //definovani vstupnich parametru, ktere jsou do s-funkce predavany


/*====================*
 * S-function methods *
 *====================*/


static void mdlInitializeSizes(SimStruct *S)    //inicializacni smycka s-funkce - povinna    
{
    /* See sfuntmpl_doc.c for more details on the macros below */

    ssSetNumSFcnParams(S,4);            /* Nastaveni poctu parametru, ktere se predavaji s-funkci */
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        /* Return if number of expected != number of actual parameters */
        return;
    }

    if (!ssSetNumInputPorts(S, 2)) return;  //nastaveni poctu vstupu do s-funkce
    ssSetInputPortWidth(S, 0, 1);   //nastaveni sirky vstupu
    ssSetInputPortWidth(S, 1, 1);
    
    ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/ //povoleni primeho pristupu ke vstupu
    ssSetInputPortRequiredContiguous(S, 1, true);
   
    ssSetInputPortDirectFeedThrough(S, 0, 1);
    ssSetInputPortDirectFeedThrough(S, 1, 1);
  
    /*
     * Nastaveni propustnosti vstupu (1=ano, 0=ne).
     * Vstup povazujeme za propustny, jestlize hodnota na vstupu 
     * je ve stejnem simulacnim kroku pouzita ve funkcich mdlOutputs 
     * (pro vypocet akcniho zasahu) nebo mdlGetTimeOfNextVarHit.
     * Vice detailu v matlabroot/simulink/src/sfuntmpl_directfeed.txt.
     */

    
    if (!ssSetNumOutputPorts(S, 1)) return; //nastaveni poctu vystupu
    ssSetOutputPortWidth(S, 0, 1);  //definovani sirky vystupu
}




static void mdlInitializeSampleTimes(SimStruct *S)  //nastaveni periody vzorkovani - povinna
{
    Ts=*mxGetPr(Ts_PARAM(S)); //touto funkci lze ziskat hodnotu paramatru, zadaneho v blocku s-funkce
    ssSetSampleTime(S, 0, Ts);  //nastaveni periody vzorkovani
    ssSetOffsetTime(S, 0, 0.0); //nastaveno offesetu periody vzorkovani

}



#define MDL_INITIALIZE_CONDITIONS   /* Change to #undef to remove function */
#if defined(MDL_INITIALIZE_CONDITIONS)

static void mdlInitializeConditions(SimStruct *S) //zde lze inicializovat globalni promenne, provede se pouze jednou, nebezi ve smycce
{
    sum=0;
    zasah=0;
    e=0;
    zasahMin=-6;
    zasahMax=6;
    
    K = *mxGetPr(K_PARAM(S));
    Ti = *mxGetPr(Ti_PARAM(S));
    Td = *mxGetPr(Td_PARAM(S));
    
    
   
}
#endif /* MDL_INITIALIZE_CONDITIONS */


/* Function: mdlOutputs =======================================================
 * Abstract:
 *    In this function, you compute the outputs of your S-function
 *    block. Generally outputs are placed in the output vector, ssGetY(S).
 */
static void mdlOutputs(SimStruct *S, int_T tid) // smycka, bezici stale dokola, provadejici vypocet, dokud neni ukoncena simulace - povinna
{
    const real_T *u1 = (const real_T*) ssGetInputPortSignal(S,0);    //ziskani hodnoty ze vstupu ulozene do u
    const real_T *u2 = (const real_T*) ssGetInputPortSignal(S,1); 
    real_T       *y = ssGetOutputPortSignal(S,0);   //ziskani pristupu na vystup, uklada se do y
   
    e=u1[0]-u2[0];
    zasah=K*e+sum+K*(Td/Ts)*e-ds;
    ds=K*(Td/Ts)*e;
    sum=sum+K*Ts/Ti*e;
    
    if(sum>zasahMax) sum=zasahMax;
    if(sum<zasahMin) sum=zasahMin;
    
    if(zasah>zasahMax) zasah=zasahMax;
    if(zasah<zasahMin) zasah=zasahMin;  
    
    y[0]=zasah;    
}


static void mdlTerminate(SimStruct *S)  //ukoncovaci funckce, provede se pouze pri skonceni simulace - povinna
{
   
    
}


/*======================================================*
 * See sfuntmpl_doc.c for the optional S-function methods *
 *======================================================*/

/*=============================*
 * Required S-function trailer *
 *=============================*/

#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif
