Class ModelPredictiveController

java.lang.Object
neqsim.util.NamedBaseClass
neqsim.process.controllerdevice.ModelPredictiveController
All Implemented Interfaces:
Serializable, ControllerDeviceInterface, NamedInterface

public class ModelPredictiveController extends NamedBaseClass implements ControllerDeviceInterface
General-purpose model predictive controller (MPC) for NeqSim process equipment.

The controller supports both single-input operation and multivariable configurations with linear quality constraints. A first-order discrete process model is used internally to predict the future trajectory of the controlled variable across a configurable prediction horizon. The controller minimises a quadratic objective consisting of tracking error, absolute control effort and control movement. The optimal actuation is calculated analytically which keeps the implementation dependency free while still representing a full MPC formulation.

In addition to the control formulation the implementation exposes a receding horizon (moving horizon) estimation routine. The estimator reuses the same first-order model to identify the process gain, time constant and bias from historical measurement and actuation data. This allows automatic tuning of the internal model parameters when operating on real process data without requiring external optimisation packages.

See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      See Also:
    • MIN_ESTIMATION_SAMPLES

      private static final int MIN_ESTIMATION_SAMPLES
      See Also:
    • transmitter

      private MeasurementDeviceInterface transmitter
    • controllerSetPoint

      private double controllerSetPoint
    • unit

      private String unit
    • reverseActing

      private boolean reverseActing
    • isActive

      private boolean isActive
    • response

      private double response
    • minResponse

      private double minResponse
    • maxResponse

      private double maxResponse
    • minMove

      private double minMove
    • maxMove

      private double maxMove
    • processGain

      private double processGain
    • timeConstant

      private double timeConstant
    • processBias

      private double processBias
    • predictionHorizon

      private int predictionHorizon
    • outputWeight

      private double outputWeight
    • controlWeight

      private double controlWeight
    • moveWeight

      private double moveWeight
    • preferredControlValue

      private double preferredControlValue
    • calcIdentifier

      private UUID calcIdentifier
    • lastSampledValue

      private double lastSampledValue
    • lastSampleTime

      private double lastSampleTime
    • lastAppliedControl

      private double lastAppliedControl
    • controlNames

      private final List<String> controlNames
    • controlVector

      private double[] controlVector
    • lastControlVector

      private double[] lastControlVector
    • minControlVector

      private double[] minControlVector
    • maxControlVector

      private double[] maxControlVector
    • minControlMoveVector

      private double[] minControlMoveVector
    • maxControlMoveVector

      private double[] maxControlMoveVector
    • preferredControlVector

      private double[] preferredControlVector
    • controlWeightsVector

      private double[] controlWeightsVector
    • moveWeightsVector

      private double[] moveWeightsVector
    • primaryControlIndex

      private int primaryControlIndex
    • qualityConstraints

      private final List<ModelPredictiveController.QualityConstraint> qualityConstraints
    • lastFeedComposition

      private Map<String,Double> lastFeedComposition
    • pendingFeedComposition

      private Map<String,Double> pendingFeedComposition
    • lastFeedRate

      private double lastFeedRate
    • pendingFeedRate

      private double pendingFeedRate
    • feedInitialised

      private boolean feedInitialised
    • predictedQualityValues

      private final Map<String,Double> predictedQualityValues
    • movingHorizonEstimationEnabled

      private boolean movingHorizonEstimationEnabled
    • movingHorizonWindow

      private int movingHorizonWindow
    • estimationMeasurements

      private final List<Double> estimationMeasurements
    • estimationControls

      private final List<Double> estimationControls
    • estimationSampleTimes

      private final List<Double> estimationSampleTimes
    • lastMovingHorizonEstimate

      private ModelPredictiveController.MovingHorizonEstimate lastMovingHorizonEstimate
  • Constructor Details

    • ModelPredictiveController

      public ModelPredictiveController()
      Default constructor assigning a generic name.
    • ModelPredictiveController

      public ModelPredictiveController(String name)
      Construct an MPC controller with a specific name.
      Parameters:
      name - controller name
  • Method Details

    • configureControls

      public final void configureControls(String... names)
      Configure the set of manipulated variables handled by the MPC. Existing quality constraints are cleared because their sensitivity dimensions may no longer match the new set of controls.
      Parameters:
      names - ordered list of control names (e.g. pressure, temperature)
    • ensureControlLength

      private void ensureControlLength(int expectedLength)
    • ensureControlIndex

      private void ensureControlIndex(int index)
    • setInitialControlValues

      public void setInitialControlValues(double... values)
      Specify the starting values of all manipulated variables.
      Parameters:
      values - control vector in the configured order
    • setPrimaryControlIndex

      public void setPrimaryControlIndex(int index)
      Choose which control variable is exposed via getResponse() to maintain compatibility with the ControllerDeviceInterface.
      Parameters:
      index - index of the primary control variable
    • setControlLimits

      public void setControlLimits(int index, double min, double max)
      Set lower and upper bounds for a control variable.
      Parameters:
      index - control index
      min - minimum allowed value (may be Double.NEGATIVE_INFINITY)
      max - maximum allowed value (may be Double.POSITIVE_INFINITY)
    • setControlMoveLimits

      public void setControlMoveLimits(int index, double minDelta, double maxDelta)
      Constrain the permitted change of a control variable relative to the previously applied value. Limits are interpreted as minDelta <= u - u_prev <= maxDelta.
      Parameters:
      index - control index
      minDelta - minimum permitted change (may be Double.NEGATIVE_INFINITY)
      maxDelta - maximum permitted change (may be Double.POSITIVE_INFINITY)
    • setControlMoveLimits

      public void setControlMoveLimits(String controlName, double minDelta, double maxDelta)
      Convenience overload to configure move limits by control name.
      Parameters:
      controlName - name of the control variable
      minDelta - minimum permitted change
      maxDelta - maximum permitted change
    • setControlLimits

      public void setControlLimits(String controlName, double min, double max)
      Convenience overload allowing limits to be set by control name.
      Parameters:
      controlName - name of the control variable
      min - minimum allowed value
      max - maximum allowed value
    • setControlWeights

      public void setControlWeights(double... weights)
      Set quadratic weights on the absolute value of each control variable. Values must be non-negative.
      Parameters:
      weights - absolute control weights
    • setMoveWeights

      public void setMoveWeights(double... weights)
      Set quadratic penalty on control moves for each variable.
      Parameters:
      weights - move weights
    • setPreferredControlVector

      public void setPreferredControlVector(double... references)
      Define the preferred steady-state operating point for each control variable. This represents the control vector that minimises the absolute control penalty when no tracking error is present.
      Parameters:
      references - preferred control levels
    • setEnergyReferenceVector

      @Deprecated public void setEnergyReferenceVector(double... references)
      Deprecated.
      Use setPreferredControlVector(double...) to configure the nominal control point. This method is retained for backwards compatibility with earlier snapshots of the MPC implementation.
      Parameters:
      references - preferred control levels for the energy terms
    • getControlNames

      public List<String> getControlNames()
      Retrieve the ordered list of configured control names.
      Returns:
      unmodifiable list of control names
    • getControlValue

      public double getControlValue(String controlName)
      Get the latest control value by name.
      Parameters:
      controlName - name of control variable
      Returns:
      value of the control variable
    • getControlValue

      public double getControlValue(int index)
      Get the latest control value by index.
      Parameters:
      index - control index
      Returns:
      value of the control variable
    • getControlVector

      public double[] getControlVector()
      Copy of the current control vector.
      Returns:
      current control vector
    • addQualityConstraint

      public void addQualityConstraint(ModelPredictiveController.QualityConstraint constraint)
      Register a new quality constraint. The sensitivity vector must match the number of configured controls.
      Parameters:
      constraint - quality constraint description
    • clearQualityConstraints

      public void clearQualityConstraints()
      Clear all registered quality constraints.
    • updateQualityMeasurement

      public boolean updateQualityMeasurement(String name, double measurement)
      Update the stored measurement for a named quality constraint. When integrating against a live plant this allows the MPC to use the latest analyser or laboratory sample even if the simulation does not contain a dedicated MeasurementDeviceInterface. The value is stored in the controller and will be used as the baseline for the next optimisation step.
      Parameters:
      name - quality constraint identifier
      measurement - measured specification value in the constraint unit
      Returns:
      true if the constraint was found and updated
    • updateQualityMeasurements

      public void updateQualityMeasurements(Map<String,Double> measurements)
      Convenience method to update multiple quality-constraint measurements in one call.
      Parameters:
      measurements - mapping of constraint name to measured value
    • updateFeedConditions

      public void updateFeedConditions(Map<String,Double> composition, double feedRate)
      Update the predicted incoming feed composition and flow rate. The values are used as feedforward information in the MPC optimisation.
      Parameters:
      composition - component molar fractions (will be normalised outside the method)
      feedRate - molar feed rate
    • getPredictedQuality

      public double getPredictedQuality(String name)
      Get the last predicted quality value produced by the controller for a named constraint.
      Parameters:
      name - constraint name
      Returns:
      predicted value or Double.NaN if unavailable
    • enableMovingHorizonEstimation

      public void enableMovingHorizonEstimation(int windowSize)
      Enable moving horizon (receding horizon) estimation of the internal first-order process model. The estimator analyses the most recent samples of measured output and applied control to update the process gain, time constant and bias.
      Parameters:
      windowSize - number of recent samples to keep in the estimation window (minimum of 5)
    • disableMovingHorizonEstimation

      public void disableMovingHorizonEstimation()
      Disable the moving horizon estimation routine. Existing history and the last estimate are retained so the method can be re-enabled later.
    • isMovingHorizonEstimationEnabled

      public boolean isMovingHorizonEstimationEnabled()
      Check whether moving horizon estimation is currently enabled.
      Returns:
      true when the estimator is active
    • getMovingHorizonEstimationWindow

      public int getMovingHorizonEstimationWindow()
      Get the number of samples kept in the moving horizon estimation window.
      Returns:
      window length
    • clearMovingHorizonHistory

      public void clearMovingHorizonHistory()
      Remove any stored estimation samples. The last estimate is cleared to make it explicit that a new identification cycle is required before accessing estimation results again.
    • getLastMovingHorizonEstimate

      public ModelPredictiveController.MovingHorizonEstimate getLastMovingHorizonEstimate()
      Retrieve the latest moving horizon estimate. The result contains the identified model parameters along with a simple mean squared prediction error. null is returned until the estimator has processed a sufficient number of samples.
      Returns:
      most recent estimate or null when unavailable
    • autoTune

      Automatically identify the internal first-order process model and configure the MPC weights using the most recent moving-horizon estimation history. The controller must have collected at least 5 valid samples via enableMovingHorizonEstimation(int) before invoking auto-tune.
      Returns:
      tuning result containing the identified parameters and applied configuration
    • autoTune

      Automatically identify the internal first-order process model and configure the MPC weights using the most recent moving-horizon estimation history.
      Parameters:
      configuration - optional tuning configuration; if null the default configuration is used
      Returns:
      tuning result containing the identified parameters and applied configuration
    • autoTune

      public ModelPredictiveController.AutoTuneResult autoTune(List<Double> measurements, List<Double> controls, List<Double> sampleTimes, ModelPredictiveController.AutoTuneConfiguration configuration)
      Auto-tune the controller using explicitly supplied measurement and actuation samples. This is useful when historical process data has been collected outside of the live controller instance. The provided lists must follow the same structure as the moving-horizon estimator where measurements.size() == controls.size() + 1 and sampleTimes.size() == controls.size().
      Parameters:
      measurements - ordered list of measured process values
      controls - ordered list of control signals that produced the subsequent measurements
      sampleTimes - sampling intervals between consecutive measurements (seconds)
      configuration - optional tuning configuration
      Returns:
      tuning result containing the identified parameters and applied configuration
    • autoTuneFromEstimate

    • setProcessModel

      public void setProcessModel(double gain, double timeConstant)
      Configure the internal first order process model.
      Parameters:
      gain - steady-state process gain relating control action to the measured variable
      timeConstant - dominant time constant of the process model (seconds)
    • setProcessModel

      public void setProcessModel(double gain, double timeConstant, double deadTimeSeconds)
      Configure the internal first order process model including dead time. Dead time is represented as an equivalent time constant increase because the simplified controller does not maintain an explicit delay line.
      Parameters:
      gain - steady-state process gain relating control action to the measured variable
      timeConstant - dominant time constant of the process model (seconds)
      deadTimeSeconds - estimated dead time (seconds)
    • setProcessBias

      public void setProcessBias(double bias)
      Set the steady-state bias of the process model. The bias corresponds to the measured value when the manipulated variable is zero (for example ambient temperature).
      Parameters:
      bias - process bias value
    • setWeights

      public void setWeights(double outputWeight, double controlWeight, double moveWeight)
      Set quadratic weights for output tracking, absolute control effort and control movement.
      Parameters:
      outputWeight - weight on future tracking error
      controlWeight - weight on absolute control magnitude (e.g. energy/emission usage)
      moveWeight - weight on control movements between successive time steps
    • setPreferredControlValue

      public void setPreferredControlValue(double reference)
      Specify the preferred steady-state control level for the single-input MPC mode. This value represents the operating point that minimises the absolute control penalty when tracking is not active.
      Parameters:
      reference - preferred control level
    • setMoveLimits

      public void setMoveLimits(double minDelta, double maxDelta)
      Limit the change of the single-input MPC output relative to the previously applied value.
      Parameters:
      minDelta - minimum allowed change (may be Double.NEGATIVE_INFINITY)
      maxDelta - maximum allowed change (may be Double.POSITIVE_INFINITY)
    • setEnergyReference

      @Deprecated public void setEnergyReference(double reference)
      Deprecated.
      Use setPreferredControlValue(double) when configuring the MPC economic target. This method is kept for compatibility with earlier code samples.
      Parameters:
      reference - preferred steady-state control value for the single-input controller
    • setPredictionHorizon

      public void setPredictionHorizon(int horizon)
      Set the number of future steps used when predicting the controlled variable trajectory.
      Parameters:
      horizon - prediction horizon length
    • getLastSampledValue

      public double getLastSampledValue()
      Retrieve the last sampled process value. Mainly intended for diagnostics and testing.
      Returns:
      last measured value
    • getLastAppliedControl

      public double getLastAppliedControl()
      Retrieve the last applied control signal.
      Returns:
      last actuation sent to the process
    • getMeasuredValue

      public double getMeasuredValue()
      Description copied from interface: ControllerDeviceInterface

      getMeasuredValue.

      Specified by:
      getMeasuredValue in interface ControllerDeviceInterface
      Returns:
      a double
    • getMeasuredValue

      public double getMeasuredValue(String unit)
      Description copied from interface: ControllerDeviceInterface

      getMeasuredValue.

      Specified by:
      getMeasuredValue in interface ControllerDeviceInterface
      Parameters:
      unit - a String object
      Returns:
      a double
    • setControllerSetPoint

      public void setControllerSetPoint(double signal)
      Description copied from interface: ControllerDeviceInterface

      setControllerSetPoint.

      Specified by:
      setControllerSetPoint in interface ControllerDeviceInterface
      Parameters:
      signal - a double
    • getControllerSetPoint

      public double getControllerSetPoint()
      Description copied from interface: ControllerDeviceInterface

      getControllerSetPoint.

      Specified by:
      getControllerSetPoint in interface ControllerDeviceInterface
      Returns:
      current controller set point
    • getUnit

      public String getUnit()
      Description copied from interface: ControllerDeviceInterface

      getUnit.

      Specified by:
      getUnit in interface ControllerDeviceInterface
      Returns:
      a String object
    • setUnit

      public void setUnit(String unit)
      Description copied from interface: ControllerDeviceInterface

      setUnit.

      Specified by:
      setUnit in interface ControllerDeviceInterface
      Parameters:
      unit - a String object
    • setTransmitter

      public void setTransmitter(MeasurementDeviceInterface device)
      Description copied from interface: ControllerDeviceInterface

      setTransmitter.

      Specified by:
      setTransmitter in interface ControllerDeviceInterface
      Parameters:
      device - a MeasurementDeviceInterface object
    • ingestPlantSample

      public void ingestPlantSample(double measurement, double appliedControl, double dt)
      Inject a measurement collected directly from a physical plant rather than the built-in transmitter abstraction. This is useful when the MPC is connected to a live facility where instrumentation values arrive asynchronously from the control system. The sample updates the diagnostic state of the controller and provides a fallback measurement if no transmitter is configured.
      Parameters:
      measurement - latest measured process value
      appliedControl - control signal that was active when the sample was taken
      dt - sample interval since the previous measurement
    • ingestPlantSample

      public void ingestPlantSample(double measurement, double appliedControl)
      Convenience overload of ingestPlantSample(double, double, double) when only the measurement and applied control are known.
      Parameters:
      measurement - measured process value
      appliedControl - applied control signal
    • runTransient

      public void runTransient(double initResponse, double dt, UUID id)
      Description copied from interface: ControllerDeviceInterface

      runTransient.

      Calculates controller output. Sets calc identifier UUID.
      Specified by:
      runTransient in interface ControllerDeviceInterface
      Parameters:
      initResponse - Init value for response calculation
      dt - Delta time [s]
      id - Calculation identifier
    • clampControlVector

      private void clampControlVector()
    • runMultivariable

      private void runMultivariable()
    • recordEstimationSample

      private void recordEstimationSample(double measurement, double appliedControl, double dt)
    • updateMovingHorizonEstimate

      private void updateMovingHorizonEstimate()
    • estimateFromSamples

      private ModelPredictiveController.MovingHorizonEstimate estimateFromSamples(List<Double> measurements, List<Double> controls, List<Double> sampleTimes)
    • estimateFromHistory

      private ModelPredictiveController.MovingHorizonEstimate estimateFromHistory()
    • solveQuadraticProgram

      private double[] solveQuadraticProgram(double[][] hessian, double[] gradient, double[][] constraints, double[] bounds)
    • buildActiveMatrix

      private double[][] buildActiveMatrix(double[][] matrix, int mask)
    • buildActiveVector

      private double[] buildActiveVector(double[] vector, int mask)
    • solveEqualityConstrained

      private double[] solveEqualityConstrained(double[] inverseDiagonal, double[] gradient, double[][] constraints, double[] bounds)
    • solveLinearSystem

      private double[] solveLinearSystem(double[][] matrix, double[] vector)
    • isFeasible

      private boolean isFeasible(double[] candidate, double[][] constraints, double[] bounds)
    • objectiveValue

      private double objectiveValue(double[][] hessian, double[] gradient, double[] candidate)
    • computeOptimalControl

      private double computeOptimalControl(double measurement, double dt, double previousControl)
    • clamp

      private double clamp(double value)
    • getResponse

      public double getResponse()
      Description copied from interface: ControllerDeviceInterface

      getResponse.

      Specified by:
      getResponse in interface ControllerDeviceInterface
      Returns:
      a double
    • isReverseActing

      public boolean isReverseActing()
      Description copied from interface: ControllerDeviceInterface

      isReverseActing.

      Specified by:
      isReverseActing in interface ControllerDeviceInterface
      Returns:
      a boolean
    • setReverseActing

      public void setReverseActing(boolean reverseActing)
      Description copied from interface: ControllerDeviceInterface

      setReverseActing.

      Specified by:
      setReverseActing in interface ControllerDeviceInterface
      Parameters:
      reverseActing - a boolean
    • setControllerParameters

      public void setControllerParameters(double Kp, double Ti, double Td)
      Description copied from interface: ControllerDeviceInterface

      Set PID tuning parameters.

      Specified by:
      setControllerParameters in interface ControllerDeviceInterface
      Parameters:
      Kp - Proportional gain
      Ti - Integral time in seconds
      Td - Derivative time in seconds
    • setOutputLimits

      public void setOutputLimits(double min, double max)
      Description copied from interface: ControllerDeviceInterface

      Set minimum and maximum controller output for anti-windup handling.

      Specified by:
      setOutputLimits in interface ControllerDeviceInterface
      Parameters:
      min - Minimum controller response
      max - Maximum controller response
    • getPredictedTrajectory

      public double[] getPredictedTrajectory(int steps, double dt)
      Predict future measurements using the internal first-order model assuming the most recent control signal is held constant.
      Parameters:
      steps - number of steps ahead to predict (must be positive)
      dt - sampling interval in seconds
      Returns:
      predicted measurements for each step into the future
    • setActive

      public void setActive(boolean isActive)
      Description copied from interface: ControllerDeviceInterface

      setActive.

      Set if controller is active
      Specified by:
      setActive in interface ControllerDeviceInterface
      Parameters:
      isActive - Set true to make controller active.
    • isActive

      public boolean isActive()
      Description copied from interface: ControllerDeviceInterface

      isActive.

      Specifies if controller is active
      Specified by:
      isActive in interface ControllerDeviceInterface
      Returns:
      a boolean
    • equals

      public boolean equals(Object other)
      Description copied from interface: ControllerDeviceInterface
      Specified by:
      equals in interface ControllerDeviceInterface
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Description copied from interface: ControllerDeviceInterface
      Specified by:
      hashCode in interface ControllerDeviceInterface
      Overrides:
      hashCode in class Object
    • getCalcIdentifier

      public UUID getCalcIdentifier()
      Get the identifier of the last run transient calculation.
      Returns:
      calculation identifier
    • getMinResponse

      public double getMinResponse()
      Get the controller output lower bound.
      Returns:
      minimum response
    • getMaxResponse

      public double getMaxResponse()
      Get the controller output upper bound.
      Returns:
      maximum response
    • getPredictionHorizon

      public int getPredictionHorizon()
      Get the configured prediction horizon.
      Returns:
      prediction horizon length
    • getLastSampleTime

      public double getLastSampleTime()
      Get the last sampling interval seen by the controller.
      Returns:
      sampling time in seconds
    • getOutputWeight

      public double getOutputWeight()
      Retrieve the configured output weight for diagnostic purposes.
      Returns:
      output tracking weight
    • getControlWeight

      public double getControlWeight()
      Retrieve the configured absolute control weight for diagnostic purposes.
      Returns:
      control usage weight
    • getMoveWeight

      public double getMoveWeight()
      Retrieve the configured move suppression weight for diagnostic purposes.
      Returns:
      control move weight
    • getProcessGain

      public double getProcessGain()
      Get the current process gain used by the controller's internal model.
      Returns:
      process gain
    • getTimeConstant

      public double getTimeConstant()
      Get the current process time constant used by the controller's internal model.
      Returns:
      process time constant in seconds
    • getProcessBias

      public double getProcessBias()
      Get the current process bias used by the controller's internal model.
      Returns:
      process bias