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

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

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

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

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

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

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

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

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

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

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

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

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

Используйте SimStruct функция ssRegAllTunableParamsAsRunTimeParams в 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). The 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)

The 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;
}

The 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-функции, чтобы отразить изменения в параметрах диалога.

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

Обновление всех параметров сразу

В функции MEX S на 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. The 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];
    }

Примечание

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

См. также

Похожие темы