Class QSSIntegrator

  • All Implemented Interfaces:
    java.lang.Cloneable, DerivativeFunction, Actor, Executable, FiringsRecordable, Initializable, TypedActor, Changeable, Debuggable, DebugListener, Derivable, Instantiable, ModelErrorHandler, MoMLExportable, Moveable, Nameable

    public class QSSIntegrator
    extends TypedAtomicActor
    implements DerivativeFunction
    A quantized-state integrator. This integrator is designed to integrate continuous-time signals under the 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:

    1. QSS1: The input u is assumed to be piecewise constant.
    2. QSS2: The input u is assumed to be piecewise linear.
    3. QSS3: The input u is assumed to be piecewise quadratic.
    An input token can be instance of 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.

    Since:
    Ptolemy II 11.0
    Version:
    $Id$
    Author:
    Edward A. Lee, Thierry Nouidui, Michael Wetter, Mehrdad Niknami
    See Also:
    QSSDirector
    Pt.AcceptedRating:
    Red (cxh)
    Pt.ProposedRating:
    Yellow (eal)
    • Field Detail

      • absoluteQuantum

        public Parameter absoluteQuantum
        If specified, the minimum quantum for this integrator. This is a double, and by default is not given, which means that the quantum is specified by the director.
      • exactInputs

        public Parameter exactInputs
        Indicator of whether the inputs are exact. Set this to true if the inputs to this integrator specify all non-zero derivatives. That is, if the input is a DoubleToken, this should be interpreted as a piecewise-constant input. If it is SmoothToken, then all non-zero derivatives are given as part of the token. This is a boolean that defaults to false.
      • impulse

        public TypedIOPort impulse
        The impulse input port. This is a single port of type double. If any derivatives are provided on this port via a SmoothToken, they are ignored.
      • q

        public TypedIOPort q
        Output (the quantized state).
      • propagateInputDerivatives

        public 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. If false, then no derivative information is provided on the output (the output is assumed to be piecewise constant), and outputs are produced only when the integral has changed enough to trigger a quantization event.
      • relativeQuantum

        public Parameter relativeQuantum
        If specified, the relative quantum for this integrator. If the value here is greater than zero, then the quantum that this integrator uses will be the larger of the 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.
      • solver

        public StringParameter solver
        The class name of the QSS solver used for integration. This is a string that defaults to the empty string, which delegates the choice to the director.
      • xInit

        public Parameter xInit
        Initial value of the state.
    • Method Detail

      • attributeChanged

        public void attributeChanged​(Attribute attribute)
                              throws IllegalActionException
        Notify this actor that the specified attribute has changed. If the attribute is propagateInputDerivatives, then notify the director that the schedule is now invalid.
        Overrides:
        attributeChanged in class NamedObj
        Parameters:
        attribute - The attribute that changed.
        Throws:
        IllegalActionException - If there is problem handling the parameter.
      • evaluateDerivatives

        public int evaluateDerivatives​(Time time,
                                       double[] dtSample,
                                       double[] xdot,
                                       double[] xdotSample,
                                       double[] xdotSample2,
                                       int stOrd)
                                throws IllegalActionException
        Evaluate the derivative function for event detection. Ignored in this base class.
        Specified by:
        evaluateDerivatives in interface DerivativeFunction
        Parameters:
        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.
        Returns:
        Success (0 for success, else user-defined error code).
        Throws:
        IllegalActionException - If derivatives cannot be evaluated.
      • evaluateDerivatives

        public int evaluateDerivatives​(Time time,
                                       double[] xx,
                                       double[] uu,
                                       double[] xdot)
                                throws IllegalActionException
        Set the derivative equal to the input.
        Specified by:
        evaluateDerivatives in interface DerivativeFunction
        Parameters:
        time - The time.
        xx - The values.
        uu - The derivatives.
        xdot - The input, which is set to the value of the derivatives.
        Returns:
        Success (0 for success, else user-defined error code).
        Throws:
        IllegalActionException - Not thrown in this base class.
      • evaluateDirectionalDerivatives

        public double evaluateDirectionalDerivatives​(int index,
                                                     double[] xx_dot,
                                                     double[] uu_dot)
                                              throws IllegalActionException
        Return 0. This actor does not provide directional derivatives.
        Specified by:
        evaluateDirectionalDerivatives in interface DerivativeFunction
        Parameters:
        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.
        Returns:
        0.
        Throws:
        IllegalActionException - Not thrown in this base class.
      • eventIndicatorDerivativeInputs

        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
        Evaluate input for event indicators derivative. Ignored in this base class.
        Specified by:
        eventIndicatorDerivativeInputs in interface DerivativeFunction
        Parameters:
        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.
        Returns:
        Success (0 for success, else user-defined error code).
        Throws:
        IllegalActionException - If derivatives cannot be evaluated.
      • fire

        public void fire()
                  throws IllegalActionException
        If it is time to produce a quantized output (there is a quantization event), produce it. Otherwise, indicate that the output is absent. Also produce an output if an impulse event is received and if this is the first firing at initialization time. If propagateInputDerivatives is true, then at the next microstep this actor will fire again. The input value (and any derivatives it provides) will be provided on the output as the derivative (and any higher-order derivatives) of the output.
        Specified by:
        fire in interface Executable
        Overrides:
        fire in class AtomicActor<TypedIOPort>
        Throws:
        IllegalActionException - If sending an output fails.
      • getInputVariableCount

        public int getInputVariableCount()
        Return 1, because this actor always has one input variable, which specifies that value of the derivative.
        Specified by:
        getInputVariableCount in interface DerivativeFunction
        Returns:
        1.
      • getProvidesDirectionalDerivatives

        public boolean getProvidesDirectionalDerivatives()
        Return false, as this actor does not provide directional derivatives. FIXME: What is a directional derivative?
        Specified by:
        getProvidesDirectionalDerivatives in interface DerivativeFunction
        Returns:
        False.
      • getStateCount

        public int getStateCount()
        Return 1, as there is one state variable.
        Specified by:
        getStateCount in interface DerivativeFunction
        Returns:
        1.
      • propagatesInputDerivatives

        public boolean propagatesInputDerivatives()
                                           throws IllegalActionException
        Return the value of the propagateInputDerivatives parameter.
        Returns:
        the value of the propagateInputDerivatives parameter.
        Throws:
        IllegalActionException - If the propagateInputDerivatives parameter cannot be read.
      • isStrict

        public boolean isStrict()
        Description copied from class: AtomicActor
        Return true unless all input ports have non-empty default values. By default, most actors do not check their inputs to see whether they are known. They assume they are known. Note that ParameterPort is not treated as having a default value because such ports might be used in a context where it is important to supply them with an input value.
        Specified by:
        isStrict in interface Executable
        Overrides:
        isStrict in class AtomicActor<TypedIOPort>
        Returns:
        False if this actor does not need to be provided with inputs to fire.