Index: mttroot/mtt/lib/rep/sfun_rep.sh ================================================================== --- mttroot/mtt/lib/rep/sfun_rep.sh +++ mttroot/mtt/lib/rep/sfun_rep.sh @@ -1,31 +1,1386 @@ #! /bin/sh set -e -debug=0 -if [ $debug -eq 1 ]; then - set -x - make_debug='--debug=a' -else - set +x - make_debug='' -fi - -check_for_errors () -{ - errno=0 - # check stuff - case $errno in - 0) - ;; # ok - *) - echo "E $errno"; - exit $errno; - ;; - esac -} - -check_for_errors $* +# +# function definitions +# + + +set_debug () +{ + debug=$1 + if [ $debug -eq 1 ]; then + set -x + make_debug='--debug=a' + else + set +x + make_debug='' + fi +} + +exit_error () +{ + message="$1" + case $message in + "Invalid Input" ) errno = 2 ;; + "Unknown Template" ) errno = 3 ;; + * ) errno = -1 ;; + esac + echo "#Error: " $message + exit errno; +} + +check_for_valid_input () +{ + args="$*" + if [ $# -neq 4 ]; then + exit_error "Invalid Input" + fi +} + +# +# file templates +# + +# template_README compilation instructions +# template_mdk simulink sub-system model + +# template_mex_ae_c +# template_sfun_c +# template_sfun_debug_h +# template_sfun_input_c +# template_sfun_interface_c + +write_template () +{ + filename="$1" + + case $filename in + + README) + + cat < model without using MTT: + +mex _sfun.c + +The input block can be created with: + +mex _sfun_input.c + +If numerical solution of algebraic equations is also required: + +mex _sfun_ae.c + +The interface block can be created with + +mex _sfun_interface.c + +EOF + ;; + + mdl) + + cat <" + Version 4.00 + SampleTimeColors off + LibraryLinkDisplay "all" + WideLines off + ShowLineDimensions on + ShowPortDataTypes off + ShowStorageClass off + ExecutionOrder off + RecordCoverage off + CovPath "/" + CovSaveName "covdata" + CovMetricSettings "dw" + CovNameIncrementing off + CovHtmlReporting on + BlockNameDataTip off + BlockParametersDataTip off + BlockDescriptionStringDataTip off + ToolBar on + StatusBar on + BrowserShowLibraryLinks off + BrowserLookUnderMasks off + Created "Mon May 20 13:21:21 2002" + Creator "geraint" + UpdateHistory "UpdateHistoryNever" + ModifiedByFormat "%" + LastModifiedBy "geraint" + ModifiedDateFormat "%" + LastModifiedDate "Thu May 23 16:35:42 2002" + ModelVersionFormat "1.%" + ConfigurationManager "None" + SimParamPage "Solver" + StartTime "0.0" + StopTime "10.0" + SolverMode "Auto" + Solver "ode45" + RelTol "1e-3" + AbsTol "auto" + Refine "1" + MaxStep "auto" + MinStep "auto" + MaxNumMinSteps "-1" + InitialStep "auto" + FixedStep "auto" + MaxOrder 5 + OutputOption "RefineOutputTimes" + OutputTimes "[]" + LoadExternalInput off + ExternalInput "[t, u]" + SaveTime on + TimeSaveName "tout" + SaveState off + StateSaveName "xout" + SaveOutput on + OutputSaveName "yout" + LoadInitialState off + InitialState "xInitial" + SaveFinalState off + FinalStateName "xFinal" + SaveFormat "Array" + LimitDataPoints on + MaxDataPoints "1000" + Decimation "1" + AlgebraicLoopMsg "warning" + MinStepSizeMsg "warning" + UnconnectedInputMsg "warning" + UnconnectedOutputMsg "warning" + UnconnectedLineMsg "warning" + InheritedTsInSrcMsg "warning" + SingleTaskRateTransMsg "none" + MultiTaskRateTransMsg "error" + IntegerOverflowMsg "warning" + CheckForMatrixSingularity "none" + UnnecessaryDatatypeConvMsg "none" + Int32ToFloatConvMsg "warning" + InvalidFcnCallConnMsg "error" + SignalLabelMismatchMsg "none" + LinearizationMsg "none" + VectorMatrixConversionMsg "none" + SfunCompatibilityCheckMsg "none" + BlockPriorityViolationMsg "warning" + ArrayBoundsChecking "none" + ConsistencyChecking "none" + ZeroCross on + Profile off + SimulationMode "normal" + RTWSystemTargetFile "grt.tlc" + RTWInlineParameters off + RTWRetainRTWFile off + RTWTemplateMakefile "grt_default_tmf" + RTWMakeCommand "make_rtw" + RTWGenerateCodeOnly off + TLCProfiler off + TLCDebug off + TLCCoverage off + AccelSystemTargetFile "accel.tlc" + AccelTemplateMakefile "accel_default_tmf" + AccelMakeCommand "make_rtw" + TryForcingSFcnDF off + ExtModeMexFile "ext_comm" + ExtModeBatchMode off + ExtModeTrigType "manual" + ExtModeTrigMode "normal" + ExtModeTrigPort "1" + ExtModeTrigElement "any" + ExtModeTrigDuration 1000 + ExtModeTrigHoldOff 0 + ExtModeTrigDelay 0 + ExtModeTrigDirection "rising" + ExtModeTrigLevel 0 + ExtModeArchiveMode "off" + ExtModeAutoIncOneShot off + ExtModeIncDirWhenArm off + ExtModeAddSuffixToVar off + ExtModeWriteAllDataToWs off + ExtModeArmWhenConnect on + ExtModeSkipDownloadWhenConnect off + ExtModeLogAll on + ExtModeAutoUpdateStatusClock off + OptimizeBlockIOStorage on + BufferReuse on + ParameterPooling on + BlockReductionOpt on + RTWExpressionDepthLimit 5 + BooleanDataType off + BlockDefaults { + Orientation "right" + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + NamePlacement "normal" + FontName "Helvetica" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + ShowName on + } + AnnotationDefaults { + HorizontalAlignment "center" + VerticalAlignment "middle" + ForegroundColor "black" + BackgroundColor "white" + DropShadow off + FontName "Helvetica" + FontSize 10 + FontWeight "normal" + FontAngle "normal" + } + LineDefaults { + FontName "Helvetica" + FontSize 9 + FontWeight "normal" + FontAngle "normal" + } + System { + Name "" + Location [51, 441, 346, 574] + Open on + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "usletter" + PaperUnits "inches" + ZoomFactor "100" + ReportName "simulink-default.rpt" + Block { + BlockType Inport + Name "In1" + Position [25, 43, 55, 57] + Port "1" + LatchInput off + DataType "double" + SignalType "real" + Interpolate on + } + Block { + BlockType SubSystem + Name "MTT Model\n" + Ports [1, 1] + Position [100, 20, 140, 80] + ForegroundColor "blue" + BackgroundColor "lightBlue" + ShowPortLabels on + TreatAsAtomicUnit off + RTWSystemCode "Auto" + RTWFcnNameOpts "Auto" + RTWFileNameOpts "Auto" + System { + Name "MTT Model\n" + Location [45, 448, 1008, 720] + Open off + ModelBrowserVisibility off + ModelBrowserWidth 200 + ScreenColor "white" + PaperOrientation "landscape" + PaperPositionMode "auto" + PaperType "usletter" + PaperUnits "inches" + ZoomFactor "100" + Block { + BlockType Inport + Name "In1" + Position [590, 203, 620, 217] + Port "1" + LatchInput off + DataType "double" + SignalType "real" + Interpolate on + } + Block { + BlockType "S-Function" + Name "MTT Model Inputs" + Ports [1, 1] + Position [390, 59, 565, 91] + BackgroundColor "lightBlue" + DropShadow on + FunctionName "_sfun_input" + PortCounts "[]" + SFunctionModules "''" + Port { + PortNumber 1 + Name "MTT Model Inputs: MTTU" + TestPoint off + LinearAnalysisOutput off + LinearAnalysisInput off + RTWStorageClass "Auto" + } + } + Block { + BlockType "S-Function" + Name "MTT Plant Model" + Ports [1, 2] + Position [65, 61, 250, 199] + BackgroundColor "lightBlue" + DropShadow on + FunctionName "_sfun" + PortCounts "[]" + SFunctionModules "''" + Port { + PortNumber 1 + Name "MTT Model States: MTTX" + TestPoint off + LinearAnalysisOutput off + LinearAnalysisInput off + RTWStorageClass "Auto" + } + Port { + PortNumber 2 + Name "MTT Model Outputs: MTTY" + TestPoint off + LinearAnalysisOutput off + LinearAnalysisInput off + RTWStorageClass "Auto" + } + } + Block { + BlockType "S-Function" + Name "S-Function" + Ports [4, 2] + Position [710, 47, 840, 238] + BackgroundColor "lightBlue" + DropShadow on + FunctionName "_sfun_interface" + PortCounts "[]" + SFunctionModules "''" + } + Block { + BlockType Outport + Name "Out1" + Position [905, 183, 935, 197] + Port "1" + OutputWhenDisabled "held" + InitialOutput "[]" + } + Line { + Name "MTT Model States: MTTX" + Labels [2, 0] + SrcBlock "MTT Plant Model" + SrcPort 1 + Points [0, 0; 105, 0] + Branch { + Points [0, -20] + DstBlock "MTT Model Inputs" + DstPort 1 + } + Branch { + Points [0, 25] + DstBlock "S-Function" + DstPort 2 + } + } + Line { + Name "MTT Model Outputs: MTTY" + Labels [1, 0] + SrcBlock "MTT Plant Model" + SrcPort 2 + DstBlock "S-Function" + DstPort 3 + } + Line { + Name "MTT Model Inputs: MTTU" + Labels [1, 0] + SrcBlock "MTT Model Inputs" + SrcPort 1 + DstBlock "S-Function" + DstPort 1 + } + Line { + SrcBlock "S-Function" + SrcPort 1 + Points [30, 0; 0, -70; -850, 0; 0, 105] + DstBlock "MTT Plant Model" + DstPort 1 + } + Line { + SrcBlock "In1" + SrcPort 1 + DstBlock "S-Function" + DstPort 4 + } + Line { + SrcBlock "S-Function" + SrcPort 2 + DstBlock "Out1" + DstPort 1 + } + } + } + Block { + BlockType Outport + Name "Out1" + Position [185, 43, 215, 57] + Port "1" + OutputWhenDisabled "held" + InitialOutput "[]" + } + Line { + SrcBlock "MTT Model\n" + SrcPort 1 + DstBlock "Out1" + DstPort 1 + } + Line { + SrcBlock "In1" + SrcPort 1 + DstBlock "MTT Model\n" + DstPort 1 + } + } +} + +EOF + ;; + + mex_ae.c) + + cat <_sfun_ae.c: + * Matlab mex algebraic equations for + */ + +#include +#include +#include +#include +#include "sfun_debug.h" +#include "_def.h" +#include "_sympar.h" + +/* utility procedures */ + +double * +array_of_double (size_t n) +{ + void *p = calloc (n, sizeof (double)); + if (! p) { + fprintf (stderr, "*** Error: failed to allocate memory\n"); + } + return (double *) p; +} + +/* system equations */ + +static double * +_ae (double *mttyz, + const double *mttx, + const double *mttu, + const double mttt, + const double *mttpar) +{ +#include "_ae.c" + PRINT_LEAVE; +} + +/* generic mex function */ + +#ifdef __cplusplus +extern "C" { +#endif + +void +mexFunction (int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[]) +{ + double *mttyz; /* residuals */ + + double *mttx; /* states */ + double *mttu; /* known + unknown inputs */ + double mttt; /* time */ + double *mttpar; /* parameters */ + + unsigned int i; + double *p; + + PRINT_ENTER; + + mttyz = array_of_double (MTTNYZ); + + mttx = array_of_double (MTTNX); + mttu = array_of_double (MTTNU + MTTNYZ); + mttpar = array_of_double (MTTNPAR); + + /* get trial values */ + p = mxGetPr (prhs[0]); + for (i = 0; i < MTTNYZ; i++) { + mttu[MTTNU + i] = p[i]; + } + + /* get states */ + p = mxGetPr (prhs[1]); + for (i = 0; i < MTTNX; i++) { + mttx[i] = p[i]; + } + + /* get known inputs */ + p = mxGetPr (prhs[2]); + for (i = 0; i < MTTNU; i++) { + mttu[i] = p[i]; + } + + /* get time */ + p = mxGetPr (prhs[3]); + mttt = *p; + + /* get parameters */ + p = mxGetPr (prhs[4]); + for (i = 0; i < MTTNPAR; i++) { + mttpar[i] = p[i]; + } + + /* evaluate residuals */ + _ae (mttyz, mttx, mttu, mttt, mttpar); + + /* return residuals */ + plhs[0] = mxCreateDoubleMatrix (MTTNYZ, 1, mxREAL); + p = mxGetPr (plhs[0]); + for (i = 0; i < MTTNYZ; i++) { + p[i] = mttyz[i]; + } + + /* release memory */ + free (mttx); + free (mttu); + free (mttpar); + free (mttyz); + + PRINT_LEAVE; +} + +#ifdef __cplusplus +} +#endif + +EOF + ;; + + sfun_c) + + cat <_sfun.c: + * Matlab S-function simulation of + */ + +#define S_FUNCTION_NAME _sfun +#define S_FUNCTION_LEVEL 2 + +#include +#include +#include +#include "simstruc.h" +#include "sfun_debug.h" +#include "_def.h" +#include "_sympar.h" + +static double *mttdx; /* pointer to rates */ +static double *mttu; /* pointer to inputs */ +static double *mttpar; /* pointer to parameters */ +static double *mttx; /* pointer to states */ +static double *mtty; /* pointer to outputs */ +static double *mttyz; /* pointer to residuals */ +static double mttt; /* time */ + +static unsigned int i; /* loop counter */ + +/* system equations */ + +static void +_ae (void) +{ +#include "_ae.c" + PRINT_LEAVE; +} + +static void +_numpar (void) +{ +#include "_numpar.c" + PRINT_LEAVE; +} + +static void +_ode (void) +{ +#include "_ode.c" + PRINT_LEAVE; +} + +static void +_odeo (void) +{ +#include "_odeo.c" + PRINT_LEAVE; +} + +static void +_state (void) +{ +#include "_state.c" + PRINT_LEAVE; +} + +/* utility procedures */ + +static double * +array_of_double (size_t n) +{ + void *p = calloc (n, sizeof (double)); + if (! p) { + fprintf (stderr, "*** Error: failed to allocate memory\n"); + } + return (double *) p; +} + +static void +initialise_arrays (void) +{ + PRINT_ENTER; + + mttdx = array_of_double (MTTNX); + mttpar = array_of_double (MTTNPAR); + mttu = array_of_double (MTTNU + MTTNYZ); + mttx = array_of_double (MTTNX); + mtty = array_of_double (MTTNY); + mttyz = array_of_double (MTTNYZ); + + PRINT_LEAVE; +} + +static void +update_states_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + for (i = 0; i < MTTNX; i++) { + mttx[i] = ssGetContStates (S)[i]; + } + PRINT_LEAVE; +} + +static void +update_inputs_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + for (i = 0; i < MTTNU; i++) { + mttu[i] = *ssGetInputPortRealSignalPtrs (S, 0)[i]; + } + PRINT_LEAVE; +} + +static void +update_inputs_from_solver (void) +{ + mxArray *MTT_MATLAB_P; + mxArray *MTT_MATLAB_T; + mxArray *MTT_MATLAB_U; + mxArray *MTT_MATLAB_Ui; + mxArray *MTT_MATLAB_X; + + double *p; + + PRINT_ENTER; + + /* starting value for solver - start with zero */ + MTT_MATLAB_Ui = mxCreateDoubleMatrix (MTTNYZ, 1, mxREAL); + mxSetName (MTT_MATLAB_Ui, "MTT_Ui"); + p = mxGetPr (MTT_MATLAB_Ui); + for (i = 0; i < MTTNYZ; i++) { + p[i] = 0.0; + } + mexPutArray (MTT_MATLAB_Ui, "base"); + + /* put states into matlab workspace */ + MTT_MATLAB_X = mxCreateDoubleMatrix (MTTNX, 1, mxREAL); + mxSetName (MTT_MATLAB_X, "MTT_X"); + p = mxGetPr (MTT_MATLAB_X); + for (i = 0; i < MTTNX; i++) { + p[i] = mttx[i]; + } + mexPutArray (MTT_MATLAB_X, "base"); + + /* put known inputs into matlab workspace */ + MTT_MATLAB_U = mxCreateDoubleMatrix (MTTNU, 1, mxREAL); + mxSetName (MTT_MATLAB_U, "MTT_U"); + p = mxGetPr (MTT_MATLAB_U); + for (i = 0; i < MTTNU; i++) { + p[i] = mttu[i]; + } + mexPutArray (MTT_MATLAB_U, "base"); + + /* put time into matlab workspace */ + MTT_MATLAB_T = mxCreateDoubleMatrix (1, 1, mxREAL); + mxSetName (MTT_MATLAB_T, "MTT_T"); + *mxGetPr (MTT_MATLAB_T) = mttt; + mexPutArray (MTT_MATLAB_T, "base"); + + /* put parameters into matlab workspace */ + MTT_MATLAB_P = mxCreateDoubleMatrix (MTTNPAR, 1, mxREAL); + mxSetName (MTT_MATLAB_P, "MTT_P"); + p = mxGetPr (MTT_MATLAB_P); + for (i = 0; i < MTTNPAR; i++) { + p[i] = mttpar[i]; + } + mexPutArray (MTT_MATLAB_P, "base"); + + /* call fsolve */ + mexEvalString ("MTT_Ui = fsolve (@_sfun_ae, MTT_Ui, optimset('display','off'), MTT_X, MTT_U, MTT_T, MTT_P);"); + + /* retrieve result */ + MTT_MATLAB_Ui = mexGetArray ("MTT_Ui", "base"); + p = mxGetPr (MTT_MATLAB_Ui); + for (i = 0; i < MTTNYZ; i++) { + mttu[MTTNU + i] = p[i]; + } + + /* free memory */ + mxDestroyArray (MTT_MATLAB_P); + mxDestroyArray (MTT_MATLAB_T); + mxDestroyArray (MTT_MATLAB_U); + mxDestroyArray (MTT_MATLAB_Ui); + mxDestroyArray (MTT_MATLAB_X); + + PRINT_LEAVE; +} + +static void +update_simtime_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + mttt = ssGetT (S); + PRINT_LEAVE; +} + +/* S-function methods */ + +static void mdlInitializeSizes(SimStruct *S) +{ + PRINT_ENTER; + + ssSetNumSFcnParams(S, 0); + if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { + PRINT_LEAVE; + return; + } + + ssSetNumContStates(S, MTTNX); + ssSetNumDiscStates(S, 0); + + if (!ssSetNumInputPorts(S, 1)) return; + ssSetInputPortWidth(S, 0, MTTNU); + ssSetInputPortDirectFeedThrough(S, 0, 1); + + if (!ssSetNumOutputPorts(S, 2)) return; + ssSetOutputPortWidth(S, 0, MTTNX); + ssSetOutputPortWidth(S, 1, MTTNY); + + ssSetNumSampleTimes(S, 1); + ssSetNumRWork(S, 0); + ssSetNumIWork(S, 0); + ssSetNumPWork(S, 0); + ssSetNumModes(S, 0); + ssSetNumNonsampledZCs(S, 0); + + ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); + + initialise_arrays (); + + PRINT_LEAVE; +} + +static void mdlInitializeSampleTimes(SimStruct *S) +{ + PRINT_ENTER; + + ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); + ssSetOffsetTime(S, 0, 0.0); + + PRINT_LEAVE; +} + +#define MDL_INITIALIZE_CONDITIONS +static void mdlInitializeConditions(SimStruct *S) +{ + PRINT_ENTER; + + _numpar (); + _state (); + + for (i = 0; i < MTTNX; i++) { + ssGetContStates (S)[i] = mttx[i]; + } + + PRINT_LEAVE; +} + +static void mdlOutputs(SimStruct *S, int_T tid) +{ + PRINT_ENTER; + + update_states_from_simulink (S); + update_inputs_from_simulink (S); + if (MTTNYZ > 0) { + update_inputs_from_solver (); + } + update_simtime_from_simulink (S); + + UNUSED_ARG(tid); /* not used in single tasking mode */ + + _odeo (); + + for (i = 0; i < MTTNX; i++) { + ssGetOutputPortRealSignal (S, 0)[i] = mttx[i]; + } + + for (i = 0; i < MTTNY; i++) { + ssGetOutputPortRealSignal (S, 1)[i] = mtty[i]; + } + + PRINT_LEAVE; +} + +#define MDL_DERIVATIVES +static void mdlDerivatives(SimStruct *S) +{ + PRINT_ENTER; + + update_states_from_simulink (S); + update_inputs_from_simulink (S); + if (MTTNYZ > 0) { + update_inputs_from_solver (); + } + update_simtime_from_simulink (S); + + _ode (); + + for (i = 0; i < MTTNX; i++) { + ssGetdX (S)[i] = mttdx[i]; + } + + PRINT_LEAVE; +} + +static void mdlTerminate(SimStruct *S) +{ + PRINT_ENTER; + UNUSED_ARG(S); + + free (mttdx); + free (mttpar); + free (mttu); + free (mttx); + free (mtty); + free (mttyz); + + PRINT_LEAVE; +} + +#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 + +EOF + ;; + + sfun_debug.h) + + cat < +#define PRINT_ENTER fprintf (stderr, "debug> Entered '%s'\n", __FUNCTION__); +#define PRINT_LEAVE fprintf (stderr, "debug> Leaving '%s'\n", __FUNCTION__); + +#elif defined DEBUG && ! defined __GNUC__ + +#include +#define PRINT_ENTER fprintf (stderr, "debug> Entered a function\n"); +#define PRINT_LEAVE fprintf (stderr, "debug> Leaving a function\n"); + +#elif ! defined DEBUG + +#define PRINT_ENTER +#define PRINT_LEAVE + +#else + +#error "Momentary lapse of logic : unreachable statement reached" + +#endif + + +#endif /* HAVE_SFUN_DEBUG_H */ + +EOF + ;; + + sfun_input.c) + + cat <_sfun_input.c: + * Matlab S-function inputs for + */ + +#define S_FUNCTION_NAME _sfun_input +#define S_FUNCTION_LEVEL 2 + +#include +#include +#include +#include "simstruc.h" +#include "sfun_debug.h" +#include "_def.h" +#include "_sympar.h" + +static double *mttu; /* pointer to inputs */ +static double *mttpar; /* pointer to parameters */ +static double *mttx; /* pointer to states */ +static double *mtty; /* pointer to outputs */ +static double mttt; /* time */ + +static unsigned int i; /* loop counter */ + +/* system equations */ + +static void +_input (void) +{ +#include "_input.c" + PRINT_LEAVE; +} + +static void +_numpar (void) +{ +#include "_numpar.c" + PRINT_LEAVE; +} + +/* utility procedures */ + +static double * +array_of_double (size_t n) +{ + void *p = calloc (n, sizeof (double)); + if (! p) { + fprintf (stderr, "*** Error: failed to allocate memory\n"); + } + return (double *) p; +} + +static void +initialise_arrays (void) +{ + PRINT_ENTER; + + mttpar = array_of_double (MTTNPAR); + mttu = array_of_double (MTTNU + MTTNYZ); + mttx = array_of_double (MTTNX); + mtty = array_of_double (MTTNY); + + PRINT_LEAVE; +} + +static void +update_inputs_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + for (i = 0; i < MTTNX; i++) { + mttx[i] = *ssGetInputPortRealSignalPtrs (S, 0)[i]; + } + PRINT_LEAVE; +} + +static void +update_simtime_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + mttt = ssGetT (S); + PRINT_LEAVE; +} + +/* S-function methods */ + +static void mdlInitializeSizes(SimStruct *S) +{ + PRINT_ENTER; + + ssSetNumSFcnParams(S, 0); + if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { + PRINT_LEAVE; + return; + } + + ssSetNumContStates(S, 0); + ssSetNumDiscStates(S, 0); + + if (!ssSetNumInputPorts(S, 1)) return; + ssSetInputPortWidth(S, 0, MTTNX); + ssSetInputPortDirectFeedThrough(S, 0, 1); + + if (!ssSetNumOutputPorts(S, 1)) return; + ssSetOutputPortWidth(S, 0, MTTNU); + + ssSetNumSampleTimes(S, 1); + ssSetNumRWork(S, 0); + ssSetNumIWork(S, 0); + ssSetNumPWork(S, 0); + ssSetNumModes(S, 0); + ssSetNumNonsampledZCs(S, 0); + + ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); + + initialise_arrays (); + + PRINT_LEAVE; +} + +static void mdlInitializeSampleTimes(SimStruct *S) +{ + PRINT_ENTER; + ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); + ssSetOffsetTime(S, 0, 0.0); + PRINT_LEAVE; +} + +#define MDL_INITIALIZE_CONDITIONS +static void mdlInitializeConditions(SimStruct *S) +{ + PRINT_ENTER; + _numpar (); + PRINT_LEAVE; +} + +static void mdlOutputs(SimStruct *S, int_T tid) +{ + PRINT_ENTER; + + update_inputs_from_simulink (S); + update_simtime_from_simulink (S); + + UNUSED_ARG(tid); /* not used in single tasking mode */ + + _input (); + + for (i = 0; i < MTTNU; i++) { + ssGetOutputPortRealSignal (S, 0)[i] = mttu[i]; + } + + PRINT_LEAVE; +} + +#define MDL_DERIVATIVES +static void mdlDerivatives(SimStruct *S) +{ + PRINT_ENTER; + + update_inputs_from_simulink (S); + update_simtime_from_simulink (S); + + PRINT_LEAVE; +} + +static void mdlTerminate(SimStruct *S) +{ + PRINT_ENTER; + + UNUSED_ARG(S); + + free (mttpar); + free (mttu); + free (mttx); + free (mtty); + + PRINT_LEAVE; +} + +#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 + +EOF + ;; + + sfun_interface.c) + + cat <_sfun_interface.c: + * Matlab S-function to process inputs and outputs of + */ + + +#define S_FUNCTION_NAME _sfun_interface +#define S_FUNCTION_LEVEL 2 + +#include +#include +#include +#include "simstruc.h" +#include "sfun_debug.h" +#include "_def.h" +#include "_sympar.h" + +static double *mttu; /* pointer to inputs */ +static double *mttpar; /* pointer to parameters */ +static double *mttx; /* pointer to states */ +static double *mtty; /* pointer to outputs */ +static double mttt; /* time */ + +static double *controller_inputs; +static double *controller_outputs; + +static unsigned int i; /* loop counter */ + +/* Start EDIT */ +/* Edit this block to define the number of controller inputs, outputs and parameters */ +const int NumberOfControllerInputs = 1; /* inputs TO controller */ +const int NumberOfControllerOutputs = 1; /* outputs FROM controller */ +/* End EDIT */ + +static void +_process_inputs (void) +{ + /* insert _struc.c */ + + /* Start EDIT */ + /* Edit this block to process the model inputs and outputs */ + + /* Remove the following line */ + fprintf (stderr, "*** Error: _sfun_interface.c has not been customised!\n"); return; + + /* simple example follows */ + + /* Get total of all outputs and input to controller */ + controller_inputs[0] = 0.0; + for (i = 0; i < MTTNY; i++) { + controller_inputs[0] += mtty[i]; + } + + /* overwrite first model input with output from controller */ + mttu[0] = controller_outputs[0]; + + /* End EDIT */ +} + + +/****************************************************************************** + * DO NOT EDIT ANYTHING BELOW THIS LINE * + ******************************************************************************/ + +/* system equations */ + +static void +_numpar (void) +{ +#include "_numpar.c" + PRINT_LEAVE; +} + +/* utility procedures */ + +static double * +array_of_double (size_t n) +{ + void *p = calloc (n, sizeof (double)); + if (! p) { + fprintf (stderr, "*** Error: failed to allocate memory\n"); + } + return (double *) p; +} + +static void +initialise_arrays (void) +{ + PRINT_ENTER; + + mttpar = array_of_double (MTTNPAR); + mttu = array_of_double (MTTNU + MTTNYZ); + mttx = array_of_double (MTTNX); + mtty = array_of_double (MTTNY); + + controller_inputs = array_of_double (NumberOfControllerInputs); + controller_outputs = array_of_double (NumberOfControllerOutputs); + + PRINT_LEAVE; +} + +static void +update_inputs_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + for (i = 0; i < MTTNU; i++) { + mttu[i] = *ssGetInputPortRealSignalPtrs (S, 0)[i]; + } + for (i = 0; i < MTTNX; i++) { + mttx[i] = *ssGetInputPortRealSignalPtrs (S, 1)[i]; + } + for (i = 0; i < MTTNY; i++) { + mtty[i] = *ssGetInputPortRealSignalPtrs (S, 2)[i]; + } + for (i = 0; i < NumberOfControllerOutputs; i++) { + controller_outputs[i] = *ssGetInputPortRealSignalPtrs (S, 3)[i]; + } + PRINT_LEAVE; +} + +static void +update_simtime_from_simulink (SimStruct *S) +{ + PRINT_ENTER; + mttt = ssGetT (S); + PRINT_LEAVE; +} + +/* S-function methods */ + +static void mdlInitializeSizes(SimStruct *S) +{ + PRINT_ENTER; + + ssSetNumSFcnParams(S, 0); + if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { + PRINT_LEAVE; + return; + } + + ssSetNumContStates(S, 0); + ssSetNumDiscStates(S, 0); + + if (!ssSetNumInputPorts(S, 4)) return; + ssSetInputPortWidth(S, 0, MTTNU); + ssSetInputPortWidth(S, 1, MTTNX); + ssSetInputPortWidth(S, 2, MTTNY); + ssSetInputPortWidth(S, 3, NumberOfControllerOutputs); /* inputs from controller */ + ssSetInputPortDirectFeedThrough(S, 0, 1); + ssSetInputPortDirectFeedThrough(S, 1, 1); + ssSetInputPortDirectFeedThrough(S, 2, 1); + ssSetInputPortDirectFeedThrough(S, 3, 1); + + if (!ssSetNumOutputPorts(S, 2)) return; + ssSetOutputPortWidth(S, 0, MTTNU); /* altered inputs */ + ssSetOutputPortWidth(S, 1, NumberOfControllerInputs); /* outputs to controller */ + + ssSetNumSampleTimes(S, 1); + ssSetNumRWork(S, 0); + ssSetNumIWork(S, 0); + ssSetNumPWork(S, 0); + ssSetNumModes(S, 0); + ssSetNumNonsampledZCs(S, 0); + + ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); + + initialise_arrays (); + + PRINT_LEAVE; +} + +static void mdlInitializeSampleTimes(SimStruct *S) +{ + PRINT_ENTER; + ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); + ssSetOffsetTime(S, 0, 0.0); + PRINT_LEAVE; +} + +#define MDL_INITIALIZE_CONDITIONS +static void mdlInitializeConditions(SimStruct *S) +{ + PRINT_ENTER; + _numpar (); + PRINT_LEAVE; +} + +static void mdlOutputs(SimStruct *S, int_T tid) +{ + PRINT_ENTER; + + update_inputs_from_simulink (S); + update_simtime_from_simulink (S); + + _process_inputs (); + + UNUSED_ARG(tid); /* not used in single tasking mode */ + + for (i = 0; i < MTTNU; i++) { + ssGetOutputPortRealSignal (S, 0)[i] = mttu[i]; + } + + for (i = 0; i < NumberOfControllerInputs; i++) { + ssGetOutputPortRealSignal (S, 1)[i] = controller_inputs[i]; + } + + PRINT_LEAVE; +} + +#define MDL_DERIVATIVES +static void mdlDerivatives(SimStruct *S) +{ + PRINT_ENTER; + PRINT_LEAVE; +} + +static void mdlTerminate(SimStruct *S) +{ + PRINT_ENTER; + + UNUSED_ARG(S); + + free (mttpar); + free (mttu); + free (mttx); + free (mtty); + + free (controller_inputs); + free (controller_outputs); + + PRINT_LEAVE; +} + +#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 + +EOF + ;; + + *) + exit_error "Unknown Template"; + ;; + + esac +} + + + + + + + +### main program + +set_debug 0 +check_for_valid_input "$*" OPTS="$1" SYS="$2" REP="$3" LANG="$4" make $make_debug -f ${MTT_REP}/sfun_rep/Makefile ${2}_${3}.${4} exit 0