Наиболее простой и быстрый путь создатьS-функцию– это написать ее на языке MATLABс использованием файла-шаблона. И хотя создание S-функцийна языке MATLAB имеет некоторые ограничения (например, MATLAB S-функция может иметь только по одному входному и выходному порту, а также передаваемые и принимаемые данные через эти порты могут быть только скалярами и векторами типа double), этот способ является наилучшим с точки зрения изучения механизма работы S-функции.
Ниже приводится шаблон S-функции с авторским переводом комментариев. Оригинальный файл шаблона sfuntmpl.m находится в папке ...\toolbox\simulink\blocks.
Шаблон MATLAB S-функции:
function [sys,x0,str,ts] = sfuntmpl(t,x,u,flag)%% SFUNTMPL - Базовый шаблон для создания MATLAB S-функции.% С помощью MATLAB S-функции пользователь может задать систему%обыкновенных дифференциальных уравнений (ODE), уравнения дискретной% системы, и(или) любой алгоритм, описывающий работу Simulink-блока. %%Базовая форма синтаксиса S-функции выглядит следующим образом:% [sys,x0,str,ts] = sfunc(t,x,u,flag,p1,...,pn)%% Параметры S-функции:%% t - Текущее время% x - Вектор переменных состояния системы% u - Вектор входных сигналов% flag - Флаг - целое число, определяющее какая функция внутри S-функции %выполняется при вызове.% p1,...,pn - Параметры S-функции, задаваемые в окне диалога%блока "S-function".%% Результат, возвращаемый (вычисляемый) S-функцией в момент времени t % зависит от значения переменной flag, значения вектора состояния системы x%и текущего значения вектора входного сигнала u.%% Результаты работы S-функции в зависимости от значения переменной flag% приведены в таблице:% _________________________________________________________________________% | | | | |% | flag | РЕЗУЛЬТАТ | ВЫПОЛНяЕМАя ФУНКЦИя | ОПИСАНИЕ |% | | | (сallback-метод)| |% |______|___________|________________________|_____________________________|% | 0 | [sizes,x0,| mdlInitializesizes | Инициализация: Расчет |% | | str,ts] | | начальных условий, значений |% | | | | вектора модельного времени |% | | | | времени, размерности матриц.|% | 1 | dx | mdlDerivatives | Расчет значений производных|% | | | | вектора x состояния системы.|% | 2 | ds | mdlUpdate | Расчет значений вектора |% | | | | состояний x дискретной | % | | | | системы: sys = x(n+1). |% | 3 | y | mdlOutputs | Расчет значений выходного |% | | | | вектора sys . |% | 4 | tnext | mdlGetTimeOfNextVarHit | Расчет значения времени для|% | | | | следующей расчетной точки |% | | | | дискретной части системы. |% | | | | Используется при расчете |% | | | | дискретной или гибридной |% | | | | системы с переменным шагом. |% | 5 | | | Зарезервировано для будущего|% | | | | использования. |% | 9 | [] | mdlTerminate | Завершение расчета |% |______|___________|________________________|_____________________________|% %% Параметры блока "S-function" p1,...,pn передаются в S-функцию при любом% значении переменной flag.%% При вызове S-функции со значением переменной flag = 0 ею рассчитываются % следующие величины:%% sys(1) - Число непрерывных переменных состояния.% sys(2) - Число дискретных переменных состояния.% sys(3) - Число выходных переменных.% sys(4) - Число входных переменных (размерность вектора u).% Любой из первых четырех элементов в sys может быть задан % равным -1 (минус один), что означает динамически задаваемую % размерность соответствующих переменных. Фактическая размерность% при вызове S-функции с другими значениями переменной flag% будет равна размерности входного вектора u.% Например, при sys(3) = -1, размерность выходного вектора будет % задана равной размерности входного вектора.% sys(5) - Значение зарезервировано для будущего использования. % sys(6) - Значение, равное 1, соответствует прохождению входного сигнала% на выход. Значение, равное 0, определяет, что входной сигнал не% используется для вычисления выходного сигнала в функции% mdlOutputs, вызываемой при значении переменной flag = 3.% sys(7) - Размерность вектора модельного времени (количество строк в% матрице ts).%%% x0 - Задание вектора начальных значений переменных состояния.%Если переменных состояния нет - значение параметра задается % равным [] .%% str - Зарезервированный параметр. Значение параметра задается% равным [] .%% ts - Матрица, размерностью m-на-2, задающая модельное время% и смещение (period и offset), где m - число строк в матрице ts. %% Например:%% ts = [0 0, % Шаг модельного времени для непрерывной% % части системы.% 0 1, % Фиксированный шаг расчета для непрерывной% % части системы.% period offset, % Фиксированный шаг модельного времени для% % дискретной части системы,% % где - period > 0 & offset < PERIOD.% -2 0]; % Переменный шаг модельного времени для% дискретной части системы. При вызове% S-функции со значением переменной flag = 4 %выполняется расчет следующей точки по времени.%% Если в матрице ts заданы несколько значений шага модельного времени,% то его значения должны располагаться в порядке возрастания.% В том случае, если задано более одного значения шага требуется проверка% времени срабатывания блока в явном виде:% abs(round((T-OFFSET)/PERIOD) - (T-OFFSET)/PERIOD)% Обычно задаваемая погрешность при проверке равна 1e-8. Она зависит от % величин шага модельного времени и времени окончания расчета.% Можно также задать, чтобы значение временного шага передавалось в% блок "S-function" из предшествующего блока модели. Для функций,% изменяющихся внутри основного временного шага должно быть задано% sys(7) = 1иts = [-1 0] .% Для функций, не изменяющихся внутри основного временного шага% должно быть задано sys(7) = 1 и ts = [-1 1] .%% Copyright 1990-2001 The MathWorks, Inc. % $Revision: 1.17 $% Авторский перевод комментариев: Черных И.В.%% Нижележащие строки показывают базовую структуру S-функции:%switch flag, % В зависимости от значения переменной flagпроисходит % вызов того или иного метода::%===============%% Инициализация %%===============%case 0, [sys,x0,str,ts]=mdlInitializeSizes; %====================%% Расчет производных %%====================%case 1, sys=mdlDerivatives(t,x,u); %============================================================%% Расчет значений вектора состояний дискретной части системы %%============================================================% case 2, sys=mdlUpdate(t,x,u); %=====================================================================%% Расчет значений вектора выходных сигналов непрерывной части системы %%=====================================================================%case 3, sys=mdlOutputs(t,x,u);%==================================================================%% Расчет значения времени для следующей расчетной точки дискретной %% части системы %%==================================================================%case 4, sys=mdlGetTimeOfNextVarHit(t,x,u);%====================%% Завершение расчета %%====================%case 9, sys=mdlTerminate(t,x,u);%======================================%% Неизвестное значение переменной flag %%======================================%otherwise error(['Unhandled flag = ',num2str(flag)]);end% Окончание функции sfuntmpl%===============================================================%% mdlInitializeSizes %% Функция инициализации %% Расчет начальных условий, значений вектора модельного времени,%% размерности матриц %%===============================================================%function [sys,x0,str,ts]=mdlInitializeSizes% Приведенные ниже значения параметров даны в качестве примера и не отражают% реально задаваемых значений.sizes = simsizes; % Первый вызов функции simsizes создает структуру sizessizes.NumContStates = 0; % Число непрерывных переменных состоянияsizes.NumDiscStates = 0; % Число дискретных переменных состоянияsizes.NumOutputs = 0; % Число выходных переменных (размерность выходного%вектора)sizes.NumInputs = 0; % Число входных переменных (размерность вектора u)sizes.DirFeedthrough = 1; % Параметр, задающий проход входного сигнала на % выход. % Этот параметр нужно задавать равным 1, в том % случае, если входной сигнал прямо или % опосредованно(например, через логическое % выражение или алгебраическую операцию) % проходит на выход системы (иными словами: если % входной сигнал u, входит в выражения задаваемые в % функции mdlOutputs)или используется метод % mdlGetTimeOfNextVarHit. % При описании системы в уравнениях пространства % состояний этот параметр следует задать равным 1, % если матрица D(матрица обхода) не пустая и % равным нулю, в противном случае.sizes.NumSampleTimes = 1; % Размерность вектора модельного времени. % Минимальное значение параметра = 1 % (одна строка в матрице ts).sys = simsizes(sizes); % Второй вызов функции simsizes. Данные о % размерностях передаются в Simulink.x0 = []; % Задание вектора начальных значений переменных состояния % (начальных условий).str = []; % Задание параметра str, как пустой матрицы. Параметр % заразервирован для будущего использования.ts = [0 0]; % Матрица из двух колонок, задающая шаг модельного времени % и смещение.% Окончание mdlInitializeSizes %========================================================================%% mdlDerivatives%% Функция для расчета значений производных вектора состояния непрерывной %% части системы %%========================================================================%function sys=mdlDerivatives(t,x,u)sys = [];% Окончание mdlDerivatives %==========================================================================% % mdlUpdate %% Функция для расчета значений вектора выходных сигналов непрерывной части % % системы %%==========================================================================% function sys=mdlUpdate(t,x,u)sys = [];% Окончание mdlUpdate%===========================================================================%% mdlOutputs%% Функция для расчета значений вектора выходных сигналов непрерывной части %% системы %%===========================================================================%function sys=mdlOutputs(t,x,u)sys = [];% Окончание mdlOutputs %===========================================================================%% mdlGetTimeOfNextVarHit %% Расчет значения времени для следующей расчетной точки дискретной части %% системы. %% Функция рассчитывает время (абсолютное значение), по достижении которого %% значения дискретной части системы передаютсяв Simulink-модель. %% Функция используется только в случае моделирования дискретной части %% системы с переменным шагом (variable discrete-time sample time). В этом %% случае параметр ts функции mdlInitializeSizes должен быть задан как [-2 0]% %===========================================================================%function sys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime = 1; % Пример: время срабатывания блока увеличивается % на 1 секунду.sys = t + sampleTime;% Окончание mdlGetTimeOfNextVarHit%=========================================%% mdlTerminate %% Функция, выполняющая завершение расчета %%=========================================%function sys=mdlTerminate(t,x,u)sys = [];% Окончание mdlTerminate