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

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

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

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

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

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

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

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

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

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

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

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

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

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

Этот подход к созданию параметров периода выполнения принимает, что существует взаимно-однозначное соответствие между 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-функцию метод mdlCheckParameters, чтобы подтвердить изменения. Если изменения допустимы, механизм вызывает S-функцию метод 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];
    }

Примечание

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

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

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте