Dynamic Estimation Tuning

Main.EstimatorTuning History

Show minor edits - Show changes to markup

February 24, 2023, at 08:59 PM by 10.37.197.230 -
Changed line 232 from:
(:source lang=python:)
to:

(:source lang=python:)

Changed lines 238-240 from:
Here is a complete example:
(:source lang=python:)
to:

Here is a complete example:

(:source lang=python:)

February 24, 2023, at 08:59 PM by 10.37.197.230 -
Changed lines 226-262 from:

(:htmlend:)

to:

(:htmlend:)

Jupyter Notebook Tip

For Jupyter notebooks, add the following code to allow real-time plots to display instead of creating a new plot for every frame. Use the clear_output() function in the loop where the plot is displayed.

(:source lang=python:)

from IPython import display

display.clear_output(wait=True) (:sourceend:)

Here is a complete example:
(:source lang=python:)

import numpy as np import matplotlib.pyplot as plt from IPython import display

x = np.linspace(0, 6 * np.pi, 100) cos_values = [] sin_values = [] for i in range(len(x)):

    # add the sin and cos of x at index i to the lists
    cos_values.append(np.cos(x[i]))
    sin_values.append(np.sin(x[i]))

    # graph up until index i
    plt.plot(x[:i], cos_values[:i], label='Cos')
    plt.plot(x[:i], sin_values[:i], label='Sin')
    plt.xlabel('input')
    plt.ylabel('output')

    # lines that help with animation
    display.clear_output(wait=True)  # replace figure
    plt.pause(.01)  # wait between figures

(:sourceend:)

February 10, 2023, at 06:09 PM by 10.35.117.248 -
Deleted line 87:
  1. Change to True for MacOS
Changed line 13 from:
to:
December 22, 2019, at 03:29 PM by 136.36.211.159 -
Changed line 11 from:
to:
December 22, 2019, at 03:27 PM by 136.36.211.159 -
Added lines 11-12:
Deleted line 14:
Deleted lines 20-21:
December 22, 2019, at 03:24 PM by 136.36.211.159 -
Added lines 12-19:

Attach:mhe_tuning.mp4 (:html:) <video width="450" controls autoplay loop>

  <source src="/do/uploads/Main/mhe_tuning.mp4" type="video/mp4">
  Your browser does not support the video tag.

</video> (:htmlend:)

February 05, 2019, at 10:22 PM by 195.184.107.10 -
Added lines 78-79:

n = 1 # process model order

Changed lines 81-82 from:

p = GEKKO()

to:
  1. Change to True for MacOS

rmt = False p = GEKKO(remote=rmt)

Changed lines 87-88 from:
  1. p.u = p.MV()

p.u = p.MV(value=2)

to:

p.u = p.MV(value=0)

Changed lines 91-94 from:
  1. variable
  2. p.y = p.SV() #measurement

p.y = p.SV(value=0) #measurement

to:
  1. Intermediate

p.x = [p.Intermediate(p.u)]

  1. Variables

p.x.extend([p.Var() for _ in range(n)]) #state variables p.y = p.SV() #measurement

Changed lines 99-100 from:

p.Equation(p.tau * p.y.dt() == -p.y + p.K * p.u)

to:

p.Equations([p.tau/n * p.x[i+1].dt() == -p.x[i+1] + p.x[i] for i in range(n)]) p.Equation(p.y == p.K * p.x[n])

Changed lines 105-109 from:
  1. MHE Model

m = GEKKO()

m.time = np.linspace(0,20,41) #0-20 by 0.5 -- discretization must match simulation

to:
  1. Model

m = GEKKO(remote=rmt)

  1. 0-20 by 0.5 -- discretization must match simulation

m.time = np.linspace(0,20,41)

Changed lines 112-114 from:
  1. m.K = m.FV(value=3, lb=1, ub=3) #gain

m.K = m.FV(value=1, lb=1, ub=3) #gain

  1. m.tau = m.FV(value=4, lb=1, ub=10) #time constant
to:

m.K = m.FV(value=1, lb=0.3, ub=3) #gain

Changed lines 116-118 from:
  1. m.y = m.CV() #measurement

m.y = m.CV(value=0) #measurement

to:

m.x = m.SV() #state variable m.y = m.CV() #measurement

Changed lines 120-121 from:

m.Equation(m.tau * m.y.dt() == -m.y + m.K*m.u)

to:

m.Equations([m.tau * m.x.dt() == -m.x + m.u,

             m.y == m.K * m.x])
Changed lines 126-127 from:

m.options.DIAGLEVEL = 0

to:
Changed lines 132-133 from:

m.y.STATUS = 1

to:
Changed lines 141-143 from:

m.K.DMAX = 0.0

  1. m.tau.DMAX = .1

m.tau.DMAX = 0.0

to:

m.K.DMAX = 1 m.tau.DMAX = .1

Changed lines 145-148 from:

m.y.MEAS_GAP = 0.25

m.y.TR_INIT = 1

to:

m.y.MEAS_GAP = 0.0

Added lines 150-151:
  1. time vector

tm = np.linspace(0,25,51)

Changed lines 153-157 from:
  1. noise = 0.25

noise = 0.0

  1. run process, estimator and control for cycles

y_meas = np.empty(cycles)

to:

noise = 0.25

  1. values of u change randomly over time every 10th step

u_meas = np.zeros(cycles) step_u = 0 for i in range(0,cycles):

    if ((i-1)%10) == 0:
        # random step (-5 to 5)
        step_u = step_u + (random()-0.5)*10
    u_meas[i] = step_u
  1. run process and estimator for cycles

y_meas = np.zeros(cycles)

Deleted lines 168-175:

u_cont = np.empty(cycles) u = 2.0

  1. Create plot

plt.figure(figsize=(10,7)) plt.ion() plt.show()

Changed lines 170-184 from:
    # change input (u)
    if i==10:
        u = 3.0
    elif i==20:
        u = 4.0
    elif i==30:
        u = 1.0
    elif i==40:
        u = 3.0
    u_cont[i] = u

    ## process simulator
    #load u value
    p.u.MEAS = u_cont[i]
    #simulate
to:
    # process simulator
    p.u.MEAS = u_meas[i]
Changed lines 173-178 from:
    #load output with white noise
    y_meas[i] = p.y.MODEL + (random()-0.5)*noise

    ## estimator
    #load input and measured output
    m.u.MEAS = u_cont[i]
to:
    r = (random()-0.5)*noise
    y_meas[i] = p.y.value[1] + r # add noise

    # estimator
    m.u.MEAS = u_meas[i]
Deleted line 178:
    #optimize parameters
Changed lines 180-184 from:
    #store results
    y_est[i+1] = m.y.MODEL 
    k_est[i+1] = m.K.NEWVAL 
    tau_est[i+1] = m.tau.NEWVAL 
to:
    y_est[i] = m.y.MODEL 
    k_est[i] = m.K.NEWVAL 
    tau_est[i] = m.tau.NEWVAL 
Changed lines 186-187 from:
    plt.plot(y_meas[0:i],'b-')
    plt.plot(y_est[0:i],'r--')
to:
    plt.plot(tm[0:i+1],y_meas[0:i+1],'b-')
    plt.plot(tm[0:i+1],y_est[0:i+1],'r--')
Changed lines 191-192 from:
    plt.plot(np.ones(i)*p.K.value[0],'b-')
    plt.plot(k_est[0:i],'r--')
to:
    plt.plot(tm[0:i+1],np.ones(i+1)*p.K.value[0],'b-')
    plt.plot(tm[0:i+1],k_est[0:i+1],'r--')
Changed lines 196-197 from:
    plt.plot(np.ones(i)*p.tau.value[0],'b-')
    plt.plot(tau_est[0:i],'r--')
to:
    plt.plot(tm[0:i+1],np.ones(i+1)*p.tau.value[0],'b-')
    plt.plot(tm[0:i+1],tau_est[0:i+1],'r--')
Changed line 201 from:
    plt.plot(u_cont[0:i])
to:
    plt.plot(tm[0:i+1],u_meas[0:i+1],'b-')
February 05, 2019, at 09:25 PM by 195.184.107.10 -
Deleted line 72:
  1. Import packages
Deleted lines 77-79:
  1. Solve local or remote

rmt = True

Deleted lines 82-83:

n = 1 #process model order

Changed lines 84-85 from:

p.u = p.MV()

to:
  1. p.u = p.MV()

p.u = p.MV(value=2)

Changed lines 89-95 from:
  1. Intermediate

p.x = [p.Intermediate(p.u)]

  1. Variables

p.x.extend([p.Var() for _ in range(n)]) #state variables p.y = p.SV() #measurement

to:
  1. variable
  2. p.y = p.SV() #measurement

p.y = p.SV(value=0) #measurement

Changed lines 94-96 from:

p.Equations([p.tau/n * p.x[i+1].dt() == -p.x[i+1] + p.x[i] for i in range(n)]) p.Equation(p.y == p.K * p.x[n])

to:

p.Equation(p.tau * p.y.dt() == -p.y + p.K * p.u)

Changed lines 99-103 from:
  1. p.u.FSTATUS = 1
  2. p.u.STATUS = 0
  3. Model
to:
  1. MHE Model
Added line 106:
  1. m.K = m.FV(value=3, lb=1, ub=3) #gain
Added line 108:
  1. m.tau = m.FV(value=4, lb=1, ub=10) #time constant
Changed lines 112-114 from:

m.x = m.SV() #state variable m.y = m.CV() #measurement

to:
  1. m.y = m.CV() #measurement

m.y = m.CV(value=0) #measurement

Changed lines 116-119 from:

m.Equations([m.tau * m.x.dt() == -m.x + m.u,

             m.y == m.K * m.x])
to:

m.Equation(m.tau * m.y.dt() == -m.y + m.K*m.u)

Changed lines 121-122 from:
to:

m.options.DIAGLEVEL = 0

Changed lines 138-140 from:

m.K.DMAX = 1 m.tau.DMAX = .1

to:

m.K.DMAX = 0.0

  1. m.tau.DMAX = .1

m.tau.DMAX = 0.0

Changed lines 150-161 from:

noise = 0.25

  1. values of u change randomly over time every 10th step

u_meas = np.zeros(cycles) step_u = 0 for i in range(0,cycles):

    if (i % 10) == 0:
        # random step (-5 to 5)
        step_u = step_u + (random()-0.5)*10
    u_meas[i] = step_u
  1. run process and estimator for cycles
to:
  1. noise = 0.25

noise = 0.0

  1. run process, estimator and control for cycles
Changed lines 155-161 from:

y_est = np.empty(cycles) k_est = np.empty(cycles) tau_est = np.empty(cycles) for i in range(cycles):

    # process simulator
    p.u.MEAS = u_meas[i]
    p.solve(remote=rmt)
to:

y_est = np.zeros(cycles) k_est = np.zeros(cycles)*np.nan tau_est = np.zeros(cycles)*np.nan u_cont = np.empty(cycles) u = 2.0

  1. Create plot

plt.figure(figsize=(10,7)) plt.ion() plt.show()

for i in range(cycles-1):

    # change input (u)
    if i==10:
        u = 3.0
    elif i==20:
        u = 4.0
    elif i==30:
        u = 1.0
    elif i==40:
        u = 3.0
    u_cont[i] = u

    ## process simulator
    #load u value
    p.u.MEAS = u_cont[i]
    #simulate
    p.solve()
    #load output with white noise
Changed lines 185-187 from:
    # estimator
    m.u.MEAS = u_meas[i]
to:
    ## estimator
    #load input and measured output
    m.u.MEAS = u_cont[i]
Changed lines 190-213 from:
    m.solve(remote=rmt)
    y_est[i] = m.y.MODEL 
    k_est[i] = m.K.NEWVAL 
    tau_est[i] = m.tau.NEWVAL 
  1. Plot results

plt.figure() plt.subplot(4,1,1) plt.plot(y_meas) plt.plot(y_est) plt.legend(('meas','pred')) plt.subplot(4,1,2) plt.plot(np.ones(cycles)*p.K.value[0]) plt.plot(k_est) plt.legend(('actual','pred')) plt.subplot(4,1,3) plt.plot(np.ones(cycles)*p.tau.value[0]) plt.plot(tau_est) plt.legend(('actual','pred')) plt.subplot(4,1,4) plt.plot(u_meas) plt.legend('u') plt.show()

to:
    #optimize parameters
    m.solve()
    #store results
    y_est[i+1] = m.y.MODEL 
    k_est[i+1] = m.K.NEWVAL 
    tau_est[i+1] = m.tau.NEWVAL 

    plt.clf()
    plt.subplot(4,1,1)
    plt.plot(y_meas[0:i],'b-')
    plt.plot(y_est[0:i],'r--')
    plt.legend(('meas','pred'))
    plt.ylabel('y')
    plt.subplot(4,1,2)
    plt.plot(np.ones(i)*p.K.value[0],'b-')
    plt.plot(k_est[0:i],'r--')
    plt.legend(('actual','pred'))
    plt.ylabel('k')
    plt.subplot(4,1,3)
    plt.plot(np.ones(i)*p.tau.value[0],'b-')
    plt.plot(tau_est[0:i],'r--')
    plt.legend(('actual','pred'))
    plt.ylabel('tau')
    plt.subplot(4,1,4)
    plt.plot(u_cont[0:i])
    plt.legend('u')
    plt.draw()
    plt.pause(0.05)
Changed line 13 from:
to:
Changed lines 9-15 from:

Tuning typically involves adjustment of objective function terms or constraints that limit the rate of change (DMAX), penalize the rate of change (DCOST), or set absolute bounds (LOWER and UPPER). Measurement availability is indicated by the parameter (FSTATUS). The optimizer can also include (1=on) or exclude (0=off) a certain adjustable parameter (FV) or manipulated variable (MV) with STATUS. Another important tuning consideration is the time horizon length. Including more points in the time horizon allows the estimator to reconcile the model to more data but also increases computational time. Below are common application, FV, MV, and CV tuning constants that are adjusted to achieve desired model predictive control performance.

to:

Tuning typically involves adjustment of objective function terms or constraints that limit the rate of change (DMAX), penalize the rate of change (DCOST), or set absolute bounds (LOWER and UPPER). Measurement availability is indicated by the parameter (FSTATUS). The optimizer can also include (1=on) or exclude (0=off) a certain adjustable parameter (FV) or manipulated variable (MV) with STATUS. Another important tuning consideration is the time horizon length. Including more points in the time horizon allows the estimator to reconcile the model to more data but also increases computational time.

Below are common application, FV, MV, and CV tuning constants that are adjusted to achieve desired model predictive control performance.

Changed lines 54-57 from:

Application constants are modified by indicating that the constant belongs to the group nlc. IMODE is adjusted to either solve the MHE problem with a simultaneous (5) or sequential (8) method. In the case below, the application IMODE is changed to sequential mode.

 apm_option(server,app,'nlc.IMODE',8)
to:

Application constants are modified by indicating that the constant belongs to the group apm. IMODE is adjusted to either solve the MHE problem with a simultaneous (5) or sequential (8) method. In the case below, the application IMODE is changed to simultaneous mode.

 apm_option(server,app,'apm.IMODE',5)
Changed line 60 from:

Objective: Design an estimator to predict an unknown parameters so that a simple model is able to predict the response of a more complex process. Tune the estimator to achieve either tracking or predictive performance. Estimated time: 2 hours.

to:

Objective: Design an estimator to predict an unknown parameters so that a simple model is able to predict the response of a more complex process. Tune the estimator to achieve either tracking or predictive performance. Estimated time: 1 hour.

Changed lines 24-25 from:
  • Manipulated Variable (MV) tuning
to:
  • Fixed Value (FV) - single parameter value over time horizon
    • DMAX = maximum that FV can move each cycle
    • LOWER = lower FV bound
    • FSTATUS = feedback status with 1=measured, 0=off
    • STATUS = turn on (1) or off (0) FV
    • UPPER = upper FV bound
  • Manipulated Variable (MV) - parameter can change over time horizon
January 28, 2018, at 06:21 AM by 174.148.61.237 -
Added lines 57-200:

(:toggle hide gekko button show="Show GEKKO (Python) Code":) (:div id=gekko:) (:source lang=python:)

  1. Import packages

import numpy as np from random import random from gekko import GEKKO import matplotlib.pyplot as plt

  1. Solve local or remote

rmt = True

  1. Process

p = GEKKO()

p.time = [0,.5]

n = 1 #process model order

  1. Parameters

p.u = p.MV() p.K = p.Param(value=1) #gain p.tau = p.Param(value=5) #time constant

  1. Intermediate

p.x = [p.Intermediate(p.u)]

  1. Variables

p.x.extend([p.Var() for _ in range(n)]) #state variables p.y = p.SV() #measurement

  1. Equations

p.Equations([p.tau/n * p.x[i+1].dt() == -p.x[i+1] + p.x[i] for i in range(n)]) p.Equation(p.y == p.K * p.x[n])

  1. options

p.options.IMODE = 4

  1. p.u.FSTATUS = 1
  2. p.u.STATUS = 0
  3. Model

m = GEKKO()

m.time = np.linspace(0,20,41) #0-20 by 0.5 -- discretization must match simulation

  1. Parameters

m.u = m.MV() #input m.K = m.FV(value=1, lb=1, ub=3) #gain m.tau = m.FV(value=5, lb=1, ub=10) #time constant

  1. Variables

m.x = m.SV() #state variable m.y = m.CV() #measurement

  1. Equations

m.Equations([m.tau * m.x.dt() == -m.x + m.u,

             m.y == m.K * m.x])
  1. Options

m.options.IMODE = 5 #MHE m.options.EV_TYPE = 1

  1. STATUS = 0, optimizer doesn't adjust value
  2. STATUS = 1, optimizer can adjust

m.u.STATUS = 0 m.K.STATUS = 1 m.tau.STATUS = 1 m.y.STATUS = 1

  1. FSTATUS = 0, no measurement
  2. FSTATUS = 1, measurement used to update model

m.u.FSTATUS = 1 m.K.FSTATUS = 0 m.tau.FSTATUS = 0 m.y.FSTATUS = 1

  1. DMAX = maximum movement each cycle

m.K.DMAX = 1 m.tau.DMAX = .1

  1. MEAS_GAP = dead-band for measurement / model mismatch

m.y.MEAS_GAP = 0.25

m.y.TR_INIT = 1

  1. problem configuration
  2. number of cycles

cycles = 50

  1. noise level

noise = 0.25

  1. values of u change randomly over time every 10th step

u_meas = np.zeros(cycles) step_u = 0 for i in range(0,cycles):

    if (i % 10) == 0:
        # random step (-5 to 5)
        step_u = step_u + (random()-0.5)*10
    u_meas[i] = step_u
  1. run process and estimator for cycles

y_meas = np.empty(cycles) y_est = np.empty(cycles) k_est = np.empty(cycles) tau_est = np.empty(cycles) for i in range(cycles):

    # process simulator
    p.u.MEAS = u_meas[i]
    p.solve(remote=rmt)
    y_meas[i] = p.y.MODEL + (random()-0.5)*noise

    # estimator
    m.u.MEAS = u_meas[i]
    m.y.MEAS = y_meas[i]
    m.solve(remote=rmt)
    y_est[i] = m.y.MODEL 
    k_est[i] = m.K.NEWVAL 
    tau_est[i] = m.tau.NEWVAL 
  1. Plot results

plt.figure() plt.subplot(4,1,1) plt.plot(y_meas) plt.plot(y_est) plt.legend(('meas','pred')) plt.subplot(4,1,2) plt.plot(np.ones(cycles)*p.K.value[0]) plt.plot(k_est) plt.legend(('actual','pred')) plt.subplot(4,1,3) plt.plot(np.ones(cycles)*p.tau.value[0]) plt.plot(tau_est) plt.legend(('actual','pred')) plt.subplot(4,1,4) plt.plot(u_meas) plt.legend('u') plt.show() (:sourceend:) (:divend:)

April 05, 2017, at 08:46 PM by 10.5.113.121 -
Added lines 18-23:
  • SOLVER
    • 0=Try all available solvers
    • 1=APOPT (MINLP, Active Set SQP)
    • 2=BPOPT (NLP, Interior Point, SQP)
    • 3=IPOPT (NLP, Interior Point, SQP)
May 14, 2015, at 08:15 PM by 45.56.3.184 -
Changed line 40 from:
 apm_option(server,app,'y.MEAS_GAS',1.0)
to:
 apm_option(server,app,'y.MEAS_GAP',1.0)
May 12, 2015, at 06:05 AM by 174.148.30.57 -
Changed line 63 from:

<iframe width="560" height="315" src="https://www.youtube.com/embed/yQWgSByYjd8?rel=0" frameborder="0" allowfullscreen></iframe>

to:

<iframe width="560" height="315" src="https://www.youtube.com/embed/yw_a9ektOqc?rel=0" frameborder="0" allowfullscreen></iframe>

May 11, 2015, at 10:54 PM by 10.5.113.160 -
Deleted line 30:
  • CV_TYPE = CV type with 1=l_1-norm, 2=squared error
Changed lines 32-38 from:
  • SP = set point with CV_TYPE = 2
  • SPLO = lower set point with CV_TYPE = 1
  • SPHI = upper set point with CV_TYPE = 1
  • STATUS = turn on (1) or off (0) MV
  • TAU = reference trajectory time-constant
  • TR_INIT = trajectory type, 0=dead-band, 1,2=trajectory
  • TR_OPEN = opening at initial point of trajectory compared to end
to:
  • MEAS_GAP = measurement gap for estimator dead-band
May 11, 2015, at 05:35 PM by 45.56.3.184 -
Changed lines 9-10 from:

Tuning typically involves adjustment of objective function terms or constraints that limit the rate of change (DMAX), penalize the rate of change (DCOST), or set absolute bounds (LOWER and UPPER). Measurement availability is indicated by the parameter (FSTATUS). The optimizer can also include (1=on) or exclude (0=off) a certain adjustable parameter (FV) or manipulated variable (MV) with STATUS. Below are common application, FV, MV, and CV tuning constants that are adjusted to achieve desired model predictive control performance.

to:

Tuning typically involves adjustment of objective function terms or constraints that limit the rate of change (DMAX), penalize the rate of change (DCOST), or set absolute bounds (LOWER and UPPER). Measurement availability is indicated by the parameter (FSTATUS). The optimizer can also include (1=on) or exclude (0=off) a certain adjustable parameter (FV) or manipulated variable (MV) with STATUS. Another important tuning consideration is the time horizon length. Including more points in the time horizon allows the estimator to reconcile the model to more data but also increases computational time. Below are common application, FV, MV, and CV tuning constants that are adjusted to achieve desired model predictive control performance.

Deleted line 11:
  • IMODE = 5 or 8 for moving horizon estimation
Added line 14:
  • IMODE = 5 or 8 for moving horizon estimation
Changed lines 51-74 from:
 apm_option(server,app,'nlc.IMODE',8)
to:
 apm_option(server,app,'nlc.IMODE',8)

Exercise

Objective: Design an estimator to predict an unknown parameters so that a simple model is able to predict the response of a more complex process. Tune the estimator to achieve either tracking or predictive performance. Estimated time: 2 hours.

Design an estimator to predict K and tau of a 1st order model to predict the dynamic response of a 1st order, 2nd order, and 10th order process. For the 2nd and 10th order systems, there is process/model mismatch. This means that the structure of the model can never exactly match the actual process because the equations are inherently incorrect. The parameter values are adjusted to best approximate the process even though the model is deficient. The process order is adjusted in the file process.apm file in the Constants section.

 Constants
   ! process model order
   n = 1  ! change to 1, 2, and 10

In each case, tune the estimator to favor either acceptable tracking or predictive performance. Tracking performance is the ability of the estimator to synchronize with measurements and is demonstrated with overall agreement between the model predictions and the measurements. Predictive performance sacrifices tracking performance to achieve more consistent values that are valid over a longer predictive horizon for model predictive control.

Solution

(:html:) <iframe width="560" height="315" src="https://www.youtube.com/embed/yQWgSByYjd8?rel=0" frameborder="0" allowfullscreen></iframe> (:htmlend:)

May 11, 2015, at 02:33 PM by 45.56.3.184 -
Changed line 5 from:

The dynamic estimation tuning is the process of adjusting certain objective function terms to give more desirable solutions. As an example, dynamic estimation application may either track noisy data too closely or the updates may be too slow to catch unmeasured disturbances of interest.

to:

Dynamic estimation tuning is the process of adjusting certain objective function terms to give more desirable solutions. As an example, a dynamic estimation application such as moving horizon estimation (MHE) may either track noisy data too closely or the updates may be too slow to catch unmeasured disturbances of interest. Tuning is the process of achieving acceptable estimator performance based on unique aspects of the application.

May 11, 2015, at 02:11 PM by 45.56.3.184 -
Added lines 6-51:

Common Tuning Parameters for MHE

Tuning typically involves adjustment of objective function terms or constraints that limit the rate of change (DMAX), penalize the rate of change (DCOST), or set absolute bounds (LOWER and UPPER). Measurement availability is indicated by the parameter (FSTATUS). The optimizer can also include (1=on) or exclude (0=off) a certain adjustable parameter (FV) or manipulated variable (MV) with STATUS. Below are common application, FV, MV, and CV tuning constants that are adjusted to achieve desired model predictive control performance.

  • Application tuning
    • IMODE = 5 or 8 for moving horizon estimation
    • DIAGLEVEL = diagnostic level (0-10) for solution information
    • EV_TYPE = 1 for l1-norm and 2 for squared error objective
    • MAX_ITER = maximum iterations
    • MAX_TIME = maximum time before stopping
    • MV_TYPE = Set default MV type with 0=zero-order hold, 1=linear interpolation
  • Manipulated Variable (MV) tuning
    • COST = (+) minimize MV, (-) maximize MV
    • DCOST = penalty for MV movement
    • DMAX = maximum that MV can move each cycle
    • FSTATUS = feedback status with 1=measured, 0=off
    • LOWER = lower MV bound
    • MV_TYPE = MV type with 0=zero-order hold, 1=linear interpolation
    • STATUS = turn on (1) or off (0) MV
    • UPPER = upper MV bound
  • Controlled Variable (CV) tuning
    • COST = (+) minimize MV, (-) maximize MV
    • CV_TYPE = CV type with 1=l_1-norm, 2=squared error
    • FSTATUS = feedback status with 1=measured, 0=off
    • SP = set point with CV_TYPE = 2
    • SPLO = lower set point with CV_TYPE = 1
    • SPHI = upper set point with CV_TYPE = 1
    • STATUS = turn on (1) or off (0) MV
    • TAU = reference trajectory time-constant
    • TR_INIT = trajectory type, 0=dead-band, 1,2=trajectory
    • TR_OPEN = opening at initial point of trajectory compared to end

There are several ways to change the tuning values. Tuning values can either be specified before an application is initialized or while an application is running. To change a tuning value before the application is loaded, use the apm_option() function such as the following example to change the lower bound in MATLAB or Python for the FV named p.

 apm_option(server,app,'p.LOWER',0)

The upper and lower measurement deadband for a CV named y are set to values around the measurement. In this case, an acceptable range for the model prediction is to intersect the measurement of 10.0 between 9.5 and 10.5 with a MEAS_GAP of 1.0 (or +/-0.5).

 apm_option(server,app,'y.MEAS_GAS',1.0)

Application constants are modified by indicating that the constant belongs to the group nlc. IMODE is adjusted to either solve the MHE problem with a simultaneous (5) or sequential (8) method. In the case below, the application IMODE is changed to sequential mode.

 apm_option(server,app,'nlc.IMODE',8)
Added lines 1-5:

(:title Dynamic Estimation Tuning:) (:keywords tuning, Python, MATLAB, Simulink, moving horizon, time window, dynamic data, validation, estimation, differential, algebraic, tutorial:) (:description Tuning of an estimator for improved rejection of corrupted data with outliers, drift, and noise:)

The dynamic estimation tuning is the process of adjusting certain objective function terms to give more desirable solutions. As an example, dynamic estimation application may either track noisy data too closely or the updates may be too slow to catch unmeasured disturbances of interest.