allen преди 1 месец
родител
ревизия
043c44a47c
променени са 1 файла, в които са добавени 150 реда и са изтрити 0 реда
  1. 150 0
      fupid.py

+ 150 - 0
fupid.py

@@ -0,0 +1,150 @@
+import numpy as np
+import skfuzzy as fuzz
+import matplotlib.pyplot as plt
+#from  mpl_toolkit.mplot3d import Axes3D
+from skfuzzy import control as ctrl
+import math
+
+
+class PIDController:
+    def __init__(self, Kp, Ki, Kd):
+        self.Kp = Kp
+        self.Ki = Ki
+        self.Kd = Kd
+        self.last_error = 0
+        self.integral = 0
+
+    def control(self, error):
+        output = self.Kp * error + self.Ki * self.integral + self.Kd * (error - self.last_error)
+        self.integral += error
+        self.last_error = error
+
+        return output
+
+
+class TemperatureSystem:
+    def __init__(self, target_temp):
+        self.target_temp = target_temp
+        self.current_temp = 0
+
+    def update(self, control_singal):
+        self.current_temp += control_singal * 1
+        return self.current_temp
+
+    def get_error(self):
+        return self.target_temp - self.current_temp
+
+
+def train(controller,system, num_iterations):
+    errors = []
+    signal = []
+    temp = []
+    e = ctrl.Antecedent(np.arange(-80, 80, 1), 'e')
+    del_e = ctrl.Antecedent(np.arange(-6, 6, 1), 'del_e')
+    kp = ctrl.Consequent(np.arange(-0.8, 0.8, 0.01), 'kp')
+    ki = ctrl.Consequent(np.arange(-0.1, 0.1, 0.005), 'ki')
+    kd = ctrl.Consequent(np.arange(-0.1, 0.1, 0.005), 'kd')
+
+    e['NB'] = fuzz.trimf(e.universe, [-80, -80, -40])
+    e['NS'] = fuzz.trimf(e.universe, [-80, -40, 0])
+    e['ZO'] = fuzz.trimf(e.universe, [-40, 0, 40])
+    e['PS'] = fuzz.trimf(e.universe, [0, 40, 80])
+    e['PB'] = fuzz.trimf(e.universe, [40, 80, 80])
+
+    del_e['NB'] = fuzz.trimf(del_e.universe, [-6, -6, -3])
+    del_e['NS'] = fuzz.trimf(del_e.universe, [-6, -3, 0])
+    del_e['ZO'] = fuzz.trimf(del_e.universe, [-3, 0, 3])
+    del_e['PS'] = fuzz.trimf(del_e.universe, [0, 3, 6])
+    del_e['PB'] = fuzz.trimf(del_e.universe, [3, 6, 6])
+
+    kp['NB'] = fuzz.trimf(kp.universe, [-0.8, -0.8, -0.4])
+    kp['NS'] = fuzz.trimf(kp.universe, [-0.8, -0.4, 0])
+    kp['ZO'] = fuzz.trimf(kp.universe, [-0.4, 0, 0.4])
+    kp['PS'] = fuzz.trimf(kp.universe, [0, 0.4, 0.8])
+    kp['PB'] = fuzz.trimf(kp.universe, [0.4, 0.8, 0.8])
+
+    ki['NB'] = fuzz.trimf(ki.universe, [-0.02, -0.02, -0.01])
+    ki['NS'] = fuzz.trimf(ki.universe, [-0.02, -0.01, 0])
+    ki['ZO'] = fuzz.trimf(ki.universe, [-0.01, 0, 0.01])
+    ki['PS'] = fuzz.trimf(ki.universe, [0, 0.01, 0.02])
+    ki['PB'] = fuzz.trimf(ki.universe, [0.01, 0.02, 0.02])
+
+    kd['NB'] = fuzz.trimf(kd.universe, [-0.02, -0.02, -0.01])
+    kd['NS'] = fuzz.trimf(kd.universe, [-0.02, -0.01, 0])
+    kd['ZO'] = fuzz.trimf(kd.universe, [-0.01, 0, 0.01])
+    kd['PS'] = fuzz.trimf(kd.universe, [0, 0.01, 0.02])
+    kd['PB'] = fuzz.trimf(kd.universe, [0.01, 0.02, 0.02])
+
+    rule1 = ctrl.Rule((e['NB'] & del_e['NB']) | (e['PS'] & del_e['PB']), kp['PB'])
+    rule2 = ctrl.Rule((e['NB'] & del_e['NS']) | (e['NB'] & del_e['ZO']) | (e['NB'] & del_e['PS']) | (e['NS'] & del_e['NS']) | (e['NS'] & del_e['ZO']) | (e['ZO'] & del_e['NS']) | (e['PB'] & del_e['NS']) | (e['PB'] & del_e['ZO']) | (e['PB'] & del_e['PS']), kp['NS'])
+    rule3 = ctrl.Rule((e['NB'] & del_e['PB']) | (e['NS'] & del_e['PS']) | (e['ZO'] & del_e['ZO']) | (e['PS'] & del_e['NS']) | (e['PB'] & del_e['NB']), kp['ZO'])
+    rule4 = ctrl.Rule((e['NS'] & del_e['NB']) | (e['NS'] & del_e['PB']) | (e['ZO'] & del_e['NB']) | (e['ZO'] & del_e['PS']) | (e['ZO'] & del_e['PB']) | (e['PS'] & del_e['NB']) | (e['PS'] & del_e['ZO']) | (e['PS'] & del_e['PS']), kp['PS'])
+    rule5 = ctrl.Rule((e['PB'] & del_e['PB']), kp['NB'])
+
+    rule6 = ctrl.Rule((e['PS'] & del_e['PB']) | (e['PB'] & del_e['PB']), ki['PB'])
+    rule7 = ctrl.Rule((e['NB'] & del_e['NS']) | (e['NB'] & del_e['ZO']) | (e['NB'] & del_e['PS']) | (e['NS'] & del_e['NS']) | (e['NS'] & del_e['ZO'])| (e['ZO'] & del_e['NB']) | (e['ZO'] & del_e['NS']) | (e['PS'] & del_e['NB']), ki['NS'])
+    rule8 = ctrl.Rule((e['NB'] & del_e['PB']) | (e['NS'] & del_e['PS']) | (e['ZO'] & del_e['ZO']) | (e['PS'] & del_e['NS']) | (e['PB'] & del_e['NB']), ki['ZO'])
+    rule9 = ctrl.Rule((e['NS'] & del_e['PB']) | (e['ZO'] & del_e['PS']) | (e['ZO'] & del_e['PB']) | (e['PS'] & del_e['ZO']) | (e['PS'] & del_e['PS']) | (e['PB'] & del_e['NS']) | (e['PB'] & del_e['ZO'])| (e['PB'] & del_e['PS']), ki['PS'])
+    rule10 = ctrl.Rule((e['NB'] & del_e['NB'])|(e['NS'] & del_e['NB']), ki['NB'])
+
+    rule11 = ctrl.Rule((e['PB'] & del_e['NB']) | (e['PB'] & del_e['PB']), kd['PB'])
+    rule12 = ctrl.Rule((e['NS'] & del_e['NS']) | (e['NS'] & del_e['ZO']) | (e['NS'] & del_e['PS']) | (e['ZO'] & del_e['NS']) | (e['ZO'] & del_e['ZO'])| (e['ZO'] & del_e['PS']), kd['NS'])
+    rule13 = ctrl.Rule((e['NS'] & del_e['NB']) | (e['NS'] & del_e['PB']) | (e['ZO'] & del_e['NB'])| (e['ZO'] & del_e['PB']) | (e['PS'] & del_e['NB']) | (e['PS'] & del_e['NS'])| (e['PS'] & del_e['ZO'])| (e['PS'] & del_e['PS'])| (e['PS'] & del_e['PB']), kd['ZO'])
+    rule14 = ctrl.Rule((e['NS'] & del_e['PB']) | (e['ZO'] & del_e['PS']) | (e['ZO'] & del_e['PB']) | (e['PS'] & del_e['ZO']) | (e['PS'] & del_e['PS']) | (e['PB'] & del_e['NS']) | (e['PB'] & del_e['ZO'])| (e['PB'] & del_e['PS']), kd['PS'])
+    rule15 = ctrl.Rule((e['NB'] & del_e['NS'])|(e['NB'] & del_e['ZO'])|(e['NB'] & del_e['PS']), kd['NB'])
+
+    sys = ctrl.ControlSystem([rule1, rule2, rule3, rule4, rule5,rule6, rule7, rule8, rule9, rule10, rule11, rule12, rule13, rule14, rule15])
+    fu = ctrl.ControlSystemSimulation(sys)
+
+    for _ in range(num_iterations):
+        error = system.get_error()
+        fu.input['e']=error
+        fu.input['del_e']= error-controller.last_error
+        fu.compute()
+        controller.Kp += fu.output['kp']
+        controller.Ki += fu.output['ki']
+        controller.Kd += fu.output['kd']
+        print("KP:",controller.Kp,"KI:",controller.Ki,"KD:",controller.Kd,"error:",error,"del_error:",error-controller.last_error)
+        control_signal = controller.control(error)
+        # system.update(control_signal)
+        temp.append(system.update(control_signal))
+        errors.append(error)
+        signal.append(control_signal)
+    return temp
+
+#controller.input['e']=20
+#controller.input['del_e']=2
+#controller.compute()
+#p=controller.output['kp']
+#print(p)
+
+#upsampled = np.linspace(-10,10,21)
+#x,y=np.meshgrid(upsampled,upsampled)
+#z=np.zeros_like(x)
+#pp=[]
+#for i in range(0,10):
+#    for j in range(-10,10):
+#        controller.input['e']=x[i,j]
+#        controller.input['del_e']=y[i,j]
+#        controller.compute()
+#        z[i,j]=controller.output['kp']
+#        pp.append(z[i,j])
+
+#fig = plt.figure(figsize=(10,10))
+#ax = fig.add_subplot(111,projection='3d')
+#surf = ax.plot_surface(x,y,z,rstride=1,cstride=1,cmap='viridis',linewidth=0.4,antialiased=True)
+#ax.view_init(30,200)
+#plt.show()
+
+
+
+target_temp = 30
+pid_controller = PIDController(0.4,0,0)
+temperature_system = TemperatureSystem(target_temp)
+temp = train(pid_controller,temperature_system, 10)
+plt.plot(temp, 'ro--', linewidth=2, markersize=6, label="fuzzy")  # 簡化後的程式碼
+plt.xlabel('Time')
+plt.ylabel('temp')
+plt.title('ML PID control')
+plt.legend()
+plt.show()