📄 sfunyst.m
字号:
function [sys, x0, str, ts] = sfunyst(t, x, u, flag, ax, ltype, npts, dt)
%SFUNYST S-function storage scope using graph window.
%
% This M-file is designed to be used in a SIMULINK S-function block.
% It stores the previous input points using discrete states
% and then plots this against time.
%
% S-function Syntax (see SFUNC):
% [SYS, X0] = SFUNYST(T,X,U,FLAG,AX,LTYPE,NPTS)
% where:
% AX - initial graph axis
% LTYPE - line type (e.g. 'r','r-.','x') (See PLOT)
% NPTS - number of storage points
%
% See also, PLOT, SFUNY, SFUNXY, LORENZ2.
% Copyright (c) 1990-94 by The MathWorks, Inc.
% Andrew Grace 1-27-92.
% Revised Wes Wang 4-28-93, 8-17-93, 12-6-93.
if abs(flag) == 2 | flag == 9 % A real time hit or end of simulation (flag 9)
npts = x(7);
len_u = length(u);
% add handle here
h_fig = x(8);
if (h_fig <= 0)
if length(ax) < 4
disp('Axis not defined correctly; using current axis');
ax = [0 1 0 1];
end
% Initialize graph
[sl_name,block] = get_param;
[n_b, m_b]= size(block);
if n_b < 1
error('Cannot delete block while simulating')
elseif n_b > 1
error('Something wrong in get_param, You don''t have the current SIMULINK')
end;
% find out if the graphics window exists
ind = find(sl_name == setstr(10));
dash = '_';
sl_name(ind)=dash(ones(size(ind)));
% find out if the graphics window exists
Figures = get(0,'Chil');
new_figure = 1;
i = 1;
while ((new_figure) & (i <= length(Figures)))
if strcmp(get(Figures(i), 'Type'), 'figure')
if strcmp(get(Figures(i), 'Name'), sl_name)
h_fig = Figures(i);
handles = get(h_fig,'UserData');
new_figure = 0;
h_axis = handles(1);
set(0,'CurrentF',h_fig);
set(h_axis,'Xlim',ax(1:2),'Ylim',ax(3:4),...
'UserData',[]);
%input number has been changed
delete(get(h_axis,'Child'));
h_plot = [];
h_plot2 = [];
set(h_axis,'NextPLot','add');
set(h_fig,'NextPlot','add');
coll = ltype;
for k=1:len_u
[col, coll]=strtok(coll,'/');
if length(col) <= 1
col = 'w-';
end;
h_plot(k) = plot(0,0,col,'Erasemode','none','Color',...
col(1),'LineStyle',col(2:length(col)));
h_plot2(k) = plot(0,0,col,'Erasemode','none','Color',...
col(1),'LineStyle',col(2:length(col)));
set(h_plot(k),'UserData',[]);
end;
set(h_fig,'UserData',[h_axis, h_plot, h_plot2 ax(2:4), abs(ltype)]);
set(h_axis,'NextPlot','new');
set(h_fig,'NextPlot','new');
end;
end;
i = i + 1;
end;
% the figure does not exist, and this is an end of simulation (flag 9) call
% exit early
if new_figure & (flag == 9)
sys = [];
return;
end;
% the figure does not exist, create a new figure
if new_figure
h_fig = figure('Unit','pixel','Pos',[100 100 400 300], ...
'Name',sl_name, 'Number','off');;
set(0, 'CurrentF', h_fig);
h_axis = axes('Xlim', ax(1:2), 'Ylim', ax(3:4),... %'XTickLabels',[],'YTickLabels',[],...
'UserData',[],'Box','on');
set(h_axis,'NextPlot','add');
coll = ltype;
for k=1:len_u
[col,coll] = strtok(coll,'/');
if length(col) <= 1
col = 'w-';
end;
h_plot(k) = plot(0,0,col,'Erasemode','none','Color',...
col(1),'LineStyle',col(2:length(col)));
h_plot2(k) = plot(0,0,col,'Erasemode','none','Color',...
col(1),'LineStyle',col(2:length(col)));
set(h_plot(k),'UserData',[]);
end;
set(h_fig,'UserData',[h_axis, h_plot, h_plot2, ax(2:4), abs(ltype)]);
set(h_axis,'NextPlot','new');
set(h_fig,'NextPlot','new');
xl = get(h_axis,'XLabel');
set(xl,'String','Time (second)');
end;
set(h_axis,'XGrid','on','YGrid','on');
set(h_fig,'Color',get(h_fig,'Color'));
set(h_fig,'NextPlot','new');
% Initial conditions
% Infinity flags used to signal first point.
x = [0, -Inf, ax(1:4), npts, h_fig, 0];
set(h_fig, 'UserData',[h_axis, h_plot, h_plot2, ax(2:4), abs(ltype)]);
end;
if ((max(get(0,'Child') == h_fig) > 0) | flag == 9)
handles = get(h_fig,'UserData');
len_c = length(ltype);
len_h = length(handles);
axis_color_reset = 0;
if (t>x(2)) | ((len_u*2 + len_c) ~= (len_h - 4))
axis_color_reset = 1;
elseif max([ax(2:4) abs(ltype)] ~= handles(2*len_u+2:len_h))
axis_color_reset = 1;
end;
h_axis = handles(1);
h_plot = handles(2:len_u+1);
h_plot2 = handles(len_u+2:len_u+len_u+1);
axss = [handles(len_u+len_u+3:len_u+len_u+4) npts];
if (length(ax) == 4) & (length(npts) ==1)
if min(axss==[ax(3:4), npts]) <1
axis_color_reset = 1;
% sys(9) = 4; %flag for replot
set(h_fig, 'UserData',[h_axis, h_plot, h_plot2, ax(2:4), abs(ltype)]);
end;
end;
discrete = any(get_param(gcb, 'sample time'));
% Loop counter
x_m = x(1);
x(1) = x(1) + 1;
if x(1) > npts
x(1) = x(1) - npts;
end;
% h_axis UserData saves the time
% h_plot UserData saves the previous input points
sys = x;
% Store last time and input point in circular buffer.
buffer_t = get(h_axis,'UserData');
len_b = length(buffer_t);
if len_b < npts
buffer_t = [buffer_t; t];
else
buffer_t(sys(1)) = t;
end;
set(h_axis,'UserData', buffer_t);
buffer_y = [];
for k=1:len_u
tmp = get(h_plot(k),'UserData');
if len_b < npts
tmp = [tmp; u(k)];
else
tmp(sys(1)) = u(k);
end;
set(h_plot(k),'UserData',tmp);
buffer_y = [buffer_y tmp];
end;
% If the input significantly exceeds the Y-axis
% then count how many times this happens.
if (1.1*u < sys(5)) | (1.1*u > sys(6))
sys(9) = sys(9) + 1;
end
% If the time is greater than the X-axis or
% the input has exceeded the Y-axis more than 3 times
% or it is the end of simulation then rescale and replot.
if (t > sys(2)) | (sys(9) > 3) | (flag == 9) | (axis_color_reset == 1)
sys(9) = 0; % Set 'exceed Y-axis' counter to zero.
if (sys(2) == -Inf) % Initial point
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)
% If time has exceeded axis limit then
% be conservative in rescaling factor for Y axis:
factor = 1.2;
sys(2) = sys(2) + ax(2);
else
% otherwise double scaling:
factor = 2;
end
newax(1,2) = sys(2);
if ~isempty(buffer_t)
newax(1,1) = min(buffer_t);
end;
% Work out new Y-axis ranges:
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;
if (discrete)
indx = [ 2:len_b; 2:len_b ];
tmp_t = tmp_t([1; indx(:)]);
end
% Plot stored points and the y=0 line:
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 (discrete)
indx = [ 1:(len_b - 1); 1:(len_b - 1) ];
tmp = [tmp([indx(:); len_b])];
end
set(h_plot2(k), 'XData', tmp_t, 'YData',tmp);
end;
set(h_axis,'Xlim',newax(1:2),'Ylim',newax(3:4));
set(h_fig,'Color',get(h_fig,'Color'));
end
len_b = length(buffer_t);
if (sys(1,1) == 1) & (len_b < npts) % Is it first point in cycle
% Use none as Erasemode for faster plotting
for k=1:len_u
set(h_plot(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
if (discrete)
set(h_plot(k),'XData',[buffer_t(x_m), t, t ],...
'YData',[buffer_y(x_m,k), buffer_y(x_m,k), u(k)]);
else
set(h_plot(k),'XData',[buffer_t(x_m),t],'YData',[buffer_y(x_m,k),u(k)]);
end
end;
drawnow
end
if (sys(1) == npts) | (sys(1) == (npts + 1))
sys(1,1) = 0;
end
if flag == 9
sys = [];
end
else
sys = x;
end;
elseif flag == 0, % Initialization
% Return system sizes:
test = length(u);
if test <= 0
test = -1;
end;
sys(1) = 0; % 0 continuous states
% sys(2) = 6 + 2*npt s+ 4; % discrete states
sys(2) = 9; % discrete states
sys(3) = 0; % 0 outputs
sys(4) = test; % 1 input
sys(5) = 0; % 0 roots
sys(6) = 0; % no direct feedthrough
sys(7) = 1; % 1 sample time
%x ==> [flag_for_replot, time_record, axes(x_l,x_h,y_l,y_h), npts, figure_handle, plot_control]
if length(ax) ~= 4
error('axis limit has not set correctly')
end;
if npts <=0
npts = 1;
end;
x0 = [0, -Inf, ax(1), ax(2), ax(3), ax(4), npts, 0, 0];
if (nargin > 7)
ts = [dt, 0];
else
ts = [-1, 0];
end
elseif (flag == 4) & (nargin > 7)
if (dt > 0)
sys = t + dt;
else
sys = [];
end;
else
% Other flag options not defined.
sys = [];
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -