Variable Monitoring Design Pattern

Intent

Decouple the monitoring of the value of a variable from the time profile against which the monitoring is performed.

Based On

This pattern is based on the object monitoring design pattern of the AOCS Framework.

Motivation

Many OBS applications must be capable of performing a certain amount of failure detection checks. One important category of failure detection checks consists in monitoring the value of a variable to ensure that it follows a specified time profile. Deviation from this profile may indicate that a failure has occurred. Thus, for instance, a typical failure detection test checks that the value of a variable remains within a pre-defined range. In this case the time profile is simply given by the range of admissible values. In other case, it may be more complex. An example is a check that the output of a sensor should not "jump" by more than a pre-defined threshold. The admissible profile is then one where the variations across sampling points are less than the threshold.

Most on-board systems have similar requirements: they identify certain variables as in need of monitoring and specify for each the type of time profile that they should follow.

In most cases, this type of failure detection is performed by hard-coding the profile against which the monitoring is to be performed. The code that performs the monitoring thus becomes dependent on the monitoring profile. This design pattern allows the two to be separated. A natural extension of the design pattern also allows to decouple the monitoring action from the variable to be monitored.

Dictionary Entries

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

Structure

The variable monitoring design pattern proposes a representation for the monitoring profile abstraction. This is represented by the MonitoringProfile abstract interface. Concrete monitoring profiles are implemented as instances of classes that implement MonitoringProfile.

Interface MonitoringProfile defines a basic operation deviatesFromProfile that takes as an argument the value of the monitored variable and returns true if this value is found to deviate from the profile encapsulated in the concrete monitoring profile component. The monitoring of the variable value is therefore performed by passing the value of the monitored variable through the monitoring profile filter.

There is usually a need to be able to selectively enable and disable a particular deviation check. For this purpose, the MonitoringProfile interface could be endowed with a second basic operation to enable and disable the execution of the deviation check.

Participants

Collaborations

The typical operational scenario for this design pattern is:

Consequences

Applicability

This design pattern is useful when:

Implementation Issues

Sometimes, the same variable has to be monitored against several profiles (e.g. it should not exceed certain limits and it should not jump by more than a certain threshold). In order to perform sequential checks in a systematic manner, it would be useful to have the option of linking monitoring profile components and to have an automatic mechanism to let the monitoring be propagated along the chain with deviatesFromProfile returning true if any of the linked monitoring profiles returns true. The structure of the design pattern then becomes as shown in the figure. Note that MonitoringProfile is best implemented as a concrete base class because method deviatesFromProfile can implement the forwarding of the monitoring checks along the chain of linked monitoring profile components.

Often, detection of a monitoring profile violation should be recorded as an event. In such cases, MonitoringProfile could be implemented as a class and the logic to create the event report could be implemented at the level of this base class thus avoiding duplication of code in concrete monitoring profile components.

Since they are encapsulated in components, monitoring profiles can have memory. Thus, the check on the value of a variable can take account not only of its current value but also of its previous values.

It is useful to have an operation to enable and disable monitoring profiles (a disabled monitoring profile will always report: no deviation detected). However, since monitoring profiles can have memory, care must be taken when making the transition from disabled to enabled status.

This design pattern decouples the monitoring action from the time profile against which monitoring is being performed. A higher degree of generality can be achieved by additionally decoupling the monitoring action from the variable to be monitored. This can be done by encapsulating variables to be monitored in dedicated MonitoredVariable components instantiated from a class defined as follows:

	class MonitoredVariable {
	  float* p;

	  MonitoredVariable(float* variableToBeMonitored) {
		p = variableToBeMonitored;
	  }

	  float getValue() {
		return *p;
	  }
	}
This class is a simple wrapper for a pointer to a float variable (it is functionally very similar to the DataItem class of the connection design pattern). Monitoring can now be performed in a systematic way on a collection of variables by code that looks as follows:
	MonitoredVariable* varList[N];
	MonitoringProfile* mpList[N];
	float value;
	. . .

	for (int k=1; k<N; k++)
	{	value = varList[k]->getValue();
		if ( mpList[k]->deviatesFromProfile(value) )
		    . . . // a monitoring violation has been detected!
	}
Code like that above would typically be found in a failure detection module where several variables have to be subjected to systematic surveillance checks. It could form the basis of an application-independent failure detection manager component (similar to the one proposed by the AOCS Framework). The important point to stress is that the monitoring code is independent of both the variables that are to be monitored (encapsulated in Property objects) and the profiles against which they have to be monitored (encapsulated in MonitoringProfile objects).

The variable monitoring design pattern together with the recovery action design pattern can be used to set up a complete FDIR mechanism (FDIR stands for: "failure detection, isolation and recovery"). The monitoring profile objects are responsible for detecting potential faults. A positive value reported by deviatesFromProfile would then be used to activate a RecoveryAction component that encapsulate the recovery part of the FDIR logic.

OBS Framework Mapping

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

Sample Code

Consider an application where failure detection checks are performed by checking that the value of the monitored variable is within a pre-specified range. This type of monitoring check could be performed in the spirit of the variable monitoring design pattern by a component defined as follows:

	class RangeProfile : MonitoringProfile {
	  float lowerBound;
	  float upperBound;
	  . . .
	  bool deviatesFromProfile(float v) {
	    if (v>upperBound) || (v<lowerBound)
		return true;
	    else
		return false;
	  }

	  void setMonitoringParameters(float l, float u) {
	    lowerBound = l;
	    upperBound = u;
	  }
	}
The code that implements the monitoring check would then look like this:
	MonitoringProfile* mp;
	. . .
            // v is the variable to be monitored
	if (mp->deviatesFromProfile(v))
	. . .    // violation of surveillance criterion detected!  
Note that this code is independent of the profile against which monitoring is being performed. The monitoring profile component is a plug-in component that is loaded during the initialization phase and is seen only through its abstract MonitoringProfile interface.

If the monitoring check is part of an FDIR logic, then a recovery action component should be associated to the monitoring profile component and the check would be performed as follows:

	MonitoringProfile* mp;
	RecoveryAction* ra;
	. . .
            // v is the variable to be monitored
	if (mp->deviatesFromProfile(v))
		ra->doRecovery();
Thus, the monitoring profile component encapsulates the failure detection part of the FDIR logic. Its job is to catch deviation from nominal behaviour. Such deviations are, by definition, considered as a fault. The response to the fault is encapsulated in the recovery action component. This response may range in complexity from doing nothing (for instance, if the fault is judged to be sporadic) to launching complex manoeuvres. The important point to stress is that the complexity of both the fault detection and fault recovery procedure is hidden behind the abstract interfaces MonitoringProfile and RecoveryAction. Thus, the above code remains the same regardless of which particular fault detection and fault recovery logic is being applied.

Remarks

None

Author

A. Pasetti (P&P Software)

Last Modified

2003-06-01

Contact Us | The OBS Framework Project