MATLAB Answers

How to programmatically rename Stateflow states that are grouped?

6 views (last 30 days)
From the command window I would like to rename all states that are in a Stateflow chart. I'll use the following built-in model as an example. In the chart there are two states, Off and On, that are grouped by the Heater box.
openExample('simulink_general/sldemo_boilerExample')
Screen Shot 2019-11-03 at 2.06.11 PM.png
I am receiving the error "Cannot change states inside a grouped state." when renaming the Off and On states because they are grouped by a box. If I simply double-click on the state name, I can easily rename via the usual Stateflow GUI, but I need to be able to do this in a script.
sys = 'sldemo_boiler';
rt = sfroot; % Get global Stateflow object
model = rt.find('-isa', 'Simulink.BlockDiagram', '-and', 'Name', sys); % Get the model
charts = model.find('-isa', 'Stateflow.Chart'); % Get the model's charts
c = charts(1); % The chart we are interested in
states = c.find('-isa', 'Stateflow.State'); % All states in the chart
state_off = states(1);
state_off.Name = 'NewName'; %% ERROR: Cannot change states inside a grouped state.
How can I rename these states? I considered just ungrouping the box by unsetting its IsGrouped parameter, but state objects don't have a parameter that tells me what object they are grouped by, so I can't trace up the hierarchy.

  0 Comments

Sign in to comment.

Accepted Answer

Fangjun Jiang
Fangjun Jiang on 4 Nov 2019
Edited: Fangjun Jiang on 4 Nov 2019
To handle this,
Box=c.find('Name', 'Heater');
Box.IsGrouped=false;
states(1).Name='NewName';
To handle it more generically (without nested boxes)
Box=c.find('-isa','Stateflow.Box');
Index=cell2mat(get(Box,'IsGrouped'));
Box=Box(Index);
set(Box,'IsGrouped',false);
%% Make needed changes
% recover the original flags
set(Box,'IsGrouped',true);

  3 Comments

Monika Jaskolka
Monika Jaskolka on 4 Nov 2019
Please read the entire question. This approach does not work for grouped states.
EDIT:
Again, please read the whole question. It does not seem possible to determine programmatically what the state is being grouped by, because there is no parameter that stores which box/state/etc. it is grouped in (see image below). The same is true in the other direction: boxes don't have a parameter that stores what elements it is grouping. This is problematic if there are multiple boxes in the chart (although the example only has one).
Screen Shot 2019-11-04 at 9.42.28 AM.png
Screen Shot 2019-11-04 at 9.47.04 AM.png
Fangjun Jiang
Fangjun Jiang on 4 Nov 2019
You might have to blindly re-set all the boxes that are "IsGrouped" and later set it again. See updated answer.
This might not work if you have nested boxes, which I didn't try. But I've done similar programing on nested library links. If you do have nested boxes, then I would assume you would need to find all the boxes, save all the "IsGrouped" flags, re-set from root-level to deep-level, make you changes, then recover all the "IsGrouped" flags from deep-level to root-level.
Monika Jaskolka
Monika Jaskolka on 5 Nov 2019
Thanks. My solution for now is:
% Save and turn off box grouping
boxes = c.find('-isa', 'Stateflow.Box');
isgrouped = cell2mat(get(boxes, 'IsGrouped'));
set(boxes, 'IsGrouped', 0);
states = c.find('-isa', 'Stateflow.State');
for m = 1:length(states)
% Make changes...
end
% Turn back on
for n = 1:length(boxes)
boxes(n).IsGrouped = isgrouped(n);
end

Sign in to comment.

More Answers (0)

Products


Release

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by