Class FSMDirector

  • All Implemented Interfaces:
    java.lang.Cloneable, Executable, Initializable, QuasiTransparentDirector, SuperdenseTimeDirector, ExplicitChangeContext, Changeable, Debuggable, DebugListener, Derivable, ModelErrorHandler, MoMLExportable, Moveable, Nameable
    Direct Known Subclasses:
    HybridModalDirector, MetroIIFSMDirector, ModalDirector, MultirateFSMDirector, NonStrictFSMDirector

    public class FSMDirector
    extends Director
    implements ExplicitChangeContext, QuasiTransparentDirector, SuperdenseTimeDirector
    An FSMDirector governs the execution of a modal model. A modal model is a TypedCompositeActor with a FSMDirector as local director. The mode control logic is captured by a mode controller, an instance of FSMActor contained by the composite actor. Each state of the mode controller represents a mode of operation and can be refined by an opaque CompositeActor contained by the same composite actor.

    The mode controller contains a set of states and transitions. A transition has a guard expression, any number of output actions, and any number of set actions. It has an initial state, which is the unique state whose isInitialState parameter is true. The states and transitions can have refinements, which are composite actors. In outline, a firing of this director is a sequence of steps:

    1. Read inputs.
    2. Evaluate the guards of preemptive transition out of the current state.
    3. If no preemptive transition is enabled:
      1. Fire the refinements of the current state (if any).
      2. Evaluate guards on non-preemptive transitions out of the current state.
    4. Choose a transition whose guard is true.
    5. Execute the output actions of the chosen transition.
    6. Fire the transition refinements of the chosen transition.

    In postfire, the following steps are performed:

    1. Postfire the refinements of the current state if they were fired.
    2. Initialize the refinements of the destination state if the transition is a reset transition.
    3. Execute the set actions of the chosen transition.
    4. Postfire the transition refinements of the chosen transition.
    5. Change the current state to the destination of the chosen transition.

    Since this director makes no persistent state changes in its fire() method, it conforms with the actor abstract semantics. Assuming the state and transition refinements also conform, this director can be used inside any Ptolemy II actor model of computation. How it behaves in each domain, however, can be somewhat subtle, particularly with domains that have fixed-point semantics and when nondeterministic transitions are used. The details are given below.

    When a modal model is fired, this director first transfers the input tokens from the outside domain to the mode controller and the refinement of its current state. The preemptive transitions from the current state of the mode controller are examined. If there is more than one transition enabled, and any of the enabled transitions is not marked nondeterministic, an exception is thrown. If there is exactly one preemptive transition enabled then it is chosen. The choice actions (outputActions) contained by the transition are executed. Any output token produced by the mode controller is transferred to both the output ports of the modal model and the input ports of the mode controller. Then the refinements associated with the enabled transition are executed. Any output token produced by the refinements is transferred to both the output ports of the modal model and the input ports of the mode controller. The refinements of the current state will not be fired.

    If no preemptive transition is enabled, the refinements of the current state are fired. Any output token produced by the refinements is transferred to both the output ports of the modal model and the input ports of the mode controller. After this, the non-preemptive transitions from the current state of the mode controller are examined. If there is more than one transition enabled, and any of the enabled transitions is not marked nondeterministic, an exception is thrown. If there is exactly one non-preemptive transition enabled then it is chosen and the choice actions contained by the transition are executed. Any output token produced by the mode controller is transferred to the output ports of the modal model and the input ports of the mode controller. Then, the refinements of the enabled transition are executed. Any output token produced by the refinements is transferred to both the output ports of the modal model and the input ports of the mode controller.

    In a firing, it is possible that the current state refinement produces an output, and a transition that is taken also produces an output on the same port. In this case, only the second of these outputs will appear on the output of the composite actor containing this director. However, the first of these output values, the one produced by the refinement, may affect whether the transition is taken. That is, it can affect the guard. If in addition a transition refinement writes to the output, then that value will be produced, overwriting the value produced either by the state refinement or the output action on the transition.

    At the end of one firing, the modal model transfers its outputs to the outside model. The mode controller does not change state during successive firings in one iteration of the top level in order to support upper level domains that iterate to a fixed point.

    When the modal model is postfired, the chosen transition of the latest firing is committed. The commit actions contained by the transition are executed and the current state of the mode controller is set to the destination state of the transition.

    FIXME: If a state has multiple refinements, they are fired in the order defined. If they write to the same output, then the "last one wins." It will be its value produced. It might make more sense to require them to be consistent, giving something closer to SR semantics. The same argument could apply when both a refinement and a transition produce outputs.

    Since:
    Ptolemy II 8.0
    Version:
    $Id$
    Author:
    Xiaojun Liu, Haiyang Zheng, Edward A. Lee, Christian Motika
    See Also:
    FSMActor
    Pt.AcceptedRating:
    Red (hyzheng)
    Pt.ProposedRating:
    Yellow (hyzheng)
    • Field Detail

      • controllerName

        public StringAttribute controllerName
        Attribute specifying the name of the mode controller in the container of this director. This director must have a mode controller that has the same container as this director, otherwise an IllegalActionException will be thrown when action methods of this director are called.
      • _currentLocalReceiverMap

        protected java.util.Map _currentLocalReceiverMap
        Map from input ports of the modal model to the local receivers for the current state.
      • _indexOffset

        protected int _indexOffset
        The _indexOffset is set by FSMActor during initialization of destination refinements upon committing to a reset transition in order to ensure that the destination refinement views its index as one larger than the current index.
      • _localReceiverMaps

        protected java.util.Map _localReceiverMaps
        Record for each state of the mode controller the map from input ports of the modal model to the local receivers when the mode controller is in that state.
    • Constructor Detail

      • FSMDirector

        public FSMDirector​(CompositeEntity container,
                           java.lang.String name)
                    throws IllegalActionException,
                           NameDuplicationException
        Construct a director in the given container with the given name. The container argument must not be null, or a NullPointerException will be thrown. If the name argument is null, then the name is set to the empty string. Increment the version number of the workspace.
        Parameters:
        container - Container of this director.
        name - Name of this director.
        Throws:
        IllegalActionException - If the name has a period in it, or the director is not compatible with the specified container.
        NameDuplicationException - If the container not a CompositeActor and the name collides with an entity in the container.
    • Method Detail

      • attributeChanged

        public void attributeChanged​(Attribute attribute)
                              throws IllegalActionException
        React to a change in an attribute. If the changed attribute is the controllerName attribute, then make note that this has changed.
        Overrides:
        attributeChanged in class Director
        Parameters:
        attribute - The attribute that changed.
        Throws:
        IllegalActionException - If thrown by the superclass attributeChanged() method.
      • clone

        public java.lang.Object clone​(Workspace workspace)
                               throws java.lang.CloneNotSupportedException
        Clone the director into the specified workspace. This calls the base class and then sets the attribute public members to refer to the attributes of the new director.
        Overrides:
        clone in class Director
        Parameters:
        workspace - The workspace for the new director.
        Returns:
        A new director.
        Throws:
        java.lang.CloneNotSupportedException - If a derived class contains an attribute that cannot be cloned.
        See Also:
        NamedObj.exportMoML(Writer, int, String), NamedObj.setDeferringChangeRequests(boolean)
      • fire

        public void fire()
                  throws IllegalActionException
        Fire the modal model for one iteration. If there is a preemptive transition enabled, execute its choice actions (outputActions). Otherwise, fire the refinement of the current state. After this firing, if there is a transition enabled, execute its choice actions. If any tokens are produced during this iteration, they are sent to the output ports of the model model and also the input ports of the mode controller.
        Specified by:
        fire in interface Executable
        Overrides:
        fire in class Director
        Throws:
        IllegalActionException - If there is more than one transition enabled and nondeterminism is not permitted, or there is no controller, or it is thrown by any choice action.
      • fireAt

        public Time fireAt​(Actor actor,
                           Time time,
                           int microstep)
                    throws IllegalActionException
        Schedule a firing of the given actor at the given time and microstep. If there exists an executive director, this method delegates to the fireAt() method of the executive director by requesting a firing of the container of this director at the given time adjusted by the current offset between local time and the environment time.

        If there is no executive director, then the request results in model time of this director being set to the specified time. The reason for this latter behavior is to support models where FSM is at the top level. A director inside the state refinements could be timed, and expects time to advance in its environment between firings. It typically makes a call to fireAt() at the conclusion of each iteration to specify the time value it expects to next see. Such directors can thus be used inside top-level FSM models. For example, the DEDirector and SDFDirector behave exactly this way.

        Overrides:
        fireAt in class Director
        Parameters:
        actor - The actor scheduled to be fired.
        time - The scheduled time.
        microstep - The microstep.
        Returns:
        The time at which the actor passed as an argument will be fired.
        Throws:
        IllegalActionException - If thrown by the executive director.
        See Also:
        Director.fireAtCurrentTime(Actor), Director.fireContainerAt(Time)
      • getController

        public FSMActor getController()
                               throws IllegalActionException
        Return the mode controller of this director. The name of the mode controller is specified by the controllerName attribute. The mode controller must have the same container as this director. This method is read-synchronized on the workspace.
        Returns:
        The mode controller of this director.
        Throws:
        IllegalActionException - If no controller is found.
      • getContext

        public Entity getContext()
        Return the explicit change context. In this case, the change context returned is the composite actor controlled by this director.
        Specified by:
        getContext in interface ExplicitChangeContext
        Returns:
        The explicit change context.
      • getModelNextIterationTime

        public Time getModelNextIterationTime()
        Override the base class so that if any outgoing transition has a guard that evaluates to true, then return the current time. Otherwise, delegate to the enclosing director.
        Overrides:
        getModelNextIterationTime in class Director
        Returns:
        The time of the next iteration.
        See Also:
        Director.getModelTime()
      • getModifiedVariables

        public java.util.List getModifiedVariables()
                                            throws IllegalActionException
        Return a list of variables that are modified in a modal model. The variables are assumed to have a change context of the container of this director. This class returns all variables that are assigned in the actions of transitions.
        Specified by:
        getModifiedVariables in interface ExplicitChangeContext
        Returns:
        A list of variables.
        Throws:
        IllegalActionException - If no controller can be found, or the variables to be assigned by the actions can not be found.
      • getParseTreeEvaluator

        public ParseTreeEvaluator getParseTreeEvaluator()
        Return the parse tree evaluator used to evaluate guard expressions. In this base class, an instance of ParseTreeEvaluator is returned. The derived classes may need to override this method to return different parse tree evaluators.
        Returns:
        ParseTreeEvaluator used to evaluate guard expressions.
      • getIndex

        public int getIndex()
        Return a superdense time index for the current time. This method delegates to the executive director, if there is one that implements SuperdenseTimeDirector, and returns current time with index 1 otherwise.
        Specified by:
        getIndex in interface SuperdenseTimeDirector
        Returns:
        A superdense time index.
        See Also:
        setIndex(int), SuperdenseTimeDirector
      • handleModelError

        public boolean handleModelError​(NamedObj context,
                                        IllegalActionException exception)
                                 throws IllegalActionException
        Return true if the model errors are handled. Otherwise, return false and the model errors are passed to the higher level in hierarchy.

        In this method, model errors including multipleEnabledTransitionException and InvariantViolationException are handled.

        In the current design, if multiple enabled transitions are detected, an exception will be thrown. For future designs, different ways to handle this situation will be introduced here.

        When an invariant is violated, this method checks whether there exists an enabled (non-preemptive) transition. If there is one, the model error is ignored and this director will handle the enabled transition later. Otherwise, an exception will be thrown.

        Specified by:
        handleModelError in interface ModelErrorHandler
        Overrides:
        handleModelError in class NamedObj
        Parameters:
        context - The context where the model error happens.
        exception - An exception that represents the model error.
        Returns:
        True if the error has been handled, false if the model error is passed to the higher level.
        Throws:
        IllegalActionException - If multiple enabled transition is detected, or mode controller can not be found, or can not read outputs from refinements.
        See Also:
        NamedObj.setModelErrorHandler(ModelErrorHandler handler)
      • implementsStrictActorSemantics

        public boolean implementsStrictActorSemantics()
        Return true if all state refinements have directors that implement the strict actor semantics.
        Overrides:
        implementsStrictActorSemantics in class Director
        Returns:
        True if the director exports strict actor semantics.
      • initialize

        public void initialize()
                        throws IllegalActionException
        Initialize the mode controller and all the refinements by calling the initialize() method in the super class. Build the local maps for receivers. Suspend all the refinements of states that are not the current state.
        Specified by:
        initialize in interface Initializable
        Overrides:
        initialize in class Director
        Throws:
        IllegalActionException - If thrown by the initialize() method of the super class, or can not find mode controller, or can not find refinement of the current state.
      • invalidateSchedule

        public void invalidateSchedule()
        Indicate that a schedule for the model may no longer be valid, if there is a schedule. This method should be called when topology changes are made, or for that matter when any change that may invalidate the schedule is made. In this class, delegate to the executive director. This is because changes in the FSM may affect the causality interface of the FSM, which may be used in scheduling by the enclosing director.
        Overrides:
        invalidateSchedule in class Director
      • newReceiver

        public Receiver newReceiver()
        Return a receiver that is a one-place buffer. A token put into the receiver will override any token already in the receiver.
        Overrides:
        newReceiver in class Director
        Returns:
        A receiver that is a one-place buffer.
      • postfire

        public boolean postfire()
                         throws IllegalActionException
        Invoke postfire() on any state refinements that were fired, then execute the commit actions contained by the last chosen transition, if any, and finally set the current state to the destination state of the transition. This will return false if any refinement that is postfired returns false.

        If any transition was taken in this iteration, and if there is an executive director, and if there is a transition from the new state that is currently enabled, then this method calls fireAtCurrentTime(Actor) on that executive director (this call occurs indirectly in the FSMActor controller). If there is an enabled transition, then the current state is transient, and we will want to spend zero time in it.

        Specified by:
        postfire in interface Executable
        Overrides:
        postfire in class Director
        Returns:
        True if the mode controller wishes to be scheduled for another iteration.
        Throws:
        IllegalActionException - If thrown by any commit action or there is no controller.
      • prefire

        public boolean prefire()
                        throws IllegalActionException
        Return true if the mode controller is ready to fire. If this model is not at the top level and the current time of this director lags behind that of the executive director, update the current time to that of the executive director. Record whether the refinements of the current state of the mode controller are ready to fire.
        Specified by:
        prefire in interface Executable
        Overrides:
        prefire in class Director
        Returns:
        True.
        Throws:
        IllegalActionException - If there is no controller.
      • resetOutputReceivers

        public void resetOutputReceivers()
                                  throws IllegalActionException
        Rebuild the output receivers map and reset the output receivers.
        Throws:
        IllegalActionException - If there is no mode controller, or can not find refinements for states or if getting the receivers fails.
      • setContainer

        public void setContainer​(NamedObj container)
                          throws IllegalActionException,
                                 NameDuplicationException
        If the container is not null, register this director as the model error handler.
        Overrides:
        setContainer in class Director
        Parameters:
        container - The proposed container.
        Throws:
        IllegalActionException - If the action would result in a recursive containment structure, or if this entity and container are not in the same workspace, or if the protected method _checkContainer() throws it, or if a contained Settable becomes invalid and the error handler throws it.
        NameDuplicationException - If the name of this entity collides with a name already in the container.
        See Also:
        Attribute.getContainer()
      • setIndex

        public void setIndex​(int index)
                      throws IllegalActionException
        Set the superdense time index by delegating to the directors of the refinements of the current state, if any. This should only be called by an enclosing director.
        Specified by:
        setIndex in interface SuperdenseTimeDirector
        Parameters:
        index - The index of the superdense time object. Events that occur at the same time have different indicies.
        Throws:
        IllegalActionException - Not thrown in this base class.
        See Also:
        getIndex(), SuperdenseTimeDirector
      • transferInputs

        public boolean transferInputs​(IOPort port)
                               throws IllegalActionException
        Transfer data from the input port of the container to the ports connected to the inside of the input port and on the mode controller or the refinement of its current state. This method will transfer exactly one token on each input channel that has at least one token available. The port argument must be an opaque input port. If any channel of the input port has no data, then that channel is ignored. Any token left not consumed in the ports to which data are transferred is discarded.
        Overrides:
        transferInputs in class Director
        Parameters:
        port - The input port to transfer tokens from.
        Returns:
        True if at least one data token is transferred.
        Throws:
        IllegalActionException - If the port is not an opaque input port.
      • _buildLocalReceiverMaps

        protected void _buildLocalReceiverMaps()
                                        throws IllegalActionException
        Build for each state of the mode controller the map from input ports of the modal model to the local receivers when the mode controller is in that state. This method is read-synchronized on the workspace.
        Throws:
        IllegalActionException - If there is no mode controller, or can not find refinements for states.
      • _currentLocalReceivers

        protected Receiver[][] _currentLocalReceivers​(IOPort port)
                                               throws IllegalActionException
        Return the receivers contained by ports connected to the inside of the given input port and on the mode controller or the refinement of its current state.
        Parameters:
        port - An input port of the container of this director.
        Returns:
        The receivers that currently get inputs from the given port.
        Throws:
        IllegalActionException - If there is no controller.
      • _getLastChosenTransition

        protected java.util.Map<State,​Transition> _getLastChosenTransition()
                                                                          throws IllegalActionException
        Return the last chosen transitions.
        Returns:
        The last chosen transitions, or null if there has been none.
        Throws:
        IllegalActionException - If there is no controller.
      • _getStateRefinementsToPostfire

        protected java.util.List<Actor> _getStateRefinementsToPostfire()
                                                                throws IllegalActionException
        Return the list used to keep track of refinements that have been fired. This is protected so that FSMDirector can mirror it with its own protected method so that subclasses of FSMDirector can access it.
        Returns:
        A list of actors to postfire.
        Throws:
        IllegalActionException - If can't get the controller.
      • _getTransitionRefinementsToPostfire

        protected java.util.List<Actor> _getTransitionRefinementsToPostfire()
                                                                     throws IllegalActionException
        Return the list used to keep track of refinements that have been fired. This is protected so that FSMDirector can mirror it with its own protected method so that subclasses of FSMDirector can access it.
        Returns:
        A list of actors to postfire.
        Throws:
        IllegalActionException - If can't get the controller.
      • _readInputs

        protected void _readInputs()
                            throws IllegalActionException
        Set the value of the shadow variables for input ports of the controller actor.
        Throws:
        IllegalActionException - If a shadow variable cannot take the token read from its corresponding channel (should not occur).
      • _readOutputsFromRefinement

        protected void _readOutputsFromRefinement()
                                           throws IllegalActionException
        Set the value of the shadow variables for input ports of the controller actor that are defined by output ports of the refinement.
        Throws:
        IllegalActionException - If a shadow variable cannot take the token read from its corresponding channel (should not occur).
      • _setCurrentConnectionMap

        protected void _setCurrentConnectionMap()
                                         throws IllegalActionException
        Set the map from input ports to boolean flags indicating whether a channel is connected to an output port of the refinement of the current state. This method is called by HDFFSMDirector.
        Throws:
        IllegalActionException - If the refinement specified for one of the states is not valid, or if there is no controller.
      • _transferOutputs

        protected boolean _transferOutputs​(IOPort port)
                                    throws IllegalActionException
        Transfer at most one data token from the given output port of the container to the ports it is connected to on the outside. If the receiver is known to be empty, then send a clear. If the receiver status is not known, do nothing.
        Overrides:
        _transferOutputs in class Director
        Parameters:
        port - The port to transfer tokens from.
        Returns:
        True if the port has an inside token that was successfully transferred. Otherwise return false (or throw an exception).
        Throws:
        IllegalActionException - If the port is not an opaque output port.