Home > m > gui > gltpda > ltpdasim.m

ltpdasim

PURPOSE ^

This is the automatic function wrapper

SYNOPSIS ^

function ltpdasim(block)

DESCRIPTION ^

             This is the automatic function wrapper
 ========================================================================
 ==================== level-2 M file S-function =========================
 ========================================================================
 This wrapper is the automatic function, called by every function block
 in Simulink, able to execute m-file functions retrieving from Simulink:
 (1) the pointer to the object(s) to be analyzed, coming in as input of 
     the corresponding block (ie, the DATA),
 (2) the name of the function to be applied on those data, from the tag
     of the currently executed block (ie, the true FUNCTION),
 (3) the parameters for that particular block, retrieved from the global
     shared workspace by the handle of the block (ie, the PARAMETERS).

 The output is then generated as:
    OUTPUT = FUNCTION(DATA,PARAMETERS)

 This output in the end is saved into the global array containing all
 the AOs (ie, all the DATA go together with other data): thus this output
 will be freely accessible by all the other functions.

 The only real output to Simulink will be just the ordinal number of the
 so-generated AO into the global array of AOs.

   $Id: ltpdasim.m,v 1.9 2008/03/26 15:14:58 nicola Exp $

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function ltpdasim(block)
0002 
0003 %             This is the automatic function wrapper
0004 % ========================================================================
0005 % ==================== level-2 M file S-function =========================
0006 % ========================================================================
0007 % This wrapper is the automatic function, called by every function block
0008 % in Simulink, able to execute m-file functions retrieving from Simulink:
0009 % (1) the pointer to the object(s) to be analyzed, coming in as input of
0010 %     the corresponding block (ie, the DATA),
0011 % (2) the name of the function to be applied on those data, from the tag
0012 %     of the currently executed block (ie, the true FUNCTION),
0013 % (3) the parameters for that particular block, retrieved from the global
0014 %     shared workspace by the handle of the block (ie, the PARAMETERS).
0015 %
0016 % The output is then generated as:
0017 %    OUTPUT = FUNCTION(DATA,PARAMETERS)
0018 %
0019 % This output in the end is saved into the global array containing all
0020 % the AOs (ie, all the DATA go together with other data): thus this output
0021 % will be freely accessible by all the other functions.
0022 %
0023 % The only real output to Simulink will be just the ordinal number of the
0024 % so-generated AO into the global array of AOs.
0025 %
0026 %   $Id: ltpdasim.m,v 1.9 2008/03/26 15:14:58 nicola Exp $
0027 
0028 
0029 setup(block);
0030 
0031 
0032 %% Setup
0033 
0034 function setup(block)
0035 
0036   %% Register dialog parameter: none, because they're retrieved directly
0037   %% from the memory. This will prevent the user to modify the parameters
0038   %% outside the proper parameters panel:
0039   block.NumDialogPrms = 0;
0040 
0041   %% Register number of input and output ports
0042   block.NumInputPorts  = 1;
0043   block.NumOutputPorts = 1;
0044 
0045   %% Setup functional port properties to dynamically inherited.
0046   block.SetPreCompInpPortInfoToDynamic;
0047 % block.SetPreCompOutPortInfoToDynamic;
0048 
0049   block.InputPort(1).DirectFeedthrough = true;
0050   block.InputPort(1).DatatypeID = 0;
0051   block.InputPort(1).Complexity = 0;
0052   block.OutputPort(1).DatatypeID = 0;
0053   block.OutputPort(1).Complexity = 0;
0054   block.SampleTimes = [0 0];
0055   block.SetAccelRunOnTLC(false);
0056   
0057   block.OutputPort(1).Dimensions = 1;
0058   
0059   %% Register methods
0060   block.RegBlockMethod('SetInputPortSamplingMode',@SetInpPortFrameData);
0061   block.RegBlockMethod('SetInputPortDimensions',  @SetInpPortDims);
0062 % block.RegBlockMethod('SetOutputPortDimensions', @SetOutPortDims);
0063   block.RegBlockMethod('Outputs',                 @Outputs);
0064   
0065   function SetInpPortFrameData(block, idx, fd)
0066   block.InputPort(1).SamplingMode = fd;
0067   block.OutputPort(1).SamplingMode  = fd;
0068   
0069   function SetInpPortDims(block, idx, di)
0070   block.InputPort(idx).Dimensions = di;
0071   
0072 %   function SetOutPortDims(block, idx, di)
0073 % % %       if isempty(block.DialogPrm(1).Data)
0074 % % %           numbOuts = 1;
0075 % % %       else
0076 % % %           numbOuts = block.DialogPrm(1).Data;
0077 % % %       end
0078 % % %       if isempty(find_system(get_param(gcbh,'Parent'),'SearchDepth',1,'LookUnderMasks','all','BlockType','Mux'))  && ~exist('category','var')
0079 % % % %           block.OutputPort(1).Dimensions = di^(numbOuts);
0080 % % %           outdims=(block.InputPort(1).Dimensions)^numbOuts
0081 % % %           block.OutputPort(idx).Dimensions = outdims;
0082 % % %
0083 % % %       end
0084 
0085 
0086 
0087 %% Outputs
0088 function Outputs(block)
0089 global LTPDAinvar
0090 
0091 % Check if the user wants to stop the execution:
0092 lastChar = get(findobj('Name','LTPDA Progress Bar'),'CurrentCharacter');
0093 if ~isempty(lastChar) && strcmp(lastChar,'x')
0094     set_param(bdroot, 'SimulationCommand', 'stop')
0095     return
0096 end
0097 
0098 % Update the progress bar window:
0099   blocksTotal = get(findobj('Tag','blockstotal'),'UserData');
0100   blocksDone  = get(findobj('Tag','done'),'UserData');
0101   blocksToGo  = get(findobj('Tag','togo'),'UserData');
0102   set(findobj('Tag','done'),'UserData',blocksDone+1);
0103   set(findobj('Tag','togo'),'UserData',blocksToGo-1);
0104   set(findobj('Tag','done'),'String',['Done: ',num2str(blocksDone+1)]);
0105   set(findobj('Tag','togo'),'String',['To go: ',num2str(blocksToGo-1)]);
0106   set(findobj('Tag','currentexec'),'String',['Currently executed block: ',get_param(get_param(gcbh,'Parent'),'Name')]);
0107   progressBar  = findobj('Tag','progressaxes');
0108   progressSize = get(progressBar,'UserData');
0109   progressPosition    = get(progressBar,'Position');
0110   progressPosition(3) = 1+(progressSize(3)/blocksTotal)*(blocksDone+1);
0111   set(progressBar,'Position',progressPosition)
0112   pause(0.1)
0113 
0114 % Retrieve the function name from the block tag:
0115   blocktag = get_param(gcb, 'tag');
0116   
0117 % Convert it into lowercase letters:
0118   blocktag = lower(blocktag);
0119   
0120 %%
0121 % ========================================================================
0122 % ==================== RETRIEVE THE PARAMETERS LIST ======================
0123 % ========================================================================
0124 
0125   % retrieve the handle of the currently executed block;
0126     currparent = get_param(gcbh,'Parent');
0127     subsyshandle = get_param(currparent, 'handle');
0128 
0129   % The command line to produce the proper parameters list for the block
0130   % currently executed is retrieved from the description of this  parent subsystem
0131     paramcommand = get_param(subsyshandle,'Description');
0132 
0133     if ~isempty(paramcommand)
0134         eval(paramcommand);
0135         if ~exist('paramEnabled','var'), paramEnabled = ones(1,nparams(params)); end
0136         currparam = plist();
0137         for jj=1:nparams(params)
0138             if paramEnabled(jj)==1
0139                 try %#ok<ALIGN>
0140                 if strcmpi(params.params(jj).key(1:7),'addPar_'), params.params(jj).key(1:7)=[]; end
0141                 catch end
0142 %                 try % for cell array params:
0143 %                     if isa(params.params(jj).val,'char') && strcmp(params.params(jj).val(1),'{'), params.params(jj).val = eval(params.params(jj).val) ; end
0144 %                 catch
0145 %                 end
0146                 currparam = append(currparam,params.params(jj));
0147             end
0148         end
0149     else
0150         currparam = plist();
0151     end
0152 
0153   % Retrieve parameters from Simulink:
0154     paramFromSimulink = 0;
0155     for i=1:nparams(currparam)
0156          paramKey = currparam.params(i).key;
0157          paramVal = currparam.params(i).val;
0158          if (isa(paramVal,'char') && strcmp(paramVal,'-->')) || (isa(paramVal,'cell') && numel(paramVal)==1 && isa(paramVal{1},'char') && strcmp(paramVal{1},'-->'))
0159              paramFromSimulink = paramFromSimulink + 1;
0160              mux = find_system(currparent,'SearchDepth',1,'LookUnderMasks','all','BlockType','Mux');
0161              muxWidths = get_param(mux{1},'CompiledPortWidths');
0162              muxWidths = muxWidths.Inport;
0163              inputBlock = find_system(currparent,'SearchDepth',1,'LookUnderMasks','all','Name',lower(paramKey));
0164              if numel(inputBlock)>1, inputBlock(1)=[]; end % this can happen only when the currparent has the same name: then, ignore the 1st, ie. the currparent itself
0165              inputNumb  = str2double(get_param(inputBlock{1},'Tag'));
0166              x = 0;
0167              for j=1:inputNumb-1
0168                  x=x+muxWidths(j);
0169              end
0170              paramVal = [LTPDAinvar{block.InputPort(1).Data(x+1)}];
0171              if muxWidths(inputNumb)>1
0172                  for j=x+2:x+muxWidths(inputNumb)
0173                      paramVal = [paramVal,LTPDAinvar{block.InputPort(1).Data(j)}];
0174                  end
0175              end
0176              currparam  = pset(currparam,paramKey,paramVal);
0177          end
0178     end
0179     
0180 %%
0181 % ========================================================================
0182 % ======================== CALCULATE THE RESULTS =========================
0183 % ========================================================================
0184 
0185    y = length(block.InputPort(1).Data) - paramFromSimulink;
0186 
0187  % Check to verify the type of function:
0188    specFunc = {'display'};
0189    [func,classes] = strtok(get(get_param(currparent,'Handle'),'Tag'));
0190    if strcmp(func,'method')
0191        category = eval(sprintf([blocktag,'(%s,''Category'')'],strtrim(classes)));
0192    end
0193    
0194    if ismember(blocktag,specFunc)
0195      % Input, but no parameters and no output
0196        type = 4;
0197      % ======================================
0198    elseif (exist('category','var') && strcmp(category,'Output'))
0199      % Input and parameters, but no output
0200        type = 3;
0201      % ===================================
0202    elseif ~isempty(find_in_models(currparent,'SearchDepth',1,'LookUnderMasks','all','BlockType','Constant'))
0203      % No input, but parameters and output
0204        type = 2;
0205      % ===================================
0206    else
0207      % Input, parameters and output
0208        type = 1;
0209      % ============================
0210    end
0211 
0212 
0213    switch type
0214      % ====================================================================
0215        case 4 % Input, but no parameters and no output
0216            inputlist = 'LTPDAinvar{block.InputPort(1).Data(1)}';
0217            for i=2:y
0218                inputlist = [inputlist,',LTPDAinvar{block.InputPort(1).Data(',num2str(i),')}'];
0219            end
0220            command = ['feval(blocktag,',inputlist,')'];
0221            block.OutputPort(1).Data = block.InputPort(1).Data;
0222            try
0223                eval(command)
0224            catch
0225                disp('4')
0226                disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag))
0227                disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name')))
0228                disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1)))
0229                rethrow(lasterror)
0230            end
0231 %          block.OutputPort(1).Data = block.InputPort(1).Data;
0232            block.OutputPort(1).Data = 1;
0233            return;
0234 
0235      % ====================================================================
0236        case 3 % Input and parameters, but no output
0237            try
0238                inputlist = 'LTPDAinvar{block.InputPort(1).Data(1)}';
0239                for i=2:y
0240                    inputlist = [inputlist,',LTPDAinvar{block.InputPort(1).Data(',num2str(i),')}'];
0241                end
0242                command = ['feval(blocktag,',inputlist,',currparam);'];
0243                eval(command);
0244            catch
0245                disp('3')
0246                disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag))
0247                disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name')))
0248                disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1)))
0249                disp('The plist passed was:')
0250                currparam
0251                rethrow(lasterror)
0252            end
0253 %          block.OutputPort(1).Data = block.InputPort(1).Data;
0254            block.OutputPort(1).Data = 1;
0255            return;
0256 
0257      % ====================================================================
0258        case 2 % No input, but parameters and output
0259            try
0260                outdata = feval(blocktag,currparam);
0261            catch
0262                disp('2')
0263                disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag))
0264                disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name')))
0265                disp('The plist passed was:')
0266                currparam
0267                rethrow(lasterror)
0268            end
0269 
0270      % ====================================================================
0271        case 1 % Input, parameters and output
0272            try
0273                inputlist = 'LTPDAinvar{block.InputPort(1).Data(1)}';
0274                for i=2:y
0275                    inputlist = [inputlist,',LTPDAinvar{block.InputPort(1).Data(',num2str(i),')}'];
0276                end
0277                command = ['outdata = feval(blocktag,',inputlist,',currparam);'];
0278                eval(command);
0279            catch
0280                disp('1')
0281                disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag))
0282                disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name')))
0283                disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1)))
0284                disp('The plist passed was:')
0285                currparam
0286                rethrow(lasterror)
0287            end
0288 
0289    end
0290 
0291 %%
0292 
0293 % ========================================================================
0294 % =============================== OUTPUTS ================================
0295 % ========================================================================
0296 
0297 signalName = get_param(currparent,'Name');
0298 setName = get_param(currparent,'UserData');
0299 if ~isempty(setName) && isa(setName,'double') && setName==1
0300     if numel(outdata)==1
0301         outdata = set(outdata,'name',signalName);
0302     else
0303         for i=1:size(outdata,1)
0304             for j=1:size(outdata,2)
0305                 outdata(i,j) = set(outdata(i,j),'name',[signalName,'_',num2str(i),'-',num2str(j)]);
0306             end
0307         end
0308     end
0309 end
0310         
0311     try
0312         
0313 % % %       % To put multiple elements into multiple lines of LTPDAinvar:
0314 % % %         oldx = size(LTPDAinvar,1);
0315 % % %         for i = 1:numel(outdata)
0316 % % %             LTPDAinvar = [LTPDAinvar;{outdata(i),0}];
0317 % % %         end
0318 % % %         x = size(LTPDAinvar,1);
0319 % % %         results = oldx+1:x;
0320 % % %         block.OutputPort(1).Data = results;
0321 
0322       % To put multiple elements into a single line of LTPDAinvar:
0323         x = size(LTPDAinvar,1);
0324         LTPDAinvar = [LTPDAinvar;{outdata,0}];
0325         block.OutputPort(1).Data = x+1;
0326         
0327       % To prevent the result calculated here from being canceled at the
0328       % end of the calculation:
0329         probe = get_param(currparent,'MaskHelp');
0330         if ~isempty(probe) && isa(probe,'char') && strcmp(probe,'probe')
0331             LTPDAinvar{size(LTPDAinvar,1),2} = 2;
0332         end
0333 
0334     catch
0335         disp('------------------============================================------------------')
0336         disp(sprintf('Something''s wrong in appending to the global variable LTPDAinvar the results of the %s function.',blocktag))
0337         disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name')))
0338         disp('The data to be saved, calculated into this block, are:')
0339         outdata
0340         size(outdata)
0341         disp('------------------============================================------------------')
0342     end
0343 
0344     % the output to Simulink is just the ordinal number (ONE AND ONLY ONE
0345     % NUMBER NOW!) of the AOs appended to the global array LTPDAinvar.
0346 
0347 % endfunction

Generated on Mon 31-Mar-2008 21:41:00 by m2html © 2003