Для настройки символьных измерений для S-функциональных блоков можно использовать следующие функции C/C + +. Можно настроить S-функции для поддержки прямого распространения, обратного распространения или прямого и обратного распространения символьных размеров во время моделирования.
Многие из этих функций возвращают переменную SymbDimsId. A SymbDimsId является уникальным целым значением. Это значение соответствует каждой создаваемой спецификации символьных размеров или является результатом математической операции, выполняемой с символьными размерами.
| C/C + + S-функции | Цель |
|---|---|
Укажите, поддерживает ли S-функция символьные размеры. | |
Укажите символические размеры входного порта и способ их распространения вперед. | |
Укажите символические размеры выходного порта и их обратное распространение. | |
Создать | |
Создать | |
Создать | |
Создать | |
Создать | |
Создать | |
Создать | |
Создать | |
Получение количества измерений для | |
Получить | |
Установка предварительно скомпилированного | |
Получить скомпилированные данные | |
Установка скомпилированного | |
Установка предварительно скомпилированного | |
Получить скомпилированные данные | |
Установка скомпилированного | |
Установка скомпилированного |
Модель ex_msymbdims_sfcn_one содержит S-функцию, вычитающую символьное измерение B из символьного входного размера, A + B. Он не поддерживает обратное распространение символьных размеров, поскольку не заданы скомпилированные символьные размеры входных портов. Для выходного порта устанавливаются символические размеры, поэтому происходит прямое распространение.
После моделирования модель показывает распространенные размеры.

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
В диалоговом окне «Параметры конфигурации» панель «Пользовательский код» содержит #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