public class FSMDirector extends Director implements ExplicitChangeContext, QuasiTransparentDirector, SuperdenseTimeDirector
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:
In postfire, the following steps are performed:
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.
FSMActor
NamedObj.ContainedObjectsIterator
Modifier and Type | Field and Description |
---|---|
protected java.util.Map |
_currentLocalReceiverMap
Map from input ports of the modal model to the local receivers
for the current state.
|
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.
|
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.
|
StringAttribute |
controllerName
Attribute specifying the name of the mode controller in the
container of this director.
|
_actorsFinishedExecution, _aspectForActor, _aspectsPresent, _defaultMicrostep, _executionAspects, _finishRequested, _initializables, _nextScheduleTime, _stopRequested, _tokenSentToCommunicationAspect, _zeroTime, localClock, startTime, stopTime
_changeListeners, _changeLock, _changeRequests, _debugging, _debugListeners, _deferChangeRequests, _elementName, _isPersistent, _verbose, _workspace, ATTRIBUTES, CLASSNAME, COMPLETE, CONTENTS, DEEP, FULLNAME, LINKS
COMPLETED, NOT_READY, STOP_ITERATING
Constructor and Description |
---|
FSMDirector()
Construct a director in the default workspace with an empty
string as its name.
|
FSMDirector(CompositeEntity container,
java.lang.String name)
Construct a director in the given container with the given
name.
|
FSMDirector(Workspace workspace)
Construct a director in the workspace with an empty name.
|
Modifier and Type | Method and Description |
---|---|
protected void |
_buildLocalReceiverMaps()
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.
|
protected Receiver[][] |
_currentLocalReceivers(IOPort port)
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.
|
protected java.util.Map<State,Transition> |
_getLastChosenTransition()
Return the last chosen transitions.
|
protected java.util.List<Actor> |
_getStateRefinementsToPostfire()
Return the list used to keep track of refinements that have been
fired.
|
protected java.util.List<Actor> |
_getTransitionRefinementsToPostfire()
Return the list used to keep track of refinements that have been
fired.
|
protected void |
_readInputs()
Set the value of the shadow variables for input ports of the controller actor.
|
protected void |
_readOutputsFromRefinement()
Set the value of the shadow variables for input ports of the
controller actor that are defined by output ports of the
refinement.
|
protected void |
_setCurrentConnectionMap()
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.
|
protected void |
_setCurrentState(State state)
Set the current state of this actor.
|
protected boolean |
_transferOutputs(IOPort port)
Transfer at most one data token from the given output port of
the container to the ports it is connected to on the
outside.
|
void |
attributeChanged(Attribute attribute)
React to a change in an attribute.
|
java.lang.Object |
clone(Workspace workspace)
Clone the director into the specified workspace.
|
Dependency |
defaultDependency()
Return a default dependency to use between input input ports
and output ports.
|
void |
fire()
Fire the modal model for one iteration.
|
Time |
fireAt(Actor actor,
Time time,
int microstep)
Schedule a firing of the given actor at the given time
and microstep.
|
Entity |
getContext()
Return the explicit change context.
|
FSMActor |
getController()
Return the mode controller of this director.
|
int |
getIndex()
Return a superdense time index for the current time.
|
Time |
getModelNextIterationTime()
Override the base class so that if any outgoing transition has
a guard that evaluates to true, then return the current
time.
|
java.util.List |
getModifiedVariables()
Return a list of variables that are modified in a modal
model.
|
ParseTreeEvaluator |
getParseTreeEvaluator()
Return the parse tree evaluator used to evaluate guard
expressions.
|
boolean |
handleModelError(NamedObj context,
IllegalActionException exception)
Return true if the model errors are handled.
|
boolean |
implementsStrictActorSemantics()
Return true if all state refinements have directors that
implement the strict actor semantics.
|
void |
initialize()
Initialize the mode controller and all the refinements by
calling the initialize() method in the super class.
|
void |
invalidateSchedule()
Indicate that a schedule for the model may no longer be valid,
if there is a schedule.
|
boolean |
isStrict()
Return false.
|
Receiver |
newReceiver()
Return a receiver that is a one-place buffer.
|
boolean |
postfire()
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.
|
boolean |
prefire()
Return true if the mode controller is ready to fire.
|
void |
preinitialize()
Check whether contained refinements have a director.
|
void |
resetOutputReceivers()
Rebuild the output receivers map and reset the output receivers.
|
void |
setContainer(NamedObj container)
If the container is not null, register this director as the model error handler.
|
void |
setIndex(int index)
Set the superdense time index by delegating to the directors of
the refinements of the current state, if any.
|
boolean |
transferInputs(IOPort port)
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.
|
_actorFinished, _consultTimeRegulators, _description, _isEmbedded, _isTopLevel, _schedule, _transferInputs, addInitializable, createSchedule, delayDependency, elapsedTimeSinceStart, finish, fireAt, fireAt, fireAtCurrentTime, fireContainerAt, fireContainerAt, getCausalityInterface, getCurrentTime, getDeadline, getEnvironmentTime, getExecutionAspect, getGlobalTime, getModelStartTime, getModelStopTime, getModelTime, getNextIterationTime, getStartTime, getStopTime, getTimeResolution, initialize, invalidateResolvedTypes, isEmbedded, isFireFunctional, isStopRequested, iterate, mutexLockObject, notifyTokenSentToCommunicationAspect, preinitialize, removeInitializable, requestInitialization, resume, resumeActor, scheduleContainedActors, setCurrentTime, setEmbedded, setModelTime, setTimeResolution, stop, stopFire, suggestedModalModelDirectors, supportMultirateFiring, suspend, terminate, transferOutputs, transferOutputs, wrapup
_checkContainer, _getContainedObject, _propagateExistence, getContainer, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, setName, updateContent
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _containedDecorators, _copyChangeRequestList, _debug, _debug, _debug, _debug, _debug, _executeChangeRequests, _exportMoMLContents, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _notifyHierarchyListenersAfterChange, _notifyHierarchyListenersBeforeChange, _propagateValue, _removeAttribute, _splitName, _stripNumericSuffix, _validateSettables, addChangeListener, addDebugListener, addHierarchyListener, attributeDeleted, attributeList, attributeList, attributeTypeChanged, clone, containedObjectsIterator, decorators, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getElementName, getFullName, getModelErrorHandler, getName, getName, getPrototypeList, getSource, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, notifyOfNameChange, propagateExistence, propagateValue, propagateValues, removeAttribute, removeChangeListener, removeDebugListener, removeHierarchyListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, uniqueName, validateSettables, workspace
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
description, getContainer, getDisplayName, getFullName, getName, getName, setName
public StringAttribute controllerName
protected java.util.Map _currentLocalReceiverMap
protected int _indexOffset
protected java.util.Map _localReceiverMaps
public FSMDirector() throws IllegalActionException, NameDuplicationException
NameDuplicationException
- If construction of Time objects fails.IllegalActionException
- If construction of Time objects fails.public FSMDirector(Workspace workspace) throws IllegalActionException, NameDuplicationException
workspace
- The workspace of this director.NameDuplicationException
- If construction of Time objects fails.IllegalActionException
- If construction of Time objects fails.public FSMDirector(CompositeEntity container, java.lang.String name) throws IllegalActionException, NameDuplicationException
container
- Container of this director.name
- Name of this director.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.public void attributeChanged(Attribute attribute) throws IllegalActionException
attributeChanged
in class Director
attribute
- The attribute that changed.IllegalActionException
- If thrown by the superclass attributeChanged()
method.public java.lang.Object clone(Workspace workspace) throws java.lang.CloneNotSupportedException
clone
in class Director
workspace
- The workspace for the new director.java.lang.CloneNotSupportedException
- If a derived class contains an attribute that
cannot be cloned.NamedObj.exportMoML(Writer, int, String)
,
NamedObj.setDeferringChangeRequests(boolean)
public Dependency defaultDependency()
defaultDependency
in class Director
Dependency
,
CausalityInterface
,
Actor.getCausalityInterface()
public void fire() throws IllegalActionException
fire
in interface Executable
fire
in class Director
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.public Time fireAt(Actor actor, Time time, int microstep) throws IllegalActionException
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.
fireAt
in class Director
actor
- The actor scheduled to be fired.time
- The scheduled time.microstep
- The microstep.IllegalActionException
- If thrown by the executive director.Director.fireAtCurrentTime(Actor)
,
Director.fireContainerAt(Time)
public FSMActor getController() throws IllegalActionException
IllegalActionException
- If no controller is found.public Entity getContext()
getContext
in interface ExplicitChangeContext
public Time getModelNextIterationTime()
getModelNextIterationTime
in class Director
Director.getModelTime()
public java.util.List getModifiedVariables() throws IllegalActionException
getModifiedVariables
in interface ExplicitChangeContext
IllegalActionException
- If no controller can be
found, or the variables to be assigned by the
actions can not be found.public ParseTreeEvaluator getParseTreeEvaluator()
ParseTreeEvaluator
is returned. The derived classes may need
to override this method to return different parse tree
evaluators.public int getIndex()
getIndex
in interface SuperdenseTimeDirector
setIndex(int)
,
SuperdenseTimeDirector
public boolean handleModelError(NamedObj context, IllegalActionException exception) throws IllegalActionException
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.
handleModelError
in interface ModelErrorHandler
handleModelError
in class NamedObj
context
- The context where the model error happens.exception
- An exception that represents the model error.IllegalActionException
- If multiple enabled transition is detected,
or mode controller can not be found, or can not read outputs from refinements.NamedObj.setModelErrorHandler(ModelErrorHandler handler)
public boolean implementsStrictActorSemantics()
implementsStrictActorSemantics
in class Director
public void initialize() throws IllegalActionException
initialize
in interface Initializable
initialize
in class Director
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.public void invalidateSchedule()
invalidateSchedule
in class Director
public boolean isStrict() throws IllegalActionException
isStrict
in interface Executable
isStrict
in class Director
IllegalActionException
- Not thrown in this base class.public Receiver newReceiver()
newReceiver
in class Director
public boolean postfire() throws IllegalActionException
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.
postfire
in interface Executable
postfire
in class Director
IllegalActionException
- If thrown by any commit action or there is no controller.public void preinitialize() throws IllegalActionException
preinitialize
in interface Initializable
preinitialize
in class Director
IllegalActionException
- If a contained refinement
does not have a director.public boolean prefire() throws IllegalActionException
prefire
in interface Executable
prefire
in class Director
IllegalActionException
- If there is no controller.public void resetOutputReceivers() throws IllegalActionException
IllegalActionException
- If there is no mode
controller, or can not find refinements for states or if
getting the receivers fails.public void setContainer(NamedObj container) throws IllegalActionException, NameDuplicationException
setContainer
in class Director
container
- The proposed container.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.Attribute.getContainer()
public void setIndex(int index) throws IllegalActionException
setIndex
in interface SuperdenseTimeDirector
index
- The index of the superdense time object.
Events that occur at the same time have different indicies.IllegalActionException
- Not thrown in this base class.getIndex()
,
SuperdenseTimeDirector
public boolean transferInputs(IOPort port) throws IllegalActionException
transferInputs
in class Director
port
- The input port to transfer tokens from.IllegalActionException
- If the port is not an opaque input port.protected void _buildLocalReceiverMaps() throws IllegalActionException
IllegalActionException
- If there is no mode controller, or can not find refinements for states.protected Receiver[][] _currentLocalReceivers(IOPort port) throws IllegalActionException
port
- An input port of the container of this director.IllegalActionException
- If there is no controller.protected java.util.Map<State,Transition> _getLastChosenTransition() throws IllegalActionException
IllegalActionException
- If there is no controller.protected java.util.List<Actor> _getStateRefinementsToPostfire() throws IllegalActionException
IllegalActionException
- If can't get the controller.protected java.util.List<Actor> _getTransitionRefinementsToPostfire() throws IllegalActionException
IllegalActionException
- If can't get the controller.protected void _readInputs() throws IllegalActionException
IllegalActionException
- If a shadow variable cannot take the token read from its corresponding channel
(should not occur).protected void _readOutputsFromRefinement() throws IllegalActionException
IllegalActionException
- If a shadow variable cannot take the token read from its corresponding channel
(should not occur).protected void _setCurrentConnectionMap() throws IllegalActionException
IllegalActionException
- If the refinement specified
for one of the states is not valid, or if there
is no controller.protected void _setCurrentState(State state) throws IllegalActionException
state
- The state to set.IllegalActionException
- If there is no controller.protected boolean _transferOutputs(IOPort port) throws IllegalActionException
_transferOutputs
in class Director
port
- The port to transfer tokens from.IllegalActionException
- If the port is not an opaque output port.