Создайте S-функции автоматически с помощью S-Function Builder

S-Function Builder является Simulink® блок, который интегрирует код C/C + +, чтобы создать S-функцию из спецификаций и кода С, которые вы поставляете. S-Function Builder также служит оберткой для сгенерированной S-функции в моделях, которые используют S-функцию.

Создайте блок S-Function Builder и задайте настройки

Чтобы использовать S-Function Builder, щелкните холст Simulink и введите S-Function Builder или перетащите блок S-Function Builder из Simulink Library > User-Defined. Чтобы открыть редактор S-Function Builder, дважды кликните значок блока S-Function Builder или выберите блок. Затем выберите команду Открыть блок (Open Block) в меню Править (Edit) редактора моделей или контекстного меню блока.

S-Function Builder редактор состоит из четырех компонентов пользовательского интерфейса:

  • Панель инструментов S-Function Builder

  • Панель параметров

  • Таблица портов и параметров

  • Таблица библиотек

Задайте имя для вашей S-функции, чтобы начать создание S-Function Builder блока. Обратите внимание, что, когда вы называете S-функцию, все функции в редакторе S-Function Builder изменяются, и имя S-функции становится префиксом ко всем функциям wrapper.

Используйте панель инструментов S-Function Builder, чтобы задать целевой язык для S-функции, которую вы хотели бы сгенерировать:

  • C - Сгенерируйте S-функции C.

  • C++ - Сгенерируйте C++ S-функции.

  • Inherit from model - наследование языковых настроек от Language настройки модели. Для получения дополнительной информации см. раздел Язык (Simulink Coder).

Настройте основные функции вашей S-функции, такие как начальные условия и количество состояний, с помощью панели Settings справа от редактора S-Function Builder. S-Function Builder использует информацию, которую вы вводите на этой панели, чтобы сгенерировать mdlInitializeSizes метод коллбэка. Механизм Simulink вызывает этот метод во время фазы инициализации модели симуляции, чтобы получить базовую информацию о S-функции.

S-function builder settings with the number of discrete states set to 2, discrete states set to 1 comma 1, number of continuous states set to 0. Array layout set to column-major. Sample mode set to discrete. Sample time value is grayed out. Number of P works set to 0. Enable access to SimStruct is unchecked. Direct feedthrough is checked.

Установите количество состояний и начальных условий

Используя таблицу Settings, можно задать количество дискретных и непрерывных состояний и их начальные условия.

Можно ввести значения начальных условий в виде списка, разделенного запятыми (для примера, 1,1,1) или как вектор (для примера, [1 1 1]). Количество начальных условий должно быть равно количеству обозначенных состояний.

Установите размещение массива

Установите размещение массива кода C/C + +. Можно выбрать один из опций, перечисленных в таблице.

ОпцияРазмещение массива функции C/C + +Действие
Column-majorОсновной столбец

Блок S-Function Builder добавляет функцию SimStruct ssSetArrayLayoutForCodeGen в mdlInitializeSizes чтобы пометить S-функцию для генерации кода основного столбца.

Row-majorОсновная строка

Блок S-Function Builder добавляет функцию SimStruct ssSetArrayLayoutForCodeGen в mdlInitializeSizes чтобы пометить S-функцию для генерации кода основной строки.

Во время симуляции, если ваш код C/C + + включает матрицы или многомерные входы, выходы или параметры, транспозиции добавляются к этим методам коллбэка S-функции:

  • mdlOutputs

  • mdlUpdate

  • mdlDerivatives

Simulink также применяет эти транспозиции при выполнении симуляции в режимах Accelerator и Rapid Accelerator. S-функция не встроена при помощи TLC. Вместо этого MEX S-функция с транспонированием компилируется непосредственно.

AnyФункция C/C + + не зависит от размещения массива

Блок S-Function Builder добавляет функцию SimStruct ssSetArrayLayoutForCodeGen в mdlInitializeSizes чтобы пометить S-функцию как принимающую генерацию кода основной строки и главного столбца.

Выберите режим расчета

Выберите режим расчета вашей S-функции. Режим расчета определяет длину интервала между временами, когда S-функция обновляет свой выход. Можно выбрать один из следующих опций:

  • Inherited - S-функция наследует время расчета от блока, подключенного к ее входному порту. Когда выбирается унаследованный шаг расчета, обратите внимание, что поле Sample time value таблицы Settings неактивно.

  • Continuous - Блок обновляет свои выходы на каждом шаге симуляции. Когда выбирается непрерывный шаг расчета, обратите внимание, что поле Sample time value таблицы Settings неактивно.

  • Discrete - S-функция обновляет свои выходы со скоростью, указанной в поле Sample time value таблицы Settings.

Установите количество PWorks

Задайте PWorks, количество указателей данных, используемых S-функцией. PWorks указывает на память в течение жизненного цикла блока. Если вы вводите любое другое значение, кроме 0 для Number of PWorks он добавляет указатель мыши, void **PW, ко всем функциям в S-Function Builder. Например, вы можете объявить и инициализировать указатель на файл или память в Start_wrapper, получите доступ к нему в Outputs_wrapper, Update_wrapper, и Derivatives_wrapper и отключите его в Terminate_wrapper функция. Код, записанный в этих функциях, вызывается mdlStart, mdlOutputs, mdlUpdate, mdlDerivatives, и mdlTerminate методы. Смотрите примеры Скользящее Среднее значение с Началом и Завершение и Сочетание с использованием Классов Cpp в Демонстрациях S-Функций.

Примечание

Использование PWorks влияет на податливость. Если вы заявляете PWorksиспользование сохранения и восстановления SimState не разрешено. В противном случае настройка податливости SimState по умолчанию, USE_DEFAULT_SIM_STATE, используется.

Включите доступ к SimStruct

Сделайте SimStruct (S) доступно для функций оболочки, которые использует S-Function Builder. Этот выбор позволяет вам использовать SimStruct макросы и функции с вашим кодом в Outputs_wrapper, Derivatives_wrapper, и Update_wrapper функций. Когда вы включаете эту настройку, SimStruct *S добавляется к списку параметров.

Например, с включенной этой опцией можно использовать макросы, такие как ssGetT в коде, который вычисляет выходы S-функции:

double t = ssGetT(S);
  if(t < 2) 
  {
    y0[0] = u0[0];
  } else 
  {
    y0[0]= 0.0;
  }

Прямое сквозное соединение

Установите флажок Direct Feedthrough в таблице Settings, если значения текущего временного шага входных параметров S-функции используются для вычисления ее выходов. Механизм Simulink использует эту информацию, чтобы обнаружить алгебраические циклы, созданные прямым или косвенным соединением выхода S-функции с входом S-функции.

Задайте порты и параметры для S-функции

Используйте таблицу Ports and Parameters в нижней части редактора, чтобы задать входные и выходные порты и параметры для S-функции. Чтобы добавить порт или параметр:

  • Выберите таблицу Ports and Parameters и на панели инструментов S-Function Builder выберите свой выбор в разделе Insert Port.

  • Выберите таблицу Ports and Parameters и щелкните правой кнопкой мыши один из заголовков таблицы.

Чтобы удалить порт или параметр в таблице, выберите порт или параметр, который вы хотели бы удалить, щелкните правой кнопкой мыши, чтобы открыть меню и нажмите Delete.

Порядок портов и параметров в таблице является порядком портов и параметров на блоке. Для примера первым входом портом в таблице является вход порт с индексом 0, и первый параметр является параметром с индексом 0.

В Ports and Parameters, таблице можно задать следующее:

  1. Имя - Имя порта или параметра. Чтобы изменить имя порта или параметра, дважды кликните имя.

  2. Возможности - Возможности порта или параметра. Переменная может быть входом или выходным портом или параметром. Щелкните значение возможностей, чтобы изменить возможности порта или параметра.

  3. Тип данных - Тип данных порта или параметра. Можно задать все встроенные типы данных Simulink, а также типы данных fixdt и шины в качестве портов.

  4. Размерности - Величина порта или параметра. Для портов задайте размерность -1, чтобы наследовать размерности от другого блока. Для параметров размерность устанавливается равной -1 и наследуется от параметров блоков в интерфейсе блоков.

    Чтобы задать 1-D размерность, вводите только количество строк для размерности, например [2]. Для ввода 2-D размерности введите размерность в виде количества строк и столбцов, например [2,1].

  5. Сложность - можно задать сложность порта или параметра как действительную или комплексную.

Используйте таблицу Libraries, чтобы задать внешний код и пути

Таблица Libraries позволяет вам задать местоположение файлов внешнего кода, на которые ссылается пользовательский код, которые вы вводите в других методах оболочки редактора S-Function Builder.

Чтобы ввести новый путь или запись, выберите таблицу Libraries и одну из опций под Insert Paths на панели инструментов S-Function Builder. Также щелкните один из тегов или значений в таблице Libraries. Если вы выбираете путь или запись, можно изменить выбор, нажав на тег в таблице. Можно вводить пути или записи во внешние библиотеки, объектные коды и исходные файлы, на которые ссылается пользовательский код в редакторе S-Function Builder.

Тег, который нужно выбратьЦель
LIB_PATHЗадайте пути к объектам и библиотеке.
INC_PATHУкажите пути поиска файлов включения для заголовочных файлов и исходных файлов.
SRC_PATHУкажите пути поиска файлов для файлов объектов и исходных файлов.
ENV_PATHЗадайте переменные окружения.
ENTRY

Задайте имена файлов объекта, источника и библиотеки. Можно также ввести директивы препроцессора в это поле, например -DDEBUG, -DHARDWARE_VARIANT=1 или -UDEBUG. Задайте каждый файл в отдельной линии.

Заключайте имена заголовочных файлов в верхнюю часть редактора кода. Если вы используете пользовательские файлы заголовков, которые находятся не в том же пути, убедитесь, что включите директорию в INC_PATH тег. Точно так же используйте верхнюю часть редактора, чтобы объявить внешние функции, которые не объявлены в заголовочных файлах. Включите каждое объявление в отдельную линию.

Можно вводить пути или записи к внешним библиотекам, объектным кодам и исходным файлам, на которые ссылается пользовательский код в редакторе S-Function Builder.

Например, рассмотрим проект S-Function Builder в C:\Program Files\MATLAB\work. Таблица показывает, как ссылаться на внешние файлы:

Расположение файловЗаписи в таблицу библиотек

c:\customfolder\customfunctions.lib

LIB_PATH c:\customfolder

ENTRY customfunctions.lib

C:\Program Files\MATLAB\work\customobjs\userfunctions.obj

LIB_PATH $MATLABROOT\customobjs

ENTRY userfunctions.obj

D:\externalsource\freesource.c

SRC_PATH D:\externalsource

ENTRY freesource.c

Можно использовать LIB_PATH для задания путей к файлам объектов и библиотек. Имя библиотеки можно включить в LIB_PATH однако необходимо поместить имя файла объекта в отдельную линию. Тег $MATLABROOT указывает путь относительно MATLAB® монтаж. Список нескольких LIB_PATH записи в отдельных линиях. Поиск путей выполняется в заданном порядке.

Каждая директива должна быть указана в отдельной линии.

Примечание

Не помещайте кавычки вокруг пути библиотеки, даже если в нем пространства имя пути. Если вы добавляете кавычки, компилятор не найдет библиотеку.

Разрабатывайте S-функцию

S-Function Builder использует методы wrapper, чтобы задать код S-функции и свойства, которые генерируют соответствующую S-функцию. Используйте соответствующие методы обертки, чтобы создать тело S-функции. Щелкните Apply на панели инструментов, чтобы сгенерировать код S-функции.

В этой таблице представлены сводные данные методов S-Function Builder:

Метод S-функцииМетод оберткиЦель
Запуск и завершение

<system_name>_Start_wrapper

<system_name>_Terminate_wrapper

Выделите и отключите память в начале и конце симуляции. На выделенную память ссылаются с помощью PWorks для использования во всей S-функции.
Выходы

<system_name>_Outputs_wrapper

Введите код, который вычисляет выходы S-функции на каждом временном шаге симуляции.
Обновление

<system_name>_Update_wrapper

Введите код, который вычисляет значение дискретных состояний на следующем временном шаге, используя значения на текущем временном шаге. Этот метод существует только тогда, когда вы задаете Number of Discrete States в таблице Settings.
Производные

<system_name>_Derivatives_wrapper

Введите код для вычисления производных по состоянию. Этот метод существует только тогда, когда вы задаете Number of Continuous States в таблице Settings.

Теперь можно исследовать эти методы более подробно.

Вычисление выходов с использованием метода выходов

В S-Function Builder используйте Outputs_wrapper метод для ввода кода, который вычисляет выходы S-функции на каждом временном шаге симуляции. Обратите внимание, что при генерации кода S-функции S-Function Builder генерирует метод-оболочку с использованием имени вашей модели и функцию-оболочку в виде <system_name>_<function_name>_wrapper. Для примера, если имя вашей модели dsfunc_builderметод выхода появляется следующим dsfunc_builder_Output_wrapper в редакторе S-Function Builder. Если у вас еще нет имени для блока S-Function Builder, он появляется следующим system_Output_wrapper.

См. следующий код для примера Outputs метод:

void sfun_Outputs_wrapper(const real_T *u,
                          real_T       *y,
				const real_T *xD, /* optional */
				const real_T *xC, /* optional */
				const real_T  *param0, /* optional */
				int_T p_width0 /* optional */
				real_T  *param1 /* optional */
				int_t p_width1 /* optional */
				int_T y_width, /* optional */
				int_T u_width) /* optional */
{

/* Your code inserted here */
}

где sfun - имя S-функции. S-Function Builder вставляет вызов этой функции оболочки в mdlOutputs метод коллбэка, который он генерирует для вашей S-функции. Механизм Simulink вызывает mdlOutputs метод на каждом времени симуляции или шага расчета для вычисления выхода S-функции. The mdlOutputs метод, в свою очередь, вызывает функцию обертки, содержащую ваш выходной код. Ваш выходной код затем вычисляет и возвращает выход S-функции.

The mdlOutputs метод передает некоторые или все из следующих аргументов в функцию оболочки выходов.

АргументОписание
u0, u1, ... uNУказатели на массивы, содержащие входы в S-функцию, где N - количество портов входа, заданное в Input возможностей найденных в таблице Ports and Parameters. Имена аргументов, которые появляются в функции оболочки выходов, совпадают с именами, найденными в Input возможностей Ports and Parameters. Ширина каждого массива совпадает с входом сигнала, заданной для каждого входа на панели Dimensions. Если вход является матрицей, ширина равняется продукту размерностей массивов. Если вы задаете -1 как вход ширину, ширина массива определяется функцией оболочки u_width аргумент.
y0, y1, ... yNУказатель на массивы, содержащие выходы S-функции, где N - количество портов выхода, заданное на панели Scope в таблице Ports and Parameters. Имена аргументов, которые появляются в функции выходов wrapper, совпадают с именами, найденными в Output возможностей Ports and Parameters таблицы. Ширина каждого массива совпадает с выходной шириной, заданной для каждого выхода на панели Dimensions. Если выход является матрицей, ширина равняется продукту размерностей массивов. Если вы задали -1 в качестве выхода ширины, ширина массива определяется функцией оболочки y_width аргумент. Используйте этот массив, чтобы передать выходы, которые ваш код вычисляет, обратно в механизм Simulink.
xDУказатель на массив, содержащий дискретные состояния S-функции. Этот аргумент появляется только, если вы задаете дискретные состояния на Number of discrete states в Settings меню. На первом временном шаге симуляции дискретные состояния имеют начальные значения, которые вы задаете на Discrete states IC. На последующих шагах во шаг расчета состояния получают из значений, которые S-функция вычисляет на предыдущем временном шаге.
xCУказатель на массив, содержащий непрерывные состояния S-функции. Этот аргумент появляется только, если вы задаете количество непрерывных состояний в Number of continuous states строке Settings меню. На первом времени симуляции шаге непрерывные состояния имеют начальные значения, которые вы задаете в Continuous states IC строке. На последующих временных шагах состояния получаются путем численного интегрирования производных состояний на предыдущем временном шаге.
param0, p_width0, param1, p_width1, ... paramN, p_widthNparam0, param1... paramN - указатели на массивы, содержащие параметры S-функции, где N - количество параметров, заданное в таблице Ports and Parameters. p_width0, p_width1... p_widthN - ширина массивов параметров. Если параметр является матрицей, ширина равняется продукту размерностей массивов. Для примера ширина матричного параметра 3 на 2 равняется 6.
y_widthШирина массива, содержащего выходы S-функции. Этот аргумент появляется в сгенерированном коде только, если вы задаете -1 как ширина вывода S-функции. Если выход является матрицей, y_width является продуктом размерностей матрицы.
u_widthШирина массива, содержащего входные параметры S-функции. Этот аргумент появляется в сгенерированном коде только, если вы задаете -1 как ширина входного сигнала S-функции. Если вход является матрицей, u_width является продуктом размерностей матрицы.

Эти аргументы позволяют вам вычислить выход блока как функцию от его входов и, опционально, его состояний и параметров. Код, который вы вводите в это поле, может вызвать внешние функции, объявленные в файлах заголовка или внешних объявлениях в таблице Libraries, что позволяет вам использовать существующий код для вычисления выходов S-функции.

Обновление дискретных состояний с помощью метода обновления

Используйте Update_wrapper функция для ввода кода, который вычисляет значения дискретных состояний на следующем временном шаге согласно значениям на текущем временном шаге. См. следующий код:

void sfun_Update_wrapper(const real_T *u,
                         const real_T *y,
                         real_T *xD,
                         const real_T  *param0,  /* optional */
                         int_T p_width0, /* optional */
                         real_T  *param1,/* optional */
                         int_T p_width1, /* optional */
                         int_T y_width, /* optional */
                         int_T u_width) /* optional */
{

	/* Your code inserted here. */

}

где sfun - имя S-функции. S-Function Builder вставляет вызов этой функции оболочки в mdlUpdate метод коллбэка, который он генерирует для S-функции. Механизм Simulink вызывает mdlUpdate способ в конце каждого временного шага для получения значений дискретных состояний на следующем временном шаге (см. Simulink Engine Interaction with C S-Functions). На следующем временном шаге механизм передает обновленные состояния обратно в mdlOutputs способ.

The mdlUpdate метод коллбэка, сгенерированный для S-функции, передает следующие аргументы в Update_wrapper функция:

  • u

  • y

  • xD

  • param0, p_width0, param1, p_width1, ... paramN, p_widthN

  • y_width

  • u_width

Значения и использование этих аргументов см. в разделе Вычисление выходных параметров с использованием метода выходов. Ваш код должен использовать дискретную переменную состояний, xD, чтобы вернуть значения дискретных состояний, которые он вычисляет. Аргументы позволяют вашему коду вычислять дискретные состояния как функции входов, выходов и, опционально, параметров S-функции. Ваш код может вызвать внешние функции, объявленные в редакторе кода.

Вычисление непрерывных состояний с использованием метода производных

Если S-функция имеет непрерывные состояния, используйте Derivatives_wrapper функция для ввода кода, необходимого для вычисления производных состояний. Введите код для mdlDerivatives функция для вычисления производных редактора непрерывных состояний в этом поле. Пример объявления функции может выглядеть следующим образом:

void system_Derivatives_wrapper(const real_T *u,
				      const real_T *y, 
				      real_T *dx,
				      real_T *xC, 
				      const real_T  *param0,  /* optional */
				      int_T p_width0, /* optional */
				      real_T  *param1,/* optional */
	 			     int_T p_width1, /* optional */
				      int_T y_width, /* optional */
		 		     int_T u_width) /* optional */
{

	/* Your code inserted here. */

}

где system - имя S-функции.

S-Function Builder вставляет вызов этой функции оболочки в mdlDerivatives метод, который он генерирует для S-функции. Механизм Simulink вызывает mdlDerivatives метод в конце каждого временного шага для получения производных непрерывных состояний (см. Simulink Engine Interaction with C S-Functions). Решатель Simulink численно интегрирует производные, чтобы определить непрерывные состояния на следующем временном шаге. На следующем временном шаге механизм передает обновленные состояния назад в mdlOutputs способ. Для получения дополнительной информации о том, как механизм Simulink взаимодействует с S-функциями, смотрите Simulink Engine Interaction with C S-Functions.

mdlDerivatives метод, сгенерированный для S-функции, передает следующие аргументы функции оболочки производных:

  • u

  • y

  • dx

  • xC

  • param0, p_width0, param1, p_width1, ... paramN, p_widthN

  • y_width

  • u_width

The dx аргумент является указателем на массив, ширина которого совпадает с количеством непрерывных производных, заданных на панели Settings. Ваш код должен использовать этот массив, чтобы вернуть значения производных, которые он вычисляет. Смотрите объяснение в разделе Метод вычисления выходов с использованием выходов для значений и использования других аргументов. Аргументы позволяют вашему коду вычислять производные как функцию от входов, выходов и, опционально, параметров S-функции. Ваш код может вызвать внешние функции, объявленные в редакторе кода.

Выделение и удаление памяти с помощью методов запуска и завершения

Используйте Start_wrapper метод записи кода для выделения памяти в начале симуляции. На выделенное ссылаются Pworks для использования во всей S-функции. Точно так же используйте Terminate_wrapper метод для записи кода, чтобы освободить память, выделенную в Start_wrapper способ. Память, на которую ссылаются PWorks могут также быть видны по Terminate, и должны быть освобождены здесь.

Смотрите раздел Set the Number of PWorks, чтобы узнать больше о PWorks.

Создайте S-функцию

После ввода кода в редакторе S-Function Builder исследуйте опции в Build меню, чтобы создать свою S-функцию.

S-function Builder build pane. There are two buttons; Build and Generate Code Only. Then there are options. These options are: Show compile steps, Create a debuggable MEX-file, Generate wrapper TLC, Enable support for coverage, Enable support for design verifier.

Меню сборки содержит следующие варианты выбора:

  • Show compile steps - Регистрируйте каждый шаг сборки в поле Build Log.

  • Create a debuggable MEX-file - Включите отладку информацию в сгенерированный файл MEX.

  • Generate wrapper TLC - Выбор этой опции позволяет вам сгенерировать файл TLC. Вам нужно сгенерировать файл TLC, если вы запускаете модель в режиме Rapid Accelerator или генерируете код Simulink Coder™ из вашей модели. Кроме того, хотя для симуляций режима Accelerator нет необходимости, файл TLC генерирует код для S-функции и таким образом заставляет вашу модель запускаться быстрее в режиме Accelerator.

  • Enable support for coverage - Сделайте S-функцию совместимой с покрытием модели. Для получения дополнительной информации смотрите Покрытие для пользовательского кода C/C + + в моделях Simulink (Покрытие Simulink) в документации Simulink Coverage™.

  • Enable support for design verifier - Сгенерируйте S-функцию для использования с Simulink Design Verifier™. Для получения дополнительной информации смотрите Ограничения поддержки для S-функций и кода C/C + + (Simulink Design Verifier).

Когда вы сделаете выбор, нажмите Build, чтобы создать свою S-функцию и создать файл MEX. Чтобы исключить создание файла MEX из сгенерированного исходного кода, выберите Generate Code Only.

См. также

|

Похожие темы