コード例 #1
0
/* Function: mdlOutputs =======================================================
 * Abstract:
 *    In this function, you compute the outputs of your S-function
 *    block.
 */
static void mdlOutputs(SimStruct *S, int_T tid) {
	// get Objects
	void** vecPWork = ssGetPWork(S);

	// get Pointers
	// accessing inputs
	const uint32_T *idx = (const uint32_T*) ssGetInputPortSignal(S, 0);
	const real_T *pts = (const real_T*) ssGetInputPortSignal(S, 1);

	if (ssGetInputPortNumDimensions(S, 0) != 2 || ssGetInputPortNumDimensions(S, 1) != 2) {
		ssSetErrorStatus(S,
				"Wrong number of dimensions. This should never happen!.");
		return;
	}

#if defined(MATLAB_MEX_FILE)
	const int_T nTriangles = ssGetCurrentInputPortDimensions(S, 0, 1);
	const int_T nPts = ssGetCurrentInputPortDimensions(S, 1, 1);
#else
	const int_T nTriangles = ssGetInputPortDimensions(S, 0)[1];
	const int_T nPts = ssGetInputPortDimensions(S, 1)[1];
#endif

	GenericPublisher<shape_msgs::Mesh>* pub =
			(GenericPublisher<shape_msgs::Mesh>*) vecPWork[0];

	const std::string* topic = (const std::string*) vecPWork[1];

	shape_msgs::Mesh msg;
	msg.triangles.resize(nTriangles);
	msg.vertices.resize(nPts);

	for (int_T i = 0; i < 3; ++i) {
		for (int_T j = 0; j < nTriangles; ++j) {
			msg.triangles[j].vertex_indices[i] = idx[3 * j + i];
		}
	}

	for (int_T j = 0; j < nPts; ++j) {
		msg.vertices[j].x = pts[3 * j + 0];
		msg.vertices[j].y = pts[3 * j + 1];
		msg.vertices[j].z = pts[3 * j + 2];
	}

	pub->publish(msg);

}
コード例 #2
0
ファイル: Turbine_PSI_TMATS.c プロジェクト: TomaszSz/T-MATS
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;

}