2

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. Commented Jan 14, 2018 at 4:18

2 Answers 2

1

A less elegant but more practical way, which doesn't require compilation, is to pass the value into the string() function, then catch the error that's thrown if it's a bus. This worked in Matlab 2019:

try
 string(value)
catch bus2stringFail
 if strcmp(bus2stringFail.identifier, 'MATLAB:invalidConversion')
 disp ('it was a bus after all')
 end
end

Scalars, arrays, and matrices can all be passed to the string() function, so can be distinguished from a bus. If you have some other exotic value that cannot be turned into a string, this method won't distinguish it from a bus.

answered Oct 6, 2022 at 16:47
Sign up to request clarification or add additional context in comments.

Comments

0

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
answered Jan 14, 2018 at 18:49

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.