├── .gitignore ├── LICENSE ├── README.md ├── demo.gif ├── result ├── PID_result.png ├── compare3.png ├── compare4.png ├── compare5.png ├── compare6.png ├── fuzzy_pid_result.png ├── membership1.png ├── membership2.png └── membership3.png ├── scripts ├── fuzzy_result.py └── pid_result.py ├── src ├── Fuzzy_PID.py ├── PID.py └── __init__.py └── test ├── fuzzy_test.py └── gym_tester.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ryan Zirui Zhao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fuzzy-Control-Project 2 | 3 | Classic PID Controler and Fuzzy PID controler. 4 | 5 | ## Demo 6 | 7 | ![Demo](demo.gif) 8 | 9 | The Fuzzy Self-Adaptive PID controler has better performance in control problems. Here are some result of the demo. 10 | 11 | ![result](./result/compare3.png) 12 | ![result2](./result/compare4.png) 13 | 14 | ## Prerequisite 15 | 16 | * Python 3.6.8 17 | * Scikit-Fuzzy 18 | * Gym 19 | 20 | ## Structure 21 | 22 | ``` 23 | /src 24 | __init__.py 25 | Fuzzy_PID.py 26 | PID.py 27 | /scripts 28 | fuzzy_result.py 29 | pid_result.py 30 | /test 31 | * 32 | LICENSE 33 | README.md 34 | .gitignore 35 | ``` -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/demo.gif -------------------------------------------------------------------------------- /result/PID_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/PID_result.png -------------------------------------------------------------------------------- /result/compare3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/compare3.png -------------------------------------------------------------------------------- /result/compare4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/compare4.png -------------------------------------------------------------------------------- /result/compare5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/compare5.png -------------------------------------------------------------------------------- /result/compare6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/compare6.png -------------------------------------------------------------------------------- /result/fuzzy_pid_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/fuzzy_pid_result.png -------------------------------------------------------------------------------- /result/membership1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/membership1.png -------------------------------------------------------------------------------- /result/membership2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/membership2.png -------------------------------------------------------------------------------- /result/membership3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1989Ryan/Fuzzy-Control-Project/ce01efe28526d5a39e499ffff23679cc06260710/result/membership3.png -------------------------------------------------------------------------------- /scripts/fuzzy_result.py: -------------------------------------------------------------------------------- 1 | import skfuzzy 2 | import time 3 | import os 4 | import sys 5 | lib_path = os.path.abspath(os.path.join(sys.path[0], '..')) 6 | sys.path.append(lib_path) 7 | import gym 8 | import matplotlib.pyplot as plt 9 | from src.Fuzzy_PID import * 10 | from src.PID import * 11 | import math 12 | import numpy as np 13 | 14 | Ctl = Fuzzy_PID(10,7,4,2,1.15, 0.75) 15 | Ctl.setKp(11,3) 16 | Ctl.setKi(10,0) 17 | Ctl.setKd(0.9,0.3) 18 | Ctl.setSampleTime(0.05) 19 | Ctl.setSetPoint(1.1) 20 | graph = [] 21 | error = [] 22 | ISE = 0.0 23 | IAE = 0.0 24 | env = gym.make('Pendulum-v0') 25 | observation = env.reset() 26 | for i in range(500): 27 | env.render() 28 | Ctl.clear() 29 | for t in range(500): 30 | env.render() 31 | feedback, thbot = env.state 32 | graph.append(feedback) 33 | error.append(Ctl.SetPoint-feedback) 34 | ISE += (Ctl.SetPoint - feedback)*0.05 35 | IAE += (Ctl.SetPoint - feedback)**2*0.05 36 | Ctl.update(feedback, thbot) 37 | action = [Ctl.output+np.random.random()] 38 | print(action) 39 | print(Ctl.PTerm, Ctl.ITerm,Ctl.DTerm) 40 | observation, reward, done, info = env.step(action) 41 | plt.plot(graph[::10], "^-", label = "fuzzy pid") 42 | graph = [] 43 | 44 | Ctl = PID() 45 | Ctl.setKp(7) 46 | Ctl.setKi(3) 47 | Ctl.setKd(0.6) 48 | Ctl.setSampleTime(0.05) 49 | graph = [] 50 | 51 | observation = env.reset() 52 | for t in range(500): 53 | env.render() 54 | print(observation) 55 | feedback, thbot = env.state 56 | graph.append(feedback) 57 | print(feedback) 58 | Ctl.update(feedback) 59 | action = [Ctl.output+np.random.random()] 60 | print(action) 61 | print(Ctl.PTerm, Ctl.ITerm,Ctl.DTerm) 62 | observation, reward, done, info = env.step(action) 63 | plt.plot(graph[::10], "^-",label = "classic PID") 64 | 65 | graph = [] 66 | plt.title("PID performance_with_noise") 67 | plt.legend(loc="upper right") 68 | string = "../result/"+str(time.time())+"Fuzzy_graph.png" 69 | plt.savefig(string) 70 | env.close() 71 | print(ISE) 72 | print(IAE) -------------------------------------------------------------------------------- /scripts/pid_result.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | lib_path = os.path.abspath(os.path.join(sys.path[0], '..')) 4 | sys.path.append(lib_path) 5 | import gym 6 | import matplotlib.pyplot as plt 7 | from src.PID import * 8 | import math 9 | import time 10 | 11 | Ctl = PID() 12 | Ctl.setKp(9) 13 | Ctl.setKi(4) 14 | Ctl.setKd(0.85) 15 | Ctl.setSampleTime(0.05) 16 | graph = [] 17 | 18 | env = gym.make('Pendulum-v0') 19 | for i_episode in range(10): 20 | observation = env.reset() 21 | Ctl.clear() 22 | for t in range(300): 23 | env.render() 24 | print(observation) 25 | feedback, thbot = env.state 26 | graph.append(feedback) 27 | print(feedback) 28 | Ctl.update(feedback) 29 | action = [Ctl.output] 30 | print(action) 31 | print(Ctl.PTerm, Ctl.ITerm,Ctl.DTerm) 32 | observation, reward, done, info = env.step(action) 33 | plt.plot(graph[::10], "^-") 34 | graph = [] 35 | plt.title("PID performance") 36 | string = "../result/"+str(time.time())+"PIDgraph.png" 37 | plt.savefig(string) 38 | env.close() -------------------------------------------------------------------------------- /src/Fuzzy_PID.py: -------------------------------------------------------------------------------- 1 | import skfuzzy as sf 2 | import time 3 | import numpy as np 4 | from math import pi, log 5 | 6 | class Fuzzy_PID: 7 | 8 | def __init__(self, Pmax, Pmin, Imax, Imin, Dmax, Dmin): 9 | self.Kpmax = Pmax 10 | self.Kpmin = Pmin 11 | self.Kimax = Imax 12 | self.Kimin = Imin 13 | self.Kdmax = Dmax 14 | self.Kdmin = Dmin 15 | self.sample_time = 0.0 16 | self.current_time = time.time() 17 | self.last_time = self.current_time 18 | self.tfm = self.tfm_generator(-pi, pi) 19 | self.dtfm = self.tfm_generator(-8,8) 20 | self.re = self.rule() 21 | self.rde = self.re.T 22 | self.rie = self.rule_ki() 23 | self.a = self.rule_alpha() 24 | self.b = self.a.T 25 | self.clear() 26 | 27 | def tfm_generator(self, xmin, xmax): 28 | x = (xmax - xmin)/2 29 | 30 | NB = np.array([xmin, xmin, xmin+1/3*x], dtype = np.float) 31 | NM = np.array([xmin, xmin+1/3*x, xmin+2/3*x], dtype = np.float) 32 | NS = np.array([xmin+1/3*x, xmin+2/3*x, xmin+x], dtype = np.float) 33 | ZE = np.array([xmin+2/3*x, xmin+x, xmax - 2/3*x], dtype = np.float) 34 | PS = np.array([xmin+x, xmax-2/3*x, xmax-x/3], dtype = np.float) 35 | PM = np.array([xmax-2/3*x, xmax-x/3, xmax], dtype = np.float) 36 | PB = np.array([xmax - 1/3*x, xmax, xmax], dtype = np.float) 37 | 38 | return [NB, NM, NS, ZE, PS, PM, PB] 39 | 40 | def membership(self, x, tfm): 41 | x = np.array([x]) 42 | return [sf.trimf(x, tfm[0]), sf.trimf(x, tfm[1]),sf.trimf(x, tfm[2]),\ 43 | sf.trimf(x, tfm[3]),sf.trimf(x, tfm[4]),sf.trimf(x, tfm[5]),sf.trimf(x, tfm[6])] 44 | 45 | def rule(self): 46 | return np.matrix([[3,4,5,6,5,4,3],[2,3,4,5,4,3,2],[1,2,3,4,3,2,1],\ 47 | [0,1,2,3,2,1,0],[1,2,3,4,3,2,1],[2,3,4,5,4,3,2],[3,4,5,6,5,4,3]]) 48 | 49 | def rule_alpha(self): 50 | return np.matrix([[2,2,2,2,2,2,2],[3,3,2,2,2,3,3],[4,3,3,2,3,3,4],\ 51 | [5,4,3,3,3,4,5],[4,3,3,2,3,3,4],[3,3,2,2,2,3,3],[2,2,2,2,2,2,2]]) 52 | 53 | def rule_ki(self): 54 | return np.matrix([[0,0,0,0,0,0,0],[0,0,0,1,0,0,0],[0,0,2,2,2,0,0],\ 55 | [0,2,4,2,4,2,0],[0,0,2,2,2,0,0],[0,0,0,1,0,0,0],[0,0,0,0,0,0,0]]) 56 | 57 | def clear(self): 58 | self.SetPoint = 0.0 59 | self.PTerm = 0.0 60 | self.ITerm = 0.0 61 | self.DTerm = 0.0 62 | self.last_error = 0.0 63 | self.int_error = 0.0 64 | self.windup_guard = 10.0 65 | self.output = 0.0 66 | 67 | def update_K(self, error, d_error): 68 | self.Kp = self.re[np.argmax(self.membership(error,self.tfm)),\ 69 | np.argmax(self.membership(d_error, self.dtfm))]/6 *(self.Kpmax-self.Kpmin)+self.Kpmin 70 | self.Kd = self.rde[np.argmax(self.membership(error, self.tfm)),\ 71 | np.argmax(self.membership(d_error, self.dtfm))]/6 *(self.Kdmax-self.Kdmin)+self.Kdmin 72 | self.alpha = self.a[np.argmax(self.membership(error, self.tfm)),\ 73 | np.argmax(self.membership(d_error, self.dtfm))] 74 | self.Ki = self.rie[np.argmax(self.membership(error, self.tfm)),\ 75 | np.argmax(self.membership(d_error, self.dtfm))]/4 *(self.Kimax - self.Kimin)+self.Kimin 76 | 77 | def update(self, feedback_value, speed): 78 | error = self.SetPoint - feedback_value 79 | 80 | self.current_time = time.time() 81 | delta_time = self.current_time - self.last_time 82 | delta_error = error - self.last_error 83 | d_error = speed 84 | self.update_K(error, d_error) 85 | 86 | if (delta_time >= self.sample_time): 87 | pTerm = self.Kp * error 88 | if (pTerm < -self.windup_guard): 89 | self.PTerm = -self.windup_guard 90 | elif (pTerm > self.windup_guard): 91 | self.PTerm = self.windup_guard 92 | else: 93 | self.PTerm = pTerm 94 | self.ITerm += self.Ki * error * delta_time 95 | if (self.ITerm < -self.windup_guard): 96 | self.ITerm = -self.windup_guard 97 | elif (self.ITerm > self.windup_guard): 98 | self.ITerm = self.windup_guard 99 | if delta_time > 0: 100 | self.DTerm = self.Kd * delta_error / delta_time 101 | if (self.DTerm < -self.windup_guard): 102 | self.DTerm = -self.windup_guard 103 | elif (self.DTerm > self.windup_guard): 104 | self.DTerm = self.windup_guard 105 | self.last_time = self.current_time 106 | self.last_error = error 107 | 108 | Output = self.PTerm + (self.ITerm) + (self.DTerm) 109 | if Output > 15: 110 | self.output = 15 111 | elif Output < -15: 112 | self.output = -15 113 | else: 114 | self.output = Output 115 | 116 | def setKp(self, Pmax, Pmin): 117 | self.Kpmax = Pmax 118 | self.Kpmin = Pmin 119 | 120 | def setKd(self, Dmax, Dmin): 121 | self.Kdmax = Dmax 122 | self.Kdmin = Dmin 123 | 124 | def setKi(self, Imax, Imin): 125 | self.Kimax = Imax 126 | self.Kimin = Imin 127 | 128 | def setSampleTime(self, sample_time): 129 | self.sample_time = sample_time 130 | 131 | def setSetPoint(self, setpoint): 132 | self.SetPoint = setpoint -------------------------------------------------------------------------------- /src/PID.py: -------------------------------------------------------------------------------- 1 | ''' 2 | PID Controler In Python 3 | Author: Ryan Zirui Zhao 4 | Email: ryan_zzr@outlook.com 5 | 6 | This is a simple PID control algorithm for python, using OOP. 7 | ''' 8 | 9 | import time 10 | 11 | class PID: 12 | 13 | def __init__(self, P = 0.2, I = 0, D = 0): 14 | ''' 15 | Initialization. 16 | :param P: Proportional Parameter 17 | :param I: integral Parameter 18 | :param D: Derivative Parameter 19 | ''' 20 | self.Kp, self.Ki, self.Kd = P, I, D 21 | self.sample_time = 0.0 22 | self.current_time = time.time() 23 | self.last_time = self.current_time 24 | self.clear() 25 | 26 | def clear(self): 27 | ''' 28 | Clear all parameters. 29 | ''' 30 | self.SetPoint = 0.0 31 | self.PTerm = 0.0 32 | self.ITerm = 0.0 33 | self.DTerm = 0.0 34 | self.last_error = 0.0 35 | 36 | self.int_error = 0.0 37 | self.windup_guard = 15.0 38 | 39 | self.output = 0.0 40 | 41 | def update(self, feedback_value): 42 | ''' 43 | State Update. 44 | :param feedback_value: Current state value 45 | ''' 46 | error = self.SetPoint - feedback_value 47 | 48 | self.current_time = time.time() 49 | delta_time = self.current_time - self.last_time 50 | delta_error = error - self.last_error 51 | 52 | if (delta_time >= self.sample_time): 53 | pTerm = self.Kp * error 54 | if (pTerm < -self.windup_guard): 55 | self.PTerm = -self.windup_guard 56 | elif (pTerm > self.windup_guard): 57 | self.PTerm = self.windup_guard 58 | else: 59 | self.PTerm = pTerm 60 | self.ITerm += self.Ki * error * delta_time 61 | if (self.ITerm < -self.windup_guard): 62 | self.ITerm = -self.windup_guard 63 | elif (self.ITerm > self.windup_guard): 64 | self.ITerm = self.windup_guard 65 | if delta_time > 0: 66 | self.DTerm = self.Kd * delta_error / delta_time 67 | if (self.DTerm < -self.windup_guard): 68 | self.DTerm = -self.windup_guard 69 | elif (self.DTerm > self.windup_guard): 70 | self.DTerm = self.windup_guard 71 | self.last_time = self.current_time 72 | self.last_error = error 73 | 74 | Output = self.PTerm + (self.ITerm) + (self.DTerm) 75 | if Output > 20: 76 | self.output = 20 77 | elif Output < -20: 78 | self.output = -20 79 | else: 80 | self.output = Output 81 | 82 | def setKp(self, Proportional_gain): 83 | self.Kp = Proportional_gain 84 | 85 | def setKi(self, Integral_gain): 86 | self.Ki = Integral_gain 87 | 88 | def setKd(self, derivative_gain): 89 | self.Kd = derivative_gain 90 | 91 | def setSampleTime(self, sample_time): 92 | self.sample_time = sample_time 93 | 94 | def setSetPoint(self, setpoint): 95 | self.SetPoint = setpoint -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | # TODO: Use OOP to finish the Fuzzy Control Project. 2 | __all__ = [ 3 | 'Fuzzy_PID', 4 | 'PID' 5 | ] -------------------------------------------------------------------------------- /test/fuzzy_test.py: -------------------------------------------------------------------------------- 1 | import skfuzzy 2 | import time 3 | import os 4 | import sys 5 | lib_path = os.path.abspath(os.path.join(sys.path[0], '..')) 6 | sys.path.append(lib_path) 7 | import gym 8 | import matplotlib.pyplot as plt 9 | from matplotlib import cm 10 | from matplotlib.colors import LogNorm 11 | from src.Fuzzy_PID import * 12 | import numpy as np 13 | import math 14 | 15 | Ctl = Fuzzy_PID(10,7,4,2,1.15, 0.75) 16 | Ctl.setKp(10,3) 17 | Ctl.setKi(9,0) 18 | Ctl.setKd(0.9,0.3) 19 | Ctl.setSampleTime(0.05) 20 | Ctl.setSetPoint(0.0) 21 | graph = [] 22 | Graph = [] 23 | a = np.arange(-pi,pi,pi/100) 24 | b = np.arange(-8,8,8/100) 25 | for i in a: 26 | for j in b: 27 | Ctl.update(i,j) 28 | graph.append(Ctl.output) 29 | Graph.append(graph) 30 | graph = [] 31 | print(Graph) 32 | plt.imshow(Graph, extent=(np.amin(a), np.amax(a), np.amax(b), np.amin(b)), 33 | cmap=cm.hot) 34 | plt.colorbar() 35 | plt.savefig('hot.png')#先存,再show 36 | plt.show() 37 | 38 | ''' 39 | tfm = Ctl.tfm_generator(-pi, pi) 40 | dtfm = Ctl.tfm_generator(-8,8) 41 | graph = [] 42 | ele = 2*8 / 100 43 | count = -8 44 | indexing = [] 45 | labels = ["NB", "NM","NS","ZE","PS","PM","PB"] 46 | for i in range(7): 47 | for j in range(100): 48 | graph.append(Ctl.membership(count, dtfm)[i]) 49 | count += ele 50 | indexing.append(count) 51 | plt.plot(indexing,graph, "-",label = labels[i]) 52 | graph = [] 53 | indexing = [] 54 | count = -8 55 | plt.title("Angle Speed Membership") 56 | plt.legend(loc = 'upper right') 57 | string = "../result/membership2.png" 58 | plt.savefig(string) 59 | ''' 60 | ''' 61 | env = gym.make('Pendulum-v0') 62 | for i_episode in range(10): 63 | observation = env.reset() 64 | Ctl.clear() 65 | for t in range(300): 66 | env.render() 67 | feedback, thbot = env.state 68 | graph.append(feedback) 69 | Ctl.update(feedback, thbot) 70 | action = [Ctl.output] 71 | print(action) 72 | print(Ctl.PTerm, Ctl.ITerm,Ctl.DTerm) 73 | observation, reward, done, info = env.step(action) 74 | plt.plot(graph[::10], "^-") 75 | graph = [] 76 | plt.title("Fuzzy PID performance") 77 | string = "../result/"+str(time.time())+"Fuzzy_graph.png" 78 | plt.savefig(string) 79 | env.close() 80 | ''' -------------------------------------------------------------------------------- /test/gym_tester.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | lib_path = os.path.abspath(os.path.join(sys.path[0], '..')) 4 | sys.path.append(lib_path) 5 | import gym 6 | import matplotlib.pyplot as plt 7 | from src.PID import * 8 | import math 9 | 10 | Ctl = PID() 11 | Ctl.setKp(9.5) 12 | Ctl.setKi(5.5) 13 | Ctl.setKd(1.15) 14 | Ctl.setSampleTime(0.05) 15 | graph = [] 16 | 17 | env = gym.make('Pendulum-v0') 18 | for i_episode in range(10): 19 | observation = env.reset() 20 | Ctl.clear() 21 | for t in range(300): 22 | env.render() 23 | print(observation) 24 | feedback, thbot = env.state 25 | graph.append(feedback) 26 | print(feedback) 27 | Ctl.update(feedback) 28 | action = [Ctl.output] 29 | print(action) 30 | print(Ctl.PTerm, Ctl.ITerm,Ctl.DTerm) 31 | observation, reward, done, info = env.step(action) 32 | plt.plot(graph[::10], "^-") 33 | plt.title("PID performance") 34 | string = "p6k7d1.5graph" + str(i_episode) + ".png" 35 | plt.savefig(string) 36 | graph = [] 37 | env.close() --------------------------------------------------------------------------------