
#define S_FUNCTION_NAME  Takahashi   //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 Ts;//definovani globalnich promennych
static double TKp,TKi,TKd,yp,ymin,ypredmin,zasah,zasahmin,zasahMin,zasahMax,i,w;

#define TKp_PARAM(S) ssGetSFcnParam(S,0) //definovani vstupnich parametru, ktere jsou do s-funkce predavany
#define TKi_PARAM(S) ssGetSFcnParam(S,1)
#define TKd_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
{
    
    zasah=0;
    i=0;
    ymin=0;
    ypredmin=0;
    zasahmin=0;
    zasahMin=-6;
    zasahMax=6;
    
    TKp = *mxGetPr(TKp_PARAM(S));
    TKi = *mxGetPr(TKi_PARAM(S));
    TKd = *mxGetPr(TKd_PARAM(S));
    Ts = *mxGetPr(Ts_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
   
    w=u1[0];
    yp=u2[0];
    zasah=TKp*(ymin-yp)+TKi*(w-yp)+TKd*(2*ymin-ypredmin-yp)+zasahmin;
    
    zasahmin=zasah;
    ypredmin=ymin;
    ymin=yp;
     
       
    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
