Recursion on charts and subcharts in a Stateflow diagram

11 views (last 30 days)
Hi Matlab Community,
This is my first matlab program in years, so apologies if it sucks. I am struggling with recursion (see code snippet). The objective here is to output a list of Charts, subcharts, states and transitions in a hierarchical fashion, such that the state charts, sub charts, states and transitions can be read into DOORS via a csv with the hierarchy maintained, we then have a nice way to connect to a representation of the modell.I am under the impression that recursion in Matlab is not normal? I wish to grab all Charts, then look for all child states and charts on the states then look at those charts in turn until there are no more charts and states to find. Recursion sounds like the way to go here. I have created a class with all the properties and fill it every tim e I come across a chart, state or transition, this appears to work when recursion is not used and I don't bother with subcharts, but I want more. I think the global variables are working OK, but I keep cycling around the top charts and can't seem to find the right way of grabbing the subChart on a state. Any idea what I am doing wrong?
Thanks for any help, as this is my first attempt, I've likely misunderstood how matlab works in some way! The processSubChart function does not recurse to the subchart on the States, I may simply be failing on getting a subchart from a State.
Cheers
Richard
clear objectCount;
global objectCount;
objectCount=1;
clear allDOORSObjects;
global allDOORSObjects;
allDOORSObjects = repmat(doorsObject(),1, 1000);
%open the simulink model
open_system('sf_aircraft');
%All subcharts are considered States with charts not subcharts, hence the
%Stateflow-Charts only ever captures top level ones
%remember to check for empty array, won't happen here
rt=sfroot;
allTopCharts= rt.find('-isa','Stateflow.Chart' );
for chartIndex=1 : length(allTopCharts)
%send each chart to a function for processing
thisChart = allTopCharts(chartIndex,1);
processSubChart(thisChart,1)
end
for n=1 : objectCount-1
writeCsvLine(fid,allDOORSObjects(1,n));
end
fclose(fid);
function processSubChart(myChart, thisDepth)
global allDOORSObjects;
global objectCount;
global fid;
%Add each top level Chart as Level 1 DoorsObjects
allDOORSObjects(objectCount)= doorsObject(myChart.id, "Chart",myChart.Name,myChart.Description, myChart.Description);
writeCsvLine(fid,allDOORSObjects(1,objectCount));
objectCount= objectCount+1;
% if isempty(allTopCharts)
% break;
% end
%https://uk.mathworks.com/help/stateflow/api/overview-of-the-stateflow-api.html
%https://uk.mathworks.com/help/stateflow/api/accessing-existing-stateflow-objects.html
%Might want to use this too ch.find('-property','HasOutputData')
allStates = myChart.find('-isa','Stateflow.State','-and', '-depth', 2);
%allFunctions = myChart.find('-isa','Stateflow.Function','-and', '-depth', 2);
%allTruthTables= myChart.find('-isa','Stateflow.TruthTable','-and', '-depth', 2);
disp(myChart.Name);
fig = get_param(string(myChart.Path) +'/','Handle');
myFileName= 'C:\Temp\' + string(myChart.Name) + '.pdf';
saveas(fig,myFileName);
%Iterate through returned states, returning their names
%I think that just the top level states are returned which is good, need to
%keep iterating down
for i=2 : length(allStates)
thisState= allStates(i,1);
disp(allStates(i,1).Name);
disp(allStates(i,1).LabelString);
allDOORSObjects(objectCount)= doorsObject(thisState.id, "State",thisState.Name,thisState.LabelString, thisState.Chart.id);
writeCsvLine(fid,allDOORSObjects(1,objectCount));
objectCount= objectCount+1;
end
%Can scroll through all transitions but some are special in that they have
%no source or destination, so need to check properties before outputting
%details
%chartobjects methods
%getChildren, findDeep, findShallow
%isSubChart, getParent, getPossibleProperties
%Need all functions too I think
%can combine property searches with listing Transitions if its easier
%probablly best to check for properties in the group of all Transitions
allTransitions = myChart.find('-isa','Stateflow.Transition','-and', '-depth', 2);
for i=1 : length(allTransitions)
thisTransition= allTransitions(i,1);
%disp( thisTransition.LabelString);
if isprop(thisTransition, 'LabelString')
transLabel= thisTransition.LabelString;
else
transLabel="";
end
dest= thisTransition.Destination;
src = thisTransition.Source;
srcName= "";
destName="";
myId=0;
if ~isempty(src)
disp(src.Type);
if isprop(src,'Name')
srcName= src.Name;
myId=src.id;
end
end
if ~isempty(dest)
if ~isprop(src,'Name')
myId=dest.id;
end
if isprop(dest,'Name')
destName=dest.Name;
end
end
disp(" ");
disp(" ");
%add source and destination and parent etc for transitions
allDOORSObjects(objectCount)= doorsObject(thisTransition.id, "Transition",srcName + "->" + destName,transLabel,srcName,destName,myId);
writeCsvLine(fid,allDOORSObjects(1,objectCount));
objectCount= objectCount+1;
end
%each subchart is contained in a state, filter on states containing sub
%charts then scroll through them by using
%subCharts(index,1).Chart
%You always need to ignore the first object as it returns the
%chart/state you are on so start indexing at 2 not 1
subCharts = myChart.find('-isa', 'Stateflow.State', '-and', 'IsSubchart', 1, '-and', '-depth', 2);
if length(subCharts) >1
for i=2 : length(subCharts)
%I think this gets the parent chart or the chart I'm on
%I want to get the child chart of the state not the parent
%keep cycling around the same charts forever
%kludge=subCharts(i,1).getChildren;
processSubChart(subCharts(i,1).Chart,thisDepth+1)
end
end
end

Accepted Answer

Richard Good
Richard Good on 7 Oct 2020
Oh Dear, think I just needed to replace subCharts(i,1).Chart with subCharts(i,1), couldn't compute that for some reason!

More Answers (0)

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!