Можно встроить более комплексные S-функции при помощи S-функции mdlRTW
стандартная программа. mdlRTW
стандартная программа предоставляет процессу генерации кода больше информации о том, как S-функция должна быть встроена путем создания записи параметра ненастраиваемого параметра для использования с файлом TLC. mdlRTW
стандартная программа помещает информацию в
файл. model
.rtwmdlRTW
функция описана в текстовом файле
.matlabroot
/simulink/src/sfuntmpl_doc.c
Использовать mdlRTW
функционируйте, предпримите шаги, чтобы создать S-функцию поиска прямого индекса. Интерполяционные таблицы являются наборами упорядоченных точек данных функции. Как правило, эти таблицы используют некоторую схему интерполяции для приближенных значений присоединенной функции между известными точками данных. Включить алгоритм интерполяционной таблицы в качестве примера в Simulink® модель, первый шаг должен записать S-функцию, которая выполняет алгоритм в mdlOutputs
. Чтобы произвести самый эффективный код, следующий шаг должен создать соответствующий файл TLC, чтобы устранить вычислительные издержки и улучшить скорость расчетов поиска.
Продукт Simulink оказывает поддержку для поиска общего назначения 1D, 2D, и n-D алгоритмы. Можно использовать эти алгоритмы, как они - или создают пользовательскую S-функцию интерполяционной таблицы, чтобы соответствовать требованиям. Можно создать 1D S-функцию поиска, sfun_directlook.c
, и его соответствующий встроенный sfun_directlook.tlc
файл (дополнительную информацию см. в Компиляторе Выходного языка). Вы можете:
Проверка на ошибки S-параметров-функции.
Информация о кэше для S-функции, которая не изменяется во время выполнения модели.
Используйте mdlRTW
функция, чтобы настроить генератор кода, чтобы произвести оптимальный код для данного набора параметров блоков.
Создайте TLC
файл для S-функции, которая или полностью встраивает код интерполяционной таблицы или вызывает функцию обертки для алгоритма интерполяционной таблицы.
RTWdata
свойство блоков, которые могут использоваться целевым Языковым компилятором при встраивании S-функции. RTWdata
структура векторов символов, которые можно присоединить к блоку. RTWdata
сохранено с моделью и помещенный в
файл, когда вы генерируете код. Например, этот набор MATLAB® команды:model
.rtw
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
стандартная программа при генерации
файл. Чтобы произвести оптимальный код для вашей модели Simulink, можно добавить информацию в model
.rtw
файл о режиме, в котором действует ваш Блок s-function.model
.rtw
Пример добавляет установки параметров в
файл. Установки параметров не изменяются во время выполнения. В этом случае, model
.rtwXDataEvenlySpaced
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
.rtwEvenlySpaced
для 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; } ...