|
|
|||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
![]() |
|||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||
|
|
|
Вход | |||||||||||||||||||||||||||||||
| Раздел "Simulink" И.В.Черных. "Simulink: Инструмент моделирования динамических систем" В оглавление книги \ К следующему разделу \ К предыдущему разделу 16. Simulink-функции 16.1. Введение Simulink-функции (S-функции, S-functions) являются описанием блока на одном из языков программирования: MATLAB, C, C++, Ada, или Fortran. Набор стандартных блоков Simulink, достаточно обширен, однако в практике моделирования встречаются ситуации, когда нужного блока нет, либо структурное моделирование делает модель слишком сложной. В этом случае необходимо использовать технологию S-функций для создания нужного блока. С помощью языков программирования пользователь может создать описание сколь угодно сложного блока и подключить его к Simulink-модели, при этом с точки зрения взаимодействия пользователя с моделью, блок на основе S-функции ничем не отличается от стандартного библиотечного блока Simulink. Создаваемые блоки могут быть непрерывными, дискретными или гибридными. S-функции, созданные на C, C++, Ada или Fortran компилируются в исполняемые (*.dll) файлы, за счет чего обеспечивается повышенная скорость выполнения таких блоков. Такие S-функции обладают еще и дополнительными возможностями, которые включают работу с разными типами данных (целыми, действительными и комплексными числами различной степени точности), использование матриц в качестве входных и выходных переменных (MATLAB S-функции могут оперировать только векторами в качестве входных и выходных переменных), а также больший набор внутренних функций (сallback-методов). Чаще всего S-функции используются при создании новых библиотечных блоков, блоков, обеспечивающих взаимодействие Simulink с аппаратными средствами компьютера, при создании блоков на основе математических уравнений, блоков реализующих анимационные возможности MATLAB, а также при подключении к модели Simulink существующего программного кода языков высокого уровня. 16.1. Блок S-function S-функция подключается к модели Simulink с помощью библиотечного блока S-function (библиотека Functions&Tables). На рис. 16.1 показано окно модели с блоком S-function и его окно диалога.
Рис. 16.1 Блок S-function и его окно диалога Параметрами блока являются:
16.2. Математическое описание S-функции Simulink-блок однозначно описывается наборами входных переменных u, переменных состояния x и выходных переменных y (рис. 16.2).
Рис. 16.2 Общий вид Simulink-блока В математической форме блок можно описать в общем виде следующей системой уравнений:
16.3. Этапы моделирования Процесс расчета модели выполняется Simulink в несколько этапов. На первом этапе выполняется инициализация модели: подключение библиотечных блоков к модели, определение размерностей сигналов, типов данных, величин шагов модельного времени, оценка параметров блоков, а также определяется порядок выполнения блоков и выполняется выделение памяти для проведения расчета. Затем Simulink начинает выполнять цикл моделирования. На каждом цикле моделирования (временном шаге) происходит расчет блоков в порядке, определенном на этапе инициализации. Для каждого блока, Simulink вызывает функции, которые вычисляют переменные состояния блока x, производные переменных состояния, и выходы y в течение текущего шага модельного времени. Этот процесс продолжается, пока моделирование не будет завершено. На рис. 16.3 показана диаграмма, иллюстрирующая этот процесс.
Рис. 16.3 Процесс моделирования 16.4. Callback-методы S-функции Каждая задача при вызове S-функции в процессе моде моделирования решается с помощью специальной внутренней функцией (сallback-метода). В MATLAB S-функции используются следующие методы:
Если S-функция содержит непрерывные переменные состояния, Simulink вызывает сallback-методы mdlDerivatives и mdlOutputs для расчета производных переменных состояния и выходных переменных на внутренних шагах моделирования. Вызов каждого из методов Simulink задает с помощью переменной flag, являющейся входным параметром S-функции. 16.5. Основные понятия S-функции Для того, чтобы создать S-функцию правильно необходимо определить основные понятия, используемые в технологии создания S-функций. К эти понятиям относятся:
16.6. Создание S-функций на языке MATLAB Наиболее простой и быстрый путь создать 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 создает структуру sizes
sizes.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
16.7. Примеры S-функций языке MATLAB 16.7.1. Простейшая S-функция Одним из самых простых примеров S-функций поставляемых с пакетом MATLAB является функция timestwo (файл timestwo.m). Данная S-функция выполняет умножение входного сигнала на коэффициент 2. Ниже приведен текст этой S-функции.
function [sys,x0,str,ts] = timestwo(t,x,u,flag)
%
% TIMESTWO - Пример S-функции. Выходной сигнал равен входному,
% умноженному на 2:
% y = 2 * u;
%
% Шаблон для создания S-функции - файл sfuntmpl.m .
%
% Copyright 1990-2001 The MathWorks, Inc.
% $Revision: 1.6 $
% Авторский перевод комментариев: Черных И.В.
%
switch flag, % В зависимости от значения переменной flag происходит
% вызов того или иного метода:
%===============%
% Инициализация %
%===============%
case 0
[sys,x0,str,ts]=mdlInitializeSizes;
%===========================================%
% Расчет значений вектора выходных сигналов %
%===========================================%
case 3
sys=mdlOutputs(t,x,u);
%=========================================%
% Неиcпользуемые значения переменной flag %
%=========================================%
% В примере не используются методы для завершения работы S-функции,
% нет непрерывных и дискретных переменных состояния,
% поэтому значения переменной flag = 1, 2, 4, 9 не используются.
% Результатом S-функции в этом случае является пустая матрица.
case { 1, 2, 4, 9 }
sys=[];
%======================================%
% Неизвестное значение переменной flag %
%======================================%
otherwise
error(['Unhandled flag = ',num2str(flag)]);
end
% Окончание функции timestwo
%===============================================================%
% mdlInitializeSizes %
% Функция инициализации %
% Расчет начальных условий, значений вектора шагов модельного %
% времени, размерности матриц %
%=============================================================%
%
function [sys,x0,str,ts] = mdlInitializeSizes()
sizes = simsizes;
sizes.NumContStates = 0; % Число непрерывных переменных состояния.
sizes.NumDiscStates = 0; % Число дискретных переменных состояния.
sizes.NumOutputs = -1; % Число выходных переменных (размерность выходного вектора).
% Динамическая размерность выходного вектора.
sizes.NumInputs = -1; % Число входных переменных (размерность входного
% вектора).
% Динамическая размерность входного вектора.
sizes.DirFeedthrough = 1; % Прямой проход. Есть проход входного сигнала
% на выход.
sizes.NumSampleTimes = 1; % Размерность вектора шагов модельного времени.
sys = simsizes(sizes);
str = []; % Параметр заразервирован для будущего
% использования.
x0 = []; % Задание вектора начальных значений переменных
% состояния.
% Переменных сомтояния нет, поэтому значение
% параметра - пустая матрица.
ts = [-1 0]; % Матрица из двух колонок, задающая шаг
% модельного времени и смещение.
% Шаг наследуется из предшествуюшего блока.
% Окончание mdlInitializeSizes
%
%========================================================%
% mdlOutputs %
% Функция для расчета значений вектора выходных сигналов %
%========================================================%
%
function sys = mdlOutputs(t,x,u)
sys = u * 2; % Выходной сигнал блока есть входной сигнал, умноженный на
% коэффициент 2.
% Окончание mdlOutputs
Пример модели с S-функцией timestwo приведен на рис.16.4.
16.7.2. Модель непрерывной системы Модель непрерывной системы, описываемой уравнениями пространства состояния дана в файле csfunc.m . Данная S-функция моделирует непрерывную систему с двумя входами, двумя выходами и двумя переменными состояния. Параметры модели (значения матриц A,В,С,D) задаются в теле S-функции и передаются в callback-методы через их заголовки в качестве дополнительных параметров. S-функция csfunc:
function [sys,x0,str,ts] = csfunc(t,x,u,flag)
% CSFUNC Пример S-функции. Спомощью уравнений пространства состояния
% моделируется непрерывная система:
%
% x' = Ax + Bu
% y = Cx + Du
%
% Значения матриц передаются в callback-методы через их заголовки
% в качестве дополнительных параметров
%
%
% Шаблон для создания S-функции - файл sfuntmpl.m .
%
% Copyright 1990-2001 The MathWorks, Inc.
% $Revision: 1.8 $
% Авторский перевод комментариев: Черных И.В.
% Задание матриц:
A=[-0.09 -0.01
1 0]; % Mатрица системы.
B=[ 1 -7
0 -2]; % Mатрица входа.
C=[ 0 2
1 -5]; % Mатрица выхода.
D=[-3 0
1 0]; % Mатрица обхода.
switch flag, % В зависимости от значения переменной flag происходит
% вызов того или иного метода:
%===============%
% Инициализация %
%===============%
case 0,
[sys,x0,str,ts]=mdlInitializeSizes(A,B,C,D);
%====================%
% Расчет производных %
%====================%
case 1,
sys=mdlDerivatives(t,x,u,A,B,C,D);
%===========================================%
% Расчет значений вектора выходных сигналов %
%===========================================%
case 3,
sys=mdlOutputs(t,x,u,A,B,C,D);
%=========================================%
% Неиcпользуемые значения переменной flag %
%=========================================%
% В примере не используются методы для завершения работы S-функции,
% нет дискретных переменных состояния,
% поэтому значения переменной flag = 2, 4, 9 не используются.
% Результатом S-функции в этом случае является пустая матрица.
case { 2, 4, 9 }
sys=[];
%======================================%
% Неизвестное значение переменной flag %
%======================================%
otherwise
error(['Unhandled flag = ',num2str(flag)]);
end
% Окончание csfunc
%
%===============================================================%
% mdlInitializeSizes %
% Функция инициализации %
% Расчет начальных условий, значений вектора модельного времени,%
% размерности матриц %
%===============================================================%
%
function [sys,x0,str,ts]=mdlInitializeSizes(A,B,C,D)
sizes = simsizes;
sizes.NumContStates = 2; % Число непрерывных переменных состояния.
sizes.NumDiscStates = 0; % Число дискретных переменных состояния.
sizes.NumOutputs = 2; % Число выходных переменных (размерность выходного
% вектора).
sizes.NumInputs = 2; % Число входных переменных (размерность входного
% вектора).
sizes.DirFeedthrough = 1; % Прямой проход. Есть проход входного сигнала
% на выход.
% (матрица D не пустая).
sizes.NumSampleTimes = 1; % Размерность вектора шагов модельного времени.
sys = simsizes(sizes);
x0 = zeros(2,1); % Задание вектора начальных значений переменных
% состояния. Начальные условия нулевые.
str = []; % Параметр заразервирован для будущего
% использования.
ts = [0 0]; % Матрица из двух колонок, задающая шаг модельного
% времени и смещение.
% Окончание mdlInitializeSizes
%
%========================================================================%
% mdlDerivatives %
% Функция для расчета значений производных вектора состояния непрерывной %
% части системы %
%========================================================================%
%
function sys=mdlDerivatives(t,x,u,A,B,C,D)
sys = A*x + B*u;
% Окончание mdlDerivatives
%
%========================================================%
% mdlOutputs %
% Функция для расчета значений вектора выходных сигналов %
%========================================================%
function sys=mdlOutputs(t,x,u,A,B,C,D)
sys = C*x + D*u;
% Окончание mdlOutputs
Пример модели с S-функцией csfunc приведен на рис.16.5.
16.7.3. Модель дискретнойной системы Модель дискретной системы, описываемой уравнениями пространства состояния, дана в файле dsfunc.m . Данная S-функция моделирует дискретную систему с двумя входами, двумя выходами и двумя переменными состояния. Параметры модели (значения матриц A, В, С, D) задаются в теле S-функции и передаются в callback-методы через их заголовки в качестве дополнительных параметров. S-функция dsfunc:
function [sys,x0,str,ts] = dsfunc(t,x,u,flag)
% DSFUNC Пример S-функции. С помощью уравнений пространства состояния
% моделируется дискретная система:
% x(n+1) = Ax(n) + Bu(n)
% y(n) = Cx(n) + Du(n)
%
% Значения матриц передаются в callback-методы через их заголовки
% в качестве дополнительных параметров
%
% Шаблон для создания S-функции - файл sfuntmpl.m .
%
% Copyright 1990-2001 The MathWorks, Inc.
% $Revision: 1.8 $
% Авторский перевод комментариев: Черных И.В.
% Задание матриц:
A = [0.9135 0.1594
-0.7971 0.5947]; % Матрица системы.
B = [0.05189 0
0.4782 0]; % Mатрица входа.
C = [0 1
1 0]; % Mатрица выхода.
D = [0.01 0
0 -0.02]; % Mатрица обхода.
switch flag, % В зависимости от значения переменной flag происходит
% вызов того или иного метода:
%===============%
% Инициализация %
%===============%
case 0,
[sys,x0,str,ts] = mdlInitializeSizes(A,B,C,D);
%============================================================%
% Расчет значений вектора состояний дискретной части системы %
%============================================================%
case 2,
sys = mdlUpdate(t,x,u,A,B,C,D);
%=====================================================================%
% Расчет значений вектора выходных сигналов непрерывной части системы %
%=====================================================================%
case 3,
sys = mdlOutputs(t,x,u,A,C,D);
%=========================================%
% Неиспользуемые значения переменной flag %
%=========================================%
% В примере не используются методы для завершения работы S-функции,
% нет непрерывных переменных состояния,
% поэтому значения переменной flag = 1, 4, 9 не используются.
% Результатом S-функции в этом случае является пустая матрица.
case { 1, 4, 9 }
sys=[];
%======================================%
% Неизвестное значение переменной flag %
%======================================%
otherwise
error(['unhandled flag = ',num2str(flag)]);
end
% Окончание dsfunc
%
%===============================================================%
% mdlInitializeSizes %
% Функция инициализации %
% Расчет начальных условий, значений вектора шагов модельного %
% времени, размерности матриц %
%===============================================================%
%
function [sys,x0,str,ts] = mdlInitializeSizes(A,B,C,D)
sizes = simsizes;
sizes.NumContStates = 0; % Число непрерывных переменных состояния.
sizes.NumDiscStates = size(A,1); % Число дискретных переменных состояния.
sizes.NumOutputs = size(D,1); % Число выходных переменных (размерность
% выходного вектора).
sizes.NumInputs = size(D,2); % Число входных переменных (размерность
% входного вектора).
sizes.DirFeedthrough = 1; % Прямой проход. Есть проход входного
% сигнала на выход (матрица D не пустая).
sizes.NumSampleTimes = 1; % Размерность вектора шагов модельного
% времени.
sys = simsizes(sizes);
x0 = zeros(sizes.NumDiscStates,1); % Задание вектора начальных значений
% переменных состояния.
% Начальные условия нулевые
str = []; % Параметр заразервирован для будущего
% использования.
ts = [0.2 0]; % Матрица из двух колонок, задающая шаг
% модельного времени и смещение.
% Окончание mdlInitializeSizes
%
%=========================================================================%
% mdlUpdate %
% Функция для расчета значений вектора состояния дискретной части системы %
%=========================================================================%
%
function sys = mdlUpdate(t,x,u,A,B,C,D)
sys = A*x+B*u;
% Окончание mdlUpdate
%========================================================%
% mdlOutputs %
% Функция для расчета значений вектора выходных сигналов %
%========================================================%
%
function sys = mdlOutputs(t,x,u,A,C,D)
sys = C*x+D*u;
% Окончание mdlOutputs
Пример модели с S-функцией dsfunc приведен на рис.16.6.
16.7.4. Модель гибридной системы Модель гибридной системы (комбинации непрерывной и дискретной системы) дана в файле mixedm.m . Рассматриваемая S-функция моделирует систему, состоящую из последовательно включенных интегратора (1/s) и блока задержки (1/z). Особенность S-функции для гибридной системы в том, что вызов callback-методов для расчета дискретной части системы выполняется в те же моменты времени, что и для непрерывной ее части, поэтому пользователь, при написании S-функции, должен предусмотреть проверку правильности вызова callback-методов рассчитывающих дискретную часть системы. S-функция dsfunc:
function [sys,x0,str,ts] = mixedm(t,x,u,flag)
% MIXEDM Пример S-функции. S-функция моделирует систему, состоящую из
% последовательно включенных интегратора (1/s) и блока задержки (1/z).
%
% Шаблон для создания S-функции - файл sfuntmpl.m .
%
% Copyright 1990-2001 The MathWorks, Inc.
% $Revision: 1.27 $
% Авторский перевод комментариев: Черных И.В.
% Шаг модельного времени и смещение для дискретной части системы:
dperiod = 1;
doffset = 0;
switch flag % В зависимости от значения переменной flag происходит
% вызов того или иного метода:
%===============%
% Инициализация %
%===============%
case 0
[sys,x0,str,ts]=mdlInitializeSizes(dperiod,doffset);
%====================%
% Расчет производных %
%====================%
case 1
sys=mdlDerivatives(t,x,u);
%============================================================%
% Расчет значений вектора состояний дискретной части системы %
%============================================================%
case 2,
sys=mdlUpdate(t,x,u,dperiod,doffset);
%===========================================%
% Расчет значений вектора выходных сигналов %
%===========================================%
case 3
sys=mdlOutputs(t,x,u,doffset,dperiod);
%====================%
% Завершение расчета %
%====================%
case 9
sys = [];
%======================================%
% Неизвестное значение переменной flag %
%======================================%
otherwise
error(['unhandled flag = ',num2str(flag)]);
end
% Окончание mixedm
%===============================================================%
% mdlInitializeSizes %
% Функция инициализации %
% Расчет начальных условий, значений вектора модельного времени,%
% размерности матриц %
%===============================================================%
function [sys,x0,str,ts]=mdlInitializeSizes(dperiod,doffset)
sizes = simsizes;
sizes.NumContStates = 1; % Число непрерывных переменных состояния.
sizes.NumDiscStates = 1; % Число дискретных переменных состояния.
sizes.NumOutputs = 1; % Число выходных переменных (размерность выходного
% вектора).
sizes.NumInputs = 1; % Число входных переменных (размерность входного
% вектора).
sizes.DirFeedthrough = 0; % Прямой проход. Прохода входного сигнала на выход
% нет.
sizes.NumSampleTimes = 2; % Размерность вектора шагов модельного времени.
% Шаги модельного времени задаются для непрерывной
% и для дискретной частей системы.
sys = simsizes(sizes);
x0 = zeros(2,1); % Задание вектора начальных значений переменных
% состояния.
% Начальные условия нулевые
str = []; % Параметр заразервирован для будущего
% использования.
ts = [0 0]; % Шаг модельного времени для непрерывной части
% системы.
dperiod doffset]; % Шаг модельного времени для дискретной части
% системы.
% Окончание mdlInitializeSizes
%
%========================================================================%
% mdlDerivatives %
% Функция для расчета значений производных вектора состояния непрерывной %
% части системы %
%========================================================================%
function sys=mdlDerivatives(t,x,u)
sys = u;
% Окончание mdlDerivatives
%=========================================================================%
% mdlUpdate %
% Функция для расчета значений вектора состояния дискретной части системы %
%=========================================================================%
%
function sys=mdlUpdate(t,x,u,dperiod,doffset)
% Расчет значения переменной состояния дискретной части системы
% выполняется в соостветствии с дискретным шагом расчета
% (погрешность по времени выбрана равной 1e-15).
if abs(round((t - doffset)/dperiod) - (t - doffset)/dperiod) < 1e-15
sys = x(1);
else
sys = [];
end
% Окончание mdlUpdate
%
%========================================================%
% mdlOutputs %
% Функция для расчета значений вектора выходных сигналов %
%========================================================%
%
function sys=mdlOutputs(t,x,u,doffset,dperiod)
% Расчет значения выходного сигнала системы
% выполняется в соостветствии с дискретным шагом расчета
% (погрешность по времени выбрана равной 1e-15).
% Если условие, заданное оператором if истинно, то выходной сигнал блока
% изменяется. В противном случае выходной сигнал остается равным значению
% на предыдущем шаге.
%
if abs(round((t - doffset)/dperiod) - (t - doffset)/dperiod) < 1e-15
sys = x(2);
else
sys = [];
end
% Окончание mdlOutputs
Пример модели с S-функцией mixedm приведен на рис.16.7.
16.7.6 Непрерывная модель электродвигателя постоянного тока независимого возбуждения В данном параграфе на примере двигателя постоянного тока независимого возбуждения (ДПТ НВ) рассмотрим создание S-функции для модели реального объекта. 16.7.6.1 Математическое описание ДПТ НВ Двигатель постоянного тока независимого возбуждения (рис. 16.9), описывается следующей системой дифференциальных и алгебраических уравнений в абсолютных единицах:
где u - напряжение на якорной обмотке двигателя, e - электродвижущая сила (ЭДС) якоря, i - ток якоря, Ф - поток, создаваемый обмоткой возбуждения, M - электромагнитный момент двигателя, MС - момент сопротивления движению,
С точки зрения будущей модели, входными воздействиями являются напряжения якоря u и момент сопротивления движению MС , выходными переменными - электромагнитный момент двигателя M и скорость вращения вала двигателя Преобразуем дифференциальные уравнения (1) и (2) к явной форме Коши и выполним подстановку. Система уравнений примет вид:
Последнее уравнение есть отражение того факта, что переменная состояния является также и выходной переменной. Введем "машинные" переменные. Входные переменные: Тогда уравнения (5) - (8) примут вид:
Перепишем систему уравнений в матричной форме:
где
Отметим, что в получившейся системе уравнений входные переменные не участвуют в формировании выходных переменных (матрица обхода D - отсутствует) и, следовательно, параметр sizes.DirFeedthrough, определяемый при инициализации S-функции должен быть задан равным нулю. 16.7.6.2 Пример S-функции для ДПТ НВ Для создания S-функции для ДПТ НВ за основу взят файл примера модели непрерывной системы csfunc.m . Принципиальные отличия нового файла от образца сводятся к следующему:
Ниже приводится текст S-функции dpt_sfunc_1 (файл dpt_sfunc_1.m): function [sys,x0,str,ts] = dpt_sfunc_1(t,x,u,flag,L,R,J,Cm,Cw,Fi)
% DPT_SFUNC_1 Пример S-функции для моделирования двигателя постоянного тока
% независимого возбуждения.
%
% В примере выполняется моделирование с помощью уравнений
% пространства-состояния:
% x' = Ax + Bu
% y = Cx + Du
%
% Copyright 2002, Chernykh ILya
% $Revision: 1.8
% Автор: Черных И.В.
%
% Параметры S-функции, передаваемые через окно диалога блока S-function:
%
% L - Индуктивность цепи якоря
% R - Активное сопротивление цепи якоря
% J - Момент инерции
% Cm - Коэффициент связи между моментом и током
% Cw - Коэффициент связи между потоком и скоростью вращения вала
% Fi - Поток, создаваемый обмоткой возбуждения
%
global A B C; % Объявление глобальными переменных, необходимых для
% расчетов внутри функций mdlDerivatives и mdlOutputs .
% Сами матрицы расчитываются в методе mdlInitializeSizes .
switch flag, % В зависимости от значения переменной flag происходит
% вызов того или иного метода:
%===============%
% Инициализация %
%===============%
case 0,
[sys,x0,str,ts]=mdlInitializeSizes(L,R,J,Cm,Cw,Fi);
%====================%
% Расчет производных %
%====================%
case 1,
sys=mdlDerivatives(t,x,u);
%===========================================%
% Расчет значений вектора выходных сигналов %
%===========================================%
case 3,
sys=mdlOutputs(t,x,u);
%=========================================%
% Неиcпользуемые значения переменной flag %
%=========================================%
case { 2, 4, 9 },
sys = [];
%======================================%
% Неизвестное значение переменной flag %
%======================================%
otherwise
error(['Unhandled flag = ',num2str(flag)]);
end
% Окончание dpt_sfunc_1
%===============================================================%
% mdlInitializeSizes %
% Функция инициализации %
% Расчет начальных условий, значений вектора шагов модельного %
% времени,размерности матриц %
%===============================================================%
function [sys,x0,str,ts]=mdlInitializeSizes(L,R,J,Cm,Cw,Fi)
sizes = simsizes;
sizes.NumContStates = 2; % Число непрерывных переменных состояния
% В данном случае этот параметр равен 2
% (ток якоря и скорость вращения вала).
sizes.NumDiscStates = 0; % Число дискретных переменных состояния
% В данном случае этот параметр равен 0,
% поскольку модель непрерывная.
sizes.NumOutputs = 2; % Число выходных переменных (размерность выходного
% вектора). В данном случае этот параметр равен 2
% (скорость вращения и момент на валу).
sizes.NumInputs = 2; % Число входных переменных (размерность входного
% вектора). В данном случае этот параметр равен 2
% (напряжение на обмотке якоря и момент
% сопротивления).
sizes.DirFeedthrough = 0; % Прямой проход. Значение параметра равно нулю,
% поскольку матрица обхода D - отсутствует (входные
% переменные не участвуют в формировании выходных
% переменных).
sizes.NumSampleTimes = 1; % Размерность вектора модельного времени.
sys = simsizes(sizes);
x0 = zeros(2,1); % Задание вектора начальных значений переменных
% состояния. Начальные условия нулевые.
str = []; % Зарезервированный параметр
ts = [0 0]; % Матрица из двух колонок, задающая шаг модельного
% времени и смещение.
% Далее в функцию mdlInitializeSizes добавлены операторы для
% вычисления матриц A, B и C уравнений пространства состояния
% модели двигателя постоянного тока
global A B C; % Объявление глобальными переменных, необходимых для
% расчетов внутри функций mdlDerivatives и mdlOutputs.
% Расчет матриц А,В и С:
%
A=[-R/L -Cw*Fi/L
Cm*Fi/J 0 ];
%
B=[1/L 0
0 -1/J];
%
C=[Cm*Fi 0
0 1];
% Окончание mdlInitializeSizes
%========================================================================%
% mdlDerivatives %
% Функция для расчета значений производных вектора состояния непрерывной %
% части системы %
%========================================================================%
function sys=mdlDerivatives(t,x,u)
%
global A B; % Объявление глобальными переменных, необходимых для
% расчетов внутри метода.
sys = A*x + B*u;
% Окончание mdlDerivatives
%========================================================%
% mdlOutputs %
% Функция для расчета значений вектора выходных сигналов %
%========================================================%
function sys=mdlOutputs(t,x,u)
global C; % Объявление глобальными переменных, необходимых для
% расчетов внутри метода.
sys = C*x;
% Окончание mdlOutputs
На рис.16.10 показаны модели двигателя постоянного тока на базе S-функции и с использованием стандартных блоков. Результаты расчета для обеих моделей идентичны. Окно диалога блока S-function изображено на рис. 16.11.
16.8. Создание S-функций на языке C с помощью S-Function Builder Инструментарий Simulink предоставляет пользователю два способа создания S-функций на языке C: с помощью автоматического построителя S-Function Builder и вручную, с использованием шаблона (аналогично созданию S-функций на языке MATLAB). И хотя наибольшими возможностями обладает именно второй способ, первый способ прост и наименее трудоемок, и, поэтому именно с помощью S-Function Builder пользователь может легко и быстро создать нужную ему S-функцию. При этом как во втором, так и в первом случаях S-функция будет создана в виде исполняемого dll-файла, что обеспечивает повышенное быстродействие этой функции.
Значения элементов матриц даны в п. 16.7.6.1. S-Function Builder оформлен в виде обычного блока Simulink и находится в библиотеке Function&Tables (функции и таблицы). Пиктограмма блока показана на рис.16.12.
Двойной щелчок на пиктограмме открывает окно S - Function Builder . Окно S - Function Builder (см. рис. 16.13) содержит панель параметров ( Parameters), в которой находится графа для ввода имени S -функции ( S - function name ) и графа для ввода начальных значений параметров, передаваемых через окно диалога блока S - function ( S - function parameters ). Также на этой панели находится кнопка Build, предназначенная для запуска процесса компиляции S -функции . В нижней части окна S - Function Builder находятся кнопки Help (вызов справки) и Close / Cancel (закрыть окно). Среднюю часть окна занимают шесть вкладок, предназначенных для задания свойств S -функции и фрагментов ее кода: 1. Initialization - Инициализация. На вкладке Initialization задаются следующие свойства S -функции:
Окно S-Function Builder с открытой вкладкой Ininialization показано на рис.16.13. Для рассматриваемого примера число входных переменных равно двум (напряжение на обмотке якоря и момент сопротивления). Число выходных переменных равно двум (момент и скорость). Количество переменных состояния также равно двум (ток якоря и скорость). Число параметров S-функции, передаваемых через окно диалога равно 6 (см. п. 16.7.6.2), шаг модельного времени - наследуемый, число дискретных переменных состояния - 0, начальные значения дискретных и непрерывных переменных состояния нулевые. 2. Libraries - Библиотеки. На вкладке имеется три окна для ввода фрагментов С-кода:
Окно S - Function Builder с открытой вкладкой Libraries показано на рис. 16.14. 3. Outputs - Выходы. Вкладка содержит текстовое окно, предназначенное для ввода выражений расчета выходных переменных. В расчетных выражениях можно использовать следующие переменные (не объявляя их специально):
На вкладке имеется флажок для установки параметра Inputs are needed in the output function ( direct feedthrough ) - использование входных сигналов для расчета выходных (прямой проход). Текст автоматически генерируемого метода mdl 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 */
{
/* Место для ввода расчетного кода */
} ,
где sfun - имя S -функции. Окно S - Function Builder с открытой вкладкой Output s показано на рис. 16.15. В примере на рис. 16.15 в первой строке объявляются переменные - параметры электродвигателя, и этим переменным присваиваются значения параметров передаваемых в S -функцию через окно диалога. Во второй строке объявляются и вычисляются переменные COO и С11, входящие в уравнения (17), (18). В третьей и четвертой строках записаны выражения для расчета выходных сигналов в соответствии с уравнениями (17) и (18). Параметр Inputs are needed in the output function ( direct feedthrough ) не установлен, поскольку в выражениях для расчета выходных сигналов отсутствуют входные. После генерации С-кода в тексте S-функции появится код, введенный в окне вкладки Outputs . 4. Continuous Derivatives - Производные непрерывных переменных состояния. Вкладка содержит текстовое окно, предназначенное для ввода выражений расчета производных непрерывных переменных состояния. В расчетных выражениях можно использовать те же переменные, что и на вкладке Outputs , за исключением дискретных переменных состояния xD . Сами производные обозначаются как dx [0], dx [1], dx [2] и т.п. Текст автоматически генерируемого метода mdl Derivatives , приведен ниже:
void sfun_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 */
{
/* Место для ввода расчетного кода */
}
Окно S-Function Builder с открытой вкладкой Continuous Derivatives показано на рис . 16.15.
В примере на рис. 16.16 в первых двух строках объявляются переменные - параметры электродвигателя, и этим переменным присваиваются значения параметров передаваемых в S -функцию через окно диалога. В следующих двух строках объявляются и вычисляются переменные AOO … B 11 , входящие в уравнения (15), (16). В последних двух строках записаны выражения для расчета производных непрерывных переменных состояния в соответствии с уравнениями (15) и (16). 5. Discrete Update - Расчет дискретных переменных состояния. В текстовом окне вкладки записываются выражения для расчета дискретных переменных состояния. В расчетных выражениях можно использовать те же переменные, что и на вкладке Outputs , за исключением непрерывных переменных состояния x С . Сами дискретные переменные состояния обозначаются как xD [0], xD [1], xD [2] и т.п. Текст автоматически генерируемо метода mdl Update , приведен ниже:
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 */
{
/* Место для ввода расчетного кода */
}
Окно S - Function Builder с открытой вкладкой Discrete Update показано на рис. 16.17. В рассматриваемом примере отсутствуют дискретные переменные состояния, поэтому на рисунке дан лишь пример расчетного выражения. 6. Build Info - Информация о компоновке. На вкладке в окне Compilation diagnostics (диагностические сообщения о ходе компиляции) отображается информацию о процессе компоновки S-функции . На вкладке Build Info с помощью флажков можно установить следующие параметры:
Перед началом компиляции необходимо выбрать (настроить) компилятор. Для этого в командном окне MATLAB следует ввести команду: mex - setup и далее следовать диалогу с компилятором. С программой MATLAB поставляется компилятор Lcc . Ниже приводится пример такого диалога: Please choose your compiler for building external interface (MEX) files: Would you like mex to locate installed compilers [y]/n? n - Ответ пользователя Select a compiler: [1] Borland C++Builder version 5.0 [2] Borland C++Builder version 4.0 [3] Borland C++Builder version 3.0 [4] Borland C/C++ version 5.02 [5] Borland C/C++ version 5.0 [6] Borland C/C++ (free command line tools) version 5.5 [7] Compaq Visual Fortran version 6.1 [8] Compaq Visual Fortran version 6.5 [9] Digital Visual Fortran version 6.0 [10] Digital Visual Fortran version 5.0 [11] Lcc C version 2.4 [12] Microsoft Visual C/C++ version 6.0 [13] Microsoft Visual C/C++ version 5.0 [14] WATCOM C/C++ version 11 [15] WATCOM C/C++ version 10.6 [0] None
Compiler: 11 - Ответ пользователя
Your machine has a Lcc C compiler located at C:\MATLAB6\sys\lcc. Do you want to use this compiler [y]/n? y - Ответ пользователя
Please verify your choices:
Compiler: Lcc C 2.4 Location: C:\MATLAB6\sys\lcc
Are these correct?([y]/n): y - Ответ пользователя
The default options file: "C:\Documents and Settings\Администратор\Application Data\MathWorks\MATLAB\R12\mexopts.bat" is being updated from C:\MATLAB6\BIN\WIN32\mexopts\lccopts.bat...
Процесс компиляции начинается после нажатия на кнопку Build . Об успешном завершении процесса компиляции свидетельствует сообщение вида: ### S-function 'DPT_Sfunc_1_C.dll' created successfully . По завершении процесса компиляции в рабочей папке будут созданы текстовые файлы с названиями вида: sfun_C.c , sfun_wrapper.c и sfun.dll > . Последний является исполняемым файлом. В файле sfun _ C . c находится текст S -функции , а в файле sfun _ wrapper . c - методы, сгенерированные S- Function Builder . Окно S - Function Builder с открытой вкладкой Build Info показано на рис. 16.18. Результаты расчетов, выполненных с использованием созданной таким образом S -функции , полностью совпадают с результатами, приведенными в п. 16.7.6.2 . Скорость расчета модели с использованием S -функции , написанной на языке C в несколько раз выше, чем при использовании языка MATLAB . 16.9. Модернизация S-функций, созданных с помощью S-Function Builder S-функции, созданные с помощью S-Function Builder обладают одним существенным недостатком. В большинстве случаев при расчете переменных состояния, выходных сигналов либо производных непрерывных переменных состояния должны использоваться некоторые ранее вычисленные константы. В задаче моделирования двигателя постоянного тока - это элементы матриц A, B, С уравнений пространства-состояния, рассчитываемые через параметры двигателя (сопротивление, индуктивность и т.п.). В примере на языке MATLAB (см. п. 16.7.6) расчет матриц выполняется в методе mdlInitializeSizes, благодаря чему этот расчет производится только один раз - на этапе инициализации модели. Далее рассчитанные матрицы только используются для вычисления производных переменных состояния в методе mdlDerivatives и выходных сигналов в методе mdlOutputs. Такая компоновка S-функции обеспечивает наибольшую скорость вычислений. К сожалению, в S-Function Builder отсутствует возможность ввести фрагмент кода на вкладке Initialization, а также скрыты заголовки методов, что делает невозможным добавление новых параметров, которые могли бы передаваться в эти методы. Такая ситуация приводит к тому, что константы, которые можно было бы вычислить всего один раз и, затем лишь использовать, вычисляются вновь и вновь на каждом шаге расчета (в примере с двигателем постоянного тока п.16.6 - это A00, A01, B00 и т.д.). И, если в относительно простых моделях с эти еще можно смириться, то для сложных моделей с большим объемом предварительных вычислений такая ситуация приведет к существенному замедлению процесса расчета.
/*
* File: DPT_Sfunc_1_C.c
*
*
*
* --- THIS FILE GENERATED BY S-FUNCTION BUILDER: BASIC, 1.0 ---
*
* This file is an S-function produced by the Basic S-Function
* Builder which only recognizes certain fields. Changes made
* outside these fields will be lost the next time the block is
* used to load, edit, and resave this file. This file will be overwritten
* by the S-function Builder block. If you want to edit this file by hand,
* you must change it only in the area defined as:
*
* %%%-SFUNWIZ_defines_Changes_BEGIN
* #define NAME 'replacement text'
* %%% SFUNWIZ_defines_Changes_END
*
* DO NOT change NAME--Change te 'replacement text' only.
*
* For better compatibility with the Real-Time Workshop, the
* "wrapper" S-function technique is used. This is discussed
* in the Real-Time Workshop User's Manual in the Chapter titled,
* "Wrapper S-functions".
*
* ------------------------------------------------------------------------
*| See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template |
* ------------------------------------------------------------------------
* Created: Sun Mar 30 13:07:10 2003
*
*
*/
#define S_FUNCTION_NAME DPT_Sfunc_1_C
#define S_FUNCTION_LEVEL 2
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */
#define NUM_INPUTS 1
#define INPUT_0_WIDTH 2
#define INPUT_0_FEEDTHROUGH 0
#define NUM_OUTPUTS 1
#define OUTPUT_0_WIDTH 2
#define NPARAMS 6
#define SAMPLE_TIME_0 INHERITED_SAMPLE_TIME
#define NUM_DISC_STATES 0
#define DISC_STATES_IC [0]
#define NUM_CONT_STATES 2
#define CONT_STATES_IC [0,0]
#define SFUNWIZ_GENERATE_TLC 1
#define SOURCEFILES "//my_lib.lib"
#define PANELINDEX 5
#define SFUNWIZ_REVISION 1.0
/* %%%-SFUNWIZ_defines_Changes_END --- EDIT HERE TO _BEGIN */
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
#include "simstruc.h"
#define PARAM_DEF0(S) ssGetSFcnParam(S, 0)
#define PARAM_DEF1(S) ssGetSFcnParam(S, 1)
#define PARAM_DEF2(S) ssGetSFcnParam(S, 2)
#define PARAM_DEF3(S) ssGetSFcnParam(S, 3)
#define PARAM_DEF4(S) ssGetSFcnParam(S, 4)
#define PARAM_DEF5(S) ssGetSFcnParam(S, 5)
extern void DPT_Sfunc_1_C_Outputs_wrapper(const real_T *u,
real_T *y,
const real_T *xC,
const real_T *param0, const int_T p_width0, const real_T *param1,
Жирным шрифтом в тексте S-функции выделены те строки кода, которые обеспечивают считывание параметров блока S-function, заданных в окне диалога. При инициализации S-функции создается структура с именем S, которая содержит в численном виде все свойства S-функции и из которой, собственно, и происходит извлечение параметров с помощью указанных строк кода. Например, строка
const real_T *param0 = mxGetPr(PARAM_DEF0(S));
обеспечивает извлечение первого (из списка в окне параметров блока S-function) параметра, а в строке
const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S));
переменной p_width0 присваивается значение размерности этого же параметра (параметры блока S-function могут быть не только скалярами, но и векторами). Отметим также, что такие строки кода имеются в каждом из методов - mdlDerivatives, mdlOutputs и mdlUpdate, благодаря чему параметры блока S-function являются доступными в каждом из методов. Таким образом, пользователю остается добавить выделенные строки в метод mdlInitializeSizes, записать в этом же методе выражения для вычисления нужных констант и обеспечить передачу рассчитанных значений в методы mdlDerivatives, mdlOutputs и mdlUpdate. Удобнее всего это сделать с помощью специально написанной функции. Ниже приводится текст такой функции (Sfun_Get_Parameters.c) для рассматриваемого примера.
double A00, A01, A10, B00, B11, C00, C11;
void Sfun_Get_Parameters(SimStruct *S)
{
const real_T *param0 = mxGetPr(PARAM_DEF0(S));
const real_T *param1 = mxGetPr(PARAM_DEF1(S));
const real_T *param2 = mxGetPr(PARAM_DEF2(S));
const real_T *param3 = mxGetPr(PARAM_DEF3(S));
const real_T *param4 = mxGetPr(PARAM_DEF4(S));
const real_T *param5 = mxGetPr(PARAM_DEF5(S));
const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S));
const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S));
const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S));
const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S));
const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S));
const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S));
double L, R, J, Cm, Cw, Fi;
L=*param0; R=*param1; J=*param2; Cm=*param3; Cw=*param4; Fi=*param5;
A00 = -R/L; A01 = -Cw*Fi/L; A10 = Cm*Fi/J;
B00 = 1/L; B11 = -1/J; C00 = Cm*Fi; C11 = 1;
}
В первой строке файла выполнено объявление переменных A00, A01, A10, B00, B11, C00, C11. Благодаря тому, что это объявление выполнено вне тела функции указанные переменные являются глобальными. Это облегчает реализацию их передачи в нужные методы. Затем в файле функции следует объявление самой функции, и, несколько строк кода, извлекающие параметры и их размерность из структуры S. Далее идет объявление переменных, являющихся параметрами электродвигателя и расчет значений переменных A00, A01, A10, B00, B11, C00, C11.
В результате файл DPT_Sfunc_1_C.c будет выглядеть следующим образом (жирным шрифтом выделены добавления):
/*
* File: DPT_Sfunc_1_C.c
*
*
*
* --- THIS FILE GENERATED BY S-FUNCTION BUILDER: BASIC, 1.0 ---
*
* This file is an S-function produced by the Basic S-Function
* Builder which only recognizes certain fields. Changes made
* outside these fields will be lost the next time the block is
* used to load, edit, and resave this file. This file will be overwritten
* by the S-function Builder block. If you want to edit this file by hand,
* you must change it only in the area defined as:
*
* %%%-SFUNWIZ_defines_Changes_BEGIN
* #define NAME 'replacement text'
* %%% SFUNWIZ_defines_Changes_END
*
* DO NOT change NAME--Change the 'replacement text' only.
*
* For better compatibility with the Real-Time Workshop, the
* "wrapper" S-function technique is used. This is discussed
* in the Real-Time Workshop User's Manual in the Chapter titled,
* "Wrapper S-functions".
*
* -------------------------------------------------------------------------
*| See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template |
* ------------------------------------------------------------------------
* Created: Sun Mar 30 13:07:10 2003
*
*
*/
#define S_FUNCTION_NAME DPT_Sfunc_1_C
#define S_FUNCTION_LEVEL 2
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */
#define NUM_INPUTS 1
#define INPUT_0_WIDTH 2
#define INPUT_0_FEEDTHROUGH 0
#define NUM_OUTPUTS 1
#define OUTPUT_0_WIDTH 2
#define NPARAMS 6
#define SAMPLE_TIME_0 INHERITED_SAMPLE_TIME
#define NUM_DISC_STATES 0
#define DISC_STATES_IC [0]
#define NUM_CONT_STATES 2
#define CONT_STATES_IC [0,0]
#define SFUNWIZ_GENERATE_TLC 1
#define SOURCEFILES "//my_lib.lib"
#define PANELINDEX 5
#define SFUNWIZ_REVISION 1.0
/* %%%-SFUNWIZ_defines_Changes_END --- EDIT HERE TO _BEGIN */
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
#include "simstruc.h"
#define PARAM_DEF0(S) ssGetSFcnParam(S, 0)
#define PARAM_DEF1(S) ssGetSFcnParam(S, 1)
#define PARAM_DEF2(S) ssGetSFcnParam(S, 2)
#define PARAM_DEF3(S) ssGetSFcnParam(S, 3)
#define PARAM_DEF4(S) ssGetSFcnParam(S, 4)
#define PARAM_DEF5(S) ssGetSFcnParam(S, 5)
//=========================NEW CODE==================================
#include "Sfun_Get_Parameters.c"
//=========================NEW CODE==================================
extern void DPT_Sfunc_1_C_Outputs_wrapper(const real_T *u,
real_T *y,
const real_T *xC,
const real_T *param0, const int_T p_width0, const real_T *param1,
Следующим шагом является модернизация файла DPT_Sfunc_1_C_wrapper.c, в котором содержится вычислительный код методов mdlDerivatives, mdlOutputs и mdlUpdate. Для рассматриваемого примера модернизация данного файла сводится к следующим шагам:
В результате файл DPT_Sfunc_1_C_wrapper.c будет выглядеть следующим образом (жирным шрифтом отмечены изменения в этом файле): /* * * --- THIS FILE GENERATED BY S-FUNCTION BUILDER: BASIC, 1.0 --- * * This file is a wrapper S-function produced by the S-Function * Builder which only recognizes certain fields. Changes made * outside these fields will be lost the next time the block is * used to load, edit, and resave this file. This file will be overwritten * by the S-function Builder block. If you want to edit this file by hand, * you must change it only in the area defined as: * * %%%-SFUNWIZ_wrapper_XXXXX_Changes_BEGIN * Your Changes go here * %%%-SFUNWIZ_wrapper_XXXXXX_Changes_END * * For better compatibility with the Real-Time Workshop, the * "wrapper" S-function technique is used. This is discussed * in the Real-Time Workshop User's Manual in the Chapter titled, * "Wrapper S-functions". * * Created: Sun Mar 30 13:07:10 2003 */ /* * Include Files * */ #include "tmwtypes.h" /* %%%-SFUNWIZ_wrapper_includes_Changes_BEGIN --- EDIT HERE TO _END */ #include Выполнить сборку S-функции на основе измененных файлов следует командой из рабочего окна MATLAB: В оглавление книги \ К следующему разделу \ К предыдущему разделу |
|
|
||
|
Всероссийская научная конференция "Проектирование научных и инженерных приложений в среде MATLAB" (май 2002 г.) |
||
| На первую страницу \ Сотрудничество \ MathWorks \ SoftLine \ Exponenta.ru \ Exponenta Pro | ||
| E-mail: info@matlab.ru | ||
| Информация на сайте была обновлена 10.11.2003 |
Copyright 2001-2003 SoftLine Co
|
|
|
|