보고서를 내야 하는데, 어지간하면 그래프를 보여주면서 하고 싶단 말이지?
그래서, 전에 CF 다루면서 썼던 코드를 좀 많이 수정해 보려고 한다.
그러려고 했는데,
- ev3 내부에 numpy같은 라이브러리를 새로 설치해야 하는데, 어떻게 ev3 내부에서 명령어를 실행할 수 있을지 모르겠다.
- 굳이 tk를 쓸 이유가 없어서 그냥 matplotlib & numpy로 새로 짜는게 더 나을 듯 하다.
받아온 거리값으로 그래프 만들기
제목→ "pid_graph_dist:"
y축 → distance(mm)
x축 → 시간(s).
ev3에서 별도의 파일을 동시에 실행시킬 수가 없고 ev3 안의 파일을 외부에서 읽을 수 있는지 모른다.
CODE ver1.0
# Make a DataList from txt file AND make graph of data with time import matplotlib as plt import numpy as np import time import datetime from final_term_pre import main as maincode class MakeDataList: def __init__(self, txt_uri): self.DataList =[] self.DataList_prev = [] self.f = open(txt_uri, 'r', encoding='UTF8') self.figplot = plt.Figure(figsize=(5, 4), dpi=100) self.ax2 = self.figplot.add_subplot(111) def ReadLineFrom_txt(self): # Find Kp, Ki, Kd string and make a list of data. while True: line = self.f.readline() if "Kp" in line: Kp = line continue elif "Ki" in line: Ki = line continue elif "Kd" in line: Kd = line continue elif line == "Program ended by stop button" or "----------" or "Completed successfully.": continue else: self.DataList.append(line) if not line: break print(Kp, Ki, Kd, self.DataList) def MakeGraph(self): x= np.arange(0,20, 0.25) y= self.DataList y_tgt = maincode.target self.ax2.clear() self.ax2.plt.xlim([0, 30]) self.ax2.plt.ylim([0, 1000]) self.ax2.plot(x, self.DataList_prev, '-' ,label='dist_prev', color='red', alpha=0.5) self.ax2.plot(x, y, '-' , label='dist', color='red') self.ax2.plot(x, y_tgt, '--' ,label='desired', color='blue') self.ax2.set_title('Mindstrom_wallfollowing_PID', loc='right') self.ax2.set_xlabel('Time (s)', loc='right') self.ax2.set_ylabel('Distance (mm)', loc='top') self.now = datetime.datetime.now() self.figplot.savefig('pid_graph_'+ self.now.strftime("%Y-%m-%d_%H:%M:%S")+'.png') # !!!!! def run(): MakeDataList.ReadLineFrom_txt() MakeDataList.MakeGraph() if __name__ == "__main__": txt_uri = "~/assignment_2021/Basic_Control/exp_001.txt" MakeDataList(txt_uri) run()
CODE ver2.0
# Make a DataList from txt file AND make graph of data with time import matplotlib.pyplot as plt import numpy as np import datetime #from final_term_pre import main as maincode class MakeDataList: def __init__(self, txt_uri_recent, txt_uri_prev): self.DataList = None self.txt_uri_recent = txt_uri_recent self.txt_uri_prev = txt_uri_prev #self.f_recent = open(txt_uri_recent, 'r', encoding='UTF8') #self.f_prev = open(txt_uri_prev, 'r', encoding='UTF8') self.figplot = plt.Figure(figsize=(5, 4), dpi=100) self.ax2 = self.figplot.add_subplot(111) def ReadLineFrom_txt(self, txt_uri): # Find Kp, Ki, Kd string and make a list of data. f_now = open(txt_uri, 'r', encoding='UTF8') DataList_now =[] while True: line = f_now.readline() if "Kp" in line: Kp = line pass elif "Ki" in line: Ki = line pass elif "Kd" in line: Kd = line pass else: if "Program ended by stop button" in line: pass elif "----------" in line: pass elif "Completed successfully." in line: pass else: DataList_now.append(line[0:3]) if not line: break print(Kp, Ki, Kd, DataList_now) self.DataList = DataList_now def MakeGraph(self, desire_alpha): x= np.arange(0,20, 0.125) y= self.DataList # when you use pybrick, use the code below... #y_tgt = maincode.target y_tgt = 150 #self.ax2.clear() plt.xlim([0, 30]) plt.ylim([0, 1000]) self.ax2.plot(x, y, '-' , label='dist', color='red', alpha=desire_alpha) self.ax2.plot(x, y_tgt, '--' ,label='desired', color='blue') self.ax2.set_title('Mindstrom_wallfollowing_PID', loc='right') self.ax2.set_xlabel('Time (s)', loc='right') self.ax2.set_ylabel('Distance (mm)', loc='top') self.now = datetime.datetime.now() self.figplot.savefig('pid_graph_'+ self.now.strftime("%Y-%m-%d_%H:%M:%S")+'.png') # !!!!! self.DataList =None def run(self): # Draw prev sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_prev) MakeDataList.MakeGraph(self, 0.5) # Draw recent sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_recent) MakeDataList.MakeGraph(self, 1.0) self.ax2.show() if __name__ == "__main__": #txt_uri = '~/assignment_2021/Basic_Control/exp_001.txt' txt_uri_recent = "/home/masterpyo/assignment_2021/Basic_Control/exp_001.txt" txt_uri_prev = "/home/masterpyo/assignment_2021/Basic_Control/exp_002.txt" MDL = MakeDataList(txt_uri_recent, txt_uri_prev) MDL.run()
중간결과!
개선사항
- 파란 기준선!
해결!
- PID 파라미터 표시!
해결!
- 그래프 동시에 나오게 하기!
해결!
- y축 빼곡한거 더 널널하게!
으아아아아아ㅏ!!!!!!!!!!!!!!1
왜 안돼!!!!
- y값이 마음대로 논다. 지보다 높은 값이 위에 있질 않나 중간에 낮은 값이 껴있지 않나 → set_ylim을 해봤는데 이상해...
- 아마 위의 문제랑 겹치는 것 같은데, 파랑 기준선이 지 맘대로 논다
- 실제로 실험 돌리면 코드에서 현재시간 - 시작시간으로 데이터 길이를 제한할 거지만, x값도 좀 문제가 있는 듯 하다. 지금은 데이터가 들어간 리스트의 구성요소 개수(len(~))으로 해놨는데, 10000은 너무 많잖아. 지금 len(DataList) 이게 recent_data ⇒ range(0, 1002) 1002, prev_data ⇒ range(0, 1002) 1002 이렇게 되는데.
y_prev = self.DataList_prev
y= self.DataList
x= range(len(y))
print(x, len(y))
print(x, len(y_prev))
# when you use pybrick, use the code below...
#y_tgt = maincode.target
y_tgt = '150'
self.ax2.set_xlim([0,100])
self.ax2.set_ylim([0,300])
CODE ver.3.0
# Make a DataList from txt file AND make graph of data with time import matplotlib.pyplot as plt import numpy as np import datetime #from final_term_pre import main as maincode class MakeDataList: def __init__(self, txt_uri_recent, txt_uri_prev): self.DataList = None self.DataList_prev = None self.txt_uri_recent = txt_uri_recent self.txt_uri_prev = txt_uri_prev self.Kp = None self.Ki = None self.Kd = None self.figplot = plt.Figure(figsize=(5, 4), dpi=1000) self.ax2 = self.figplot.add_subplot(111) def ReadLineFrom_txt(self, txt_uri): # Find Kp, Ki, Kd string and make a list of data. if txt_uri == self.txt_uri_prev : txt_uri = self.txt_uri_prev factor_time = True elif txt_uri == self.txt_uri_recent: txt_uri = self.txt_uri_recent factor_time = False else: print("e") f_now = open(txt_uri, 'r', encoding='UTF8') DataList_now =[] while True: line = f_now.readline() if "Kp" in line: self.Kp = line pass elif "Ki" in line: self.Ki = line pass elif "Kd" in line: self.Kd = line pass else: if "Program ended by stop button" in line: pass elif "----------" in line: pass elif "Completed successfully." in line: pass else: DataList_now.append(line[0:3]) if not line: break #print(Kp, Ki, Kd, DataList_now) if factor_time == True: self.DataList_prev = DataList_now elif factor_time == False: self.DataList = DataList_now def MakeGraph(self): # Graph initalize self.ax2.clear() y_prev = self.DataList_prev y= self.DataList x= range(len(y)) print(x, len(y)) print(x, len(y_prev)) # when you use pybrick, use the code below... #y_tgt = maincode.target y_tgt = '150' self.ax2.set_xlim([0,100]) self.ax2.set_ylim([0,300]) self.ax2.plot(x, y_prev, '-' , label='dist_prev', color='red', alpha=0.5) self.ax2.plot(x, y, '-' , label='dist_recent', color='red') self.ax2.axhline(y= y_tgt, color = 'blue', linestyle='--') self.ax2.set_title('Mindstrom_wallfollowing_PID', loc='right') self.ax2.set_xlabel('Time (s)', loc='right') self.ax2.set_ylabel('Distance (mm)', loc='top') self.ax2.text(7.80,6.0, 'Kp='+ str(self.Kp[4:])) self.ax2.text(7.80,4.0, 'Ki='+ str(self.Ki[4:])) self.ax2.text(7.80,2.0, 'Kd='+ str(self.Kd[4:])) self.now = datetime.datetime.now() self.figplot.savefig('pid_graph_'+ self.now.strftime("%Y-%m-%d_%H:%M:%S")+'.png') # !!!!! def run(self): # Read recent sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_recent) # Read prev sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_prev) # Draw data graph MakeDataList.MakeGraph(self) if __name__ == "__main__": #txt_uri = '~/assignment_2021/Basic_Control/exp_001.txt' txt_uri_recent = "/home/masterpyo/assignment_2021/Basic_Control/exp_004.txt" txt_uri_prev = "/home/masterpyo/assignment_2021/Basic_Control/exp_003.txt" MDL = MakeDataList(txt_uri_recent, txt_uri_prev) MDL.run()
환장하제
⇒ 데이터를 수집할때 시간 데이터도 가져오자. 거리값 & 시간!
CODE ver4.0
# Make a DataList from txt file AND make graph of data with time import matplotlib.pyplot as plt import numpy as np import datetime #from final_term_pre import main as maincode ## 2021/11/22 update : Adding time value; Reaing, Making graph class MakeDataList: def __init__(self, txt_uri_recent, txt_uri_prev): self.txt_uri_recent = txt_uri_recent self.txt_uri_prev = txt_uri_prev self.DataList = None self.DataList_prev = None self.TimeList =None self.TimeList_prev =None self.Kp = None self.Ki = None self.Kd = None self.figplot = plt.Figure(figsize=(5, 4), dpi=1000) self.ax2 = self.figplot.add_subplot(111) def ReadLineFrom_txt(self, txt_uri): # Find Kp, Ki, Kd string and make a list of data. if txt_uri == self.txt_uri_prev : txt_uri = self.txt_uri_prev factor_time = True elif txt_uri == self.txt_uri_recent: txt_uri = self.txt_uri_recent factor_time = False else: print("e") f_now = open(txt_uri, 'r', encoding='UTF8') DataList_now =[] TimeList_now =[] while True: line = f_now.readline() if "Kp" in line: self.Kp = line pass elif "Ki" in line: self.Ki = line pass elif "Kd" in line: self.Kd = line pass else: if "Program ended by stop button" in line: pass elif "----------" in line: pass elif "Completed successfully." in line: pass elif "2021" in line: TimeList_now.append(line) else: DataList_now.append(line[0:3]) if not line: break #print(Kp, Ki, Kd, DataList_now) if factor_time == True: self.DataList_prev = DataList_now self.TimeList_prev = TimeList_now elif factor_time == False: self.DataList = DataList_now self.TimeList = TimeList_now def MakeGraph(self): # Graph initalize self.ax2.clear() y_prev = self.DataList_prev y= self.DataList x_prev = self.TimeList_prev x = self.TimeList print(len(x), len(y)) print(len(x_prev), len(y_prev)) # when you use pybrick, use the code below... #y_tgt = maincode.target y_tgt = '150' self.ax2.set_xlim([0,100]) self.ax2.set_ylim([0,300]) self.ax2.plot(x_prev, y_prev, '-' , label='dist_prev', color='red', alpha=0.5) self.ax2.plot(x, y, '-' , label='dist_recent', color='red') self.ax2.axhline(y= y_tgt, color = 'blue', linestyle='--') self.ax2.set_title('Mindstrom_wallfollowing_PID', loc='right') self.ax2.set_xlabel('Time (s)', loc='right') self.ax2.set_ylabel('Distance (mm)', loc='top') self.ax2.text(7.80,6.0, 'Kp='+ str(self.Kp[4:])) self.ax2.text(7.80,4.0, 'Ki='+ str(self.Ki[4:])) self.ax2.text(7.80,2.0, 'Kd='+ str(self.Kd[4:])) self.now = datetime.datetime.now() self.figplot.savefig('pid_graph_'+ self.now.strftime("%Y-%m-%d_%H:%M:%S")+'.png') # !!!!! def run(self): # Read recent sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_recent) # Read prev sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_prev) # Draw data graph MakeDataList.MakeGraph(self) if __name__ == "__main__": #txt_uri = '~/assignment_2021/Basic_Control/exp_001.txt' txt_uri_recent = "/home/masterpyo/assignment_2021/Basic_Control/exp_004.txt" txt_uri_prev = "/home/masterpyo/assignment_2021/Basic_Control/exp_003.txt" MDL = MakeDataList(txt_uri_recent, txt_uri_prev) MDL.run()
끝!!!
pybrick에서 시간 모듈이 안되길래 기존처럼 센서 데이터만 가져오는 대신에, 인덱싱을 해주는 프로그램을 만들었다.
그런데 인덱싱하는건 좋았는데 하고 나니까 자꾸 null 데이터(' ')가 들어갔다.
리스트로 받아온 거리값 & 인덱스는 문자열 자료형이기 때문에 정수형으로 바꿔줘야 그래프에 순서대로 쌓인다. 때문에 list(map())으로 정수형으로 변환을 시켰는데 들어온 null 데이터 때문에 자꾸 에러가 생겼다.
그래서 그냥 데이터를 적당히 잘라서 각 텍스트 문서 길이만큼 count가 쌓이면 break 되도록 했다.
해결!
CODE ver5.0 _hardcoding&fin
# Make a DataList from txt file AND make graph of data with time import matplotlib.pyplot as plt import numpy as np import datetime #from final_term_pre import main as maincode ## 2021/11/22 update : Adding time value; Reaing, Making graph ## 2021/11/23 update : Adding count(time, data) for stop reading null data ## graph: 'vel', 'dt' text included class MakeDataList: def __init__(self, txt_uri_recent, txt_uri_prev): self.txt_uri_recent = txt_uri_recent self.txt_uri_prev = txt_uri_prev self.DataList = None self.DataList_prev = None self.TimeList =None self.TimeList_prev =None self.Kp = None self.Ki = None self.Kd = None self.vel = None self.dt = None self.figplot = plt.Figure(figsize=(5, 4), dpi=1000) self.ax2 = self.figplot.add_subplot(111) def ReadLineFrom_txt(self, txt_uri): # Find Kp, Ki, Kd string and make a list of data. if txt_uri == self.txt_uri_prev : txt_uri = self.txt_uri_prev factor_time = True elif txt_uri == self.txt_uri_recent: txt_uri = self.txt_uri_recent factor_time = False else: print("e") f_now = open(txt_uri, 'r') DataList_now =[] TimeList_now =[] count_T = 0 count_data =0 while True: line = f_now.readline() if "Kp" in line: self.Kp = line pass elif "Ki" in line: self.Ki = line pass elif "Kd" in line: self.Kd = line pass elif "vel" in line: self.vel = line pass elif "dt" in line: self.dt = line pass else: if "Program ended by stop button" in line: pass elif "----------" in line: pass elif "Completed successfully." in line: pass elif "T: " in line: line = line.strip('\n') line = line.strip(' ') TimeList_now.append(int(line[3:])) print("CT = %d" %count_T) count_T +=1 else: line = line.strip('\n') line = line.strip(' ') DataList_now.append(int(line[:])) print("CD = %d" %count_data) count_data += 1 # 5293 == exp_B_INDEXED.txt Data.len() if (factor_time == True) and (count_T == 5293): break # 7437 == exp_B_INDEXED.txt Data.len() elif (factor_time == False) and (count_T == 7437): break # 11241 == exp_BOX_INDEXED.txt Data.len() #if (factor_time == True) and (count_T == 11241): # break # 11241 == exp_BOX_INDEXED.txt Data.len() #elif (factor_time == False) and (count_T == 7825): # break if factor_time == True: self.DataList_prev = DataList_now self.TimeList_prev = TimeList_now elif factor_time == False: self.DataList = DataList_now self.TimeList = TimeList_now def MakeGraph(self): # Graph initalize self.ax2.clear() y_prev = [] y = [] x_prev =[] x= [] # Transform : string list -> int list #y_prev = list(map(int,self.DataList_prev)) #y= list(map(int,self.DataList)) #x_prev = list(map(int,self.TimeList_prev)) #x = list(map(int,self.TimeList)) y_prev = self.DataList_prev y=self.DataList x_prev = self.TimeList_prev x = self.TimeList #print(len(x), len(y)) # when you use pybrick, use the code below... #y_tgt = maincode.target y_tgt = '150' #self.ax2.set_xlim([0,100]) self.ax2.set_ylim([0,300]) self.ax2.plot(x_prev, y_prev, '-' , label='dist_prev', color='red', alpha=1.0) self.ax2.plot(x, y, '-' , label='dist_recent', color='red') self.ax2.axhline(y= int(y_tgt), color = 'blue', linestyle='--') self.ax2.set_title('Mindstrom_wallfollowing_PID', loc='right') self.ax2.set_xlabel('Time (sequence)', loc='right') self.ax2.set_ylabel('Distance (mm)', loc='top') #self.ax2.text(7.80,600.0, 'Kp='+ str(self.Kp[4:])) #self.ax2.text(7.80,570.0, 'Ki='+ str(self.Ki[4:])) #self.ax2.text(7.80,540.0, 'Kd='+ str(self.Kd[4:])) #self.ax2.text(7.80,510.0, 'vel'+ str(self.vel[4:])) #self.ax2.text(7.80,480.0, 'dt='+ str(self.dt[4:])) self.ax2.text(7.80,250.0, 'Kp='+ str(self.Kp[4:])) self.ax2.text(7.80,235.0, 'Ki='+ str(self.Ki[4:])) self.ax2.text(7.80,220.0, 'Kd='+ str(self.Kd[4:])) self.ax2.text(7.80,205.0, 'vel'+ str(self.vel[4:])) self.ax2.text(7.80,190.0, 'dt='+ str(self.dt[4:])) self.now = datetime.datetime.now() self.figplot.savefig('pid_graph_'+ self.now.strftime("%Y-%m-%d_%H:%M:%S")+'.png') # !!!!! def run(self): # Read recent sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_recent) # Read prev sensor data graph MakeDataList.ReadLineFrom_txt(self, self.txt_uri_prev) # Draw data graph MakeDataList.MakeGraph(self) if __name__ == "__main__": #txt_uri = '~/assignment_2021/Basic_Control/exp_001.txt' txt_uri_recent = "/home/masterpyo/assignment_2021/Basic_Control/exp_A_INDEXED.txt" txt_uri_prev = "/home/masterpyo/assignment_2021/Basic_Control/exp_B_INDEXED.txt" MDL = MakeDataList(txt_uri_recent, txt_uri_prev) MDL.run()
Uploaded by N2T
'Projects > 2021년 기초제어실습' 카테고리의 다른 글
프로젝트 개요 (0) | 2023.01.03 |
---|---|
Line Tracer-코드 정리 (0) | 2023.01.03 |
Line Tracer-센서 데이터 그래프 생성 (0) | 2023.01.03 |
wall follower-실험용 코드 (0) | 2023.01.03 |
wall follower-코드 정리 (0) | 2023.01.03 |