PID 控制器代码实现

PID 控制器代码实现

  • PID 控制器代码实现
    • 效果展示
    • 实现代码

PID 控制器代码实现

PID:比列(Proportion),积分(Integral),微分(Differential)

偏差 e:某时刻的系统的输出值(output)和目标值(target)之差
Kp: 比列系数
Ki: 积分系数
Kd: 微分系数
Ti: 积分时间
Td: 微分时间

比例系数Kp:

增大比例系数使系统反应灵敏,调节速度加快,并且可以减小稳态误差。但是比例系数过大会使超调量增大,振荡次数增加,调节时间加长,动态性能变坏,比例系数太大甚至会使闭环系统不稳定。

比例控制不能消除稳态误差

积分系数Ki:
使系统消除稳态误差,提高无差度。积分控制的作用是,只要系统有误差存在,积分调节就进行,积分控制器就不断地积累,输出控制量,直至无差,积分调节停止,积分调节输出一常值。因而,只要有足够的时间,积分控制将能完全消除误差,使系统误差为零,从而消除稳态误差。积分作用的强弱取决于积分时间常数Ti,Ti越小,积分作用就越强,积分作用太强会使系统超调加大,甚至使系统出现振荡,反之Ti大则积分作用弱。加入积分调节可使系统稳定性下降,动态响应变慢

微分系数Kd:
微分控制可以减小超调量,克服振荡,使系统的稳定性提高,同时加快系统的动态响应速度,减小调整时间,从而改善系统的动态性能。

微分的控制作用跟偏差的变化的速度有关,微分控制能够预测偏差,产生超前的校正作用,有助于减少超调。

效果展示

  • 参数 1.5, 1, 0.01
    PID 控制器代码实现_第1张图片
  • 参数 2.5,1, 0.01
    PID 控制器代码实现_第2张图片
  • 参数 1.5, 5, 0.01
    PID 控制器代码实现_第3张图片
  • 参数

实现代码

# this code refer to CSDN and do some minor change. 
import time

class PID:
    def __init__(self, P, I, D):
        self.Kp = P
        self.Ki = I
        self.Kd = D
        self.sample_time = 0.00
        self.current_time = time.time()
        self.last_time = self.current_time
        self.clear()
    def clear(self):
        self.SetPoint = 0.0
        self.PTerm = 0.0
        self.ITerm = 0.0
        self.DTerm = 0.0
        self.last_error = 0.0
        self.int_error = 0.0
        self.output = 0.0
    def update(self, feedback_value):
        error = self.SetPoint - feedback_value
        self.current_time = time.time()
        delta_time = self.current_time - self.last_time
        delta_error = error - self.last_error
        if (delta_time >= self.sample_time):
            self.PTerm = self.Kp * error#比例
            self.ITerm += error * delta_time#积分
            self.DTerm = 0.0
            if delta_time > 0:
                self.DTerm = delta_error / delta_time#微分
            self.last_time = self.current_time
            self.last_error = error
            self.output = self.PTerm + (self.Ki * self.ITerm) + (self.Kd * self.DTerm)


    def setSampleTime(self, sample_time):
        self.sample_time = sample_time

# import PID #导入上面的PID算法
import time
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import splrep


def test_pid(P, I , D, L):

    pid = PID(P, I, D)

    pid.SetPoint=1.1
    pid.setSampleTime(0.01)

    END = L
    feedback = 0
    feedback_list = []
    time_list = []
    setpoint_list = []

    for i in range(1, END):
        pid.update(feedback)
        output = pid.output
        feedback +=output #PID控制系统的函数
        time.sleep(0.01)
        feedback_list.append(feedback)
        setpoint_list.append(pid.SetPoint)
        time_list.append(i)

    time_sm = np.array(time_list)
    time_smooth = np.linspace(time_sm.min(), time_sm.max(), 300)
    # print(len(time_list), len(feedback_list), len(time_smooth))
    # feedback_smooth = splrep(time_list, feedback_list) #, time_smooth)
    plt.figure(0)
    plt.grid(True)
    # plt.plot(time_smooth, feedback_smooth,'b-')
    plt.plot(time_list, feedback_list,'b-')
    plt.plot(time_list, setpoint_list,'r')
    plt.xlim((0, L))
    plt.ylim((min(feedback_list)-0.5, max(feedback_list)+0.5))
    plt.xlabel('time (s)')
    plt.ylabel('PID (PV)')
    plt.title('PythonTEST PID--xiaomokuaipao',fontsize=15)

    plt.ylim((1-0.5, 1+0.5))

    plt.grid(True)
    plt.show()

if __name__ == "__main__": 
    test_pid(1.5, 1, 0.001, L=100)

你可能感兴趣的:(解决问题)