Time to convert from find_system to Simulink.findBlocks
If you are creating, editing or analyzing Simulink models programmatically, you are probably familiar with find_system.
While there is nothing fundamentally wrong with find_system, in this post I want to highlight a set of functions that provide similar capabilities with improved usability.
In MATLAB R2018a, we introduced:
- Simulink.findBlocks: Find blocks in Simulink models
- Simulink.findBlocksOfType: Find specified type of block in Simulink models
- Simulink.allBlockDiagrams: Find loaded Simulink models and libraries
- Simulink.FindOptions: Specify options for finding blocks in models and subsystems
Let's examine why I believe these newer APIs offer a an improved usability.
Two Equivalent Queries
Let's first look at a typical example. Using the example sldemo_fuelsys, let's compare the code to find the only Math Function block in this model:
mdl = 'sldemo_fuelsys';
load_system(mdl);
Using find_system:
blksFindSystem = find_system(mdl,'LookUnderMasks','all','FollowLinks','on','BlockType','Math')
Using Simulink.findBlocksOfType:
opts = Simulink.FindOptions;
opts.FollowLinks = true;
blksFindBlocks = Simulink.findBlocksOfType(mdl,'Math',opts);
getfullname(blksFindBlocks)
When looking at this code, you are probably wondering why I consider the second option better in terms of usability. After all, it's 3 lines of code instead of 1.
Let's look into that in more details.
find_system - Step by Step
Let's go through my thought process when I write the line of code with find_system. I will first type the return variable, the equal sign and start typing "find_" until the suggestion mechanism offers find_system:
Once I accept that, I type the model name and see the next suggestions:
With the function-style of find_system, the MATLAB Editor is able to list the different syntaxes, but not the argument values. As first guess, I'll probably go with:
blksFindSystem = find_system(mdl,'BlockType','Math')
Since it returns nothing, I look at the find_system documentation for more details. The first thing I determine is that the block I am looking for is inside a library link, so I add the FollowLinks option.
I copy the option name from the documentation and paste it in my line of code
blksFindSystem = find_system(mdl,'FollowLinks','on','BlockType','Math')
This time, I am successful:
blksFindSystem = find_system(mdl,'FollowLinks','on','LookUnderMasks','all','BlockType','Math')
One thing to admit: even after writing code with find_system for 20 years, even if I know exactly the options I need, I always open the documentation and copy the option names from there. The reason is probably a mix of having made typos too often and a preference to copy and paste versus typing everything.
Simulink.findBlocksOfType - Step by Step
Let's go through the same thought process for Simulink.findBlocksOfType. As in the previous case, I begin typing the first line
I accept the suggestion.
opts = Simulink.FindOptions;
Once this is done, I can hover the mouse over "opts" and immediately see the options:
Quickly scanning them, I can see that LookUnderMasks is already set to "All", but FollowLinks is not enabled, so I start typing:
I accept the suggestion and finish the line:
opts.FollowLinks = true;
I start typing the last line, accompanied by the code suggestions all the way:
blksFindBlocks = Simulink.findBlocksOfType(mdl,'Math',opts)
What I receive is a block handle, which can be passed to other functions like set_param, get_param, hilite_system, etc. If you want to see the block path as find_system returns, use getfullname:
getfullname(blksFindBlocks)
Final Comparison
I hope I illustrated how, thanks to the latest enhancements to tab-completion and code suggestions in the MATLAB Editor, Simulink.FindBlocks and related functions can improve the coding experience. It's 3 lines of code instead of 1, but they are easier to write and as easy to understand at first look.
One more advantage is when I need to call Simulink.findBlocks multiple times. In most cases, I will be able to create the Simulink.FindOptions object only once and reuse it many times in my code, simplifying things even more.
Now it's your turn
It took me longer than it should have to realize how Simulink.findBlocks and related functions improve my workflow compared to find_system. At first, I was sort of turned off by the need to call the additional function Simulink.findOptions. However, after forcing myself to use them a few times, I quickly changed my mind and abandoned find_system.
Give a try to Simulink.finBlocks and related functions and let us know what you think in the comments below.
- Category:
- Commands,
- Simulink Tips,
- What's new?
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.