📄 xferplot.m
字号:
function [sys, x0, str, ts] = xferplot(t,x,u,varargin)%XFERPLOT Frame- and vector-display block for the DSP Blockset.% The DSP Blockset provides several scopes useful for visualizing% frame- or vector-based signals in a Simulink model.%% The following blocks in the "DSP Sinks" library utilize this% scope display:% - Vector Scope% - FFT Frame Scope% - Buffered FFT Frame Scope%% These blocks accept 2-D signals, where an MxN input matrix is% interpreted as N channels of data, each presenting M consecutive% time samples of data. A 1-D signal is interpreted as a single% channel of data.%% Most menu options are duplicated in a context menu, accessible% by right-clicking within the scope display. Depending upon the% scope block, and the number of data channels entering the block,% different options are provided.%% See also DSPLIB.% This is an M-file S-Function used by the DSP Blockset that% implements a frame- or vector-based scope display.% Copyright 1995-2001 The MathWorks, Inc.% $Revision: 1.1.2.1 $ $Date: 2003/03/06 00:39:12 $% RAB, tweaked for transfer function % Syntax:%% xferplot(t,x,u,flag,params);%% where params is a structure containing all block dialog parameters.%% What's in the Figure userdata:% ------------------------------% Main scope figure handles:% fig_data.block block name% fig_data.hfig handle to figure% fig_data.hcspec handle to non-displayed line for color translation%% fig_data.main.haxis handle to axes% fig_data.main.hline Nx1 vector of line handles% fig_data.main.hstem scalar stem line handle% fig_data.main.hgrid vector of handles to axis grid lines% fig_data.main.axiszoom.on P/V cell-array pairs to turn on% fig_data.main.axiszoom.off and off full-axis zoom%% Handles to menu items:% - appearing only in figure menu:% fig_data.menu.recpos record position% fig_data.menu.axislegend (checkable)% fig_data.menu.framenumber (checkable)% fig_data.menu.axisgrid (checkable)% fig_data.menu.memory (checkable)% fig_data.menu.refresh%% - appearing in both figure and context menu:% fig_data.menu.top top-level Axes and Lines in Figure% fig_data.menu.context context menu% fig_data.menu.linestyle 2xN, [fig;context] x [one per display line]% fig_data.menu.linemarker 2xN (children are individual submenu options)% fig_data.menu.linecolor 2xN% fig_data.menu.linedisable 2x1% fig_data.menu.axiszoom 2x1, [fig;context] (checkable)% fig_data.menu.autoscale%%% What's in the Block userdata:% -----------------------------% block_data.firstcall flag for first call to function% block_data.autoscaling indicates autoscale computation in progress% block_data.hfig handle to figure% block_data.hcspec handle to non-displayed line for color translation% block_data.haxis handle to axes% block_data.hline Nx1 vector of line handles% block_data.hstem scalar line handle% block_data.hgrid handles to axis grid lines% block_data.hgridtext vector of handles% block_data.hlegend handle to legend itself% block_data.hframenum handle to frame number text indicator% block_data.params structure of cached block dialog parameters% block_data.Ts updated sample time for block% block_data.inputDims dimension vector of input to scope% block_data.NChans Number of frames (columns) in input matrix%%%% Parameters structure fields:% ----------------------------% .ScopeParams% .Domain: 1=Time, 2=Frequency, 3=User Defined% .XLabel:% Time, Frequency: ignored% User: displayed% .XUnits:% User, Time: ignored% Freq: 1=Hz, 2=rad/s% .InheritXIncr: checkbox% .XIncr: increment of x-axis samples, used for x-axis display% Time: ignored (assumes frame-based)% User, Freq: seconds per sample% .XRange:% User, Time: ignored% Freq: 1=[0,Fn] , 2=[-Fn,Fn], 3=[0, Fs]% (Fn=Nyquist rate, Fs=Sample rate)% .YLabel:% .YUnits:% User, Time: ignored% Freq: 1=Magnitude, 2=dB%% .HorizSpan: Horizontal time span (number of frames)% Only displayed for Time and User-defined%% Optionally displayed in dialog:% .AxisParams: indicates whether the Axis Settings are% currently displayed in block dialog.% .YMin: Minimum y-limit% .YMax: Maximum y-limit% .FigPos: figure position%% .AxisGrid: Current setting, on or off% .AxisZoom: similar% .FrameNumber: similar% .AxisLegend: similar% .Memory: checkbox%% .LineParams:% .LineDisables:% .LineColors: pipe-delimited string of colors, one per channel% .LineStyles: similar% .LineMarkers: similar%% .WindowParams: indicates whether the Scope Settings are% currently displayed in block dialog.% .OpenScopeAtSimStart: checkbox% .OpenScopeImmediately: checkboxswitch(varargin{1})case 3, sys = []; % mdlOutput - unusedcase 2, sys = mdlUpdate(t,x,u,varargin{:});case 0, [sys,x0,str,ts] = mdlInitializeSizes;case 9, sys = mdlTerminate;otherwise % GUI callback: feval(varargin{:}); sys = []; % None of these options change the state:end% -----------------------------------------------------------function [sys,x0,str,ts] = mdlInitializeSizessfcn = gcb; % s-fcnblk = get_param(sfcn,'parent');parent = get_param(blk, 'parent');sizes = simsizes;sizes.NumInputs = -1;sizes.NumOutputs = 0;sizes.NumSampleTimes = 1;sys = simsizes(sizes);x0 = []; % statesstr = ''; % state ordering stringsts = [-1 1]; % inherited sample time, fixed in minor steps%%% if ~syslocked(parent), % No need to execute in a library % (we also want to keep the block UserData empty so that % DialogApply will not run)%%% resetToFirstCall(blk);%%% end% ------------------------------------------------------------function sys = mdlUpdate(t,x,u,flag,params)% Faster implementation of: blk=gcb;cs = get_param(0,'CurrentSystem');cb = get_param(cs,'CurrentBlock');sfcn = [cs '/' cb];blk = get_param(sfcn,'parent');sys = [];block_data = get_param(blk, 'UserData');if block_data.firstcall, first_update(blk, sfcn, u, params);else update_lines(block_data, u);end% ---------------------------------------------------------------function update_lines(block_data, u)% UPDATE_LINES Update the lines in the scope display% u: one frame of data% Does not alter block_data% If the user closed the figure window while the simulation% was running, then hfig has been reset to empty.%% Allow the simulation to continue, do not put up a new figure% window, and do not generate an error if window closes early.%if isempty(block_data.hfig), return; end% Call update_lines function:feval(block_data.UpdateLinesFcn, block_data, u);% Update frame number display:% Always update - it is invisible unless feature is enabled%% UpdateFramenum(block_data);d = get(block_data.hframenum(2),'userdata');set(block_data.hframenum(2), 'userdata', d+1, ... 'string', sprintf('%d',d+1));% Check if autoscaling is in progress:if ~isempty(block_data.autoscaling), Autoscale([],[], block_data, u); % next frame of dataend% ---------------------------------------------------------------function fcn = select_UpdateLinesFcn(block_data)freqDomain = (block_data.params.Domain==2);oneFrame = (block_data.params.HorizSpan==1);oneChan = (block_data.NChans==1);% Use the frame counter to determine where we are:% Counter starts at 0, since it is incremented after% update_lines occurs.nframes = block_data.params.HorizSpan;d = get(block_data.hframenum(2),'userdata');useInit = (d < nframes);if freqDomain, % Frequency domain: if oneChan, fcn = @update_lines_freq_oneframe_onechan; else fcn = @update_lines_freq_oneframe_multichan; endelse % Time domain: if oneFrame, if oneChan, fcn = @update_lines_time_oneframe_onechan; else fcn = @update_lines_time_oneframe_multichan; end else if oneChan, if useInit, fcn = @init_lines_time_multiframe_onechan; else fcn = @update_lines_time_multiframe_onechan; end else if useInit, fcn = @init_lines_time_multiframe_multichan; else fcn = @update_lines_time_multiframe_multichan; end end endend% ---------------------------------------------------------------function update_lines_freq_oneframe_onechan(block_data, u)% Single channel% One frame per horizontal span[nrows,nchans] = size(u);% Frequency domain conversions% Convert to dB if required:if(block_data.params.YUnits==2), u = lin2dB(u);end% Rotate data if display range is [-Fn, Fn]:if (block_data.params.XRange==2), % rotate each channel of data: p = nrows./2; % all FFT's are a power of 2 here u = u([p+1:nrows 1:p],:);endset(block_data.hline, 'YData', u);if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: ystem = get(block_data.hstem,'ydata'); ystem((0:nrows-1)*3 + 2) = u; set(block_data.hstem,'ydata',ystem);end% ---------------------------------------------------------------function update_lines_freq_oneframe_multichan(block_data, u)% One frame per horizontal span% Multiple channels (matrix input)[nrows,nchans] = size(u);% Frequency domain conversions% Convert to dB if required:if(block_data.params.YUnits==2), u = lin2dB(u);end% Rotate data if display range is [-Fn, Fn]:if (block_data.params.XRange==2), % rotate each channel of data: p = nrows./2; % all FFT's are a power of 2 here u = u([p+1:nrows 1:p],:);endhline = block_data.hline;if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: ystem = get(block_data.hstem,'ydata'); kup = (0:length(u)-1)*3 + 2; % index to top of stems kdn = kup-1; % index to bottom of stems ystem(kup) = 0; ystem(kdn) = 0; markerpipestr = block_data.params.LineMarkers; for i = 1:nchans, % block_data.NChans val = u(:,i)'; set(hline(i), 'YData', val); if strcmp(get_pipestr(markerpipestr, i,1), 'stem'), ystem(kup) = max(ystem(kup), val); ystem(kdn) = min(ystem(kdn), val); end end set(block_data.hstem,'ydata',ystem); else for i = 1:nchans, % block_data.NChans set(hline(i), 'YData', u(:,i)); endend% ---------------------------------------------------------------function update_lines_time_oneframe_onechan(block_data, u)% One frame per horizontal span% Single channelset(block_data.hline, 'YData', u);if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: [nrows,nchans] = size(u); ystem = get(block_data.hstem,'ydata'); ystem((0:nrows-1)*3 + 2) = u; set(block_data.hstem,'ydata',ystem);end% ---------------------------------------------------------------function update_lines_time_oneframe_multichan(block_data, u)% One frame per horizontal span% Multiple channels (matrix input):[nrows,nchans] = size(u);hline = block_data.hline;if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: ystem = get(block_data.hstem,'ydata'); kup = (0:length(u)-1)*3 + 2; % index to top of stems kdn = kup-1; % index to bottom of stems ystem(kup) = 0; ystem(kdn) = 0; markerpipestr = block_data.params.LineMarkers; for i = 1:nchans, % block_data.NChans val = u(:,i)'; set(hline(i), 'YData', val); if strcmp(get_pipestr(markerpipestr, i,1), 'stem'), ystem(kup) = max(ystem(kup), val); ystem(kdn) = min(ystem(kdn), val); end end set(block_data.hstem,'ydata',ystem);else for i = 1:nchans, % block_data.NChans set(hline(i), 'YData', u(:,i)); endend% ---------------------------------------------------------------function init_lines_time_multiframe_onechan(block_data, u)% differs from update_lines_time_multiframe_onechan in that% this begins rendering data from the LEFT side of the display.% Used at the start (or re-start) of a simulation, and% is only used for nframes number of input frames. After that,% the non-init version is installed and used thereafter.% Multiple frames per horiz span% Single channel[nrows,nchans] = size(u);nframes = block_data.params.HorizSpan;% Use the frame counter to determine where we are:% Counter starts at 0, since it is incremented after% update_lines occurs.d = get(block_data.hframenum(2),'userdata');y = get(block_data.hline,'YData')';y(d*nrows+1 : (d+1)*nrows, :) = u;set(block_data.hline, 'YData', y);if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: ystem = get(block_data.hstem,'ydata'); ystem( 3*nrows*d + (0:length(u)-1)*3 + 2 ) = u; set(block_data.hstem,'ydata',ystem);endif (d >= nframes-1), % install non-init update fcn: % Cache the appropriate line-update function: block_data.UpdateLinesFcn = @update_lines_time_multiframe_onechan; ud=get(block_data.hfig,'userdata'); set_param(ud.block,'userdata',block_data);end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -