# 一种基于云平台负载的非线性控制系统设计

N=10, R=n*N, C=(n+2)*N

PID的Python代码实现如下：

!/usr/bin/python

import time

class PID: def __init__(self, P=0.2, I=0.0, D=0.0):

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72  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): #Clears PID computations and coefficients self.SetPoint = 0.0 self.PTerm = 0.0 self.ITerm = 0.0 self.DTerm = 0.0 self.last\_error = 0.0 # Windup Guard self.int\_error = 0.0 self.windup\_guard = 20.0 self.output = 0.0 def update(self, feedback\_value): # Calculates PID value for given reference feedback 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 if (self.ITerm < -self.windup\_guard): self.ITerm = -self.windup\_guard elif (self.ITerm > self.windup\_guard): self.ITerm = self.windup\_guard self.DTerm = 0.0 if delta\_time > 0: self.DTerm = delta\_error / delta\_time # Remember last time and last error for next calculation self.last\_time = self.current\_time self.last\_error = error self.output = self.PTerm + (self.Ki \* self.ITerm) + (self.Kd \* self.DTerm) def setKp(self, proportional\_gain): # Determines how aggressively the PID reacts to the current error with setting Proportional Gain self.Kp = proportional\_gain def setKi(self, integral\_gain): # Determines how aggressively the PID reacts to the current error with setting Integral Gain self.Ki = integral\_gain def setKd(self, derivative\_gain): # Determines how aggressively the PID reacts to the current error with setting Derivative Gain self.Kd = derivative\_gain def setWindup(self, windup): # unwound self.windup\_guard = windup def setSampleTime(self, sample\_time): # PID that should be updated at a regular interval. self.sample\_time = sample\_time 

import PID import time import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import spline

def test_pid(P = 0.2, I = 0.0, D= 0.0, L=100): """Self-test PID class

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 .. note:: ... for i in range(1, END): pid.update(feedback) output = pid.output if pid.SetPoint > 0: feedback += (output - (1/i)) if i>9: pid.SetPoint = 1 time.sleep(0.02) --- """ pid = PID.PID(P, I, D) pid.clear() pid.SetPoint=0.0 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 if pid.SetPoint > 0: feedback += (output - (1/i)) if i<10: pid.SetPoint = 20 if i>20: pid.SetPoint = 50 if i>22: pid.SetPoint = 100 if i>24: pid.SetPoint = 10 if i>28: pid.SetPoint = 200 if i>30: pid.SetPoint = 200 if i>70: pid.SetPoint = 20 feedback\_list.append(feedback) setpoint\_list.append(pid.SetPoint) time\_list.append(i) time.sleep(0.02) time\_sm = np.array(time\_list) time\_smooth = np.linspace(time\_sm.min(), time\_sm.max(), 300) feedback\_smooth = spline(time\_list, feedback\_list, time\_smooth) plt.plot(time\_smooth, feedback\_smooth) plt.plot(time\_list, setpoint\_list) plt.xlim((0, L)) plt.ylim((min(feedback\_list)-0.5, max(feedback\_list)+0.5)) plt.xlabel('time (s)') plt.ylabel('PID C-R') plt.grid(True) plt.show() 

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