[英]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, MINLP
) large-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
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 (导致最差的控制性能)。
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:
这里有几种方法可以解决这个问题:
K
(maybe to 1) or decrease your model tau
(maybe to 120) so that the controller becomes less aggressive.K
(可能为 1)或减少您的 model tau
(可能为 120),以便 controller 变得不那么激进。 You may also want to re-identify your model so that it better reflects your TCLab system dynamics.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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.