public class QSSIntegrator extends TypedAtomicActor implements DerivativeFunction
QSSDirector
. The input events indicate significant changes in the input
signal, and output events indicate significant changes in the output signal.
The value of the input signal is the derivative of the output.
Here "significant" means that the signal has changed by more than the specified
quantum, as defined by the selected solver, explained in detail below.
Three types of solvers are provided:
DoubleToken
or SmoothToken
,
the latter of which potentially carries
not only a value at q time, but also zero or more derivatives
of the input signal at that time. To provide a piecewise linear input to a
QSS2 integrator, for example, you can specify an input with the expression
smoothToken(2.0, {1.0}), which specifies a value of 2.0 and a first
derivative of 1.0. All other derivatives are assumed to be zero.
A QSS1 integrator will ignore all derivatives on the input.
A QSS2 integrator will ignore all but the first derivative on the input.
A QSS3 integrator will ignore all but the first and second derivatives on the input.
If a DoubleToken
is provided on the input, then all derivatives of the input
are assumed to be zero.
This integrator has two modes of operation, depending on the value of propagateInputDerivatives. In both modes, the integrator will produce an output whenever a quantization event occurs. For QSS1, a quantization event occurs when the state of the integrator changes by the quantum (see below for an explanation of the quantum). For example, if the input is a constant 1.0 and the quantum is 0.1, then an output will be produced every 0.1 seconds, because the input specifies that the state has slope 1.0, so it will increase by the quantum every 0.1 seconds. For QSS2, a quantization event occurs when the derivative of the state changes by the quantum. For example, if the input is piecewise linear with initial value 0.0 and first derivative 1.0 and the state has initial value 0.0, then at the start, the state has value 0.0, first derivative 0.0, and second derivative 1.0. Because of the second derivative, as time elapses, the first derivative of the state will increase. When it increases by the quantum, an output will be produced. For QSS3, a quantization event occurs when the second derivative changes by the quantum in a similar fashion.
Also, in both modes of operation, the integrator will produce an output whenever it is initialized, and whenever it receives an impulse input event.
When an output is produced, its value will be the current state of the integrator. In addition, depending on the solver, it may contain derivative information. For QSS1, the input is semantically piecewise constant, so the output is piecewise linear; hence each output event will be a SmoothToken that is piecewise linear, with a first derivative equal to the most recently received input value. For QSS2, the output will have a first and second derivative obtained from the input. For QSS3, the output will have first, second, and third derivatives.
We can now explain how the two modes of operation differ. If propagateInputDerivatives is set to true (the default), then this integrator will also produce an output every time it receives an input, at the following microstep. Each output will include derivative information from the input, to the extent that these are appropriate for the solver.
If propagateInputDerivatives is set to false, then output is not produced only when quantization events occur, when the integrator is initialized, and when the impulse port receives an event. In this case, there is no direct dependence between the u input and the output, and hence there is no difficulty putting this integrator in a feedback loop. The price paid, however, is that downstream actors do not get immediately informed of changes in the derivatives of the output. They will learn of these changes when the next quantization event occurs. To see an example of the consequences, see the demo $PTII/ptolemy/domains/qss/demo/HelloWorld/HelloWorld_Propagate.xml.
The frequency with which the output q of this integrator is produced depends on the solver choice and the absoluteQuantum and relativeQuantum parameter values. These determine when a quantization event occurs, as explained above. The quantum is equal to the larger of absoluteQuantum and the product of relativeQuantum and the current state value. The simplest case is where the solver is QSS1 and relativeQuantum is zero. In this case, a quantization event occurs whenever the integral of the input signal changes by the absoluateQuantum. For QSS1, the input is assumed to be piecewise constant. If the input is a SmoothToken, the derivatives of the input are ignored.
On the first firing at initialization time, the output value is given by xInit. That initial value can be a SmoothToken (expressed as smoothToken(value, {array of derivatives}).
When an impulse input is received, the value of that event is added to the current state of this integrator (any derivatives provided on the impulse input are ignored). Then an output event is produced and the integrator is reinitialized so that the next output quantum is relative to the new state value.
Note that in most cases, this actor outputs a SmoothToken.
(The only exception is at initialization, where xInit is produced;
it may not be a SmoothToken.)
A SmoothToken has that property that any downstream
actor can read the signal at any time, and the value will
be extrapolated to the time of the read automatically, regardless of whether
the source of the SmoothToken has produced an output at that time.
Thus, the outputs of this integrator only need to occur
explicitly when something interesting has changed that would make such prediction invalid.
Even though the signal contains only infrequent events, a downstream actor can read
the values frequently, for example to generate more representative plots of
the signal.
If want downstream actors to see only the actual events produced by this
integrator, then you can feed the output into an instance of SmoothToDouble
.
FIXME: To do: - Make xInit a PortParameter. - Make a vector version.
QSSDirector
Entity.ContainedObjectsIterator
Modifier and Type | Field and Description |
---|---|
Parameter |
absoluteQuantum
If specified, the minimum quantum for this integrator.
|
Parameter |
exactInputs
Indicator of whether the inputs are exact.
|
TypedIOPort |
impulse
The impulse input port.
|
Parameter |
propagateInputDerivatives
If true (the default), then derivative information from the input will be
produced on the outputs, and an output will be produced whenever
an input is received.
|
TypedIOPort |
q
Output (the quantized state).
|
Parameter |
relativeQuantum
If specified, the relative quantum for this integrator.
|
StringParameter |
solver
The class name of the QSS solver used for integration.
|
TypedIOPort |
u
Input (the derivative).
|
Parameter |
xInit
Initial value of the state.
|
_typesValid
_actorFiringListeners, _initializables, _notifyingActorFiring, _stopRequested
_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 |
---|
QSSIntegrator(CompositeEntity container,
java.lang.String name)
Construct a new instance of this integrator.
|
Modifier and Type | Method and Description |
---|---|
void |
attributeChanged(Attribute attribute)
Notify this actor that the specified attribute has changed.
|
int |
evaluateDerivatives(Time time,
double[] xx,
double[] uu,
double[] xdot)
Set the derivative equal to the input.
|
int |
evaluateDerivatives(Time time,
double[] dtSample,
double[] xdot,
double[] xdotSample,
double[] xdotSample2,
int stOrd)
Evaluate the derivative function for event detection.
|
double |
evaluateDirectionalDerivatives(int index,
double[] xx_dot,
double[] uu_dot)
Return 0.
|
int |
eventIndicatorDerivativeInputs(Time time,
double[] xx,
double[] uu,
Time timeSample,
double[] xxSample,
double[] uuSample,
double dtSample,
Time timeSample2,
double[] xxSample2,
double[] uuSample2,
double dtSample2,
Time timeSample3,
double[] xxSample3,
double[] uuSample3,
double dtSample3,
Time timeSample4,
double[] xxSample4,
double[] uuSample4,
double dtSample4,
Time timeSample5,
double[] xxSample5,
double[] uuSample5,
double dtSample5,
int stateModelOrder)
Evaluate input for event indicators derivative.
|
void |
fire()
If it is time to produce a quantized output (there is a quantization event), produce it.
|
CausalityInterface |
getCausalityInterface()
Override the base class to return a causality interface that breaks causality.
|
int |
getEventIndicatorCount()
Return the number of event indicators.
|
int |
getInputVariableCount()
Return 1, because this actor always has one input variable,
which specifies that value of the derivative.
|
boolean |
getProvidesDirectionalDerivatives()
Return false, as this actor does not provide directional derivatives.
|
int |
getStateCount()
Return 1, as there is one state variable.
|
void |
initialize()
Initialize this actor to indicate that no input has yet been provided.
|
boolean |
isStrict()
Return true unless all input ports have non-empty default values.
|
boolean |
postfire()
Update the calculation of the next output time and request
a refiring at that time.
|
boolean |
propagatesInputDerivatives()
Return the value of the propagateInputDerivatives parameter.
|
_containedTypeConstraints, _customTypeConstraints, _defaultTypeConstraints, _fireAt, _fireAt, attributeTypeChanged, clone, clone, isBackwardTypeInferenceEnabled, newPort, typeConstraintList, typeConstraints
_actorFiring, _actorFiring, _declareDelayDependency, addActorFiringListener, addInitializable, connectionsChanged, createReceivers, declareDelayDependency, getDirector, getExecutiveDirector, getManager, inputPortList, isFireFunctional, iterate, newReceiver, outputPortList, prefire, preinitialize, pruneDependencies, recordFiring, removeActorFiringListener, removeDependency, removeInitializable, setContainer, stop, stopFire, terminate, wrapup
_adjustDeferrals, _checkContainer, _getContainedObject, _propagateExistence, getContainer, instantiate, isAtomic, isOpaque, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, propagateExistence, setName
_addPort, _description, _exportMoMLContents, _removePort, _validateSettables, connectedPortList, connectedPorts, containedObjectsIterator, getAttribute, getPort, getPorts, linkedRelationList, linkedRelations, portList, removeAllPorts, setClassDefinition, uniqueName
_setParent, exportMoML, getChildren, getElementName, getParent, getPrototypeList, isClassDefinition, isWithinClassDefinition
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _containedDecorators, _copyChangeRequestList, _debug, _debug, _debug, _debug, _debug, _executeChangeRequests, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _notifyHierarchyListenersAfterChange, _notifyHierarchyListenersBeforeChange, _propagateValue, _removeAttribute, _splitName, _stripNumericSuffix, addChangeListener, addDebugListener, addHierarchyListener, attributeDeleted, attributeList, attributeList, decorators, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getFullName, getModelErrorHandler, getName, getName, getSource, handleModelError, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, notifyOfNameChange, propagateValue, propagateValues, removeAttribute, removeChangeListener, removeDebugListener, removeHierarchyListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, validateSettables, workspace
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
createReceivers, getDirector, getExecutiveDirector, getManager, inputPortList, newReceiver, outputPortList
isFireFunctional, iterate, prefire, stop, stopFire, terminate
addInitializable, preinitialize, removeInitializable, wrapup
description, getContainer, getDisplayName, getFullName, getName, getName, setName
getDerivedLevel, getDerivedList, propagateValue
public Parameter absoluteQuantum
public Parameter exactInputs
public TypedIOPort impulse
public TypedIOPort q
public Parameter propagateInputDerivatives
public Parameter relativeQuantum
absoluteQuantum
and |x| * relativeQuantum,
where x is the current value of the state.
This is a double that defaults to be empty (nothing
specified), which causes the relativeQuantum to be
retrieved from the director.public StringParameter solver
public TypedIOPort u
public Parameter xInit
public QSSIntegrator(CompositeEntity container, java.lang.String name) throws IllegalActionException, NameDuplicationException
container
- The container.name
- The name.IllegalActionException
- If setting up ports and parameters fails.NameDuplicationException
- If the container already contains an object with this name.public void attributeChanged(Attribute attribute) throws IllegalActionException
attributeChanged
in class NamedObj
attribute
- The attribute that changed.IllegalActionException
- If there is problem handling
the parameter.public int evaluateDerivatives(Time time, double[] dtSample, double[] xdot, double[] xdotSample, double[] xdotSample2, int stOrd) throws IllegalActionException
evaluateDerivatives
in interface DerivativeFunction
time
- Simulation time.dtSample
- An array of samples over time.xdot
- The vector of time rates of change of the state variables at time
.xdotSample
- The vector of time rates of change of the state variables at a sample time.xdotSample2
- The vector of time rates of change of the state variables at a sample time.stOrd
- The stOrd.IllegalActionException
- If derivatives cannot be evaluated.public int evaluateDerivatives(Time time, double[] xx, double[] uu, double[] xdot) throws IllegalActionException
evaluateDerivatives
in interface DerivativeFunction
time
- The time.xx
- The values.uu
- The derivatives.xdot
- The input, which is set to the value of the derivatives.IllegalActionException
- Not thrown in this base class.public double evaluateDirectionalDerivatives(int index, double[] xx_dot, double[] uu_dot) throws IllegalActionException
evaluateDirectionalDerivatives
in interface DerivativeFunction
index
- The index. Ignored in this base class.xx_dot
- The values. Ignored in this base class.uu_dot
- The derivatives. Ignored in this base class.IllegalActionException
- Not thrown in this base class.public int eventIndicatorDerivativeInputs(Time time, double[] xx, double[] uu, Time timeSample, double[] xxSample, double[] uuSample, double dtSample, Time timeSample2, double[] xxSample2, double[] uuSample2, double dtSample2, Time timeSample3, double[] xxSample3, double[] uuSample3, double dtSample3, Time timeSample4, double[] xxSample4, double[] uuSample4, double dtSample4, Time timeSample5, double[] xxSample5, double[] uuSample5, double dtSample5, int stateModelOrder) throws IllegalActionException
eventIndicatorDerivativeInputs
in interface DerivativeFunction
time
- Simulation time.xx
- The vector of state variables at time
.uu
- The vector of input variables at time
.timeSample
- Simulation time.xxSample
- The vector of state variables at timeSample
.uuSample
- The vector of input variables at timeSample
.dtSample
- The delta between timeSample and time
.timeSample2
- Simulation time.xxSample2
- The vector of state variables at timeSample2
.uuSample2
- The vector of input variables at timeSample2
.dtSample2
- The delta between timeSample2 and time
.timeSample3
- Simulation time.xxSample3
- The vector of state variables at timeSample3
.uuSample3
- The vector of input variables at timeSample3
.dtSample3
- The delta between timeSample3 and time
.timeSample4
- Simulation time.xxSample4
- The vector of state variables at timeSample4
.uuSample4
- The vector of input variables at timeSample4
.dtSample4
- The delta between timeSample4 and time
.timeSample5
- Simulation time.xxSample5
- The vector of state variables at timeSample5
.uuSample5
- The vector of input variables at timeSample5
.dtSample5
- The delta between timeSample5 and time
.
variables at time
.stateModelOrder
- The state model order.IllegalActionException
- If derivatives cannot be evaluated.public void fire() throws IllegalActionException
fire
in interface Executable
fire
in class AtomicActor<TypedIOPort>
IllegalActionException
- If sending an output fails.public CausalityInterface getCausalityInterface() throws IllegalActionException
getCausalityInterface
in interface Actor
getCausalityInterface
in class AtomicActor<TypedIOPort>
IllegalActionException
- Thrown in subclasses if causality
interface cannot be computed.public int getEventIndicatorCount()
getEventIndicatorCount
in interface DerivativeFunction
public int getInputVariableCount()
getInputVariableCount
in interface DerivativeFunction
public boolean getProvidesDirectionalDerivatives()
getProvidesDirectionalDerivatives
in interface DerivativeFunction
public int getStateCount()
getStateCount
in interface DerivativeFunction
public void initialize() throws IllegalActionException
initialize
in interface Initializable
initialize
in class AtomicActor<TypedIOPort>
IllegalActionException
- If a derived class throws it.public boolean propagatesInputDerivatives() throws IllegalActionException
IllegalActionException
- If the
propagateInputDerivatives parameter cannot be read.public boolean isStrict()
AtomicActor
isStrict
in interface Executable
isStrict
in class AtomicActor<TypedIOPort>
public boolean postfire() throws IllegalActionException
postfire
in interface Executable
postfire
in class AtomicActor<TypedIOPort>
IllegalActionException
- If reading inputs or parameters fails.