import pandas as pd
= pd.read_csv('data/step-test-data.csv')
df = df.set_index('Time')
df =True) df.plot(grid
Adattamento dei dati dei test di fase ai modelli empirici
Leggi il file dati
Parametro
Adattamento dei dati di modifica del passo a un modello del primo ordine
Per un sistema lineare del primo ordine inizialmente allo stato stazionario, la risposta a una variazione dell’ingresso a gradino a
dove
le celle seguenti forniscono le stime iniziali per il guadagno in stato stazionario
Lettura dei dati salvati
'Q1','T1','T2']].plot(grid=True) df[[
Stima del guadagno e della costante di tempo
Nel limite
che fornisce un metodo per stimare
Questi calcoli vengono eseguiti di seguito dove utilizziamo la prima e l’ultima misurazione di
= df['T1']
T1 = df['Q1']
Q1
= max(T1) - min(T1)
DeltaT1 = Q1.mean()
DeltaQ1
= DeltaT1/DeltaQ1
K1 print("K1 is approximately", K1)
K1 is approximately 0.6968700000000001
# find when the increase in T1 gets larger than 63.2% of the final increase
= (T1 - T1.min()) > 0.632*(T1.max()-T1.min())
i = T1.index[i].min()
tau1 print("tau1 is approximately", tau1, "seconds")
tau1 is approximately 163.0 seconds
import matplotlib.pyplot as plt
import numpy as np
= np.exp
exp = df.index
t
= T1.min() + K1*(1 - exp(-t/tau1))*DeltaQ1
T1_est
=(10,5))
plt.figure(figsize= plt.subplot(2,1,1)
ax 'T1'].plot(ax = ax, grid=True)
df[
plt.plot(t,T1_est)'Step Test Data Compared to Model')
plt.title(
2,1,2)
plt.subplot(-T1)
plt.plot(t,T1_est
plt.grid()'Residual Error') plt.title(
Text(0.5, 1.0, 'Residual Error')
Un modello del primo ordine cattura determinate caratteristiche e fornisce un risultato ragionevolmente buono quando il sistema si avvicina a un nuovo stato stazionario. Il problema, tuttavia, è che per il controllo abbiamo bisogno di un buon modello durante il transitorio iniziale. È qui che il modello del primo ordine crolla e prevede una risposta qualitativamente diversa da quella che osserviamo.
Primo Ordine più Ritardo (o Tempo Morto)
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from ipywidgets import interact
= pd.read_csv('data/step-test-data.csv')
df = df.set_index('Time')
df
= df['T1']
T1 = df['Q1']
Q1 = df.index
t
= max(T1) - min(T1)
DeltaT1 = Q1.mean()
DeltaQ1
= DeltaT1/DeltaQ1
K1 = (T1 - T1.min()) > 0.632*(T1.max()-T1.min())
i = T1.index[i].min()
tau1
def fopdt(K=K1, tau=tau1, theta=0, T10=T1.min()):
def Q1(t):
return 0 if t < 0 else DeltaQ1
= np.vectorize(Q1)
Q1vec = T10 + K*(1-np.exp(-(t-theta)/tau))*Q1vec(t-theta)
T1_fopdt =(10,5))
plt.figure(figsize2,1,1)
plt.subplot(
plt.plot(t,T1_fopdt)'T1'])
plt.plot(t,df[2,1,2)
plt.subplot(- T1)
plt.plot(t,T1_fopdt
plt.show()
=(0,1,.001),tau=(50,200,.5),theta=(0,50,.5),T10=(15,25,.1)) interact(fopdt,K
<function __main__.fopdt(K=0.6968700000000001, tau=163.0, theta=0, T10=20.9)>
Secondo ordine
SEMD Equaz. 5-48
from scipy.optimize import least_squares
import numpy as np
= 50
Qmax
def f(x):
= x
K,tau1,tau2,T10 = df.index
t = np.exp
exp = T10 + K*(1 - (tau1*exp(-t/tau1) - tau2*exp(-t/tau2))/(tau1-tau2))*Qmax
Tpred = df['T1'] - Tpred
resid return resid
= [0.86,40,130,20]
ic
= least_squares(f,ic,bounds=(0,np.inf))
r r.x
array([ 0.69537389, 19.68872647, 141.40950924, 20.91093839])
E la funzione di trasferimento risultante è: