Getting Started with Stateflow
Discover the basics of using Stateflow® by walking through an example. You will learn how to model, simulate, and test a supervisory controller that determines whether a building uses energy stored in a battery or energy from the electric grid. You’ll also see how to build a state diagram from scratch, connect states with conditional transitions, add flow chart decision logic, and then run simulations with animation to ensure that the model is working correctly.
After going through the example, you’ll learn how Stateflow is just one part of Model-Based Design for modeling, simulating, testing, and implementing real-world systems.
Published: 22 Dec 2020
Stateflow is a graphical environment that allows you to design and simulate decision logic for supervisor control, task scheduling, and fault management applications. This video will show you the basics of Stateflow and give you an idea of how to use it to model decision logic. At the end, we'll show you where to go next to learn more about Stateflow and start using it today. So let's get started.
MathWorks has roof mounted solar panels at our headquarters in Natick, Massachusetts. These solar panels can help to reduce our electricity costs and dependence on fossil fuels. In fact, they provide about 8% of the MathWorks energy needs.
Pairing the solar panels with a battery lets us collect solar energy and then use it when we want. The energy produced by these solar panels varies throughout each day. This makes it difficult to find the best way to use the energy collected.
Let's assume our building uses 200 kilowatts and the panels will charge a 3 megawatt hour battery. This acts as a buffer to power the building when it's not sunny. Now we need to decide when to use the grid and when to use the battery so we can reduce the electricity bill. We need to represent all these operating modes and make decisions about when to transition between them.
Fortunately, we have Stateflow, which can do all of this and more. Electricity is priced differently throughout the day. The battery will save us the most money if we can use it to avoid the highest prices.
Based on what time it is, we want to be in one of the two operating modes. We can represent this as two separate states using a finite state machine. We'll either be using the grid or the battery if it has enough charge. If the battery gets drained, we'll fall back to using the grid. Only one operating mode will be active at any time.
We're going to model our finite state machine with a state flow chart. The hardware is already modeled in Simulink, so we can just load the model and add to it. The model's input data is the power in watts coming from the solar panels sampled every 15 minutes. We have a year's worth of data. So that's how long our simulation will be.
We'll use this data to determine if it's sunny with our weather detector. We also need to know the time of day. We'll make decisions based on the battery level. So we have a plan model for the battery, and we monitor the stored energy with a scope.
Last, we've set the solver to a fixed step solver to match the sampling rate of our solar data. You can use Stateflow with continuous systems. But for decision logic like this, it will usually be discrete time.
OK, so that covers everything that was already built. But we need to make decisions about when to use the battery and when to use the grid. How can we do that? We can do this by adding a Stateflow chart to represent our decision logic.
We'll start by dragging a chart block from the Stateflow library into our model. Now let's connect our signals to the chart so we can use them inside. Since our signals have names already, we can drag them onto the chart block. And the port names will be set to the signal names.
As we drag the other two signals onto the chart, two more ports will be added. It's starting to get a little crowded, so we'll resize the chart block. Last, we'll rename this chart block to Building Manager. Now we're ready to build our decision logic. And inside we can use all the signals we just connected.
The energy system within our building can switch between using the grid and the battery for power. We'll represent these two operation modes using two states called use grid and use battery. We also need to tell Stateflow which state to enter at the start of our simulation by adding a default transition.
We'll start out by drawing power from the grid. So the default transmission will go into the use grid state. After we've collected some solar energy in the battery, we should then consider switching to the use battery state. So we'll allow transmissions between the use grid and the use battery states by connecting them.
In Stateflow we can use square brackets to specify a condition and curly braces to specify an action. Every 15 minutes, we need to decide whether to use the grid or the battery for the next 15 minutes. To reduce the total energy cost, let's try to use the battery first whenever possible.
To meet the power demand of 200 kilowatts for 15 minutes, the stored energy must be greater than 50 kilowatt hours. So we'll use this condition to guard the transition from the use grid state to the use battery state. If we're using the battery and its stored energy drops below 50 kilowatt hours, we'll use the grid again.
Next, let's specify the state actions. In Stateflow, states can have different action types, including entry, during, and exit actions. Entry actions are performed if something happens on the way into a state. During actions are performed when remaining in a state. And exit actions are performed on the way out of a state.
When entering the use battery state, we will use an entry action to set the battery usage rate to 200 kilowatts. When leaving the use battery state, we'll use an exit action to set the usage rate to 0. Later, we'll make the usage rate an output signal and use its value to adjust the battery level of charge in Simulink.
There's no cost for using the battery since its energy comes from the sun. On the other hand, when using the grid, the energy price is $0.20 per kilowatt hour, meaning the energy cost will go up by $10 every 15 minutes. So we should increment the energy cost when entering or remaining in the use grid state with entry and during actions. Also, let's not forget to specify a 0 initial value for the cost.
All right, that completes our first state transition diagram. We're off to a really good start, but there's something missing. The energy price of $0.20 per kilowatt hour is only valid for off-peak hours. For peak hours, the energy price is $0.30 per kilowatt hour.
So how can we accommodate for the time varying prices? Well, to be able to track the time, all we need is another state transition diagram. And we already know how to build one in Stateflow. With that, we can easily know what the energy price would be based on the time of use.
Now we have two separate tasks, tracking whether it's off-peak time or peak time and managing the energy sources. To organize both, we'll introduce two superstates called time and energy manager. Using state hierarchy helps us to better organize, structure, and manage our decision logic within Stateflow.
By default, only one state can be active at any given level, which means the state flowchart has an exclusive decomposition. That's the reason why Stateflow is warning us that we don't have a default transition. But actually, we don't need one at this level.
We want to track the time and manage the energy sources concurrently. So let's switch the chart decomposition to parallel. We call these parallel states. But in reality, things must happen in a particular order. Stateflow lets us specify the execution order for each parallel state, which helps us to avoid ambiguities in our decision logic.
Next, let's check the execution order for these two parallel states. To be able to calculate the energy cost, we need to know the current time first. So the execution order is already correct.
Now that we're tracking time of use, we can simply follow a flowchart to determine the current energy cost. Is it currently during peak hours? If yes, then the energy cost would be $15. If no, then the energy cost would be $10.
OK, back to our state flowchart. Let's redo the energy cost calculation based on the time of day by adding a flowchart. This time the default transition takes us to a junction, and we'll branch out from there. We can use the in operator to detect the time of use.
If it's during peak hours, we'll take the first branch, and the action is to increment the cost by 15. Otherwise, we'll take the second branch and increment the cost by 10. Just like for parallel states, it's important to have the correct execution order for each transition. For example, if the execution order is backward here, the right branch would never be checked.
Next, we can use the Symbols pane to define our symbols being used in our chart. Notice that we already have three input symbols, which correspond to the three input ports that we created from the top level model. Let's click on Resolve Undefined Symbols. This will automatically confirm the symbols we've used and define their data scope based on how they're being used. In particular, each of the input and output data symbols will become a port of the chart block.
Since the energy cost is important to us, let's make it an output signal by changing its data scope to output data. Going back to the top level model, now our state flowchart has output ports for the output data. Now let's add a display block to capture the total energy cost and make all the connections. Within Stateflow, we can easily monitor the active state data for post-simulation analysis.
Since we're interested in monitoring the energy usage at different times of the day, let's log the child activities for both superstates. We're ready to run the simulation by clicking the Run button. The chart is fully animated during simulation, so we can see our states and transitions at runtime.
But how do we make sure our decision logic is working properly? Let's pause the simulation and slow down the animation speed. We're using the grid at this time step. And we can see that we're in the off-peak state. Our cost is $4,855 so far.
Now we'll step forward one step and see that we were billed the off-peak price of $10. As we take another step, we transition to the peak state, and then we're billed the peak price of $15.01. One last step, and we've transitioned to the use battery state. As we would expect, our cost hasn't changed.
OK, it looks like our decision logic is working properly. Let's turn off the animation and click Continue to run the remaining steps. Once the simulation has finished running, we can see the total energy cost from the display.
Let's open the scope to see how the stored energy varies over time. We can observe strong oscillations in the stored energy from the varying sunlight conditions. Using the battery as a buffering unit, we've managed to obtain a more stable energy source from the solar panels.
Next, let's open the Simulation Data Inspector. Stateflow has saved the entire history of the active state data for us. The top display shows the current hour. Is it peak or off-peak? The bottom display tells us the energy source being used, grid or battery.
After taking a closer look at these state activities, we noticed a problem with our decision logic. Let's focus on this particular day. We can tell from the fact that it was switching back and forth that the battery could not accumulate much energy, so it must have been a cloudy day. As a result, we had to fall back to using the grid in the middle of the peak hours on a very steep price.
At this point, we regret using the battery when the energy price was low. To solve this problem, we can add some additional conditions. Let's wait until we're in the peak state to use the battery. Or if we're in the off-peak state, we can use the battery only when it's sunny outside.
This allows for more effective use of the limited solar energy that we've collected throughout the day. That's how easy it is to modify our decision logic within Stateflow. In practice, we can iterate the whole design process as many times as needed until we have an optimized design.
Now let's rerun the simulation. With this smart decision logic, the total energy cost went down by 2%. Again, this is because now we're more conservative with the battery during bad weather.
Meanwhile, the more conservative usage pattern can lead to higher peak values in the battery's stored energy. In reality, we should try to find the balance between using the battery too aggressively and too conservatively. In either case, Stateflow can help us evaluate our decision logic and identify potential pitfalls.
We've used Stateflow to model and simulate decision logic depending on the current state of our system. And you can, too. Now that you have a feel for what working with Stateflow is like, it's time to learn it.
The best way to learn Stateflow is to work with it. So start up Stateflow OnRamp, which will teach you the basics. It's free and it takes just a couple of hours. Welcome to Stateflow.