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

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

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

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

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

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

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

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

S-функция 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, которые соединяются с библиотекой.

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

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

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

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

XData, YData, XEvenlySpaced

XData и YData удваивают векторы равной длины, представляющей значения неизвестной функции. XDataEvenlySpaced скаляр, 0.0 для лжи и 1.0 для истины. Если 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-функции интерполяционной таблицы прямого индекса, чтобы уменьшать размер кода и КПД увеличения сгенерированного кода.

Реализация алгоритма прямого индекса со встроенным файлом TLC требует S-функции основной модуль, sfun_directlook.c и соответствующий lookup_index.c модуль. 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 скаляр.

  • 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 был задан как ложь (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 неравномерно расположен с интервалами. Сгенерированный modelC или 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;
}
...

Похожие темы