Implementation Notes

 

This document describes the ASW framework that is being supplied and explains how this could be expanded into a fully working altitude switch implementation.

 

The framework lets you get started right away with the coding of the core of the state machine for the Altitude Switch. The framework provides all the code necessary for the communication with the Nimbus channel framework.  To get your Altitude Switch running, you have to:

 

  1. Extend framework class ASW with a derived class, say AltitudeSwitch, that provides your implementation of the altitude switch.
  2. Create interfaces that hook up your ASW implementation to the channel framework.
  3. Implement two methods in the derived class, init and next
  4. Compile your implementation and execute it.

 

The following sections describe this process in more detail with examples as necessary.

Extending the ASW framework

 

This is simply achieved by importing the framework ASW as:

 

import edu.umn.cs.crisys.*;

 

and declaring a class for your implementation

 

public class AltitudeSwitch extends ASW {

 

      // all your implementation code goes here

 

}

Creating Communication Interfaces (and channels)

 

The interface classes are all provided in the framework.  The interfaces are also instantiated in the ASW class that you would extend. Thus the only effort is to use the

interfaces in your code.  See the sample implementation and the documentation  on how to use these interfaces.

 

Implementing init and next

 

The bulk of the work is in implementing these two methods. Internally, you are free to decide on the appropriate fields and representations for your state machine. 

 

The only contract on the interfaces is that you provide two methods init, which takes no argument and returns nothing and next, that takes an argument, which is a reference to the input interface that received a message.

 

protected void init();

 

protected void next(Interface trigger);

 

The init method will be invoked once at start-up and the next method will be invoked each time a computation is necessary.  In the init method, you should call

super.init() that takes care of opening the communication channels for the interfaces.

 

Note that a step computation is triggered whenever an input is received in any of the interfaces.  Also, periodically (approx. 5 times per second) the next method will be invoked with a null reference as the interface. This is to be understood as a time triggered computation step.  Time is not explicitly supplied as an input. However, you can get the current time System.currentTimeMillis() call.  A straightforward approach is to retrieve the current time at the start of each step and remembering it locally in the state information.

 

Finally, there is also an end()method that is called when stopping the machine. However, the framework class implements this method which will take care of closing the interfaces.  If you override this method, remember to call super.end() to close the interfaces.

 

Message Reception and Sending:

 

Messages are automatically received and stored as they arrive.  You may retrieve the current message at an interface by accessing its message field. For example:

 

 ((InhibitMessage)InhibitMessageInterface.myMessage).i

 

yields the field i from the InhibitMessageInterface.

 

When a message has to be sent through an output interface the send()method should be called. For example:

 

((FaultMessage)FaultDetectionInterface.myMessage).fault =

      cur.sFaultDetectedVariable.booleanValue();

 FaultDetectionInterface.send();

 

Further Information:

The classes and interfaces provided in the framework come with documentation explaining how those could be used. The documentation is accessible from the  doc directory.