exponenta event banner

Конфигурирование вариантов измерения для S-функциональных блоков

Для настройки символьных измерений для S-функциональных блоков можно использовать следующие функции C/C + +. Можно настроить S-функции для поддержки прямого распространения, обратного распространения или прямого и обратного распространения символьных размеров во время моделирования.

Многие из этих функций возвращают переменную SymbDimsId. A SymbDimsId является уникальным целым значением. Это значение соответствует каждой создаваемой спецификации символьных размеров или является результатом математической операции, выполняемой с символьными размерами.

C/C + + S-функцииЦель

ssSetSymbolicDimsSupport

Укажите, поддерживает ли S-функция символьные размеры.

mdlSetInputPortSymbolicDimensions

Укажите символические размеры входного порта и способ их распространения вперед.

mdlSetOutputPortSymbolicDimensions

Укажите символические размеры выходного порта и их обратное распространение.

ssRegisterSymbolicDimsExpr

Создать SymbDimsId из строки выражения (aExpr). Строка выражения должна формировать допустимый синтаксис в C.

ssRegisterSymbolicDims

Создать SymbDimsId из вектора SymbDimsIds.

ssRegisterSymbolicDimsString

Создать SymbDimsId из строки идентификатора (aString).

ssRegisterSymbolicDimsIntValue

Создать SymbDimsId из целого значения (aIntValue)

ssRegisterSymbolicDimsPlus

Создать SymbDimsId путем добавления двух символьных размеров.

ssRegisterSymbolicDimsMinus

Создать SymbDimsId вычитанием двух символьных размеров.

ssRegisterSymbolicDimsMultiply

Создать SymbDimsId умножением двух символьных размеров.

ssRegisterSymbolicDimsDivide

Создать SymbDimsId делением двух символьных размеров.

ssGetNumSymbolicDims

Получение количества измерений для SymbDimsId.

ssGetSymbolicDim

Получить SymbDimsId из вектора SymbDimsIds.

ssSetInputPortSymbolicDimsId

Установка предварительно скомпилированного SymbDimsId входного порта. Вы можете вызвать эту функцию изнутри mdlInitializeSizes функция.

ssGetCompInputPortSymbolicDimsId

Получить скомпилированные данные SymbDimsId входного порта.

ssSetCompInputPortSymbolicDimsId

Установка скомпилированного SymbDimsId входного порта.

ssSetOutputPortSymbolicDimsId

Установка предварительно скомпилированного SymbDimsId выходного порта. Вы можете вызвать эту функцию изнутри mdlInitializeSizes функция.

ssGetCompOutputPortSymbolicDimsId

Получить скомпилированные данные SymbDimsId выходного порта.

ssSetCompOutputPortSymbolicDimsId

Установка скомпилированного SymbDimsId выходного порта.

ssSetCompDWorkSymbolicDimsId

Установка скомпилированного SymbDimsId индекса работы типа данных блока (DWork) вектор.

S-функция, поддерживающая прямое распространение символьных размеров

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

После моделирования модель показывает распространенные размеры.

Model with an S-function and symbolic dimensions

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-функция, поддерживающая распространение символьных размеров вперед и назад

Эта 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

Связанные темы