0
votes

I am using MATLAB 2013b, and I am attempting to write a script that will automatically wire up ToWorkspace blocks to a selected set of signals.

I can handle finding/getting handles to the signals, adding the blocks, setting the variable names, and so forth. What I want to do, however, is programmatically discover if a selected signal is a scalar, array, or bus signal. This way, I can reshape arrays to be 1D (so that they concatenate the way I want) and break down bus signals into their individual elements.

I attempted the fix posted at See if a signal originates from a bus in Simulink but with no luck. I'm betting that the post is old enough that the proposed fix didn't work in the version of MATLAB I'm attempting to use.

I know the answer involves compiling the model or updating the model with a certain command, but I am stuck. Help please!

Here's what I tried to do, based on the link above:

function usedNames = addToWorkspaceBlock( signal, usedNames )
   % Recursively add whatever blocks are necessary to break down the signal
   % into raw bus elements or reshaped arrays and output them that way

   switch upper( get(signal,'CompiledBusType') )
      case 'NOT_BUS'
         % Will add the reshape block and ToWorkspace block here, saving
         % the name of the ToWorkspace VariableName to usedNames
         keyboard % for debugging
      case {'VIRTUAL_BUS','NON_VIRTUAL_BUS'}
         % Will add the reshape block and ToWorkspace block here, saving
         % the name of the ToWorkspace VariableName to usedNames
         keyboard % for debugging
      otherwise
         error('Unrecognized CompiledBusType %s', get(signal,'CompiledBusType'));
   end
end

The error I get is this: (ignore the line numbers; my addToWorkspaceBlock() function is a subfunction of my main function which handles getting the signals and looping through them)

Error using createToWorkspaceBlocks>addToWorkspaceBlock (line 48)
    line does not have a parameter named 'CompiledBusType'

Error in createToWorkspaceBlocks (line 36)
    usedNames = addToWorkspaceBlock( signals(i), usedNames );
1
To help others answer your question, post your formatted code in the question.Joey Harwood

1 Answers

0
votes

I think I have found a solution.

After the model has been compiled with modelName([],[],[],'compile') and the sizes phase has been executed with modelName([],[],[],'sizes'), the CompiledPortDimensions will now be a property of the source port of the signal. If the signal is a bus, the first CompiledPortDimensions will be negative. If it's numeric (scalar or array), CompiledPortDimensions will show the size() of the signal.

I have updated my code below. Note that I don't show my actual finding of signals or how I'm going to add the blocks, but this is how I ended up doing it:

function createToWorkspaceBlocks(signals)

   % Create a ToWorkspace output for each of the given signals


   % Get the root model containing these signals (assume all given signals
   % are in the same root diagram)
   rootSystem = bdroot( get(signals(1),'Parent') );


   % Update the model to establish the CompiledPortDimensions property and rethrow
   % any errors that occur during (i.e., stop this function)
   try
      cmd = [ rootSystem '([],[],[],''compile'')' ];
      evalin('base',cmd);
      %       set_param( rootSystem, 'SimulationCommand', 'update' );
   catch me
      warndlg('The model could not be compiled!');
      rethrow(me);
   end

   cmd = [ rootSystem '([],[],[],''sizes'')' ];
   evalin('base',cmd);


   % Loop through the signals and determine what signal type it is. Make
   % ToWorkspace blocks based on the signal type:
   %  - scalars: signal --> ToWorkspace block
   %  - arrays:  signal --> Reshape(1D) --> ToWorkspace block
   %  - bus:     signal --> BusSelector --> (Reshape(1D) if needed) --> ToWorkspaceBlock
   % Recursively
   usedNames = cell( numel(signals), 1 );

   for i = 1 : numel(signals)
      usedNames = addToWorkspaceBlock( signals(i), usedNames );
   end

   cmd = [ rootSystem '([],[],[],''term'')' ];
   evalin('base',cmd);

end

function usedNames = addToWorkspaceBlock( signal, usedNames )
   % Recursively add whatever blocks is necessary to break down the signal
   % into raw bus elements or reshaped arrays and output them that way

   srcPort     = get( signal, 'SrcPortHandle' );
   srcPortDims = get( srcPort, 'CompiledPortDimensions' );

   if srcPortDims(1) < 0
      % Signal is a BUS

   elseif all(srcPortDims > 0)
      % Signal is NUMERIC
      % % Add reshape block
      % % Add ToWorkspace block
   end
end