Можно встроить более сложные S-функции с помощью S-функции mdlRTW
стандартная программа. mdlRTW
стандартная программа предоставляет процессу генерации кода дополнительную информацию о том, как S-функция должна быть встроена путем создания записи параметра ненастраиваемого параметра для использования с файлом. mdlRTW
стандартная программа помещает информацию в
файл. model
.rtwmdlRTW
функция описана в текстовом файле
.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-функции, которая либо полностью строит код интерполяционной таблицы, либо вызывает функцию оболочки для алгоритма интерполяционной таблицы.
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, связанных с библиотекой.
Блок интерполяционной таблицы 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
стандартная программа при генерации
файл. Чтобы создать оптимальный код для модели Simulink, можно добавить информацию в model
.rtw
файл о режиме, в котором работает ваш блок S-Function.model
.rtw
Пример добавляет настройки параметра к
файл. Настройки параметра не изменяются во время выполнения. В этом случае model
.rtwXDataEvenlySpaced
Параметр 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
.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; } ...