1. 删除未使用部分 2. 删除本地sqlite保存功能 3. 新增do_current多采集两条曲线 4. 优化耐久采集,修改最短间隔未30s

This commit is contained in:
gitea 2025-04-10 11:33:42 +08:00
parent 6e547ca6a3
commit 387618efb9
10 changed files with 258 additions and 40 deletions

2
.gitignore vendored
View File

@ -3,5 +3,5 @@ venv/
**/__pycache__/
assets/files/examples/
assets/logs/*
codes/durable/curves_draw.py
package/*
test/

20
aio.py
View File

@ -1,16 +1,9 @@
import datetime
import json
import os
import re
import sqlite3
import sys
import time
from urllib import request
import os.path
# import matplotlib
# import matplotlib.pyplot as plt
# import pandas
# from matplotlib.widgets import Slider
from PySide6.QtCore import Qt, QThread, Signal, QObject, QTimer
from PySide6.QtGui import QTextCursor, QFont, QPixmap, QColor, QBrush, QIcon
@ -22,7 +15,6 @@ import codes.ui.main_window as main_window
from codes.analysis import brake, current, wavelogger, iso
from codes.autotest import do_current, do_brake
from codes.durable import factory_test, curves_draw
# matplotlib.use('QtAgg')
class ContentDialog(QDialog):
@ -895,18 +887,6 @@ class MainWindow(main_window.Ui_MainWindow):
info_text = "当前有程序正在停止中,确认退出?" if clibs.stop_flag else info_text
reply = QMessageBox.question(self, "退出", info_text)
if reply == QMessageBox.Yes:
# os.chdir(clibs.log_path)
# t = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
# disk_conn = sqlite3.connect(f"log_{t}.db", isolation_level=None, check_same_thread=False, cached_statements=256)
#
# clibs.conn.backup(target=disk_conn, pages=1, progress=None)
#
# _, logs = clibs.traversal_files(".")
# logs.sort()
# while len(logs) > 10:
# _ = logs.pop(0)
# os.remove(_)
if clibs.status["md"] == 1:
self.run_program_thread(clibs.c_md.close, -99, self.prog_done_disconn, "md")
if clibs.status["ec"] == 1:

View File

@ -6,8 +6,8 @@ VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(0, 4, 0, 2),
prodvers=(0, 4, 0, 2),
filevers=(0, 4, 0, 3),
prodvers=(0, 4, 0, 3),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
@ -31,12 +31,12 @@ VSVersionInfo(
'040904b0',
[StringStruct('CompanyName', 'Rokae - https://www.rokae.com/'),
StringStruct('FileDescription', 'All in one automatic toolbox'),
StringStruct('FileVersion', '0.4.0.2 (2025-04-07)'),
StringStruct('FileVersion', '0.4.0.3 (2025-04-10)'),
StringStruct('InternalName', 'AIO.exe'),
StringStruct('LegalCopyright', '© 2024-2025 Manford Fan'),
StringStruct('OriginalFilename', 'AIO.exe'),
StringStruct('ProductName', 'AIO'),
StringStruct('ProductVersion', '0.4.0.2 (2025-04-07)')])
StringStruct('ProductVersion', '0.4.0.3 (2025-04-10)')])
]),
VarFileInfo([VarStruct('Translation', [1033, 1200])])
]

View File

@ -1 +1 @@
0.4.0.2@04/07/2025
0.4.0.3@04/10/2025

View File

@ -1 +1 @@
0.4.0.2@04/07/2025
0.4.0.3@04/10/2025

View File

@ -67,7 +67,7 @@ class DoCurrentTest(QThread):
def single_axis_proc(self, records, number):
text = "single" if number < 6 else "hold"
number = number if number < 6 else number - 6
d_vel, d_trq, d_sensor, d_trans = [], [], [], []
d_vel, d_trq, d_sensor, d_trans, d_predict_trq, d_real_trq = [], [], [], [], [], []
for record in records:
data = eval(record[0])["data"]
for item in data:
@ -80,17 +80,24 @@ class DoCurrentTest(QThread):
d_sensor.extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_estimate_trans_trq_res":
d_trans.extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_predict_trq_res":
d_predict_trq.extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_real_trq_res":
d_real_trq.extend(d_item)
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
df4 = pandas.DataFrame.from_dict({"hw_estimate_trans_trq_res": d_trans})
df = pandas.concat([df1, df2, df3, df4], axis=1)
df5 = pandas.DataFrame.from_dict({"hw_predict_trq_res": d_predict_trq})
df6 = pandas.DataFrame.from_dict({"hw_real_trq_res": d_real_trq})
df = pandas.concat([df1, df2, df3, df4, df5, df6], axis=1)
filename = f"{self.dir_path}/single/j{number + 1}_{text}_{time.time()}.data"
df.to_csv(filename, sep="\t", index=False)
def scenario_proc(self, records, number, scenario_time):
d_vel, d_trq, d_sensor, d_trans = [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []]
# d_vel, d_trq, d_sensor, d_trans, d_predict_trq, d_real_trq = [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []]
d_vel, d_trq, d_sensor, d_trans, d_predict_trq, d_real_trq = [[[], [], [], [], [], []] for _ in range(6)]
for record in records:
data = eval(record[0])["data"]
for item in data:
@ -104,13 +111,19 @@ class DoCurrentTest(QThread):
d_sensor[axis].extend(d_item)
elif item.get("channel", None) == axis and item.get("name", None) == "hw_estimate_trans_trq_res":
d_trans[axis].extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_predict_trq_res":
d_predict_trq[axis].extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_real_trq_res":
d_real_trq[axis].extend(d_item)
for axis in range(6):
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel[axis]})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq[axis]})
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor[axis]})
df4 = pandas.DataFrame.from_dict({"hw_estimate_trans_trq_res": d_trans[axis]})
df = pandas.concat([df1, df2, df3, df4], axis=1)
df5 = pandas.DataFrame.from_dict({"hw_predict_trq_res": d_predict_trq[axis]})
df6 = pandas.DataFrame.from_dict({"hw_real_trq_res": d_real_trq[axis]})
df = pandas.concat([df1, df2, df3, df4, df5, df6], axis=1)
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)
@ -139,7 +152,7 @@ class DoCurrentTest(QThread):
@staticmethod
def change_curve_state(stat):
curves = ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback", "hw_estimate_trans_trq_res"]
curves = ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback", "hw_estimate_trans_trq_res", "hw_predict_trq_res", "hw_real_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)

View File

@ -104,14 +104,13 @@ def detect_db_size():
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] # 制动数据/转矩数据/激光数据/精度数据/制动自动化/转矩自动化/耐久数据采集
stop_flag = False
functions = ["制动数据处理", "转矩数据处理", "激光数据处理", "精度数据处理", "制动自动化测试", "转矩自动化测试", "耐久数据采集"]
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", "123456"
username, password = "luoshi", "luoshi2019"
INTERVAL, RADIAN, MAX_FRAME_SIZE, MAX_LOG_NUMBER, CYCLE = 1, 57.3, 1024, 10, 30
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}

View File

@ -0,0 +1,226 @@
from PySide6.QtWidgets import QApplication, QMainWindow, QSlider, QVBoxLayout, QComboBox, QWidget, QPushButton, QToolBar, QGridLayout, QHBoxLayout, QLabel, QRadioButton, QScrollArea, QSizePolicy, QSpacerItem
from PySide6.QtCore import Qt, QTimer, QSize, QPointF
from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis
from PySide6.QtGui import QAction, QPainter, QColor, QIcon, QFont
from codes.common import clibs
import os
import pandas
class ChartWindow(QMainWindow):
curve_map = {
"周期内平均转矩": ["device_servo_trq_feedback", ],
"周期内最大速度": ["hw_joint_vel_feedback", ],
}
ylabels = {"周期内最大速度": "速度(rad/s)", "周期内平均转矩": "转矩(Nm)"}
colors = [QColor(255, 0, 0), QColor(255, 0, 0), QColor(0, 0, 255), QColor(0, 255, 0), QColor(254, 153, 0), QColor(0, 255, 255), QColor(255, 0, 255), QColor(0, 0, 0), QColor(255, 255, 255), QColor(128, 128, 128), QColor(255, 182, 193), QColor(173, 216, 230), QColor(144, 238, 144)]
def __init__(self, dir_path, procs):
super().__init__()
self.procs = procs
self.dir_path = dir_path
self.setup_ui()
self.detect_files()
# self.timer = QTimer()
# self.timer.timeout.connect(self.reset_zoom)
# self.timer.start(60000) # 60000ms 更新一次数据
def detect_files(self):
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)
if not os.path.exists(self.dir_path):
clibs.logger("ERROR", "curves_draw", f"数据文件夹{self.dir_path}不存在,请确认后重试......", "red")
for proc_name, is_enabled in self.procs.items():
if is_enabled:
break
else:
clibs.logger("ERROR", "curves_draw", f"需要选择至少一个功能,才能继续绘图......", "red")
_, files = clibs.traversal_files(self.dir_path)
csv_files = []
for file in files:
if file.lower().endswith(".csv"):
self.cb_func_name.addItem(file.split("/")[-1].split(".")[0])
csv_files.append(file)
if len(csv_files) == 0:
clibs.logger("ERROR", "curves_draw", "程序未开始运行,暂无数据可以展示......", "red")
self.reset_zoom()
def get_current_info(self):
self.func_name = self.cb_func_name.currentText()
self.file_name = f"{self.dir_path}/{self.func_name}.csv"
self.df = pandas.read_csv(self.file_name)
self.horizontal_slider.setRange(0, len(self.df))
def center_on_screen(self):
screen_geometry = QApplication.primaryScreen().geometry()
screen_width = screen_geometry.width()
screen_height = screen_geometry.height()
win_width = self.width()
win_height = self.height()
x = (screen_width - win_width) // 2
y = (screen_height - win_height) // 2
self.move(x, y)
def setup_ui(self):
self.setWindowTitle("曲线绘制")
self.setGeometry(100, 100, 1000, 500)
self.setWindowIcon(QIcon(f"{clibs.PREFIX}/media/icon.ico"))
self.center_on_screen()
# 窗体布局
self.centralwidget = QWidget(self)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
# 布局spinbox 和 label coordinate
self.hl_spinbox_btn = QHBoxLayout()
self.hl_spinbox_btn.setObjectName(u"hl_spinbox_btn")
font = QFont()
font.setFamilies([u"Consolas"])
font.setPointSize(10)
self.rb_x = QRadioButton(self.centralwidget)
self.rb_x.setObjectName(u"rb_x")
self.rb_x.setText(u"仅X轴缩放")
self.rb_x.setFont(font)
self.rb_y = QRadioButton(self.centralwidget)
self.rb_y.setObjectName(u"rb_y")
self.rb_y.setText(u"仅Y轴缩放")
self.rb_y.setFont(font)
self.rb_xy = QRadioButton(self.centralwidget)
self.rb_xy.setObjectName(u"rb_xy")
self.rb_xy.setText(u"XY轴缩放")
self.rb_xy.setFont(font)
self.rb_xy.setChecked(True)
self.cb_func_name = QComboBox(self.centralwidget)
self.cb_func_name.setObjectName(u"cb_func_name")
self.cb_func_name.setMinimumSize(QSize(200, 0))
self.cb_func_name.setFont(font)
self.button_reset = QPushButton(self.centralwidget)
self.button_reset.setObjectName(u"button_reset")
self.button_reset.setFont(font)
self.button_reset.setText(u"视图重置")
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.hl_spinbox_btn.addWidget(self.rb_x)
self.hl_spinbox_btn.addWidget(self.rb_y)
self.hl_spinbox_btn.addWidget(self.rb_xy)
self.hl_spinbox_btn.addItem(self.horizontalSpacer)
self.hl_spinbox_btn.addWidget(self.cb_func_name)
self.hl_spinbox_btn.addWidget(self.button_reset)
# 连接信号
self.rb_x.clicked.connect(lambda: self.set_zoom_mode(QChartView.RubberBand.HorizontalRubberBand))
self.rb_y.clicked.connect(lambda: self.set_zoom_mode(QChartView.RubberBand.VerticalRubberBand))
self.rb_xy.clicked.connect(lambda: self.set_zoom_mode(QChartView.RubberBand.RectangleRubberBand))
self.button_reset.clicked.connect(self.reset_zoom)
self.cb_func_name.currentTextChanged.connect(self.cb_func_name_change)
# 生成曲线图
self.chart = QChart()
self.chart.setTheme(QChart.ChartTheme.ChartThemeLight) # 设置主题
self.chart.legend().setVisible(True)
self.chart.legend().setAlignment(Qt.AlignmentFlag.AlignRight) # 图例右对齐
self.chart_view = QChartView(self.chart)
self.chart_view.setRubberBand(QChartView.RubberBand.RectangleRubberBand) # 矩形缩放
self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing) # 抗锯齿
self.axisX = QValueAxis()
# self.axisX.setTitleText("X轴")
self.axisX.setRange(0, 10) # 初始显示范围
self.axisY = QValueAxis()
# self.axisY.setTitleText("Y轴")
self.axisY.setRange(-5, 5)
self.chart.addAxis(self.axisX, Qt.AlignmentFlag.AlignBottom)
self.chart.addAxis(self.axisY, Qt.AlignmentFlag.AlignLeft)
# 创建水平滚动条
self.horizontal_slider = QSlider(Qt.Orientation.Horizontal)
self.horizontal_slider.valueChanged.connect(self.update_view)
# self.horizontal_slider.setFixedHeight(200)
# 左侧布局
self.vl_central = QVBoxLayout()
self.vl_central.setObjectName(u"vl_central")
self.vl_central.addWidget(self.chart_view)
self.vl_central.addWidget(self.horizontal_slider)
self.vl_central.addLayout(self.hl_spinbox_btn)
self.vl_central.setStretch(0, 20)
self.vl_central.setStretch(1, 1)
self.vl_central.setStretch(2, 1)
self.gridLayout.addLayout(self.vl_central, 0, 0)
self.setCentralWidget(self.centralwidget)
def connect_legend_markers(self):
for marker in self.chart.legend().markers():
try:
marker.clicked.disconnect()
except:
pass
marker.clicked.connect(self.toggle_series_visibility)
self.update_legend_style(marker)
def update_legend_style(self, marker):
alpha = 255 if marker.series().isVisible() else 128
color = marker.labelBrush().color()
color.setAlpha(alpha)
marker.setLabelBrush(color)
marker_color = marker.series().color()
marker_color.setAlpha(alpha)
marker.setBrush(marker_color)
marker.setPen(marker_color.darker())
def toggle_series_visibility(self):
marker = self.sender()
if series := marker.series():
new_visibility = not series.isVisible()
series.setVisible(new_visibility)
self.update_legend_style(marker)
marker.setVisible(True)
def cb_func_name_change(self):
self.reset_zoom()
def set_zoom_mode(self, mode):
"""设置缩放模式"""
self.chart_view.setRubberBand(mode)
# 取消其他按钮的选中状态
self.rb_x.setChecked(mode == QChartView.RubberBand.HorizontalRubberBand)
self.rb_y.setChecked(mode == QChartView.RubberBand.VerticalRubberBand)
self.rb_xy.setChecked(mode == QChartView.RubberBand.RectangleRubberBand)
def reset_zoom(self):
self.chart.removeAllSeries()
self.get_current_info()
self.axisY.setTitleText(self.ylabels[self.func_name])
series_s = [QLineSeries() for _ in range(18)]
for col in range(1, len(self.df.columns)):
self.series = series_s[col]
self.chart.addSeries(self.series)
self.series.attachAxis(self.axisX)
self.series.attachAxis(self.axisY)
data = [QPointF(idx, self.df.iloc[:, col].values[idx]) for idx in range(len(self.df))]
self.series.append(data)
self.series.setColor(self.colors[col])
self.series.setName(self.df.columns[col])
self.chart.zoomReset() # 重置所有缩放
self.horizontal_slider.setValue(0)
self.axisX.setRange(0, len(self.df))
self.axisY.setRange(min(self.df.iloc[:, 1:].min())-1, max(self.df.iloc[:, 1:].max())+1)
self.connect_legend_markers()
def update_view(self):
self.connect_legend_markers()
# 自动滚动显示最新10个点
if self.horizontal_slider.value() > 10:
self.axisX.setRange(self.horizontal_slider.value() - 10, self.horizontal_slider.value())
else:
self.axisX.setRange(0, 10)

View File

@ -27,7 +27,7 @@ class Ui_MainWindow(QMainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.setEnabled(True)
MainWindow.resize(1006, 568)
MainWindow.resize(1004, 563)
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -281,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, 213, 78))
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 212, 78))
self.horizontalLayout_9 = QHBoxLayout(self.scrollAreaWidgetContents)
self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")
self.verticalLayout_5 = QVBoxLayout()
@ -950,7 +950,7 @@ class Ui_MainWindow(QMainWindow):
#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.le_durable_interval.setPlaceholderText(QCoreApplication.translate("MainWindow", u"\u6bcf\u6b21\u6570\u636e\u91c7\u96c6\u7684\u65f6\u95f4\u95f4\u9694\uff0c\u9ed8\u8ba4(\u6700\u5c0f)30s", None))
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("")

View File

@ -225,7 +225,7 @@
</font>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<property name="elideMode">
<enum>Qt::TextElideMode::ElideNone</enum>
@ -702,7 +702,7 @@
<set>Qt::InputMethodHint::ImhNone</set>
</property>
<property name="placeholderText">
<string>每次数据采集的时间间隔,默认(最小)300s</string>
<string>每次数据采集的时间间隔,默认(最小)30s</string>
</property>
</widget>
</item>