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

27 views (last 30 days)
Thomas MacGregor
Thomas MacGregor on 12 Oct 2021
Edited: Jonas on 20 Oct 2021
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
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
Jonas
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)

Community Treasure Hunt

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

Start Hunting!