class MassSpringDamper(object):
def __init__(self, m=1.0, b=10.0, k=20.0, f=0.0):
self.m, self.b, self.k, self.f = m, b, k, f
def function(self, t, x_state):
x = x_state[0]
v = x_state[1]
dx = v
dv = (self.f - self.k * x - self.b * v) / self.m
return [dx, dv]
class PID(object):
def __init__(self, kp, ki, kd, dt):
self.kp, self.ki, self.kd, self.dt = kp, ki, kd, dt
self.last_error = None
self.status = 0.0
def update(self, error):
p = self.kp * error
i = self.ki * self.status
if self.last_error is None:
d = 0.0
else:
d = self.kd * (error - self.last_error) / self.dt
self.status += error * self.dt
self.last_error = error
return p + i + d
import numpy as np
from scipy.integrate import ode
from Python_SciPy.PID_Control import system
from Python_SciPy.PID_Control import controler
import matplotlib.pyplot as plt
def pid_control_system(kp, ki, kd, dt=0.01, end_time=3.0, target=3.0):
x0_state = np.array([0.0, 0.0])
t0 = 0.0
sys = system.MassSpringDamper()
pid = controler.PID(kp, ki, kd, dt)
r = ode(sys.function)
r.set_integrator('vode', method='bdf')
r.set_initial_value(x0_state, t0)
t = [0]
result = [x0_state]
F_arr = [0]
while r.successful() and r.t+dt < end_time:
r.integrate(r.t + dt)
err = target - r.y[0]
F = pid.update(err)
sys.f = F
print('时间: %s, 状态: %s, 外控制力: %s' % (r.t, r.y[0], F))
t.append(r.t)
result.append(r.y)
F_arr.append(F)
result_np = np.array(result)
t_np = np.array(t)
F_arr_np = np.array(F_arr)
return [t_np, F_arr_np, result_np]
def PlotFigure(t, F, x_state):
plt.figure(figsize=(12, 8))
plt.plot(t, F, color='red', label='Force', linewidth=2)
plt.title('PID_Control_State or F')
plt.xlabel('time/s')
plt.ylabel('x and v or F')
plt.legend()
plt.grid()
plt.show()
if __name__ == '__main__':
[t, F_arr, result] = pid_control_system(50.0, 100.0, 10.0)
print('_______________________________________')
print('程序自身在运行')
print('控制力的终值:', F_arr[-1])
print(result.shape)
print('_______________________________________')
PlotFigure(t, F_arr, result)
else:
print('我是被引入')
外部控制力变化如下
|