- •Лабораторная работа № 9 тема: «Связь Simulink-модели и приложения с графическим интерфейсом»
- •Описание приложения с графическим интерфейсом и Simulink-модели
- •Аргументы mysfun
- •Подфункция mdlInitializeSizes
- •Value - текущее значение, задаем равным InitControl.
- •Подфункция mdlUpdate
- •Окно с запросом на удаление окна приложения
- •Подфункция sldCallback
- •Текст s-функции mysfun с подфункциями
Подфункция sldCallback
Подфункция sldCallback служит для обработки события Callback, которое возникает при изменении положения бегунка полосы прокрутки. Ее первый входной аргумент src содержит указатель на полосу прокрутки, а второй evt не используется, но нужен при программировании функций обработки событий от элементов интерфейса.
В подфункции sldCallback при помощи функции get значение, соответствующее положению бегунка, (т.е. значение свойства Value) записывается в переменную s. Далее используется функция set_param для задания этого значения блоку Control нашей Simulink-модели. Первый ее аргумент является полным именем блока, которое формируется сцеплением строк. Первая из них - имя модели - возвращается функцией gcs, а вторая является именем блока. (Полное имя блока является иерархическим, оно состоит из имени системы, дальше возможны подсистемы, которым принадлежит блок, и имени самого блока, причем все имена разделяются косой чертой). При задании значения константе в Simulink-модели требуется преобразование числового значения в строковое представление, которое выполняется при помощи функции num2str.
Текст s-функции mysfun с подфункциями
function [sys, x0, str, ts] = mysfun(t, x, u, flag)
% Основная функция для блока S-function
% Определение действия в зависимости от значения flag
switch flag
case 0
% Инициализация S-функции
[sys, x0, str, ts] = mdlInitializeSizes;
case 2
% Действия, производимые на каждом шаге по времени
sys=mdlUpdate(t, x, u);
case 3
% Вычисление значений на выходах S-функции
sys=mdlOutputs(t,x,u);
case 9
% Завершение работы
sys=mdlTerminate(t,x,u);
otherwise
% выводим ошибку, т.к. действие не определено
error(['Unhandled flag = ',num2str(flag)]);
end
function [sys, x0, str, ts] = mdlInitializeSizes
% Инициализация S-функции
% Получение структуры с описанием S-функции
sizes = simsizes;
% задание числа входных портов
sizes.NumInputs = 2;
% число дискретизаций по времени
sizes.NumSampleTimes = 1;
% создание вектора с информацией об S-функции
sys = simsizes(sizes);
% задание начальных условий
x0 = [];
% параметр str зарезервирован для будущих расширений,
% полагаем его пустым массивом
str = [];
% задание вектора с шагами расчета
ts = [-1 0];
% создание графического окна GUI_Simulink
% и запись указателя на него в переменную Fig
Fig=figure('Position',[100 100 400 300],...
'Color', 'k',...
'MenuBar', 'none',...
'Name', 'GUI_Simulink',...
'NumberTitle', 'off');
% задание начального значения параметра Control
InitControl = 1;
% создание полосы прокрутки, значения которой
% изменяются от 0 до 5, начальное значение равно InitControl
uicontrol('Style', 'slider',...
'Position',[10 10 380 15],...
'Min', 0, 'Max', 5, 'Value', InitControl,...
'Callback', @sldCallback);
% установка константе Control в Simulink-модели
% значения InitControl
set_param([gcs '/Control'],'Value',num2str(InitControl));
% создание нижних осей для вывода сигнала
axes('Tag', 'ax1',...
'Units', 'pixels',...
'Position',[30 50 350 100],...
'NextPlot','add',...
'Xlim', [0 50],...
'Ylim', [-5.2 5.2],...
'Color','k',...
'Xcolor', 'g',...
'YColor', 'g',...
'Box', 'on',...
'XGrid', 'on',...
'YGrid', 'on');
% создание верхних осей для вывода параметра Control
axes('Tag', 'ax2',...
'Units', 'pixels',...
'Position',[30 180 350 100],...
'NextPlot','add',...
'Xlim', [0 50],...
'Ylim', [-0.2 5.2],...
'Color','k',...
'Xcolor', 'g',...
'YColor', 'g',...
'Box', 'on',...
'XGrid', 'on',...
'YGrid', 'on');
% создание заголовка Signal для нижних осей
uicontrol('Style', 'text',...
'String', 'Signal',...
'Position', [180 152 50 16],...
'FontSize', 10,...
'FontWeight', 'bold',...
'BackgroundColor', 'k',...
'ForegroundColor', 'm')
% создание заголовка Control для верхних осей
uicontrol('Style', 'text',...
'String', 'Control',...
'Position', [180 282 50 16],...
'FontSize', 10,...
'FontWeight', 'bold',...
'BackgroundColor', 'k',...
'ForegroundColor', 'y')
% сохранение указателя на графическое окно в свойстве
% UserData S-функции
set_param(gcbh, 'UserData', Fig);
function sys=mdlUpdate(t, x, u)
% действия, выполняемые на каждом шаге по времени
% получаем указатель на графическое окно GUI_Simulink
Fig = get_param(gcbh,'UserData');
% получаем структуру указателей на объекты окна GUI_Simulink
Handles = guihandles(Fig);
% Выясняем, нужно ли сдвинуть пределы по оси времени на 50 сек.
PassedSampleNum = int32(t*10);
if mod(PassedSampleNum, 500) == 0
set(Handles.ax1, 'XLim', [t t+50])
set(Handles.ax2, 'XLim', [t t+50])
end
% делаем текущими нижние оси
axes(Handles.ax1)
% получаем координаты предыдущей точки
LastPoint = get(Handles.ax1, 'UserData');
if ~isempty(LastPoint)
% соединяем предыдущую точку линией с текущей
plot([LastPoint(1) t],[LastPoint(2) u(2)*u(1)],...
'Color', 'm', 'LineWidth', 2)
set(Handles.ax1, 'UserData', [t, u(1)*u(2)])
else
% предыдущей точки не было, т.к. текущая точка - первая
% выводим текущую точку на оси
set(Handles.ax1, 'UserData', [t, u(1)*u(2)])
plot(t, u(1)*u(2), 'Color', 'm', 'LineWidth', 2 )
end
% делаем текущими верхние оси
axes(Handles.ax2)
% получаем координаты предыдущей точки
LastPoint = get(Handles.ax2, 'UserData');
if ~isempty(LastPoint)
% соединяем предыдущую точку линией с текущей
plot([LastPoint(1) t],[LastPoint(2) u(1)],...
'Color', 'y', 'LineWidth', 2)
set(Handles.ax2, 'UserData', [t, u(1)])
else
% предыдущей точки не было, т.к. текущая точка - первая
% выводим текущую точку на оси
set(Handles.ax2, 'UserData', [t, u(1)])
plot(t, u(1), 'Color', 'y', 'LineWidth', 2 )
end
sys = [];
function sys=mdlOutputs(t,x,u)
% вычисление значений на выходах блока S-function
%выходов нет, поэтому присваиваем пустой массив.
sys=[];
function sys=mdlTerminate(t,x,u)
% действия, выполняемые при завершении работы
% Simulink-модели
% выводим диалоговое окно с запросом на удаление окна GUI_Simulink
button = questdlg('Delete the GUI_Simulink window?','GUI_Simulink',...
'No','Yes','No');
if isequal(button, 'Yes')
% если было выбрано удаление, то получаем указатель
% на окно GUI_Simulink
Fig = get_param(gcbh,'UserData');
% удаляем его
delete(Fig)
end
sys = [];
function sldCallback(src,evt)
% обработка события Callback полосы прокрутки
% получаем значение, установленное полосой прокрутки
s = get(src, 'Value');
% задаем это значение константе Control в Simulink-модели
set_param([gcs '/Control'], 'Value', num2str(s));