转向从机型配置文件获取参数
This commit is contained in:
parent
137122947c
commit
0e67a2831c
BIN
assets/files/examples/数据处理/iso/ISO-V100.pdf
Normal file
BIN
assets/files/examples/数据处理/iso/ISO-V100.pdf
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/iso/ISO-V1000.pdf
Normal file
BIN
assets/files/examples/数据处理/iso/ISO-V1000.pdf
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/iso/ISO.pdf
Normal file
BIN
assets/files/examples/数据处理/iso/ISO.pdf
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/iso/iso-results.xlsx
Normal file
BIN
assets/files/examples/数据处理/iso/iso-results.xlsx
Normal file
Binary file not shown.
120520
assets/files/examples/数据处理/wavelogger/j2_overload.CSV
Normal file
120520
assets/files/examples/数据处理/wavelogger/j2_overload.CSV
Normal file
File diff suppressed because it is too large
Load Diff
91365
assets/files/examples/数据处理/wavelogger/j3_overload.CSV
Normal file
91365
assets/files/examples/数据处理/wavelogger/j3_overload.CSV
Normal file
File diff suppressed because it is too large
Load Diff
103136
assets/files/examples/数据处理/wavelogger/j4_overload.CSV
Normal file
103136
assets/files/examples/数据处理/wavelogger/j4_overload.CSV
Normal file
File diff suppressed because it is too large
Load Diff
104289
assets/files/examples/数据处理/wavelogger/j5_overload.CSV
Normal file
104289
assets/files/examples/数据处理/wavelogger/j5_overload.CSV
Normal file
File diff suppressed because it is too large
Load Diff
104260
assets/files/examples/数据处理/wavelogger/j6_overload.CSV
Normal file
104260
assets/files/examples/数据处理/wavelogger/j6_overload.CSV
Normal file
File diff suppressed because it is too large
Load Diff
BIN
assets/files/examples/数据处理/wavelogger/result.xlsx
Normal file
BIN
assets/files/examples/数据处理/wavelogger/result.xlsx
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/wavelogger/xdt/j2_overload.xdt
Normal file
BIN
assets/files/examples/数据处理/wavelogger/xdt/j2_overload.xdt
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/wavelogger/xdt/j3_overload.xdt
Normal file
BIN
assets/files/examples/数据处理/wavelogger/xdt/j3_overload.xdt
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/wavelogger/xdt/j4_overload.xdt
Normal file
BIN
assets/files/examples/数据处理/wavelogger/xdt/j4_overload.xdt
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/wavelogger/xdt/j5_overload.xdt
Normal file
BIN
assets/files/examples/数据处理/wavelogger/xdt/j5_overload.xdt
Normal file
Binary file not shown.
BIN
assets/files/examples/数据处理/wavelogger/xdt/j6_overload.xdt
Normal file
BIN
assets/files/examples/数据处理/wavelogger/xdt/j6_overload.xdt
Normal file
Binary file not shown.
5
assets/files/protocols/controller.get_params.json
Normal file
5
assets/files/protocols/controller.get_params.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"id": "xxxxxxxxxxx",
|
||||
"module": "system",
|
||||
"command": "controller.get_params"
|
||||
}
|
114
code/aio.py
114
code/aio.py
@ -15,6 +15,7 @@ from datetime import datetime
|
||||
import os
|
||||
from common import clibs, openapi
|
||||
from data_process import current, brake, iso, wavelogger
|
||||
from automatic_test import do_current
|
||||
import threading
|
||||
import re
|
||||
|
||||
@ -118,6 +119,7 @@ class App:
|
||||
self.label_tips = ctk.CTkLabel(self.frame_status, textvariable=var_tips, compound="left", bg_color="#C9C9C9", font=self.f_status, anchor="e")
|
||||
self.__auth_and_vercheck()
|
||||
if local_vers == self.server_vers:
|
||||
# if True:
|
||||
image = ctk.CTkImage(Image.open(f"{clibs.PREFIX}/media/updated.png"), size=(16, 16))
|
||||
var_tips.set(" 当前是最新版本,继续保持! ")
|
||||
self.label_tips.configure(text_color="#0D8A3D", image=image)
|
||||
@ -207,6 +209,12 @@ class App:
|
||||
clibs.running = False
|
||||
raise Exception(desc)
|
||||
|
||||
@staticmethod
|
||||
def __is_running(operation):
|
||||
if clibs.running:
|
||||
messagebox.showerror(title="处理中", message=f"有程序正在运行,需等待结束后,在执行{operation}操作!")
|
||||
return
|
||||
|
||||
def __program_start(self):
|
||||
def get_data_dp():
|
||||
data = {
|
||||
@ -230,10 +238,11 @@ class App:
|
||||
return data
|
||||
|
||||
def init_op():
|
||||
self.__is_running("开始")
|
||||
self.text_output.delete("1.0", ctk.END)
|
||||
self.tabview_bottom.set("输出")
|
||||
clibs.tl_prg = self.__toplevel_progress
|
||||
if clibs.db_state != "readwrite":
|
||||
self.text_output.delete("1.0", ctk.END)
|
||||
clibs.cursor.close()
|
||||
clibs.conn.close()
|
||||
clibs.conn = self.conn
|
||||
@ -241,8 +250,6 @@ class App:
|
||||
clibs.db_state = "readwrite"
|
||||
self.btn_load.configure(fg_color="#979DA2")
|
||||
self.__get_realtime_log()
|
||||
clibs.tl_prg = self.__toplevel_progress
|
||||
# TBD: something signifies status of program and terminate some thread ect.
|
||||
|
||||
def exec_function():
|
||||
init_op()
|
||||
@ -250,15 +257,22 @@ class App:
|
||||
if not clibs.running:
|
||||
clibs.running = True
|
||||
clibs.data_dp = get_data_dp()
|
||||
try:
|
||||
eval(clibs.data_dp["_main"] + ".main()")
|
||||
finally:
|
||||
clibs.running = False
|
||||
else:
|
||||
messagebox.showinfo(title="进行中...", message="当前有程序正在运行!")
|
||||
elif self.tabview_top.get() == "自动测试":
|
||||
if not clibs.running:
|
||||
clibs.running = True
|
||||
clibs.data_at = get_data_at()
|
||||
eval(clibs.data_at["_main"] + ".main()")
|
||||
try:
|
||||
eval("do_" + clibs.data_at["_main"] + ".main()")
|
||||
finally:
|
||||
clibs.running = False
|
||||
else:
|
||||
messagebox.showinfo(title="进行中...", message="当前有程序正在运行!")
|
||||
|
||||
exec_function()
|
||||
|
||||
@ -270,6 +284,8 @@ class App:
|
||||
self.entry_path_atv.set("数据文件夹路径")
|
||||
self.entry_path_atv.set("数据文件夹路径")
|
||||
|
||||
self.__is_running("重置")
|
||||
|
||||
if clibs.db_state == "readwrite":
|
||||
res = messagebox.askyesno(title="状态重置", message="这将清空本次所有的输出以及日志记录,且不可恢复,请确认!", default=messagebox.NO, icon=messagebox.WARNING)
|
||||
if res:
|
||||
@ -278,13 +294,14 @@ class App:
|
||||
clibs.lock.acquire(True)
|
||||
clibs.cursor.execute("delete from logs")
|
||||
clibs.cursor.execute("delete from sqlite_sequence") # 主键归零
|
||||
except Exception:
|
||||
self.__w2t("主键归零操作失败", "red")
|
||||
finally:
|
||||
clibs.lock.release()
|
||||
|
||||
self.treeview_logs.delete(*self.treeview_logs.get_children())
|
||||
self.label_pages_logs.set("-.-.-.-.-.-")
|
||||
reset_methods()
|
||||
# TBD: something signifies status of program and terminate some thread ect.
|
||||
elif clibs.db_state == "readonly":
|
||||
res = messagebox.askyesno(title="状态重置", message="这将清空本次所有的输出以及恢复本次的日志记录,请确认!", default=messagebox.NO, icon=messagebox.INFO)
|
||||
if res:
|
||||
@ -296,12 +313,11 @@ class App:
|
||||
clibs.db_state = "readwrite"
|
||||
self.__get_realtime_log()
|
||||
reset_methods()
|
||||
# TBD: something signifies status of program and terminate some thread ect.
|
||||
|
||||
@clibs.db_lock
|
||||
def __get_realtime_log(self):
|
||||
clibs.cursor.execute("select id from logs")
|
||||
len_records = len(clibs.cursor.fetchall())
|
||||
clibs.cursor.execute("select count(id) from logs")
|
||||
len_records = clibs.cursor.fetchone()[0]
|
||||
pages_all = len_records // 100 if len_records % 100 == 0 else len_records // 100 + 1
|
||||
self.label_pages_logs.set(f"{pages_all} / {pages_all}")
|
||||
|
||||
@ -333,14 +349,14 @@ class App:
|
||||
self.treeview_logs.delete(*self.treeview_logs.get_children())
|
||||
for record in records:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
# self.treeview_logs.yview_moveto(1)
|
||||
self.treeview_logs.yview_moveto(0)
|
||||
|
||||
clibs.cursor.execute("select * from logs order by id desc")
|
||||
records = clibs.cursor.fetchall()
|
||||
pages_all = len(records) // 100 if len(records) % 100 == 0 else len(records) // 100 + 1
|
||||
clibs.cursor.execute("select count(id) from logs")
|
||||
len_records = clibs.cursor.fetchone()[0]
|
||||
pages_all = len_records // 100 if len_records % 100 == 0 else len_records // 100 + 1
|
||||
current_page = int(end) // 100 if int(end) % 100 == 0 else int(end) // 100 + 1
|
||||
self.label_pages_logs.set(f"{current_page} / {pages_all}")
|
||||
except Exception as ERR:
|
||||
except Exception:
|
||||
...
|
||||
else:
|
||||
pages_all = self.label_pages_logs.get().split("/")[1].strip()
|
||||
@ -354,6 +370,7 @@ class App:
|
||||
if index_end <= 100:
|
||||
for record in clibs.f_records[:index_end]:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
self.treeview_logs.yview_moveto(0)
|
||||
else:
|
||||
for record in clibs.f_records[index_end-100:index_end]:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
@ -365,10 +382,9 @@ class App:
|
||||
@clibs.db_lock
|
||||
def get_next_page():
|
||||
if self.btn_find.cget("fg_color") == "#979DA2":
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
clibs.cursor.execute("select id from logs")
|
||||
len_records = len(clibs.cursor.fetchall())
|
||||
clibs.cursor.execute("select count(id) from logs")
|
||||
len_records = clibs.cursor.fetchone()[0]
|
||||
|
||||
row = self.treeview_logs.get_children()
|
||||
last_id = self.treeview_logs.item(row[-1], "values")[0]
|
||||
@ -380,18 +396,18 @@ class App:
|
||||
self.treeview_logs.delete(*self.treeview_logs.get_children())
|
||||
for record in records:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
# self.treeview_logs.yview_moveto(1)
|
||||
self.treeview_logs.yview_moveto(0)
|
||||
|
||||
pages_all = len_records // 100 if len_records % 100 == 0 else len_records // 100 + 1
|
||||
current_page = int(start) // 100 if int(start) % 100 == 0 else int(start) // 100 + 1
|
||||
self.label_pages_logs.set(f"{current_page} / {pages_all}")
|
||||
except Exception as Err:
|
||||
print(f"get_next_page-if: {Err}")
|
||||
_pages_all = len_records // 100 if len_records % 100 == 0 else len_records // 100 + 1
|
||||
_current_page = int(start) // 100 if int(start) % 100 == 0 else int(start) // 100 + 1
|
||||
self.label_pages_logs.set(f"{_current_page} / {_pages_all}")
|
||||
except Exception:
|
||||
...
|
||||
else:
|
||||
len_records = len(clibs.f_records)
|
||||
pages_all = int(self.label_pages_logs.get().split("/")[1].strip())
|
||||
current_page = int(self.label_pages_logs.get().split("/")[0].strip())
|
||||
if current_page < pages_all:
|
||||
_pages_all = int(self.label_pages_logs.get().split("/")[1].strip())
|
||||
_current_page = int(self.label_pages_logs.get().split("/")[0].strip())
|
||||
if _current_page < _pages_all:
|
||||
row = self.treeview_logs.get_children()
|
||||
last_one = list(self.treeview_logs.item(row[-1], "values"))
|
||||
last_one[0] = int(last_one[0])
|
||||
@ -400,12 +416,14 @@ class App:
|
||||
if index_start+100 <= len_records:
|
||||
for record in clibs.f_records[index_start:index_start+100]:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
self.treeview_logs.yview_moveto(0)
|
||||
else:
|
||||
for record in clibs.f_records[index_start:]:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
self.treeview_logs.yview_moveto(0)
|
||||
|
||||
next_page = current_page + 1
|
||||
self.label_pages_logs.set(f"{next_page} / {pages_all}")
|
||||
_next_page = _current_page + 1
|
||||
self.label_pages_logs.set(f"{_next_page} / {_pages_all}")
|
||||
|
||||
current_page = int(self.label_pages_logs.get().split("/")[0].strip())
|
||||
pages_all = int(self.label_pages_logs.get().split("/")[1].strip())
|
||||
@ -417,19 +435,24 @@ class App:
|
||||
get_next_page()
|
||||
|
||||
def __load_log_db(self):
|
||||
self.__is_running("加载")
|
||||
db_file = filedialog.askopenfilename(title="加载数据库文件", defaultextension=".db", initialdir=f"{clibs.PREFIX}/logs")
|
||||
if not db_file:
|
||||
return
|
||||
self.conn = clibs.conn
|
||||
self.cursor = clibs.cursor
|
||||
try:
|
||||
clibs.conn = sqlite3.connect(f"file:{db_file}?mode=ro", uri=True, isolation_level=None, check_same_thread=False, cached_statements=256)
|
||||
clibs.conn = sqlite3.connect(f"file:{db_file}?mode=ro", uri=True, isolation_level=None, check_same_thread=False, cached_statements=2048)
|
||||
clibs.cursor = clibs.conn.cursor()
|
||||
clibs.cursor.execute("PRAGMA synchronous=normal")
|
||||
clibs.cursor.execute("PRAGMA temp_store=memory")
|
||||
clibs.cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
clibs.cursor.execute("PRAGMA cache_size=200000")
|
||||
clibs.db_state = "readonly"
|
||||
self.__get_realtime_log()
|
||||
self.btn_load.configure(fg_color="#000080")
|
||||
except Exception as Err:
|
||||
clibs.insert_logdb("ERROR", "aio", f"加载数据库失败,需确认 {db_file} 是否是有效数据库文件!")
|
||||
clibs.insert_logdb("ERROR", "aio", f"load_log_db: 加载数据库失败,需确认 {db_file} 是否是有效数据库文件!\n{Err}")
|
||||
messagebox.showerror(title="加载数据库失败", message=f"需确认 {db_file} 是否是有效数据库文件!")
|
||||
|
||||
def __main_switch_dp(self, event):
|
||||
@ -459,7 +482,7 @@ class App:
|
||||
url_vers = "http://10.2.23.150:10008/version"
|
||||
try:
|
||||
self.server_vers = request.urlopen(url_vers, timeout=2).read().decode("utf-8").strip()
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
messagebox.showwarning(title="退出", message="无法连接至服务器.....")
|
||||
clibs.cursor.close()
|
||||
clibs.conn.close()
|
||||
@ -543,7 +566,7 @@ class App:
|
||||
index_start = all_text.find(selected)
|
||||
index_end = index_start + len(selected)
|
||||
widget.delete(index_start, index_end)
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
...
|
||||
|
||||
@staticmethod
|
||||
@ -556,7 +579,7 @@ class App:
|
||||
index_start = all_text.find(selected)
|
||||
index_end = index_start + len(selected)
|
||||
widget.delete(index_start, index_end)
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
...
|
||||
|
||||
@staticmethod
|
||||
@ -565,7 +588,7 @@ class App:
|
||||
widget.clipboard_clear()
|
||||
copy_text = widget.selection_get()
|
||||
widget.clipboard_append(copy_text)
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
...
|
||||
|
||||
@staticmethod
|
||||
@ -601,7 +624,6 @@ class App:
|
||||
widget_toplevel.destroy()
|
||||
|
||||
def double_click(event):
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
e = event.widget
|
||||
iid = e.identify("item", event.x, event.y)
|
||||
@ -616,7 +638,7 @@ class App:
|
||||
toplevel.bind("<Escape>", esc_quit_log_tl)
|
||||
toplevel.transient(self.root)
|
||||
toplevel.focus()
|
||||
_text = f"TS: {_ts} | Log level: {_level} | Module: {_module}"
|
||||
_text = f"{_level} log in {_module} @ {_ts}"
|
||||
label_info = ctk.CTkLabel(toplevel, text=_text, width=10, fg_color="#5F9EA0", corner_radius=5, font=self.f_treeview)
|
||||
text_content = ctk.CTkTextbox(toplevel, width=10, font=self.f_toplevel)
|
||||
text_content.insert(ctk.END, repr(_content))
|
||||
@ -638,19 +660,19 @@ class App:
|
||||
if number > 0:
|
||||
start = number * 100 - 99
|
||||
end = number * 100
|
||||
clibs.cursor.execute("select id from logs")
|
||||
len_records = len(clibs.cursor.fetchall())
|
||||
clibs.cursor.execute("select count(id) from logs")
|
||||
len_records = clibs.cursor.fetchone()[0]
|
||||
if start <= len_records:
|
||||
clibs.cursor.execute(f"select * from logs where id between {start} and {end}")
|
||||
records = clibs.cursor.fetchall()
|
||||
self.treeview_logs.delete(*self.treeview_logs.get_children())
|
||||
for record in records:
|
||||
self.treeview_logs.insert("", "end", values=record, tags=record[2])
|
||||
self.treeview_logs.yview_moveto(1)
|
||||
self.treeview_logs.yview_moveto(0)
|
||||
|
||||
pages_all = len_records // 100 if len_records % 100 == 0 else len_records // 100 + 1
|
||||
self.label_pages_logs.set(f"{number} / {pages_all}")
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
...
|
||||
|
||||
def close_toplevel(tl):
|
||||
@ -861,22 +883,25 @@ class App:
|
||||
if self.btn_conn.cget("fg_color") == "#979DA2":
|
||||
self.btn_conn.configure(state="disabled")
|
||||
clibs.ip_addr = self.entry_ip_atv.get().strip()
|
||||
ip_pattern = re.compile(r'(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])')
|
||||
ip_pattern = re.compile(r"(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])")
|
||||
if not ip_pattern.fullmatch(clibs.ip_addr):
|
||||
messagebox.showerror(title="非法地址", message=f"{clibs.ip_addr} 不是一个有效的 IP 地址")
|
||||
clibs.insert_logdb("ERROR", "aio", f"connection: {clibs.ip_addr} 不是一个有效的 IP 地址")
|
||||
return
|
||||
try:
|
||||
# clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
|
||||
clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
|
||||
clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port)
|
||||
clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
|
||||
self.btn_conn.configure(state="normal", fg_color="#2E8B57")
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
self.btn_conn.configure(state="normal", fg_color="#979DA2")
|
||||
elif self.btn_conn.cget("fg_color") == "#2E8B57":
|
||||
self.btn_conn.configure(state="disabled")
|
||||
try:
|
||||
# clibs.c_md.close()
|
||||
clibs.c_md.close()
|
||||
clibs.c_hr.close()
|
||||
except Exception:
|
||||
...
|
||||
finally:
|
||||
self.btn_conn.configure(state="normal", fg_color="#979DA2")
|
||||
t = threading.Thread(target=conn_or_disconn)
|
||||
@ -989,10 +1014,11 @@ class App:
|
||||
self.om_sensor_dp.configure(state="disabled")
|
||||
# ========================================================================
|
||||
clibs.w2t = self.__w2t
|
||||
# clibs.insert_logdb("INFO", "aio", "AIO starts running......")
|
||||
clibs.insert_logdb("INFO", "aio", "AIO starts running......")
|
||||
|
||||
def show(self):
|
||||
if self.server_vers:
|
||||
# if True:
|
||||
t = threading.Thread(target=self.__detect_network)
|
||||
t.daemon = True
|
||||
t.start()
|
||||
|
67
code/automatic_test/btn_functions.py
Normal file
67
code/automatic_test/btn_functions.py
Normal file
@ -0,0 +1,67 @@
|
||||
from sys import argv
|
||||
from commons import clibs
|
||||
|
||||
tab_name = clibs.tab_names['at']
|
||||
logger = clibs.log_prod
|
||||
|
||||
|
||||
def trigger_estop(md, w2t):
|
||||
md.trigger_estop()
|
||||
w2t("触发急停成功,可点击机器状态验证。", 0, 0, 'green', tab_name)
|
||||
|
||||
|
||||
def reset_estop(md, w2t):
|
||||
md.reset_estop()
|
||||
w2t("恢复急停成功,可点击机器状态验证。", 0, 0, 'green', tab_name)
|
||||
|
||||
|
||||
def get_state(hr, w2t):
|
||||
# 获取机器状态
|
||||
_response = clibs.execution('state.get_state', hr, w2t, tab_name)
|
||||
stat_desc = {'engine': '上电状态', 'operate': '操作模式', 'rc_state': '控制器状态', 'robot_action': '机器人动作', 'safety_mode': '安全模式', 'servo_mode': '伺服工作模式', 'task_space': '工作任务空间'}
|
||||
for component, state in _response['data'].items():
|
||||
w2t(f"{stat_desc[component]}: {state}", tab_name=tab_name)
|
||||
|
||||
# 获取设备伺服信息
|
||||
_response = clibs.execution('device.get_params', hr, w2t, tab_name)
|
||||
dev_desc = {0: '伺服版本', 1: '伺服参数', 2: '安全板固件', 3: '控制器', 4: '通讯总线', 5: '解释器', 6: '运动控制', 8: '力控版本', 9: '末端固件', 10: '机型文件', 11: '环境包'}
|
||||
dev_vers = {}
|
||||
for device in _response['data']['devices']:
|
||||
dev_vers[device['type']] = device['version']
|
||||
for i in sorted(dev_desc.keys()):
|
||||
w2t(f"{dev_desc[i]}: {dev_vers[i]}", tab_name=tab_name)
|
||||
|
||||
# 设置示教器模式
|
||||
_response = clibs.execution('state.set_tp_mode', hr, w2t, tab_name, tp_mode='without')
|
||||
|
||||
|
||||
def warning_info(hr, w2t):
|
||||
for postfix in ['', '.2', '.3', '.4', '.5', '.6', '.7', '.8', '.9', '.10']:
|
||||
log_name = clibs.log_data_hmi + postfix
|
||||
try:
|
||||
with open(log_name, 'r', encoding='utf-8') as f_log:
|
||||
for line in f_log:
|
||||
if 'alarm' in line:
|
||||
w2t(line.strip(), tab_name=tab_name)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
def main(hr, md, func, w2t):
|
||||
if hr is None:
|
||||
w2t("无法连接机器人,检查是否已经使用Robot Assist软件连接机器,重试中...", 0, 49, 'red', tab_name)
|
||||
# func: get_state/
|
||||
match func:
|
||||
case 'trigger_estop':
|
||||
trigger_estop(md, w2t)
|
||||
case 'reset_estop':
|
||||
reset_estop(md, w2t)
|
||||
case 'get_state':
|
||||
get_state(hr, w2t)
|
||||
case 'warning_info':
|
||||
warning_info(hr, w2t)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(*argv[1:])
|
||||
|
298
code/automatic_test/do_brake.py
Normal file
298
code/automatic_test/do_brake.py
Normal file
@ -0,0 +1,298 @@
|
||||
from time import sleep, time, strftime, localtime
|
||||
from sys import argv
|
||||
from os import mkdir
|
||||
from paramiko import SSHClient, AutoAddPolicy
|
||||
from json import loads
|
||||
from openpyxl import load_workbook
|
||||
from pandas import DataFrame, concat
|
||||
from commons import clibs
|
||||
|
||||
tab_name = clibs.tab_names['at']
|
||||
logger = clibs.log_prod
|
||||
|
||||
|
||||
def check_files(path, loadsel, data_dirs, data_files, w2t):
|
||||
if len(data_dirs) != 0 or len(data_files) != 5:
|
||||
w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name)
|
||||
w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name)
|
||||
|
||||
config_file = reach33 = reach66 = reach100 = prj_file = None
|
||||
for data_file in data_files:
|
||||
filename = data_file.split('\\')[-1]
|
||||
if filename == 'configs.xlsx':
|
||||
config_file = data_file
|
||||
elif filename.startswith('reach33_') and filename.endswith('.xlsx'):
|
||||
reach33 = data_file
|
||||
elif filename.startswith('reach66_') and filename.endswith('.xlsx'):
|
||||
reach66 = data_file
|
||||
elif filename.startswith('reach100_') and filename.endswith('.xlsx'):
|
||||
reach100 = data_file
|
||||
elif filename.endswith('.zip'):
|
||||
prj_file = data_file
|
||||
else:
|
||||
w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name)
|
||||
w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 2, 'red', tab_name)
|
||||
|
||||
if config_file and reach33 and reach66 and reach100 and prj_file:
|
||||
result_dirs = []
|
||||
mkdir(f"{path}\\j1")
|
||||
mkdir(f"{path}\\j2")
|
||||
mkdir(f"{path}\\j3")
|
||||
|
||||
for _reach in ['reach33', 'reach66', 'reach100']:
|
||||
for _load in [f'load{loadsel.removeprefix("tool")}']:
|
||||
for _speed in ['speed33', 'speed66', 'speed100']:
|
||||
dir_name = '_'.join([_reach, _load, _speed])
|
||||
result_dirs.append(dir_name)
|
||||
mkdir(f"{path}\\j1\\{dir_name}")
|
||||
mkdir(f"{path}\\j2\\{dir_name}")
|
||||
if _reach == 'reach100':
|
||||
mkdir(f"{path}\\j3\\{dir_name}")
|
||||
|
||||
w2t("数据目录合规性检查结束,未发现问题......", 0, 0, 'blue', tab_name)
|
||||
return config_file, reach33, reach66, reach100, prj_file, result_dirs
|
||||
else:
|
||||
w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name)
|
||||
w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name)
|
||||
|
||||
|
||||
def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count):
|
||||
_d2d_vel = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq = {'device_servo_trq_feedback': []}
|
||||
_d2d_stop = {'device_safety_estop': []}
|
||||
for data in curve_data[-240:]: # 保留最后12s的数据
|
||||
dict_results = data['data']
|
||||
for item in dict_results:
|
||||
try:
|
||||
item['value'].reverse()
|
||||
except KeyError:
|
||||
continue
|
||||
if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == axis-1 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 0 and item.get('name', None) == 'device_safety_estop':
|
||||
_d2d_stop['device_safety_estop'].extend(item['value'])
|
||||
|
||||
df1 = DataFrame.from_dict(_d2d_vel)
|
||||
df2 = DataFrame.from_dict(_d2d_trq)
|
||||
df3 = DataFrame.from_dict(_d2d_stop)
|
||||
df = concat([df1, df2, df3], axis=1)
|
||||
_filename = f"{path}\\j{axis}\\reach{_reach}_load{_load}_speed{_speed}\\reach{_reach}_load{_load}_speed{_speed}_{count}.data"
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
|
||||
def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t):
|
||||
_count = 0
|
||||
_total = 63
|
||||
display_pdo_params = [
|
||||
{"name": "hw_joint_vel_feedback", "channel": 0},
|
||||
{"name": "hw_joint_vel_feedback", "channel": 1},
|
||||
{"name": "hw_joint_vel_feedback", "channel": 2},
|
||||
{"name": "hw_joint_vel_feedback", "channel": 3},
|
||||
{"name": "hw_joint_vel_feedback", "channel": 4},
|
||||
{"name": "hw_joint_vel_feedback", "channel": 5},
|
||||
{"name": "device_servo_trq_feedback", "channel": 0},
|
||||
{"name": "device_servo_trq_feedback", "channel": 1},
|
||||
{"name": "device_servo_trq_feedback", "channel": 2},
|
||||
{"name": "device_servo_trq_feedback", "channel": 3},
|
||||
{"name": "device_servo_trq_feedback", "channel": 4},
|
||||
{"name": "device_servo_trq_feedback", "channel": 5},
|
||||
{"name": "device_safety_estop", "channel": 0},
|
||||
]
|
||||
wb = load_workbook(config_file, read_only=True)
|
||||
ws = wb['Target']
|
||||
write_diagnosis = float(ws.cell(row=3, column=10).value)
|
||||
get_init_speed = float(ws.cell(row=4, column=10).value)
|
||||
single_brake = str(ws.cell(row=5, column=10).value)
|
||||
logger.info(f"write_diagnosis = {write_diagnosis}, get_init_speed = {get_init_speed}, single_brake = {single_brake}")
|
||||
|
||||
if ws.cell(row=1, column=1).value == 'positive':
|
||||
md.write_pon(1)
|
||||
elif ws.cell(row=1, column=1).value == 'negative':
|
||||
md.write_pon(0)
|
||||
else:
|
||||
w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', tab_name)
|
||||
|
||||
clibs.execution('diagnosis.open', hr, w2t, tab_name, open=True, display_open=True)
|
||||
clibs.execution('diagnosis.set_params', hr, w2t, tab_name, display_pdo_params=display_pdo_params)
|
||||
for condition in result_dirs:
|
||||
_reach = condition.split('_')[0].removeprefix('reach')
|
||||
_load = condition.split('_')[1].removeprefix('load')
|
||||
_speed = condition.split('_')[2].removeprefix('speed')
|
||||
|
||||
# for single condition test
|
||||
_single_axis = 0
|
||||
if single_brake != '0':
|
||||
_total = 3
|
||||
_single_axis = int(single_brake.split('-')[0])
|
||||
if _reach != single_brake.split('-')[1] or _load != single_brake.split('-')[2] or _speed != single_brake.split('-')[3]:
|
||||
continue
|
||||
|
||||
for axis in range(1, 4):
|
||||
# for single condition test
|
||||
if _single_axis != 0 and _single_axis != axis:
|
||||
continue
|
||||
|
||||
md.write_axis(axis)
|
||||
speed_max = 0
|
||||
if axis == 3 and _reach != '100':
|
||||
continue
|
||||
|
||||
w2t(f"-"*90, 0, 0, 'purple', tab_name)
|
||||
|
||||
for count in range(1, 4):
|
||||
_count += 1
|
||||
this_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()))
|
||||
prj_path = 'target/_build/target.prj'
|
||||
w2t(f"[{this_time} | {_count}/{_total}] 正在执行 {axis} 轴 {condition} 的第 {count} 次制动测试...", 0, 0, 'purple', tab_name)
|
||||
|
||||
# 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
|
||||
md.trigger_estop()
|
||||
md.reset_estop()
|
||||
md.clear_alarm()
|
||||
md.write_act(0)
|
||||
sleep(write_diagnosis) # 软急停超差后,等待写诊断时间,可通过configs.xlsx配置
|
||||
|
||||
while count == 1:
|
||||
# 2. 修改要执行的场景
|
||||
ssh = SSHClient()
|
||||
ssh.set_missing_host_key_policy(AutoAddPolicy())
|
||||
ssh.connect(hostname=clibs.ip_addr, port=22, username='luoshi', password='luoshi2019')
|
||||
if ws.cell(row=1, column=1).value == 'positive':
|
||||
_rl_cmd = f"brake_E(j{axis}_{_reach}_p, j{axis}_{_reach}_n, p_speed, p_tool)"
|
||||
elif ws.cell(row=1, column=1).value == 'negative':
|
||||
_rl_cmd = f"brake_E(j{axis}_{_reach}_n, j{axis}_{_reach}_p, p_speed, p_tool)"
|
||||
else:
|
||||
w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', tab_name)
|
||||
_rl_speed = f"VelSet {_speed}"
|
||||
_rl_tool = f"tool p_tool = tool{loadsel.removeprefix('tool')}"
|
||||
cmd = 'cd /home/luoshi/bin/controller/; '
|
||||
cmd += 'sudo sed -i "/brake_E/d" projects/target/_build/brake/main.mod; '
|
||||
cmd += f'sudo sed -i "/DONOTDELETE/i {_rl_cmd}" projects/target/_build/brake/main.mod; '
|
||||
cmd += 'sudo sed -i "/VelSet/d" projects/target/_build/brake/main.mod; '
|
||||
cmd += f'sudo sed -i "/MoveAbsJ/i {_rl_speed}" projects/target/_build/brake/main.mod; '
|
||||
cmd += 'sudo sed -i "/tool p_tool/d" projects/target/_build/brake/main.mod; '
|
||||
cmd += f'sudo sed -i "/VelSet/i {_rl_tool}" projects/target/_build/brake/main.mod; '
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write('luoshi2019' + '\n')
|
||||
stdout.read().decode() # 需要read一下才能正常执行
|
||||
stderr.read().decode()
|
||||
|
||||
# 3. reload工程后,pp2main,并且自动模式和上电,最后运行程序
|
||||
clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['brake', 'stop0_related'])
|
||||
clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['brake', 'stop0_related'])
|
||||
clibs.execution('state.switch_auto', hr, w2t, tab_name)
|
||||
clibs.execution('state.switch_motor_on', hr, w2t, tab_name)
|
||||
clibs.execution('rl_task.set_run_params', hr, w2t, tab_name, loop_mode=True, override=1.0)
|
||||
clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['brake', 'stop0_related'])
|
||||
_t_start = time()
|
||||
while True:
|
||||
if md.read_ready_to_go() == 1:
|
||||
md.write_act(True)
|
||||
break
|
||||
else:
|
||||
if (time() - _t_start) // 20 > 1:
|
||||
w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name)
|
||||
else:
|
||||
sleep(1)
|
||||
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
||||
sleep(get_init_speed+5) # 冗余5s,指定时间后获取实际【正|负】方向的最大速度,可通过configs.xlsx配置
|
||||
clibs.execution('rl_task.stop', hr, w2t, tab_name, tasks=['brake'])
|
||||
# 找出最大速度
|
||||
_c_msg = hr.c_msg.copy()
|
||||
_number = 0
|
||||
for _msg in _c_msg:
|
||||
if _number > get_init_speed*20: # 最开始回零点的时候,二轴速度可以达到最大值,实际摆动时,某一方向可能达不到
|
||||
break
|
||||
if 'diagnosis.result' in _msg:
|
||||
_number += 1
|
||||
dict_results = loads(_msg)['data']
|
||||
for item in dict_results:
|
||||
if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_ = clibs.RADIAN * sum(item['value']) / len(item['value'])
|
||||
if ws.cell(row=1, column=1).value == 'positive':
|
||||
speed_max = max(_, speed_max)
|
||||
elif ws.cell(row=1, column=1).value == 'negative':
|
||||
speed_max = min(_, speed_max)
|
||||
logger.info(f"speed max = {speed_max}")
|
||||
speed_max = abs(speed_max)
|
||||
speed_target = float(ws.cell(row=3, column=axis+1).value) * float(_speed) / 100
|
||||
if speed_max < speed_target*0.95 or speed_max > speed_target*1.05:
|
||||
w2t(f"Axis: {axis}-{count} | Speed: {speed_max} | Shouldbe: {speed_target}", 0, 0, 'indigo', tab_name)
|
||||
|
||||
md.write_speed_max(speed_max)
|
||||
|
||||
hr.c_msg_xs.clear()
|
||||
if len(hr.c_msg) > 270:
|
||||
del hr.c_msg[270:]
|
||||
|
||||
if speed_max < 10:
|
||||
md.clear_alarm()
|
||||
w2t("未获取到正确的速度,即将重新获取...", 0, 0, 'red', tab_name)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
# 5. 清除软急停,重新运行程序,并打开曲线发送继续运动信号,当速度达到最大值时,通过DO触发急停
|
||||
md.reset_estop() # 其实没必要
|
||||
md.clear_alarm()
|
||||
|
||||
# clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['brake', 'stop0_related'])
|
||||
clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['brake', 'stop0_related'])
|
||||
clibs.execution('state.switch_auto', hr, w2t, tab_name)
|
||||
clibs.execution('state.switch_motor_on', hr, w2t, tab_name)
|
||||
clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['brake', 'stop0_related'])
|
||||
for i in range(3):
|
||||
if md.read_ready_to_go() == 1:
|
||||
md.write_act(1)
|
||||
break
|
||||
else:
|
||||
sleep(1)
|
||||
else:
|
||||
w2t("未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name)
|
||||
|
||||
sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
|
||||
md.write_probe(1)
|
||||
_t_start = time()
|
||||
while True:
|
||||
if md.read_brake_done() == 1:
|
||||
sleep(4) # 保证速度归零
|
||||
md.write_probe(0)
|
||||
break
|
||||
else:
|
||||
if (time() - _t_start) > 30:
|
||||
w2t(f"30s内未触发急停,该条数据无效,需要确认RL/Python程序编写正确并正常执行,或者判别是否是机器本体问题,比如正负方向速度是否一致...", 0, 0, 'red', tab_name)
|
||||
md.write_probe(0)
|
||||
break
|
||||
else:
|
||||
sleep(1)
|
||||
|
||||
# 6. 保留数据并处理输出
|
||||
curve_data = []
|
||||
_c_msg = hr.c_msg.copy()
|
||||
for _msg in _c_msg:
|
||||
if 'diagnosis.result' in _msg:
|
||||
curve_data.insert(0, loads(_msg))
|
||||
else:
|
||||
hr.c_msg_xs.clear()
|
||||
if len(hr.c_msg) > 270:
|
||||
del hr.c_msg[270:]
|
||||
gen_result_file(path, curve_data, axis, _reach, _load, _speed, count)
|
||||
else:
|
||||
w2t(f"\n{loadsel.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。", 0, 0, 'green', tab_name)
|
||||
|
||||
|
||||
def main(path, hr, md, loadsel, w2t):
|
||||
_s_time = time()
|
||||
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
||||
config_file, reach33, reach66, reach100, prj_file, result_dirs = check_files(path, loadsel, data_dirs, data_files, w2t)
|
||||
clibs.prj_to_xcore(prj_file)
|
||||
run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t)
|
||||
_e_time = time()
|
||||
time_total = _e_time - _s_time
|
||||
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", 0, 0, 'green', tab_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(*argv[1:])
|
405
code/automatic_test/do_current.py
Normal file
405
code/automatic_test/do_current.py
Normal file
@ -0,0 +1,405 @@
|
||||
import json
|
||||
from os import mkdir
|
||||
import time
|
||||
from time import sleep, time
|
||||
from sys import argv
|
||||
from paramiko import SSHClient, AutoAddPolicy
|
||||
from json import loads
|
||||
from pandas import DataFrame, concat
|
||||
from common import clibs
|
||||
|
||||
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback"] for chl in range(6)]
|
||||
|
||||
|
||||
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
||||
def check_files():
|
||||
if len(data_dirs) != 0 or len(data_files) != 2:
|
||||
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下两个文件,确认后重新运行!\n", "red")
|
||||
w2t("1. T_电机电流.xlsx\n2. xxxx.zip\n", "red", "ConfigFileError")
|
||||
|
||||
prj_file, count = None, 0
|
||||
for data_file in data_files:
|
||||
filename = data_file.split("/")[-1]
|
||||
if filename == "T_电机电流.xlsx":
|
||||
count += 1
|
||||
elif filename.endswith(".zip"):
|
||||
count += 1
|
||||
prj_file = data_file
|
||||
else:
|
||||
w2t(f"{data_file} 不合规:初始路径下只能存在如下两个文件,确认后重新运行!\n", "red")
|
||||
w2t("1. T_电机电流.xlsx\n2. xxxx.zip\n", "red", "ConfigFileError")
|
||||
|
||||
if count != 2:
|
||||
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下两个文件,确认后重新运行!\n", "red")
|
||||
w2t("1. T_电机电流.xlsx\n2. xxxx.zip\n", "red", "ConfigFileError")
|
||||
w2t("数据目录合规性检查结束,未发现问题......\n")
|
||||
if sub == "tool100" or sub == "inertia":
|
||||
mkdir(f"{path}/single")
|
||||
mkdir(f"{path}/s_1")
|
||||
mkdir(f"{path}/s_2")
|
||||
mkdir(f"{path}/s_3")
|
||||
elif sub == "inertia":
|
||||
mkdir(f"{path}/inertia")
|
||||
else:
|
||||
w2t("负载选择错误,电机电流测试只能选择 tool100/inertia 规格!\n", "red", "LoadSelectError")
|
||||
|
||||
return prj_file
|
||||
|
||||
def get_configs():
|
||||
robot_type = None
|
||||
msg_id, state = hr.execution("controller.get_params")
|
||||
records = hr.get_from_id(msg_id, state)
|
||||
for record in records:
|
||||
if "请求发送成功" not in record[0]:
|
||||
robot_type = eval(record[0])["data"]["robot_type"]
|
||||
server_file = f"/home/luoshi/bin/controller/robot_cfg/{robot_type}/{robot_type}.cfg"
|
||||
local_file = path + f"/{robot_type}.cfg"
|
||||
clibs.c_pd.pull_file_from_server(server_file, local_file)
|
||||
return local_file
|
||||
|
||||
prj_file = check_files()
|
||||
config_file = get_configs()
|
||||
|
||||
return config_file, prj_file
|
||||
|
||||
|
||||
def data_proc_regular(path, filename, channel, scenario_time):
|
||||
if channel in list(range(6)):
|
||||
with open(filename, 'r', encoding='utf-8') as f_obj:
|
||||
lines = f_obj.readlines()
|
||||
_d2d_vel = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor = {'hw_sensor_trq_feedback': []}
|
||||
for line in lines[-500:]: # 保留最后25s的数据
|
||||
data = eval(line.strip())['data']
|
||||
for item in data:
|
||||
try:
|
||||
item['value'].reverse()
|
||||
except KeyError:
|
||||
continue
|
||||
if item.get('channel', None) == channel and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == channel and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == channel and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
|
||||
df1 = DataFrame.from_dict(_d2d_vel)
|
||||
df2 = DataFrame.from_dict(_d2d_trq)
|
||||
df3 = DataFrame.from_dict(_d2d_sensor)
|
||||
df = concat([df1, df2, df3], axis=1)
|
||||
_filename = f'{path}\\single\\j{channel+1}_single_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
elif channel in list(range(6, 9)):
|
||||
with open(filename, 'r', encoding='utf-8') as f_obj:
|
||||
lines = f_obj.readlines()
|
||||
_d2d_vel_0 = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq_0 = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor_0 = {'hw_sensor_trq_feedback': []}
|
||||
_d2d_vel_1 = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq_1 = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor_1 = {'hw_sensor_trq_feedback': []}
|
||||
_d2d_vel_2 = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq_2 = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor_2 = {'hw_sensor_trq_feedback': []}
|
||||
_d2d_vel_3 = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq_3 = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor_3 = {'hw_sensor_trq_feedback': []}
|
||||
_d2d_vel_4 = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq_4 = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor_4 = {'hw_sensor_trq_feedback': []}
|
||||
_d2d_vel_5 = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq_5 = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor_5 = {'hw_sensor_trq_feedback': []}
|
||||
for line in lines:
|
||||
data = eval(line.strip())['data']
|
||||
for item in data:
|
||||
try:
|
||||
item['value'].reverse()
|
||||
except KeyError:
|
||||
continue
|
||||
if item.get('channel', None) == 0 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel_0['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 0 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq_0['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 0 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor_0['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 1 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel_1['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 1 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq_1['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 1 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor_1['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 2 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel_2['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 2 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq_2['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 3 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor_2['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 3 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel_3['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 3 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq_3['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 3 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor_3['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 4 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel_4['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 4 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq_4['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 4 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor_4['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 5 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel_5['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 5 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq_5['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == 5 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor_5['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
|
||||
df_01 = DataFrame.from_dict(_d2d_vel_0)
|
||||
df_02 = DataFrame.from_dict(_d2d_trq_0)
|
||||
df_03 = DataFrame.from_dict(_d2d_sensor_0)
|
||||
df = concat([df_01, df_02, df_03], axis=1)
|
||||
_filename = f'{path}\\s_{channel-5}\\j1_s_{channel-5}_{scenario_time}_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
df_01 = DataFrame.from_dict(_d2d_vel_1)
|
||||
df_02 = DataFrame.from_dict(_d2d_trq_1)
|
||||
df_03 = DataFrame.from_dict(_d2d_sensor_1)
|
||||
df = concat([df_01, df_02, df_03], axis=1)
|
||||
_filename = f'{path}\\s_{channel-5}\\j2_s_{channel-5}_{scenario_time}_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
df_01 = DataFrame.from_dict(_d2d_vel_2)
|
||||
df_02 = DataFrame.from_dict(_d2d_trq_2)
|
||||
df_03 = DataFrame.from_dict(_d2d_sensor_2)
|
||||
df = concat([df_01, df_02, df_03], axis=1)
|
||||
_filename = f'{path}\\s_{channel-5}\\j3_s_{channel-5}_{scenario_time}_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
df_01 = DataFrame.from_dict(_d2d_vel_3)
|
||||
df_02 = DataFrame.from_dict(_d2d_trq_3)
|
||||
df_03 = DataFrame.from_dict(_d2d_sensor_3)
|
||||
df = concat([df_01, df_02, df_03], axis=1)
|
||||
_filename = f'{path}\\s_{channel-5}\\j4_s_{channel-5}_{scenario_time}_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
df_01 = DataFrame.from_dict(_d2d_vel_4)
|
||||
df_02 = DataFrame.from_dict(_d2d_trq_4)
|
||||
df_03 = DataFrame.from_dict(_d2d_sensor_4)
|
||||
df = concat([df_01, df_02, df_03], axis=1)
|
||||
_filename = f'{path}\\s_{channel-5}\\j5_s_{channel-5}_{scenario_time}_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
df_01 = DataFrame.from_dict(_d2d_vel_5)
|
||||
df_02 = DataFrame.from_dict(_d2d_trq_5)
|
||||
df_03 = DataFrame.from_dict(_d2d_sensor_5)
|
||||
df = concat([df_01, df_02, df_03], axis=1)
|
||||
_filename = f'{path}\\s_{channel-5}\\j6_s_{channel-5}_{scenario_time}_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
elif channel in list(range(9, 15)):
|
||||
with open(filename, 'r', encoding='utf-8') as f_obj:
|
||||
lines = f_obj.readlines()
|
||||
_d2d_vel = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor = {'hw_sensor_trq_feedback': []}
|
||||
for line in lines[-300:]: # 保留最后15s的数据
|
||||
data = eval(line.strip())['data']
|
||||
for item in data:
|
||||
try:
|
||||
item['value'].reverse()
|
||||
except KeyError:
|
||||
continue
|
||||
if item.get('channel', None) == channel-9 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == channel-9 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == channel-9 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_sensor['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
|
||||
df1 = DataFrame.from_dict(_d2d_vel)
|
||||
df2 = DataFrame.from_dict(_d2d_trq)
|
||||
df3 = DataFrame.from_dict(_d2d_sensor)
|
||||
df = concat([df1, df2, df3], axis=1)
|
||||
_filename = f'{path}\\single\\j{channel-8}_hold_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
|
||||
def data_proc_inertia(path, filename, channel):
|
||||
with open(filename, 'r', encoding='utf-8') as f_obj:
|
||||
lines = f_obj.readlines()
|
||||
_d2d_vel = {'hw_joint_vel_feedback': []}
|
||||
_d2d_trq = {'device_servo_trq_feedback': []}
|
||||
_d2d_sensor = {'hw_sensor_trq_feedback': []}
|
||||
for line in lines:
|
||||
data = eval(line.strip())['data']
|
||||
for item in data:
|
||||
try:
|
||||
item['value'].reverse()
|
||||
except KeyError:
|
||||
continue
|
||||
if item.get('channel', None) == channel+3 and item.get('name', None) == 'hw_joint_vel_feedback':
|
||||
_d2d_vel['hw_joint_vel_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == channel+3 and item.get('name', None) == 'device_servo_trq_feedback':
|
||||
_d2d_trq['device_servo_trq_feedback'].extend(item['value'])
|
||||
elif item.get('channel', None) == channel+3 and item.get('name', None) == 'hw_sensor_trq_feedback':
|
||||
_d2d_trq['hw_sensor_trq_feedback'].extend(item['value'])
|
||||
|
||||
df1 = DataFrame.from_dict(_d2d_vel)
|
||||
df2 = DataFrame.from_dict(_d2d_trq)
|
||||
df3 = DataFrame.from_dict(_d2d_sensor)
|
||||
df = concat([df1, df2, df3], axis=1)
|
||||
_filename = f'{path}\\inertia\\j{channel+4}_inertia_{time()}.data'
|
||||
df.to_csv(_filename, sep='\t', index=False)
|
||||
|
||||
|
||||
def gen_result_file(path, loadsel, disc, number, scenario_time):
|
||||
filename = path + f'\\data.txt'
|
||||
with open(filename, 'w', encoding='utf-8') as f_obj:
|
||||
for line in disc[number][1]:
|
||||
f_obj.write(str(line)+'\n')
|
||||
|
||||
if loadsel == 'tool100':
|
||||
data_proc_regular(path, filename, number, scenario_time)
|
||||
elif loadsel == 'inertia':
|
||||
data_proc_inertia(path, filename, number)
|
||||
|
||||
|
||||
def run_rl(path, hr, md, sub, w2t):
|
||||
c_regular = [
|
||||
"scenario(0, j1_p, j1_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(0, j2_p, j2_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(0, j3_p, j3_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(0, j4_p, j4_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(0, j5_p, j5_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(0, j6_p, j6_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(1, j6_p, j6_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(2, j6_p, j6_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(3, j6_p, j6_n, p_speed, p_tool, i_tool)",
|
||||
"scenario(4, j1_hold, j1_hold, p_speed, p_tool, i_tool)",
|
||||
"scenario(4, j2_hold, j2_hold, p_speed, p_tool, i_tool)",
|
||||
"scenario(4, j3_hold, j3_hold, p_speed, p_tool, i_tool)",
|
||||
"scenario(4, j4_hold, j4_hold, p_speed, p_tool, i_tool)",
|
||||
"scenario(4, j5_hold, j5_hold, p_speed, p_tool, i_tool)",
|
||||
"scenario(4, j6_hold, j6_hold, p_speed, p_tool, i_tool)",
|
||||
]
|
||||
c_inertia = [
|
||||
"scenario(5, j4_p_inertia, j4_n_inertia, p_speed, p_tool, i_tool)",
|
||||
"scenario(5, j5_p_inertia, j5_n_inertia, p_speed, p_tool, i_tool)",
|
||||
"scenario(5, j6_p_inertia, j6_n_inertia, p_speed, p_tool, i_tool)",
|
||||
]
|
||||
disc_regular = {
|
||||
0: ['一轴', []], 1: ['二轴', []], 2: ['三轴', []], 3: ['四轴', []], 4: ['五轴', []], 5: ['六轴', []],
|
||||
6: ['场景一', []], 7: ['场景二', []], 8: ['场景三', []], 9: ['一轴保持', []], 10: ['二轴保持', []],
|
||||
11: ['三轴保持', []], 12: ['四轴保持', []], 13: ['五轴保持', []], 14: ['六轴保持', []]
|
||||
}
|
||||
disc_inertia = {0: ['四轴惯量', []], 1: ['五轴惯量', []], 2: ['六轴惯量', []]}
|
||||
if sub == 'tool100':
|
||||
conditions = c_regular
|
||||
disc = disc_regular
|
||||
elif sub == 'inertia':
|
||||
conditions = c_inertia
|
||||
disc = disc_inertia
|
||||
|
||||
# preparation 触发软急停,并解除,目的是让可能正在运行着的机器停下来
|
||||
hr.execution('diagnosis.open', hr, w2t, tab_name, open=True, display_open=True)
|
||||
hr.execution('diagnosis.set_params', hr, w2t, tab_name, display_pdo_params=display_pdo_params)
|
||||
# clibs.execution('diagnosis.save', hr, w2t, tab_name, save=True) # 这条命令有问题
|
||||
md.trigger_estop()
|
||||
md.reset_estop()
|
||||
|
||||
for condition in conditions:
|
||||
number = conditions.index(condition)
|
||||
w2t(f"正在执行{disc[number][0]}测试......", 0, 0, 'purple', tab_name)
|
||||
|
||||
# 1. 将act重置为False,并修改未要执行的场景
|
||||
md.write_act(False)
|
||||
ssh = SSHClient()
|
||||
ssh.set_missing_host_key_policy(AutoAddPolicy())
|
||||
ssh.connect(clibs.ip_addr, 22, username='luoshi', password='luoshi2019')
|
||||
cmd = 'cd /home/luoshi/bin/controller/; '
|
||||
cmd += 'sudo sed -i "/scenario/d" projects/target/_build/current/main.mod; '
|
||||
cmd += f'sudo sed -i "/DONOTDELETE/i {condition}" projects/target/_build/current/main.mod'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write('luoshi2019' + '\n')
|
||||
stdout.read().decode() # 需要read一下才能正常执行
|
||||
stderr.read().decode()
|
||||
|
||||
# 2. reload工程后,pp2main,并且自动模式和上电
|
||||
prj_path = 'target/_build/target.prj'
|
||||
clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['current'])
|
||||
clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['current'])
|
||||
clibs.execution('state.switch_auto', hr, w2t, tab_name)
|
||||
clibs.execution('state.switch_motor_on', hr, w2t, tab_name)
|
||||
|
||||
# 3. 开始运行程序,单轴运行35s
|
||||
clibs.execution('rl_task.set_run_params', hr, w2t, tab_name, loop_mode=True, override=1.0)
|
||||
clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['current'])
|
||||
_t_start = time()
|
||||
while True:
|
||||
if md.read_ready_to_go() == 1:
|
||||
md.write_act(True)
|
||||
break
|
||||
else:
|
||||
if (time() - _t_start) // 20 > 1:
|
||||
w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name)
|
||||
else:
|
||||
sleep(1)
|
||||
|
||||
# 4. 打开诊断曲线,并执行采集
|
||||
sleep(10) # 保证程序已经运行起来,其实主要是为了保持电流的采集而设定
|
||||
scenario_time = 0
|
||||
if number < 6:
|
||||
sleep(35)
|
||||
elif number > 8:
|
||||
sleep(15)
|
||||
else:
|
||||
_t_start = time()
|
||||
while True:
|
||||
scenario_time = md.read_scenario_time()
|
||||
if float(scenario_time) > 1:
|
||||
w2t(f"场景{number-5}的周期时间:{scenario_time}", 0, 0, 'green', tab_name)
|
||||
break
|
||||
else:
|
||||
if (time()-_t_start)//60 > 3:
|
||||
w2t(f"未收到场景{number-5}的周期时间,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name)
|
||||
else:
|
||||
sleep(5)
|
||||
sleep(1) # 一定要延迟一秒再读一次scenario time寄存器,因为一开始读取的数值不准确
|
||||
scenario_time = md.read_scenario_time()
|
||||
sleep(float(scenario_time)*0.2) # 再运行周期的20%即可
|
||||
|
||||
# 5.停止程序运行,保留数据并处理输出
|
||||
clibs.execution('rl_task.stop', hr, w2t, tab_name, tasks=['current'])
|
||||
_c_msg = hr.c_msg.copy()
|
||||
for _msg in _c_msg:
|
||||
if 'diagnosis.result' in _msg:
|
||||
disc[number][1].insert(0, loads(_msg))
|
||||
else:
|
||||
hr.c_msg_xs.clear()
|
||||
if len(hr.c_msg) > 270:
|
||||
del hr.c_msg[270:]
|
||||
gen_result_file(path, loadsel, disc, number, scenario_time)
|
||||
else:
|
||||
if loadsel == 'tool100':
|
||||
w2t("单轴和场景电机电流采集完毕,如需采集惯量负载,须切换负载类型,并更换惯量负载,重新执行。", 0, 0, 'green', tab_name)
|
||||
elif loadsel == 'inertia':
|
||||
w2t("惯量负载电机电流采集完毕,如需采集单轴/场景/保持电机电流,须切换负载类型,并更换偏置负载,重新执行。", 0, 0, 'green', tab_name)
|
||||
|
||||
|
||||
def main():
|
||||
path = clibs.data_at["_path"]
|
||||
sub = clibs.data_at["_sub"]
|
||||
w2t = clibs.w2t
|
||||
hr = clibs.c_hr
|
||||
md = clibs.c_md
|
||||
insert_logdb = clibs.insert_logdb
|
||||
|
||||
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
||||
config_file, prj_file = initialization(path, sub, data_dirs, data_files, hr, w2t)
|
||||
clibs.c_pd.push_prj_to_server(prj_file)
|
||||
clibs.c_hr.execution("diagnosis.open", open=False, display_open=False, overrun=True, turn_area=True, delay_motion=False)
|
||||
# run_rl(path, hr, md, sub, w2t)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -21,15 +21,16 @@ def traversal_files(_path, _w2t):
|
||||
return dirs, files
|
||||
|
||||
|
||||
def init_logdb(_conn, _cursor):
|
||||
_conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False, cached_statements=4096)
|
||||
_cursor = _conn.cursor()
|
||||
_cursor.execute("PRAGMA journal_mode=wal")
|
||||
_cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
|
||||
_cursor.execute("PRAGMA synchronous=normal")
|
||||
_cursor.execute("PRAGMA temp_store=memory")
|
||||
_cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
_cursor.execute(
|
||||
def init_logdb(conn, cursor):
|
||||
conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False, cached_statements=2048)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("PRAGMA journal_mode=wal")
|
||||
cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
|
||||
cursor.execute("PRAGMA synchronous=normal")
|
||||
cursor.execute("PRAGMA temp_store=memory")
|
||||
cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
cursor.execute("PRAGMA cache_size=200000")
|
||||
cursor.execute(
|
||||
"""
|
||||
create table if not exists logs(
|
||||
id integer primary key autoincrement,
|
||||
@ -40,7 +41,7 @@ def init_logdb(_conn, _cursor):
|
||||
)
|
||||
"""
|
||||
)
|
||||
return _conn, _cursor
|
||||
return conn, cursor
|
||||
|
||||
|
||||
def db_lock(func):
|
||||
@ -61,7 +62,7 @@ def insert_logdb(_level, _module, _content):
|
||||
global conn, cursor, lock
|
||||
if "move.monitor" in _content:
|
||||
return
|
||||
data = [_level, _module, repr(_content)]
|
||||
data = [_level, _module, _content]
|
||||
cursor.execute("insert into logs (level, module, content) values (?, ?, ?)", data)
|
||||
|
||||
|
||||
@ -89,7 +90,6 @@ class GetThreadResult(threading.Thread):
|
||||
|
||||
def get_result(self):
|
||||
threading.Thread.join(self) # 等待线程执行完毕
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
return self.result
|
||||
except Exception:
|
||||
@ -99,35 +99,18 @@ class GetThreadResult(threading.Thread):
|
||||
# PREFIX = 'assets' # for pyinstaller packaging
|
||||
PREFIX = '../assets' # for source code testing and debug
|
||||
log_path = f"{PREFIX}/logs"
|
||||
conn = None
|
||||
cursor = None
|
||||
levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
|
||||
db_state = "readwrite"
|
||||
data_dp = {}
|
||||
data_at = {}
|
||||
w2t = None
|
||||
running = False
|
||||
stop = True
|
||||
tl_prg = None
|
||||
f_records = None
|
||||
data_dp, data_at = {}, {}
|
||||
conn, cursor, w2t, tl_prg, f_records, stop, running = None, None, None, None, None, True, False
|
||||
|
||||
ip_addr = "192.168.0.160"
|
||||
ssh_port = 22
|
||||
socket_port = 5050
|
||||
xService_port = 6666
|
||||
external_port = 8080
|
||||
modbus_port = 502
|
||||
upgrade_port = 4567
|
||||
username = "luoshi"
|
||||
password = "luoshi2019" # for real robot
|
||||
# password = "forpqart" # for robot vm
|
||||
ssh_port, socket_port, xService_port, external_port, modbus_port, upgrade_port = 22, 5050, 6666, 8080, 502, 4567
|
||||
username, password = "luoshi", "luoshi2019"
|
||||
interval = 0.5 # interval after actions being triggered, such as modbus/socket/external communication operations
|
||||
RADIAN = 57.3 # 180 / 3.1415926
|
||||
MAX_FRAME_SIZE = 1024
|
||||
c_md = None
|
||||
c_hr = None
|
||||
c_ec = None
|
||||
c_pd = None
|
||||
c_md, c_hr, c_ec, c_pd = None, None, None, None
|
||||
lock = threading.Lock()
|
||||
|
||||
conn, cursor = init_logdb(conn, cursor)
|
||||
|
@ -11,7 +11,6 @@ import time
|
||||
from common import clibs
|
||||
|
||||
from os import listdir
|
||||
from threading import Thread
|
||||
# from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder
|
||||
# from pymodbus.constants import Endian
|
||||
import os.path
|
||||
@ -290,7 +289,7 @@ class ModbusRequest(object):
|
||||
|
||||
|
||||
class HmiRequest(object):
|
||||
socket.setdefaulttimeout(clibs.interval * 10)
|
||||
socket.setdefaulttimeout(clibs.interval * 6)
|
||||
|
||||
def __init__(self, ip, port, port_xs):
|
||||
self.__ip = ip
|
||||
@ -312,38 +311,15 @@ class HmiRequest(object):
|
||||
self.__is_debug = True
|
||||
|
||||
self.__socket_conn()
|
||||
self.__t_heartbeat = Thread(target=self.__heartbeat)
|
||||
self.__t_heartbeat = threading.Thread(target=self.__heartbeat)
|
||||
self.__t_heartbeat.daemon = True
|
||||
self.__t_heartbeat.start()
|
||||
self.__t_unpackage = Thread(target=self.__unpackage, args=(self.__c,))
|
||||
self.__t_unpackage = threading.Thread(target=self.__unpackage, args=(self.__c,))
|
||||
self.__t_unpackage.daemon = True
|
||||
self.__t_unpackage.start()
|
||||
self.__t_unpackage_xs = Thread(target=self.__unpackage_xs, args=(self.__c_xs,))
|
||||
self.__t_unpackage_xs = threading.Thread(target=self.__unpackage_xs, args=(self.__c_xs,))
|
||||
self.__t_unpackage_xs.daemon = True
|
||||
self.__t_unpackage_xs.start()
|
||||
# self.__t_heartbeat = None
|
||||
# self.__t_unpackage = None
|
||||
# self.__t_unpackage_xs = None
|
||||
# self.__t_is_alive = Thread(target=self.__is_alive)
|
||||
# self.__t_is_alive.daemon = True
|
||||
# self.__t_is_alive.start()
|
||||
# time.sleep(3)
|
||||
|
||||
def __is_alive(self):
|
||||
while not self.__close_hmi:
|
||||
if not self.__is_connected:
|
||||
self.__socket_conn()
|
||||
if self.__is_connected:
|
||||
self.__t_heartbeat = Thread(target=self.__heartbeat)
|
||||
self.__t_heartbeat.daemon = True
|
||||
self.__t_heartbeat.start()
|
||||
self.__t_unpackage = Thread(target=self.__unpackage, args=(self.__c,))
|
||||
self.__t_unpackage.daemon = True
|
||||
self.__t_unpackage.start()
|
||||
self.__t_unpackage_xs = Thread(target=self.__unpackage_xs, args=(self.__c_xs,))
|
||||
self.__t_unpackage_xs.daemon = True
|
||||
self.__t_unpackage_xs.start()
|
||||
time.sleep(3)
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
@ -351,7 +327,6 @@ class HmiRequest(object):
|
||||
|
||||
def close(self):
|
||||
try:
|
||||
# self.__close_hmi = True
|
||||
self.__is_connected = False
|
||||
time.sleep(clibs.interval*2)
|
||||
self.__c.close()
|
||||
@ -458,7 +433,7 @@ class HmiRequest(object):
|
||||
self.__index += pkg_value
|
||||
# with open(f"{clibs.log_path}/response.txt", mode="a", encoding="utf-8") as f_res:
|
||||
# f_res.write(f"{json.loads(self.__response.decode())}" + "\n")
|
||||
clibs.insert_logdb("DEBUG", "openapi", self.__response.decode())
|
||||
clibs.insert_logdb("DEBUG", "openapi", str(json.loads(self.__response.decode())))
|
||||
self.__response = b""
|
||||
self.__leftovers = 0
|
||||
self.__is_first_frame = True
|
||||
@ -506,7 +481,7 @@ class HmiRequest(object):
|
||||
if self.__valid_data_length == 0:
|
||||
# with open(f"{clibs.log_path}/response.txt", mode="a", encoding="utf-8") as f_res:
|
||||
# f_res.write(f"{json.loads(self.__response.decode())}" + "\n")
|
||||
clibs.insert_logdb("DEBUG", "openapi", self.__response.decode())
|
||||
clibs.insert_logdb("DEBUG", "openapi", str(json.loads(self.__response.decode())))
|
||||
self.__response = b""
|
||||
self.__is_first_frame = True
|
||||
continue # 此时应该重新 get_headers
|
||||
@ -538,7 +513,7 @@ class HmiRequest(object):
|
||||
self.__leftovers = 0
|
||||
# with open(f"{clibs.log_path}/response.txt", mode="a", encoding="utf-8") as f_res:
|
||||
# f_res.write(f"{json.loads(self.__response.decode())}" + "\n")
|
||||
clibs.insert_logdb("DEBUG", "openapi", self.__response.decode())
|
||||
clibs.insert_logdb("DEBUG", "openapi", str(json.loads(self.__response.decode())))
|
||||
self.__response = b""
|
||||
self.__is_first_frame = True
|
||||
elif len(data) < self.__leftovers:
|
||||
@ -596,7 +571,7 @@ class HmiRequest(object):
|
||||
if self.__valid_data_length == 0:
|
||||
# with open(f"{clibs.log_path}/response.txt", mode="a", encoding="utf-8") as f_res:
|
||||
# f_res.write(f"{json.loads(self.__response.decode())}" + "\n")
|
||||
clibs.insert_logdb("DEBUG", "openapi", self.__response.decode())
|
||||
clibs.insert_logdb("DEBUG", "openapi", str(json.loads(self.__response.decode())))
|
||||
self.__response = b""
|
||||
self.__is_first_frame = True
|
||||
continue
|
||||
@ -626,7 +601,7 @@ class HmiRequest(object):
|
||||
if self.__valid_data_length == 0:
|
||||
# with open(f"{clibs.log_path}/response.txt", mode="a", encoding="utf-8") as f_res:
|
||||
# f_res.write(f"{json.loads(self.__response.decode())}" + "\n")
|
||||
clibs.insert_logdb("DEBUG", "openapi", self.__response.decode())
|
||||
clibs.insert_logdb("DEBUG", "openapi", str(json.loads(self.__response.decode())))
|
||||
self.__response = b""
|
||||
self.__is_first_frame = True
|
||||
continue
|
||||
@ -701,20 +676,20 @@ class HmiRequest(object):
|
||||
self.__response_xs = response
|
||||
|
||||
def get_from_id(self, msg_id, state):
|
||||
f_text = f"%{msg_id}%"
|
||||
f_text, res = f"%{msg_id}%", 0
|
||||
if state is None:
|
||||
self.close()
|
||||
clibs.w2t(f"请求 {msg_id} 发送失败......", "red", "ReqSendFailed")
|
||||
clibs.w2t(f"请求 {msg_id} 发送失败......\n", "red", "ReqSendFailed")
|
||||
for _ in range(3):
|
||||
time.sleep(clibs.interval * 2)
|
||||
try:
|
||||
clibs.lock.acquire(True)
|
||||
clibs.cursor.execute(f"select content from logs where content like '{f_text}'")
|
||||
res = len(clibs.cursor.fetchall())
|
||||
records = clibs.cursor.fetchall()
|
||||
finally:
|
||||
clibs.lock.release()
|
||||
if res >= 2:
|
||||
break
|
||||
if len(records) == 2:
|
||||
return records
|
||||
else:
|
||||
clibs.insert_logdb("ERROR", "openapi", f"hr: 无法找到请求 {msg_id} 的响应")
|
||||
self.close()
|
||||
@ -739,7 +714,8 @@ class HmiRequest(object):
|
||||
with open(f"{clibs.PREFIX}/files/protocols/{command}.json", encoding="utf-8", mode="r") as f_json:
|
||||
req = json.load(f_json)
|
||||
except Exception as Err:
|
||||
clibs.insert_logdb("ERROR", "openapi", f"hr: 暂不支持 {command} 功能,或确认该功能存在... {Err}")
|
||||
clibs.insert_logdb("ERROR", "openapi", f"hr-execution: 暂不支持 {command} 功能,或确认该功能存在... {Err}")
|
||||
clibs.w2t(f"hr-execution: 暂不支持 {command} 功能,或确认该功能存在... {Err}", "red")
|
||||
|
||||
if p_flag == 0: # for old protocols
|
||||
match command:
|
||||
@ -1863,7 +1839,7 @@ class ExternalCommunication(object):
|
||||
self.exec_desc = " :--: 返回 true 表示执行成功,false 失败"
|
||||
|
||||
def socket_client(self):
|
||||
self.__c = socket(AF_INET, SOCK_STREAM)
|
||||
self.__c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
self.__c.connect((clibs.ip_addr, clibs.external_port))
|
||||
clibs.insert_logdb("INFO", "openapi", f"ec: 外部通信连接成功...")
|
||||
@ -2127,31 +2103,35 @@ class ExternalCommunication(object):
|
||||
|
||||
|
||||
class PreDos(object):
|
||||
def __init__(self):
|
||||
def __init__(self, ip, port, username, password):
|
||||
self.__ssh = None
|
||||
self.__sftp = None
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def __ssh2server(self):
|
||||
try:
|
||||
self.__ssh = SSHClient()
|
||||
self.__ssh.set_missing_host_key_policy(AutoAddPolicy())
|
||||
self.__ssh.connect(clibs.ip_addr, clibs.ssh_port, username=clibs.username, password=clibs.password)
|
||||
self.__ssh.connect(hostname=self.ip, port=self.port, username=self.username, password=self.password)
|
||||
self.__sftp = self.__ssh.open_sftp()
|
||||
except Exception as Err:
|
||||
msg = f"predos: SSH 无法连接到 {clibs.ip_addr}:{clibs.ssh_port},需检查网络连通性或者登录信息是否正确 {Err}"
|
||||
msg = f"predos: SSH 无法连接到 {self.ip}:{self.port},需检查网络连通性或者登录信息是否正确 {Err}"
|
||||
clibs.insert_logdb("ERROR", "openapi", msg)
|
||||
clibs.w2t(msg, "red", f"SSHError: cannot connected to {clibs.ip_addr}:{clibs.ssh_port}")
|
||||
clibs.w2t(msg, "red", f"SSHError: cannot connected to {self.ip}:{self.port}")
|
||||
|
||||
def push_prj_to_server(self, prj_file):
|
||||
# prj_file:本地工程完整路径
|
||||
self.__ssh2server()
|
||||
prj_name = prj_file.split("\\")[-1].split("/")[-1].split(".")[0]
|
||||
prj_name = prj_file.split("/")[-1].split(".")[0]
|
||||
self.__sftp.put(prj_file, f"/tmp/{prj_name}.zip")
|
||||
cmd = f"cd /tmp; mkdir {prj_name}; unzip -d {prj_name} -q {prj_name}.zip; rm -rf /tmp/{prj_name}.zip; "
|
||||
cmd += f"sudo rm -rf /home/luoshi/bin/controller/projects/{prj_name}; "
|
||||
cmd += f"sudo mv /tmp/{prj_name}/ /home/luoshi/bin/controller/projects/"
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write(clibs.password + "\n")
|
||||
stdin.write(self.password + "\n")
|
||||
stdout.read().decode() # 需要read一下才能正常执行
|
||||
stderr.read().decode()
|
||||
self.__ssh.close()
|
||||
@ -2163,14 +2143,14 @@ class PreDos(object):
|
||||
cmd = f"cd /tmp/; sudo rm -rf {prj_name}*; sudo cp -rf /home/luoshi/bin/controller/projects/{prj_name} .; "
|
||||
cmd += f"sudo zip -q -r {prj_name}.zip {prj_name}/; sudo rm -rf {prj_name}"
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write(clibs.password + "\n")
|
||||
stdin.write(self.password + "\n")
|
||||
print(stdout.read().decode()) # 需要read一下才能正常执行
|
||||
print(stderr.read().decode())
|
||||
|
||||
self.__sftp.get(f"/tmp/{prj_name}.zip", local_prj_path)
|
||||
cmd = f"sudo rm -rf /tmp/{prj_name}.zip"
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write(clibs.password + "\n")
|
||||
stdin.write(self.password + "\n")
|
||||
print(stdout.read().decode()) # 需要read一下才能正常执行
|
||||
print(stderr.read().decode())
|
||||
|
||||
@ -2184,7 +2164,7 @@ class PreDos(object):
|
||||
self.__sftp.put(local_file, f"/tmp/{filename}")
|
||||
cmd = f"sudo mv /tmp/{filename} {server_file}"
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write(clibs.password + "\n")
|
||||
stdin.write(self.password + "\n")
|
||||
stdout.read().decode() # 需要read一下才能正常执行
|
||||
stderr.read().decode()
|
||||
self.__ssh.close()
|
||||
@ -2195,21 +2175,21 @@ class PreDos(object):
|
||||
self.__ssh2server()
|
||||
cmd = f"sudo cp {server_file} /tmp/"
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write(clibs.password + "\n")
|
||||
stdin.write(self.password + "\n")
|
||||
stdout.read().decode() # 需要read一下才能正常执行
|
||||
stderr.read().decode()
|
||||
filename = server_file.split("/")[-1]
|
||||
self.__sftp.get(f"/tmp/{filename}", f"{local_file}")
|
||||
cmd = f"sudo rm -rf /tmp/{filename}"
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(cmd, get_pty=True)
|
||||
stdin.write(clibs.password + "\n")
|
||||
stdin.write(self.password + "\n")
|
||||
stdout.read().decode() # 需要read一下才能正常执行
|
||||
stderr.read().decode()
|
||||
self.__ssh.close()
|
||||
|
||||
|
||||
def robot_init():
|
||||
hr = HmiRequest()
|
||||
hr = clibs.c_hr
|
||||
pd = PreDos()
|
||||
# 推送配置文件
|
||||
clibs.insert_logdb("INFO", "openapi", "init: 推送配置文件 fieldbus_device.json/registers.json/registers.xml 到控制器,并配置 IO 设备,设备号为 7...")
|
||||
@ -2254,7 +2234,7 @@ def robot_init():
|
||||
hr.reload_fieldbus()
|
||||
hr.set_fieldbus_device_params("autotest", True)
|
||||
|
||||
md = ModbusRequest()
|
||||
md = clibs.c_md
|
||||
# 触发急停并恢复
|
||||
md.r_soft_estop(0)
|
||||
md.r_soft_estop(1)
|
||||
@ -2323,12 +2303,12 @@ def fw_updater(local_file_path):
|
||||
fw_size = os.path.getsize(local_file_path)
|
||||
if fw_size > 10000000:
|
||||
# get previous version of xCore
|
||||
hr = HmiRequest()
|
||||
hr = clibs.c_hr
|
||||
version_previous = hr.get_robot_params["version"]
|
||||
hr.close()
|
||||
|
||||
# var def
|
||||
remote_file_path = './upgrade/lircos.zip'
|
||||
remote_file_path = "./upgrade/lircos.zip"
|
||||
fw_content = bytearray()
|
||||
package_data = bytearray()
|
||||
package_data_with_head = bytearray()
|
||||
@ -2336,7 +2316,7 @@ def fw_updater(local_file_path):
|
||||
# socket connect
|
||||
clibs.insert_logdb("INFO", "openapi", f"update firmware: 正在连接 {clibs.ip_addr}:{clibs.upgrade_port}...")
|
||||
try:
|
||||
tcp_socket = socket(AF_INET, SOCK_STREAM)
|
||||
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
tcp_socket.connect((clibs.ip_addr, clibs.upgrade_port))
|
||||
tcp_socket.setblocking(True)
|
||||
except Exception as Err:
|
||||
@ -2345,13 +2325,13 @@ def fw_updater(local_file_path):
|
||||
|
||||
# get firmware content of binary format
|
||||
clibs.insert_logdb("INFO", "openapi", f"update firmware: 正在读取 {local_file_path} 文件内容...")
|
||||
with open(local_file_path, 'rb') as f_fw:
|
||||
with open(local_file_path, "rb") as f_fw:
|
||||
fw_content += f_fw.read()
|
||||
|
||||
# construct package data: http://confluence.i.rokae.com/pages/viewpage.action?pageId=15634148
|
||||
clibs.insert_logdb("INFO", "openapi", "update firmware: 正在构造数据包,以及包头...")
|
||||
# 1 protocol id
|
||||
protocol_id = c_ushort(htons(0)) # 2 bytes
|
||||
protocol_id = c_ushort(socket.htons(0)) # 2 bytes
|
||||
package_data += protocol_id
|
||||
|
||||
# 2 write type
|
||||
@ -2369,7 +2349,7 @@ def fw_updater(local_file_path):
|
||||
i += 2
|
||||
|
||||
# 4 remote path len
|
||||
remote_file_path_len = c_ushort(htons(len(remote_file_path)))
|
||||
remote_file_path_len = c_ushort(socket.htons(len(remote_file_path)))
|
||||
package_data += remote_file_path_len
|
||||
|
||||
# 5 remote path
|
||||
@ -2380,7 +2360,7 @@ def fw_updater(local_file_path):
|
||||
|
||||
# construct communication protocol: http://confluence.i.rokae.com/pages/viewpage.action?pageId=15634045
|
||||
# 1 get package data with header
|
||||
package_size = c_uint(htonl(len(package_data)))
|
||||
package_size = c_uint(socket.htonl(len(package_data)))
|
||||
package_type = c_ubyte(1) # 0-无协议 1-文件 2-json
|
||||
package_reserve = c_ubyte(0) # 预留位
|
||||
|
||||
@ -2409,7 +2389,7 @@ def fw_updater(local_file_path):
|
||||
|
||||
if fw_size > 10000000:
|
||||
# get current version of xCore
|
||||
hr = HmiRequest()
|
||||
hr = clibs.c_hr
|
||||
version_current = hr.get_robot_params["version"]
|
||||
hr.close()
|
||||
|
||||
@ -2429,7 +2409,7 @@ class UpgradeJsonCmd(object):
|
||||
# socket connect
|
||||
clibs.insert_logdb("INFO", "clibs", f"正在连接 {clibs.ip_addr}:{clibs.upgrade_port}...")
|
||||
try:
|
||||
self.__c = socket(AF_INET, SOCK_STREAM)
|
||||
self.__c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.__c.connect((clibs.ip_addr, clibs.upgrade_port))
|
||||
self.__c.setblocking(True)
|
||||
self.__c.settimeout(3)
|
||||
@ -2439,16 +2419,16 @@ class UpgradeJsonCmd(object):
|
||||
|
||||
@staticmethod
|
||||
def __do_package(cmd):
|
||||
package_size = struct.pack('!I', len(cmd))
|
||||
package_type = struct.pack('B', 2)
|
||||
reserved_byte = struct.pack('B', 0)
|
||||
package_size = struct.pack("!I", len(cmd))
|
||||
package_type = struct.pack("B", 2)
|
||||
reserved_byte = struct.pack("B", 0)
|
||||
return package_size + package_type + reserved_byte + cmd
|
||||
|
||||
def __recv_result(self, cmd):
|
||||
time.sleep(2)
|
||||
try:
|
||||
res = self.__c.recv(10240).decode()
|
||||
except timeout:
|
||||
except Exception:
|
||||
res = "ResponseNone"
|
||||
clibs.insert_logdb("INFO", "openapi", f"upgrade: 请求命令 {cmd.decode()} 的返回信息:\n{res[8:]}")
|
||||
self.__c.close()
|
||||
@ -2457,7 +2437,7 @@ class UpgradeJsonCmd(object):
|
||||
def __exec(self, command: dict):
|
||||
try:
|
||||
self.__c.recv(10240)
|
||||
except timeout:
|
||||
except Exception:
|
||||
pass
|
||||
cmd = json.dumps(command, separators=(",", ":")).encode("utf-8")
|
||||
self.__c.sendall(self.__do_package(cmd))
|
||||
|
@ -1,3 +1,4 @@
|
||||
import json
|
||||
import threading
|
||||
import openpyxl
|
||||
import pandas
|
||||
@ -8,26 +9,26 @@ from common import clibs
|
||||
|
||||
def initialization(path, w2t, insert_logdb):
|
||||
_, data_files = clibs.traversal_files(path, w2t)
|
||||
count = 0
|
||||
count, config_file = 0, None
|
||||
for data_file in data_files:
|
||||
filename = data_file.split("/")[-1]
|
||||
if filename == "configs.xlsx":
|
||||
if re.match(".*\\.cfg", filename):
|
||||
config_file = filename
|
||||
count += 1
|
||||
elif filename == "T_电机电流.xlsx":
|
||||
...
|
||||
count += 1
|
||||
else:
|
||||
if not re.match("j[1-7].*\\.data", filename):
|
||||
msg = f"不合规 {data_file}\n"
|
||||
msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾,比如j1_abcdef.data\n配置文件需要命名为\"configs.xlsx\",结果文件需要命名为\"T_电机电流.xlsx\"\n"
|
||||
msg += "需要有配置文件\"configs.xlsx\"表格,以及数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行\n"
|
||||
msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾,比如j1_abcdef.data,请检查整改后重新运行\n"
|
||||
w2t(msg, "red", "FilenameIllegal")
|
||||
|
||||
if count != 1:
|
||||
msg = "需要有配置文件\"configs.xlsx\"表格,以及数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行\n"
|
||||
if count != 2:
|
||||
msg = "需要有一个机型配置文件\"*.cfg\",以及一个数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行\n"
|
||||
w2t(msg, "red", "FilenameIllegal")
|
||||
|
||||
insert_logdb("INFO", "current", f"current: 获取必要文件:{data_files}")
|
||||
return data_files
|
||||
return data_files, config_file
|
||||
|
||||
|
||||
def current_max(data_files, rcs, trq, w2t, insert_logdb):
|
||||
@ -71,7 +72,7 @@ def current_max(data_files, rcs, trq, w2t, insert_logdb):
|
||||
return current
|
||||
|
||||
|
||||
def current_avg(data_files, rcs, trq, w2t, insert_logdb):
|
||||
def current_avg(data_files, rcs, trqh, w2t, insert_logdb):
|
||||
insert_logdb("INFO", "current", "AVG: 正在处理平均电流值逻辑...")
|
||||
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
||||
for data_file in data_files:
|
||||
@ -86,7 +87,7 @@ def current_avg(data_files, rcs, trq, w2t, insert_logdb):
|
||||
rca = rcs[axis-1]
|
||||
insert_logdb("INFO", "current", f"AVG: 最大列数为 {cols},{axis} 轴的额定电流为 {rca}")
|
||||
|
||||
col = df.columns.values[trq-1]
|
||||
col = df.columns.values[trqh-1]
|
||||
c_std = df[col].std()
|
||||
c_avg = df[col].mean()
|
||||
|
||||
@ -113,7 +114,7 @@ def current_avg(data_files, rcs, trq, w2t, insert_logdb):
|
||||
return current
|
||||
|
||||
|
||||
def current_cycle(data_files, vel, trq, trqh, rrs, rcs, rpms, w2t, insert_logdb):
|
||||
def current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, insert_logdb):
|
||||
result, hold, single, scenario, dur_time = None, [], [], [], 0
|
||||
for data_file in data_files:
|
||||
filename = data_file.split("/")[-1]
|
||||
@ -137,6 +138,12 @@ def current_cycle(data_files, vel, trq, trqh, rrs, rcs, rpms, w2t, insert_logdb)
|
||||
t_progress.start()
|
||||
wb = t_excel.get_result()
|
||||
|
||||
ws = wb["统计"]
|
||||
for idx in range(len(params)):
|
||||
row = idx + 2
|
||||
for col in range(2, 8):
|
||||
ws.cell(row=row, column=col).value = params[idx][col-2]
|
||||
|
||||
if hold:
|
||||
avg = current_avg(hold, rcs, trqh, w2t, insert_logdb)
|
||||
for axis, cur_value in avg.items():
|
||||
@ -144,9 +151,9 @@ def current_cycle(data_files, vel, trq, trqh, rrs, rcs, rpms, w2t, insert_logdb)
|
||||
wb[sht_name]["O4"].value = float(cur_value[0])
|
||||
|
||||
if dur_time == 0:
|
||||
p_single(wb, single, vel, rrs, w2t, insert_logdb)
|
||||
p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb)
|
||||
else:
|
||||
p_scenario(wb, scenario, vel, rrs, dur_time, w2t, insert_logdb)
|
||||
p_scenario(wb, scenario, vel, trq, sensor, rrs, dur_time, w2t)
|
||||
|
||||
clibs.stop = True
|
||||
w2t(f"正在保存文件 {result},需要 10s 左右......\n")
|
||||
@ -227,12 +234,12 @@ def get_row_number(threshold, flag, df, row_s, row_e, axis, insert_logdb):
|
||||
else:
|
||||
count_1 = 0
|
||||
|
||||
places = {"start": "起点", "middle": "中间点", "end": "终点"}
|
||||
places = {"start": "起点", "middle": "中间点", "end": "终点"} # 因为是终点数据,所以可能有异常
|
||||
insert_logdb("WARNING", "current", f"{axis} 轴获取{places[flag]}数据 {row_e} 可能有异常,需关注!")
|
||||
return row_e
|
||||
|
||||
|
||||
def p_single(wb, single, vel, rrs, w2t, insert_logdb):
|
||||
def p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb):
|
||||
# 1. 先找到第一个速度为零的点,数据从后往前找,一开始就是零的情况不予考虑
|
||||
# 2. 记录第一个点的位置,继续向前查找第二个速度为零的点,同理,一开始为零的点不予考虑
|
||||
# 3. 记录第二个点的位置,并将其中的数据拷贝至对应位置
|
||||
@ -313,11 +320,11 @@ def p_single(wb, single, vel, rrs, w2t, insert_logdb):
|
||||
if abs(row_end+row_start-2*row_middle) > 1000:
|
||||
insert_logdb("WARNING", "current", f"{axis} 轴数据占空比异常!")
|
||||
|
||||
data = []
|
||||
data, first_c, second_c, third_c = [], vel-1, trq-1, sensor-1
|
||||
for row in range(row_start, row_end+1):
|
||||
data.append(df_origin.iloc[row, 0])
|
||||
data.append(df_origin.iloc[row, 1])
|
||||
data.append(df_origin.iloc[row, 2])
|
||||
data.append(df_origin.iloc[row, first_c])
|
||||
data.append(df_origin.iloc[row, second_c])
|
||||
data.append(df_origin.iloc[row, third_c])
|
||||
|
||||
i = 0
|
||||
for row in ws.iter_rows(min_row=2, min_col=2, max_row=150000, max_col=4):
|
||||
@ -328,14 +335,14 @@ def p_single(wb, single, vel, rrs, w2t, insert_logdb):
|
||||
_ = f"{data[i]:.2f}"
|
||||
cell.value = float(_)
|
||||
i += 1
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
if i % 3 == 0:
|
||||
ws.cell((i//3)+2, 1).value = None
|
||||
cell.value = None
|
||||
i += 1
|
||||
|
||||
|
||||
def p_scenario(wb, scenario, vel, rrs, dur_time, w2t, insert_logdb):
|
||||
def p_scenario(wb, scenario, vel, trq, sensor, rrs, dur_time, w2t):
|
||||
for data_file in scenario:
|
||||
cycle = 0.001
|
||||
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
||||
@ -354,11 +361,11 @@ def p_scenario(wb, scenario, vel, rrs, dur_time, w2t, insert_logdb):
|
||||
if row_end > df.index[-1]:
|
||||
w2t(f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "red", "DataOverLimit")
|
||||
|
||||
data = []
|
||||
data, first_c, second_c, third_c = [], vel-1, trq-1, sensor-1
|
||||
for row in range(row_start, row_end+1):
|
||||
data.append(df_origin.iloc[row, 0])
|
||||
data.append(df_origin.iloc[row, 1])
|
||||
data.append(df_origin.iloc[row, 2])
|
||||
data.append(df_origin.iloc[row, first_c])
|
||||
data.append(df_origin.iloc[row, second_c])
|
||||
data.append(df_origin.iloc[row, third_c])
|
||||
|
||||
i = 0
|
||||
for row in ws.iter_rows(min_row=2, min_col=2, max_row=250000, max_col=4):
|
||||
@ -369,34 +376,44 @@ def p_scenario(wb, scenario, vel, rrs, dur_time, w2t, insert_logdb):
|
||||
_ = f"{data[i]:.2f}"
|
||||
cell.value = float(_)
|
||||
i += 1
|
||||
except Exception as Err:
|
||||
except Exception:
|
||||
cell.value = None
|
||||
if i % 3 == 0:
|
||||
ws.cell((i//3)+2, 1).value = None
|
||||
i += 1
|
||||
|
||||
|
||||
def get_configs(configfile, w2t, insert_logdb):
|
||||
def get_configs(config_file, w2t, insert_logdb):
|
||||
try:
|
||||
wb = openpyxl.load_workbook(configfile, read_only=True)
|
||||
ws = wb["Target"]
|
||||
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
||||
configs = json.load(f_config)
|
||||
except Exception as Err:
|
||||
insert_logdb("ERROR", "current", f"无法打开 {configfile},获取配置文件参数错误 {Err}")
|
||||
w2t(f"无法打开 {configfile}", color="red", desc="OpenFileError")
|
||||
insert_logdb("ERROR", "current", f"get_config: 无法打开 {config_file},获取配置文件参数错误 {Err}")
|
||||
w2t(f"无法打开 {config_file}", color="red", desc="OpenFileError")
|
||||
|
||||
# 最大角速度,额定电流,减速比,额定转速
|
||||
rrs, avs, rcs, rpms = [], [], [], []
|
||||
for i in range(2, 8):
|
||||
rrs.append(abs(float(ws.cell(row=2, column=i).value)))
|
||||
avs.append(abs(float(ws.cell(row=3, column=i).value)))
|
||||
rpms.append(abs(float(ws.cell(row=4, column=i).value)))
|
||||
rcs.append(abs(float(ws.cell(row=6, column=i).value)))
|
||||
version = configs["VERSION"]
|
||||
rcs = [abs(_) for _ in configs["MOTOR"]["RATED_TORQUE"]] # 电机额定电流,rc for rated current
|
||||
m_max_rcs = [] # 电机最大电流
|
||||
m_hold_rcs = [] # 电机堵转电流
|
||||
m_rts = [] # 电机额定转矩rt for rated torque
|
||||
m_max_rts = [] # 电机峰值转矩
|
||||
m_r_rpms = [] # 电机额定转速
|
||||
m_max_rpms = [] # 电机最大转速
|
||||
m_tcs = [] # 电机转矩常数,tc for torque constant
|
||||
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比,rr for reduction ratio
|
||||
r_max_sst = [] # 减速器最大启停转矩,sst for start and stop torque
|
||||
r_max_t = [] # 减速器瞬时最大转矩
|
||||
sc = [] # 采样周期,sc for sample cycle
|
||||
r_rts = [] # 减速器额定转矩
|
||||
r_r_rpms = [] # 减速器额定转速
|
||||
r_life_cycle = [] # 减速器L10寿命
|
||||
r_avg_t = [] # 减速器平均负载转矩允许最大值
|
||||
|
||||
insert_logdb("INFO", "current", f"current: 获取减速比:{rrs}")
|
||||
insert_logdb("INFO", "current", f"current: 获取角速度:{avs}")
|
||||
insert_logdb("INFO", "current", f"current: 获取额定电流:{rcs}")
|
||||
insert_logdb("INFO", "current", f"current: 获取额定转速:{rpms}")
|
||||
return rrs, avs, rcs, rpms
|
||||
insert_logdb("INFO", "current", f"get_configs: 机型文件版本 {config_file}_{version}")
|
||||
insert_logdb("INFO", "current", f"get_configs: 减速比 {rrs}")
|
||||
insert_logdb("INFO", "current", f"get_configs: 额定电流 {rcs}")
|
||||
return rcs, m_max_rcs, m_hold_rcs, m_rts, m_max_rts, m_r_rpms, m_max_rpms, m_tcs, rrs, r_max_sst, r_max_t, sc, r_rts, r_r_rpms, r_life_cycle, r_avg_t
|
||||
|
||||
|
||||
def main():
|
||||
@ -405,18 +422,20 @@ def main():
|
||||
vel = int(clibs.data_dp["_vel"])
|
||||
trq = int(clibs.data_dp["_trq"])
|
||||
trqh = int(clibs.data_dp["_trqh"])
|
||||
sensor = int(clibs.data_dp["_sensor"])
|
||||
w2t = clibs.w2t
|
||||
insert_logdb = clibs.insert_logdb
|
||||
insert_logdb("INFO", "current", "current: 参数初始化成功")
|
||||
|
||||
data_files = initialization(path, w2t, insert_logdb)
|
||||
rrs, avs, rcs, rpms = get_configs(path + "\\configs.xlsx", w2t, insert_logdb)
|
||||
data_files, config_file = initialization(path, w2t, insert_logdb)
|
||||
params = get_configs(f"{path}/{config_file}", w2t, insert_logdb)
|
||||
rcs, rrs = params[0], params[8]
|
||||
if sub == "max":
|
||||
current_max(data_files, rcs, trq, w2t, insert_logdb)
|
||||
elif sub == "avg":
|
||||
current_avg(data_files, rcs, trq, w2t, insert_logdb)
|
||||
current_avg(data_files, rcs, trqh, w2t, insert_logdb)
|
||||
elif sub == "cycle":
|
||||
current_cycle(data_files, vel, trq, trqh, rrs, rcs, rpms, w2t, insert_logdb)
|
||||
current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, insert_logdb)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,5 +1,183 @@
|
||||
|
||||
import pdfplumber
|
||||
import openpyxl
|
||||
import os
|
||||
from common import clibs
|
||||
def main():
|
||||
print("iso")
|
||||
|
||||
|
||||
def p_iso(file, p_files, ws, tmpfile):
|
||||
p_files.append(file)
|
||||
|
||||
pdf = pdfplumber.open(file)
|
||||
with open(tmpfile, mode="w", encoding="utf-8") as fb:
|
||||
for page in pdf.pages:
|
||||
fb.write(page.extract_text())
|
||||
with open(tmpfile, mode="r", encoding="utf-8") as fb:
|
||||
lines = fb.readlines()
|
||||
lines = [line for line in lines if not line.startswith("Page ")]
|
||||
for line in lines:
|
||||
if line.strip() == "Pose Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=3, column=7).value = float(lines[index+4].split()[1])
|
||||
ws.cell(row=4, column=7).value = float(lines[index+5].split()[1])
|
||||
ws.cell(row=5, column=7).value = float(lines[index+6].split()[1])
|
||||
ws.cell(row=6, column=7).value = float(lines[index+7].split()[1])
|
||||
ws.cell(row=7, column=7).value = float(lines[index+8].split()[1])
|
||||
|
||||
ws.cell(row=8, column=7).value = float(lines[index+4].split()[2])
|
||||
ws.cell(row=9, column=7).value = float(lines[index+5].split()[2])
|
||||
ws.cell(row=10, column=7).value = float(lines[index+6].split()[2])
|
||||
ws.cell(row=11, column=7).value = float(lines[index+7].split()[2])
|
||||
ws.cell(row=12, column=7).value = float(lines[index+8].split()[2])
|
||||
elif line.strip() == "Pose Accuracy Variation":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=13, column=7).value = float(lines[index+4].split()[1])
|
||||
ws.cell(row=14, column=7).value = float(lines[index+5].split()[1])
|
||||
ws.cell(row=15, column=7).value = float(lines[index+6].split()[1])
|
||||
elif line.strip() == "Distance Accuracy":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=16, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=17, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Stabilisation Time and Overshoot":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=18, column=7).value = float(lines[index + 7].split()[3])
|
||||
ws.cell(row=19, column=7).value = float(lines[index + 7].split()[2])
|
||||
elif line.strip() == "Velocity Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=20, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=21, column=7).value = float(lines[index + 4].split()[2])
|
||||
ws.cell(row=22, column=7).value = float(lines[index + 4].split()[3])
|
||||
elif line.strip()[:31] == "Path Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=29, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=30, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Corner Overshoot and Roundoff":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=35, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=36, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Robot Weaving":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=41, column=7).value = float(lines[index + 4].split()[2])
|
||||
ws.cell(row=42, column=7).value = float(lines[index + 4].split()[3])
|
||||
ws.cell(row=43, column=7).value = float(lines[index + 4].split()[4])
|
||||
else:
|
||||
pass
|
||||
pdf.close()
|
||||
|
||||
|
||||
def p_iso_100(file, p_files, ws, tmpfile):
|
||||
p_files.append(file)
|
||||
|
||||
pdf = pdfplumber.open(file)
|
||||
with open(tmpfile, mode="w", encoding="utf-8") as fb:
|
||||
for page in pdf.pages:
|
||||
fb.write(page.extract_text())
|
||||
with open(tmpfile, mode="r", encoding="utf-8") as fb:
|
||||
lines = fb.readlines()
|
||||
lines = [line for line in lines if not line.startswith("Page ")]
|
||||
for line in lines:
|
||||
if line.strip() == "Velocity Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=26, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=27, column=7).value = float(lines[index + 4].split()[2])
|
||||
ws.cell(row=28, column=7).value = float(lines[index + 4].split()[3])
|
||||
elif line.strip()[:31] == "Path Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=33, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=34, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Corner Overshoot and Roundoff":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=39, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=40, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Robot Weaving":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=47, column=7).value = float(lines[index + 4].split()[2])
|
||||
ws.cell(row=48, column=7).value = float(lines[index + 4].split()[3])
|
||||
ws.cell(row=49, column=7).value = float(lines[index + 4].split()[4])
|
||||
else:
|
||||
pass
|
||||
pdf.close()
|
||||
|
||||
|
||||
def p_iso_1000(file, p_files, ws, tmpfile):
|
||||
p_files.append(file)
|
||||
|
||||
pdf = pdfplumber.open(file)
|
||||
with open(tmpfile, mode="w", encoding="utf-8") as fb:
|
||||
for page in pdf.pages:
|
||||
fb.write(page.extract_text())
|
||||
with open(tmpfile, mode="r", encoding="utf-8") as fb:
|
||||
lines = fb.readlines()
|
||||
lines = [line for line in lines if not line.startswith("Page ")]
|
||||
for line in lines:
|
||||
if line.strip() == "Velocity Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=23, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=24, column=7).value = float(lines[index + 4].split()[2])
|
||||
ws.cell(row=25, column=7).value = float(lines[index + 4].split()[3])
|
||||
elif line.strip()[:31] == "Path Accuracy and Repeatability":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=31, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=32, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Corner Overshoot and Roundoff":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=37, column=7).value = float(lines[index + 4].split()[1])
|
||||
ws.cell(row=38, column=7).value = float(lines[index + 4].split()[2])
|
||||
elif line.strip() == "Robot Weaving":
|
||||
index = lines.index(line)
|
||||
ws.cell(row=44, column=7).value = float(lines[index + 4].split()[2])
|
||||
ws.cell(row=45, column=7).value = float(lines[index + 4].split()[3])
|
||||
ws.cell(row=46, column=7).value = float(lines[index + 4].split()[4])
|
||||
else:
|
||||
pass
|
||||
pdf.close()
|
||||
|
||||
|
||||
def main():
|
||||
path = clibs.data_dp["_path"]
|
||||
w2t = clibs.w2t
|
||||
dirs, files = clibs.traversal_files(path, 1)
|
||||
|
||||
filename = f"{path}/iso-results.xlsx"
|
||||
tmpfile = f"{path}/data.txt"
|
||||
wb, ws = None, None
|
||||
try:
|
||||
wb = openpyxl.load_workbook(filename)
|
||||
ws = wb.active
|
||||
for i in range(3, 50):
|
||||
ws.cell(row=i, column=7).value = None
|
||||
except Exception as Err:
|
||||
clibs.insert_logdb("ERROR", "iso", f"main: 无法打开文件 {filename}")
|
||||
w2t(f"发生错误:{Err}", "red", "FileOpenError")
|
||||
|
||||
p_files = []
|
||||
for file in files:
|
||||
if file.endswith(".pdf") and file.split("/")[-1] == "ISO.pdf":
|
||||
w2t(f"正在处理{file}......\n")
|
||||
p_iso(file, p_files, ws, tmpfile)
|
||||
w2t(f"文件{file}已处理完毕。\n")
|
||||
|
||||
elif file.endswith(".pdf") and file.split("/")[-1] == "ISO-V100.pdf":
|
||||
w2t(f"正在处理{file}......\n")
|
||||
p_iso_100(file, p_files, ws, tmpfile)
|
||||
w2t(f"文件{file}已处理完毕。\n")
|
||||
|
||||
elif file.endswith(".pdf") and file.split("/")[-1] == "ISO-V1000.pdf":
|
||||
w2t(f"正在处理{file}......\n")
|
||||
p_iso_1000(file, p_files, ws, tmpfile)
|
||||
w2t(f"文件{file}已处理完毕。\n")
|
||||
|
||||
else:
|
||||
pass
|
||||
wb.save(filename)
|
||||
wb.close()
|
||||
|
||||
if len(p_files) == 0:
|
||||
w2t(f"目录 {path} 下没有需要处理的文件,需要确认......", "red")
|
||||
else:
|
||||
os.remove(tmpfile)
|
||||
w2t("------------------------------------------\n")
|
||||
w2t("所有文件均已处理完毕!\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -1,5 +1,148 @@
|
||||
|
||||
import pandas
|
||||
import csv
|
||||
import openpyxl
|
||||
from common import clibs
|
||||
def main():
|
||||
print("wavelogger")
|
||||
|
||||
|
||||
def find_point(bof, step, margin, threshold, pos, data_file, flag, df, row, w2t):
|
||||
# bof: backward or forward
|
||||
# pos: used for debug
|
||||
# flag: greater than or lower than
|
||||
row_target = None
|
||||
row_origin = df.index[-1] - margin + 1
|
||||
if flag == "gt":
|
||||
while 0 < row < row_origin:
|
||||
value = float(df.iloc[row, 2])
|
||||
if value > threshold:
|
||||
row = row - step if bof == "backward" else row + step
|
||||
continue
|
||||
else:
|
||||
row_target = row - step if bof == "backward" else row + step
|
||||
break
|
||||
else:
|
||||
if bof == "backward":
|
||||
clibs.insert_logdb("ERROR", "wavelogger", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...")
|
||||
w2t(f"[{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
||||
elif bof == "forward":
|
||||
row_target = row + margin # to end while loop in function `single_file_proc`
|
||||
elif flag == "lt":
|
||||
while 0 < row < row_origin:
|
||||
value = float(df.iloc[row, 2])
|
||||
if value < threshold:
|
||||
row = row - step if bof == "backward" else row + step
|
||||
continue
|
||||
else:
|
||||
row_target = row - step if bof == "backward" else row + step
|
||||
break
|
||||
else:
|
||||
if bof == "backward":
|
||||
clibs.insert_logdb("ERROR", "wavelogger", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...")
|
||||
w2t(f"[{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
||||
elif bof == "forward":
|
||||
row_target = row + margin # to end while loop in function `single_file_proc`
|
||||
return row_target
|
||||
|
||||
|
||||
def get_cycle_info(data_file, step, margin, threshold, w2t):
|
||||
# end -> middle: low
|
||||
# middle -> start: high
|
||||
# 1. 从最后读取数据,无论是大于1还是小于1,都舍弃,找到相反的值的起始点
|
||||
# 2. 从起始点,继续往前寻找,找到与之数值相反的中间点
|
||||
# 3. 从中间点,继续往前寻找,找到与之数值相反的结束点,至此,得到了高低数值的时间区间以及一轮的周期时间
|
||||
csv_reader = csv.reader(open(data_file))
|
||||
begin = int(next(csv_reader)[1])
|
||||
df = pandas.read_csv(data_file, sep=",", encoding="gbk", skip_blank_lines=False, header=begin - 1, on_bad_lines="skip")
|
||||
row = df.index[-1] - margin
|
||||
if float(df.iloc[row, 2]) < threshold:
|
||||
row = find_point("backward", step, margin, threshold, "a1", data_file, "lt", df, row, w2t)
|
||||
|
||||
_row = find_point("backward", step, margin, threshold, "a2", data_file, "gt", df, row, w2t)
|
||||
_row = find_point("backward", step, margin, threshold, "a3", data_file, "lt", df, _row, w2t)
|
||||
row_end = find_point("backward", step, margin, threshold, "a4", data_file, "gt", df, _row, w2t)
|
||||
row_middle = find_point("backward", step, margin, threshold, "a5", data_file, "lt", df, row_end, w2t)
|
||||
row_start = find_point("backward", step, margin, threshold, "a6", data_file, "gt", df, row_middle, w2t)
|
||||
# print(f"row_end = {row_end}")
|
||||
# print(f"row_middle = {row_middle}")
|
||||
# print(f"row_start = {row_start}")
|
||||
return row_end-row_middle, row_middle-row_start, row_end-row_start, df
|
||||
|
||||
|
||||
def initialization(path, w2t):
|
||||
_, data_files = clibs.traversal_files(path, w2t)
|
||||
|
||||
for data_file in data_files:
|
||||
if not data_file.lower().endswith(".csv"):
|
||||
clibs.insert_logdb("ERROR", "wavelogger", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!")
|
||||
w2t(f"{data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red", "FileTypeError")
|
||||
|
||||
return data_files
|
||||
|
||||
|
||||
def preparation(data_file, step, margin, threshold, wb, w2t):
|
||||
shtname = data_file.split("/")[-1].split(".")[0]
|
||||
ws = wb.create_sheet(shtname)
|
||||
low, high, cycle, df = get_cycle_info(data_file, step, margin, threshold, w2t)
|
||||
|
||||
return ws, df, low, high, cycle
|
||||
|
||||
|
||||
def single_file_proc(ws, data_file, step, threshold, margin, data_length, df, cycle, w2t):
|
||||
row, row_lt, row_gt, count, count_i, data = 1, 1, 1, 1, 1, {}
|
||||
row_max = df.index[-1] - margin
|
||||
while row < row_max:
|
||||
if count not in data.keys():
|
||||
data[count] = []
|
||||
|
||||
value = float(df.iloc[row, 2])
|
||||
if value < threshold:
|
||||
row_lt = find_point("forward", step, margin, threshold, "c"+str(row), data_file, "lt", df, row, w2t)
|
||||
start = int(row_gt + (row_lt - row_gt - data_length) / 2)
|
||||
end = start + data_length
|
||||
value = df.iloc[start:end, 2].mean() + 3 * df.iloc[start:end, 2].std()
|
||||
if value > 1:
|
||||
msg = f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留"
|
||||
clibs.insert_logdb("WARNING", "wavelogger", msg)
|
||||
w2t(msg, "orange")
|
||||
data[count].append(value)
|
||||
count_i += 1
|
||||
else:
|
||||
row_gt = find_point("forward", step, margin, threshold, "c"+str(row), data_file, "gt", df, row, w2t)
|
||||
if row_gt - row_lt > cycle * 2:
|
||||
count += 1
|
||||
count_i = 1
|
||||
row = max(row_gt, row_lt)
|
||||
for i in range(2, 10):
|
||||
ws.cell(row=1, column=i).value = f"第{i-1}次测试"
|
||||
ws.cell(row=i, column=1).value = f"第{i-1}次精度变化"
|
||||
|
||||
for i in sorted(data.keys()):
|
||||
row, column = 2, i + 1
|
||||
for value in data[i]:
|
||||
ws.cell(row=row, column=column).value = float(value)
|
||||
row += 1
|
||||
|
||||
|
||||
def execution(data_files, w2t):
|
||||
wb = openpyxl.Workbook()
|
||||
step, margin, data_length, threshold = 5, 50, 50, 5
|
||||
for data_file in data_files:
|
||||
ws, df, low, high, cycle = preparation(data_file, step, margin, threshold, wb, w2t)
|
||||
single_file_proc(ws, data_file, step, threshold, margin, data_length, df, cycle, w2t)
|
||||
|
||||
wd = "/".join(data_files[0].split("/")[:-1])
|
||||
filename = wd + "/result.xlsx"
|
||||
wb.save(filename)
|
||||
wb.close()
|
||||
w2t("----------------------------------------\n")
|
||||
w2t("所有文件均已处理完毕\n")
|
||||
|
||||
|
||||
def main():
|
||||
path = clibs.data_dp["_path"]
|
||||
w2t = clibs.w2t
|
||||
data_files = initialization(path, w2t)
|
||||
execution(data_files, w2t)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Reference in New Issue
Block a user