Можно встроить более комплексные 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
(см. Компилятор Выходного языка (Simulink Coder) для получения дополнительной информации). Вы можете:
Проверка на ошибки 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 Использовании (Simulink Coder)).
В 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
вместо того, чтобы вызвать функцию MATLAB API mxGetPr
.
Генератор кода вызывает стандартную программу mdlRTW
при генерации файла
. Чтобы произвести оптимальный код для вашей модели Simulink, можно добавить информацию в model.rtw
файл
о режиме, в котором действует Блок s-function.model.rtw
Пример добавляет установки параметров в файл
. Установки параметров не изменяются во время выполнения. В этом случае S-параметр-функции model.rtw
XDataEvenlySpaced
не может измениться во время выполнения (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
неравномерно расположен с интервалами. Сгенерированный код
или 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; } ...