Запись полностью встроенных S-функций с стандартная программа mdlRTW

Можно встроить более сложные S-функции с помощью S-функции mdlRTW стандартная программа. mdlRTW стандартная программа предоставляет процессу генерации кода дополнительную информацию о том, как S-функция должна быть встроена путем создания записи параметра ненастраиваемого параметра для использования с файлом. mdlRTW стандартная программа помещает информацию в model.rtw файл. mdlRTW функция описана в текстовом файле matlabroot/ simulink/src/sfuntmpl_doc.c.

Как использовать mdlRTW function, выполните шаги, чтобы создать S-функцию поиска прямого индекса. Интерполяционные таблицы являются наборами упорядоченных точек данных функции. Обычно эти таблицы используют некоторую схему интерполяции, чтобы аппроксимировать значения связанной функции между известными точками данных. Чтобы включить алгоритм интерполяционной таблицы в Simulink® модель, первым шагом является запись S-функции, которая выполняет алгоритм в mdlOutputs. Чтобы создать наиболее эффективный код, следующим шагом является создание соответствующего файла TLC, чтобы исключить вычислительные накладные расходы и улучшить скорость интерполяционных расчетов.

Продукт Simulink обеспечивает поддержку универсальных интерполяционных 1-D, 2-D и n-D алгоритмов. Можно использовать эти алгоритмы в их качестве или создать пользовательскую интерполяционную таблицу S-функцию, чтобы соответствовать вашим требованиям. Можно создать 1-D интерполяционную S-функцию, sfun_directlook.c, и соответствующие ей встроенные sfun_directlook.tlc файл (для получения дополнительной информации см. Target Language Compiler). Вы можете:

  • Проверка на ошибку параметров S-функции.

  • Информация о кэше для S-функции, которая не меняется во время выполнения модели.

  • Используйте mdlRTW функция для настройки генератора кода, чтобы создать оптимальный код для заданного набора параметров блоков.

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

S-Function RTWdata

RTWdata - свойство блоков, которое может использоваться компилятором целевого языка при встраивании S-функции. RTWdata - структура векторов символов, которую можно присоединить к блоку. RTWdata сохраняется вместе с моделью и помещается в model.rtw файл при генерации кода. Для примера, этот набор MATLAB® команды:

mydata.field1 = 'information for field1';
mydata.field2 = 'information for field2';
set_param(gcb,'RTWdata',mydata)
get_param(gcb,'RTWdata')

приводит к следующему результату:

ans = 
 
    field1: 'information for field1'
    field2: 'information for field2'

Информация для связанного блока S-Function внутри model.rtw файл следующий:

Block {
  Type                    "S-Function"
  RTWdata {
    field1                  "information for field1"
    field2                  "information for field2"
  }

Примечание

RTWdata сохраняется в файле модели для S-функций, которые не связаны с библиотекой. Однако RTWdata не является постоянным для блоков S-Function, связанных с библиотекой.

Алгоритм интерполяционной таблицы с прямым индексом

Блок интерполяционной таблицы 1-D, предоставленный в библиотеке Simulink, использует интерполяцию или экстраполяцию при вычислении выходов. В этом примере вы создаете интерполяционную таблицу, которая непосредственно индексирует вектор выхода (вектор y-данных) на основе текущей точки входа (x-данные).

Этот пример прямого поиска 1-D вычисляет приблизительное решение p (x) к частично известной функции f (x) при x = x0, заданных парах точек данных (x, y) в виде вектора x-данных и вектора y-данных. Для заданной пары данных (для примера - i-я пара) y_i = f (x_i). Принято, что значения x-данных монотонно увеличиваются. Если x0 находится вне области значений вектора x-данных, возвращается первая или последняя точка.

Параметры S-функции:

XData, YData, XEvenlySpaced

XData и YData являются двойными векторами равной длины, представляющими значения неизвестной функции. XDataEvenlySpaced является скаляром, 0.0 для ложных и 1.0 для true. Если на XData вектор разделен равномерно, XDataEvenlySpaced является 1.0 и генерируется более эффективный код.

График показывает, как параметры XData=[1:6]и YData=[1,2,7,4,5,9] обрабатываются. Для примера, если вход (значение x) в блок S-Function равен 3, выход (значение y) равен 7.

Пример интерполяционной таблицы с прямым индексом

Улучшите интерполяционную таблицу, вставив S-функцию с прямым индексом в файл TLC. Эта интерполяционная таблица с прямым индексом S-функция не требует файла TLC. Пример использует файл TLC для интерполяционной таблицы S-функции прямого индекса, чтобы уменьшить размер кода и повысить эффективность сгенерированного кода.

Реализация алгоритма прямого индекса с встроенным файлом требует основного модуля S-функции sfun_directlook.c и соответствующее lookup_index.c модуль. The lookup_index.c модуль содержит GetDirectLookupIndex функция, которая используется для определения местоположения индекса в XData для текущей x входное значение, когда XData неравномерно разнесен. GetDirectLookupIndex стандартная программа вызывается из S-функции и сгенерированного кода. В примере используется концепция обертки для совместного использования кодом C/C + + между MEX-файлами Simulink и сгенерированным кодом.

Если на XData равномерно разнесен, тогда и основной модуль S-функции, и сгенерированный код содержат алгоритм поиска, чтобы вычислить y-значение заданного значения x, потому что алгоритм короткий.

Встроенный TLC- файла sfun_directlook.tlc, который используется для выполнения вызова оболочки или для встраивания оптимального кода C/C + + для S-функции. (См. пример в разделе Использование mdlRTW).

Обработка ошибок

В sfun_directlook.tlc, а mdlCheckParameters стандартная программа проверяет, что:

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

  • XData и YData - векторы той же длины, содержащие вещественные, конечные числа.

  • XDataEvenlySpaced является скаляром.

  • The XData вектор является монотонно увеличивающимся вектором и равномерно распределенным.

mdlInitializeSizes функция явно вызывает mdlCheckParameters после того, как он проверяет количество параметров, переданных S-функции. После вызовов механизма Simulink mdlInitializeSizes, затем вызывает mdlCheckParameters каждый раз, когда вы изменяете параметры или переоцениваете их.

Кэширование пользовательских данных

В sfun_directlook.tlc, а mdlStart стандартная программа показывает, как кэшировать информацию, которая не меняется во время симуляции или во время выполнения сгенерированного кода. Пример кэширует значение XDataEvenlySpaced параметр в UserData, поле SimStruct. Следующая линия в mdlInitializeSizes инструктирует механизм Simulink запретить изменения в XDataEvenlySpaced.

ssSetSFcnParamTunable(S, iParam, SS_PRM_NOT_TUNABLE);

Во время выполнения, mdlOutputs обращается к значению XDataEvenlySpaced от UserData вместо того, чтобы вызывать mxGetPr Функция MATLAB API.

Использование mdlRTW

Генератор кода вызывает mdlRTW стандартная программа при генерации model.rtw файл. Чтобы создать оптимальный код для модели Simulink, можно добавить информацию в model.rtw файл о режиме, в котором работает ваш блок S-Function.

Пример добавляет настройки параметра к model.rtw файл. Настройки параметра не изменяются во время выполнения. В этом случае XDataEvenlySpaced Параметр S-функции не может измениться во время выполнения (ssSetSFcnParamTunable был задан как false (0) для него в mdlInitializeSizes). Установка параметра (XSpacing) использует функцию ssWriteRTWParamSettings.

Потому что xData и yData регистрируются как параметры во время выполнения в mdlSetWorkWidthsгенератор кода записывает в model.rtw файл автоматически.

Прежде чем исследовать S-функцию и встроенный файл TLC, рассмотрите сгенерированный код для этой модели.

Модель использует равномерно расположенные XData в верхнем блоке S-Function и неравномерно разнесенных XData в нижнем блоке S-Function. При создании этой модели задайте следующие команды для каждого блока S-Function.

set_param('sfun_directlook_ex/S-Function','SFunctionModules','lookup_index')
set_param('sfun_directlook_ex/S-Function1','SFunctionModules','lookup_index')

Процесс сборки использует модуль lookup_index.c при создании исполняемого файла.

При генерации кода для этой модели генератор кода использует S-функцию mdlRTW метод для генерации model.rtw файл со значением EvenlySpaced для XSpacing параметр для верхнего блока S-Function и значения UnEvenlySpaced для XSpacing параметр для нижнего блока S-Function. В TLC-файле используется значение XSpacing определить, какой алгоритм включить в сгенерированный код. Сгенерированный код содержит алгоритм поиска, когда XData равномерно разнесен, но вызывает GetDirectLookupIndex стандартная программа, когда XData неравномерно разнесен. Сгенерированный model.c или model.cpp код для модели примера интерполяционной таблицы аналогичен этому коду:

/*
 * sfun_directlook_ex.c
 * 
 * Code generation for Simulink model 
 * "sfun_directlook_ex.slx".
 *
...
 */

#include "sfun_directlook_ex.h"
#include "sfun_directlook_ex_private.h"

/* External outputs (root outports fed by signals with auto storage) */
ExtY_sfun_directlook_ex_T sfun_directlook_ex_Y;

/* Real-time model */
RT_MODEL_sfun_directlook_ex_T sfun_directlook_ex_M_;
RT_MODEL_sfun_directlook_ex_T *const sfun_directlook_ex_M =
  &sfun_directlook_ex_M_;

/* Model output function */
void sfun_directlook_ex_output(void)
{
  /* local block i/o variables */
  real_T rtb_SFunction;
  real_T rtb_SFunction1;

  /* Sin: '<Root>/Sine Wave' */
  rtb_SFunction1 = sin(sfun_directlook_ex_M->Timing.t[0]);
  
/* Code that is inlined for the top S-function block in the 
   * sfun_directlook_ex model
   */
  /* S-Function (sfun_directlook): '<Root>/S-Function' */
  {
    const real_T *xData = sfun_directlook_ex_ConstP.SFunction_XData;
    const real_T *yData = sfun_directlook_ex_ConstP.SFunction_YData;
    real_T spacing = xData[1] - xData[0];
    if (rtb_SFunction1 <= xData[0] ) {
      rtb_SFunction = yData[0];
    } else if (rtb_SFunction1 >= yData[20] ) {
      rtb_SFunction = yData[20];
    } else {
      int_T idx = (int_T)( ( rtb_SFunction1 - xData[0] ) / spacing );
      rtb_SFunction = yData[idx];
    }
  }

  /* Outport: '<Root>/Out1' */
  sfun_directlook_ex_Y.Out1 = rtb_SFunction;

/* Code that is inlined for the bottom S-function block in the 
   * sfun_directlook_ex model
   */
  /* S-Function (sfun_directlook): '<Root>/S-Function1' */
  {
    const real_T *xData = sfun_directlook_ex_ConstP.SFunction1_XData;
    const real_T *yData = sfun_directlook_ex_ConstP.SFunction1_YData;
    int_T idx;
    idx = GetDirectLookupIndex(xData, 5, rtb_SFunction1);
    rtb_SFunction1 = yData[idx];
  }

  /* Outport: '<Root>/Out2' */
  sfun_directlook_ex_Y.Out2 = rtb_SFunction1;
}

/* Model update function */
void sfun_directlook_ex_update(void)
{
  /* signal main to stop simulation */
  {                                    /* Sample time: [0.0s, 0.0s] */
    if ((rtmGetTFinal(sfun_directlook_ex_M)!=-1) &&
        !((rtmGetTFinal(sfun_directlook_ex_M)-sfun_directlook_ex_M->Timing.t[0])
          > sfun_directlook_ex_M->Timing.t[0] * (DBL_EPSILON))) {
      rtmSetErrorStatus(sfun_directlook_ex_M, "Simulation finished");
    }
  }

  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The absolute time is the multiplication of "clockTick0"
   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
   * overflow during the application lifespan selected.
   * Timer of this task consists of two 32 bit unsigned integers.
   * The two integers represent the low bits Timing.clockTick0 and the high bits
   * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
   */
  if (!(++sfun_directlook_ex_M->Timing.clockTick0)) {
    ++sfun_directlook_ex_M->Timing.clockTickH0;
  }

  sfun_directlook_ex_M->Timing.t[0] = sfun_directlook_ex_M->Timing.clockTick0 *
    sfun_directlook_ex_M->Timing.stepSize0 +
    sfun_directlook_ex_M->Timing.clockTickH0 *
    sfun_directlook_ex_M->Timing.stepSize0 * 4294967296.0;
}
...

Похожие темы