/* -*-c-*- Put emacs into c-mode
* <mtt_model_name>_sfun_interface.c:
* Matlab S-function to process inputs and outputs of <mtt_model_name>
*/
#define S_FUNCTION_NAME <mtt_model_name>_sfun_interface
#define S_FUNCTION_LEVEL 2
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "simstruc.h"
#include "sfun_debug.h"
#include "useful-functions.hh"
#include "<mtt_model_name>_def.h"
#include "<mtt_model_name>_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 *MTT_outputs;
static double *MTT_inputs;
static unsigned int i; /* loop counter */
/* Start EDIT */
/* Edit this block to define the number of simulink inputs, outputs and parameters */
#define NumberOfSimulinkInputs MTTNY /* MTT outputs */
#define NumberOfSimulinkOutputs MTTNU /* MTT inputs */
/* End EDIT */
static void
<mtt_model_name>_process_inputs (SimStruct *S)
{
/* insert <mtt_model_name>_struc.c */
/* Start EDIT */
/* Edit this block to process the model inputs and outputs */
/* Error messages can be set using the following line */
/* ssSetErrorStatus (S, "<mtt_model_name>_some error message!\n"); */
/* Default is to expose all MTT inputs, outputs and states */
/* Get all the MTT model outputs and pass them to simulink */
for (i = 0; i < NumberOfSimulinkInputs; i++) {
MTT_outputs[i] = mtty[i];
}
/* Get all inputs from Simulink and pass them to the MTT model */
/* Any inputs not over-written here will be read from <mtt_model_name>_input.c */
for (i = 0; i < NumberOfSimulinkOutputs; i++) {
mttu[i] = MTT_inputs[i];
}
/* End EDIT */
}
/******************************************************************************
* DO NOT EDIT ANYTHING BELOW THIS LINE *
******************************************************************************/
/* system equations */
static void
<mtt_model_name>_numpar (void)
{
#include "<mtt_model_name>_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
check_finite(SimStruct *S, double *array, unsigned int index)
{
const char *array_name;
char warning[128];
if ((array[index] <= 0.0) || (array[index] >= 0.0)) {
; /* no problem */
} else {
if (array == mttpar) {
array_name = "mttpar";
} else if (array == mttu) {
array_name = "mttu";
} else if (array == mttx) {
array_name = "mttx";
} else if (array == mtty) {
array_name = "mtty";
} else if (array == MTT_outputs) {
array_name = "MTT_outputs";
} else if (array == MTT_inputs) {
array_name = "MTT_inputs";
} else {
array_name = "unknown_array";
}
sprintf(warning, "(time %f) Non-finite array element: %s[%d]\n", mttt, array_name, index);
ssWarning(S, warning);
}
}
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);
MTT_outputs = array_of_double (NumberOfSimulinkInputs);
MTT_inputs = array_of_double (NumberOfSimulinkOutputs);
PRINT_LEAVE;
}
static void
update_inputs_from_simulink (SimStruct *S)
{
PRINT_ENTER;
for (i = 0; i < MTTNU; i++) {
mttu[i] = *ssGetInputPortRealSignalPtrs (S, 0)[i];
check_finite(S, mttu, i);
}
for (i = 0; i < MTTNX; i++) {
mttx[i] = *ssGetInputPortRealSignalPtrs (S, 1)[i];
check_finite(S, mttx, i);
}
for (i = 0; i < MTTNY; i++) {
mtty[i] = *ssGetInputPortRealSignalPtrs (S, 2)[i];
check_finite(S, mtty, i);
}
for (i = 0; i < NumberOfSimulinkOutputs; i++) {
MTT_inputs[i] = *ssGetInputPortRealSignalPtrs (S, 3)[i];
check_finite(S, MTT_inputs, 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, NumberOfSimulinkOutputs); /* inputs from simulink */
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, NumberOfSimulinkInputs); /* outputs to simulink */
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;
<mtt_model_name>_numpar ();
PRINT_LEAVE;
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
PRINT_ENTER;
update_inputs_from_simulink (S);
update_simtime_from_simulink (S);
<mtt_model_name>_process_inputs (S);
UNUSED_ARG(tid); /* not used in single tasking mode */
for (i = 0; i < MTTNU; i++) {
check_finite(S, mttu, i);
ssGetOutputPortRealSignal (S, 0)[i] = mttu[i];
}
for (i = 0; i < NumberOfSimulinkInputs; i++) {
check_finite(S, MTT_outputs, i);
ssGetOutputPortRealSignal (S, 1)[i] = MTT_outputs[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 (MTT_outputs);
free (MTT_inputs);
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