Mode Management Design Pattern

Intent

This design pattern addresses the problem of endowing components with mode-dependent behaviour. It separates the implementation of the mode-dependent behaviour from the implementation of the logic required to decide mode switches.

Based On

This is pattern is essentially identical to the mode management pattern of the AOCS Framework (see also: A. Pasetti, Embedded Control Systems and Software Frameworks, Springer-Verlag, 2002).

Motivation

Current on-board applications are based on the concept of operational mode. The operational mode changes in response to changes in the operational environment of the application. The operational mode however is typically seen as an attribute of the on-board application as a whole. This typically requires a single "mode manager" component which is responsible for maintaining the system mode. The mode manager might also be responsible for ensuring that each component behaves in a manner that is consistent with the current mode. This component acts as a centralized coordinator of component behaviour. As such, it normally requires a rather detailed understanding of how each component is constructed and of what its internal state is. This approach therefore weakens behaviour encapsulation.

In an alternative variant of this centralized mode management architecture, the mode manager acts as a client for other components that periodically sample it to ask what the current mode is and use this information to tune their behaviour. Or, equivalently, a registration mechanism could be used based on the classical observer pattern where the application component register with the centralized mode manager and are notified whenever there is a mode change. The drawback of these architectures is that different components may need different sets of modes and a centralized mode manager needs to keep track of all of them which again weakens data encapsulation and component decoupling.

Once one decides to move towards a component-based approach, a more appropriate architecture is to make operational mode an attribute of individual components. A mode-dependent component then becomes a component that, depending on operational conditions, needs to select a particular implementation of one or more strategies. As an example consider an attitude controller component in a satellite control system. This component is responsible for implementing the attitude control algorithm and might have two modes: low accuracy control, and high accuracy control. In low accuracy mode, attitude information is provided by a low-accuracy sensor, for instance a coarse sun sensor (CSS), and is processed by a low-accuracy algorithm, for instance a proportional-integral (PI) controller. In high-accuracy mode instead, a high accuracy sensor, for instance a fine sun sensor (FSS), and a high accuracy control algorithm, for instance a PI controller with Kalman filtering (KF), are used. In this case, the controller component (the mode-dependent component) has two strategies (the sensor and the control algorithm) and each strategy has two implementations (the CSS and the FSS for the sensor strategy, and the PI and PI+KF for the control algorithm strategy). During normal operation, the satellite decides which strategy to use based on the size of the control error.

The advantage of this approach is that it allows the selection of the operational modes and of their associated strategies to be tailored to the needs of each component. Its potential disadvantage is that it complicates the problem of separating the problem of designing and implementing the strategies separate from the problem of designing and implementing the logic that controls the operational mode transitions. There is a risk that each mode-dependent component becomes responsible for both tasks with a consequent weakening of the principle of separation of concerns. This design pattern is useful in precisely this situation because it offers a way of separating the implementation of the mode-dependent behaviour from the implementation of the logic required to decide mode switches.

Dictionary Entries

The following abstractions or domain-wide concepts are defined to support the implementation of this design pattern:

Structure

The pattern class diagram in the figure illustrates the case of a mode-dependent component with two strategies. The mode dependent component uses a mode manager to supply to it the implementations of the strategies that are appropriate for a given operational situation. The two strategies are seen as instances of classes Strategy_1 and Strategy_2. These could be concrete classes, or base abstract classes, or abstract interfaces. The mode manager is characterized by the ability to provide instances of these two classes to the mode-dependent component. It must therefore implement an abstract interface like ModeManager in the figure that defines two getter methods for the two strategy implementations and two loader methods to associate the strategy implementations to the various modes managed by the mode manager. Concrete implementations of the ModeManager interface provide the logic to switch between modes. This logic is implemented in a method like updateMode that sets the current mode and therefore indirectly determines which implementers of the strategies are returned by calls to the getter methods.

The mode manager encapsulates the logic to decide which implementation of each strategy is appropriate at any given time. When the mode-dependent component needs a strategy implementation, it uses the strategy getter methods offered by the mode manager to obtain one. From the point of view of the mode-dependent component, the strategy implementations are always seen as instances of type Strategy_1 and Strategy_2.

Participants

Collaborations

The typical operational scenario for this design pattern is:

Consequences

Applicability

Consider an application that is component-based and that has a need to tune its behaviour to changes in its operational environment. If it is not practical to define a single operational mode for the entire application and if operational mode is better seen as an attribute of individual components, then this design pattern helps defines an architecture that separates the implementation of the mode-dependent behaviours (the strategies) from the implementation of the mode management logic.

Implementation Issues

It would be useful to be able to define a generic ModeManager abstract interface. This could probably be done using meta-language facilities (such as, for instance, Java reflection) or template meta-programming. In most cases, these techniques will not be acceptable for on-board applications and hence differences in the number and type of strategies and in the mode update mechanisms will usually mean that a dedicated mode manager interface must be defined for each mode-dependent component.

The mode manager maintains the operational mode of the mode-dependent component. Which mechanism should it use to update this operational mode in response to changes in the component's operational environment? The class diagram above shows the mode manager exposing an update method that should be periodically called to give the mode manager a chance to check whether its operational mode needs to be updated. There are at least two alternative mechansisms. The mode manager might check for updates whenever one of the getter methods is called. This is a form of lazy update that is performed only when and if the mode-dependent component requires a new strategy implementation. Or, alternatively, the mode manager might use the classical observer pattern to ask to be notified whenever certain environmental parameters change and might use these notifications as opportunities to update its internal operational mode.

With the approach proposed here, the operational mode becomes a property of (some) application components. In order to ensure consistency of behaviour at the system level, it is necessary to ensure that changes in the operational mode of individual components are coordinated. Coordination will normally imply that a mode manager expose its operational mode as a monitorable property to give other components (possibly other mode managers) the chance to observe changes in its value and therefore to coordinate their behaviour with it.

OBS Framework Mapping

The implementation of this design pattern in the OBS Framework is supported by the following classes:

Sample Code

Consider the example of the mode-dependent attitude controller component considered in the motivation section above. A skeleton code for this component could be as follows:

	class AttitudeController {

		AttitudeSensor* sensor;
		AttitudeControlAlgorithm* controlAlgorithm;
		AttitudeControllerModeManager* modeManager;
		. . .
		void computeControlAction() {

		  // Retrieve strategy implementers
		  sensor = modeManager->getAttitudeSensor();
		  controlAlgorithm = modeManager->getControlAlgorithm ();

		  // Use first strategy to acquire sensor data
		  sensor->acquireData();

	 	  // Use second strategy to process the sensor data
	  	  controlAlgorithm->processSensorData();
		}
	}	

The mode manager of this example will maintain two versions of the attitude control algorithms and two versions of the attitude sensor and will supply the appropriate one to the attitude controller algorithm based on operational conditions. The controller component can thus concentrate on computing the processing of the sensor data without having to keep track of changes in operational conditions.

Remarks

None

Author

A. Pasetti (P&P Software)

Last Modified

2002-12-12

Contact Us | The OBS Framework Project