How to programmatically know if a block is a sink block?

5 visualizaciones (últimos 30 días)
Sohil Shrestha
Sohil Shrestha el 7 de Mzo. de 2021
Comentada: Paul el 28 de Dic. de 2021
I have Simulink model. I want to know if each of the block inside my model is a sink block or not (or it belongs to a Sink Simulink library block or not )?
Currently I first get block type using get_param("blkname", 'BlockType') api. Then I try to map the blocktype to simulink library block .
For example, "Scope" maps to "simulink/sinks/Scope". This approach works for Simulink Block whose type is not Subsystem.
For example , for XYGraph which is a Sink block. get_param returns its blocktype as Subsystem.
Is there any alternative way to verify if a block is a source or a sink block ?

Respuesta aceptada

Paul
Paul el 8 de Mzo. de 2021
Editada: Paul el 8 de Mzo. de 2021
I'm actually suprised that there's not an easier way to to do this.
The BlockType is a read-only so checking:
ismember(get_param(blk,'BlockType'),blktypes)
with
blktypes =
1×7 cell array
{'Display'} {'Outport'} {'Scope'} {'Stop'} {'Terminator'} {'ToFile'} {'ToWorkspace'}
will work for every block ecept the XY Graph block (at least in 2019a). But the XY Graph has another parameter:
>> get_param(gcb,'ReferenceBlock')
ans =
'simulink/Sinks/XY Graph'
that could be used also:
ismember(get_param(blk,'BlockType')) || isequal(get_param(blk,'ReferenceBlock'), 'simulink/Sinks/XY Graph')
might be a good place to start.
However, the ReferenceBlock parameter is NOT read-only (oversight by TMW?), so it's possible that it could be changed (which would be crazy,but if so it wouldn't then really be part of the Sinks library, so maybe not a big deal). Also, I'm not sure if that ReferenceBlock parameter varies depending on the system (e.g, Windows v. Linux.) but I suspect that one could come up with a check that would be robust across different system types.
  2 comentarios
Sohil Shrestha
Sohil Shrestha el 9 de Mzo. de 2021
Editada: Sohil Shrestha el 9 de Mzo. de 2021
Thank you for the input. Looking at the ReferenceBlock parameter of the blocks in combination to the approach I have listed should suffice to distinguish if the block is Source or Sink (at least for the Simulink library blocks). For blocks whose type is not S-funtion or Subsystem, you still have to check the map.
Based on the Simulink documentation , I think ReferenceBlock is meant to have read-write access. Reference Block seems to have precedence over actual block type(based on my testing) which transforms the block to whatever ReferenceBlock parameter we set it to.
This may cause some unexpected behavior though, which might be an oversight from MW or an intentional feature.
Paul
Paul el 28 de Dic. de 2021
In 2021b, the XYGraph has BlockType == 'Record' and its ReferenceBlock is empty.

Iniciar sesión para comentar.

Más respuestas (2)

Sohil Shrestha
Sohil Shrestha el 7 de Mzo. de 2021
Editada: Sohil Shrestha el 8 de Mzo. de 2021
%Upon digging into some api , this is the solution I came up with.
% I have not tested with all possible cases.
% If there are any pitfalls with this approach, I will appreciate any corrections.
src = get_param(blk,'Name');
ports_info = get_param(blk,'PortConnectivity');
block_type = get_param(blk, 'BlockType');
if sum(size(ports_info)) <= 2 && ~(strcmp(block_type,'From') || strcmp(block_type,'Goto'))
if(strcmp(block_type,'Scope') || any(size(ports_info.SrcBlock))) % for Floating Scope
sinks{end+1} = src;
elseif (any(size(ports_info.DstBlock)))
sources{end+1} = src;
end
end
  3 comentarios
Sohil Shrestha
Sohil Shrestha el 9 de Mzo. de 2021
The idea with this approach is Source and Sink blocks have typically one input (or output port) giving the size of the array to (1,1)
size(get_param( get_param(blk,'PortConnectivity')) ) =[1,1]
It seems there are pitfalls with this approach in case of Scope with more than one port where size would be
[more than 1 , 2 ] where it will fail.
Apart from Scope, I could not find another instance(at least from Source and Sink library blocks) where this might fail but I could be wrong.
Regarding
if size(ports_info{1,1},1) == 1
I think @Pat Gipper adapted my approach and wrote a more complete code. It seems there are syntax error with brace indexing.
Paul
Paul el 9 de Mzo. de 2021
Editada: Paul el 9 de Mzo. de 2021
Pat Gipper's code uses the brace indexing as well, but I see an error:
>> ports_info=get_param(gcb,'PortConnectivity');
>> size(ports_info{1,1},1)
Brace indexing is not supported for variables of this type.
>> ports_info
ports_info =
struct with fields:
Type: '1'
Position: [100 95]
SrcBlock: 4.0520e+03
SrcPort: 0
DstBlock: []
DstPort: []
So I'm still confused about this.
More importantly, I don't see why checking for a single input or output is sufficent to check if a block is in the Sinks or Sources library. As you've already found, there are exceptions to this rule with From and Goto, and there are others, such as in the Model Verification library, not to mention blocks that can be defined as user defined library links that can have only one input or one output.

Iniciar sesión para comentar.


Pat Gipper
Pat Gipper el 8 de Mzo. de 2021
I had to add some complexity to your code to make it work on my sample file.
modelfile = 'SinkXY';% Or whatever your model filename is?
load_system(modelfile);
blk0 = find_system(bdroot,'LookUnderMasks','on','FollowLinks','on');
%Upon digging into some api , this is the solution I came up with.
% I have no tested with all possible cases.
% If there are any pitfalls with this approach, I will appreciate any corrections.
[i,~] = size(blk0);
ptr_sinks=0;ptr_sources=0;
for ii=2:i
blk = blk0(ii);
src = get_param(blk,'Name');
ports_info = get_param(blk,'PortConnectivity');
block_type = get_param(blk, 'BlockType');
if sum(size(ports_info)) <= 2 && ~(strcmp(block_type,'From') || strcmp(block_type,'Goto'))
if size(ports_info{1,1},1) == 1
if(strcmp(block_type,'Scope') || any(size(ports_info{1,1}.SrcBlock))) % for Floating Scope
sinks{ptr_sinks+1} = src; %#ok<SAGROW>
ptr_sinks=ptr_sinks+1;
elseif (any(size(ports_info{1,1}.DstBlock)))
sources{ptr_sources+1} = src; %#ok<SAGROW>
ptr_sources=ptr_sources+1;
end
end
end
end

Categorías

Más información sobre Programmatic Model Editing en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by