我不知道之前是否已经问过这个问题,我会继续在这里发布,我试图解决一个带有PID控制器的简单系统,下面给出了我的微分方程系统。我基本上试图编写非常基本的PID算法。我的控制结构取决于误差项的导数和积分。我对衍生术语没有任何问题,它是在我的代码中创建问题的积分术语。当我在开头指定s = 0时,问题就出现了 并在我的函数中使用它,如下面的代码所述。有没有办法绕过它?我尝试分配s并告诉全局变量,但它没有解决我的问题。简而言之,我正在做的是 - 我每次都添加状态x1并乘以dt(用t-tell表示)。
请帮助我解决这个问题,PFA我的代码附在下面。
import numpy as np
from scipy.integrate import ode
import matplotlib.pyplot as plt
plt.style.use('bmh')
t0=0
y0=[0.1,0.2]
kp,kd,ki=2,0.5,0.8
s,told=0,0
def pid(t,Y):
x1,x2=Y[0],Y[1]
e=x1-1
de=x2
s=(x1+s)
integral=s*(t-told)
told=t
#ie=
u=kp*e+kd*de+ki*integral
x1dot=x2
x2dot=u-5*x1-2*x2
return[x1dot,x2dot]
solver=ode(pid).set_integrator('dopri5',rtol=1e-6,method='bdf',nsteps=1e5,max_step=1e-3)
solver.set_initial_value(y0,t0)
t1=10
dt=5e-3
sol = [ [yy] for yy in y0 ]
t=[t0]
while solver.successful() and solver.t<t1:
solver.integrate(solver.t+dt)
for k in range(2): sol[k].append(solver.y[k]);
t.append(solver.t)
print(len(sol[0]))
print(len(t))
x1=np.array(sol[0])
x2=np.array(sol[1])
e=x1-1
de=x2
u=kp*e+kd*de
for k in range(2):
if k==0:
plt.subplot(2,1,k+1)
plt.plot(t,sol[k],label='x1')
plt.plot(t,sol[k+1],label='x2')
plt.legend(loc='lower right')
else:
plt.subplot(2,1,k+1)
plt.plot(t,u)
plt.show()
答案 0 :(得分:0)
首先,您需要在pid函数中包含“s”变量。
” def pid(s,t,Y):... “
答案 1 :(得分:0)
我现在能看到的最简单的解决方案是创建一个以s
和told
作为此类属性的类:
class PIDSolver:
def __init__(self)
self.t0=0
self.y0=[0.1,0.2]
self.kp,self.kd,self.ki=2,0.5,0.8
self.s,self.told=0,0
def pid(t,Y):
x1,x2=Y[0],Y[1]
e=x1-1
de=x2
self.s=(x1+self.s)
integral=self.s*(t-self.told)
self.told=t
#ie=
u=self.kp*e+self.kd*de+self.ki*integral
x1dot=x2
x2dot=u-5*x1-2*x2
return[x1dot,x2dot]
问题的第一部分。在解决方案的下一部分中使用pidsolver = PIDSolver()
。
答案 2 :(得分:0)
我自己通过使用set_f_params()
方法并在itz参数中传递列表来解决此问题。我还在pid()
中传递了第3个参数,即pid(t,Y,arg)
。最后我分配了s,told=arg[0],arg[1]
。
答案 3 :(得分:0)
您正在假设解算器及其访问的时间步骤是不合理的。随着你对积分的破解,即使它在数学上是合理的(它应该看起来像integral = integral + e*(t-told)
,它提供了一个1阶积分方法),你减少了任何积分方法的顺序,可能降到1,如果你是幸运只能订购2.
实现此系统的数学上正确的方法是为x3
的积分引入第三个变量e
,即x3
的导数为e
。正确的订单1系统必须是维度3,可以读取(消除e
)您的系统具有3个区分/集成操作的事实。随之而来的是你的系统
def pid(t,Y):
x1, x2, x3 =Y
e=x1-1
x1dot = x2
edot = x1dot
x3dot = e
u=kp*e+kd*edot+ki*x3
x2dot=u-5*x1-2*x2
return[x1dot, x2dot, x3dot]
请注意,没有必要的全局动态变量,只有常量(也可以作为参数传递,无论看起来更有效还是可读)。
现在您还需要x3
的初始值,系统无法看到集成变量必须是什么,您的代码似乎建议0
。