Чтобы сконфигурировать символьные размерности для Блоков s-function, можно использовать следующие функции C/C++. Можно сконфигурировать S-функции, чтобы поддержать прямое распространение, обратное распространение или прямое и обратное распространение символьных размерностей в процессе моделирования.
Многие из этих функций возвращают переменную SymbDimsId
. SymbDimsId
уникальное целочисленное значение. Это значение соответствует каждой символьной спецификации размерности, которую вы создаете, или результат математической операции, которую вы выполняете с символьными размерностями.
S-функции C/C++ | Цель |
---|---|
Задайте, поддерживает ли S-функция символьные размерности. | |
Задайте символьные размерности входного порта и как те размерности распространяют вперед. | |
Задайте символьные размерности выходного порта и как те размерности распространяют назад. | |
Создайте | |
Создайте | |
Создайте | |
Создайте | |
Создайте | |
Создайте | |
Создайте | |
Создайте | |
Получите количество размерностей для | |
Получите | |
Установите предварительно скомпилированный | |
Получите скомпилированный | |
Установите скомпилированный | |
Установите предварительно скомпилированный | |
Получите скомпилированный | |
Установите скомпилированный | |
Установите скомпилированный |
Модель ex_msymbdims_sfcn_one
содержит S-функцию, которая вычитает символьную размерность B
от символьной входной размерности, A + B
. Это не поддерживает обратное распространение символьных размерностей, потому что скомпилированные символьные размерности input ports не установлены. Символьные размерности установлены для output port, таким образом, прямое распространение происходит.
После симуляции модель показывает распространенные размерности.
sfun_symbdims_sfcn_one.c
файл содержит этот код.
#define S_FUNCTION_NAME sfun_symbdims_sfcn_one #define S_FUNCTION_LEVEL 2 #include "simstruc.h" #include <assert.h> /* Function: mdlInitializeSizes =============================================== * Abstract: * Setup sizes of the various vectors. */ static void mdlInitializeSizes(SimStruct *S) { ssSetNumSFcnParams(S, 0); /* Number of expected parameters */ ssSetNumContStates(S, 0); ssSetNumDiscStates(S, 0); if (!ssSetNumInputPorts(S, 1)) return; ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortDimensionInfo(S, 0, DYNAMIC_DIMENSION); ssSetInputPortRequiredContiguous(S, 0, 1); if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortDimensionInfo(S, 0, DYNAMIC_DIMENSION); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumPWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs( S, 0); ssAllowSignalsWithMoreThan2D(S); ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); ssSetSymbolicDimsSupport(S, true); } /*If underspecified for propagation, say i/o are scalars.*/ #if defined(MATLAB_MEX_FILE) #define MDL_SET_DEFAULT_PORT_DIMENSION_INFO static void mdlSetDefaultPortDimensionInfo(SimStruct *S) { if( (ssGetOutputPortWidth(S, 0) == DYNAMICALLY_SIZED) && (ssGetInputPortWidth(S, 0) == DYNAMICALLY_SIZED) ) { ssSetOutputPortMatrixDimensions(S, 0, 1, 1 ); } } #endif #if defined(MATLAB_MEX_FILE) #define MDL_SET_INPUT_PORT_SYMBOLIC_DIMENSIONS static void mdlSetInputPortSymbolicDimensions(SimStruct* S, int_T portIndex, SymbDimsId symbDimsId) { assert(0 == portIndex); // Set the compiled input symbolic dimension. ssSetCompInputPortSymbolicDimsId(S, portIndex, symbDimsId); // Register "B" and get its symbolic dimensions id. const SymbDimsId symbolId = ssRegisterSymbolicDimsString(S, "B"); // Subtract "B" from the input symbolic dimension. const SymbDimsId outputDimsId = ssRegisterSymbolicDimsMinus(S, symbDimsId, symbolId); ssSetCompOutputPortSymbolicDimsId(S, portIndex, outputDimsId); } #endif #if defined(MATLAB_MEX_FILE) #define MDL_SET_OUTPUT_PORT_SYMBOLIC_DIMENSIONS static void mdlSetOutputPortSymbolicDimensions(SimStruct *S, int_T portIndex, SymbDimsId symbDimsId) { assert(0 == portIndex); // The input dimensions are not set, so this S-function only // supports forward propagation. ssSetCompOutputPortSymbolicDimsId(S, portIndex, symbDimsId); } #endif /* Function: mdlInitializeSampleTimes ========================================= * Abstract: * Specify that we inherit our sample time from the driving block. * However, we don't execute in minor steps. */ static void mdlInitializeSampleTimes(SimStruct *S) { ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); ssSetModelReferenceSampleTimeDefaultInheritance(S); } /* Function: mdlOutputs ======================================================= * Abstract: * y=u'; */ static void mdlOutputs(SimStruct *S, int_T tid) { } /* Function: mdlTerminate ===================================================== * Abstract: * No termination needed, but we are required to have this routine. */ static void mdlTerminate(SimStruct *S) { UNUSED_ARG(S); /* unused input argument */ } #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
Simulink.Parameter
объекты A
и B
содержите эти определения.
A = Simulink.Parameter; A.DataType = 'int32'; A.Value = 6; A.Min=5; A.Max=7; A.CoderInfo.StorageClass = 'Custom'; A.CoderInfo.CustomStorageClass = 'ImportedDefine'; A.CoderInfo.CustomAttributes.HeaderFile = 'ImportedDefinitions.h'; B = Simulink.Parameter; B.DataType = 'int32'; B.Value = 10; B.Min=9; B.Max=11; B.CoderInfo.StorageClass = 'Custom'; B.CoderInfo.CustomStorageClass = 'ImportedDefine'; B.CoderInfo.CustomAttributes.HeaderFile = 'ImportedDefinitions.h';
ImportedDefinitions
заголовочный файл содержит этот код.#ifndef _IMPORTEDDEFINITIONS_H_ #define _IMPORTEDDEFINITIONS_H_ #define A 6 #define B 10 #endif
В диалоговом окне Configuration Parameters панель Custom Code содержит #include
оператор.
#include "ImportedDefinitions.h"
sfun_symbdims_sfcn_one
S-функция встраивается, таким образом, TLC
файл с этим кодом должен присутствовать на пути с моделью и другими вспомогательными файлами.
%implements "sfun_symbdims_sfcn_two" "C" %function BlockInstanceSetup(block, system) void %endfunction %% Function: BlockOutputSignal ================================================= %function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void %endfunction %% Function: Outputs =========================================================== %% %function Outputs(block, system) Output %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %% %assign u = LibBlockInputSignal( 0, "", lcv, idx) %assign y = LibBlockOutputSignal(0, "", lcv, idx) %<y> = %<u>; %endroll %endfunction %% Outputs
Чтобы сгенерировать MEX-функцию, в командной строке, вводят эту команду:
mex sfun_symbdims_sfcn_one.c
Сгенерируйте код для модели. ex_msymbdims_sfcn_one_step
функция содержит этот код. Код S-функции установлен встроенный.
/* Model step function */ void ex_msymbdims_sfcn_one_step(void) { int32_T i; /* Gain: '<Root>/Gain' incorporates: * Inport: '<Root>/In1' */ for (i = 0; i < A; i++) { ex_msymbdims_sfcn_one_B.MatrixConcatenate[i] = 2.0 * ex_msymbdims_sfcn_one_U.In1[i]; } /* End of Gain: '<Root>/Gain' */ /* Gain: '<Root>/Gain2' incorporates: * Inport: '<Root>/In2' */ for (i = 0; i < B; i++) { ex_msymbdims_sfcn_one_B.MatrixConcatenate[A + i] = 2.0 * ex_msymbdims_sfcn_one_U.In2[i]; } /* End of Gain: '<Root>/Gain2' */ /* S-Function (sfun_symbdims_sfcn_one): '<Root>/Minus' incorporates: * Outport: '<Root>/Out7' */ { int_T i1; const real_T *u0 = &ex_msymbdims_sfcn_one_B.MatrixConcatenate[0]; real_T *y0 = &ex_msymbdims_sfcn_one_Y.Out7[0]; for (i1=0; i1 < ((A + B)); i1++) { y0[i1] = u0[i1]; } } }
Эта S-функция транспонирует две символьных размерности. Это поддерживает прямое и обратное распространение символьных размерностей, потому что скомпилированная символьная размерность обоих порты ввода и вывода установлена.
static void mdlInitializeSizes(SimStruct *S) { // Enable symbolic dimensions for the s-function. ssSetSymbolicDimsSupport(S, true); } #if defined(MATLAB_MEX_FILE) #define MDL_SET_INPUT_PORT_SYMBOLIC_DIMENSIONS static void mdlSetInputPortSymbolicDimensions(SimStruct* S, int_T portIndex, SymbDimsId symbDimsId) { assert(0 == portIndex); ssSetCompInputPortSymbolicDimsId(S, portIndex, symbDimsId); assert(2U == ssGetNumSymbolicDims(S, symbDimsId)); if (SL_INHERIT == ssGetCompOutputPortSymbolicDimsId(S, portIndex)) { const SymbDimsId idVec[] = { ssGetSymbolicDim(S, symbDimsId, 1), ssGetSymbolicDim(S, symbDimsId, 0)}; // Register the transposed dimensions. // Set the output symbolic dimension to the resulting id. const SymbDimsId outputDimsId = ssRegisterSymbolicDims(S, idVec, 2U); ssSetCompOutputPortSymbolicDimsId(S, portIndex, outputDimsId); } } #endif #if defined(MATLAB_MEX_FILE) #define MDL_SET_OUTPUT_PORT_SYMBOLIC_DIMENSIONS static void mdlSetOutputPortSymbolicDimensions(SimStruct *S, int_T portIndex, SymbDimsId symbDimsId) { assert(0 == portIndex); ssSetCompOutputPortSymbolicDimsId(S, portIndex, symbDimsId); assert(2U == ssGetNumSymbolicDims(S, symbDimsId)); if (SL_INHERIT == ssGetCompInputPortSymbolicDimsId(S, portIndex)) { const SymbDimsId idVec[] = { ssGetSymbolicDim(S, symbDimsId, 1), ssGetSymbolicDim(S, symbDimsId, 0)}; const SymbDimsId inputDimsId = ssRegisterSymbolicDims(S, idVec, 2U); // Register the transposed dimensions. // Set the input symbolic dimension to the resulting id. ssSetCompInputPortSymbolicDimsId(S, portIndex, inputDimsId); } } #endif