How do I create a switch statement using 1 variable rather than multiple separate ones in Stateflow?

53 views (last 30 days)
I'm tyring to setup a stateflow chart in simulink right now, and a problem I am running into is the way the cases are defined. The goal is to recreate a system we already have in place using Stateflow, and that requires the state machine's cases to have the ability to be changed outside the state machine itself.
As an example, (EDITED)
int ExampleCase = 0; % global defined at the start of the program
main(){
while(1)
% Main while loop
ExampleFunction();
Reset();
end
}
ExampleFunction(void){
switch(ExampleCase)
{
case 0:
% Case 0 Functions
if (%Some condition is met)
ExampleCase = 1;
end
break;
case 1:
% Case 1 Functions
if (//Some condition is met)
ExampleCase = 2;
else if (//some other condition is met)
ExampleCase = 0;
end
break;
case 2:
% Case 2 fucntions
if (//some condition is met)
ExampleCase = 1;
end
break;
}
}
Reset(void)
{
if (%FailureFlag or something similar is tripped)
ExampleCase = 0; % RESET THE MACHINE
end
}
In our current project, we would call on this switch statement each iteration of our main while loop and it would go through up to case 2, but there are times where the machine needs to be sent to a different case outside of this statement.
Somewhere else in the code ExampleCase would be set to something other than what the current active case is (i.e. if the switch statement was currently at case 2, which would be a normal operating state, an interrupt outside of this statement could set ExampleCase to 0). This can be done easily in code, but to simulate it in Stateflow has been a bit difficult.
How can we force the input variable of the statement, ExampleCase, to be a specific value? Rather than whatever it was set to during the previous run of the stateflow chart. Could this be done with the default transitions?
EDIT:
So I reworked the code snippet for a better idea of what I am trying to do, as in heinsight it had little info. I may be confusing the terminology for switch-cases and state machines, as I had thought they were similar. But the general idea is that I have a main program loop with a global variable that represents the current state of that machine. While in Stateflow I can go through the steps inside the chart itself, we have other functions in the program that could influence the global state variable, i.e. a reset function. I attatched below a stateflow chart with how I was attempting to setup the machine. The question I have, is whether it is possible to recreate what I have in that code snippet example into something in stateflow? Or, would it be more benificial to create it in a different method? Unfortunatley, the actual code I am attempting to recreate in this model cannot be changed, so I need to work in that format. Hopefully this info helps, thank you for taking the time
  2 Comments
Jonas
Jonas on 13 Oct 2021
You mention you are recreating some other code in Stateflow, and you quote a switch-case. Is this because it is a switch-case in that external code representing a statemachine? If that's the case, you would want to ditch the switch-case and create proper states and transitions in Stateflow. In code generation for example, the states of a Stateflow end up as a switch case.
Just a comment on my side because I have seen people trying to recreate switch-cases from other code, which actually represent state machines, and then it is much better to implement it using States and Transitions instead of a switch-case in Stateflow.
Besides this, it is a bit difficult to visualise what you want to do without a first try of your Stateflow chart.
Thomas MacGregor
Thomas MacGregor on 13 Oct 2021
Thanks for the input, I did some edits to hopefully clear up some things, I realized a bit too late that the info there wasn't too clear.

Sign in to comment.

Accepted Answer

Jonas
Jonas on 14 Oct 2021
Edited: Jonas on 14 Oct 2021
Thank you for the clarification of your example code.
The code example you show is a statemachine implemented in code. The statemachine is implemented using a switch-case, with a switch variable (ExampleCase in your example). To be able to control transitions from one 'case' to another, you use if-statements to check a condition, and if it is true, you assign a new value to the switch variable. The value of your switch variable represents in which 'state' we currently are, and writing another value to it will make sure we transition to another case when we execute the switch-case code next time.
In Stateflow, the implementation is more visual. However, when you generate code from a Stateflow with states and transitions, it will also generate a switch-case and will use if-statements within the cases to control the value of the switch variable to change state.
So you will need to get a grasp of what the switch-case implementation is doing, and translate that to Stateflow concepts. If you have enough experience with Stateflow - or know the features available in Stateflow - you will quickly relate the code you have with the Stateflow concepts.
One implementation you could do is this:
As you can see, we don't need to manually maintain a switch-variable such as ExampleCase. The code generator will do this for you. You just directly put the transitions in between states with a condition. You don't need to write to ExampleCase. In fact, you don't need to care about the switch variable.
However, if you want to monitor or use the switch variable, which represents the active state with a unique value, you can enable an output for monitoring:
It can be found in the Chart settings using the Model Explorer. This is basically your ExampleCase variable.
For resetting the state machine based on an error input, you can use transitions, as I have done in my example above, where we transition from all states back to the default transition based on an error input. Alternatively, you can remove those error transitions, and put your whole Stateflow chart inside an Enabled Subsystem. Based on the error signal, you quickly disable and enable the subsystem. As long as the setting 'Status when enabling' of the Enabled Subsystem is set to 'reset', the Stateflow will reset back to its original values and states as if it was run for the very first time. This option is less invasive to your chart.
All in all difficult to give a complete answer to your question, but in summary it is definitely possible to represent your example code with switch-case using Stateflow and code generation, since a code generated Stateflow is the same as a switch-case. You just need to know the Stateflow concepts to be able to implement it in Stateflow.
If there is anything specific, let me know.
Edit:
I just took a few minutes to generate code from the example in my screenshot above. This is what comes out of Embedded Coder:
switch (untitled_Y.ChartMode) {
case ChartModeType_Case0:
if (untitled_U.In1 == 1.0) {
untitled_Y.ChartMode = ChartModeType_Case1;
}
break;
case ChartModeType_Case1:
if (untitled_U.error_input != 0.0) {
untitled_Y.ChartMode = ChartModeType_Case0;
} else if (untitled_U.In1 == 2.0) {
untitled_Y.ChartMode = ChartModeType_Case2;
} else {
if (untitled_U.In1 == 0.0) {
untitled_Y.ChartMode = ChartModeType_Case0;
}
}
break;
default:
/* State Case2 */
if (untitled_U.error_input != 0.0) {
untitled_Y.ChartMode = ChartModeType_Case0;
} else {
if (untitled_U.In1 == 1.0) {
untitled_Y.ChartMode = ChartModeType_Case1;
}
}
break;
}
As you can see, a switch-case!
  2 Comments
Thomas MacGregor
Thomas MacGregor on 19 Oct 2021
Thank you for the detailed and helpful response! I was able to get my project up and running how I wanted to now. ido have one quick question on the example you gave though: Why does Case2 get set to default? And is there any way to change that/remove the default case altogether? I saw in other posts about a setting in Code Generation, but the Code Style tab doesn't show up for me and I can't find anywhere else for the default case settings. Is there any way to keep Case2 as Case2 instead of default?
Jonas
Jonas on 20 Oct 2021
Edited: Jonas on 20 Oct 2021
Please see this answer.
A default case is always generated, as the last state in alphabetical order.
This results in the switch-case completely representing the Stateflow chart. The Stateflow has 3 states, at any given time, one of these 3 will be active. When generating a switch-case with 2 cases and a default, always any of these three situations is valid.
If you have a switch-case with 3 cases and no default, then it could be that none of the three cases is valid and then you have bad code. Or at least, code that may not cover all cases.

Sign in to comment.

More Answers (0)

Categories

Find more on MAB Modeling Guidelines in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!