Создайте и обновите параметры периода выполнения S-функции

О параметрах периода выполнения

Можно создать внутренние представления названных параметров периода выполнения параметров диалогового окна внешней S-функции. Каждый параметр периода выполнения соответствует одному или нескольким параметрам диалогового окна и может иметь то же значение и тип данных как его соответствующие внешние параметры или различное значение или тип данных. Если параметр периода выполнения отличается по значению или типу данных от его внешнего дубликата, диалоговый параметр, как говорят, был преобразован, чтобы создать параметр периода выполнения. Значение параметра периода выполнения, который соответствует нескольким диалоговым параметрам, обычно является функцией значений диалоговых параметров. Механизм Simulink® выделяет и освобождает память для параметров периода выполнения и обеспечивает функции для обновления и доступа к ним, таким образом избавляя от необходимости S-функции выполнить эти задачи. Параметры периода выполнения упрощают следующие виды операций S-функции:

  • Вычисленные параметры

    Часто выход блока является функцией значений нескольких диалоговых параметров. Например, предположите, что блок имеет два параметра, объем и плотность некоторого объекта, и выход блока является функцией входного сигнала и массой объекта. В этом случае масса может быть просмотрена как третий внутренний параметр, вычисленный из двух внешних параметров, объема и плотности. S-функция может создать параметр периода выполнения, соответствующий вычисленному весу, таким образом, избавив от необходимости обеспечить обработку особого случая для веса в выходном расчете. Смотрите Параметры периода выполнения Создания от Нескольких S-параметров-функции для получения дополнительной информации.

  • Преобразования типа данных

    Часто блок должен изменить тип данных диалогового параметра, чтобы упростить внутреннюю обработку. Например, предположите, что выход блока является функцией входа и диалогового параметра, и вход и диалоговый параметр имеет различные типы данных. В этом случае S-функция может создать параметр периода выполнения, который имеет то же значение как диалоговый параметр, но имеет тип данных входного сигнала, и используйте параметр периода выполнения в расчете выхода.

  • Генерация кода

    Во время генерации кода продукт Simulink Coder™ пишет все параметры периода выполнения автоматически в model.rtw файл, избавляя от необходимости S-функцию выполнить эту задачу через mdlRTW метод.

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

Создание параметров периода выполнения

В S-функции C можно создать параметры периода выполнения различными способами. Следующие разделы описывают различные методы для создания параметров периода выполнения в S-функции C.

Создание параметров периода выполнения целиком

Используйте SimStruct функция ssRegAllTunableParamsAsRunTimeParams \in mdlSetWorkWidths создать параметры периода выполнения, соответствующие всем настраиваемым параметрам. Эта функция требует, чтобы вы передали ее массив имен, один для каждого параметра периода выполнения. Продукт Simulink Coder использует эти имена в качестве имен параметров во время генерации кода. S-функция sfun_runtime1.c показывает, как создать параметры периода выполнения целиком.

Этот подход к созданию параметров периода выполнения принимает, что существует взаимно-однозначное соответствие между S-функцией параметры периода выполнения и ее настраиваемыми диалоговыми параметрами. Эта сила не иметь место. Например, S-функция может хотеть использовать вычисленный параметр, значение которого является функцией нескольких диалоговых параметров. В таких случаях S-функция может должна быть создать параметры периода выполнения индивидуально.

Создание параметров периода выполнения индивидуально

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

  1. Задайте количество параметров периода выполнения, которые оно намеревается использовать, с помощью ssSetNumRunTimeParams.

  2. Использование ssRegDlgParamAsRunTimeParam указывать параметр периода выполнения, который соответствует одному диалоговому параметру, даже если существует преобразование типа данных, или ssSetRunTimeParamInfo установить атрибуты параметра периода выполнения, который соответствует больше чем одному диалоговому параметру.

Следующий пример использует ssRegDlgParamAsRunTimeParam и взят из S-функции sfun_runtime3.c. Этот пример создает параметр периода выполнения непосредственно из диалогового параметра и с совпадающим типом данных как сигнал первого входного порта.

static void mdlSetWorkWidths(SimStruct *S)
{
    /* Get data type of input to use for run-time parameter */
    DTypeId      dtId         = ssGetInputPortDataType(S, 0);

    /* Define name of run-time parameter */
    const char_T *rtParamName = "Gain";

    ssSetNumRunTimeParams(S, 1); /* One run-time parameter */
    if (ssGetErrorStatus(S) != NULL) return;
    ssRegDlgParamAsRunTimeParam(S, GAIN_IDX, 0, rtParamName, dtId);
}
#endif /* MDL_SET_WORK_WIDTHS */

Следующий пример использует ssSetRunTimeParamInfo и взят из S-функции sfun_runtime2.c.

static void mdlSetWorkWidths(SimStruct *S)
{
    ssParamRec p; /* Initialize an ssParamRec structure */
    int        dlgP = GAIN_IDX; /* Index of S-function parameter */

    /* Configure run-time parameter information */
    p.name             = "Gain";
    p.nDimensions      = 2;
    p.dimensions       = (int_T *) mxGetDimensions(GAIN_PARAM(S));
    p.dataTypeId       = SS_DOUBLE;
    p.complexSignal    = COMPLEX_NO;
    p.data             = (void *)mxGetPr(GAIN_PARAM(S));
    p.dataAttributes   = NULL;
    p.nDlgParamIndices = 1;
    p.dlgParamIndices  = &dlgP;
    p.transformed      = false;
    p.outputAsMatrix   = false;   
    
    /* Set number of run-time parameters */
    if (!ssSetNumRunTimeParams(S, 1)) return;

    /* Set run-time parameter information */
    if (!ssSetRunTimeParamInfo(S, 0, &p)) return;
}

S-функция sfun_runtime2.c задает параметры GAIN_IDX и GAIN_PARAM можно следующим образом, до использования этих параметров в mdlSetWorkWidths.

#define GAIN_IDX  1
#define GAIN_PARAM(S) ssGetSFcnParam(S,GAIN_IDX)

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

Используйте ssSetRunTimeParamInfo функция в mdlSetWorkWidths создать параметры периода выполнения в зависимости от нескольких S-параметров-функции. Например, рассмотрите S-функцию с двумя S-параметрами-функции, плотностью и объемом. S-входные-параметры-функции сила (F) и выходные параметры ускорение (a). mdlOutputs метод вычисляет силу с помощью уравнения F=m*a, где масса (m) продукт плотности и объема.

S-функция sfun_runtime4.c реализации этот пример с помощью одного параметра периода выполнения, чтобы сохранить массу. S-функция начинается путем определения типа данных параметра периода выполнения, а также переменных, сопоставленных с объемом и плотностью.

#define RUN_TIME_DATA_TYPE SS_DOUBLE
#if RUN_TIME_DATA_TYPE == SS_DOUBLE
typedef real_T RunTimeDataType;
#endif

#define VOL_IDX  0
#define VOL_PARAM(S) ssGetSFcnParam(S,VOL_IDX)

#define DEN_IDX   1
#define DEN_PARAM(S) ssGetSFcnParam(S,DEN_IDX)

mdlSetWorkWidths метод затем инициализирует параметр периода выполнения, можно следующим образом.

static void mdlSetWorkWidths(SimStruct *S)
{
    ssParamRec p; /* Initialize an ssParamRec structure */
    int               dlg[2]; /* Stores dialog indices */
    real_T vol      = *mxGetPr(VOL_PARAM(S));
    real_T den      = *mxGetPr(DEN_PARAM(S));
    RunTimeDataType   *mass;
    
    /* Initialize dimensions for the run-time parameter as a
     * local variable. The Simulink engine makes a copy of this
     * information to store in the run-time parameter. */
    int_T  massDims[2] = {1,1};
    
    /* Allocate memory for the run-time parameter data. The S-function
     * owns this memory location. The Simulink engine does not copy the data.*/
    if ((mass=(RunTimeDataType*)malloc(1)) == NULL) {
        ssSetErrorStatus(S,"Memory allocation error");
        return;
    }

    /* Store the pointer to the memory location in the S-function 
     * userdata. Since the S-function owns this data, it needs to
     * free the memory during mdlTerminate */
    ssSetUserData(S, (void*)mass);
    
    /* Call a local function to initialize the run-time 
     * parameter data. The Simulink engine checks that the data is not
     * empty so an initial value must be stored. */
    calcMass(mass, vol, den);

    /* Specify mass as a function of two S-function dialog parameters */
    dlg[0] = VOL_IDX;
    dlg[1] = DEN_IDX;
    
    /* Configure run-time parameter information. */
    p.name             = "Mass";
    p.nDimensions      = 2;
    p.dimensions       = massDims;
    p.dataTypeId       = RUN_TIME_DATA_TYPE;
    p.complexSignal    = COMPLEX_NO;
    p.data             = mass;
    p.dataAttributes   = NULL;
    p.nDlgParamIndices = 2;
    p.dlgParamIndices  = &dlg
    p.transformed      = RTPARAM_TRANSFORMED;
    p.outputAsMatrix   = false;
    
    /* Set number of run-time parameters  */
    if (!ssSetNumRunTimeParams(S, 1)) return;

    /* Set run-time parameter information */
    if (!ssSetRunTimeParamInfo(S,0,&p)) return;
            
}

Локальная функция calcMass обновляет значение параметра периода выполнения в mdlSetWorkWidths и в mdlProcessParameters, когда значения плотности или объема настраиваются.

/* Function: calcMass ==============================================
 * Abstract:
 *      Local function to calculate the mass as a function of volume
 *      and density.
 */
static void calcMass(RunTimeDataType *mass, real_T vol, real_T den)
{
  *mass = vol * den;
}

mdlOutputs метод использует сохраненную массу, чтобы вычислить силу.

/* Function: mdlOutputs ==========================================
 * Abstract:
 *
 *   Output acceleration calculated as input force divided by mass.   
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
    real_T *y1              = ssGetOutputPortRealSignal(S,0);
    InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
    RunTimeDataType *mass   = 
        (RunTimeDataType *)((ssGetRunTimeParamInfo(S,0))->data);
  
     /*
     * Output acceleration = force / mass
     */
     y1[0] = (*uPtrs[0]) / *mass;
}

Наконец, mdlTerminate метод освобождает память, выделенную для параметра периода выполнения в mdlSetWorkWidths.

/* Function: mdlTerminate ==========================================
 * Abstract:
 *      Free the user data.
 */
static void mdlTerminate(SimStruct *S)
{
    /* Free memory used to store the run-time parameter data*/
   RunTimeDataType *mass = ssGetUserData(S);
    if (mass != NULL) {
        free(mass);
    } 
}

Чтобы запустить пример, откройте модель Simulink:

Обновление параметров периода выполнения

Каждый раз, когда вы изменяете значения диалоговых параметров S-функции в процессе моделирования, механизм Simulink вызывает S-function mdlCheckParameters метод, чтобы подтвердить изменения. Если изменения допустимы, механизм вызывает S-function mdlProcessParameters метод в начале следующего временного шага. Этот метод должен обновить параметры периода выполнения S-функции, чтобы отразить изменения в диалоговых параметрах.

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

Обновление всех параметров целиком

В S-функции MEX C, если существует взаимно-однозначное соответствие между S-функцией, настраиваемые диалоговые параметры и параметры периода выполнения, т.е. параметры периода выполнения были указаны с помощью ssRegAllTunableParamsAsRunTimeParams, S-функция может использовать SimStruct функция ssUpdateAllTunableParamsAsRunTimeParams выполнить эту задачу. Эта функция обновляет каждый параметр периода выполнения, чтобы иметь то же значение как соответствующий диалоговый параметр. Смотрите sfun_runtime1.c для примера.

Обновление параметров индивидуально

Если нет взаимно-однозначного соответствия между диалоговым окном S-функции и параметрами периода выполнения, или параметры периода выполнения являются преобразованными версиями диалоговых параметров, mdlProcessParameters метод должен обновить каждый параметр индивидуально. Выберите метод, используемый, чтобы обновить параметр периода выполнения на основе того, как это было указано.

Если вы указываете параметр периода выполнения с помощью ssSetRunTimeParamInfo, mdlProcessParameters использование метода ssUpdateRunTimeParamData обновить параметр периода выполнения, как показано в sfun_runtime2.c. Эта функция обновляет поле данных в записи атрибутов параметра, ssParamRec, с новым значением. Вы не можете непосредственно изменить ssParamRec, даже при том, что можно получить указатель на ssParamRec использование ssGetRunTimeParamInfo.

Если вы указываете параметр периода выполнения с помощью ssRegDlgParamAsRunTimeParam, mdlProcessParameters использование метода ssUpdateDlgParamAsRunTimeParam обновить параметр периода выполнения, как показан в sfun_runtime3.c.

Обновление параметров как функции нескольких S-параметров-функции

Если вы указываете параметр периода выполнения в зависимости от нескольких S-параметров-функции, mdlProcessParameters использование метода ssUpdateRunTimeParamData обновить параметр периода выполнения.

S-функция sfun_runtime4.c обеспечивает пример. В этом примере, mdlProcessParameters метод вычисляет новое значение для параметра периода выполнения и передает значение указателю ячейки памяти параметра периода выполнения, которая была выделена во время вызова mdlSetWorkWidths. mdlProcessParameters метод затем передает указатель обновленного параметра периода выполнения на ssUpdateRunTimeParamData.

Настройка параметров периода выполнения

Настройка диалогового параметра настраивает соответствующий параметр периода выполнения в процессе моделирования и в коде, сгенерированном, только если диалоговый параметр отвечает следующим условиям:

  • S-функция отмечает диалоговый параметр как настраиваемый, с помощью ssSetSFcnParamTunable.

  • Диалоговый параметр является массивом MATLAB® значений с типом данных, поддержанным продуктом Simulink.

Обратите внимание на то, что вы не можете настроить параметр периода выполнения, значение которого является массивом ячеек или структурой.

Доступ к параметрам периода выполнения

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

  • Если данные имеют тип double:

    real_T *dataPtr = (real_T *) ssGetRunTimeParamInfo(S, #)->data;
  • Если параметр является комплексным, действительные и мнимые части данных чередованы. Например, если пользователь вводит следующее:

    K = [1+2i, 3+4i; 5+6i, 7+8i]

    матрица, которая сгенерирована,

    K = 
        1+2i     3+4i
        5+6i     7+8i

    Память для этой матрицы размечается как

    [1, 2, 5, 6, 3, 4, 7, 8]

    Получить доступ к комплексному параметру периода выполнения из кода S-функции:

    for (i = 0; i<width; i++)
    {
    real_T realData = dataPtr[(2*i)];
    real_T imagData = dataPtr[(2*i)+1];
    }

Примечание

Элементы матрицы выписаны в упорядоченном по столбцам формате. Чередованы действительные и мнимые значения.

Смотрите также

Похожие темы