Пример #1
0
  /* Function: mdlUpdate ======================================================
   * Abstract:
   *    This function is called once for every major integration time step.
   *    Discrete states are typically updated here, but this function is useful
   *    for performing any tasks that should only take place once per
   *    integration step.
   */
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
    real_T t, *xC, *xD, *uWQ, *uES;

	SS=S;
   
    t  = ssGetT(S);
    xC = ssGetContStates(S);
    xD = ssGetDiscStates(S);
    uWQ  = ssGetInputPortRealSignal(S,0);

  	// verwijzing naar exra inputs
  	if (B(S,"Setpoints")>0)
  	{
  	  uES = &(uWQ[(int) (U(S,"Number")*B(S,"WaterIn"))]); 
  	}
  	else
  	{
  	  uES=NULL;
  	}
  	
	
    wsgetq_Update(t,xC,xD,uWQ,uES,
                      ssGetSFcnParam(S, 0),ssGetSFcnParam(S, 2),ssGetSFcnParam(S, 3));
  }
Пример #2
0
  /* Function: mdlDerivatives =================================================
   * Abstract:
   *    In this function, you compute the S-function block's derivatives.
   *    The derivatives are placed in the derivative vector, ssGetdX(S).
   */
  static void mdlDerivatives(SimStruct *S)
  {

    real_T t, *xC, *xD, *uWQ, *uES, *sys;
	int i;

    SS=S;
    
    t  = ssGetT(S);
    xC = ssGetContStates(S);
    xD = ssGetDiscStates(S);
    uWQ  = ssGetInputPortRealSignal(S,0);
    sys  = ssGetdX(S);

    for (i=0; i<(int)B(S,"CStates"); i++)
    {
        sys[i]=0.0;
    }
    
  	// verwijzing naar exra inputs
  	if (B(S,"Setpoints")>0)
  	{
  	  uES = &(uWQ[(int) (U(S,"Number")*B(S,"WaterIn"))]); 
  	}
  	else
  	{
  	  uES=NULL;
  	}

    wsgetq_Derivatives(sys,t,xC,xD,uWQ,uES,
                          ssGetSFcnParam(S, 0),ssGetSFcnParam(S, 2),ssGetSFcnParam(S, 3));
    
 }
Пример #3
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    int j;

    ocp_nlp_dims *nlp_dims = (ocp_nlp_dims *) ssGetPWork(S)[0];
    ocp_nlp_in *nlp_in = (ocp_nlp_in *) ssGetPWork(S)[1];
    ocp_nlp_out *nlp_out = (ocp_nlp_out *) ssGetPWork(S)[2];
    ocp_nlp_solver *nlp_solver = (ocp_nlp_solver *) ssGetPWork(S)[4];

    ocp_nlp_constraints_bgh_model **constraints = (ocp_nlp_constraints_bgh_model **) nlp_in->constraints;
	ocp_nlp_constraints_bgh_dims **constraints_dims = (ocp_nlp_constraints_bgh_dims **) nlp_dims->constraints;
    ocp_nlp_cost_nls_model **cost = (ocp_nlp_cost_nls_model **) nlp_in->cost;

    const double *x0 = ssGetInputPortRealSignal(S, 0);
    const double *reference = ssGetInputPortRealSignal(S, 1);

    // bounds
    double lb_0[] = {-10000, -10000, 50, 50, 1.14275, 1.53787};
    double ub_0[] = {+10000, +10000, 50, 50, 1.14275, 1.53787};
    for (j = 0; j < NUM_STATES; ++j) {
        lb_0[NUM_CONTROLS+j] = x0[j];
        ub_0[NUM_CONTROLS+j] = x0[j];
    } 

    ocp_nlp_constraints_bounds_set(config, dims, nlp_in, 0, "lb", lb_0);
    ocp_nlp_constraints_bounds_set(config, dims, nlp_in, 0, "ub", ub_0);
    
    for (j = 0; j <= NUM_STAGES; ++j)
        BLASFEO_DVECEL(&cost[j]->y_ref, 0) = *reference;

    int status = ocp_nlp_solve(nlp_solver, nlp_in, nlp_out);
    
    double *u0_opt = ssGetOutputPortRealSignal(S, 0);
    double *x1 = ssGetOutputPortRealSignal(S, 1);
    double *status_out = ssGetOutputPortRealSignal(S, 2);
    double *comp_time = ssGetOutputPortRealSignal(S, 3);

    blasfeo_unpack_dvec(NUM_CONTROLS, &nlp_out->ux[0], 0, u0_opt);
    blasfeo_unpack_dvec(NUM_STATES, &nlp_out->ux[1], NUM_CONTROLS, x1);
    *status_out = (double) status;
    *comp_time = nlp_out->total_time;
}
Пример #4
0
  /* Function: mdlUpdate ======================================================
   * Abstract:
   *    This function is called once for every major integration time step.
   *    Discrete states are typically updated here, but this function is useful
   *    for performing any tasks that should only take place once per
   *    integration step.
   */
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
     const real_T *u = (const real_T*) ssGetInputPortRealSignal(S,0);
     struct comStruc_OUT **dataOUT = (struct comStruc_OUT**) ssGetDWork(S,DVECSHMOUT);

     dataOUT[0]->index_counter = (int32_t) u[0];
     dataOUT[0]->sin_value = (float) u[1];
     dataOUT[0]->cos_value = (float) u[2];

     printf("value OUT 1 %d\n", dataOUT[0]->index_counter);
     printf("value OUT 2 %f\n", dataOUT[0]->sin_value);
     printf("value OUT 3 %f\n\n", dataOUT[0]->cos_value);
  }
Пример #5
0
/* Function: mdlOutputs =======================================================
 * Abstract:
 *      y = f(X,U), where f(.) is the static mapping defined in eval_treepartition
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
   real_T   *y          = ssGetOutputPortRealSignal(S,0);
   ParStruc *Par        = ssGetUserData(S);
   const real_T   *Reg;
   
   UNUSED_ARG(tid); /* not used in single tasking mode */
   
   /* Execute the nonlinearity mapping function*/
   Reg = ssGetInputPortRealSignal(S,0); /* input signals are contiguous */
   evaluate_pwlinear(y, Reg, 1, Par);

}
Пример #6
0
  /* Function: mdlUpdate ======================================================
   * Abstract:
   *    This function is called once for every major integration time step.
   *    Discrete states are typically updated here, but this function is useful
   *    for performing any tasks that should only take place once per
   *    integration step.
   */
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
    real_T t, *xC, *xD, *u;

    int i;
    
    t  = ssGetT(S);
    xC = ssGetContStates(S);
    xD = ssGetDiscStates(S);
    u  = ssGetInputPortRealSignal(S,0);

    block0_Update(t,xC,xD,u,
      ssGetSFcnParam(S, 0),ssGetSFcnParam(S, 2),ssGetSFcnParam(S, 3));
  }
Пример #7
0
/* 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)
{
    real_T t, *xC, *xD, *u, *sys;

    int i;
    
    t  = ssGetT(S);
    xC = ssGetContStates(S);
    xD = ssGetDiscStates(S);
    u  = ssGetInputPortRealSignal(S,0);
    sys  = ssGetOutputPortRealSignal(S,0);

    block0_Outputs(sys,t,xC,xD,u,
      ssGetSFcnParam(S, 0),ssGetSFcnParam(S, 2),ssGetSFcnParam(S, 3));
}
Пример #8
0
/* 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)
{
    real_T t, *xC, *xD, *uWQ, *uES, *sysWQ, *sysEM;
    int i;

   	SS=S;

    t  = ssGetT(S);
    xC = ssGetContStates(S);
    xD = ssGetDiscStates(S);
    uWQ  = ssGetInputPortRealSignal(S,0);
    sysWQ  = ssGetOutputPortRealSignal(S,0);

    
    for (i=0;i<U(S,"Number")*B(S,"WaterIn")*B(S,"WaterOut");i++)
  	{
	    sysWQ[i] = uWQ[i];
  	}

  	// verwijzing naar exra inputs
  	if (B(S,"Setpoints")>0)
  	{
  	  uES = &(uWQ[ (int) (U(S,"Number")*B(S,"WaterIn"))]); 
  	}
  	else
  	{
  	  uES=NULL;
  	}
  	
  	// verwijzing naar exra metingen
  	if (B(S,"Measurements")>0)
  	{
  	  sysEM = &(sysWQ[(int) (U(S,"Number")*B(S,"WaterOut"))]); 
      for (i=0;i<B(S,"Measurements");i++)
    	{
	      sysEM[i] = 0.0;
  	  }
  	}
  	else
  	{
  	  sysEM=NULL;
  	}
  	
	
    wsgetq_Outputs(sysWQ,sysEM,t,xC,xD,uWQ,uES,
                   ssGetSFcnParam(S, 0),ssGetSFcnParam(S, 2),ssGetSFcnParam(S, 3));
}
Пример #9
0
/* Function: mdlDerivatives =================================================
 * Abstract:
 *    In this function, you compute the S-function block's derivatives.
 *    The derivatives are placed in the derivative vector, ssGetdX(S).
 */
static void mdlDerivatives(SimStruct *S)
{

    real_T t, *xC, *xD, *u, *sys;

    int i;

    t  = ssGetT(S);
    xC = ssGetContStates(S);
    xD = ssGetDiscStates(S);
    u  = ssGetInputPortRealSignal(S,0);
    sys  = ssGetdX(S);

    buffer_Derivatives(sys,t,xC,xD,u,
                       ssGetSFcnParam(S, 0),ssGetSFcnParam(S, 2),ssGetSFcnParam(S, 3));

}
Пример #10
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*--------Define Parameters-------*/
    const real_T NcDes              = *mxGetPr(NcDes_p(S));
    const real_T PRDes              = *mxGetPr(PRDes_p(S));
    const real_T EffDes             = *mxGetPr(EffDes_p(S));
    const real_T RlineDes           = *mxGetPr(RlineDes_p(S));
    const real_T IDes               = *mxGetPr(IDesign_p(S));
    const real_T CustBldEn          = *mxGetPr(CustBldEn_p(S));
    const real_T FBldEn             = *mxGetPr(FBldEn_p(S));
    const real_T CustBldNm          = *mxGetPr(CustBldNm_p(S));
    const real_T FracBldNm          = *mxGetPr(FracBldNm_p(S));
    
    /* vector & array data */
    const real_T *Y_C_Map_NcVec        = mxGetPr(Y_C_Map_NcVec_p(S));
    const real_T *X_C_RlineVec         = mxGetPr(X_C_RlineVec_p(S));
    const real_T *Z_C_AlphaVec         = mxGetPr(Z_C_AlphaVec_p(S));
    const real_T *T_C_Map_WcArray      = mxGetPr(T_C_Map_WcArray_p(S));
    const real_T *T_C_Map_PRArray      = mxGetPr(T_C_Map_PRArray_p(S));
    const real_T *T_C_Map_EffArray     = mxGetPr(T_C_Map_EffArray_p(S));
    
    const real_T *FracCusBldht         = mxGetPr(FracCusBldht_p(S));
    const real_T *FracCusBldPt         = mxGetPr(FracCusBldPt_p(S));
    const real_T *FracBldht            = mxGetPr(FracBldht_p(S));
    const real_T *FracBldPt            = mxGetPr(FracBldPt_p(S));
    
    const real_T *X_C_Map_WcSurgeVec   = mxGetPr(X_C_Map_WcSurgeVec_p(S));
    const real_T *T_C_Map_PRSurgeVec   = mxGetPr(T_C_Map_PRSurgeVec_p(S));
    
    /*------get dimensions of parameter arrays-------*/
    const int_T A   = mxGetNumberOfElements(Y_C_Map_NcVec_p(S));
    const int_T B   = mxGetNumberOfElements(X_C_RlineVec_p(S));
    const int_T C   = mxGetNumberOfElements(Z_C_AlphaVec_p(S));
    const int_T D   = mxGetNumberOfElements(X_C_Map_WcSurgeVec_p(S));
    
    const int_T WcMapCol  = *mxGetPr(WcMapCol_p(S));
    const int_T PRMapCol  = *mxGetPr(PRMapCol_p(S));
    const int_T EffMapCol = *mxGetPr(EffMapCol_p(S));
    const int_T WcMapRw   = *mxGetPr(WcMapRw_p(S));
    const int_T PRMapRw   = *mxGetPr(PRMapRw_p(S));
    const int_T EffMapRw  = *mxGetPr(EffMapRw_p(S));
    const int_T WcMapLay   = *mxGetPr(WcMapLay_p(S));
    const int_T PRMapLay   = *mxGetPr(PRMapLay_p(S));
    const int_T EffMapLay  = *mxGetPr(EffMapLay_p(S));
    
    /*---------Define Inputs for input port 1--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);
    
    double WIn      = u[0];     /* Input Flow [pps] 	*/
    double htIn     = u[1];     /* Input Enthalpy [BTU/lbm] */
    double TtIn     = u[2];     /* Temperature Input [degR] 	*/
    double PtIn     = u[3];     /* Pressure Input [psia] 	*/
    double FARcIn   = u[4];     /* Combusted Fuel to Air Ratio [frac] 	*/
    double Nmech    = u[5];     /* Mechancial Shaft Speed [rpm] 	*/
    double Rline    = u[6];     /* Rline [NA]  */
    double Alpha    = u[7];     /* Alpha [NA]  */
    double s_C_Nc   = u[8];     /* Nc map scalar [NA]  */
    double s_C_Wc   = u[9];     /* Wc map scalar [NA] */
    double s_C_PR   = u[10];     /* PR map scalar [NA]  */
    double s_C_Eff  = u[11];    /* Eff map scalar [NA]  */
    
    /*---------Define Inputs for input port 2--------*/
    const real_T *Wcust = ssGetInputPortRealSignal(S, 1);
    int uWidth1 = CustBldNm;
    
    /*---------Define Inputs for input port 3--------*/
    const real_T *FracWbld  = ssGetInputPortSignal(S,2);
    int uWidth2 = FracBldNm;
    
    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);   /* Output Array port 1 */
    real_T *y1  = (real_T *)ssGetOutputPortRealSignal(S,1);   /* Output Array port 2 */
    real_T *y2  = (real_T *)ssGetOutputPortRealSignal(S,2);   /* Output Array port 3 */
    
    /*--------Define Constants-------*/
    double WOut, htOut, TtOut, PtOut, FARcOut, TorqueOut, NErrorOut;
    double C_Nc, C_Wc, C_PR, C_Eff;
    double htin, Sin, Wcin, WcCalcin, WcMap, theta,delta, Pwrout, Wbleeds, Wsumbleed;
    double TtIdealout, htIdealout, Test, Sout, NcMap, Nc, PRMap, PR, EffMap, Eff;
    double Wb4bleed, Pwrb4bleed, PwrBld;
    double SPR, SPRMap, SMavail, SMMap;
    
    /* Define Arrays for bleed calcs */
    int MaxNumberBleeds = 100;
    double WcustOut[500];
    double PtcustOut[500];
    double TtcustOut[500];
    double FARcustOut[500];
    double WbldOut[500];
    double FARbldOut[500];
    double PtbldOut[500];
    double TtbldOut[500];
    double htbldOut[500];
    double htcustOut[500];
    
    double SMWcVec[500];
    double SMPRVec[500];
    
    int interpErr = 0;
    int i;
    
    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;
    
    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);
    
    
    /*-- Compute output Fuel to Air Ratio ---*/
    FARcOut = FARcIn;
    
    /*-- Compute Input enthalpy --------*/
    
    htin = t2hc(TtIn,FARcIn);
    
    /*-- Compute Input entropy  --------*/
    
    Sin = pt2sc(PtIn,TtIn,FARcIn);
    
    /*---- calculate misc. fluid condition related variables and corrected Flow --*/
    delta = PtIn / C_PSTD;
    theta = TtIn / C_TSTD;
    Wcin = WIn*sqrtT(theta)*divby(delta);
    
    /*------ Calculate corrected speed ---------*/
    Nc = Nmech*divby(sqrtT(theta));
    if (IDes < 0.5)
        C_Nc = Nc *divby(NcDes) ;
    else
        C_Nc = s_C_Nc;
    
    NcMap = Nc *divby(C_Nc);
    
    /*-- Compute Total Flow input (from Compressor map)  --------*/
    if(C > 1)
        WcMap = interp3Ac(X_C_RlineVec,Y_C_Map_NcVec,Z_C_AlphaVec,T_C_Map_WcArray,Rline,NcMap,Alpha,B,A,C,&interpErr);
    else
        WcMap = interp2Ac(X_C_RlineVec,Y_C_Map_NcVec,T_C_Map_WcArray,Rline,NcMap,B,A,&interpErr);
        
    if ((WcMapCol != B || WcMapRw != A || WcMapLay !=C) && ssGetIWork(S)[Er1]==0){
        printf("Warning in %s, Error calculating WcMap. Table size does not match axis vector lengths.\n", BlkNm);
        ssSetIWorkValue(S,Er1,1);
    }
    else if (interpErr == 1 && ssGetIWork(S)[Er1]==0){
        printf("Warning in %s, Error calculating WcMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er1,1);
    }
    
    if (IDes < 0.5)
        C_Wc = Wcin*divby(WcMap);
    else
        C_Wc = s_C_Wc;
    
    WcCalcin = WcMap * C_Wc;
    
    /*-- Compute Pressure Ratio (from Compressor map)  --------*/
    if(C > 1)
        PRMap = interp3Ac(X_C_RlineVec,Y_C_Map_NcVec,Z_C_AlphaVec,T_C_Map_PRArray,Rline,NcMap,Alpha,B,A,C,&interpErr);
    else
        PRMap = interp2Ac(X_C_RlineVec,Y_C_Map_NcVec,T_C_Map_PRArray,Rline,NcMap,B,A,&interpErr);
    
    if ((PRMapCol != B || PRMapRw != A || PRMapLay !=C) && ssGetIWork(S)[Er2]==0){
        printf("Warning in %s, Error calculating PRMap. Table size does not match axis vector lengths.\n", BlkNm);
        ssSetIWorkValue(S,Er2,1);
    }
    else if (interpErr == 1 && ssGetIWork(S)[Er2]==0){
        printf("Warning in %s, Error calculating PRMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er2,1);
    }
    
    if (IDes < 0.5)
        C_PR = (PRDes -1)*divby(PRMap-1);
    else
        C_PR = s_C_PR;
    
    PR = C_PR*(PRMap - 1) + 1 ;
    
    /*-- Compute Efficiency (from Compressor map) ---*/
    if(C > 1)
        EffMap = interp3Ac(X_C_RlineVec,Y_C_Map_NcVec,Z_C_AlphaVec,T_C_Map_EffArray,Rline,NcMap,Alpha,B,A,C,&interpErr);
    else
        EffMap = interp2Ac(X_C_RlineVec,Y_C_Map_NcVec,T_C_Map_EffArray,Rline,NcMap,B,A,&interpErr);
    
    if ((EffMapCol != B || EffMapRw != A || EffMapLay !=C) && ssGetIWork(S)[Er3]==0){
        printf("Warning in %s, Error calculating EffMap. Table size does not match axis vector lengths.\n", BlkNm);
        ssSetIWorkValue(S,Er3,1);
    }
    else if (interpErr == 1 && ssGetIWork(S)[Er3]==0){
        printf("Warning in %s, Error calculating EffMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er3,1);
    }
    
    if (IDes < 0.5)
        C_Eff = EffDes*divby(EffMap);
    else
        C_Eff = s_C_Eff;
    
    Eff = EffMap * C_Eff;
    
    /*------ Compute pressure output --------*/
    
    PtOut = PtIn*PR;
    
    
    /*------ enthalpy calculations ---------*/
    
    /* ---- Ideal enthalpy ----*/
    Sout = Sin;
    TtIdealout = sp2tc(Sout,PtOut,FARcIn);
    htIdealout = t2hc(TtIdealout,FARcIn);
    
    
    /* ---- Final enthalpy output ----*/
    
    htOut = ((htIdealout - htin)*divby(Eff)) + htin;
    
    /*------ Compute Temperature output ---------*/
    
    TtOut = h2tc(htOut,FARcIn);
    
    
    /* initalize Bleed sums components */
    Wbleeds = 0;
    PwrBld = 0;
    
    /* compute customer Bleed components */
    for (i = 0; i < uWidth1; i++)
    {
        /* if customer bleed = 0 or Cust bld is not enabled set outputs to zero */
        if (Wcust[i] == 0 || CustBldEn < 0.5){
            WcustOut[i] = 0;
            htcustOut[i] = 0;
            TtcustOut[i] = 0;
            PtcustOut[i] = 0;
            FARcustOut[i] = 0;
        }
        else {
            /*-- Compute sum of customer Bleed Flow output  --------*/
            Wbleeds = Wbleeds + Wcust[i]; /* add to total bleed value */
            WcustOut[i] = Wcust[i];
            FARcustOut[i] = FARcIn;
            htcustOut[i] = htin + FracCusBldht[i]*(htOut - htin); /* calculate customer bleed enthalpy */
            PtcustOut[i] = PtIn + FracCusBldPt[i]*(PtOut -PtIn); /* calculate customer bleed Total Pressure */
            TtcustOut[i] = h2tc(htcustOut[i],FARcustOut[i]); /* calculate customer bleed Total Temp */
            PwrBld = PwrBld + WcustOut[i]*(htcustOut[i]-htOut)*C_BTU_PER_SECtoHP;  /* calculate customer bleed power */
        }
        if (i > 4*MaxNumberBleeds && ssGetIWork(S)[Er4]==0){
            printf("Error in %s, Number of bleeds in compressor exceeds 100... Array overflow! Reading Bad Data\n", BlkNm);
            ssSetIWorkValue(S,Er4,1);
        }
    }
    
    /*----Disable Fractional bleed when requested----*/
    
    for (i = 0; i < uWidth2; i++)
    {
        if (FracWbld[i] <= 0 || FBldEn < 0.5 ){
            WbldOut[i] = 0;
            htbldOut[i] = 0;
            FARbldOut[i] = 0;
            TtbldOut[i] = 0;
            PtbldOut[i] = 0;
        }
        
        else {
            /*-- Compute sum of Fractional Bleed Flow output  --------*/
            Wbleeds = Wbleeds + FracWbld[i]*WIn; /* add to total bleed value */
            WbldOut[i] = FracWbld[i]*WIn;
            FARbldOut[i] = FARcIn;
            PtbldOut[i] = PtIn + FracBldPt[i]*(PtOut -PtIn); /* calculate  bleed Total Pressure */
            htbldOut[i] = htin + FracBldht[i]*(htOut - htin); /* calculate  bleed enthalpy */
            TtbldOut[i] = h2tc(htbldOut[i],FARbldOut[i]); /* calculate  bleed Total Temp */
            PwrBld = PwrBld + WbldOut[i]*(htbldOut[i]-htOut)*C_BTU_PER_SECtoHP;  /* calculate bleed power */
        }
        if (i > 4*MaxNumberBleeds && ssGetIWork(S)[Er4]==0){
            printf("Error in %s, Number of bleeds in compressor exceeds 100... Array overflow! Reading Bad Data\n", BlkNm);
            ssSetIWorkValue(S,Er4,1);
        }
    }
    
    /*-- Compute Flows  --------*/
    Wb4bleed = WIn;
    WOut = WIn - Wbleeds;
    
    /*------ Compute Powers ---------*/
    
    Pwrb4bleed = Wb4bleed * (htin - htOut) * C_BTU_PER_SECtoHP;
    Pwrout = Pwrb4bleed - PwrBld;
    
    /*----- Compute output Torque to shaft ----*/
    TorqueOut = C_HP_PER_RPMtoFT_LBF * Pwrout*divby(Nmech);
    
    /* ----- Compute Normalized Flow Error ----- */
    if (IDes < 0.5 && Rline == 0)
        NErrorOut = 100;
    else if (IDes < 0.5)
        NErrorOut = (Rline - RlineDes)*divby(Rline);
    else if (WIn == 0)
        NErrorOut = 100;
    else
        NErrorOut = (Wcin - WcCalcin)*divby(Wcin);
    
    /* Compute Stall Margin */
    if (C > 1){
        /* Define 1-D surge margin vectors based on alpha */
        for (i = 0; i < D/C; i++){
            SMWcVec[i] = interp1Ac(Z_C_AlphaVec, X_C_Map_WcSurgeVec + C*i, Alpha,C, &interpErr);
            if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
                printf("Warning in %s, Error calculating 1D SMWcVec. Vector definitions may need to be adjusted.\n", BlkNm);
                ssSetIWorkValue(S,Er5,1);
            }
            SMPRVec[i] = interp1Ac(Z_C_AlphaVec, T_C_Map_PRSurgeVec + C*i, Alpha,C, &interpErr);
            if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
                printf("Warning in %s, Error calculating 1D SMPRVec. Vector definitions may need to be adjusted.\n", BlkNm);
                ssSetIWorkValue(S,Er5,1);
            }
        }
        SPRMap = interp1Ac(SMWcVec, SMPRVec,WcMap,A,&interpErr);
        if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
            printf("Warning in %s, Error calculating 2D SPR. Vector definitions may need to be adjusted.\n", BlkNm);
            ssSetIWorkValue(S,Er5,1);
        }
    }
    else
        SPRMap = interp1Ac(X_C_Map_WcSurgeVec,T_C_Map_PRSurgeVec,WcMap,D,&interpErr);
    
    if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
        printf("Warning in %s, Error calculating SPR. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er5,1);
    }
    SPR = C_PR*(SPRMap - 1) + 1;
    SMavail = (SPR - PR)*divby(PR) * 100;
    SMMap = (SPRMap - PRMap)*divby(PRMap) * 100;
    
    /* Test variable */
    Test = SPRMap;
    
    /*------Assign output values port1------------*/
    y[0] = WOut;            /* Outlet Total Flow [pps]	*/
    y[1] = htOut;           /* Output Enthalpy [BTU/lbm]	*/
    y[2] = TtOut;           /* Outlet Temperature [degR]	*/
    y[3] = PtOut;           /* Outlet Pressure [psia] 	*/
    y[4] = FARcOut;         /* Exit Combusted Fuel Flow [frac] */
    y[5] = TorqueOut;       /* Outlet Torque [lbf*ft]	*/
    y[6] = NErrorOut;       /* Normalized compressor Error [frac]*/
    y[7] = SMavail;         /* Available Stall Margin [%] */
    y[8] = C_Nc;            /* Corrected shaft speed scalar */
    y[9] = C_Wc;            /* Corrected flow scalar */
    y[10] = C_PR;           /* Pressure Ratio scalar */
    y[11] = C_Eff;          /* Efficiency scalar */
    y[12] = Wcin;           /* Corrected input flow [pps] */
    y[13] = Nc;             /* Corrected speed [rpm]*/
    y[14] = PR;             /* Pressure ratio */
    y[15] = NcMap;          /* Map corrected speed */
    y[16] = WcMap;          /* Map corrected flow */
    y[17] = PRMap;          /* Map pressure ratio */
    y[18] = EffMap;         /* Map efficiency */
    y[19] = SPR;            /* Surge pressure ratio */
    y[20] = Wbleeds;        /* Bleed flow [pps]*/
    y[21] = Pwrb4bleed;     /* Power if there was no bleed [hp]*/
    y[22] = PwrBld;         /* Power loss due to bleed [hp] */
    y[23] = Pwrout;         /* Output power [hp]*/
    y[24] = SMMap;          /* Stall margin calculated from map values [%]*/
    y[25] = SPRMap;         /* Map stall pressure ratio*/
    y[26] = Test;           /* test signal */
    
    /*------Assign output values port2------------*/
    /* Customer or flow based bleed*/
    for (i = 0; i < uWidth1; i++)
    {
        *y1++ = WcustOut[i];
        *y1++ = htcustOut[i];
        *y1++ = TtcustOut[i];
        *y1++ = PtcustOut[i];
        *y1++ = FARcustOut[i];
    }
    
    /*------Assign output values port3------------*/
    /* fractional bleed, typically used for turbine cooling flow */
    for (i = 0; i < uWidth2; i++)
    {
        *y2++ = WbldOut[i];
        *y2++ = htbldOut[i];
        *y2++ = TtbldOut[i];
        *y2++ = PtbldOut[i];
        *y2++ = FARbldOut[i];
    }
    
}
Пример #11
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*--------Define Parameters-------*/
    const real_T s_T_Nc             = *mxGetPr(s_T_Nc_p(S));
    const real_T s_T_PR             = *mxGetPr(s_T_PR_p(S));
    const real_T s_T_Wc             = *mxGetPr(s_T_Wc_p(S));
    const real_T s_T_Eff            = *mxGetPr(s_T_Eff_p(S));
    const real_T NcDes              = *mxGetPr(NcDes_p(S));
    const real_T PRmapDes           = *mxGetPr(PRmapDes_p(S));
    const real_T EffDes             = *mxGetPr(EffDes_p(S));
    const real_T NDes               = *mxGetPr(NDes_p(S));
    const real_T IDes               = *mxGetPr(IDesign_p(S));
    const real_T s_T_hi				= *mxGetPr(s_T_hi_p(S));
    const real_T gamma_T			= *mxGetPr(gamma_T_p(S));
    const real_T Rt_T				= *mxGetPr(Rt_T_p(S));
    const int_T  BldPosLeng         = *mxGetPr(BldPosLeng_p(S));
    const int_T  CoolFlwEn          = *mxGetPr(CoolFlwEn_p(S));


    /* vector & array data */
    const real_T *Y_T_NcpsiVec         = mxGetPr(Y_T_NcpsiVec_p(S));
    const real_T *X_T_PRpsiVec         = mxGetPr(X_T_PRpsiVec_p(S));
    const real_T *Y_T_NcwowVec         = mxGetPr(Y_T_NcwowVec_p(S));
    const real_T *X_T_PRwowVec         = mxGetPr(X_T_PRwowVec_p(S));
    const real_T *T_T_Map_WoWArray     = mxGetPr(T_T_Map_WoWArray_p(S));
    const real_T *T_T_Map_psiArray     = mxGetPr(T_T_Map_psiArray_p(S));
    const real_T *T_BldPos             = mxGetPr(T_BldPos_p(S));

    /*------get dimensions of parameter arrays-------*/
    const int_T A   = mxGetNumberOfElements(Y_T_NcpsiVec_p(S));
    const int_T B   = mxGetNumberOfElements(X_T_PRpsiVec_p(S));
    const int_T C   = mxGetNumberOfElements(Y_T_NcwowVec_p(S));
    const int_T D   = mxGetNumberOfElements(X_T_PRwowVec_p(S));

    /*---------Define Inputs--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);

    double WIn      = u[0];     /* Input Flow [pps]	*/
    double htIn     = u[1];     /* input enthalpy [BTU/lbm]*/
    double TtIn     = u[2];     /* Temperature Input [degR]  */
    double PtIn     = u[3];     /* Pressure Input [psia] 	 */
    double FARcIn   = u[4];     /* Compusted Fuel to Air Ratio [frac] */
    double Nmech    = u[5];     /* Mechancial Shaft Speed [rpm]*/
    double psiMapIn = u[6];     /* PSI map [NA] 	 */

    /*---------Define Inputs for input port 2--------*/
    /* N 5x1 vectors consisting of W, ht, Tt, Pt and FAR, where N is the number of cooling flows */
    const real_T *CoolFlow = ssGetInputPortRealSignal(S, 1);
    int cfWidth = ssGetCurrentInputPortDimensions(S, 1, 0);

    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);   /* Output Array */

    /*--------Define Constants-------*/
    double WOut, htOut, TtOut, PtOut, FARcOut, TorqueOut, NErrorOut;
    double WcCalcin, WcMap, theta,delta, Pwrout, PRin, htin;
    double TtIdealout, Test, htIdealout, Sout, NcMap, Nc, EffMap, Eff;
    double dHcools1, dHcoolout, Wfcools1, Wfcoolout, Ws1in,hts1in, Tts1in, Pts1in, FARs1in;
    double Ss1in, dHout, Wcoolout, Wcools1, PRmapRead;
    double C_Eff, C_PR, C_Nc, C_Wc, TtOutIdeal;
    double WMap, psiMapI, delHtIdealMap, erT, erT_old, Ptoutg, Ptoutg_old;
    double TtOutIdealg, WpqAcrit, WoWMap, Ptoutg_new;

    int interpErr = 0;
    double Wcool[100];
    double htcool[100];
    double Ttcool[100];
    double Ptcool[100];
    double FARcool[100];
    int Vtest, i;

    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;

    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);

    /* Verify input bleed vector is a multiple of 5 */
    Vtest = cfWidth/5;
    if(5*Vtest != cfWidth && CoolFlwEn > 0.5 && ssGetIWork(S)[0]==0){
        printf("Error in %s, one or more of the cooling flow input vector eleements is missing(Vector form; 5x1: W,ht,Tt,Pt,FAR)\n",BlkNm);
        ssSetIWorkValue(S,0,1);
    }
    else if(BldPosLeng != cfWidth/5 && CoolFlwEn > 0.5 && ssGetIWork(S)[1]==0){
        printf("Errorin %s, number of cooling flow inputs does not match the length of the Cooling flow postion vector in the mask\n",BlkNm);
        ssSetIWorkValue(S,1,1);
    }

    /* unpack CoolFlow vector */
    for (i = 0; i < cfWidth/5; i++)
    {
        if (CoolFlwEn < 0.5){
            Wcool[i] = 0;
            htcool[i] = 0;
            Ttcool[i] = 0;
            Ptcool[i] = 0;
            FARcool[i] = 0;
        }
        else {
            Wcool[i] = CoolFlow[5*i];
            Ttcool[i] = CoolFlow[5*i+2];
            Ptcool[i] = CoolFlow[5*i+3];
            FARcool[i] = CoolFlow[5*i+4];
            htcool[i] = t2hc(Ttcool[i],FARcool[i]);
        }
    }

    /* Initialize cooling flow sum constants */

    dHcools1 = 0;   /* enthalpy * mass cooling flow rate at stage 1 of turbine */
    dHcoolout = 0;   /* enthalpy * mass cooling flow rate at exit of turbine */
    Wcools1 = 0;    /* total cooling flow at stage 1 of turbine*/
    Wcoolout = 0;    /* total cooling flow at output of turbine */
    Wfcools1 = 0;  /* combusted fuel flow in cooling at stage 1 of turbine */
    Wfcoolout = 0;  /* combusted fuel flow in cooling at exit of turbine */

    /* calc cooling flow constants for stage 1 and output of the turbine */
    for (i = 0; i < cfWidth/5; i++)
    {
        if ((T_BldPos[i] > 1 || T_BldPos[i] < 0) && CoolFlwEn > 0.5 && ssGetIWork(S)[2]==0){
            printf(" Error in %s, cooling flow postion element %i needs to be defined as a 0 or 1\n",BlkNm,i+1);
            ssSetIWorkValue(S,2,1);
        }

        /* calc mass flow for cooling flows */
        Wcools1 = Wcools1 + Wcool[i]*(1-T_BldPos[i]);
        Wcoolout = Wcoolout + Wcool[i];

        /* calc fuel mass flow for cooling flows*/
        Wfcools1 = Wfcools1 + FARcool[i]*Wcool[i]*(1-T_BldPos[i])/(1+FARcool[i]);
        Wfcoolout = Wfcoolout + FARcool[i]*Wcool[i]/(1+FARcool[i]);
    }
    /*-- Compute Total Flow  --------*/

    Ws1in = WIn + Wcools1;  /* mass flow at station 1 */
    WOut = WIn + Wcoolout;   /* mass flow at turbine exit */

    /*-- Compute Fuel to Air Ratios ---*/

    FARs1in = (FARcIn* WIn/(1+FARcIn) + Wfcools1)/(WIn/(1+FARcIn) + Wcools1- Wfcools1);
    FARcOut = (FARcIn* WIn/(1+FARcIn)+ Wfcoolout)/(WIn/(1+FARcIn) + Wcoolout- Wfcoolout);

    /* calc input enthalpy of cooling flow for stage 1 */
    for (i = 0; i < cfWidth/5; i++)
    {
        /* Compute cooling flow dH at stage 1  */
        dHcools1 = dHcools1 + htcool[i]*Wcool[i]*(1-T_BldPos[i]);
        /* Compute cooling flow dH for the exit of the turbine assuming input htcool = htcoolout for turbine rear bleeds  */
        dHcoolout = dHcoolout + htcool[i]*Wcool[i]*T_BldPos[i];
    }

    /*-- Compute avg enthalpy at stage 1 --------*/
    htin = t2hc(TtIn,FARcIn);
    hts1in = (htin* WIn + dHcools1)/Ws1in;


    /*-- Compute  stage 1 total temp--------*/

    Tts1in = h2tc(hts1in,FARs1in);

    /*-- Compute Stage 1 entropy, assuming PtIn = Pts1in  --------*/
    Ss1in = pt2sc(PtIn,Tts1in,FARs1in);

    /*---- calculate misc. fluid condition related variables --------*/
    delta = PtIn / C_PSTD;
    theta = TtIn / C_TSTD;

    /*------ Calculate corrected speed ---------*/
    Nc = Nmech/sqrt(theta);

    if(IDes < 0.5)
        C_Nc = Nc / NcDes;
    else
        C_Nc = s_T_Nc;

    NcMap = Nc / C_Nc;

    /* ---- Calculate output entropy ----*/
    Sout = Ss1in;

    /*-- Compute Turbine Efficiency (from Turbine map)  --------*/

    psiMapI = interp2Ac(X_T_PRpsiVec,Y_T_NcpsiVec,T_T_Map_psiArray,psiMapIn,NcMap,B,A,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[3]==0){
        printf("Warning in %s, Error calculating psiMapI. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,3,1);
    }
    EffMap = psiMapIn/psiMapI;
    if(IDes < 0.5)
        C_Eff = EffDes / EffMap;
    else
        C_Eff = s_T_Eff;

    Eff = EffMap * C_Eff;

    /* ---- Ideal enthalpy  ----*/
    delHtIdealMap = psiMapI * (Nmech / 60)*(Nmech / 60);
    htIdealout = hts1in - delHtIdealMap * s_T_hi;


    /* ensure enthalpy is >= 0 */
    if(htIdealout < 0)
    {
        htIdealout = 0;
    }

    /* Determine Ideal exit temp */
    TtOutIdeal = h2tc(htIdealout,FARs1in);

    /* Determine starting point for iteration to find PR */
    Ptoutg = PtIn*pow((TtOutIdeal/TtIn),(gamma_T/(gamma_T-1)));
    TtOutIdealg = sp2tc(Sout,Ptoutg,FARs1in);
    erT = 100*abs_D(TtOutIdealg - TtOutIdeal)/TtOutIdeal;
    Ptoutg_new = Ptoutg;

    /* iterate to find Ptout when TtOutIdeal guess = TtOutIdeal */
    while (abs_D(erT) > 0.05) {
        erT_old = erT;
        Ptoutg_old = Ptoutg;
        if(abs_D(Ptoutg - Ptoutg_new) < 0.02)
            Ptoutg = Ptoutg + 0.05;
        else
            Ptoutg = Ptoutg_new;

        Ptoutg = Ptoutg + 0.05;
        TtOutIdealg = sp2tc(Sout,Ptoutg,FARs1in);
        erT = 100*(TtOutIdealg - TtOutIdeal)/TtOutIdeal;
        if (abs_D(erT) > 0.05) {
            /* determine next guess pressure by secant algorithm */
            Ptoutg_new = Ptoutg - erT *(Ptoutg - Ptoutg_old)/(erT - erT_old);
        }
    }
    PRin = PtIn/Ptoutg;


    /*------ Compute pressure output --------*/
    if(IDes < 0.5)
        C_PR = (PRin - 1)/(PRmapDes -1);
    else
        C_PR = s_T_PR;

    PRmapRead = (PRin -1)/C_PR + 1;

    PtOut = PtIn/PRin;

    /*-- Compute Total Flow input (from Turbine map)  --------*/

    WoWMap = interp2Ac(X_T_PRwowVec,Y_T_NcwowVec,T_T_Map_WoWArray,PRmapRead,NcMap,D,C,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[4]==0){
        printf("Warning in %s, Error calculating WoWMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,4,1);
    }
    WpqAcrit = sqrt((gamma_T*C_GRAVITY)/(Rt_T*JOULES_CONST))/pow((1+(gamma_T-1)/2),((gamma_T+1)/(2*(gamma_T-1))));
    WMap = WoWMap * WpqAcrit * (PtIn/sqrt(Tts1in));
    WcMap = WMap * sqrt(theta)/delta;
    if(IDes < 0.5)
        C_Wc = Ws1in*sqrt(theta)/delta / WcMap;
    else
        C_Wc = s_T_Wc;

    WcCalcin = WcMap * C_Wc;

    /*-Compute power output only takes into account cooling flow that enters at front of engine (stage 1)-*/

    Pwrout = ((hts1in - htIdealout)*Eff)*Ws1in * C_BTU_PER_SECtoHP;

    /* ---- enthalpy output ----*/

    htOut = ((((htIdealout - hts1in)*Eff) + hts1in)*Ws1in + dHcoolout)/WOut;

    /*------ Compute Temperature output (empirical) ---------*/

    TtOut = h2tc(htOut,FARcOut);

    /*----- Compute output Torque to shaft ----*/
    TorqueOut = C_HP_PER_RPMtoFT_LBF * Pwrout/Nmech;

    /* ----- Compute Normalized Flow Error ----- */
    if (IDes < 0.5 && NDes == 0)
        NErrorOut = 100;
    else if (IDes < 0.5)
        NErrorOut = (Nmech - NDes)/NDes;
    else if (Ws1in == 0) {
        NErrorOut = 100;
    }
    else {
        NErrorOut = (Ws1in*sqrt(theta)/delta-WcCalcin)/(Ws1in*sqrt(theta)/delta) ;
    }
    Test = Wcool[0];
    /*------Assign output values------------        */
    y[0] = WOut;            /* Outlet Total Flow [pps]   */
    y[1] = htOut;           /* Outlet Enthalpy [BTU/lbm]*/
    y[2] = TtOut;           /* Outlet Temperature [degR]      */
    y[3] = PtOut;           /* Outlet Pressure  [psia]     */
    y[4] = FARcOut;         /* Outlet Fuel to Air Ratio [NA]	*/
    y[5] = TorqueOut;       /* Torque Output [lbf*ft]       */
    y[6] = NErrorOut;       /* Normalized turbine Error [frac]*/
    y[7] = C_Nc;            /* Corrected Shaft Speed Scalar */
    y[8] = C_Wc;            /* Corrected Flow Scalar */
    y[9] = C_PR;            /* Pressure Ratio Scalar */
    y[10] = C_Eff;          /* Efficiency Scalar */
    y[11] = Test;

}
Пример #12
0
/* Function: mdlJacobian ======================================================
 * Abstract: populate the model's Jacobian data.
 * See the on-line documentation for mxCreateSparse for
 * information regarding the format of Ir, Jc, and Pr data.
 *
 *        [ A | B ]    
 *  J =   [ --+-- ]  (= D here)
 *        [ C | D ]  
 *                 
 */
static void mdlJacobian(SimStruct *S)
{
    #if defined(MATLAB_MEX_FILE)
    real_T      *Pr     = ssGetJacobianPr(S);
	real_T		*out;
	real_T		*temp;
    uint_T      nr      = (uint_T) mxGetScalar(NUMREG(S));
    ParStruc    *Par    = ssGetUserData(S);
    const real_T      *Reg    = ssGetInputPortRealSignal(S,0); /* input signals are contiguous */
    int_T		k;
    mxArray *plhs;
    mxArray *prhs[3];
    mxArray *ParStruct, *TreeParStruct;
    mxArray *TypeStr;
    const char **fnamesPar;
    const char **fnamesTree;
    
    /* plhs            = mxCreateDoubleMatrix(1,nr,mxREAL); */
    TypeStr         = mxCreateString("treepartition");
    fnamesPar       = mxCalloc(8, sizeof(*fnamesPar));
    fnamesTree      = mxCalloc(5, sizeof(*fnamesTree));
       
     /* memory error check */
    if ( (fnamesPar==NULL) || (fnamesTree==NULL) || (TypeStr==NULL) || (prhs==NULL)){
        ssSetErrorStatus(S, "Could not allocate memory for Jacobian computation.");
        return;
    }
    
    /* Tree struct field names */
    fnamesTree[0] = "TreeLevelPntr";
    fnamesTree[1] = "AncestorDescendantPntr";
    fnamesTree[2] = "LocalizingVectors";
    fnamesTree[3] = "LocalCovMatrix";
    fnamesTree[4] = "LocalParVector";
    
    /* Parameter struct field names */
    fnamesPar[0] = "NumberOfUnits";
    fnamesPar[1] = "Threshold";
    fnamesPar[2] = "RegressorMean";
    fnamesPar[3] = "OutputOffset";
    fnamesPar[4] = "LinearCoef";
    fnamesPar[5] = "SampleLength";
    fnamesPar[6] = "NoiseVariance";
    fnamesPar[7] = "Tree";
    
    TreeParStruct   = mxCreateStructMatrix(1,1,5,fnamesTree);
    ParStruct       = mxCreateStructMatrix(1,1,8,fnamesPar);
    
    /* do memory error check */
    if ((TreeParStruct==NULL) || (ParStruct==NULL)){
        ssSetErrorStatus(S, "Could not allocate memory for Jacobian computation.");
        return;
    }
    
    /* set fields of Parameters.Tree struct */
    mxSetFieldByNumber(TreeParStruct, 0, 0, mxDuplicateArray(TREE_TREELEVELPNTR(S)));
    mxSetFieldByNumber(TreeParStruct, 0, 1, mxDuplicateArray(TREE_ANCESTORDESCENDANTPNTR(S)));
    mxSetFieldByNumber(TreeParStruct, 0, 2, mxDuplicateArray(TREE_LOCALIZINGVECTORS(S)));
    mxSetFieldByNumber(TreeParStruct, 0, 3, mxDuplicateArray(TREE_LOCALCOVMATRIX(S)));
    mxSetFieldByNumber(TreeParStruct, 0, 4, mxDuplicateArray(TREE_LOCALPARVECTOR(S)));
    
    /* set fields of Paramater struct */
    mxSetFieldByNumber(ParStruct, 0, 0, mxDuplicateArray(NUMUNITS(S)));
    mxSetFieldByNumber(ParStruct, 0, 1, mxDuplicateArray(OPT_THRESHOLD(S)));
    mxSetFieldByNumber(ParStruct, 0, 2, mxDuplicateArray(PAR_REGRESSORMEAN(S)));
    mxSetFieldByNumber(ParStruct, 0, 3, mxDuplicateArray(PAR_OUTPUTOFFSET(S)));
    mxSetFieldByNumber(ParStruct, 0, 4, mxDuplicateArray(PAR_LINEARCOEF(S)));
    mxSetFieldByNumber(ParStruct, 0, 5, mxDuplicateArray(PAR_SAMPLELENGTH(S)));
    mxSetFieldByNumber(ParStruct, 0, 6, mxDuplicateArray(PAR_NOISEVARIANCE(S)));
    mxSetFieldByNumber(ParStruct, 0, 7, TreeParStruct);
	
	prhs[0] = mxCreateDoubleMatrix(1,nr,mxREAL);
    temp = mxGetPr(prhs[0]);
	for (k=0; k<nr; k++){
		temp[k] = Reg[k];
	}

	/* mxSetPr(prhs[0],Reg); */
    prhs[1] = ParStruct;
    prhs[2] = TypeStr;
    
    /* 
     * Call utEvalStateJacobian to compute the regressors 
     * M file: dydx = utEvalStateJacobian(x,par,type) 
     */
    
    mexCallMATLAB(1,&plhs,3,prhs,"utEvalStateJacobian");

    out = mxGetPr(plhs);
	for(k=0; k<nr; k++){
		Pr[k] = out[k];
	}
    
    mxFree((void *)fnamesTree);
    mxFree((void *)fnamesPar);
    mxDestroyArray(plhs);
    
	mxDestroyArray(prhs[0]);
	mxDestroyArray(TypeStr);
	mxDestroyArray(ParStruct);
    #endif
    
}
Пример #13
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    PCONFIG_DATA config;
    const real_T         *in_xdot;
    const real_T         *in_x0;
    InputRealPtrsType    pin_params;
    const boolean_T      *in_reset;
    real_T               *out_x;
    real_T               *out_t;
    real_T               *xd;
    real_T               *xd_temp;
    real_T               *xd_temp2;
    time_T               initial_time;
    time_T               final_time;
    quaternion           phi;
    quaternion           q;
    vector               omegadot_temp;
    const real_T         *pomegadot;
    int_T                i;

    /* Retrieve C object from the pointers vector */
    config = ssGetPWork(S)[0];

    xd = (real_T*) ssGetDWork(S,0);
    xd_temp = (real_T*) ssGetDWork(S,1);
    if( config->nq ) xd_temp2 = (real_T*) ssGetDWork(S,2);
    in_xdot = ssGetInputPortRealSignal(S, config->idxin_xdot);
    if( config->idxin_x0 ) in_x0 = ssGetInputPortRealSignal(S, config->idxin_x0);
    if( config->idxin_params ) pin_params = ssGetInputPortRealSignalPtrs(S, config->idxin_params);
    if( config->idxin_reset ) in_reset = ((InputBooleanPtrsType) ssGetInputPortSignalPtrs(S, config->idxin_reset))[0];
    out_x = ssGetOutputPortRealSignal(S, 1);
    if( config->idxout_time ) out_t = ssGetOutputPortRealSignal(S, config->idxout_time);

    switch( intval(mxGetScalar(paramSpecificationsSource)) )
    {
        case 1:
            initial_time = config->initial_time;
            final_time   = ssGetTaskTime(S,0);
            break;
        case 2:
            initial_time = mxGetScalar(paramInitialTime);
            final_time   = mxGetScalar(paramFinalTime);
            break;
        case 3:
            initial_time = *(pin_params[0]);
            final_time   = *(pin_params[1]);
            break;
        default:
            ssSetErrorStatus(S,"Wrong integration algorithm selected");
            return;
    }
    
/*    ssPrintf("ti=%f, tf=%f\r\n", initial_time, final_time); */

    /* Reset the states */
    if( ssGetIWorkValue(S, 0) || (config->idxin_reset && *in_reset) || (intval(mxGetScalar(paramSpecificationsSource)) > 1) )
    {
        ssSetIWorkValue(S, 0, 0);
        if( intval(mxGetScalar(paramInitialConditionSource)) == 1 )
        {
            /* Internal initial conditions */
            for( i=0; i<config->nstates; i++ )
            {
                xd[i] = mxGetPr(paramInitialCondition)[(mxGetNumberOfElements(paramInitialCondition) == 1 ? 0 : i)];
            }
        }
        else
        {
            /* External initial conditions */
            memcpy(xd, in_x0, config->nstates*sizeof(real_T));
        }
        memcpy(out_x, xd, config->nstates*sizeof(real_T));
        if( config->idxout_time ) out_t[0] = initial_time;
    }
    
    if( final_time > initial_time )
    {
        if( intval(mxGetScalar(paramIntegrationAlgorithm)) == 1 )
        {
            /* Euler algorithm */
            if( !ssCallSystemWithTid(S,0,tid) ) return;
            i = 0;
            while( i<config->nstates )
            {
                if( config->nq && (i >= config->start_idx_q) && (i < config->end_idx_q) )
                {
                    pomegadot = ( config->use_omegadot ? &in_xdot[i] : config->omegadot_zero );
                    QuaternionIntegralEulerChange( final_time-initial_time, &in_xdot[i], pomegadot, &xd[i], phi );
                    QuaternionProd(&xd[i], phi, &xd[i]);
                    QuaternionNormalize(&xd[i]);
                    i += 4;
                }
                else
                {
                    xd[i] += in_xdot[i] * (final_time-initial_time);
                    i++;
                }
            }
        }
        
        if( intval(mxGetScalar(paramIntegrationAlgorithm)) == 2 )
        {
            /* Runge-Kutta algorithm */
            /* f1 */
            if( !ssCallSystemWithTid(S,0,tid) ) return;
            i = 0;
            while( i<config->nstates )
            {
                if( config->nq && (i >= config->start_idx_q) && (i < config->end_idx_q) )
                {
                    pomegadot = ( config->use_omegadot ? &in_xdot[i] : config->omegadot_zero );
                    omegadot_temp[0] = pomegadot[0]*6; omegadot_temp[1] = pomegadot[1]*6; omegadot_temp[2] = pomegadot[2]*6;
                    QuaternionIntegralEulerChange( (final_time-initial_time)/6, &in_xdot[i], omegadot_temp, &xd[i], &xd_temp[i] );
                    QuaternionProd(&xd_temp[i], &xd_temp[i], q);
                    QuaternionProd(&xd_temp[i], q, phi);
                    QuaternionProd(&xd[i], phi, &out_x[i]);
                    i += 4;
                }
                else
                {
                    xd_temp[i] = in_xdot[i];
                    out_x[i] = xd[i] + 0.5*(final_time-initial_time)*in_xdot[i];
                    i++;
                }
            }
            if( config->idxout_time ) out_t[0] = initial_time + 0.5*(final_time-initial_time);
            
            /* f2 */
            if( !ssCallSystemWithTid(S,0,tid) ) return;
            i = 0;
            while( i<config->nstates )
            {
                if( config->nq && (i >= config->start_idx_q) && (i < config->end_idx_q) )
                {
                    pomegadot = ( config->use_omegadot ? &in_xdot[i] : config->omegadot_zero );
                    omegadot_temp[0] = pomegadot[0]*6; omegadot_temp[1] = pomegadot[1]*6; omegadot_temp[2] = pomegadot[2]*6;
                    QuaternionIntegralEulerChange( (final_time-initial_time)/6, &in_xdot[i], omegadot_temp, &xd[i], q );
                    QuaternionProd(q, q, phi);
                    QuaternionProd(&xd_temp[i], phi, &xd_temp[i]);
                    QuaternionProd(phi, q, phi);
                    QuaternionProd(&xd[i], phi, &out_x[i]);
                    i += 4;
                }
                else
                {
                    xd_temp[i] += 2*in_xdot[i];
                    out_x[i] = xd[i] + 0.5*(final_time-initial_time)*in_xdot[i];
                    i++;
                }
            }
            if( config->idxout_time ) out_t[0] = initial_time + 0.5*(final_time-initial_time);
            
            /* f3 */
            if( !ssCallSystemWithTid(S,0,tid) ) return;
            i = 0;
            while( i<config->nstates )
            {
                if( config->nq && (i >= config->start_idx_q) && (i < config->end_idx_q) )
                {
                    pomegadot = ( config->use_omegadot ? &in_xdot[i] : config->omegadot_zero );
                    omegadot_temp[0] = pomegadot[0]*6; omegadot_temp[1] = pomegadot[1]*6; omegadot_temp[2] = pomegadot[2]*6;
                    QuaternionIntegralEulerChange( (final_time-initial_time)/6, &in_xdot[i], omegadot_temp, &xd[i], q );
                    QuaternionProd(q, q, phi);
                    QuaternionProd(&xd_temp[i], phi, &xd_temp[i]);
                    QuaternionProd(phi, q, phi);
                    QuaternionProd(phi, phi, phi);
                    QuaternionProd(&xd[i], phi, &out_x[i]);
                    i += 4;
                }
                else
                {
                    xd_temp[i] += 2*in_xdot[i];
                    out_x[i] = xd[i] + (final_time-initial_time)*in_xdot[i];
                    i++;
                }
            }
            if( config->idxout_time ) out_t[0] = final_time;
            
            /* f4 */
            if( !ssCallSystemWithTid(S,0,tid) ) return;
            i = 0;
            while( i<config->nstates )
            {
                if( config->nq && (i >= config->start_idx_q) && (i < config->end_idx_q) )
                {
                    pomegadot = ( config->use_omegadot ? &in_xdot[i] : config->omegadot_zero );
                    omegadot_temp[0] = pomegadot[0]*6; omegadot_temp[1] = pomegadot[1]*6; omegadot_temp[2] = pomegadot[2]*6;
                    QuaternionIntegralEulerChange( (final_time-initial_time)/6, &in_xdot[i], omegadot_temp, &xd[i], q );
                    QuaternionProd(&xd_temp[i], q, &xd_temp[i]);
                    QuaternionProd(&xd[i], &xd_temp[i], &xd[i]);
                    QuaternionNormalize(&xd[i]);
                    i += 4;
                }
                else
                {
                    xd_temp[i] += in_xdot[i];
                    xd[i] += 1.0/6*(final_time-initial_time)*xd_temp[i];
                    i++;
                }
            }
        }
    }
    else
    {
        if( !ssCallSystemWithTid(S,0,tid) ) return;
    }

    config->initial_time = final_time;

    /* Update the outputs */
    memcpy(out_x, xd, config->nstates*sizeof(real_T));
    if( config->idxout_time ) out_t[0] = final_time;
}
static void mdlUpdate(SimStruct *S, int_T tid)
{
	/*********************************
	* Entradas :
	*	0:	Variador			(16)
	*	1:	Valvula Solenoide	(13)
	*	2:	Valvula Motorizada	(12)
	*	3:	Calefactor 1		(20)
	*	4:	Calefactor 2		(22)
	*	5:	Calefactor 3		(21)
	*	6:	Agitador			(23)
	*	7:	Valv. Solenoide 1	(24)
	*	8:	Valv. Solenoide 2	(25)
	*	9:	Luces Lab.      	(26)
	*********************************/

	O22SnapIoMemMap *Brain;
	long nResult,tempDig;
	float tempAna;

	Brain = (O22SnapIoMemMap *) ssGetPWork(S)[0];

	const real_T *u = ssGetInputPortRealSignal(S,0);

	// Variador de Frecuencia
	if( u[0]<5 )
		tempAna = 4.0;
	else
		tempAna = 4.0 + (float)u[0]*16.0/100.0;

	nResult=Brain->SetAnaPtValue(16,tempAna);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato del variador de frecuencia.");
		return;
	}

	// Valvula Solenoide
	tempAna = 4.0 + (float)u[1]*16.0/100.0;
	nResult=Brain->SetAnaPtValue(13,tempAna);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato de la valvula solenoide.");
		return;
	}

	// Valvula Motorizada
	tempAna = 4.0 + (float)u[2]*16.0/100.0;
	nResult=Brain->SetAnaPtValue(12,tempAna);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato de la valvula motorizada.");
		return;
	}

	// Calefactor 1
	if( (float)u[3] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(20,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato del calefactor 1.");
		return;
	}

	// Calefactor 2
	if( (float)u[4] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(22,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato del calefactor 2.");
		return;
	}

	// Calefactor 3
	if( (float)u[5] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(21,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato del calefactor 3.");
		return;
	}

	// Agitador
	if( (float)u[6] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(23,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato del agitador.");
		return;
	}

	// Valv. Solenoide 1
	if( (float)u[7] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(24,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato de la valvula solenoide 1.");
		return;
	}

	// Valv. Solenoide 2
	if( (float)u[8] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(25,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato de la valvula solenoide 2.");
		return;
	}
	
	// Luces Lab.
	if( (float)u[9] > 0.5 )
		tempDig = 1;
	else
		tempDig = 0;
	nResult=Brain->SetDigPtState(26,tempDig);
	if ( nResult != SIOMM_OK )
	{
		ssSetErrorStatus(S,"Error al transmitir el dato de las luces del laboratorio.");
		return;
	}
}
Пример #15
0
/* Function: mdlJacobian ======================================================
 * Abstract: populate the model's Jacobian data.
 * See the on-line documentation for mxCreateSparse for
 * information regarding the format of Ir, Jc, and Pr data.
 *
 *        [ A | B ]    
 *  J =   [ --+-- ]  (= D here)
 *        [ C | D ]  
 *                 
 */
static void mdlJacobian(SimStruct *S)
{
    #if defined(MATLAB_MEX_FILE)
    real_T      *Pr     = ssGetJacobianPr(S);
	real_T		*out;
	real_T		*temp;
    ParStruc    *Par    = ssGetUserData(S);
    const real_T *Reg   = ssGetInputPortRealSignal(S,0); /* input signals are contiguous */
    mxArray *plhs;
    mxArray *prhs[3];
    mxArray *ParStruct;
    mxArray *TypeStr;
    const char **fnamesPar;
    
    /* plhs            = mxCreateDoubleMatrix(1,nr,mxREAL); */
    TypeStr         = mxCreateString("pwlinear");
    fnamesPar       = mxCalloc(5, sizeof(*fnamesPar));
       
     /* memory error check */
    if ( (fnamesPar==NULL) || (TypeStr==NULL) || (prhs==NULL)){
        ssSetErrorStatus(S, "Could not allocate memory for Jacobian computation.");
        return;
    }
    
    /* Parameter struct field names */
    fnamesPar[0]  = "NumberOfUnits";
    fnamesPar[1]  = "LinearCoef";
    fnamesPar[2]  = "OutputCoef";
    fnamesPar[3]  = "OutputOffset";
    fnamesPar[4]  = "Translation";
    
    ParStruct     = mxCreateStructMatrix(1,1,5,fnamesPar);
    
    /* do memory error check */
    if (ParStruct==NULL) {
        ssSetErrorStatus(S, "Could not allocate memory for Jacobian computation.");
        return;
    }
    
    /* set fields of Paramater struct */
    mxSetFieldByNumber(ParStruct, 0, 0,  mxDuplicateArray(NUMUNITS(S)));
    mxSetFieldByNumber(ParStruct, 0, 1,  mxDuplicateArray(PAR_LINEARCOEF(S)));
    mxSetFieldByNumber(ParStruct, 0, 2,  mxDuplicateArray(PAR_OUTPUTCOEF(S)));
    mxSetFieldByNumber(ParStruct, 0, 3,  mxDuplicateArray(PAR_OUTPUTOFFSET(S)));
    mxSetFieldByNumber(ParStruct, 0, 4,  mxDuplicateArray(PAR_TRANSLATION(S)));
    
    /* nr = dimension of regressor = 1 */
	prhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
    temp = mxGetPr(prhs[0]);
	temp[0] = Reg[0];
    prhs[1] = ParStruct;
    prhs[2] = TypeStr;
    
    /* 
     * Call utEvalStateJacobian to compute the regressors 
     * M file: dydx = utEvalStateJacobian(x,par,type) 
     */
    mexCallMATLAB(1,&plhs,3,prhs,"utEvalStateJacobian");

    out = mxGetPr(plhs);
    Pr[0] = out[0];
    
    mxFree((void *)fnamesPar);
    mxDestroyArray(plhs);
    
	mxDestroyArray(prhs[0]);
	mxDestroyArray(TypeStr);
	mxDestroyArray(ParStruct);
    #endif
}