Guy on Simulink

Simulink & Model-Based Design

Creating a Match Filter for Simulink.findBlocks

Some time ago, I published a post encouraging you to use Simulink.findBlocks instead of find_system. This week, I will take this a little bit further and show how to create a custom match filter to accomplish advanced searches.

Introduction

If you are not familiar with creating match filters for Simulink.findBlock, I recommend first going through these documentation links to get the basic:
In short, a match filter is a function that takes as input block handles and returns a true or false value indicating if the block should be included in the search results or not.

The Problem

I recently got a request for something slightly more complex than the examples in the above link, and I thought it would be interesting to share here. The question I received was more complex than that, but could be approximated to:
How to find all the blocks that are inside active variants and not of type Inport, Outport or Subsystem?
To illustrate this, let's use the model included in the shipping example Implement Variations in Separate Hierarchy Using Variant Subsystems, which you can open in MATLAB by executing:
openExample('simulink/VariantSubsystemsExample')
Here is what the model looks like:

The Solution

The technique I want to highlight here is to combine a built-in filter like Simulink.match.activeVariants with custom logic. More specifically:
  • Use the prune output of the built-in filter Simulink.match.activeVariants to eliminate all the blocks inside inactive variants
  • Filter out blocks of undesired types
This results in this match filter function:
function [match, prune] = myFilter(blk)
%% Step 1:
% Look if the block is inside an active variant and prune if it does
[match, prune] = Simulink.match.activeVariants(blk);
if (prune) || not(match)
% Do not process blocks inside inactive variants. The "prune"
% flag will tell Simulink.findBlocks to skip all blocks inside inactive variant subsystems
return;
end
%% Step 2:
% Return true only if the block type does not match any of the specified non-desired types
match = false;
unwantedBlocktypes = {'Inport','Outport','SubSystem'};
blkType = get_param(blk,'BlockType');
if not(any(strcmp(blkType,unwantedBlocktypes)))
match = true;
end
We can test the match filter function:
opts = Simulink.FindOptions;
opts.MatchFilter = @myFilter;
VSS_MODE = 1;
set_param('sldemo_variant_subsystems','SimulationCommand','Update');
blks = Simulink.findBlocks('sldemo_variant_subsystems/Controller',opts);
getfullname(blks)
ans = 2×1 cell
'sldemo_variant_subsystems/Controller/Linear Controller/Add'
'sldemo_variant_subsystems/Controller/Linear Controller/DiscreteTransfer …
Let's change the active variant and confirm that it returns different blocks:
VSS_MODE = 2;
set_param('sldemo_variant_subsystems','SimulationCommand','Update');
blks = Simulink.findBlocks('sldemo_variant_subsystems/Controller',opts);
getfullname(blks)
ans = 2×1 cell
'sldemo_variant_subsystems/Controller/Nonlinear Controller/1-D Lookup Table'
'sldemo_variant_subsystems/Controller/Nonlinear Controller/Add'

Now it's your turn

Using a similar approach, it should be possible to create any complex logic.
Have you created custom match filters for Simulink.findBlocks? If yes, let us know what kind of search you are doing in the comments below.
|
  • print

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.