-
Notifications
You must be signed in to change notification settings - Fork 0
/
pi_controller.py
68 lines (48 loc) · 1.92 KB
/
pi_controller.py
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
import numpy as np
import matplotlib.pyplot as plt
import json
class PI_Controller:
def __init__(self, pi_controller_data):
self.K_p = pi_controller_data["K_p"]
self.T_i = pi_controller_data["T_i"]
self.A = np.matrix([0])
self.B = np.matrix([self.K_p/self.T_i])
self.C = np.matrix([1])
self.D = np.matrix([self.K_p])
x11 = pi_controller_data["init"]
self.x = np.matrix([x11])
self.sat = pi_controller_data["sat"]
self.T_a = pi_controller_data["T_a"]
self.anti = pi_controller_data["anti"]
def simulation_euler(self, dt, iterations, u_dict):
y = np.zeros(iterations)
for i in range(iterations):
u = u_dict["e"][i]
y[i] = self.C*self.x + self.D*u
self.x = self.x + dt*(self.A*self.x + self.B*u)
return y
def simulation_euler_anti_windup(self, dt, iterations, u_dict, **kwargs):
# Prepare arrays for signals
y = np.zeros(iterations)
y_prim = np.zeros(iterations)
for i in range(iterations):
if "show" in kwargs.keys() and kwargs["show"]:
if (i+1)%1000 == 0:
print(str(((i+1)/iterations)*100)+"%")
u = u_dict["e"][i]
y[i] = self.C*self.x + self.D*u
self.x = self.x + dt*(self.A*self.x + self.B*u + self.anti)
# anti wind-up system
if y[i] > self.sat:
y_prim[i] = self.sat
elif y[i] < -self.sat:
y_prim[i] = -self.sat
else:
y_prim[i] = y[i]
self.anti = (y_prim[i] - y[i])/self.T_a
y_dict = {"y": y_prim}
return y_dict
if __name__ == "__main__":
# Simulation data
pi_controller_data = json.load(open("./pi_controller_data.json"))
pi_controller = PI_Controller(pi_controller_data)