Skip to content

Commit

Permalink
Adapt rtwsfcnfmi.tlc for R2022b
Browse files Browse the repository at this point in the history
and use integer MATLAB_VERSION

fixes #371
  • Loading branch information
t-sommer committed Oct 12, 2022
1 parent e473260 commit cd8cc24
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 57 deletions.
8 changes: 4 additions & 4 deletions rtwsfcnfmi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ cmake_minimum_required (VERSION 3.22)
set(MODEL_NAME "" CACHE STRING "Model name")
set(SOLVER "ode1" CACHE STRING "Solver")
set_property(CACHE SOLVER PROPERTY STRINGS ode1 ode2 ode3 ode4 ode5 ode8 ode14x)
set(MATLAB_ROOT "C:/Program Files/MATLAB/R2019b" CACHE STRING "MATLAB install directory")
set(MATLAB_VERSION "MATLAB_R2017b_" CACHE STRING "MATLAB version for conditional compilation")
set(MATLAB_ROOT "C:/Program Files/MATLAB/R2022b" CACHE STRING "MATLAB install directory")
set(MATLAB_VERSION "913" CACHE STRING "MATLAB version for conditional compilation")
set(RTW_DIR "" CACHE STRING "RTW generated model directory")
set(CUSTOM_INCLUDE "" CACHE STRING "Additional include directories")
set(CUSTOM_SOURCE "" CACHE STRING "Additional source files")
Expand Down Expand Up @@ -72,7 +72,7 @@ if (EXISTS "${RTW_DIR}/rt_zcfcn.c")
endif ()

if (NOT LOAD_MEX)
set (MODEL_SOURCES ${MODEL_SOURCES} "${MATLAB_ROOT}/rtw/c/src/rt_matrx.c")
set (MODEL_SOURCES ${MODEL_SOURCES} rt_matrx_wrapper.c)
endif ()

add_library(${MODEL_NAME} SHARED
Expand Down Expand Up @@ -112,7 +112,7 @@ target_compile_definitions(${MODEL_NAME} PRIVATE
rt_matrx_h
RT_MALLOC
NDEBUG
${MATLAB_VERSION}
MATLAB_VERSION=${MATLAB_VERSION}
)

# don't add the "lib" prefix to the shared library
Expand Down
4 changes: 4 additions & 0 deletions rtwsfcnfmi/rt_matrx_wrapper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "rtwtypes.h" /* needed for real_T */
#include "rt_mxclassid.h" /* needed for mxClassID */

#include "rt_matrx.c"
21 changes: 11 additions & 10 deletions rtwsfcnfmi/rtwsfcnfmi_make_rtw_hook.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,21 @@ function rtwsfcnfmi_make_rtw_hook(hookMethod, modelName, rtwRoot, templateMakefi
command = get_param(modelName, 'CMakeCommand');
command = grtfmi_find_cmake(command);
generator = get_param(modelName, 'CMakeGenerator');
toolset = get_param(modelName, 'CMakeToolset');
toolset = get_param(modelName, 'CMakeToolset');
build_configuration = get_param(modelName, 'CMakeBuildConfiguration');

version = str2double(ver('MATLAB').Version);

major_version = floor(version);
minor_version = num2str((version - major_version) * 100);

% MATLAB version for conditional compilation
if verLessThan('matlab', '7.12')
matlab_version = ''; % do nothing
elseif verLessThan('matlab', '8.5')
matlab_version = 'MATLAB_R2011a_'; % R2011a - R2014b
elseif verLessThan('matlab', '9.3')
matlab_version = 'MATLAB_R2015a_'; % R2015a - R2017a
elseif verLessThan('matlab', '9.8')
matlab_version = 'MATLAB_R2017b_'; % R2017b - R2019b
matlab_version = num2str(major_version);

if strcmp(minor_version(2), '0')
matlab_version = [matlab_version '0' minor_version(1)];
else
matlab_version = 'MATLAB_R2020a_'; % R2020a and later
matlab_version = [matlab_version minor_version];
end

solver = get_param(modelName, 'Solver');
Expand Down
105 changes: 62 additions & 43 deletions rtwsfcnfmi/sfunction.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include "sfunction.h"
#include "model_interface.h"

// MATLAB versions for conditional compilation
#define R2020b 908
#define R2017b 903

Model* currentModel = NULL;

const char* _SFCN_FMI_MATLAB_BIN = NULL;
Expand Down Expand Up @@ -207,45 +211,50 @@ Model *InstantiateModel(const char* instanceName, logMessageCallback logMessage,
currentModel = model;
}

model->S = CreateSimStructForFMI(model->instanceName);
if (model->S == NULL) {
SimStruct* S = CreateSimStructForFMI(model->instanceName);

if (S == NULL) {
goto fail;
}

model->S = S;

/* Register model callback functions in Simstruct */
sfcn_fmi_registerMdlCallbacks_(model->S);
sfcn_fmi_registerMdlCallbacks_(S);

/* Initialize sizes and create vectors */
sfcnInitializeSizes(model->S);
sfcnInitializeSizes(S);
allocateSimStructVectors(model);

/* Create solver data and ZC vector */
rt_CreateIntegrationData(model->S);
model->S->mdlInfo->solverInfo->zcSignalVector = (real_T*)calloc(SFCN_FMI_ZC_LENGTH + 1, sizeof(real_T));
model->S->states.nonsampledZCs = model->S->mdlInfo->solverInfo->zcSignalVector;
rt_CreateIntegrationData(S);
S->mdlInfo->solverInfo->numContStatesPtr = ssGetNumContStatesPtr(S);
S->mdlInfo->solverInfo->zcSignalVector = (real_T*)calloc(SFCN_FMI_ZC_LENGTH + 1, sizeof(real_T));
S->states.nonsampledZCs = S->mdlInfo->solverInfo->zcSignalVector;

/* Register model callback for ODE solver */
sfcn_fmi_registerRTModelCallbacks_(model->S);
sfcn_fmi_registerRTModelCallbacks_(S);

/* Initialize sample times and sample flags */
sfcnInitializeSampleTimes(model->S);
sfcnInitializeSampleTimes(S);
setSampleStartValues(model);

/* non-finites */
rt_InitInfAndNaN(sizeof(real_T));
/* Create and initialize global tunable parameters */
sfcn_fmi_mxGlobalTunable_(model->S, 1, 0);
sfcn_fmi_mxGlobalTunable_(S, 1, 0);
/* Call mdlStart */
if (ssGetmdlStart(model->S) != NULL) {
sfcnStart(model->S);
if (ssGetmdlStart(S) != NULL) {
sfcnStart(S);
}

/* Allocate model vectors */
model->oldZC = (real_T*)calloc(SFCN_FMI_ZC_LENGTH + 1, sizeof(real_T));
model->numSampleHits = (int_T*)calloc(model->S->sizes.numSampleTimes + 1, sizeof(int_T));
model->numSampleHits = (int_T*)calloc(S->sizes.numSampleTimes + 1, sizeof(int_T));
// model->inputDerivatives = (real_T*)calloc(SFCN_FMI_NBR_INPUTS + 1, sizeof(real_T));

/* Check Simstruct error status and stop requested */
if ((ssGetErrorStatus(model->S) != NULL) || (ssGetStopRequested(model->S) != 0)) {
if ((ssGetErrorStatus(S) != NULL) || (ssGetStopRequested(S) != 0)) {
goto fail;
}

Expand Down Expand Up @@ -277,14 +286,29 @@ Model *InstantiateModel(const char* instanceName, logMessageCallback logMessage,
SimStruct *CreateSimStructForFMI(const char* instanceName)
{
SimStruct *S = (SimStruct*)calloc(1, sizeof(SimStruct));

if (S == NULL) {
return NULL;
}

S->mdlInfo = (struct _ssMdlInfo*)calloc(1, sizeof(struct _ssMdlInfo));

if (S->mdlInfo == NULL) {
return NULL;
}

S->blkInfo.blkInfo2 = (struct _ssBlkInfo2*)calloc(1, sizeof(struct _ssBlkInfo2));

if (S->blkInfo.blkInfo2 == NULL) {
return NULL;
}

S->blkInfo.blkInfo2->mdlInfoSLSize = (struct _ssMdlInfoSLSize*)calloc(1, sizeof(struct _ssMdlInfoSLSize));

if (S->blkInfo.blkInfo2->mdlInfoSLSize == NULL) {
return NULL;
}

_ssSetRootSS(S, S);
_ssSetSimMode(S, SS_SIMMODE_SIZES_CALL_ONLY);
_ssSetSFcnParamsCount(S, 0);
Expand Down Expand Up @@ -316,12 +340,8 @@ SimStruct *CreateSimStructForFMI(const char* instanceName)
S->blkInfo.block = NULL; /* Accessed by ssSetOutputPortBusMode in mdlInitializeSizes */
S->regDataType.setNumDWorkFcn = setNumDWork_FMI;

#if defined(MATLAB_R2011a_) || defined(MATLAB_R2015a_) || defined(MATLAB_R2017b_) || defined(MATLAB_R2020a_)
S->states.statesInfo2 = (struct _ssStatesInfo2 *) calloc(1, sizeof(struct _ssStatesInfo2));
#if defined(MATLAB_R2015a_) || defined(MATLAB_R2017b_) || defined(MATLAB_R2020a_)
S->states.statesInfo2->periodicStatesInfo = (ssPeriodicStatesInfo *)calloc(1, sizeof(ssPeriodicStatesInfo));
#endif
#endif

return(S);
}
Expand Down Expand Up @@ -367,14 +387,10 @@ void FreeSimStruct(SimStruct *S) {
sfcn_fmi_mxGlobalTunable_(S, 0, 0);
free(S->sfcnParams.dlgParams);

#if defined(MATLAB_R2011a_) || defined(MATLAB_R2015a_) || defined(MATLAB_R2017b_) || defined(MATLAB_R2020a_)
free(S->states.statesInfo2->absTol);
free(S->states.statesInfo2->absTolControl);
#if defined(MATLAB_R2015a_) || defined(MATLAB_R2017b_) || defined(MATLAB_R2020a_)
free(S->states.statesInfo2->periodicStatesInfo);
#endif
free(S->states.statesInfo2);
#endif

if (S->mdlInfo != NULL) {
if (S->mdlInfo->dataTypeAccess != NULL) {
Expand Down Expand Up @@ -501,26 +517,26 @@ static size_t getDataTypeSize(SimStruct *S, BuiltInDTypeId dataTypeId) {
}

void allocateSimStructVectors(Model* m) {
int_T i;
size_t dtypeSize;

SimStruct* S = m->S;

S->states.contStates = (real_T*)calloc(S->sizes.numContStates + 1, sizeof(real_T));
S->states.dX = (real_T*)calloc(S->sizes.numContStates + 1, sizeof(real_T));
/* store pointer, since it will be changed to point to ODE integration data */
m->dX = S->states.dX;
S->states.contStateDisabled = (boolean_T*)calloc(S->sizes.numContStates + 1, sizeof(boolean_T));
S->states.discStates = (real_T* )calloc(S->sizes.numDiscStates + 1, sizeof(real_T));
#if defined(MATLAB_R2011a_) || defined(MATLAB_R2015a_) || defined(MATLAB_R2017b_) || defined(MATLAB_R2020a_)
S->states.statesInfo2->absTol = (real_T* )calloc(S->sizes.numContStates + 1, sizeof(real_T));
S->states.statesInfo2->absTolControl = (uint8_T*)calloc(S->sizes.numContStates + 1, sizeof(uint8_T));
#endif
S->stInfo.sampleTimes = (time_T*)calloc(S->sizes.numSampleTimes + 1, sizeof(time_T));
S->stInfo.offsetTimes = (time_T*)calloc(S->sizes.numSampleTimes + 1, sizeof(time_T));
S->stInfo.sampleTimeTaskIDs = (int_T* )calloc(S->sizes.numSampleTimes + 1, sizeof(int_T));
#if defined(MATLAB_R2020a_)
S->states.contStates = (real_T* )calloc(S->sizes.numContStates + 1, sizeof(real_T));
S->states.dX = (real_T* )calloc(S->sizes.numContStates + 1, sizeof(real_T));
S->states.contStateDisabled = (boolean_T*)calloc(S->sizes.numContStates + 1, sizeof(boolean_T));
S->states.discStates = (real_T* )calloc(S->sizes.numDiscStates + 1, sizeof(real_T));
S->states.statesInfo2->absTol = (real_T* )calloc(S->sizes.numContStates + 1, sizeof(real_T));
S->states.statesInfo2->absTolControl = (uint8_T* )calloc(S->sizes.numContStates + 1, sizeof(uint8_T));
#if MATLAB_VERSION >= R2020b
S->states.statesInfo2->jacPerturbBounds = (ssJacobianPerturbationBounds*)calloc(1, sizeof(ssJacobianPerturbationBounds));
#endif

/* store pointer, since it will be changed to point to ODE integration data */
m->dX = S->states.dX;

S->stInfo.sampleTimes = (time_T*)calloc(S->sizes.numSampleTimes + 1, sizeof(time_T));
S->stInfo.offsetTimes = (time_T*)calloc(S->sizes.numSampleTimes + 1, sizeof(time_T));
S->stInfo.sampleTimeTaskIDs = (int_T* )calloc(S->sizes.numSampleTimes + 1, sizeof(int_T));

/* allocate per-task sample hit matrix */
S->mdlInfo->sampleHits = (int_T* )calloc(S->sizes.numSampleTimes*S->sizes.numSampleTimes + 1, sizeof(int_T));
S->mdlInfo->perTaskSampleHits = S->mdlInfo->sampleHits;
Expand All @@ -529,14 +545,17 @@ void allocateSimStructVectors(Model* m) {
S->work.iWork = (int_T* )calloc(S->sizes.numIWork + 1, sizeof(int_T));
S->work.pWork = (void** )calloc(S->sizes.numPWork + 1, sizeof(void*));
S->work.rWork = (real_T*)calloc(S->sizes.numRWork + 1, sizeof(real_T));
for (i = 0; i < S->sizes.in.numInputPorts; i++) {

for (int_T i = 0; i < S->sizes.in.numInputPorts; i++) {
SetInputPortDimensionInfoFcn_FMI(S, i);
}
for (i = 0; i < S->sizes.out.numOutputPorts; i++) {

for (int_T i = 0; i < S->sizes.out.numOutputPorts; i++) {
SetOutputPortDimensionInfoFcn_FMI(S, i);
}
for (i = 0; i < S->sizes.numDWork; i++) {
dtypeSize = getDataTypeSize(S, S->work.dWork.sfcn[i].dataTypeId);

for (int_T i = 0; i < S->sizes.numDWork; i++) {
size_t dtypeSize = getDataTypeSize(S, S->work.dWork.sfcn[i].dataTypeId);
S->work.dWork.sfcn[i].array = calloc(S->work.dWork.sfcn[i].width + 1, dtypeSize);
}
}
Expand Down Expand Up @@ -886,7 +905,7 @@ void NewDiscreteStates(Model *model, int *valuesOfContinuousStatesChanged, real_

model->shouldRecompute = 1;

#if defined(MATLAB_R2017b_) || defined(MATLAB_R2020a_)
#if MATLAB_VERSION >= R2017b
if (model->S->mdlInfo->mdlFlags.blockStateForSolverChangedAtMajorStep) {
model->S->mdlInfo->mdlFlags.blockStateForSolverChangedAtMajorStep = 0U;
#else
Expand Down
14 changes: 14 additions & 0 deletions rtwsfcnfmi/sfunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@
#define SFCN_FMI_MAX_TIME 1e100
#define SFCN_FMI_EPS 2e-13 /* Not supported with discrete sample times smaller than this */

#ifndef ssSetRegInputPortDimensionInfoFcn
#define ssSetRegInputPortDimensionInfoFcn(S, fcn) \
(S)->blkInfo.blkInfo2->mdlInfoSLSize->regInputPortDimsInfo = (fcn)
#endif

#ifndef ssSetRegOutputPortDimensionInfoFcn
#define ssSetRegOutputPortDimensionInfoFcn(S, fcn) \
(S)->blkInfo.blkInfo2->mdlInfoSLSize->regOutputPortDimsInfo = (fcn)
#endif

#ifndef ssGetNumContStatesPtr
#define ssGetNumContStatesPtr(S) &((S)->sizes.numContStates)
#endif


/* Model status */
typedef enum {
Expand Down

0 comments on commit cd8cc24

Please sign in to comment.