FSM Lecture 81| Orthogonal state pattern

 

Orthogonal state pattern

 

 

This is about implementing the orthogonal regions. And here, we use container and component relationships.

The orthogonal component state pattern is a design pattern commonly used in finite state machines (FSMs) to improve their modularity and flexibility.

The main advantages of using the orthogonal state pattern is

  • Its ability to simplify the design of complex state machines. By breaking down the behavior of a machine into a set of orthogonal states, developers can focus on each individual state’s functionality and behavior, making it easier to manage and maintain the state machine as a whole.
  • Another advantage of the orthogonal state pattern is its flexibility. The independent nature of the orthogonal states makes it easy to add, remove, or modify states as needed, without affecting the rest of the state machine’s behavior. This makes it a valuable pattern for systems that require a high degree of flexibility or modifiability.

 

 

Orthogonal Component state pattern:

  • Using state machine as components
  • Identify the independent components in your project and use the technique ‘composition’ of classes
  • For example, in our Clock Alarm exercise, Alarm could be independent exhibiting its own behavior(State machine) and data (attributes such as alarm_time, alarm_mode, alarm_status)
  • Alarm component can be reused with other containers of the application

Each orthogonal component has its own set of states, events, and transitions, and can transition between states independently of the other components. This allows for greater flexibility in designing the system, as different aspects of the system can be modified and tested separately without impacting the rest of the system.

You have to identify the independent components in your project and use the technique ‘composition’ of classes. What is that? Let’s explore. 

 

Figure 1. Composition or strong aggregation in OOP relationship
Figure 1. Composition or strong aggregation in OOP relationship

 

This relationship is called composition or strong aggregation in OOP, as shown in Figure 1.  Let’s consider Clock_Alarm is one class and Alarm is one class. Here, we can say that the Clock_Alarm class consists of the Alarm class, called composition or strong aggregation. Strong aggregation means when the parent or container dies, the child also dies. 

Here you can call Clock_Alarm as a ‘parent’ and Alarm as a ‘child,’ or Clock_Alarm is a ‘container’ and Alarm is a ‘component.’

The parent manages the memory for the child. That means when this parent comes into existence in memory, the child also comes into existence. When the memory for the Clock_Alarm object is deallocated, then the memory for Alarm is also deallocated automatically. So, this is like a Room and Wall relationship. In this analogous to Room and Wall relationship.

The Room is a container for the Wall. You can call it a Room as a container and Wall as a component. When Room dies, Wall also dies. You can say that, Room ‘consist of’  wall. That’s the meaning of composition in OOP.

 

Composition 

Figure 2. Composition
Figure 2. Composition

 

In composition, please note that there is no independent existence for the child or the component. Consider there are two containers. Container-1 and container-2. 

Here in Alarm, its existence is because of container-1. Because whenever container-1 comes into life, the Alarm component also comes into life. That’s why you cannot use the composition of the Alarm component with another container here; that is not possible. Because its memory is exclusively for the Clock_Alarm container.

We can say here that Clock Alarm is an exclusive container of the Alarm component. That doesn’t mean that this Fire safety container cannot use the Alarm class as its attribute. It can use it. If it wants to use it, then it has to create its own copy of this Alarm object. It can do that.

Here, the Alarm component has no independent existence. I’m talking about here the alarm object. In this case, the alarm object. Object means there is some existence in the memory. The memory of this is exclusively for this container. That’s why I say the alarm has no independent existence. Its existence is only inside the Clock_Alarm. When a container gets created, all components are also gets created. 

 

Figure 3. Simple Aggregation
Figure 3. Simple Aggregation

 

There is one more term is called just a simple Aggregation, denoted by a diamond symbol, which is not filled. This is Has a relationship. Here, the Alarm object has independent existence somewhere in the memory, and both the containers can claim that alarm object as their attributes.

 

Figure 4.Composition or strong aggregation in OOP relationship
Figure 4. Composition or strong aggregation in OOP relationship

 

In our project, we have a state ‘Clock_Alarm.’ I will call it CA. And it has got two regions, r1 and r2. And r2 could be a collection of many substates, I will call it an Alarm substate. Now, we can use this composition technique here. We can convert this r2 region as a component using its dedicated class, which is nothing but a component or a child. The relationship between the main class(Clock_Alarm) and this subclass or child class(Alarm) is because of the composition technique. So, we will see later how to do that. If you are confused, don’t worry, so as we make progress, it will get clear.

 

Orthogonal state pattern
Figure 5. Orthogonal component state pattern

 

Now let’s discuss using the container and component approach and how you communicate between container to component and component to the container.

 

Container to the component

Orthogonal state pattern
Figure 6. Container to component

 

When the container state machine is executing, the container can synchronously communicate with the component. This is called synchronous communication. The container state machines executing, and it received one event, that event should be reported to the component.

Since it is a composition, the container can call the dispatch function of the component. And a component will then consume that event. Here, the container waits until its component’s RTC step gets over. That’s why the RTC step of the component will get executed in the thread context of the container. When the RTC step of the component gets over, the control is returned to the container, and then the container resumes, and it finishes its RTC step. Container RTC Step cannot proceed until the components RTC step completes. That’s why it is called synchronous communication between container and component.

So, the container calls the dispatch function exposed by this component, and it should wait, or it cannot proceed until the RTC step of the component gets over. This is a way to communicate in a container to a component. 

 

Component to container

Orthogonal state pattern
Figure 7. Component to container

 

So, if the component wants to communicate with the container, then it cannot call the dispatch function of the container because it is executing in the thread context of the container. That’s why it cannot call the dispatch function of the container.

If that happens, then the RTC semantic will be violated. Because the container has started, it’s an RTC step here. It has to finish before processing the RTC step for the next event. That’s why the component cannot call the dispatch function of the container to execute the RTC step for a new event. That’s not possible. The component can do if it has any events to report to the container.

For example, in our case, Container SM is Clock_Alarm class, Component SM is Alarm class. When it is executing its component RTC step, let’s say somewhere it comes to know that Alarm has happened, and now it has to inform the container there is an Alarm.

Then that Alarm event must be posted to the queue, that is the event queue of the container. A container is an active object with its own Event queue. Component must publish, or it should post events to the Event queue of the container, and then it returns. And the container RTC step will be completed here, and then it processes its event, which is there in the event queue. It’s like that. We’ll see all these things while writing the code.

 

Now, let’s head over to our IDE and create a new project. Basically, we are implementing the same project, 007ClockAlarm, but using active objects. So, we will be using active objects, it’s associated event queues and direct posting of events from ISRs, etc. And also, we will use the orthogonal state pattern approach.  

Orthogonal state pattern
Figure 8. 008ClockAlarm_AO project

 

What you need to do now is, you have to create a new project. I have already created 008ClockAlarm_AO, as shown in Figure 8. Create one more folder called QM, and please download the attached QM model file with this lecture and place that in this folder. 

 

Get the Embedded System Design using UML State Machines Full Course on Here

FastBit Embedded Brain Academy Courses

Click here: https://fastbitlab.com/course1

 

FastBitLab

The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.