File mttroot/mtt/lib/rep/sfun_rep/sfun_interface.c.tmpl artifact 8f8ea00a46 part of check-in b3c9364a2b


/* -*-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


MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]