简体   繁体   English

如何通过使用 gekko 调整参数来解决超调?

[英]How to solve overshoot by tuning parameters with gekko?

GEKKO is optimization software for mixed-integer and differential algebraic equations. GEKKO是混合整数和微分代数方程的优化软件。 It is coupled with large-scale solvers for linear, quadratic, nonlinear , and mixed integer programming ( LP, QP, NLP, MILP, MINLP ).它与用于linear, quadratic, nonlinear和混合 integer 编程( LP, QP, NLP, MILP, MINLPlarge-scale solvers相结合。 I use gekko to control my TCLab Arduino , but when I give a disturbance, no matter how I adjust the parameters, there will be a overshoot temperature.我使用gekko来控制我的TCLab Arduino ,但是当我给干扰时,无论我如何调整参数,都会出现温度过冲。 How can I solve this problem?我怎么解决这个问题?

Here is my code:这是我的代码:

import tclab
import numpy as np
import time
import matplotlib.pyplot as plt
from gekko import GEKKO

# Connect to Arduino
a = tclab.TCLab()

# Get Version
print(a.version)

# Turn LED on
print('LED On')
a.LED(100)

# Run time in minutes
run_time = 60.0

# Number of cycles
loops = int(60.0*run_time)
tm = np.zeros(loops)

# Temperature (K)
T1 = np.ones(loops) * a.T1 # temperature (degC)
Tsp1 = np.ones(loops) * 35.0 # set point (degC)

# heater values
Q1s = np.ones(loops) * 0.0

#########################################################
# Initialize Model
#########################################################
# use remote=True for MacOS
m = GEKKO(name='tclab-mpc',remote=False)

# 100 second time horizon
m.time = np.linspace(0,100,101)

# Parameters
Q1_ss = m.Param(value=0)
TC1_ss = m.Param(value=a.T1)
Kp = m.Param(value=0.8)
tau = m.Param(value=160.0)

# Manipulated variable
Q1 = m.MV(value=0)
Q1.STATUS = 1  # use to control temperature
Q1.FSTATUS = 0 # no feedback measurement
Q1.LOWER = 0.0
Q1.UPPER = 100.0
Q1.DMAX = 50.0
# Q1.COST = 0.0
Q1.DCOST = 0.2

# Controlled variable
TC1 = m.CV(value=TC1_ss.value)
TC1.STATUS = 1     # minimize error with setpoint range
TC1.FSTATUS = 1    # receive measurement
TC1.TR_INIT = 2    # reference trajectory
TC1.TR_OPEN = 2    # reference trajectory
TC1.TAU = 35       # time constant for response

m.Equation(tau * TC1.dt() + (TC1-TC1_ss) == Kp * (Q1-Q1_ss))

# Global Options
m.options.IMODE   = 6 # MPC
m.options.CV_TYPE = 1 # Objective type
m.options.NODES   = 2 # Collocation nodes
m.options.SOLVER  = 1 # 1=APOPT, 3=IPOPT
##################################################################

# Create plot
plt.figure()
plt.ion()
plt.show()

filter_tc1 = []
def movefilter(predata, new, n):
    if len(predata) < n:
        predata.append(new)
    else:
        predata.pop(0)
        predata.append(new)
    return np.average(predata)

# Main Loop
start_time = time.time()
prev_time = start_time
try:
    for i in range(1,loops):
        # Sleep time
        sleep_max = 1.0
        sleep = sleep_max - (time.time() - prev_time)
        if sleep>=0.01:
            time.sleep(sleep)
        else:
            time.sleep(0.01)

        # Record time and change in time
        t = time.time()
        dt = t - prev_time
        prev_time = t
        tm[i] = t - start_time

        # Read temperatures in Kelvin
        curr_T1 = a.T1
        last_T1 = curr_T1
        avg_T1 = movefilter(filter_tc1, last_T1, 3)
        T1[i] = curr_T1

        ###############################
        ### MPC CONTROLLER          ###
        ###############################
        TC1.MEAS = avg_T1
        # input setpoint with deadband +/- DT
        DT = 0.1
        TC1.SPHI = Tsp1[i] + DT
        TC1.SPLO = Tsp1[i] - DT
        # solve MPC
        m.solve(disp=False)
        # test for successful solution
        if (m.options.APPSTATUS==1):
            # retrieve the first Q value
            Q1s[i] = Q1.NEWVAL
        else:
            # not successful, set heater to zero
            Q1s[i] = 0

        # Write output (0-100)
        a.Q1(Q1s[i])

        # Plot
        plt.clf()
        ax=plt.subplot(2,1,1)
        ax.grid()
        plt.plot(tm[0:i],T1[0:i],'ro',MarkerSize=3,label=r'$T_1$')
        plt.plot(tm[0:i],Tsp1[0:i],'b-',MarkerSize=3,label=r'$T_1 Setpoint$')
        plt.ylabel('Temperature (degC)')
        plt.legend(loc='best')
        ax=plt.subplot(2,1,2)
        ax.grid()
        plt.plot(tm[0:i],Q1s[0:i],'r-',LineWidth=3,label=r'$Q_1$')
        plt.ylabel('Heaters')
        plt.xlabel('Time (sec)')
        plt.legend(loc='best')
        plt.draw()
        plt.pause(0.05)

    # Turn off heaters
    a.Q1(0)
    a.Q2(0)
    print('Shutting down')
    a.close()

# Allow user to end loop with Ctrl-C
except KeyboardInterrupt:
    # Disconnect from Arduino
    a.Q1(0)
    a.Q2(0)
    print('Shutting down')
    a.close()

# Make sure serial connection still closes when there's an error
except:
    # Disconnect from Arduino
    a.Q1(0)
    a.Q2(0)
    print('Error: Shutting down')
    a.close()
    raise

There is the test result picture.有测试结果图。 图片

When you add the disturbance (such as turn on the other heater), the apparent system gain increases because the temperature rises higher than anticipated by the controller.当您添加干扰(例如打开另一个加热器)时,明显的系统增益会增加,因为温度升高高于 controller 的预期。 That means you start to go left on the mismatch plot (leads to worst control performance).这意味着您开始 go 不匹配 plot (导致最差的控制性能)。

MPC 目标

This is Figure 14 in Hedengren, JD, Eaton, AN, Overview of Estimation Methods for Industrial Dynamic Systems , Optimization and Engineering, Springer, Vol 18 (1), 2017, pp. 155-178, DOI: 10.1007/s11081-015-9295-9.这是 Hedengren, JD, Eaton, AN, Overview of Estimation Methods for Industrial Dynamic Systems , Optimization and Engineering, Springer, Vol 18 (1), 2017, pp. 155-178, DOI: 10.1007/s11081-015-中的图 14 9295-9。

One of the reasons for the overshoot is because of model mismatch.过冲的原因之一是因为 model 不匹配。 Here are a few ways to deal with this:这里有几种方法可以解决这个问题:

  1. Increase your model gain K (maybe to 1) or decrease your model tau (maybe to 120) so that the controller becomes less aggressive.增加您的 model 增益K (可能为 1)或减少您的 model tau (可能为 120),以便 controller 变得不那么激进。 You may also want to re-identify your model so that it better reflects your TCLab system dynamics.您可能还想重新识别您的 model,以便它更好地反映您的 TCLab 系统动态。 Here is a tutorial on getting a first order or second order model.这是获取一二阶model 的教程。 A higher order ARX model also works well for the TCLab.更高阶的 ARX model 也适用于 TCLab。
  2. Change the reference trajectory to be less aggressive with TC.TAU=50 and include the reference trajectory on the plot so that you can observe what the controller is planning.使用TC.TAU=50将参考轨迹更改为不那么激进,并将参考轨迹包含在 plot 上,以便您可以观察 controller 的计划。 I also like to include the unbiased model on the plot to show how the model is performing.我还想在 plot 上包含无偏的 model 以展示 model 的性能。
  3. Check out this Control Tuning page for help with other MV and CV tuning options.查看此控制调整页面以获取有关其他 MV 和 CV 调整选项的帮助。 The Jupyter notebook widget can help give you an intuitive understanding of those options. Jupyter 笔记本小部件可以帮助您直观地了解这些选项。

MPC 调优

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM