The AOCS framework is designed as a truly object-oriented system. The design process then proceeds in three major steps.
Very simplified versions of the abstract interfaces corresponding to the abstract functionalities listed above are (using C++ syntax):
A call to method writeToTelemetry causes an object to write its own state to the telemetry stream.class ConsistencyCheckable {
ConsistencyCheckable Functionality
A call to method doConsistencyCheck causes an object to perform a consistency check upon itself. The return value indicates whether the consistency check failed or succeeded.class Resettable {
Resettable Functionality
A call to method reset causes an object to reset its internal state.
In the figure, abstract interfaces are shown in red with the class name in italic and concrete classes are shown in yellow with the class name in normal type. Arrows represent inheritance relationships.
Class FineSunSensor is derived from class AocsUnit that represents generic AOCS units (either sensors or actuators). Class AocsUnit is in turn derived from class AocsObject which in the AOCS framework is used as the common base class for all non-trivial objects and additionally implements interfaces Resettable, Telemeterable and ConsistencyCheckable. Note that class AocsUnit only has single inheritance of implementation (although it has multiple inheritance of interfaces).
Note also that the proposed class hierarchy ensures that, as desired, fine sun sensor objects implement the Resettable, ConsistencyCheckable and Telemeterable functionalities. This same fact can be alternatively expressed by saying that objects instantiated from class FineSunSensor can have several dynamic types. Thus, a fine sun sensor object will be seen by its clients as an instance of type Resettable, by other clients as an instance of type Telemeterable, by still others as an instance of type ConsistencyCheckable, etc.
Consider for instance the management of failure detection tests. In many current AOCS systems, this functionalities is spread over the entire software. With the approach taken in the AOCS Framework, instead it is possible to concentrate this functionality in a single, application-independent, component. The consistency checks (one important part of the failure detection tests) could for instance be carried out as follows;
ConsistencyCheckable*
consistencyCheckableList[N];
. . .
for (int i=0; i<N;
i++)
{
if (consistencyCheckableList[i]->doConsistencyCheck())
. . . // check failed, report failure
}
Obviously, the failure detection manager would have to expose methods
to allow objects to be (dynamically) added or removed from consistencyCheckableList.
The important point, however, is that the consistency checks are managed
in a completely application-independent manner.
Telemetry management would be performed in a similar manner. The core of the telemetry manager object would be something like:
Telemeterable* telemeterableList[N];
. . .
for (int i=0; i<N;
i++)
telemeterableList[i]->writeToTelemetry()
Once again, telemetry management is completely mission-independent.
A point worthy of note is that, thanks to the use of multiple inheritance, the same concrete object can be simultaneously present on both consistencyCheckableList and telemeterableList. In one cases it is treated as an instance of type ConsistencyCheckable*, whereas in the secon case it is treated as an instance of type Telemeterable. Multiple inheritance is used to allow this multiplicity of views of the same concrete objects.
Thus, for instance, a fine sun sensor object can be declared as follows:
FineSunSensor fss;
FineSunSensor*
ptr_ss=&fss;
The pointer ptr_fss can be passed both to the telemetry manager and to the failure detection manager. This is possible because variable ptr_fss can have different dynamic types corresponding to all the classes from which fss inherits (either directly or indirectly). In other words, ptr_fss is declared as a pointer to FssSunSensor but it can be used wherever pointers to any of its superclasses are required. This is expressed by saying that the static type of ptr_fss is FssSunSensor* but its dynamic type can be pointer to any of the superclasses of FssSunSensor.
In summary then, the AOCS Framework provides functionality manager components that are mission independent because they operate on abstract interfaces. Concrete objects use multiple inheritance to implement several abstract interfaces corresponding to their various functionalities. This allows them to play different roles depending on the context in which they are used.
Finally, it is hardly necessary to stress that the code examples given above are highly simplified. The abstract interfaces in the AOCS Framework are richer than shown here and the functionality managers consist of much more than simple loops.
A naive observer might argue that the class structure of the figure above is unnecessarily complex. Why not combine the three abstract interfaces into class AocsObject? This would streamline the class tree and remove the need for multiple implementation of interfaces (it would notably make implementation in a language like Ada95 possible). There are at least two reasons why this type of simplification would lead to a deeply flawed design.
First, not all classes in the AOCS Framework need to implement all three abstract functionalities. There are for instance some classes that should be telemerable and resettable but that should not be consistency checkable. There are also classes that should be resettable without being either telemeterable or consistency checkable. Thus, keeping the abstract interfaces separate allows to allocate responsibilities to classes in a more finely grained manner.
Secondly, some of the clients that need to access objects instantiated from class FineSunSensor only need to have access to services of a certain type. For instance, the telemetry manager only needs access to the services defined by the telemeterable functionality. With the proposed architecture, the telemetry manager sees instances of class FineSunSensor as objects of (dynamic) type Telemerable. There is therefore a syntactical check, statically enforced by the compiler, that it will only have access to the telemeterable operations. Mistakes arising from the fact that the telemetry manager tries to access operations that are outside its competence simply cannot occur. Thus, keeping the abstract interfaces separate helps avoid design mistakes and enforces clean software architectures.
Back to Top, Back to Aocs Framework Project Home