分享一个用S-Function编写的离散函数自动生成Matlab图形窗口并封装成Scope
示例
脚本如下
function [sys,x0,str,ts] = sfunyst(t,x,u,flag,ax,ltype,npts,dt)
if (nargin <= 7)
dt = -1;
end
switch flag,
case 0,
[sys,x0,str,ts]=mdlInitializeSizes(t,u,ax,ltype,npts,dt);
if isempty(get_param(gcb,'DeleteFcn'))
SetBlockCallbacks(gcb);
end
case {2,9}
sys=mdlUpdate(t,x,u,flag,ax,ltype,npts,dt);
case {1,3}
case { 'CopyBlock', 'LoadBlock' }
LocalCopyLoadBlock
case 'DeleteBlock'
LocalDeleteBlock
case 'DeleteFigure'
LocalDeleteFigure
otherwise
if ischar(flag),
DAStudio.error('Simulink:blocks:unhandledFlag', flag);
else
DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
end
end
function [sys,x0,str,ts]=mdlInitializeSizes(t,u,ax,ltype,npts,dt)
sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumOutputs = 0;
sizes.NumInputs = -1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
if length(ax) ~= 4
DAStudio.error('Simulink:blocks:axisLimitsAreIncorrect');
end;
x0 = [0, -Inf, ax(1), ax(2), ax(3), ax(4), npts, 0, 0];
str = [];
ts = [dt, 0];
if strcmp(get_param(bdroot,'SimulationStatus'),'initializing')
SfunYSTFigure('Initialize',t,ax,ltype);
end
function sys=mdlUpdate(t,x,u,flag,ax,ltype,npts,dt)
FigHandle=SfunYSTFigure('Get');
if ~ishghandle(FigHandle),
sys=[];
return
end
set(0,'CurrentFigure', FigHandle)
ud = get(FigHandle,'UserData');
len_u = length(u);
if isempty(ud.InitialTime)
cla;
coll = ltype;
hold on;
for k=1:len_u
[col,coll] = strtok(coll,'/');
if length(col) <= 1
col = 'b-';
end;
ud.Line(k) = plot(0,0,col,'Color',...
col(1),'LineStyle',col(2:length(col)));
ud.Line2(k) = plot(0,0,col,'Color',...
col(1),'LineStyle',col(2:length(col)));
end;
set(ud.SysAxis,'Xlim',ax(1:2),'Ylim',ax(3:4));
set(ud.SysAxis,'UserData',[]);
drawnow;
ud.InitialTime = t;
set(FigHandle,'UserData',ud);
end;
npts = x(7);
if npts <=0
npts = 1;
end;
len_u = length(u);
x_m = x(1);
x(1) = x(1) + 1;
if x(1) > npts
x(1) = x(1) - npts;
end;
sys = x;
buffer_t = get(ud.SysAxis,'UserData');
len_b = length(buffer_t);
if len_b < npts
buffer_t = [buffer_t; t];
else
buffer_t(sys(1)) = t;
end;
set(ud.SysAxis,'UserData', buffer_t);
buffer_y = [];
for k=1:len_u
tmp = get(ud.Line(k),'UserData');
if len_b < npts
tmp = [tmp; u(k)];
else
tmp(sys(1)) = u(k);
end;
set(ud.Line(k),'UserData',tmp);
buffer_y = [buffer_y tmp];
end;
if (1.1*u < sys(5)) | (1.1*u > sys(6))
sys(9) = sys(9) + 1;
end
if (t > sys(2)) | (sys(9) > 3) | (flag == 9)
if (flag == 9)
sys = [];
else
sys(2) = ax(2);
end
return
end
newax = ax;
if flag == 9
factor = 1.2;
sys(2) = t;
elseif t > sys(2)
factor = 1.2;
sys(2) = sys(2) + ax(2);
else
factor = 2;
end
newax(1,2) = sys(2);
if ~isempty(buffer_t)
newax(1,1) = min(buffer_t);
end;
minb = min(min(buffer_y));
maxb = max(max(buffer_y));
if ~isempty(minb)
if minb < 0
newax(1,3) = factor*minb;
else
newax(1,3) = (1/factor)*minb;
end
if maxb > 0
newax(1,4) = factor*max(max(buffer_y));
else
newax(1,4) = (1/factor)*max(max(buffer_y));
end
else
newax(1,3) = ax(3);
newax(1,4) = ax(4);
end;
sys(5) = newax(1,3);
sys(6) = newax(1,4);
if newax(4) <= newax(3)
if (newax(3) ~= 0)
newax(4) = newax(3) * (1 + eps);
else
newax(4) = eps;
end
end;
if newax(2) <= buffer_t(1)
if (buffer_t(1) ~= 0)
newax(2) = buffer_t(1) * (1 + eps);
else
newax(2) = eps;
end
end;
len_b = length(buffer_t);
if (sys(1) ~= len_b) & (len_b == npts)
tmp_t = [buffer_t(sys(1)+1:len_b); buffer_t(1:x(1))];
else
tmp_t = [buffer_t(1:len_b)];
end;
for k=1:len_u
if (sys(1) ~= len_b) & (len_b == npts)
tmp = [buffer_y(sys(1)+1:len_b,k); buffer_y(1:x(1),k)];
else
tmp = [buffer_y(1:len_b,k)];
end;
set(ud.Line2(k), 'XData', tmp_t, 'YData',tmp);
end;
set(ud.SysAxis,'Xlim',newax(1:2),'Ylim',newax(3:4));
set(FigHandle ,'Color',get(FigHandle,'Color'));
len_b = length(buffer_t);
for k=1:len_u
set(ud.Line(k), 'XData',[t,t], 'YData',[u(k),u(k)]);
end;
else
if x_m <= 0
x_m = len_b;
end;
for k=1:len_u
set(ud.Line(k),'XData',[buffer_t(x_m),t],'YData',[buffer_y(x_m,k),u(k)]);
end
end
set(ud.SysAxis,'Visible','on');
else
if (sys(1) ~= len_b) & (len_b == npts)
tmp_t = [buffer_t(sys(1)+1:len_b); buffer_t(1:x(1))];
else
tmp_t = [buffer_t(1:len_b)];
end;
for k=1:len_u
if (sys(1) ~= len_b) & (len_b == npts)
tmp = [buffer_y(sys(1)+1:len_b,k); buffer_y(1:x(1),k)];
else
tmp = [buffer_y(1:len_b,k)];
end;
if x_m <= 0
x_m = len_b;
end;
set(ud.Line2(k),'XData',tmp_t,'YData',tmp);
set(ud.Line(k),'XData',[buffer_t(x_m),t],'YData',[buffer_y(x_m,k),u(k)]);
end;
set(ud.SysAxis,'Visible','on');
end
drawnow;
if (sys(1) == npts) | (sys(1) == (npts + 1))
sys(1,1) = 0;
end
if flag == 9
sys = [];
end
function FigHandle=SfunYSTFigure(action,t,ax,ltype)
FigHandle = get_param(gcb,'UserData');
if isempty(FigHandle),
FigHandle=-1;
end
switch action
case 'Get',
return;
case 'Initialize',
if ~ishghandle(FigHandle),
FigHandle = CreateSfunYSTFigure(t,ax);
end
ud = get(FigHandle,'UserData');
ud.InitialTime = t;
set(FigHandle,'Userdata',ud);
otherwise,
DAStudio.error('Simulink:blocks:unexpectedAction', action);
end
function FigHandle=CreateSfunYSTFigure(t,ax)
sl_name = get_param(get_param(gcb,'Parent'),'Name');
FigHandle = figure('Unit','pixel',...
'Pos',[100 100 400 300],...
'Name',sl_name, 'NumberTitle','off');
ud.Block=get_param(gcb,'Handle');
ud.SysAxis = subplot(1,1,1);
set(ud.SysAxis,'Box','on');
if length(ax) < 4
disp(DAStudio.message('Simulink:dialog:AxisUseCurrent'));
ax = [0 1 0 1];
end
set(ud.SysAxis,'Xlim',ax(1:2),'Ylim',ax(3:4));
set(ud.SysAxis,'Visible','off');
set(ud.SysAxis,'XGrid','on','YGrid','on');
ud.AxisLimits = ax;
ud.Xlabel = get(ud.SysAxis,'Xlabel');
set(ud.Xlabel,'String', DAStudio.message('Simulink:dialog:TimeInSeconds'));
ud.Title = get(ud.SysAxis,'Title');
titl = strrep(bdroot,'_','\_');
set(ud.Title,'String',titl);
SetSfunYSTFigure(gcb,FigHandle);
set(FigHandle,'HandleVisibility','on','UserData',ud);
function SetSfunYSTFigure(block,FigHandle)
set_param(block,'UserData',FigHandle);
function LocalCopyLoadBlock
SetSfunYSTFigure(gcb,-1);
function LocalDeleteBlock
FigHandle=SfunYSTFigure('Get');
if ishghandle(FigHandle),
delete(FigHandle);
SetSfunYSTFigure(gcb,-1);
end
function LocalDeleteFigure
ud=get(gcbf,'UserData');
SetSfunYSTFigure(ud.Block,-1)
function SetBlockCallbacks(block)
set_param(block, 'CopyFcn', 'sfunyst([],[],[],''CopyBlock'')')
set_param(block, 'LoadFcn', 'sfunyst([],[],[],''LoadBlock'')')
set_param(block, 'DeleteFcn', 'sfunyst([],[],[],''DeleteBlock'')')