Skip to content

Commit efdd78e

Browse files
authored
Merge pull request nasa#81 from mathworks/master
Split S-function code to allow for embedded code generation.
2 parents dbd3867 + 17bc6d4 commit efdd78e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3533
-4046
lines changed
-18.5 KB
Binary file not shown.
-33.6 KB
Binary file not shown.
-20.8 KB
Binary file not shown.
-31.6 KB
Binary file not shown.

Trunk/TMATS_Library/MATLAB_Scripts/stripchar_TMATS.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
name(ii)= '_';
99
elseif strcmp(name(ii), '\o')
1010
name(ii)= '';
11+
elseif strcmp(name(ii), ' ')
12+
name(ii)= '_';
13+
elseif strcmp(name(ii), sprintf('\n'))
14+
name(ii)= '_';
1115
end
1216
ii= ii + 1;
1317
end;

Trunk/TMATS_Library/MEX/Ambient_TMATS.c

Lines changed: 62 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
#define S_FUNCTION_NAME Ambient_TMATS
1010
#define S_FUNCTION_LEVEL 2
1111
#include "simstruc.h"
12-
#include "constants_TMATS.h"
13-
#include "functions_TMATS.h"
14-
#include <math.h>
12+
#include "types_TMATS.h"
1513

1614
#define X_A_AltVec_p(S) ssGetSFcnParam(S,0)
1715
#define T_A_TsVec_p(S) ssGetSFcnParam(S,1)
@@ -23,10 +21,18 @@
2321
#define AFARc_p(S) ssGetSFcnParam(S,7)
2422
#define BN_p(S) ssGetSFcnParam(S,8)
2523
#define NPARAMS 9
24+
#define NERRORS 5
2625

27-
/* create enumeration for Iwork */
28-
typedef enum {Er1 = 0, Er2, Er3, Er4, Er5, NUM_IWORK}IWorkIdx;
26+
extern void Ambient_TMATS_body(real_T *y, const real_T *u, const AmbientStruct* prm);
2927

28+
#define MDL_SET_WORK_WIDTHS
29+
#if defined(MDL_SET_WORK_WIDTHS) && defined(MATLAB_MEX_FILE)
30+
static void mdlSetWorkWidths(SimStruct *S)
31+
{
32+
const char_T *rtParamNames[] = {"X_A_AltVec", "T_A_TsVec", "T_A_PsVec", "X_A_FARVec", "Y_A_TVec", "T_A_RtArray", "T_A_gammaArray", "AFARc"};
33+
ssRegAllTunableParamsAsRunTimeParams(S, rtParamNames);
34+
}
35+
#endif
3036

3137
static void mdlInitializeSizes(SimStruct *S)
3238
{
@@ -37,8 +43,15 @@ static void mdlInitializeSizes(SimStruct *S)
3743
return;
3844
}
3945

40-
for (i = 0; i < NPARAMS; i++)
41-
ssSetSFcnParamTunable(S, i, 0);
46+
for (i = 0; i < NPARAMS; i++) {
47+
if (i != 8)
48+
ssSetSFcnParamTunable(S, i, 1);
49+
else
50+
ssSetSFcnParamTunable(S, i, 0);
51+
}
52+
53+
ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE |
54+
SS_OPTION_USE_TLC_WITH_ACCELERATOR);
4255

4356
ssSetNumContStates(S, 0);
4457
ssSetNumDiscStates(S, 0);
@@ -53,7 +66,7 @@ static void mdlInitializeSizes(SimStruct *S)
5366

5467
ssSetNumSampleTimes(S, 1);
5568
ssSetNumRWork(S, 0);
56-
ssSetNumIWork(S, NUM_IWORK);
69+
ssSetNumIWork(S, NERRORS);
5770
ssSetNumPWork(S, 0);
5871
ssSetNumModes(S, 0);
5972
ssSetNumNonsampledZCs(S, 0);
@@ -82,166 +95,61 @@ static void mdlStart(SimStruct *S)
8295

8396
static void mdlOutputs(SimStruct *S, int_T tid)
8497
{
85-
/*--------parameters defined in S-function block--------*/
86-
const real_T AFARc = *mxGetPr(AFARc_p(S));
87-
88-
/*-------- vector & array data -------*/
89-
const real_T *X_A_AltVec = mxGetPr(X_A_AltVec_p(S));
90-
const real_T *T_A_TsVec = mxGetPr(T_A_TsVec_p(S));
91-
const real_T *T_A_PsVec = mxGetPr(T_A_PsVec_p(S));
92-
const real_T *X_A_FARVec = mxGetPr(X_A_FARVec_p(S));
93-
const real_T *T_A_RtArray = mxGetPr(T_A_RtArray_p(S));
94-
const real_T *Y_A_TVec = mxGetPr(Y_A_TVec_p(S));
95-
const real_T *T_A_gammaArray = mxGetPr(T_A_gammaArray_p(S));
96-
97-
/*------get dimensions of parameter arrays-------*/
98-
const int_T A = mxGetNumberOfElements(X_A_AltVec_p(S));
99-
const int_T B = mxGetNumberOfElements(X_A_FARVec_p(S));
100-
const int_T C = mxGetNumberOfElements(Y_A_TVec_p(S));
101-
102-
/*---------Define Inputs--------*/
98+
/* Input and output vectors */
10399
const real_T *u = (const real_T*) ssGetInputPortSignal(S,0);
104100

105-
double AltIn = u[0]; /* Altitude(ft) */
106-
double dTempIn = u[1]; /* delta Temperature [degF] */
107-
double MNIn = u[2]; /* Mach Number (frac) */
108-
109-
real_T *y = (real_T *)ssGetOutputPortRealSignal(S,0); /* Output Array */
110-
111-
/*--------Define Constants-------*/
112-
double PsOut, TsOut, TtOut, PtOut, VengOut, TsStDayOut, Vsound;
113-
double Ttg, Ptg, Vg, Vsg, MNg, Sout, htg, gammasg, Rs, Rt;
114-
double hs, htOut, Test;
115-
double er, er_old, erthr, Ptg_new, Ptg_old, FAR, FAROut;
116-
int iter, maxiter;
117-
118-
int interpErr = 0;
101+
real_T *y = (real_T *)ssGetOutputPortRealSignal(S,0);
119102

120-
121-
122-
/* ------- get strings -------------- */
123-
char * BlkNm;
103+
/* Block name buffer length and string read status */
124104
int_T buflen;
125105
int_T status;
126-
106+
107+
/* Block mask parameter struct */
108+
AmbientStruct ambientStruct;
109+
ambientStruct.AFARc = *mxGetPr(AFARc_p(S));
110+
/* Vector & array data */
111+
ambientStruct.X_A_AltVec = mxGetPr(X_A_AltVec_p(S));
112+
ambientStruct.T_A_TsVec = mxGetPr(T_A_TsVec_p(S));
113+
ambientStruct.T_A_PsVec = mxGetPr(T_A_PsVec_p(S));
114+
ambientStruct.X_A_FARVec = mxGetPr(X_A_FARVec_p(S));
115+
ambientStruct.T_A_RtArray = mxGetPr(T_A_RtArray_p(S));
116+
ambientStruct.Y_A_TVec = mxGetPr(Y_A_TVec_p(S));
117+
ambientStruct.T_A_gammaArray = mxGetPr(T_A_gammaArray_p(S));
118+
/* Dimensions of parameter arrays */
119+
ambientStruct.A = mxGetNumberOfElements(X_A_AltVec_p(S));
120+
ambientStruct.B = mxGetNumberOfElements(X_A_FARVec_p(S));
121+
ambientStruct.C = mxGetNumberOfElements(Y_A_TVec_p(S));
122+
123+
ambientStruct.IWork = ssGetIWork(S);
124+
127125
/* Get name of block from dialog parameter (string) */
128126
buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
129-
BlkNm = mxMalloc(buflen);
130-
status = mxGetString(BN_p(S), BlkNm, buflen);
131-
132-
FAR = AFARc;
133-
134-
Rt = interp1Ac(X_A_FARVec,T_A_RtArray,FAR,B,&interpErr);
135-
if (interpErr == 1 && ssGetIWork(S)[Er1] == 0){
136-
printf("Warning in %s, Error calculating Rt. Vector definitions may need to be expanded.\n", BlkNm);
137-
ssSetIWorkValue(S,Er1,1);
138-
}
139-
140-
Rs = Rt;
141-
142-
/* Static Temperature */
143-
TsStDayOut = interp1Ac(X_A_AltVec,T_A_TsVec,AltIn,A,&interpErr);
144-
if (interpErr == 1 && ssGetIWork(S)[Er2] == 0){
145-
printf("Warning in %s, Error calculating TsStDayOut. Vector definitions may need to be expanded.\n", BlkNm);
146-
ssSetIWorkValue(S,Er2,1);
147-
}
148-
TsOut = TsStDayOut + dTempIn;
149-
150-
/* Static Pressure*/
151-
PsOut = interp1Ac(X_A_AltVec,T_A_PsVec,AltIn,A,&interpErr);
152-
if (interpErr == 1 && ssGetIWork(S)[Er3] == 0){
153-
printf("Warning in %s, Error calculating PsOut. Vector definitions may need to be expanded.\n", BlkNm);
154-
ssSetIWorkValue(S,Er3,1);
155-
}
156-
157-
/* Calc output entropy */
158-
Sout = pt2sc(PsOut, TsOut, FAR);
159-
/* Determine Static enthalpy */
160-
hs = t2hc(TsOut,FAR);
161-
162-
/* Pt guess */
163-
/*------ Total Temperature ---------*/
164-
Ttg = TsOut * (1+MNIn*MNIn*(C_GAMMA-1)/2);
165-
/*------ Total Pressure ---------*/
166-
Ptg = PsOut*divby((powT((TsOut*divby(Ttg)),(C_GAMMA*divby(C_GAMMA-1)))));
167-
168-
/* calculate total temperature */
169-
Ttg = sp2tc(Sout,Ptg,FAR);
170-
/* calculate total enthalpy */
171-
htg = t2hc(Ttg,FAR);
172-
/* calculate velocity */
173-
Vg = sqrtT(2 * (htg - hs)*C_GRAVITY*JOULES_CONST);
174-
175-
gammasg = interp2Ac(X_A_FARVec,Y_A_TVec,T_A_gammaArray,FAR,TsOut,B,C,&interpErr);
176-
if (interpErr == 1 && ssGetIWork(S)[Er4] == 0){
177-
printf("Warning in %s, Error calculating iteration gammasg. Vector definitions may need to be expanded.\n", BlkNm);
178-
ssSetIWorkValue(S,Er4,1);
179-
}
180-
Vsg = sqrtT(gammasg*Rs*TsOut*C_GRAVITY*JOULES_CONST);
181-
MNg = Vg*divby(Vsg);
182-
er = MNIn - MNg;
183-
Ptg_new = Ptg + 0.05;
184-
maxiter = 15;
185-
iter = 0;
186-
erthr = 0.001;
187-
188-
while (fabs(er) > erthr && iter < maxiter) {
189-
er_old = er;
190-
Ptg_old = Ptg;
191-
if(fabs(Ptg - Ptg_new) < 0.03)
192-
Ptg = Ptg + 0.05;
193-
else
194-
Ptg = Ptg_new;
195-
196-
/* calculate Total emperature */
197-
Ttg = sp2tc(Sout,Ptg,FAR);
198-
/* calculate total enthalpy */
199-
htg = t2hc(Ttg,FAR);
200-
/* calculate velocity */
201-
Vg = sqrtT(2 * (htg - hs)*C_GRAVITY*JOULES_CONST);
202-
203-
Vsg = sqrtT(gammasg*Rs*TsOut*C_GRAVITY*JOULES_CONST);
204-
MNg = Vg*divby(Vsg);
205-
er = MNIn - MNg;
206-
if (fabs(er) > erthr) {
207-
/* determine next guess pressure by secant algorithm */
208-
Ptg_new = Ptg - er *(Ptg - Ptg_old)*divby(er - er_old);
209-
}
210-
iter = iter + 1;
211-
}
212-
if (iter == maxiter && ssGetIWork(S)[Er5]==0 ){
213-
printf("Warning in %s, Error calculating Pt at input MN. There may be error in output pressure\n", BlkNm);
214-
ssSetIWorkValue(S,Er5,1);
215-
}
216-
217-
htOut = htg;
218-
TtOut = Ttg;
219-
PtOut = Ptg;
220-
221-
/*---- Engine Velocity ---------*/
222-
Vsound = Vsg;
223-
VengOut = Vsound * MNIn;
224-
225-
FAROut = FAR;
127+
ambientStruct.BlkNm = mxMalloc(buflen);
128+
status = mxGetString(BN_p(S), ambientStruct.BlkNm, buflen);
226129

227-
Test = divby(dTempIn);
228-
229-
/*------Assign output values------------*/
230-
y[0] = htOut; /* Total enthalpy */
231-
y[1] = TtOut; /* Total Temperature [degR] */
232-
y[2] = PtOut; /* Total Pressure [psia] */
233-
y[3] = FAROut; /* Fuel to Air Ratio */
234-
y[4] = PsOut; /* Static Pressure [psia] */
235-
y[5] = TsOut; /* Static Temperature [degR] */
236-
y[6] = VengOut; /* Engine Velocity [ft/sec] */
237-
y[7] = Test; /* Test signal */
238-
130+
/* Perform core block calculations */
131+
Ambient_TMATS_body(y, u, &ambientStruct);
239132
}
240133

241134
static void mdlTerminate(SimStruct *S)
242135
{
243136
}
244137

138+
#define MDL_RTW
139+
static void mdlRTW(SimStruct *S)
140+
{
141+
if (!ssWriteRTWWorkVect(S, "IWork", 1 /* nNames */,
142+
"Errors",
143+
ssGetNumIWork(S))) {
144+
return;
145+
}
146+
/*
147+
This registration of the error code symbols "Er1, etc."
148+
allows tlc to call
149+
LibBlockIWork(Er1,[...])
150+
*/
151+
152+
}
245153
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
246154
#include "simulink.c" /* MEX-file interface mechanism */
247155
#else
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
%% File : Ambient_TMATS.tlc
2+
%%
3+
%% Description:
4+
%% Simulink Coder TLC Code Generation file for Ambient_TMATS
5+
%%
6+
%implements Ambient_TMATS "C"
7+
8+
%% Function: BlockTypeSetup ===============================================
9+
%%
10+
%function BlockTypeSetup(block, system) void
11+
%%
12+
%% The Target Language must be C
13+
%if ::GenCPP==1
14+
%<LibReportFatalError("This S-Function generated by the Legacy Code Tool must be only used with the C Target Language")>
15+
%endif
16+
17+
%<LibAddToCommonIncludes("types_TMATS.h")>
18+
19+
%<SLibAddToStaticSources("Ambient_TMATS_body.c")>
20+
21+
%openfile forwardDecls
22+
extern void Ambient_TMATS_body(double *y, const double *u, const AmbientStruct* prm);
23+
AmbientStruct ambientStruct;
24+
%closefile forwardDecls
25+
26+
%assign srcFile = LibGetModelDotCFile()
27+
%<LibSetSourceFileSection(srcFile, "Definitions", forwardDecls)>
28+
29+
%endfunction
30+
31+
%% Function: BlockInstanceSetup ===========================================
32+
%%
33+
%function BlockInstanceSetup(block, system) void
34+
%%
35+
%<LibBlockSetIsExpressionCompliant(block)>
36+
%endfunction
37+
38+
%% Function: Outputs ======================================================
39+
%%
40+
%function Outputs(block, system) Output
41+
%%
42+
ambientStruct.AFARc = %<LibBlockParameter(AFARc,"","",0)>;
43+
ambientStruct.X_A_AltVec = (double*)(%<LibBlockParameterBaseAddr(X_A_AltVec)>);
44+
ambientStruct.T_A_TsVec = (double*)(%<LibBlockParameterBaseAddr(T_A_TsVec)>);
45+
ambientStruct.T_A_PsVec = (double*)(%<LibBlockParameterBaseAddr(T_A_PsVec)>);
46+
ambientStruct.X_A_FARVec = (double*)(%<LibBlockParameterBaseAddr(X_A_FARVec)>);
47+
ambientStruct.T_A_RtArray = (double*)(%<LibBlockParameterBaseAddr(T_A_RtArray)>);
48+
ambientStruct.Y_A_TVec = (double*)(%<LibBlockParameterBaseAddr(Y_A_TVec)>);
49+
ambientStruct.T_A_gammaArray = (double*)(%<LibBlockParameterBaseAddr(T_A_gammaArray)>);
50+
ambientStruct.A = %<LibBlockParameterSize(X_A_AltVec)[1]>;
51+
ambientStruct.B = %<LibBlockParameterSize(X_A_FARVec)[1]>;
52+
ambientStruct.C = %<LibBlockParameterSize(Y_A_TVec)[1]>;
53+
54+
ambientStruct.IWork = &%<LibBlockIWork(Errors,"","",0)>;
55+
ambientStruct.BlkNm = "%<LibGetFormattedBlockPath(block)>";
56+
57+
%assign y_ptr = LibBlockOutputSignalAddr(0, "", "", 0)
58+
%assign y_dataType = LibBlockOutputSignalDataTypeName(0,"")
59+
60+
%assign u_ptr = LibBlockInputSignalAddr(0, "", "", 0)
61+
%assign u_dataType = LibBlockInputSignalDataTypeName(0,"")
62+
63+
%%
64+
Ambient_TMATS_body((%<y_dataType>*)%<y_ptr>,\
65+
(%<u_dataType>*)%<u_ptr>,\
66+
&ambientStruct);
67+
%%
68+
%endfunction
69+
70+
%% [EOF]

0 commit comments

Comments
 (0)