// -*-c++-*-
// <mtt_model_name>_sfun.cc:
// Matlab S-function simulation of <mtt_model_name>
#define S_FUNCTION_NAME <mtt_model_name>_sfun
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include <iostream>
#include <string>
#include "<mtt_model_name>_def.h"
mxArray *
get_parameters_from_simulink (SimStruct *S)
{
static const mxArray *constpar = mxCreateDoubleMatrix (MTTNPAR, 1, mxREAL);
static mxArray * par = mxCreateDoubleMatrix (MTTNPAR, 1, mxREAL);
double *constptr;
double *ptr;
std::cerr << "Parameters:\t";
for (int i = 0; i < MTTNPAR; i++) {
constpar = ssGetSFcnParam (S, i);
constptr = mxGetPr (constpar);
ptr = mxGetPr ( par);
*ptr = *constptr;
std::cerr << *ptr << ' ';
}
std::cerr << std::endl;
return par;
}
mxArray *
get_states_from_simulink (SimStruct *S)
{
static mxArray *x = mxCreateDoubleMatrix (MTTNX, 1, mxREAL);
static double *states;
static double *ptr = mxGetPr (x);
std::cerr << "States:\t\t";
states = ssGetContStates (S);
for (int i = 0; i < MTTNX; i++) {
ptr [i] = states [i];
std::cerr << ptr [i] << ' ';
}
std::cerr << std::endl;
return x;
}
mxArray *
get_inputs_from_simulink (SimStruct *S)
{
static mxArray *u = mxCreateDoubleMatrix (MTTNU, 1, mxREAL);
static double *ptr = mxGetPr (u);
std::cerr << "Inputs:\t\t";
for (int i = 0; i < MTTNU; i++) {
ptr [i] = *ssGetInputPortRealSignalPtrs (S, i)[0];
std::cerr << ptr [i] << ' ';
}
std::cerr << std::endl;
return u;
}
mxArray *
get_time_from_simulink (SimStruct *S)
{
static mxArray *t = mxCreateDoubleMatrix (1, 1, mxREAL);
double *ptr = mxGetPr (t);
ptr [0] = ssGetT (S);
std::cerr << "Time:\t\t" << ptr [0] << std::endl;
return t;
}
// S-function methods
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, MTTNPAR);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
ssSetNumContStates(S, MTTNX);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, 1);
for (int i = 0; i < MTTNU; i++) {
ssSetInputPortDirectFeedThrough(S, i, 1);
}
if (!ssSetNumOutputPorts(S, MTTNY)) return;
for (int i = 0; i < MTTNY; i++) {
ssSetOutputPortWidth(S, i, 1);
}
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);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
#define MDL_INITIALIZE_CONDITIONS
static void mdlInitializeConditions(SimStruct *S)
{
static mxArray *states = mxCreateDoubleMatrix (MTTNX, 1, mxREAL);
static double *ptr;
mxArray *plhs[1];
mxArray *prhs[1];
plhs[0] = states;
prhs[0] = get_parameters_from_simulink (S);
mexCallMATLAB (1, plhs, 1, prhs, "<mtt_model_name>_state");
ptr = mxGetPr (plhs[0]);
std::cerr << "Initial states;\t";
for (int i = 0; i < MTTNX; i++) {
ssGetContStates (S)[i] = ptr [i];
std::cerr << ptr [i] << ' ';
}
std::cerr << std::endl;
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
static mxArray *outputs = mxCreateDoubleMatrix (MTTNY, 1, mxREAL);
static double *ptr;
mxArray *plhs[1];
mxArray *prhs[4];
plhs[0] = outputs;
prhs[0] = get_states_from_simulink (S);
prhs[1] = get_inputs_from_simulink (S);
prhs[2] = get_time_from_simulink (S);
prhs[3] = get_parameters_from_simulink (S);
UNUSED_ARG(tid); // not used in single tasking mode
mexCallMATLAB (1, plhs, 4, prhs, "<mtt_model_name>_odeo");
ptr = mxGetPr (plhs [0]);
std::cerr << "Outputs:\t";
for (int i = 0; i < MTTNY; i++) {
ssGetOutputPortRealSignal (S,i)[0] = ptr [i];
std::cerr << ptr [i] << ' ';
}
std::cerr << std::endl;
}
#define MDL_DERIVATIVES
static void mdlDerivatives(SimStruct *S)
{
static mxArray *rates = mxCreateDoubleMatrix (MTTNX, 1, mxREAL);
static double *ptr;
mxArray *plhs[1];
mxArray *prhs[4];
plhs[0] = rates;
prhs[0] = get_states_from_simulink (S);
prhs[1] = get_inputs_from_simulink (S);
prhs[2] = get_time_from_simulink (S);
prhs[3] = get_parameters_from_simulink (S);
mexCallMATLAB (1, plhs, 4, prhs, "<mtt_model_name>_ode");
ptr = mxGetPr (plhs[0]);
std::cerr << "Rates:\t\t";
for (int i = 0; i < MTTNX; i++) {
ssGetdX (S)[i] = ptr [i];
std::cerr << ptr[i] << ' ';
}
std::cerr << std::endl;
}
static void mdlTerminate(SimStruct *S)
{
UNUSED_ARG(S);
}
#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