界面优化,监控逻辑优化

This commit is contained in:
gitea 2025-03-30 12:27:57 +08:00
parent c325875dbb
commit a9a6db23fd
20 changed files with 574 additions and 594 deletions

244
aio.py
View File

@ -4,6 +4,7 @@ import os
import re
import sqlite3
import sys
import threading
import time
from urllib import request
import os.path
@ -92,46 +93,43 @@ class MainWindow(main_window.Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.close_on_net_error = None
self.is_searching = False
self.setupUi(self)
self.predoes()
self.pre_does()
def predoes(self):
def pre_does(self):
# ========================= treeview init =========================
self.cb_data_current.setDisabled(True)
self.setup_statusbar()
self.setWindowIcon(QIcon(f"{clibs.PREFIX}/media/icon.ico"))
self.treew_log.header().setFont(QFont("Arial", 12, QFont.Weight.Bold))
header = self.treew_log.header()
for i in range(self.treew_log.columnCount()):
header.setSectionResizeMode(i, QHeaderView.ResizeMode.ResizeToContents)
self.md_btn.setStyleSheet("background-color: DarkGrey; color: white;")
self.ec_btn.setStyleSheet("background-color: DarkGrey; color: white;")
# ========================= stylesheet =========================
with open(f"{clibs.PREFIX}/qss/style.qss", mode="r", encoding="utf-8") as f_qss:
style_sheet = f_qss.read()
self.setStyleSheet(style_sheet)
# ========================= clibs =========================
self.setup_statusbar()
self.setWindowIcon(QIcon(f"{clibs.PREFIX}/media/icon.ico"))
# ========================= styleSheet =========================
tws = [self.tw_funcs, self.tw_docs]
for tw in tws:
tw.setStyleSheet("""
QTabBar::tab:selected {
background: #0078D4;
color: white;
border-radius: 4px;
}
QTabBar::tab:!selected {
background: #F0F0F0;
color: #333;
}
QTabWidget::pane {
border: 1px solid #CCCCCC;
}
""")
# ============================↓↓↓debug↓↓↓============================
# print(f"self.cb_data_func.currentIndex() = {self.cb_data_func.currentIndex()}")
logger_handler = clibs.LoggerHandler()
logger_handler.signal.connect(self.w2t)
clibs.logger = logger_handler.logger
# ========================= detection =========================
self.detection_thread = StateDetection()
self.detection_thread.finished.connect(self.prog_done_detection)
self.detection_thread.start()
# ========================= debug =========================
# for i in range(105):
# clibs.logger("DEBUG", "aio", "debug testing log for aio", color="gray")
# clibs.logger("INFO", "clibs", "info testing log for clibs", color="green")
# clibs.logger("WARNING", "iso", "warning testing log for aio", color="yellow")
# # clibs.logger("ERROR", "openapi", "error testing log for aio", color="red")
def run_program_thread(self, prog, idx, prog_done, reserved):
if idx != -98 and idx != -97:
self.tw_docs.setCurrentIndex(0)
if idx != -99 and idx != -98:
prog.output.connect(self.w2t)
self.t = QThread(self)
self.run = RunProg()
@ -191,7 +189,13 @@ class MainWindow(main_window.Ui_MainWindow):
self.run_program_thread(factory_test.DoFactoryTest(self.le_durable_path.text(), self.le_durable_interval.text(), self.get_checkbox_states()), 6, prog_done, None)
def prog_stop(self):
QMessageBox.warning(self, "停止运行", "运行过程中不建议停止运行,可能会损坏文件,如果确实需要停止运行,可以直接关闭窗口!")
if sum(clibs.running) == 0:
return
idx = clibs.running.index(1)
clibs.running[idx] = 0
clibs.logger("INFO", "aio", f"{clibs.functions[idx]}程序已经停止涉及Excel文件读写时可能会损坏该文件", "red")
# QMessageBox.warning(self, "停止运行", "运行过程中不建议停止运行,可能会损坏文件,如果确实需要停止运行,可以直接关闭窗口!")
def prog_reset(self):
self.tw_docs.setCurrentIndex(0)
@ -205,7 +209,6 @@ class MainWindow(main_window.Ui_MainWindow):
idx_dict[tab_index].setText(dir_path)
def curve_draw(self):
output = Signal(str, str)
procs = self.get_checkbox_states()
dir_path = self.le_durable_path.text()
curve_map = {
@ -230,7 +233,7 @@ class MainWindow(main_window.Ui_MainWindow):
self.w2t(f"需要选择至少一个功能,才能继续绘图......", "red")
return
_, files = clibs.traversal_files(dir_path, output)
_, files = clibs.traversal_files(dir_path)
csv_files = []
for file in files:
if file.endswith(".csv"):
@ -320,7 +323,7 @@ class MainWindow(main_window.Ui_MainWindow):
end = first_id-1 if first_id-1 > 0 else None
if end is None:
return
start = end-100 if end-100 > 0 else 1
start = end-100+1 if end-100+1 > 0 else 1
clibs.cursor.execute(f"SELECT * FROM logs WHERE id BETWEEN {start} AND {end}")
records = clibs.cursor.fetchall()
@ -397,12 +400,12 @@ class MainWindow(main_window.Ui_MainWindow):
line_number = self.treew_log.topLevelItemCount()
last_id = int(self.treew_log.topLevelItem(line_number-1).text(0))
start = last_id + 1 if last_id % 100 == 0 else last_id - last_id % 100 + 1
end = int(start) + 100
if int(start) <= len_records:
end = int(start) + 100 - 1
if start <= len_records:
clibs.cursor.execute(f"select * from logs where id between {start} and {end}")
records = clibs.cursor.fetchall()
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
current_page = start // 100 if start % 100 == 0 else start // 100 + 1
return pages_all, current_page, records
elif self.is_searching is True:
@ -688,25 +691,26 @@ class MainWindow(main_window.Ui_MainWindow):
flag, result, ret, error, idx, network = results
if flag is False:
...
# self.w2t(f"{network.upper()}连接失败", "red")
self.w2t(f"{network.upper()}连接失败", "red")
elif flag is True:
clibs.status[network] = 1
if network == "hmi":
self.btn_hmi_conn.setText("断开")
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>HR&nbsp;&nbsp;</b></font>')
clibs.c_hr = result
elif network == "md":
self.btn_md_conn.setText("断开")
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>MD&nbsp;&nbsp;</b></font>')
clibs.c_md = result
elif network == "ec":
self.btn_ec_conn.setText("断开")
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>EC&nbsp;&nbsp;</b></font>')
clibs.c_ec = result
def prog_done_disconn(self, results):
self.btn_hmi_conn.setDisabled(False)
self.btn_md_conn.setDisabled(False)
self.btn_ec_conn.setDisabled(False)
flag, result, ret, error, idx, network = results
if flag is False:
self.w2t(f"{network.upper()}断开连接失败", "red")
@ -714,13 +718,16 @@ class MainWindow(main_window.Ui_MainWindow):
clibs.status[network] = 0
if network == "hmi":
self.btn_hmi_conn.setText("连接")
clibs.c_hr = result
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>HR&nbsp;&nbsp;</b></font>')
clibs.c_hr = None
elif network == "md":
self.btn_md_conn.setText("连接")
clibs.c_md = result
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>MD&nbsp;&nbsp;</b></font>')
clibs.c_md = None
elif network == "ec":
self.btn_ec_conn.setText("连接")
clibs.c_ec = result
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>EC&nbsp;&nbsp;</b></font>')
clibs.c_ec = None
def hmi_conn(self):
self.btn_hmi_conn.setDisabled(True)
@ -759,22 +766,51 @@ class MainWindow(main_window.Ui_MainWindow):
self.run_program_thread(clibs.c_ec.close, -99, self.prog_done_disconn, "ec")
def hmi_page(self):
self.pte_md_send.clear()
self.pte_md_recv.clear()
self.pte_ec_send.clear()
self.pte_ec_recv.clear()
self.tw_funcs.setCurrentIndex(3)
self.sw_network.setCurrentIndex(0)
self.hmi_btn.setStyleSheet("background-color: DarkCyan; color: white;")
self.md_btn.setStyleSheet("background-color: DarkGrey; color: white;")
self.ec_btn.setStyleSheet("background-color: DarkGrey; color: white;")
def md_page(self):
self.pte_hmi_send.clear()
self.pte_hmi_recv.clear()
self.pte_ec_send.clear()
self.pte_ec_recv.clear()
self.tw_funcs.setCurrentIndex(3)
self.sw_network.setCurrentIndex(1)
self.hmi_btn.setStyleSheet("background-color: DarkGrey; color: white;")
self.md_btn.setStyleSheet("background-color: DarkCyan; color: white;")
self.ec_btn.setStyleSheet("background-color: DarkGrey; color: white;")
def ec_page(self):
self.pte_md_send.clear()
self.pte_md_recv.clear()
self.pte_hmi_send.clear()
self.pte_hmi_recv.clear()
self.tw_funcs.setCurrentIndex(3)
self.sw_network.setCurrentIndex(2)
self.hmi_btn.setStyleSheet("background-color: DarkGrey; color: white;")
self.md_btn.setStyleSheet("background-color: DarkGrey; color: white;")
self.ec_btn.setStyleSheet("background-color: DarkCyan; color: white;")
def prog_done_hmi_send(self, results):
_, result, ret, error, idx, (msg_id, flag) = results
if _ is False:
self.btn_hmi_send.setDisabled(False)
clibs.logger("INFO", "aio", f"hmi: [send] 请求发送失败 {msg_id}", "red")
return
records = clibs.c_hr.get_from_id(msg_id)
for record in records:
if "请求发送成功" not in record[0]:
self.pte_him_recv.clear()
self.pte_hmi_recv.clear()
response = eval(record[0]) if flag == 0 else json.loads(record[0])
self.pte_him_recv.appendPlainText(json.dumps(response, indent=4, separators=(",", ":")))
self.pte_hmi_recv.appendPlainText(json.dumps(response, indent=4, separators=(",", ":")))
else:
self.btn_hmi_send.setDisabled(False)
@ -852,9 +888,7 @@ class MainWindow(main_window.Ui_MainWindow):
self.pte_ec_recv.clear()
cmd = self.pte_ec_send.toPlainText().strip()
try:
clibs.c_ec.s_string(cmd)
time.sleep(clibs.INTERVAL/2)
result = clibs.c_ec.r_string(cmd)
result = clibs.c_ec.sr_string(cmd)
self.pte_ec_recv.appendPlainText(str(result))
except Exception as err:
self.pte_ec_recv.appendPlainText(f"操作失败:{err}")
@ -862,7 +896,7 @@ class MainWindow(main_window.Ui_MainWindow):
def hmi_cb_change(self):
cmd = self.cb_hmi_cmd.currentText()
self.pte_hmi_send.clear()
self.pte_him_recv.clear()
self.pte_hmi_recv.clear()
with open(f"{clibs.PREFIX}/files/protocols/hmi/{cmd}.json", mode="r", encoding="utf-8") as f_hmi:
hmi_dict = json.load(f_hmi)
t = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
@ -886,6 +920,13 @@ class MainWindow(main_window.Ui_MainWindow):
c_send = f_md.read()
self.pte_ec_send.appendPlainText(c_send)
def data_cb_change(self):
proc = self.cb_data_func.currentText()
if proc != "转矩":
self.cb_data_current.setDisabled(True)
else:
self.cb_data_current.setDisabled(False)
def check_interval(self):
try:
interval = float(self.le_durable_interval.text())
@ -894,13 +935,21 @@ class MainWindow(main_window.Ui_MainWindow):
interval = clibs.CYCLE
self.le_durable_interval.setText(str(interval))
def state_detection(self):
while True:
time.sleep(clibs.INTERVAL)
if clibs.status["hmi"] == 0 and self.btn_hmi_conn.text() == "断开":
self.btn_hmi_conn.setText("连接")
elif clibs.status["hmi"] == 1 and self.btn_hmi_conn.text() == "连接":
self.btn_hmi_conn.setText("断开")
def prog_done_detection(self, finished):
if clibs.status["hmi"] == 0:
self.btn_hmi_conn.setText("连接")
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>HR&nbsp;&nbsp;</b></font>')
if clibs.status["md"] == 0:
self.btn_md_conn.setText("连接")
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>MD&nbsp;&nbsp;</b></font>')
if clibs.status["ec"] == 0:
self.btn_ec_conn.setText("连接")
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>EC&nbsp;&nbsp;</b></font>')
# ============= Program running status =============
if sum(clibs.running) == 1:
self.run_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>BUSY</b></font>')
else:
self.run_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>IDLE</b></font>')
def closeEvent(self, event):
idx = -1 if clibs.running.count(1) == 0 else clibs.running.index(1)
@ -913,7 +962,7 @@ class MainWindow(main_window.Ui_MainWindow):
clibs.conn.backup(target=disk_conn, pages=1, progress=None)
_, logs = clibs.traversal_files(".", None)
_, logs = clibs.traversal_files(".")
logs.sort()
while len(logs) > 10:
_ = logs.pop(0)
@ -938,24 +987,68 @@ class MainWindow(main_window.Ui_MainWindow):
with open(f"{clibs.PREFIX}/files/version/server_vers", mode="r", encoding="utf-8") as f_server:
server_vers = f_server.read().strip()
update_label = QLabel()
version_label = QLabel()
self.statusbar.addWidget(version_label, 0)
self.statusbar.addPermanentWidget(update_label, 0) # 添加到右侧
self.update_label, self.hmi_state, self.md_state, self.ec_state, self.run_state, self.version_label = QLabel(), ClickableLabel(), ClickableLabel(), ClickableLabel(), QLabel(), QLabel()
self.statusbar.addWidget(self.version_label, 0)
self.statusbar.addWidget(self.hmi_state, 0)
self.statusbar.addWidget(self.md_state, 0)
self.statusbar.addWidget(self.ec_state, 0)
self.statusbar.addWidget(self.run_state, 0)
self.statusbar.addPermanentWidget(self.update_label, 0) # 添加到右侧
self.hmi_state.clicked.connect(self.hmi_page)
self.md_state.clicked.connect(self.md_page)
self.ec_state.clicked.connect(self.ec_page)
if local_vers == server_vers:
update_label.setText(f'<img src="{clibs.PREFIX}/media/updated.png" width="12" height="12" /><font color="#0D8A3D" face="consolas" size="4"><b>&nbsp;当前是最新版本,继续保持!&nbsp;</b></font>')
self.update_label.setText(f'<img src="{clibs.PREFIX}/media/updated.png" width="14" height="14" style="vertical-align: middle;" /><span style="vertical-align: middle; font-size: 14px; font-weight: bold; color: #0D8A3D;"> Current is the latest version</span>')
elif local_vers > server_vers:
pass
elif local_vers < server_vers:
update_label.setText(f'''<a href="https://www.rustle.cc/aio.zip" style="text-decoration: none;"><img src="{clibs.PREFIX}/media/upgrade.png" width="12" height="12" /><font color="#D81E06" face="consolas" size="4"><b>&nbsp;v{server_vers.split('@')[0]}已经发布,尽快更新至最新版本!&nbsp;</b></font></a>''')
self.update_label.setText(f'''<a href="https://www.rustle.cc/aio.zip" style="text-decoration: none;"><img src="{clibs.PREFIX}/media/upgrade.png" width="14" height="14" style="vertical-align: middle;" /><span style="vertical-align: middle; font-size: 14px; font-weight: bold; color: #D81E06;"> v{server_vers.split('@')[0]} has been released, update ASAP!</span></a>''')
version_label.setText(f'<font color="black" face="consolas" size="4"><b>&nbsp;{vers_info}</b></font>')
update_label.setOpenExternalLinks(True) # 允许超链接在浏览器中打开
# update_label.setAlignment(Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignRight)
update_label.setStyleSheet("border: none;")
update_label.setFrameShape(QFrame.Shape.NoFrame)
update_label.setFrameShadow(QFrame.Shadow.Plain)
self.close_on_net_error = False
self.version_label.setText(f'<font color="black" face="consolas" size="4"><b>{vers_info}&nbsp;&nbsp;</b></font>')
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>HR&nbsp;&nbsp;</b></font>')
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>MD&nbsp;&nbsp;</b></font>')
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>EC&nbsp;&nbsp;</b></font>')
self.run_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>IDLE</b></font>')
self.update_label.setOpenExternalLinks(True) # 允许超链接在浏览器中打开
class StateDetection(QThread):
finished = Signal(bool)
def __init__(self, /):
super().__init__()
def run(self):
while True:
time.sleep(clibs.INTERVAL*2)
# ============= HMI connection status =============
try:
clibs.c_hr.execution("controller.heart")
except:
clibs.status["hmi"] = 0
# ============= MD connection status =============
try:
clibs.c_md.c.read_holding_registers(40503, count=1).registers[0]
except:
clibs.status["md"] = 0
# ============= EC connection status =============
try:
clibs.c_ec.sr_string("controller_is_running")
except:
clibs.status["ec"] = 0
self.finished.emit(True)
class ClickableLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
def mousePressEvent(self, event):
self.clicked.emit()
clicked = Signal()
class InitWork(QThread):
@ -994,13 +1087,16 @@ class SplashScreen(QApplication):
self.splash.show()
self.splash.showMessage("正在加载资源.....", Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignHCenter, Qt.GlobalColor.white)
self.t = QThread(self)
self.run = InitWork()
self.run.moveToThread(self.t)
self.run.completed.connect(self.prog_done)
self.action.connect(self.run.program)
self.t.start()
self.action.emit(1)
# self.t = QThread(self)
# self.run = InitWork()
# self.run.moveToThread(self.t)
# self.run.completed.connect(self.prog_done)
# self.action.connect(self.run.program)
# self.t.start()
# self.action.emit(1)
# without validation of server version
self.prog_done("true")
def prog_done(self, result):
if result == "false" or result == "":

View File

@ -0,0 +1 @@
close_reduced_mode

View File

@ -0,0 +1 @@
open_reduced_mode

View File

@ -0,0 +1 @@
soft_estop_state

View File

@ -1 +0,0 @@
tcp_pos

View File

@ -0,0 +1 @@
tcp_pose

BIN
assets/media/green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
assets/media/red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

50
assets/qss/style.qss Normal file
View File

@ -0,0 +1,50 @@
/* ------------------------------------------- QTabBar -------------------------------------------*/
QTabBar::tab:selected {
padding: 6px;
background: #909090;
color: white;
border-radius: 0px;
}
QTabBar::tab:!selected {
padding: 4px;
background: #b0b0b0;
color: white;
}
QTabWidget::pane {
border: 4px solid #CCCCCC;
padding: 1px;
}
/* ------------------------------------------- QPushButton -------------------------------------------*/
QPushButton[objectName$="_btn"] {
background-color: DarkCyan; /* 按钮背景颜色 */
color: white; /* 按钮文本颜色 */
border: 1px solid DarkGray; /* 按钮边框 */
border-radius: 4px; /* 按钮圆角 */
padding: 2px 4px; /* 按钮内边距 */
}
QPushButton[objectName$="_btn"]:hover {
background-color: #000000;
}
QPushButton[objectName^="btn"] {
background-color: #666666; /* 按钮背景颜色 */
color: white; /* 按钮文本颜色 */
border: 1px solid #555555; /* 按钮边框 */
border-radius: 4px; /* 按钮圆角 */
padding: 4px 8px; /* 按钮内边距 */
}
QPushButton[objectName^="btn"]:hover {
background-color: #888888; /* 鼠标悬停时的背景颜色 */
}
QPushButton[objectName^="btn"]:pressed {
background-color: #8FBC8F; /* 按钮按下时的背景颜色 */
}
/* ------------------------------------------- QStatusBar -------------------------------------------*/
QStatusBar::item { border: 0px; }

View File

@ -9,27 +9,19 @@ from codes.common import clibs
class BrakeDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, /):
super().__init__()
self.dir_path = dir_path
self.idx = 0
self.logger = clibs.logger
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
@clibs.handle_exception
def check_files(self, rawdata_dirs, result_files):
msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:<br>"
msg_wrong += "- reach33/66/100_XXXXXXX.xlsx<br>- *.cfg<br>"
msg_wrong += "- reach33_load33_speed33<br>- reach33_load33_speed66<br>...<br>- reach100_load100_speed66<br>- reach100_load100_speed100<br>"
if len(result_files) != 4 or len(rawdata_dirs) == 0:
self.logger("ERROR", "brake", msg_wrong, "red", "InitFileError")
self.logger("ERROR", "brake", msg_wrong, "red")
config_file, reach33_file, reach66_file, reach100_file = None, None, None, None
for result_file in result_files:
@ -44,7 +36,7 @@ class BrakeDataProcess(QThread):
reach100_file = result_file
else:
if not (config_file and reach33_file and reach66_file and reach100_file):
self.logger("ERROR", "brake", msg_wrong, "red", "InitFileError")
self.logger("ERROR", "brake", msg_wrong, "red")
reach_s = ['reach33', 'reach66', 'reach100']
load_s = ['load33', 'load66', 'load100']
@ -57,17 +49,17 @@ class BrakeDataProcess(QThread):
msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式<br>"
msg += "命名规则reachAA_loadBB_speedCCAA/BB/CC 指的是臂展/负载/速度的比例<br>"
msg += "规则解释reach66_load100_speed33表示 66% 臂展100% 负载以及 33% 速度情况下的测试结果文件夹<br>"
self.logger("ERROR", "brake", msg, "red", "WrongDataFolder")
self.logger("ERROR", "brake", msg, "red")
_, rawdata_files = clibs.traversal_files(rawdata_dir, self.output)
_, rawdata_files = clibs.traversal_files(rawdata_dir)
if len(rawdata_files) != 3:
msg = f"数据目录 {rawdata_dir} 下数据文件个数错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
self.logger("ERROR", "brake", msg, "red", "WrongDataFile")
self.logger("ERROR", "brake", msg, "red")
for rawdata_file in rawdata_files:
if not rawdata_file.endswith(".data"):
msg = f"数据文件 {rawdata_file} 后缀错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
self.logger("ERROR", "brake", msg, "red", "WrongDataFile")
self.logger("ERROR", "brake", msg, "red")
result_files = []
for _ in [reach33_file, reach66_file, reach100_file]:
@ -77,7 +69,6 @@ class BrakeDataProcess(QThread):
self.logger("INFO", "brake", "数据目录合规性检查结束,未发现问题......", "green")
return config_file, result_files
@clibs.handle_exception
def get_configs(self, config_file):
try:
with open(config_file, mode="r", encoding="utf-8") as f_config:
@ -85,7 +76,7 @@ class BrakeDataProcess(QThread):
p_dir = config_file.split('/')[-2]
if not re.match("^[jJ][123]$", p_dir):
self.logger("ERROR", "brake", "被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
self.logger("ERROR", "brake", "被处理的根文件夹命名必须是 [Jj][123] 的格式", "red")
axis = int(p_dir[-1]) # 要处理的轴
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比rr for reduction ratio
@ -94,7 +85,7 @@ class BrakeDataProcess(QThread):
av = avs[axis-1]
return av, rr
except Exception as Err:
self.logger("ERROR", "brake", f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查<br>{Err}", "red", "OpenFileError")
self.logger("ERROR", "brake", f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查<br>{Err}", "red")
def now_doing_msg(self, docs, flag):
now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
@ -109,7 +100,6 @@ class BrakeDataProcess(QThread):
self.logger("INFO", "brake", f"[{now}] 文件 {docs} 数据已处理完毕")
@staticmethod
@clibs.handle_exception
def data2result(df, ws_result, row_start, row_end):
data = []
for row in range(row_start, row_end):
@ -130,7 +120,6 @@ class BrakeDataProcess(QThread):
ws_result.cell(row=row, column=2).value = None
ws_result.cell(row=row, column=3).value = None
@clibs.handle_exception
def get_row_range(self, data_file, df, conditions, av, rr):
row_start, row_end = 0, 0
ratio = float(conditions[2].removeprefix('speed')) / 100
@ -142,7 +131,7 @@ class BrakeDataProcess(QThread):
row_start = row - 20 if row - 20 > 0 else 0 # 急停前找 20 个点
break
else:
self.logger("ERROR", "brake", f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", "red", "StartNotFoundError")
self.logger("ERROR", "brake", f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", "red")
for row in range(row_start, df.index[-1] - 1, 10):
speed_row = df.iloc[row, 0] * clibs.RADIAN * rr * 60 / 360
@ -150,7 +139,7 @@ class BrakeDataProcess(QThread):
row_end = row + 100 if row + 100 <= df.index[-1] - 1 else df.index[-1] - 1
break
else:
self.logger("ERROR", "brake", f"数据文件 {data_file} 最后的速度未降为零", "red", "SpeedNotZeroError")
self.logger("ERROR", "brake", f"数据文件 {data_file} 最后的速度未降为零", "red")
av_estop = abs(df.iloc[row_start - 20:row_start, 0].abs().mean() * clibs.RADIAN)
if abs(av_estop / av_max) < threshold:
@ -161,7 +150,6 @@ class BrakeDataProcess(QThread):
return row_start, row_end
@staticmethod
@clibs.handle_exception
def get_shtname(conditions, count):
# 33%负载_33%速度_1 - reach/load/speed
load = conditions[1].removeprefix('load')
@ -170,7 +158,6 @@ class BrakeDataProcess(QThread):
return result_sheet_name
@clibs.handle_exception
def single_file_process(self, data_file, wb, count, av, rr):
df = pandas.read_csv(data_file, sep='\t')
conditions = data_file.split("/")[-2].split("_") # reach/load/speed
@ -180,20 +167,19 @@ class BrakeDataProcess(QThread):
row_start, row_end = self.get_row_range(data_file, df, conditions, av, rr)
self.data2result(df, ws, row_start, row_end)
@clibs.handle_exception
def data_process(self, result_file, rawdata_dirs, av, rr):
filename = result_file.split("/")[-1]
self.logger("INFO", "brake", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
try:
wb = openpyxl.load_workbook(result_file)
except Exception as Err:
self.logger("ERROR", "brake", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
self.logger("ERROR", "brake", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red")
prefix = filename.split('_')[0]
for rawdata_dir in rawdata_dirs:
if rawdata_dir.split("/")[-1].split('_')[0] == prefix:
self.now_doing_msg(rawdata_dir, 'start')
_, data_files = clibs.traversal_files(rawdata_dir, self.output)
_, data_files = clibs.traversal_files(rawdata_dir)
for idx in range(3):
self.single_file_process(data_files[idx], wb, idx+1, av, rr)
# threads = [
@ -209,12 +195,11 @@ class BrakeDataProcess(QThread):
wb.save(result_file)
wb.close()
@clibs.handle_exception
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
rawdata_dirs, result_files = clibs.traversal_files(self.dir_path, self.output)
rawdata_dirs, result_files = clibs.traversal_files(self.dir_path)
config_file, result_files = self.check_files(rawdata_dirs, result_files)
av, rr = self.get_configs(config_file)

View File

@ -9,23 +9,15 @@ from codes.common import clibs
class CurrentDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, proc, /):
super().__init__()
self.dir_path = dir_path
self.proc = proc
self.idx = 1
self.logger = clibs.logger
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
@clibs.handle_exception
def initialization(self):
_, data_files = clibs.traversal_files(self.dir_path, self.output)
_, data_files = clibs.traversal_files(self.dir_path)
count, config_file = 0, None
for data_file in data_files:
filename = data_file.split("/")[-1]
@ -38,15 +30,14 @@ class CurrentDataProcess(QThread):
if not re.match("^j[1-7].*\\.data$", filename):
msg = f"不合规 {data_file}<br>"
msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾比如j1_abcdef.data请检查整改后重新运行"
self.logger("ERROR", "current", msg, "red", "FilenameIllegal")
self.logger("ERROR", "current", msg, "red")
if count != 2:
msg = "需要有一个机型配置文件\"*.cfg\",以及一个数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行"
self.logger("ERROR", "current", msg, "red", "FilenameIllegal")
self.logger("ERROR", "current", msg, "red")
return data_files, config_file
@clibs.handle_exception
def current_max(self, data_files, rts):
self.logger("INFO", "current", f"正在处理最大转矩值逻辑......")
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
@ -88,7 +79,6 @@ class CurrentDataProcess(QThread):
self.logger("INFO", "current", f"最大转矩数据处理完毕......")
return current
@clibs.handle_exception
def current_avg(self, data_files, rts):
self.logger("INFO", "current", f"正在处理平均转矩值逻辑......")
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
@ -131,7 +121,6 @@ class CurrentDataProcess(QThread):
self.logger("INFO", "current", f"平均转矩数据处理完毕......")
return current
@clibs.handle_exception
def current_cycle(self, data_files, rrs, rts, params):
result, hold, single, scenario, dur_time = None, [], [], [], 0
for data_file in data_files:
@ -150,8 +139,8 @@ class CurrentDataProcess(QThread):
self.logger("INFO", "current", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
try:
wb = openpyxl.load_workbook(result)
except Exception as Err:
self.logger("ERROR", "current", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
except Exception as err:
self.logger("ERROR", "current", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{err}", "red")
ws = wb["统计"]
for idx in range(len(params)-1):
@ -175,7 +164,6 @@ class CurrentDataProcess(QThread):
wb.save(result)
wb.close()
@clibs.handle_exception
def find_point(self, data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq):
if flag == "lt":
while row_e > end_point:
@ -192,7 +180,7 @@ class CurrentDataProcess(QThread):
self.logger("WARNING", "current", f"【lt】{axis} 轴第 {seq} 次查找数据可能有异常row_s = {row_s}, row_e = {row_e}", "purple")
return row_s, row_e
else:
self.logger("ERROR", "current", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
self.logger("ERROR", "current", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red")
elif flag == "gt":
while row_e > end_point:
speed_avg = df.iloc[row_s:row_e].abs().mean()
@ -208,9 +196,8 @@ class CurrentDataProcess(QThread):
self.logger("WARNING", "current", f"【gt】{axis} 轴第 {seq} 次查找数据可能有异常row_s = {row_s}, row_e = {row_e}", "purple")
return row_s, row_e
else:
self.logger("ERROR", "current", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
self.logger("ERROR", "current", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red")
@clibs.handle_exception
def get_row_number(self, threshold, flag, df, row_s, row_e, axis):
count_1, count_2 = 0, 0
if flag == "start" or flag == "end":
@ -236,7 +223,6 @@ class CurrentDataProcess(QThread):
self.logger("DEBUG", "current", f"{axis} 轴获取{places[flag]}数据 {row_e} 可能有异常,需关注!", "purple")
return row_e
@clibs.handle_exception
def p_single(self, wb, single, rrs):
# 1. 先找到第一个速度为零的点,数据从后往前找,一开始就是零的情况不予考虑
# 2. 记录第一个点的位置,继续向前查找第二个速度为零的点,同理,一开始为零的点不予考虑
@ -316,7 +302,7 @@ class CurrentDataProcess(QThread):
self.logger("DEBUG", "current", f"{axis} 轴数据非零段点数:{row_middle-row_start+1}")
self.logger("DEBUG", "current", f"{axis} 轴数据为零段点数:{row_end-row_middle+1}")
if abs(row_end+row_start-2*row_middle) > 1000:
self.logger("DEBUG", "current", f"{axis} 轴数据占空比异常", "purple")
self.logger("WARNING", "current", f"{axis} 轴数据占空比异常,处理数据可能有误,需检查", "purple")
data, first_c, second_c, third_c, fourth_c = [], clibs.c_joint_vel-1, clibs.c_servo_trq-1, clibs.c_sensor_trq-1, clibs.c_estimate_trans_trq-1
for row in range(row_start, row_end+1):
@ -340,7 +326,6 @@ class CurrentDataProcess(QThread):
cell.value = None
i += 1
@clibs.handle_exception
def p_scenario(self, wb, scenario, rrs, dur_time):
self.logger("INFO", "current", f"本次处理的是电机电流场景数据,场景运动周期为 {dur_time}s", "blue")
for data_file in scenario:
@ -359,7 +344,7 @@ class CurrentDataProcess(QThread):
row_start = 3000
row_end = row_start + int(dur_time/cycle)
if row_end > df.index[-1]:
self.logger("ERROR", "current", f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "blue", "DataOverLimit")
self.logger("ERROR", "current", f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "red")
data, first_c, second_c, third_c, fourth_c = [], clibs.c_joint_vel-1, clibs.c_servo_trq-1, clibs.c_sensor_trq-1, clibs.c_estimate_trans_trq-1
for row in range(row_start, row_end+1):
@ -383,7 +368,6 @@ class CurrentDataProcess(QThread):
ws.cell((i//4)+2, 1).value = None
i += 1
@clibs.handle_exception
def get_configs(self, config_file):
try:
if re.match("^[NXEC]B.*", config_file.split("/")[-1]):
@ -412,10 +396,9 @@ class CurrentDataProcess(QThread):
self.logger("INFO", "current", f"get_configs: 额定转矩 {m_rts}")
self.logger("INFO", "current", f"get_configs: 最大角速度 {m_avs}")
return sc, r_rrs, m_avs, m_stall_ts, m_rts, m_max_ts, m_r_rpms, m_max_rpms, r_max_sst, r_max_t, r_avg_t, robot_type
except Exception as Err:
self.logger("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {Err}", "red", "OpenFileError")
except Exception as err:
self.logger("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {err}", "red")
@clibs.handle_exception
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
@ -432,5 +415,5 @@ class CurrentDataProcess(QThread):
self.logger("INFO", "current", "-"*60 + "<br>全部处理完毕<br>", "purple")
time_total = time.time() - time_start
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n"
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
self.logger("INFO", "current", msg)

View File

@ -7,20 +7,14 @@ from codes.common import clibs
class IsoDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, /):
super().__init__()
self.dir_path = dir_path
self.idx = 2
self.logger = clibs.logger
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
def p_iso(self, file, p_files, ws, tmpfile):
@staticmethod
def p_iso(file, p_files, ws, tmpfile):
p_files.append(file)
pdf = pdfplumber.open(file)
@ -79,7 +73,8 @@ class IsoDataProcess(QThread):
pass
pdf.close()
def p_iso_100(self, file, p_files, ws, tmpfile):
@staticmethod
def p_iso_100(file, p_files, ws, tmpfile):
p_files.append(file)
pdf = pdfplumber.open(file)
@ -112,7 +107,8 @@ class IsoDataProcess(QThread):
pass
pdf.close()
def p_iso_1000(self, file, p_files, ws, tmpfile):
@staticmethod
def p_iso_1000(file, p_files, ws, tmpfile):
p_files.append(file)
pdf = pdfplumber.open(file)
@ -146,9 +142,9 @@ class IsoDataProcess(QThread):
pdf.close()
def initialization(self):
dirs, files = clibs.traversal_files(self.dir_path, self.output)
dirs, files = clibs.traversal_files(self.dir_path)
if len(dirs) != 0:
self.logger("ERROR", "iso", f"init: 工作目录下不可以有文件夹!", "red", "InitFileError")
self.logger("ERROR", "iso", f"init: 工作目录下不可以有文件夹!", "red")
for file in files:
file = file.lower()
@ -161,7 +157,7 @@ class IsoDataProcess(QThread):
elif file.endswith("iso.pdf"):
pass
else:
self.logger("ERROR", "iso", f"init: 工作目录下只允许有如下四个文件不区分大小写pdf文件最少有一个<br>1. iso-results.xlsx<br>2. ISO.pdf<br>3. ISO-V100.pdf<br>4. ISO-V1000.pdf", "red", "InitFileError")
self.logger("ERROR", "iso", f"init: 工作目录下只允许有如下四个文件不区分大小写pdf文件最少有一个<br>1. iso-results.xlsx<br>2. ISO.pdf<br>3. ISO-V100.pdf<br>4. ISO-V1000.pdf", "red")
return files
@ -178,8 +174,8 @@ class IsoDataProcess(QThread):
ws = wb.active
for i in range(3, 50):
ws.cell(row=i, column=7).value = None
except Exception as Err:
self.logger("ERROR", "iso", f"main: 无法打开文件 {filename}<br>{Err}", "red", "FileOpenError")
except Exception as err:
self.logger("ERROR", "iso", f"main: 无法打开文件 {filename}<br>{err}", "red")
p_files = []
for file in files:
@ -204,11 +200,11 @@ class IsoDataProcess(QThread):
wb.close()
if len(p_files) == 0:
self.logger("ERROR", "iso", f"目录 {self.dir_path} 下没有需要处理的文件,需要确认......", "red", "FileNotFound")
self.logger("ERROR", "iso", f"目录 {self.dir_path} 下没有需要处理的文件,需要确认......", "red")
else:
os.remove(tmpfile)
self.logger("INFO", "current-processing", "-" * 60 + "<br>全部处理完毕<br>", "purple")
time_total = time.time() - time_start
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n"
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
self.logger("INFO", "current-processing", msg)

View File

@ -8,18 +8,11 @@ from codes.common import clibs
class WaveloggerDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, /):
super().__init__()
self.dir_path = dir_path
self.idx = 3
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
self.logger = clibs.logger
def find_point(self, bof, step, margin, threshold, pos, data_file, flag, df, row):
# bof: backward or forward
@ -38,7 +31,7 @@ class WaveloggerDataProcess(QThread):
break
else:
if bof == "backward":
self.logger("ERROR", "wavelogger", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
self.logger("ERROR", "wavelogger", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red")
elif bof == "forward":
row_target = row + margin # to end while loop in function `single_file_proc`
elif flag == "lt":
@ -52,7 +45,7 @@ class WaveloggerDataProcess(QThread):
break
else:
if bof == "backward":
self.logger("ERROR", "wavelogger", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
self.logger("ERROR", "wavelogger", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red")
elif bof == "forward":
row_target = row + margin # to end while loop in function `single_file_proc`
return row_target
@ -85,11 +78,11 @@ class WaveloggerDataProcess(QThread):
return row_end-row_middle, row_middle-row_start, row_end-row_start, df
def initialization(self):
_, data_files = clibs.traversal_files(self.dir_path, self.output)
_, data_files = clibs.traversal_files(self.dir_path)
for data_file in data_files:
if not data_file.lower().endswith(".csv"):
self.logger("ERROR", "wavelogger", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red", "FileTypeError")
self.logger("ERROR", "wavelogger", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red")
return data_files
@ -115,7 +108,7 @@ class WaveloggerDataProcess(QThread):
value = df.iloc[start:end, 2].astype(float).mean() + 3 * df.iloc[start:end, 2].astype(float).std()
if value > 1:
msg = f"\n"
self.logger("WARNING", "wavelogger", f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留", "purple")
self.logger("WARNING", "wavelogger", f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留")
data[count].append(value)
count_i += 1
@ -157,5 +150,5 @@ class WaveloggerDataProcess(QThread):
self.logger("INFO", "wavelogger", "-" * 60 + "<br>全部处理完毕<br>", "purple")
time_total = time.time() - time_start
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n"
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
self.logger("INFO", "wavelogger", msg)

View File

@ -1,3 +1,4 @@
import threading
import time
import os
import paramiko
@ -9,27 +10,19 @@ from codes.common import clibs
class DoBrakeTest(QThread):
output = Signal(str, str)
def __init__(self, dir_path, tool, /):
super().__init__()
self.dir_path = dir_path
self.tool = tool
self.idx = 4
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
self.logger = clibs.logger
def initialization(self, data_dirs, data_files):
@clibs.handle_exception
def check_files():
msg = "初始路径下不允许有文件夹,只能存在如下五个文件,且文件为关闭状态,确认后重新运行!<br>"
msg += "1. configs.xlsx<br>2. reach33/reach66/reach100_xxxx.xlsx<br>3. xxxx.zip"
if len(data_dirs) != 0 or len(data_files) != 5:
self.logger("ERROR", "do_brake", msg, "red", "InitFileError")
self.logger("ERROR", "do_brake", msg, "red")
config_file, reach33_file, reach66_file, reach100_file, prj_file, result_dirs = None, None, None, None, None, []
for data_file in data_files:
@ -45,7 +38,7 @@ class DoBrakeTest(QThread):
elif filename.endswith(".zip"):
prj_file = data_file
else:
self.logger("ERROR", "do_brake", msg, "red", "InitFileError")
self.logger("ERROR", "do_brake", msg, "red")
if config_file and reach33_file and reach66_file and reach100_file and prj_file:
os.mkdir(f"{self.dir_path}/j1")
@ -64,9 +57,8 @@ class DoBrakeTest(QThread):
return config_file, prj_file, result_dirs
else:
self.logger("ERROR", "do_brake", msg, "red", "InitFileError")
self.logger("ERROR", "do_brake", msg, "red")
@clibs.handle_exception
def get_configs():
robot_type = None
msg_id = clibs.c_hr.execution("controller.get_params")
@ -82,7 +74,7 @@ class DoBrakeTest(QThread):
with open(local_file, mode="r", encoding="utf-8") as f_config:
configs = json.load(f_config)
except Exception as Err:
self.logger("ERROR", "do_brake", f"无法打开 {local_file}<br>{Err}", "red", "OpenFileError")
self.logger("ERROR", "do_brake", f"无法打开 {local_file}<br>{Err}", "red")
# 最大角速度,额定电流,减速比,额定转速
version = configs["VERSION"]
@ -97,7 +89,6 @@ class DoBrakeTest(QThread):
self.logger("INFO", "do_brake", "数据目录合规性检查结束,未发现问题......", "green")
return _config_file, _prj_file, _result_dirs, _avs
@clibs.handle_exception
def gen_result_file(self, axis, end_time, reach, load, speed, speed_max, rounds):
d_vel, d_trq, d_stop, threshold = [], [], [], 0.95
s_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time-clibs.INTERVAL*12))
@ -133,7 +124,7 @@ class DoBrakeTest(QThread):
return "retry"
else:
clibs.count = 0
self.logger("WARNING", "do_brake",f"尝试三次后仍无法获取正确数据,本次数据无效,继续执行...", "red")
self.logger("WARNING", "do_brake", f"尝试三次后仍无法获取正确数据,本次数据无效,继续执行...", "red")
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
@ -143,7 +134,6 @@ class DoBrakeTest(QThread):
df.to_csv(filename, sep="\t", index=False)
@staticmethod
@clibs.handle_exception
def change_curve_state(stat):
if not stat:
display_pdo_params = []
@ -153,7 +143,6 @@ class DoBrakeTest(QThread):
clibs.c_hr.execution("diagnosis.open", open=stat, display_open=stat)
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params)
@clibs.handle_exception
def run_rl(self, config_file, prj_file, result_dirs, avs):
count, total, speed_target = 0, 63, 0
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
@ -172,7 +161,7 @@ class DoBrakeTest(QThread):
elif pon == "negative":
clibs.c_md.write_pon(0)
else:
self.logger("ERROR", "do_brake", "configs.xlsx 中 Target 页面 B5 单元格填写不正确,检查后重新运行...", "red", "DirectionError")
self.logger("ERROR", "do_brake", "configs.xlsx 中 Target 页面 B5 单元格填写不正确,检查后重新运行...", "red")
self.change_curve_state(True)
for condition in result_dirs:
@ -194,7 +183,7 @@ class DoBrakeTest(QThread):
continue
clibs.c_md.write_axis(axis)
self.logger("INFO", "brake", "-" * 90, "purple", flag="signal")
self.logger("INFO", "brake", "-" * 90, "purple")
speed_max = 0
for rounds in range(1, 4):
count += 1
@ -207,7 +196,7 @@ class DoBrakeTest(QThread):
# 1. 触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
clibs.c_md.r_soft_estop(0)
clibs.c_md.r_soft_estop(1)
clibs.c_ec.setdo_value(io_name, "true")
clibs.c_ec.sr_string(f"setdo:{io_name},true")
clibs.c_md.r_reset_estop()
clibs.c_md.r_clear_alarm()
clibs.c_md.write_act(0)
@ -251,7 +240,7 @@ class DoBrakeTest(QThread):
else:
time.sleep(1)
if (time.time() - t_start) > 15:
self.logger("ERROR", "do_brake", "15s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
self.logger("ERROR", "do_brake", "15s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red")
# 4. 找出最大速度传递给RL程序最后清除相关记录
time.sleep(5) # 消除前 5s 的不稳定数据
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
@ -261,7 +250,6 @@ class DoBrakeTest(QThread):
# 找出最大速度
@clibs.db_lock
@clibs.handle_exception
def get_speed_max():
_speed_max = 0
clibs.cursor.execute(f"SELECT content FROM logs WHERE timestamp BETWEEN '{start_time}' AND '{end_time}' AND content LIKE '%diagnosis.result%' ORDER BY id ASC")
@ -292,7 +280,7 @@ class DoBrakeTest(QThread):
break
while 1:
clibs.c_ec.setdo_value(io_name, "true")
clibs.c_ec.sr_string(f"setdo:{io_name},true")
clibs.c_md.r_reset_estop()
clibs.c_md.r_clear_alarm()
clibs.c_md.write_act(0)
@ -310,7 +298,7 @@ class DoBrakeTest(QThread):
else:
time.sleep(2)
if time.time() - t_start > 60:
self.logger("ERROR", "do_brake", "60s 内程序未能正常执行,需检查...", "red", "RlProgramStartTimeout")
self.logger("ERROR", "do_brake", "60s 内程序未能正常执行,需检查...", "red")
for i in range(16):
if clibs.c_md.read_ready_to_go() == 1:
@ -319,15 +307,14 @@ class DoBrakeTest(QThread):
else:
time.sleep(1)
else:
self.logger("ERROR", "do_brake", "16s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
self.logger("ERROR", "do_brake", "16s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red")
@clibs.handle_exception
def exec_brake():
flag, start, data, record = True, time.time(), None, None
while flag:
time.sleep(0.05)
if time.time() - start > 20:
self.logger("ERROR", "do_brake", "20s 内未触发急停,需排查......", "red", "BrakeTimeoutError")
self.logger("ERROR", "do_brake", "20s 内未触发急停,需排查......", "red")
try:
clibs.lock.acquire(True)
@ -344,7 +331,7 @@ class DoBrakeTest(QThread):
speed_moment = clibs.RADIAN * sum(item["value"]) / len(item["value"])
if abs(speed_moment) > speed_max - 2:
if (pon == "positive" and speed_moment > 0) or (pon == "negative" and speed_moment < 0):
clibs.c_ec.setdo_value(io_name, "false")
clibs.c_ec.sr_string(f"setdo:{io_name},false")
time.sleep(clibs.INTERVAL*2) # wait speed goes down to 0
flag = False
break
@ -364,14 +351,16 @@ class DoBrakeTest(QThread):
msg = f"<br>{self.tool.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行"
self.logger("INFO", "do_brake", msg, "green")
@clibs.handle_exception
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
if clibs.status["hmi"] != 1 or clibs.status["md"] != 1 or clibs.status["ec"] != 1:
self.logger("ERROR", "do_brake", "processing: 需要在网络设置中连接HMIModbus通信以及外部通信", "red", "NetworkError")
self.logger("ERROR", "do_brake", "processing: 需要在网络设置中连接HMIModbus通信以及外部通信", "red")
t = threading.Thread(target=clibs.running_detection, args=(self.idx, ))
t.daemon = True
t.start()
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
data_dirs, data_files = clibs.traversal_files(self.dir_path)
config_file, prj_file, result_dirs, avs = self.initialization(data_dirs, data_files)
clibs.c_pd.push_prj_to_server(prj_file)
self.run_rl(config_file, prj_file, result_dirs, avs)

View File

@ -8,27 +8,19 @@ from codes.common import clibs
class DoCurrentTest(QThread):
output = Signal(str, str)
def __init__(self, dir_path, tool, /):
super().__init__()
self.dir_path = dir_path
self.tool = tool
self.idx = 5
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
self.logger = clibs.logger
def initialization(self, data_dirs, data_files):
@clibs.handle_exception
def check_files():
msg = "初始路径下不允许有文件夹,初始路径下只能存在如下两个文件,且文件为关闭状态,确认后重新运行!<br>"
msg += "1. T_电机电流.xlsx<br>2. xxxx.zip"
if len(data_dirs) != 0 or len(data_files) != 2:
self.logger("ERROR", "do_current", msg, "red", "InitFileError")
self.logger("ERROR", "do_current", msg, "red")
prj_file, count = None, 0
for data_file in data_files:
@ -39,10 +31,10 @@ class DoCurrentTest(QThread):
count += 1
prj_file = data_file
else:
self.logger("ERROR", "do_current", msg, "red", "InitFileError")
self.logger("ERROR", "do_current", msg, "red")
if count != 2:
self.logger("ERROR", "do_current", msg, "red", "InitFileError")
self.logger("ERROR", "do_current", msg, "red")
if self.tool == "tool100":
os.mkdir(f"{self.dir_path}/single")
@ -52,11 +44,10 @@ class DoCurrentTest(QThread):
elif self.tool == "inertia":
os.mkdir(f"{self.dir_path}/inertia")
else:
self.logger("ERROR", "do_current", "负载选择错误,电机电流测试只能选择 tool100/inertia 规格!", "red", "LoadSelectError")
self.logger("ERROR", "do_current", "负载选择错误,电机电流测试只能选择 tool100/inertia 规格!", "red")
return prj_file
@clibs.handle_exception
def get_configs():
robot_type = None
msg_id = clibs.c_hr.execution("controller.get_params")
@ -74,7 +65,6 @@ class DoCurrentTest(QThread):
self.logger("INFO", "do_current", "数据目录合规性检查结束,未发现问题......", "green")
return _prj_file
@clibs.handle_exception
def single_axis_proc(self, records, number):
text = "single" if number < 6 else "hold"
number = number if number < 6 else number - 6
@ -100,7 +90,6 @@ class DoCurrentTest(QThread):
filename = f"{self.dir_path}/single/j{number + 1}_{text}_{time.time()}.data"
df.to_csv(filename, sep="\t", index=False)
@clibs.handle_exception
def scenario_proc(self, records, number, scenario_time):
d_vel, d_trq, d_sensor, d_trans = [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []]
for record in records:
@ -126,9 +115,7 @@ class DoCurrentTest(QThread):
filename = f"{self.dir_path}/s_{number-11}/j{axis+1}_s_{number-11}_{scenario_time}_{time.time()}.data"
df.to_csv(filename, sep="\t", index=False)
@clibs.handle_exception
def gen_result_file(self, number, start_time, end_time, scenario_time):
@clibs.handle_exception
def get_records():
s_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start_time))
e_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time+clibs.INTERVAL))
@ -152,14 +139,12 @@ class DoCurrentTest(QThread):
t.start()
@staticmethod
@clibs.handle_exception
def change_curve_state(stat):
curves = ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback", "hw_estimate_trans_trq_res"]
display_pdo_params = [] if not stat else [{"name": curve, "channel": chl} for curve in curves for chl in range(6)]
clibs.c_hr.execution("diagnosis.open", open=stat, display_open=stat)
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params)
@clibs.handle_exception
def run_rl(self, prj_file):
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
c_regular = [
@ -235,7 +220,7 @@ class DoCurrentTest(QThread):
else:
time.sleep(1)
if (time.time() - t_start) > 15:
self.logger("ERROR", "do_current", "15s 内未收到机器人的运行信号需要确认RL程序和工具通信是否正常执行...", "red", "ReadySignalTimeoutError")
self.logger("ERROR", "do_current", "15s 内未收到机器人的运行信号需要确认RL程序和工具通信是否正常执行...", "red")
# 4. 执行采集
time.sleep(10) # 消除前 10s 的不稳定数据
@ -256,7 +241,7 @@ class DoCurrentTest(QThread):
else:
time.sleep(1)
if (time.time()-t_start) > 180:
self.logger("ERROR", "do_current", f"180s 内未收到场景{number - 11}的周期时间需要确认RL程序和工具通信交互是否正常执行...", "red", "GetScenarioTimeError")
self.logger("ERROR", "do_current", f"180s 内未收到场景{number - 11}的周期时间需要确认RL程序和工具通信交互是否正常执行...", "red")
time.sleep(20)
# 5.停止程序运行,保留数据并处理输出
@ -271,14 +256,13 @@ class DoCurrentTest(QThread):
elif self.tool == "inertia":
self.logger("INFO", "do_current", "惯量负载电机电流采集完毕,如需采集单轴/场景/保持电机电流,须切换负载类型,并更换偏置负载,重新执行", "green")
@clibs.handle_exception
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
if clibs.status["hmi"] != 1 or clibs.status["md"] != 1:
self.logger("ERROR", "do_current", "processing: 需要在网络设置中连接HMI以及Modbus通信", "red", "NetworkError")
self.logger("ERROR", "do_current", "processing: 需要在网络设置中连接HMI以及Modbus通信", "red")
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
data_dirs, data_files = clibs.traversal_files(self.dir_path)
prj_file = self.initialization(data_dirs, data_files)
clibs.c_pd.push_prj_to_server(prj_file)
self.run_rl(prj_file)

View File

@ -2,14 +2,14 @@ import os
import os.path
import threading
import sqlite3
import time
from PySide6.QtCore import Signal, QThread
def traversal_files(dir_path, signal):
# 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录
# 参数:路径/信号/游标/功能编号
# 返回值:路径下的文件夹列表 路径下的文件列表
def traversal_files(dir_path):
if not os.path.exists(dir_path):
logger("ERROR", "clibs", f"数据文件夹{dir_path}不存在,请确认后重试......", "red", signal=signal)
logger("ERROR", "clibs", f"数据文件夹{dir_path}不存在,请确认后重试......", color="red")
else:
dirs, files = [], []
for item in os.scandir(dir_path):
@ -56,33 +56,42 @@ def db_lock(func):
return wrapper
@db_lock
def logger(level, module, content, color="black", flag="both", signal=""):
global cursor
if "move.monitor" in content:
return
class LoggerHandler(QThread):
signal = Signal(str, str)
if flag == "signal":
signal.emit(content, color)
elif flag == "cursor":
cursor.execute(f"INSERT INTO logs (level, module, content) VALUES (?, ?, ?)", (level, module, content))
elif flag == "both":
signal.emit(content, color)
cursor.execute(f"INSERT INTO logs (level, module, content) VALUES (?, ?, ?)", (level, module, content))
def __init__(self, /):
super().__init__()
@db_lock
def logger(self, level, module, content, color="black", flag="both"):
global cursor
if "move.monitor" in content:
return
if level.upper() == "DEBUG":
flag = "cursor"
if flag == "signal":
self.signal.emit(content, color)
elif flag == "cursor":
cursor.execute(f"INSERT INTO logs (level, module, content) VALUES (?, ?, ?)", (level, module, content))
elif flag == "both":
self.signal.emit(content, color)
cursor.execute(f"INSERT INTO logs (level, module, content) VALUES (?, ?, ?)", (level, module, content))
if level.upper() == "ERROR":
raise Exception()
def handle_exception(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as err:
print(f"{func.__name__} err = {err}")
logger("DEBUG", "clibs", f"{func.__name__} err = {err}", flag="cursor")
return wrapper
def running_detection(idx):
while True:
time.sleep(INTERVAL*2)
if not running[idx]:
raise Exception("")
PREFIX = "resources/assets" # for pyinstaller
# PREFIX = "assets" # for local testing
# PREFIX = "resources/assets" # for pyinstaller
PREFIX = "assets" # for local testing
log_path = f"{PREFIX}/logs"
lock = threading.Lock()
running = [0, 0, 0, 0, 0, 0, 0] # 制动数据/转矩数据/激光数据/精度数据/制动自动化/转矩自动化/耐久数据采集
@ -91,7 +100,7 @@ levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
ip_addr, ssh_port, socket_port, xService_port, external_port, modbus_port, upgrade_port = "", 22, 5050, 6666, 8080, 502, 4567
username, password = "luoshi", "luoshi2019"
INTERVAL, RADIAN, MAX_FRAME_SIZE, MAX_LOG_NUMBER, CYCLE = 1, 57.3, 1024, 10, 300
c_md, c_hr, c_ec, c_pd, conn, cursor, search_records = None, None, None, None, None, None, None
c_md, c_hr, c_ec, c_pd, conn, cursor, search_records, logger, count = None, None, None, None, None, None, None, None, 0
status = {"mysql": 0, "hmi": 0, "md": 0, "ec": 0}
c_joint_vel, c_servo_trq, c_sensor_trq, c_estimate_trans_trq, c_safety_estop = 1, 2, 3, 4, 3 # 各个指标所在列

View File

@ -16,12 +16,12 @@ from codes.common import clibs
class ModbusRequest(QThread):
output = Signal(str, str)
def __init__(self, ip, port, /):
super().__init__()
self.ip = ip
self.port = port
self.c = None
self.logger = clibs.logger
def net_conn(self):
self.logger("INFO", "openapi", f"Modbus 正在连接中,需要配置设备,这可能需要一点时间......", "blue")
@ -30,21 +30,11 @@ class ModbusRequest(QThread):
if self.c.connect():
self.logger("INFO", "openapi", f"Modbus connection({clibs.ip_addr}:{clibs.modbus_port}) success!", "green")
else:
self.logger("ERROR", "openapi", f"Modbus connection({clibs.ip_addr}:{clibs.modbus_port}) failed!", "red", "MdConnFailed")
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
self.logger("ERROR", "openapi", f"Modbus connection({clibs.ip_addr}:{clibs.modbus_port}) failed!", "red")
def close(self):
if self.c.connect():
try:
self.c.close()
self.logger("INFO", "openapi", f"modbus: 关闭 Modbus 连接成功", "green")
except Exception as err:
self.logger("ERROR", "openapi", f"modbus: 关闭 Modbus 连接失败:{err}", "red", "MdCloseFailed")
self.c.close()
self.logger("INFO", "openapi", f"modbus: 关闭 Modbus 连接成功", "green")
def __reg_high_pulse(self, addr: int) -> None:
self.c.write_register(addr, 0)
@ -344,7 +334,6 @@ class HmiRequest(QThread):
self.__port = port
self.__port_xs = port_xs
self.__close_hmi = False
self.__is_connected = False
self.__index = 0
self.__previous_data = b""
self.__valid_data_length = 0
@ -357,12 +346,10 @@ class HmiRequest(QThread):
self.__half_pkg_flag = False
self.__is_first_frame = True
self.__is_debug = True
self.logger = clibs.logger
def net_conn(self):
self.__socket_conn()
self.__t_heartbeat = threading.Thread(target=self.__heartbeat)
self.__t_heartbeat.daemon = True
self.__t_heartbeat.start()
self.__t_unpackage = threading.Thread(target=self.__unpackage, args=(self.c,))
self.__t_unpackage.daemon = True
self.__t_unpackage.start()
@ -370,30 +357,13 @@ class HmiRequest(QThread):
self.__t_unpackage_xs.daemon = True
self.__t_unpackage_xs.start()
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
@property
def status(self):
return self.__is_connected
def close(self):
if self.__is_connected:
try:
self.__is_connected = False
time.sleep(clibs.INTERVAL/2)
self.c.close()
self.c_xs.close()
clibs.status["hmi"] = 0
self.logger("INFO", "openapi", f"hmi: 关闭 Socket 连接成功", "green")
except Exception as err:
self.logger("ERROR", "openapi", f"hmi: 关闭 Socket 连接失败 {err}", "red", "HmiCloseFailed")
self.c.close()
self.c_xs.close()
self.logger("INFO", "openapi", f"hmi: 关闭 Socket 连接成功", "green")
def __socket_conn(self):
self.close()
# self.close()
try:
self.c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.c.settimeout(clibs.INTERVAL*5)
@ -405,16 +375,11 @@ class HmiRequest(QThread):
state = None
for i in range(3):
_ = self.execution("controller.heart")
time.sleep(clibs.INTERVAL/2)
self.__is_connected = True
time.sleep(clibs.INTERVAL/4)
clibs.status["hmi"] = 1
self.logger("INFO", "openapi", "hmi: HMI connection success...", "green")
except Exception as err:
self.logger("ERROR", "openapi", f"hmi: HMI connection timeout...", "red", "HmiConnTimeout")
def __heartbeat(self):
while self.__is_connected:
self.execution("controller.heart")
time.sleep(clibs.INTERVAL*2)
except Exception:
self.logger("ERROR", "openapi", f"hmi: HMI connection failed...", "red")
@staticmethod
def package(cmd):
@ -439,13 +404,13 @@ class HmiRequest(QThread):
try:
sel = selectors.DefaultSelector()
sel.register(sock, selectors.EVENT_READ, to_read)
while self.__is_connected:
while clibs.status["hmi"]:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
except Exception as Err:
self.logger("DEBUG", "openapi", f"hmi: 老协议解包报错 {Err}", "red", "UnpackageFailed")
except Exception as err:
self.logger("DEBUG", "openapi", f"hmi: 老协议解包报错 err = {err}")
def __get_headers(self, index, data):
if index + 8 < len(data):
@ -458,7 +423,7 @@ class HmiRequest(QThread):
else:
# print("hr-get_headers: 解包数据有误,需要确认!")
# print(data)
self.logger("ERROR", "openapi", f"hmi: 解包数据有误,需要确认,最后一个数据包如下 {data}")
self.logger("ERROR", "openapi", f"hmi: 解包数据有误,需要确认,最后一个数据包如下 {data}", "red")
else:
self.__half_pkg = data[index:]
self.__half_pkg_flag = True
@ -681,7 +646,7 @@ class HmiRequest(QThread):
# if self.__valid_data_length < 0 or self.__leftovers > 1024:
# print(f"data = {data}")
# raise Exception("DataError")
self.logger("ERROR", "openapi", "hmi: Will never be here", "red", "WillNeverBeHere")
self.logger("ERROR", "openapi", "hmi: will never be here", "red")
@staticmethod
def package_xs(cmd):
@ -701,13 +666,13 @@ class HmiRequest(QThread):
sel = selectors.DefaultSelector()
sel.register(sock, selectors.EVENT_READ, to_read)
while self.__is_connected:
while clibs.status["hmi"]:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
except Exception as err:
self.logger("DEBUG", "openapi", f"hmi: xService解包报错 {err}", "red", "XsUnpackageFailed")
self.logger("DEBUG", "openapi", f"hmi: xService解包报错 err = {err}")
def get_response_xs(self, data):
char, response = "", self.__response_xs
@ -721,7 +686,6 @@ class HmiRequest(QThread):
else:
self.__response_xs = response
@clibs.handle_exception
def get_from_id(self, msg_id):
f_text, flag, records, time_delay, ts = f"%{msg_id}%", False, "Null", clibs.INTERVAL*10, msg_id.split("@")[-1]
t = ts.replace("T", " ")
@ -740,7 +704,7 @@ class HmiRequest(QThread):
if flag is True:
return records
else:
self.logger("ERROR", "openapi", f"hmi: {time_delay}s内无法找到请求 {msg_id} 的响应!", "red", "ResponseNotFound")
self.logger("ERROR", "openapi", f"hmi: {time_delay}s内无法找到请求 {msg_id} 的响应!", "red")
def execution(self, command, **kwargs):
req = None
@ -752,7 +716,7 @@ class HmiRequest(QThread):
flag = req["p_type"]
del req["p_type"]
except Exception as err:
self.logger("ERROR", "openapi", f"hmi: 暂不支持 {command} 功能,或确认该功能存在... {err}", "red", "CommandNotSupport")
self.logger("ERROR", "openapi", f"hmi: 暂不支持 {command} 功能,或确认该功能存在...<br>err = {err}", "red")
match command:
case "state.set_tp_mode" | "overview.set_autoload" | "overview.reload" | "rl_task.pp_to_main" | "rl_task.run" | "rl_task.stop" | "rl_task.set_run_params" | "diagnosis.set_params" | "diagnosis.open" | "drag.set_params" | "controller.set_params" | "collision.set_state" | "collision.set_params" | "move.set_quickstop_distance" | "move.set_params" | "move.set_monitor_cfg" | "modbus.get_values" | "modbus.set_params" | "system_io.update_configuration" | "diagnosis.get_params" | "jog.set_params" | "jog.start" | "move.stop" | "move.quick_turn" | "move.set_quickturn_pos" | "soft_limit.set_params" | "fieldbus_device.set_params" | "socket.set_params" | "diagnosis.save" | "register.set_value":
@ -768,17 +732,19 @@ class HmiRequest(QThread):
cmd = json.dumps(req, separators=(",", ":"))
try:
self.c.send(self.package(cmd))
time.sleep(clibs.INTERVAL/4)
time.sleep(clibs.INTERVAL/4) # 这里一定是要等几百毫秒的避免多指令同一时间发送导致xCore不响应
self.logger("DEBUG", "openapi", f"hmi: 老协议请求发送成功 {cmd}")
except Exception as err:
self.logger("ERROR", "openapi", f"hmi: 老协议请求发送失败 {cmd},报错信息 {err}", "red", "CommandSendFailed")
if "controller.heart" in cmd:
raise Exception()
self.logger("ERROR", "openapi", f"hmi: 老协议请求发送失败 {cmd},报错信息 {err}", "red")
elif flag == 1:
try:
self.c_xs.send(self.package_xs(req))
time.sleep(clibs.INTERVAL/4)
self.logger("DEBUG", "openapi", f"hmi: xService请求发送成功 {req}")
except Exception as Err:
self.logger("ERROR", "openapi", f"hr: xService请求发送失败 {req} 报错信息 {Err}", "red", "CommandSendFailed")
except Exception as err:
self.logger("ERROR", "openapi", f"hr: xService请求发送失败 {req} 报错信息 {err}", "red")
return req["id"]
@ -796,7 +762,7 @@ class HmiRequest(QThread):
case "off":
self.execution("state.switch_motor_off")
case _:
self.logger("ERROR", "openapi", f"hmi: switch_motor_state 参数错误 {state} 非法参数,只接受 on/off", "red", "ArgumentError")
self.logger("ERROR", "openapi", f"hmi: switch_motor_state 参数错误 {state} 非法参数,只接受 on/off", "red")
def switch_operation_mode(self, mode: str): # OK
"""
@ -810,7 +776,7 @@ class HmiRequest(QThread):
case "manual":
self.execution("state.switch_manual")
case _:
self.logger("ERROR", "openapi", f"hmi: switch_operation_mode 参数错误 {mode},非法参数,只接受 auto/manual", "red", "ArgumentError")
self.logger("ERROR", "openapi", f"hmi: switch_operation_mode 参数错误 {mode},非法参数,只接受 auto/manual", "red")
def reload_project(self, prj_name: str, tasks: list): # OK
"""
@ -887,7 +853,7 @@ class HmiRequest(QThread):
self.__sth_wrong("3min 内未能完成重新连接,需要查看后台控制器是否正常启动,或者 ip/port 是否正确")
break
for _ in range(3):
if not self.__is_connected:
if not clibs.status["hmi"]:
break
time.sleep(2)
else:
@ -1517,7 +1483,7 @@ class HmiRequest(QThread):
case "without":
self.execution("state.set_tp_mode", tp_mode="without")
case _:
self.logger("ERROR", "openapi", f"hmi: switch_tp_mode 参数错误{mode} 非法参数,只接受 with/without", "red", "ArgumentError")
self.logger("ERROR", "openapi", f"hmi: switch_tp_mode 参数错误{mode} 非法参数,只接受 with/without", "red")
@property
def get_tp_mode(self): # OK
@ -1772,8 +1738,6 @@ class HmiRequest(QThread):
class ExternalCommunication(QThread):
output = Signal(str, str)
def __init__(self, ip, port, /):
super().__init__()
self.c = None
@ -1781,34 +1745,32 @@ class ExternalCommunication(QThread):
self.port = int(port)
self.suffix = "\r"
self.exec_desc = " :--: 返回 true 表示执行成功false 失败"
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
self.logger = clibs.logger
def net_conn(self):
# clibs.c_hr.execution("socket.set_params", enable=False, ip="0.0.0.0", port=str(self.port), suffix="\r", type=1)
# time.sleep(clibs.INTERVAL)
clibs.c_hr.execution("socket.set_params", enable=False, ip="0.0.0.0", port=str(self.port), suffix="\r", type=1)
time.sleep(clibs.INTERVAL)
clibs.c_hr.execution("socket.set_params", enable=True, ip="0.0.0.0", port=str(self.port), suffix="\r", type=1)
time.sleep(clibs.INTERVAL*2)
# time.sleep(clibs.INTERVAL*2)
self.c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.c.settimeout(clibs.INTERVAL*5)
try:
self.c.connect((self.ip, self.port))
self.logger("INFO", "openapi", f"ec: 外部通信连接成功...", "green")
return self.c
# return self.c
except Exception as err:
self.logger("ERROR", "openapi", f"ec: 外部通信连接失败... {err}", "red", "EcConnFailed")
self.logger("ERROR", "openapi", f"ec: 外部通信连接失败... {err}", "red")
def close(self):
if clibs.status["ec"]:
try:
self.c.close()
self.logger("INFO", "openapi", f"ec: 关闭外部通信连接成功", "green")
except Exception as err:
self.logger("ERROR", "openapi", f"ec: 关闭外部通信连接失败:{err}", "red", "EcCloseFailed")
self.c.close()
self.logger("INFO", "openapi", f"ec: 关闭外部通信连接成功", "green")
@clibs.db_lock
def sr_string(self, directive, interval=clibs.INTERVAL/2):
self.s_string(directive)
time.sleep(interval)
result = self.r_string(directive)
return result
def s_string(self, directive):
order = "".join([directive, self.suffix])
@ -1820,7 +1782,7 @@ class ExternalCommunication(QThread):
try:
char = self.c.recv(1).decode(encoding="unicode_escape")
except Exception as err:
self.logger("ERROR", "openapi", f"ec: 获取请求指令 {directive} 的返回数据超时,需确认指令发送格式以及内容正确!具体报错信息如下 {err}", "red", "RecvMsgFailed")
self.logger("ERROR", "openapi", f"ec: 获取请求指令 {directive} 的返回数据超时,需确认指令发送格式以及内容正确!具体报错信息如下 {err}", "red")
result = "".join([result, char])
return result
@ -2057,7 +2019,7 @@ class ExternalCommunication(QThread):
def __exec_cmd(self, directive, description, more_desc=""):
self.s_string(directive)
time.sleep(clibs.INTERVAL)
time.sleep(clibs.INTERVAL/2)
result = self.r_string(directive).strip()
self.logger("DEBUG", "openapi", f"ec: 执行{description}指令是 {directive},返回值为 {result}{more_desc}")
return result
@ -2082,7 +2044,6 @@ class PreDos(object):
print(f"predos: SSH 无法连接到 {self.ip}:{self.ssh_port},需检查网络连通性或者登录信息是否正确 {err}")
raise Exception("SshConnFailed")
@clibs.handle_exception
def push_prj_to_server(self, prj_file):
# prj_file本地工程完整路径
self.__ssh2server()
@ -2151,7 +2112,6 @@ class PreDos(object):
class RobotInit(object):
@staticmethod
@clibs.handle_exception
def modbus_init():
clibs.c_pd = PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
# 推送配置文件

View File

@ -10,7 +10,6 @@ from codes.common import clibs
class DoFactoryTest(QThread):
output = Signal(str, str)
curve_map = {
"周期内平均转矩": ["device_servo_trq_feedback", ],
"周期内最大速度": ["hw_joint_vel_feedback", ],
@ -23,32 +22,25 @@ class DoFactoryTest(QThread):
self.procs = procs
self.idx = 6
self.curves = []
def logger(self, level, module, content, color="black", error="", flag="both"):
flag = "cursor" if level.upper() == "DEBUG" else "both"
clibs.logger(level, module, content, color, flag, signal=self.output)
if level.upper() == "ERROR":
raise Exception(f"{error} | {content}")
self.logger = clibs.logger
def initialization(self, data_dirs, data_files):
@clibs.handle_exception
def check_files():
for proc_name, is_enabled in self.procs.items():
if is_enabled:
self.curves.extend(self.curve_map[proc_name])
if len(self.curves) == 0:
self.logger("ERROR", "factory", "未查询到需要记录数据的曲线,至少选择一个!", "red", "CurveNameError")
self.logger("ERROR", "factory", "未查询到需要记录数据的曲线,至少选择一个!", "red")
if len(data_dirs) != 0 or len(data_files) != 1:
self.logger("ERROR", "factory", "初始路径下不允许有文件夹,且初始路径下只能存在一个工程文件 —— *.zip确认后重新运行", "red", "InitFileError")
self.logger("ERROR", "factory", "初始路径下不允许有文件夹,且初始路径下只能存在一个工程文件 —— *.zip确认后重新运行", "red")
if not data_files[0].endswith(".zip"):
self.logger("ERROR", "factory", f"{data_files[0]} 不是一个有效的工程文件,需确认!", "red", "ProjectFileError")
self.logger("ERROR", "factory", f"{data_files[0]} 不是一个有效的工程文件,需确认!", "red")
return data_files[0]
@clibs.handle_exception
def get_configs():
robot_type, records = None, None
msg_id = clibs.c_hr.execution("controller.get_params")
@ -64,7 +56,7 @@ class DoFactoryTest(QThread):
with open(local_file, mode="r", encoding="utf-8") as f_config:
configs = json.load(f_config)
except Exception as Err:
self.logger("ERROR", "factory", f"无法打开 {local_file}<br>{Err}", "red", "OpenFileError")
self.logger("ERROR", "factory", f"无法打开 {local_file}<br>{Err}", "red")
# 最大角速度,额定电流,减速比,额定转速
version = configs["VERSION"]
@ -86,13 +78,11 @@ class DoFactoryTest(QThread):
self.logger("INFO", "factory", "数据目录合规性检查结束,未发现问题......", "green")
return params
@clibs.handle_exception
def change_curve_state(self, stat):
display_pdo_params = [{"name": name, "channel": chl} for name in self.curves for chl in range(6)]
clibs.c_hr.execution("diagnosis.open", open=stat, display_open=stat)
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params)
@clibs.handle_exception
def run_rl(self, params):
prj_file, interval = params["prj_file"], params["interval"]
# 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
@ -123,7 +113,7 @@ class DoFactoryTest(QThread):
break
else:
if (time.time() - t_start) > 15:
self.logger("ERROR", "factory", "15s 内未收到机器人的运行信号需要确认RL程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
self.logger("ERROR", "factory", "15s 内未收到机器人的运行信号需要确认RL程序编写正确并正常执行...", "red")
else:
time.sleep(clibs.INTERVAL)
@ -138,7 +128,7 @@ class DoFactoryTest(QThread):
else:
time.sleep(clibs.INTERVAL)
if (time.time() - t_start) > 900:
self.logger("ERROR", "factory", f"900s内未收到耐久工程的周期时间需要确认RL程序和工具通信交互是否正常执行支持最长工程周期时间为300s......", "red", "GetScenarioTimeError")
self.logger("ERROR", "factory", f"900s内未收到耐久工程的周期时间需要确认RL程序和工具通信交互是否正常执行支持最长工程周期时间为300s......", "red")
# 6. 准备数据保存文件
for proc_name, is_enabled in self.procs.items():
@ -180,7 +170,6 @@ class DoFactoryTest(QThread):
self.change_curve_state(False)
self.logger("INFO", "factory", "后台数据清零完成,现在可以重新运行其他程序。", "green")
@clibs.handle_exception
def gen_results(self, params, start_time, end_time):
s_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start_time))
e_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time))
@ -193,7 +182,6 @@ class DoFactoryTest(QThread):
self.data_proc(records, params)
@clibs.handle_exception
def data_proc(self, records, params):
for proc_name, is_enabled in self.procs.items():
if not is_enabled:
@ -210,7 +198,6 @@ class DoFactoryTest(QThread):
t.daemon = True
t.start()
@clibs.handle_exception
def get_avg_trq(self, records, params, proc_name):
d_trq, results = [[], [], [], [], [], []], [time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))]
for record in records:
@ -231,7 +218,6 @@ class DoFactoryTest(QThread):
csv_writer = csv.writer(f_csv)
csv_writer.writerow(results)
@clibs.handle_exception
def get_joint_max_vel(self, records, params, proc_name):
d_trq, results = [[], [], [], [], [], []], [time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))]
for record in records:
@ -255,7 +241,6 @@ class DoFactoryTest(QThread):
@staticmethod
def detect_db_size():
@clibs.db_lock
@clibs.handle_exception
def release_memory():
line_number = 20000
leftover = 4000 # 200s
@ -272,18 +257,17 @@ class DoFactoryTest(QThread):
release_memory()
time.sleep(clibs.INTERVAL*10)
@clibs.handle_exception
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
if clibs.status["hmi"] != 1 or clibs.status["md"] != 1:
self.logger("ERROR", "factory", "processing: 需要在网络设置中连接HMI以及Modbus通信", "red", "NetworkError")
self.logger("ERROR", "factory", "processing: 需要在网络设置中连接HMI以及Modbus通信", "red")
t = threading.Thread(target=self.detect_db_size)
t.daemon = True
t.start()
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
data_dirs, data_files = clibs.traversal_files(self.dir_path)
params = self.initialization(data_dirs, data_files)
clibs.c_pd.push_prj_to_server(params["prj_file"])
self.run_rl(params)

View File

@ -19,15 +19,15 @@ from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QFormLayout,
QFrame, QHBoxLayout, QHeaderView, QLabel,
QLineEdit, QMainWindow, QPlainTextEdit, QPushButton,
QScrollArea, QSizePolicy, QSpacerItem, QStackedWidget,
QStatusBar, QTabWidget, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget)
QStatusBar, QTabWidget, QToolButton, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QWidget)
class Ui_MainWindow(QMainWindow):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.setEnabled(True)
MainWindow.resize(1004, 560)
MainWindow.resize(1006, 568)
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -174,18 +174,15 @@ class Ui_MainWindow(QMainWindow):
self.horizontalLayout.addWidget(self.le_data_path)
self.btn_data_open = QPushButton(self.tab_data)
self.btn_data_open.setObjectName(u"btn_data_open")
self.btn_data_open.setMaximumSize(QSize(30, 16777215))
self.btn_data_open.setFont(font4)
self.toolButton = QToolButton(self.tab_data)
self.toolButton.setObjectName(u"toolButton")
self.horizontalLayout.addWidget(self.btn_data_open)
self.horizontalLayout.addWidget(self.toolButton)
self.horizontalLayout.setStretch(0, 1)
self.horizontalLayout.setStretch(1, 1)
self.horizontalLayout.setStretch(2, 1)
self.horizontalLayout.setStretch(3, 10)
self.horizontalLayout.setStretch(4, 1)
self.verticalLayout.addLayout(self.horizontalLayout)
@ -235,18 +232,15 @@ class Ui_MainWindow(QMainWindow):
self.hl_2_unit1.addWidget(self.le_unit_path)
self.btn_unit_open = QPushButton(self.tab_unit)
self.btn_unit_open.setObjectName(u"btn_unit_open")
self.btn_unit_open.setMaximumSize(QSize(30, 16777215))
self.btn_unit_open.setFont(font4)
self.toolButton_2 = QToolButton(self.tab_unit)
self.toolButton_2.setObjectName(u"toolButton_2")
self.hl_2_unit1.addWidget(self.btn_unit_open)
self.hl_2_unit1.addWidget(self.toolButton_2)
self.hl_2_unit1.setStretch(0, 1)
self.hl_2_unit1.setStretch(1, 1)
self.hl_2_unit1.setStretch(2, 1)
self.hl_2_unit1.setStretch(3, 10)
self.hl_2_unit1.setStretch(4, 1)
self.verticalLayout_2.addLayout(self.hl_2_unit1)
@ -287,7 +281,7 @@ class Ui_MainWindow(QMainWindow):
self.sa_durable.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 212, 78))
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 213, 78))
self.horizontalLayout_9 = QHBoxLayout(self.scrollAreaWidgetContents)
self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")
self.verticalLayout_5 = QVBoxLayout()
@ -343,13 +337,14 @@ class Ui_MainWindow(QMainWindow):
self.horizontalLayout_6.addWidget(self.le_durable_path)
self.btn_durable_open = QPushButton(self.tab_durable)
self.btn_durable_open.setObjectName(u"btn_durable_open")
self.btn_durable_open.setMaximumSize(QSize(30, 16777215))
self.btn_durable_open.setFont(font4)
self.toolButton_3 = QToolButton(self.tab_durable)
self.toolButton_3.setObjectName(u"toolButton_3")
self.horizontalLayout_6.addWidget(self.btn_durable_open)
self.horizontalLayout_6.addWidget(self.toolButton_3)
self.horizontalLayout_6.setStretch(0, 1)
self.horizontalLayout_6.setStretch(1, 10)
self.horizontalLayout_6.setStretch(2, 1)
self.verticalLayout_6.addLayout(self.horizontalLayout_6)
@ -371,17 +366,8 @@ class Ui_MainWindow(QMainWindow):
self.horizontalLayout_7.addWidget(self.le_durable_interval)
self.label_10 = QLabel(self.tab_durable)
self.label_10.setObjectName(u"label_10")
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.label_10.sizePolicy().hasHeightForWidth())
self.label_10.setSizePolicy(sizePolicy2)
self.label_10.setMinimumSize(QSize(30, 0))
self.horizontalLayout_7.addWidget(self.label_10)
self.horizontalLayout_7.setStretch(0, 1)
self.horizontalLayout_7.setStretch(1, 10)
self.verticalLayout_6.addLayout(self.horizontalLayout_7)
@ -505,10 +491,10 @@ class Ui_MainWindow(QMainWindow):
self.horizontalLayout_5.addWidget(self.pte_hmi_send)
self.pte_him_recv = QPlainTextEdit(self.page)
self.pte_him_recv.setObjectName(u"pte_him_recv")
self.pte_hmi_recv = QPlainTextEdit(self.page)
self.pte_hmi_recv.setObjectName(u"pte_hmi_recv")
self.horizontalLayout_5.addWidget(self.pte_him_recv)
self.horizontalLayout_5.addWidget(self.pte_hmi_recv)
self.verticalLayout_10.addLayout(self.horizontalLayout_5)
@ -746,23 +732,23 @@ class Ui_MainWindow(QMainWindow):
self.verticalLayout_4 = QVBoxLayout()
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
self.pushButton = QPushButton(self.tab_network)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setFont(font5)
self.hmi_btn = QPushButton(self.tab_network)
self.hmi_btn.setObjectName(u"hmi_btn")
self.hmi_btn.setFont(font5)
self.verticalLayout_4.addWidget(self.pushButton)
self.verticalLayout_4.addWidget(self.hmi_btn)
self.pushButton_2 = QPushButton(self.tab_network)
self.pushButton_2.setObjectName(u"pushButton_2")
self.pushButton_2.setFont(font5)
self.md_btn = QPushButton(self.tab_network)
self.md_btn.setObjectName(u"md_btn")
self.md_btn.setFont(font5)
self.verticalLayout_4.addWidget(self.pushButton_2)
self.verticalLayout_4.addWidget(self.md_btn)
self.pushButton_3 = QPushButton(self.tab_network)
self.pushButton_3.setObjectName(u"pushButton_3")
self.pushButton_3.setFont(font5)
self.ec_btn = QPushButton(self.tab_network)
self.ec_btn.setObjectName(u"ec_btn")
self.ec_btn.setFont(font5)
self.verticalLayout_4.addWidget(self.pushButton_3)
self.verticalLayout_4.addWidget(self.ec_btn)
self.horizontalLayout_12.addLayout(self.verticalLayout_4)
@ -877,11 +863,11 @@ class Ui_MainWindow(QMainWindow):
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
sizePolicy3.setHorizontalStretch(0)
sizePolicy3.setVerticalStretch(0)
sizePolicy3.setHeightForWidth(self.statusbar.sizePolicy().hasHeightForWidth())
self.statusbar.setSizePolicy(sizePolicy3)
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.statusbar.sizePolicy().hasHeightForWidth())
self.statusbar.setSizePolicy(sizePolicy2)
self.statusbar.setMinimumSize(QSize(0, 27))
self.statusbar.setStyleSheet(u"background-color: rgb(200, 200, 200);")
MainWindow.setStatusBar(self.statusbar)
@ -890,11 +876,8 @@ class Ui_MainWindow(QMainWindow):
self.btn_start.clicked.connect(MainWindow.prog_start)
self.btn_stop.clicked.connect(MainWindow.prog_stop)
self.btn_reset.clicked.connect(MainWindow.prog_reset)
self.btn_durable_open.clicked.connect(MainWindow.file_browser)
self.btn_draw.clicked.connect(MainWindow.curve_draw)
self.cb_durable_total.checkStateChanged.connect(MainWindow.durable_cb_change)
self.btn_unit_open.clicked.connect(MainWindow.file_browser)
self.btn_data_open.clicked.connect(MainWindow.file_browser)
self.btn_docs_previous.clicked.connect(MainWindow.pre_page)
self.btn_docs_realtime.clicked.connect(MainWindow.realtime_page)
self.btn_docs_next.clicked.connect(MainWindow.next_page)
@ -902,9 +885,9 @@ class Ui_MainWindow(QMainWindow):
self.le_docs_search.returnPressed.connect(MainWindow.search_keyword)
self.cb_hmi_cmd.currentTextChanged.connect(MainWindow.hmi_cb_change)
self.btn_hmi_send.clicked.connect(MainWindow.hmi_send)
self.pushButton.clicked.connect(MainWindow.hmi_page)
self.pushButton_2.clicked.connect(MainWindow.md_page)
self.pushButton_3.clicked.connect(MainWindow.ec_page)
self.hmi_btn.clicked.connect(MainWindow.hmi_page)
self.md_btn.clicked.connect(MainWindow.md_page)
self.ec_btn.clicked.connect(MainWindow.ec_page)
self.cb_md_cmd.currentTextChanged.connect(MainWindow.md_cb_change)
self.btn_md_send.clicked.connect(MainWindow.md_send)
self.btn_ec_send.clicked.connect(MainWindow.ec_send)
@ -916,6 +899,10 @@ class Ui_MainWindow(QMainWindow):
self.le_hmi_ip.returnPressed.connect(MainWindow.hmi_conn)
self.tw_docs.currentChanged.connect(MainWindow.switch_log_tab)
self.treew_log.itemDoubleClicked.connect(MainWindow.show_item_content)
self.cb_data_func.currentTextChanged.connect(MainWindow.data_cb_change)
self.toolButton.clicked.connect(MainWindow.file_browser)
self.toolButton_2.clicked.connect(MainWindow.file_browser)
self.toolButton_3.clicked.connect(MainWindow.file_browser)
self.tw_funcs.setCurrentIndex(0)
self.sw_network.setCurrentIndex(0)
@ -941,7 +928,7 @@ class Ui_MainWindow(QMainWindow):
self.cb_data_current.setItemText(2, QCoreApplication.translate("MainWindow", u"\u5e73\u5747\u503c", None))
self.label_4.setText(QCoreApplication.translate("MainWindow", u"\u8def\u5f84", None))
self.btn_data_open.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.toolButton.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_data), QCoreApplication.translate("MainWindow", u"\u6570\u636e\u5904\u7406", None))
self.cb_unit_func.setItemText(0, QCoreApplication.translate("MainWindow", u"\u5236\u52a8", None))
self.cb_unit_func.setItemText(1, QCoreApplication.translate("MainWindow", u"\u8f6c\u77e9", None))
@ -952,19 +939,18 @@ class Ui_MainWindow(QMainWindow):
self.cb_unit_tool.setItemText(3, QCoreApplication.translate("MainWindow", u"inertia", None))
self.label_6.setText(QCoreApplication.translate("MainWindow", u"\u8def\u5f84", None))
self.btn_unit_open.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.toolButton_2.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_unit), QCoreApplication.translate("MainWindow", u"\u6574\u673a\u6d4b\u8bd5", None))
self.label_11.setText(QCoreApplication.translate("MainWindow", u"\u9009\u62e9\u6307\u6807", None))
self.cb_1.setText(QCoreApplication.translate("MainWindow", u"\u5468\u671f\u5185\u5e73\u5747\u8f6c\u77e9", None))
self.cb_2.setText(QCoreApplication.translate("MainWindow", u"\u5468\u671f\u5185\u6700\u5927\u901f\u5ea6", None))
self.label_8.setText(QCoreApplication.translate("MainWindow", u"\u8def\u5f84", None))
self.btn_durable_open.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.toolButton_3.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.label_9.setText(QCoreApplication.translate("MainWindow", u"\u95f4\u9694", None))
#if QT_CONFIG(whatsthis)
self.le_durable_interval.setWhatsThis("")
#endif // QT_CONFIG(whatsthis)
self.le_durable_interval.setPlaceholderText(QCoreApplication.translate("MainWindow", u"\u6bcf\u6b21\u6570\u636e\u91c7\u96c6\u7684\u65f6\u95f4\u95f4\u9694\uff0c\u9ed8\u8ba4(\u6700\u5c0f)300s", None))
self.label_10.setText("")
self.cb_durable_total.setText(QCoreApplication.translate("MainWindow", u"\u5168\u90e8\u6253\u5f00/\u5173\u95ed", None))
self.btn_draw.setText(QCoreApplication.translate("MainWindow", u"\u7ed8\u56fe", None))
self.label_3.setText("")
@ -1053,16 +1039,16 @@ class Ui_MainWindow(QMainWindow):
self.cb_ec_cmd.setItemText(52, QCoreApplication.translate("MainWindow", u"safe_door_open", None))
self.cb_ec_cmd.setItemText(53, QCoreApplication.translate("MainWindow", u"soft_estop_state", None))
self.cb_ec_cmd.setItemText(54, QCoreApplication.translate("MainWindow", u"cart_vel", None))
self.cb_ec_cmd.setItemText(55, QCoreApplication.translate("MainWindow", u"tcp_pos", None))
self.cb_ec_cmd.setItemText(55, QCoreApplication.translate("MainWindow", u"tcp_pose", None))
self.cb_ec_cmd.setItemText(56, QCoreApplication.translate("MainWindow", u"tcp_vel", None))
self.cb_ec_cmd.setItemText(57, QCoreApplication.translate("MainWindow", u"tcp_vel_mag", None))
self.cb_ec_cmd.setItemText(58, QCoreApplication.translate("MainWindow", u"ext_estop_state", None))
self.cb_ec_cmd.setItemText(59, QCoreApplication.translate("MainWindow", u"hand_estop_state", None))
self.btn_ec_send.setText(QCoreApplication.translate("MainWindow", u"\u53d1\u9001", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"HMI", None))
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"Modbus", None))
self.pushButton_3.setText(QCoreApplication.translate("MainWindow", u"EC", None))
self.hmi_btn.setText(QCoreApplication.translate("MainWindow", u"HMI", None))
self.md_btn.setText(QCoreApplication.translate("MainWindow", u"Modbus", None))
self.ec_btn.setText(QCoreApplication.translate("MainWindow", u"EC", None))
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_network), QCoreApplication.translate("MainWindow", u"\u7f51\u7edc\u8bbe\u7f6e", None))
self.tw_docs.setTabText(self.tw_docs.indexOf(self.tab_output), QCoreApplication.translate("MainWindow", u"\u8f93\u51fa", None))
___qtreewidgetitem = self.treew_log.headerItem()

View File

@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1004</width>
<height>563</height>
<width>1006</width>
<height>568</height>
</rect>
</property>
<property name="sizePolicy">
@ -248,7 +248,7 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1,1,10,1">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1,1,10,0">
<item>
<widget class="QComboBox" name="cb_data_func">
<property name="minimumSize">
@ -346,19 +346,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_data_open">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
</font>
</property>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string>...</string>
</property>
@ -387,7 +375,7 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="hl_2_unit1" stretch="1,1,1,10,1">
<layout class="QHBoxLayout" name="hl_2_unit1" stretch="1,1,1,10,0">
<item>
<widget class="QComboBox" name="cb_unit_func">
<property name="minimumSize">
@ -483,19 +471,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_unit_open">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
</font>
</property>
<widget class="QToolButton" name="toolButton_2">
<property name="text">
<string>...</string>
</property>
@ -583,7 +559,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>212</width>
<width>213</width>
<height>78</height>
</rect>
</property>
@ -645,7 +621,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,10,1">
<item>
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
@ -679,19 +655,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_durable_open">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
</font>
</property>
<widget class="QToolButton" name="toolButton_3">
<property name="text">
<string>...</string>
</property>
@ -700,7 +664,7 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<layout class="QHBoxLayout" name="horizontalLayout_7" stretch="1,10">
<item>
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
@ -742,25 +706,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -977,7 +922,7 @@
<widget class="QPlainTextEdit" name="pte_hmi_send"/>
</item>
<item>
<widget class="QPlainTextEdit" name="pte_him_recv"/>
<widget class="QPlainTextEdit" name="pte_hmi_recv"/>
</item>
</layout>
</item>
@ -1524,7 +1469,7 @@
</item>
<item>
<property name="text">
<string>tcp_pos</string>
<string>tcp_pose</string>
</property>
</item>
<item>
@ -1584,7 +1529,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="hmi_btn">
<property name="font">
<font>
<family>Consolas</family>
@ -1598,7 +1543,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<widget class="QPushButton" name="md_btn">
<property name="font">
<font>
<family>Consolas</family>
@ -1612,7 +1557,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<widget class="QPushButton" name="ec_btn">
<property name="font">
<font>
<family>Consolas</family>
@ -1894,22 +1839,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>btn_durable_open</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>file_browser()</slot>
<hints>
<hint type="sourcelabel">
<x>964</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>990</x>
<y>97</y>
</hint>
</hints>
</connection>
<connection>
<sender>btn_draw</sender>
<signal>clicked()</signal>
@ -1917,8 +1846,8 @@
<slot>curve_draw()</slot>
<hints>
<hint type="sourcelabel">
<x>692</x>
<y>136</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>701</x>
@ -1933,8 +1862,8 @@
<slot>durable_cb_change()</slot>
<hints>
<hint type="sourcelabel">
<x>566</x>
<y>135</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>546</x>
@ -1942,38 +1871,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>btn_unit_open</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>file_browser()</slot>
<hints>
<hint type="sourcelabel">
<x>981</x>
<y>78</y>
</hint>
<hint type="destinationlabel">
<x>974</x>
<y>181</y>
</hint>
</hints>
</connection>
<connection>
<sender>btn_data_open</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>file_browser()</slot>
<hints>
<hint type="sourcelabel">
<x>964</x>
<y>73</y>
</hint>
<hint type="destinationlabel">
<x>941</x>
<y>180</y>
</hint>
</hints>
</connection>
<connection>
<sender>btn_docs_previous</sender>
<signal>clicked()</signal>
@ -1981,8 +1878,8 @@
<slot>pre_page()</slot>
<hints>
<hint type="sourcelabel">
<x>408</x>
<y>507</y>
<x>326</x>
<y>266</y>
</hint>
<hint type="destinationlabel">
<x>307</x>
@ -1997,8 +1894,8 @@
<slot>realtime_page()</slot>
<hints>
<hint type="sourcelabel">
<x>489</x>
<y>507</y>
<x>326</x>
<y>266</y>
</hint>
<hint type="destinationlabel">
<x>435</x>
@ -2013,8 +1910,8 @@
<slot>next_page()</slot>
<hints>
<hint type="sourcelabel">
<x>570</x>
<y>507</y>
<x>326</x>
<y>266</y>
</hint>
<hint type="destinationlabel">
<x>520</x>
@ -2029,8 +1926,8 @@
<slot>search_keyword()</slot>
<hints>
<hint type="sourcelabel">
<x>730</x>
<y>507</y>
<x>326</x>
<y>266</y>
</hint>
<hint type="destinationlabel">
<x>688</x>
@ -2045,8 +1942,8 @@
<slot>search_keyword()</slot>
<hints>
<hint type="sourcelabel">
<x>838</x>
<y>505</y>
<x>326</x>
<y>266</y>
</hint>
<hint type="destinationlabel">
<x>932</x>
@ -2061,7 +1958,7 @@
<slot>hmi_cb_change()</slot>
<hints>
<hint type="sourcelabel">
<x>806</x>
<x>475</x>
<y>89</y>
</hint>
<hint type="destinationlabel">
@ -2077,7 +1974,7 @@
<slot>hmi_send()</slot>
<hints>
<hint type="sourcelabel">
<x>887</x>
<x>335</x>
<y>89</y>
</hint>
<hint type="destinationlabel">
@ -2087,14 +1984,14 @@
</hints>
</connection>
<connection>
<sender>pushButton</sender>
<sender>hmi_btn</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>hmi_page()</slot>
<hints>
<hint type="sourcelabel">
<x>980</x>
<y>85</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>744</x>
@ -2103,14 +2000,14 @@
</hints>
</connection>
<connection>
<sender>pushButton_2</sender>
<sender>md_btn</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>md_page()</slot>
<hints>
<hint type="sourcelabel">
<x>980</x>
<y>124</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>784</x>
@ -2119,14 +2016,14 @@
</hints>
</connection>
<connection>
<sender>pushButton_3</sender>
<sender>ec_btn</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>ec_page()</slot>
<hints>
<hint type="sourcelabel">
<x>980</x>
<y>163</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>969</x>
@ -2141,8 +2038,8 @@
<slot>md_cb_change()</slot>
<hints>
<hint type="sourcelabel">
<x>467</x>
<y>81</y>
<x>466</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>612</x>
@ -2157,8 +2054,8 @@
<slot>md_send()</slot>
<hints>
<hint type="sourcelabel">
<x>327</x>
<y>81</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>795</x>
@ -2173,8 +2070,8 @@
<slot>ec_send()</slot>
<hints>
<hint type="sourcelabel">
<x>327</x>
<y>81</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>652</x>
@ -2189,7 +2086,7 @@
<slot>hmi_conn()</slot>
<hints>
<hint type="sourcelabel">
<x>545</x>
<x>335</x>
<y>89</y>
</hint>
<hint type="destinationlabel">
@ -2205,8 +2102,8 @@
<slot>md_conn()</slot>
<hints>
<hint type="sourcelabel">
<x>327</x>
<y>81</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>398</x>
@ -2221,8 +2118,8 @@
<slot>ec_conn()</slot>
<hints>
<hint type="sourcelabel">
<x>327</x>
<y>81</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>412</x>
@ -2237,8 +2134,8 @@
<slot>check_interval()</slot>
<hints>
<hint type="sourcelabel">
<x>844</x>
<y>97</y>
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>821</x>
@ -2253,8 +2150,8 @@
<slot>ec_cb_change()</slot>
<hints>
<hint type="sourcelabel">
<x>467</x>
<y>81</y>
<x>466</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>540</x>
@ -2269,8 +2166,8 @@
<slot>hmi_conn()</slot>
<hints>
<hint type="sourcelabel">
<x>420</x>
<y>79</y>
<x>385</x>
<y>89</y>
</hint>
<hint type="destinationlabel">
<x>216</x>
@ -2301,8 +2198,8 @@
<slot>show_item_content()</slot>
<hints>
<hint type="sourcelabel">
<x>441</x>
<y>321</y>
<x>308</x>
<y>230</y>
</hint>
<hint type="destinationlabel">
<x>205</x>
@ -2310,6 +2207,70 @@
</hint>
</hints>
</connection>
<connection>
<sender>cb_data_func</sender>
<signal>currentTextChanged(QString)</signal>
<receiver>MainWindow</receiver>
<slot>data_cb_change()</slot>
<hints>
<hint type="sourcelabel">
<x>273</x>
<y>61</y>
</hint>
<hint type="destinationlabel">
<x>208</x>
<y>7</y>
</hint>
</hints>
</connection>
<connection>
<sender>toolButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>file_browser()</slot>
<hints>
<hint type="sourcelabel">
<x>973</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>1002</x>
<y>19</y>
</hint>
</hints>
</connection>
<connection>
<sender>toolButton_2</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>file_browser()</slot>
<hints>
<hint type="sourcelabel">
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>1004</x>
<y>56</y>
</hint>
</hints>
</connection>
<connection>
<sender>toolButton_3</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>file_browser()</slot>
<hints>
<hint type="sourcelabel">
<x>326</x>
<y>80</y>
</hint>
<hint type="destinationlabel">
<x>1004</x>
<y>88</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>prog_start()</slot>
@ -2338,5 +2299,6 @@
<slot>check_interval()</slot>
<slot>switch_log_tab()</slot>
<slot>show_item_content()</slot>
<slot>data_cb_change()</slot>
</slots>
</ui>