完成了电流->转矩的转变,基本完成
This commit is contained in:
parent
7f815ac63e
commit
92bdf133f2
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -6,8 +6,8 @@ VSVersionInfo(
|
|||||||
ffi=FixedFileInfo(
|
ffi=FixedFileInfo(
|
||||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||||
# Set not needed items to zero 0.
|
# Set not needed items to zero 0.
|
||||||
filevers=(0, 3, 0, 0),
|
filevers=(0, 3, 1, 0),
|
||||||
prodvers=(0, 3, 0, 0),
|
prodvers=(0, 3, 1, 0),
|
||||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||||
mask=0x3f,
|
mask=0x3f,
|
||||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||||
@ -31,12 +31,12 @@ VSVersionInfo(
|
|||||||
'040904b0',
|
'040904b0',
|
||||||
[StringStruct('CompanyName', 'Rokae - https://www.rokae.com/'),
|
[StringStruct('CompanyName', 'Rokae - https://www.rokae.com/'),
|
||||||
StringStruct('FileDescription', 'All in one automatic toolbox'),
|
StringStruct('FileDescription', 'All in one automatic toolbox'),
|
||||||
StringStruct('FileVersion', '0.3.0.0 (2025-01-17)'),
|
StringStruct('FileVersion', '0.3.1.0 (2025-01-22)'),
|
||||||
StringStruct('InternalName', 'AIO.exe'),
|
StringStruct('InternalName', 'AIO.exe'),
|
||||||
StringStruct('LegalCopyright', '© 2024-2025 Manford Fan'),
|
StringStruct('LegalCopyright', '© 2024-2025 Manford Fan'),
|
||||||
StringStruct('OriginalFilename', 'AIO.exe'),
|
StringStruct('OriginalFilename', 'AIO.exe'),
|
||||||
StringStruct('ProductName', 'AIO'),
|
StringStruct('ProductName', 'AIO'),
|
||||||
StringStruct('ProductVersion', '0.3.0.0 (2025-01-17)')])
|
StringStruct('ProductVersion', '0.3.1.0 (2025-01-22)')])
|
||||||
]),
|
]),
|
||||||
VarFileInfo([VarStruct('Translation', [1033, 1200])])
|
VarFileInfo([VarStruct('Translation', [1033, 1200])])
|
||||||
]
|
]
|
||||||
|
@ -1 +1 @@
|
|||||||
0.3.0.0@01/17/2025
|
0.3.1.0@01/22/2025
|
164
code/aio.py
164
code/aio.py
@ -13,6 +13,7 @@ import os
|
|||||||
from common import clibs, openapi
|
from common import clibs, openapi
|
||||||
from data_process import current, brake, iso, wavelogger
|
from data_process import current, brake, iso, wavelogger
|
||||||
from automatic_test import do_current, do_brake
|
from automatic_test import do_current, do_brake
|
||||||
|
from durable_docs import factory_test, create_plot
|
||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -38,6 +39,10 @@ class App:
|
|||||||
self.entry_tips_v = None
|
self.entry_tips_v = None
|
||||||
self.server_vers = None
|
self.server_vers = None
|
||||||
self.tv_cols = {1: ["ID", 1], 2: ["time", 160], 3: ["level", 25], 4: ["module", 30], 5: ["content", 700]}
|
self.tv_cols = {1: ["ID", 1], 2: ["time", 160], 3: ["level", 25], 4: ["module", 30], 5: ["content", 700]}
|
||||||
|
self.chk_box_v = ctk.BooleanVar()
|
||||||
|
self.chk_box_v.set(False)
|
||||||
|
self.entry_path_ddv = ctk.StringVar()
|
||||||
|
self.entry_path_ddv.set("数据文件夹路径")
|
||||||
|
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
self.frame_left = ctk.CTkFrame(self.root, width=80, corner_radius=0, fg_color="#E9E9E9")
|
self.frame_left = ctk.CTkFrame(self.root, width=80, corner_radius=0, fg_color="#E9E9E9")
|
||||||
@ -46,6 +51,7 @@ class App:
|
|||||||
self.tabview_top._segmented_button.configure(font=ctk.CTkFont(family="Consolas", size=18, weight="bold"))
|
self.tabview_top._segmented_button.configure(font=ctk.CTkFont(family="Consolas", size=18, weight="bold"))
|
||||||
self.tabview_top.add("数据处理")
|
self.tabview_top.add("数据处理")
|
||||||
self.tabview_top.add("自动测试")
|
self.tabview_top.add("自动测试")
|
||||||
|
self.tabview_top.add("耐久记录")
|
||||||
# -------
|
# -------
|
||||||
self.tabview_bottom = ctk.CTkTabview(self.root, fg_color="#E9E9E9", segmented_button_selected_color="#008B8B", segmented_button_selected_hover_color="#2F4F4F", border_width=2, anchor="w", command=self.__switch_tab_bottom)
|
self.tabview_bottom = ctk.CTkTabview(self.root, fg_color="#E9E9E9", segmented_button_selected_color="#008B8B", segmented_button_selected_hover_color="#2F4F4F", border_width=2, anchor="w", command=self.__switch_tab_bottom)
|
||||||
self.tabview_bottom._segmented_button.configure(font=ctk.CTkFont(family="Consolas", size=18, weight="bold"))
|
self.tabview_bottom._segmented_button.configure(font=ctk.CTkFont(family="Consolas", size=18, weight="bold"))
|
||||||
@ -58,23 +64,25 @@ class App:
|
|||||||
self.btn_start = ctk.CTkButton(self.frame_left, text="开始运行", font=self.f_normal, fg_color="#4F4F4F", command=lambda: self.__thread_it(self.__program_start))
|
self.btn_start = ctk.CTkButton(self.frame_left, text="开始运行", font=self.f_normal, fg_color="#4F4F4F", command=lambda: self.__thread_it(self.__program_start))
|
||||||
self.btn_reset_state = ctk.CTkButton(self.frame_left, text="重置状态", font=self.f_normal, fg_color="#4F4F4F", command=self.__reset_state)
|
self.btn_reset_state = ctk.CTkButton(self.frame_left, text="重置状态", font=self.f_normal, fg_color="#4F4F4F", command=self.__reset_state)
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
self.om_main_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=160, dynamic_resizing=False, values=["brake", "current", "iso", "wavelogger"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D", command=self.__main_switch_dp)
|
self.om_main_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=160, dynamic_resizing=False, values=["brake", "current", "iso", "wavelogger"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090", command=self.__main_switch_dp)
|
||||||
self.om_sub_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=160, dynamic_resizing=False, values=["cycle", "max", "avg"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D")
|
self.om_sub_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=160, dynamic_resizing=False, values=["cycle", "max", "avg"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090")
|
||||||
self.label_path_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="Path", font=self.f_common)
|
self.label_path_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="Path", font=self.f_common)
|
||||||
self.entry_path_dp = ctk.CTkEntry(self.tabview_top.tab("数据处理"), width=80, state="disabled", textvariable=self.entry_path_dpv, font=self.f_entry, text_color="#818181")
|
self.entry_path_dp = ctk.CTkEntry(self.tabview_top.tab("数据处理"), width=80, state="disabled", textvariable=self.entry_path_dpv, font=self.f_entry, text_color="#818181")
|
||||||
self.label_vel_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="Vel", font=self.f_common)
|
self.label_vel_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="Vel", font=self.f_common)
|
||||||
self.om_vel_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", text_color_disabled="#808000")
|
self.om_vel_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090", text_color_disabled="#808000")
|
||||||
self.label_trq_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="Trq", font=self.f_common)
|
self.label_trq_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="Trq", font=self.f_common)
|
||||||
self.om_trq_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", text_color_disabled="#808000")
|
self.om_trq_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090", text_color_disabled="#808000")
|
||||||
self.label_trqh_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="TrqH", font=self.f_common)
|
self.label_trqh_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=40, anchor="e", text="TrqH", font=self.f_common)
|
||||||
self.om_trqh_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", text_color_disabled="#808000")
|
self.om_trqh_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090", text_color_disabled="#808000")
|
||||||
self.label_sensor_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=60, anchor="e", text="Sensor", font=self.f_common)
|
self.label_sensor_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=60, anchor="e", text="Sensor", font=self.f_common)
|
||||||
self.om_sensor_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", text_color_disabled="#808000")
|
self.om_sensor_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090", text_color_disabled="#808000")
|
||||||
self.label_estop_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=60, anchor="e", text="Estop", font=self.f_common)
|
self.label_estop_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=60, anchor="e", text="Estop", font=self.f_common)
|
||||||
self.om_estop_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", text_color_disabled="#808000")
|
self.om_estop_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_common, button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090", text_color_disabled="#808000")
|
||||||
|
self.popupmenu_path_dp = tk.Menu(self.entry_path_dp, tearoff=False)
|
||||||
|
self.popupmenu_path_dp.add_command(label="复制", accelerator="Ctrl+C", font=self.f_treeview, command=lambda: self.__copy_path(self.entry_path_dp))
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
self.om_main_at = ctk.CTkOptionMenu(self.tabview_top.tab("自动测试"), width=160, dynamic_resizing=False, values=["brake", "current"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D")
|
self.om_main_at = ctk.CTkOptionMenu(self.tabview_top.tab("自动测试"), width=160, dynamic_resizing=False, values=["brake", "current"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090")
|
||||||
self.om_sub_at = ctk.CTkOptionMenu(self.tabview_top.tab("自动测试"), width=160, dynamic_resizing=False, values=["tool33", "tool66", "tool100", "inertia"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D")
|
self.om_sub_at = ctk.CTkOptionMenu(self.tabview_top.tab("自动测试"), width=160, dynamic_resizing=False, values=["tool33", "tool66", "tool100", "inertia"], font=self.f_common, text_color="#3C3C3C", button_color="#7B6B5B", fg_color="#8D8D8D", button_hover_color="#708090")
|
||||||
self.label_ip_at = ctk.CTkLabel(self.tabview_top.tab("自动测试"), anchor="e", text="IP", font=self.f_common)
|
self.label_ip_at = ctk.CTkLabel(self.tabview_top.tab("自动测试"), anchor="e", text="IP", font=self.f_common)
|
||||||
self.entry_ip_at = ctk.CTkEntry(self.tabview_top.tab("自动测试"), width=160, textvariable=self.entry_ip_atv, font=self.f_entry, text_color="#818181")
|
self.entry_ip_at = ctk.CTkEntry(self.tabview_top.tab("自动测试"), width=160, textvariable=self.entry_ip_atv, font=self.f_entry, text_color="#818181")
|
||||||
self.btn_conn = ctk.CTkButton(self.tabview_top.tab("自动测试"), text="连接", width=60, font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, cursor="hand2")
|
self.btn_conn = ctk.CTkButton(self.tabview_top.tab("自动测试"), text="连接", width=60, font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, cursor="hand2")
|
||||||
@ -89,16 +97,30 @@ class App:
|
|||||||
self.popupmenu_ip.add_command(label="剪切", accelerator="Ctrl+X", font=self.f_treeview, command=lambda: self.__cut(self.entry_ip_at))
|
self.popupmenu_ip.add_command(label="剪切", accelerator="Ctrl+X", font=self.f_treeview, command=lambda: self.__cut(self.entry_ip_at))
|
||||||
self.popupmenu_ip.add_command(label="粘贴", accelerator="Ctrl+V", font=self.f_treeview, command=lambda: self.__paste(self.entry_ip_at))
|
self.popupmenu_ip.add_command(label="粘贴", accelerator="Ctrl+V", font=self.f_treeview, command=lambda: self.__paste(self.entry_ip_at))
|
||||||
self.popupmenu_ip.add_command(label="全选", accelerator="Ctrl+A", font=self.f_treeview, command=lambda: self.__select(self.entry_ip_at))
|
self.popupmenu_ip.add_command(label="全选", accelerator="Ctrl+A", font=self.f_treeview, command=lambda: self.__select(self.entry_ip_at))
|
||||||
|
self.popupmenu_path_at = tk.Menu(self.entry_path_at, tearoff=False)
|
||||||
|
self.popupmenu_path_at.add_command(label="复制", accelerator="Ctrl+C", font=self.f_treeview, command=lambda: self.__copy_path(self.entry_path_at))
|
||||||
|
# ========================================================================
|
||||||
|
self.scrollable_frame = ctk.CTkScrollableFrame(self.tabview_top.tab("耐久记录"), width=360, height=60, label_text="选择曲线", label_font=self.f_segbtn)
|
||||||
|
self.switch_1 = ctk.CTkSwitch(self.scrollable_frame, text="hw_joint_vel_feedback", font=self.f_treeview, onvalue=True, offvalue=False)
|
||||||
|
self.switch_2 = ctk.CTkSwitch(self.scrollable_frame, text="device_servo_trq_feedback", font=self.f_treeview, onvalue=True, offvalue=False)
|
||||||
|
self.label_path_dd = ctk.CTkLabel(self.tabview_top.tab("耐久记录"), width=80, anchor="e", text="指定路径", font=self.f_segbtn_l)
|
||||||
|
self.entry_path_dd = ctk.CTkEntry(self.tabview_top.tab("耐久记录"), width=80, state="disabled", textvariable=self.entry_path_ddv, font=self.f_entry, text_color="#818181")
|
||||||
|
self.label_interval = ctk.CTkLabel(self.tabview_top.tab("耐久记录"), text="间隔时间", width=80, font=self.f_segbtn_l)
|
||||||
|
self.entry_interval = ctk.CTkEntry(self.tabview_top.tab("耐久记录"), placeholder_text="采样间隔时间,默认(最小)300s", font=self.f_entry)
|
||||||
|
self.btn_plot = ctk.CTkButton(self.tabview_top.tab("耐久记录"), text="绘图", width=80, font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__create_plot)
|
||||||
|
self.chk_box = ctk.CTkCheckBox(self.tabview_top.tab("耐久记录"), text="全部打开/关闭", checkbox_width=15, checkbox_height=15, corner_radius=0, onvalue=True, offvalue=False, variable=self.chk_box_v, width=20, font=self.f_segbtn_l, command=self.__all_or_none)
|
||||||
|
self.popupmenu_path_dd = tk.Menu(self.entry_path_dd, tearoff=False)
|
||||||
|
self.popupmenu_path_dd.add_command(label="复制", accelerator="Ctrl+C", font=self.f_treeview, command=lambda: self.__copy_path(self.entry_path_dd))
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
self.text_output = ctk.CTkTextbox(self.tabview_bottom.tab("输出"), height=10, corner_radius=0, wrap="none", font=self.f_text)
|
self.text_output = ctk.CTkTextbox(self.tabview_bottom.tab("输出"), height=10, corner_radius=0, wrap="none", font=self.f_text)
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
self.label_logs = ctk.CTkLabel(self.tabview_bottom.tab("日志"), width=80, font=self.f_pager, textvariable=self.label_pages_logs, text_color="blue", bg_color="#DCDCDC", cursor="hand2")
|
self.label_logs = ctk.CTkLabel(self.tabview_bottom.tab("日志"), width=100, font=self.f_pager, textvariable=self.label_pages_logs, text_color="blue", bg_color="#DCDCDC", cursor="hand2")
|
||||||
self.btn_previous = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="上一页", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__get_previous_log)
|
self.btn_previous = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="上一页", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__get_previous_log)
|
||||||
self.btn_realtime = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="实时", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__get_realtime_log)
|
self.btn_realtime = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="实时", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__get_realtime_log)
|
||||||
self.btn_next = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="下一页", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__get_next_log)
|
self.btn_next = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="下一页", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__get_next_log)
|
||||||
self.btn_load = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="加载", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__load_log_db)
|
self.btn_load = ctk.CTkButton(self.tabview_bottom.tab("日志"), width=60, text="加载", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__load_log_db)
|
||||||
self.btn_find = ctk.CTkButton(self.tabview_bottom.tab("日志"), text="查找", width=60, font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, cursor="hand2")
|
self.btn_find = ctk.CTkButton(self.tabview_bottom.tab("日志"), text="查找", width=60, font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, cursor="hand2")
|
||||||
self.entry_keyword = ctk.CTkEntry(self.tabview_bottom.tab("日志"), placeholder_text="[id/level/module] 查找内容", width=60, font=self.f_entry)
|
self.entry_keyword = ctk.CTkEntry(self.tabview_bottom.tab("日志"), placeholder_text="[id/level/module] 查找内容", width=10, font=self.f_entry)
|
||||||
self.treeview_logs = ttk.Treeview(self.tabview_bottom.tab("日志"), height=1, columns=("id", "time", "level", "module", "content"), style="tv.Treeview", show="headings")
|
self.treeview_logs = ttk.Treeview(self.tabview_bottom.tab("日志"), height=1, columns=("id", "time", "level", "module", "content"), style="tv.Treeview", show="headings")
|
||||||
self.y_scrollbar_logs = tk.Scrollbar(self.tabview_bottom.tab("日志"), width=30, command=self.treeview_logs.yview)
|
self.y_scrollbar_logs = tk.Scrollbar(self.tabview_bottom.tab("日志"), width=30, command=self.treeview_logs.yview)
|
||||||
self.popupmenu_kw = tk.Menu(self.entry_keyword, tearoff=False)
|
self.popupmenu_kw = tk.Menu(self.entry_keyword, tearoff=False)
|
||||||
@ -140,6 +162,29 @@ class App:
|
|||||||
def __do_nothing(event):
|
def __do_nothing(event):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __create_plot():
|
||||||
|
create_plot.main()
|
||||||
|
|
||||||
|
def __all_or_none(self):
|
||||||
|
if self.chk_box_v.get():
|
||||||
|
for widget in self.scrollable_frame.winfo_children():
|
||||||
|
widget.select()
|
||||||
|
else:
|
||||||
|
for widget in self.scrollable_frame.winfo_children():
|
||||||
|
widget.deselect()
|
||||||
|
|
||||||
|
def __get_curve_names(self):
|
||||||
|
curves = []
|
||||||
|
for widget in self.scrollable_frame.winfo_children():
|
||||||
|
if widget.get():
|
||||||
|
curves.append(widget.cget("text"))
|
||||||
|
return curves
|
||||||
|
|
||||||
|
def __copy_path(self, widget):
|
||||||
|
self.root.clipboard_clear()
|
||||||
|
self.root.clipboard_append(widget.get())
|
||||||
|
|
||||||
def __detect_network(self):
|
def __detect_network(self):
|
||||||
def func_access(state):
|
def func_access(state):
|
||||||
self.btn_robot_info.configure(state=state)
|
self.btn_robot_info.configure(state=state)
|
||||||
@ -157,12 +202,12 @@ class App:
|
|||||||
except Exception:
|
except Exception:
|
||||||
self.btn_conn.configure(fg_color="#979DA2")
|
self.btn_conn.configure(fg_color="#979DA2")
|
||||||
func_access("disabled")
|
func_access("disabled")
|
||||||
time.sleep(3)
|
time.sleep(2)
|
||||||
|
|
||||||
def __robot_info(self):
|
def __robot_info(self):
|
||||||
def get_robot_info():
|
def get_robot_info():
|
||||||
self.tabview_bottom.set("输出")
|
self.tabview_bottom.set("输出")
|
||||||
self.text_output.delete("1.0", "end")
|
# self.text_output.delete("1.0", "end")
|
||||||
self.__w2t("正在获取机器信息,请稍后...\n\n")
|
self.__w2t("正在获取机器信息,请稍后...\n\n")
|
||||||
infos = {0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}, 8: {}, 9: {}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}, 15: {}, 16: {}, 17: {}, 18: {}, 19: {}, 20: {}}
|
infos = {0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}, 8: {}, 9: {}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}, 15: {}, 16: {}, 17: {}, 18: {}, 19: {}, 20: {}}
|
||||||
msg_id, state = clibs.c_hr.execution("controller.get_params")
|
msg_id, state = clibs.c_hr.execution("controller.get_params")
|
||||||
@ -229,17 +274,23 @@ class App:
|
|||||||
def __trig_estop(self):
|
def __trig_estop(self):
|
||||||
def trig_estop():
|
def trig_estop():
|
||||||
self.tabview_bottom.set("输出")
|
self.tabview_bottom.set("输出")
|
||||||
self.text_output.delete("1.0", "end")
|
|
||||||
self.__w2t("触发软急停信号已发送...\n")
|
self.__w2t("触发软急停信号已发送...\n")
|
||||||
clibs.c_md.r_soft_estop(0)
|
clibs.c_md.r_soft_estop(0)
|
||||||
clibs.running = False
|
try:
|
||||||
raise Exception("StopProcRunning")
|
clibs.c_hr.execution("diagnosis.open", open=False, display_open=False, overrun=True, turn_area=True, delay_motion=False)
|
||||||
|
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=[], frequency=50, version="1.4.1")
|
||||||
|
except Exception as Err:
|
||||||
|
clibs.insert_logdb("WARNING", "aio", f"关闭诊断曲线失败 - {Err}")
|
||||||
|
if clibs.running:
|
||||||
|
clibs.running = False
|
||||||
|
self.__w2t("程序已停止运行,执行过程中停止时需要清零后台数据,大约一分钟左右后再重新运行!!!\n", "red", "TerminateProgram")
|
||||||
|
|
||||||
self.__thread_it(trig_estop)
|
self.__thread_it(trig_estop)
|
||||||
|
|
||||||
def __reset_estop(self):
|
def __reset_estop(self):
|
||||||
def reset_estop():
|
def reset_estop():
|
||||||
self.tabview_bottom.set("输出")
|
self.tabview_bottom.set("输出")
|
||||||
self.text_output.delete("1.0", "end")
|
# self.text_output.delete("1.0", "end")
|
||||||
self.__w2t("解除软急停信号已发送...\n")
|
self.__w2t("解除软急停信号已发送...\n")
|
||||||
clibs.c_md.r_soft_estop(1)
|
clibs.c_md.r_soft_estop(1)
|
||||||
clibs.c_md.r_clear_alarm()
|
clibs.c_md.r_clear_alarm()
|
||||||
@ -322,6 +373,14 @@ class App:
|
|||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def get_data_dd():
|
||||||
|
data = {
|
||||||
|
"path": self.entry_path_ddv.get(),
|
||||||
|
"interval": self.entry_interval.get(),
|
||||||
|
"curves": self.__get_curve_names()
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
def init_op():
|
def init_op():
|
||||||
if self.__is_running("开始") == "running":
|
if self.__is_running("开始") == "running":
|
||||||
return "running"
|
return "running"
|
||||||
@ -342,22 +401,22 @@ class App:
|
|||||||
if init_op() == "running":
|
if init_op() == "running":
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.tabview_top.get() == "数据处理":
|
clibs.running = True
|
||||||
clibs.running = True
|
try:
|
||||||
clibs.data_dp = get_data_dp()
|
if self.tabview_top.get() == "数据处理":
|
||||||
try:
|
clibs.data_dp = get_data_dp()
|
||||||
eval(clibs.data_dp["_main"] + ".main()")
|
eval(clibs.data_dp["_main"] + ".main()")
|
||||||
finally:
|
elif self.tabview_top.get() == "自动测试":
|
||||||
clibs.running = False
|
clibs.data_at = get_data_at()
|
||||||
clibs.stop = False
|
|
||||||
elif self.tabview_top.get() == "自动测试":
|
|
||||||
clibs.running = True
|
|
||||||
clibs.data_at = get_data_at()
|
|
||||||
try:
|
|
||||||
eval("do_" + clibs.data_at["_main"] + ".main()")
|
eval("do_" + clibs.data_at["_main"] + ".main()")
|
||||||
finally:
|
elif self.tabview_top.get() == "耐久记录":
|
||||||
clibs.running = False
|
clibs.data_dd = get_data_dd()
|
||||||
clibs.stop = False
|
factory_test.main()
|
||||||
|
except Exception as Err:
|
||||||
|
self.__w2t(f"程序执行过程中出现异常,{Err}\n", "red")
|
||||||
|
finally:
|
||||||
|
clibs.running = False
|
||||||
|
clibs.stop = False
|
||||||
|
|
||||||
exec_function()
|
exec_function()
|
||||||
|
|
||||||
@ -593,6 +652,7 @@ class App:
|
|||||||
self.f_logo = ("Segoe Script Bold", 28, "bold")
|
self.f_logo = ("Segoe Script Bold", 28, "bold")
|
||||||
self.f_normal = ("Consolas", 20, "bold")
|
self.f_normal = ("Consolas", 20, "bold")
|
||||||
self.f_segbtn = ("楷体", 20, "bold")
|
self.f_segbtn = ("楷体", 20, "bold")
|
||||||
|
self.f_segbtn_l = ("楷体", 18, "bold")
|
||||||
self.f_common = ("Consolas", 18, "bold")
|
self.f_common = ("Consolas", 18, "bold")
|
||||||
self.f_entry = ("Consolas", 16, "bold")
|
self.f_entry = ("Consolas", 16, "bold")
|
||||||
self.f_text = ("仿宋", 16, "normal")
|
self.f_text = ("仿宋", 16, "normal")
|
||||||
@ -643,11 +703,17 @@ class App:
|
|||||||
self.__quit_preparation()
|
self.__quit_preparation()
|
||||||
|
|
||||||
def __switch_tab_top(self):
|
def __switch_tab_top(self):
|
||||||
...
|
tab_name = self.tabview_top.get()
|
||||||
|
if tab_name == "数据处理" or tab_name == "自动测试":
|
||||||
|
self.tabview_top.configure(height=180)
|
||||||
|
elif tab_name == "耐久记录":
|
||||||
|
self.tabview_top.configure(height=330)
|
||||||
|
|
||||||
def __switch_tab_bottom(self):
|
def __switch_tab_bottom(self):
|
||||||
if self.tabview_bottom.get() == "日志":
|
if self.tabview_bottom.get() == "日志":
|
||||||
self.__get_realtime_log()
|
self.__get_realtime_log()
|
||||||
|
elif self.tabview_bottom.get() == "输出":
|
||||||
|
self.text_output.see(ctk.END)
|
||||||
|
|
||||||
def __cut(self, widget):
|
def __cut(self, widget):
|
||||||
try:
|
try:
|
||||||
@ -704,6 +770,12 @@ class App:
|
|||||||
self.entry_path_atv.set(dir_path)
|
self.entry_path_atv.set(dir_path)
|
||||||
else:
|
else:
|
||||||
self.entry_path_atv.set(c_origin)
|
self.entry_path_atv.set(c_origin)
|
||||||
|
elif t_name == "耐久记录":
|
||||||
|
c_origin = self.entry_path_ddv.get()
|
||||||
|
if dir_path:
|
||||||
|
self.entry_path_ddv.set(dir_path)
|
||||||
|
else:
|
||||||
|
self.entry_path_ddv.set(c_origin)
|
||||||
|
|
||||||
def esc_quit_log_tl(event):
|
def esc_quit_log_tl(event):
|
||||||
widget_toplevel = event.widget
|
widget_toplevel = event.widget
|
||||||
@ -973,6 +1045,14 @@ class App:
|
|||||||
def show_popupmenu_output(event):
|
def show_popupmenu_output(event):
|
||||||
self.popupmenu_output.post(event.x_root, event.y_root)
|
self.popupmenu_output.post(event.x_root, event.y_root)
|
||||||
|
|
||||||
|
def show_popupmenu_path(event):
|
||||||
|
if self.tabview_top.get() == "数据处理":
|
||||||
|
self.popupmenu_path_dp.post(event.x_root, event.y_root)
|
||||||
|
elif self.tabview_top.get() == "自动测试":
|
||||||
|
self.popupmenu_path_at.post(event.x_root, event.y_root)
|
||||||
|
elif self.tabview_top.get() == "耐久记录":
|
||||||
|
self.popupmenu_path_dd.post(event.x_root, event.y_root)
|
||||||
|
|
||||||
def conn_change(event):
|
def conn_change(event):
|
||||||
def conn_or_disconn():
|
def conn_or_disconn():
|
||||||
if self.btn_conn.cget("fg_color") == "#979DA2":
|
if self.btn_conn.cget("fg_color") == "#979DA2":
|
||||||
@ -987,9 +1067,6 @@ class App:
|
|||||||
clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
|
clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
|
||||||
clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port)
|
clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port)
|
||||||
clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
|
clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
|
||||||
|
|
||||||
# clibs.c_md.write_speed_max(123.456)
|
|
||||||
# clibs.c_hr.execution('state.set_tp_mode', tp_mode='without')
|
|
||||||
self.btn_conn.configure(state="normal", fg_color="#2E8B57")
|
self.btn_conn.configure(state="normal", fg_color="#2E8B57")
|
||||||
except Exception:
|
except Exception:
|
||||||
self.btn_conn.configure(state="normal", fg_color="#979DA2")
|
self.btn_conn.configure(state="normal", fg_color="#979DA2")
|
||||||
@ -1052,6 +1129,7 @@ class App:
|
|||||||
self.om_sensor_dp.grid(row=1, column=10, padx=(0, 10), pady=(0, 10))
|
self.om_sensor_dp.grid(row=1, column=10, padx=(0, 10), pady=(0, 10))
|
||||||
|
|
||||||
self.entry_path_dp.bind("<Button-1>", select_path)
|
self.entry_path_dp.bind("<Button-1>", select_path)
|
||||||
|
self.entry_path_dp.bind("<Button-3>", show_popupmenu_path, add="+")
|
||||||
self.om_vel_dp.set("1")
|
self.om_vel_dp.set("1")
|
||||||
self.om_trq_dp.set("2")
|
self.om_trq_dp.set("2")
|
||||||
self.om_trqh_dp.set("2")
|
self.om_trqh_dp.set("2")
|
||||||
@ -1072,13 +1150,27 @@ class App:
|
|||||||
self.btn_trig_estop.grid(row=0, column=1, padx=(0, 10), pady=0)
|
self.btn_trig_estop.grid(row=0, column=1, padx=(0, 10), pady=0)
|
||||||
self.btn_reset_estop.grid(row=0, column=2, padx=(0, 10), pady=0)
|
self.btn_reset_estop.grid(row=0, column=2, padx=(0, 10), pady=0)
|
||||||
|
|
||||||
# self.om_main_at.bind("<<ComboboxSelected>>", change_sub_at)
|
|
||||||
self.om_main_at.bind("<Button-1>", change_sub_at)
|
self.om_main_at.bind("<Button-1>", change_sub_at)
|
||||||
self.entry_path_at.bind("<Button-1>", select_path)
|
self.entry_path_at.bind("<Button-1>", select_path)
|
||||||
|
self.entry_path_at.bind("<Button-3>", show_popupmenu_path, add="+")
|
||||||
self.entry_ip_at.bind("<Button-3>", show_popupmenu_ip, add="+")
|
self.entry_ip_at.bind("<Button-3>", show_popupmenu_ip, add="+")
|
||||||
self.btn_conn.bind("<Button-1>", conn_change)
|
self.btn_conn.bind("<Button-1>", conn_change)
|
||||||
self.btn_conn.bind("<Double-1>", self.__do_nothing, add="+")
|
self.btn_conn.bind("<Double-1>", self.__do_nothing, add="+")
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
|
self.tabview_top.tab("耐久记录").grid_columnconfigure(2, weight=1)
|
||||||
|
self.scrollable_frame.grid(row=0, column=0, rowspan=30, padx=10, pady=0)
|
||||||
|
self.switch_1.grid(row=0, column=0, padx=10, sticky="w")
|
||||||
|
self.switch_2.grid(row=1, column=0, padx=10, sticky="w")
|
||||||
|
self.label_path_dd.grid(row=0, column=1, padx=10, pady=0, sticky="w")
|
||||||
|
self.entry_path_dd.grid(row=0, column=2, padx=(0, 10), pady=0, sticky="we")
|
||||||
|
self.label_interval.grid(row=1, column=1, padx=10, pady=0, sticky="w")
|
||||||
|
self.entry_interval.grid(row=1, column=2, padx=(0, 10), pady=0, sticky="we")
|
||||||
|
self.btn_plot.grid(row=2, column=1, padx=10, pady=(5, 0), sticky="w")
|
||||||
|
self.chk_box.grid(row=2, column=2, padx=(0, 10), pady=(5, 0), sticky="e")
|
||||||
|
|
||||||
|
self.entry_path_dd.bind("<Button-1>", select_path)
|
||||||
|
self.entry_path_dd.bind("<Button-3>", show_popupmenu_path, add="+")
|
||||||
|
# ========================================================================
|
||||||
self.tabview_bottom.tab("输出").grid_rowconfigure(0, weight=1)
|
self.tabview_bottom.tab("输出").grid_rowconfigure(0, weight=1)
|
||||||
self.tabview_bottom.tab("输出").grid_columnconfigure(0, weight=1)
|
self.tabview_bottom.tab("输出").grid_columnconfigure(0, weight=1)
|
||||||
self.text_output.grid(row=0, column=0, sticky="news")
|
self.text_output.grid(row=0, column=0, sticky="news")
|
||||||
|
@ -10,7 +10,7 @@ from common import clibs, openapi
|
|||||||
|
|
||||||
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
||||||
def check_files():
|
def check_files():
|
||||||
msg = "初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!\n"
|
msg = "初始路径下不允许有文件夹,初始路径下只能存在如下五个文件,且文件为关闭状态,确认后重新运行!\n"
|
||||||
msg += "1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n"
|
msg += "1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n"
|
||||||
if len(data_dirs) != 0 or len(data_files) != 5:
|
if len(data_dirs) != 0 or len(data_files) != 5:
|
||||||
w2t(msg, "red", "InitFileError")
|
w2t(msg, "red", "InitFileError")
|
||||||
@ -130,16 +130,19 @@ def gen_result_file(path, axis, t_end, reach, load, speed, speed_target, rounds,
|
|||||||
df.to_csv(filename, sep="\t", index=False)
|
df.to_csv(filename, sep="\t", index=False)
|
||||||
|
|
||||||
|
|
||||||
def change_curve_state(hr, stat_1, stat_2):
|
def change_curve_state(hr, stat):
|
||||||
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback"] for chl in range(6)]
|
if not stat:
|
||||||
display_pdo_params.append({"name": "device_safety_estop", "channel": 0})
|
display_pdo_params = []
|
||||||
hr.execution("diagnosis.open", open=stat_1, display_open=stat_2, overrun=True, turn_area=True, delay_motion=False)
|
else:
|
||||||
|
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback"] for chl in range(6)]
|
||||||
|
display_pdo_params.append({"name": "device_safety_estop", "channel": 0})
|
||||||
|
hr.execution("diagnosis.open", open=stat, display_open=stat, overrun=True, turn_area=True, delay_motion=False)
|
||||||
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
||||||
|
|
||||||
|
|
||||||
def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
||||||
count, total, speed_target = 0, 63, 0
|
count, total, speed_target = 0, 63, 0
|
||||||
prj_name = prj_file.split("/")[-1].split(".")[0]
|
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
|
||||||
wb = openpyxl.load_workbook(config_file, read_only=True)
|
wb = openpyxl.load_workbook(config_file, read_only=True)
|
||||||
ws = wb["Target"]
|
ws = wb["Target"]
|
||||||
write_diagnosis = float(ws.cell(row=2, column=2).value)
|
write_diagnosis = float(ws.cell(row=2, column=2).value)
|
||||||
@ -171,6 +174,10 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for axis in range(1, 4):
|
for axis in range(1, 4):
|
||||||
|
if not clibs.running:
|
||||||
|
w2t("后台数据清零完成,现在可以重新运行之前停止的程序。", "red")
|
||||||
|
exit()
|
||||||
|
|
||||||
# for single condition test
|
# for single condition test
|
||||||
if (single_axis != -1 and single_axis != axis) or (axis == 3 and reach != "100"):
|
if (single_axis != -1 and single_axis != axis) or (axis == 3 and reach != "100"):
|
||||||
continue
|
continue
|
||||||
@ -231,16 +238,16 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if (time.time() - t_start) > 20:
|
if (time.time() - t_start) > 3:
|
||||||
w2t("20s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
w2t("3s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
||||||
time.sleep(5) # 消除前 5s 的不稳定数据
|
time.sleep(5) # 消除前 5s 的不稳定数据
|
||||||
change_curve_state(hr, True, True)
|
change_curve_state(hr, True)
|
||||||
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
time.sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度,可通过configs.xlsx配置
|
time.sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度,可通过configs.xlsx配置
|
||||||
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
hr.execution("rl_task.stop", tasks=["brake"])
|
hr.execution("rl_task.stop", tasks=["brake"])
|
||||||
change_curve_state(hr, False, False)
|
change_curve_state(hr, False)
|
||||||
|
|
||||||
# 找出最大速度
|
# 找出最大速度
|
||||||
@clibs.db_lock
|
@clibs.db_lock
|
||||||
@ -297,7 +304,7 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
|
|
||||||
def exec_brake():
|
def exec_brake():
|
||||||
flag, start, data, record = True, time.time(), None, None
|
flag, start, data, record = True, time.time(), None, None
|
||||||
change_curve_state(hr, True, True)
|
change_curve_state(hr, True)
|
||||||
while flag:
|
while flag:
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
if time.time() - start > 20:
|
if time.time() - start > 20:
|
||||||
@ -320,7 +327,7 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
if (pon == "positive" and speed_moment > 0) or (pon == "negative" and speed_moment < 0):
|
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.setdo_value(io_name, "false")
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
change_curve_state(hr, False, False)
|
change_curve_state(hr, False)
|
||||||
flag = False
|
flag = False
|
||||||
return time.time()
|
return time.time()
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from common import clibs
|
|||||||
|
|
||||||
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
||||||
def check_files():
|
def check_files():
|
||||||
msg = "初始路径下不允许有文件夹,且初始路径下只能存在如下两个文件,确认后重新运行!\n"
|
msg = "初始路径下不允许有文件夹,初始路径下只能存在如下两个文件,且文件为关闭状态,确认后重新运行!\n"
|
||||||
msg += "1. T_电机电流.xlsx\n2. xxxx.zip\n"
|
msg += "1. T_电机电流.xlsx\n2. xxxx.zip\n"
|
||||||
if len(data_dirs) != 0 or len(data_files) != 2:
|
if len(data_dirs) != 0 or len(data_files) != 2:
|
||||||
w2t(msg, "red", "InitFileError")
|
w2t(msg, "red", "InitFileError")
|
||||||
@ -60,7 +60,7 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
|||||||
def single_axis_proc(path, records, number):
|
def single_axis_proc(path, records, number):
|
||||||
text = "single" if number < 6 else "hold"
|
text = "single" if number < 6 else "hold"
|
||||||
number = number if number < 6 else number - 6
|
number = number if number < 6 else number - 6
|
||||||
d_vel, d_trq, d_sensor = [], [], []
|
d_vel, d_trq, d_sensor, d_trans = [], [], [], []
|
||||||
for record in records:
|
for record in records:
|
||||||
data = eval(record[0])["data"]
|
data = eval(record[0])["data"]
|
||||||
for item in data:
|
for item in data:
|
||||||
@ -71,33 +71,40 @@ def single_axis_proc(path, records, number):
|
|||||||
d_trq.extend(d_item)
|
d_trq.extend(d_item)
|
||||||
elif item.get("channel", None) == number and item.get("name", None) == "hw_sensor_trq_feedback":
|
elif item.get("channel", None) == number and item.get("name", None) == "hw_sensor_trq_feedback":
|
||||||
d_sensor.extend(d_item)
|
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)
|
||||||
|
|
||||||
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
||||||
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
||||||
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
|
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
|
||||||
df = pandas.concat([df1, df2, df3], axis=1)
|
df4 = pandas.DataFrame.from_dict({"hw_estimate_trans_trq_res": d_trans})
|
||||||
|
df = pandas.concat([df1, df2, df3, df4], axis=1)
|
||||||
filename = f"{path}/single/j{number + 1}_{text}_{time.time()}.data"
|
filename = f"{path}/single/j{number + 1}_{text}_{time.time()}.data"
|
||||||
df.to_csv(filename, sep="\t", index=False)
|
df.to_csv(filename, sep="\t", index=False)
|
||||||
|
|
||||||
|
|
||||||
def scenario_proc(path, records, number, scenario_time):
|
def scenario_proc(path, records, number, scenario_time):
|
||||||
for axis in range(6):
|
d_vel, d_trq, d_sensor, d_trans = [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []]
|
||||||
d_vel, d_trq, d_sensor = [], [], []
|
for record in records:
|
||||||
for record in records:
|
data = eval(record[0])["data"]
|
||||||
data = eval(record[0])["data"]
|
for item in data:
|
||||||
for item in data:
|
d_item = reversed(item["value"])
|
||||||
d_item = reversed(item["value"])
|
for axis in range(6):
|
||||||
if item.get("channel", None) == axis and item.get("name", None) == "hw_joint_vel_feedback":
|
if item.get("channel", None) == axis and item.get("name", None) == "hw_joint_vel_feedback":
|
||||||
d_vel.extend(d_item)
|
d_vel[axis].extend(d_item)
|
||||||
elif item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
|
elif item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
|
||||||
d_trq.extend(d_item)
|
d_trq[axis].extend(d_item)
|
||||||
elif item.get("channel", None) == axis and item.get("name", None) == "hw_sensor_trq_feedback":
|
elif item.get("channel", None) == axis and item.get("name", None) == "hw_sensor_trq_feedback":
|
||||||
d_sensor.extend(d_item)
|
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)
|
||||||
|
|
||||||
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
for axis in range(6):
|
||||||
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel[axis]})
|
||||||
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
|
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq[axis]})
|
||||||
df = pandas.concat([df1, df2, df3], axis=1)
|
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)
|
||||||
filename = f"{path}/s_{number-11}/j{axis+1}_s_{number-11}_{scenario_time}_{time.time()}.data"
|
filename = f"{path}/s_{number-11}/j{axis+1}_s_{number-11}_{scenario_time}_{time.time()}.data"
|
||||||
df.to_csv(filename, sep="\t", index=False)
|
df.to_csv(filename, sep="\t", index=False)
|
||||||
|
|
||||||
@ -121,14 +128,15 @@ def gen_result_file(path, number, start_time, end_time, scenario_time):
|
|||||||
p.start()
|
p.start()
|
||||||
|
|
||||||
|
|
||||||
def change_curve_state(hr, stat_1, stat_2):
|
def change_curve_state(hr, stat):
|
||||||
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback"] for chl in range(6)]
|
curves = ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback", "hw_estimate_trans_trq_res"]
|
||||||
hr.execution("diagnosis.open", open=stat_1, display_open=stat_2, overrun=True, turn_area=True, delay_motion=False)
|
display_pdo_params = [] if not stat else [{"name": curve, "channel": chl} for curve in curves for chl in range(6)]
|
||||||
|
hr.execution("diagnosis.open", open=stat, display_open=stat, overrun=True, turn_area=True, delay_motion=False)
|
||||||
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
||||||
|
|
||||||
|
|
||||||
def run_rl(path, prj_file, hr, md, sub, w2t):
|
def run_rl(path, prj_file, hr, md, sub, w2t):
|
||||||
prj_name = prj_file.split("/")[-1].split(".")[0]
|
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
|
||||||
c_regular = [
|
c_regular = [
|
||||||
"scenario(0, j1_p, j1_n, p_speed, p_tool, i_tool)",
|
"scenario(0, j1_p, j1_n, p_speed, p_tool, i_tool)",
|
||||||
"scenario(0, j2_p, j2_n, p_speed, p_tool, i_tool)",
|
"scenario(0, j2_p, j2_n, p_speed, p_tool, i_tool)",
|
||||||
@ -165,6 +173,10 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
|
|||||||
md.r_clear_alarm()
|
md.r_clear_alarm()
|
||||||
|
|
||||||
for condition in conditions:
|
for condition in conditions:
|
||||||
|
if not clibs.running:
|
||||||
|
w2t("后台数据清零完成,现在可以重新运行之前停止的程序。", "red")
|
||||||
|
exit()
|
||||||
|
|
||||||
number = conditions.index(condition)
|
number = conditions.index(condition)
|
||||||
w2t(f"正在执行{disc[number]}测试......\n")
|
w2t(f"正在执行{disc[number]}测试......\n")
|
||||||
|
|
||||||
@ -198,12 +210,12 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if (time.time() - t_start) > 20:
|
if (time.time() - t_start) > 3:
|
||||||
w2t("20s 内未收到机器人的运行信号,需要确认RL程序和工具通信是否正常执行...", "red", "ReadySignalTimeoutError")
|
w2t("3s 内未收到机器人的运行信号,需要确认RL程序和工具通信是否正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
|
|
||||||
# 4. 执行采集
|
# 4. 执行采集
|
||||||
time.sleep(10) # 消除前 10s 的不稳定数据
|
time.sleep(10) # 消除前 10s 的不稳定数据
|
||||||
change_curve_state(hr, True, True)
|
change_curve_state(hr, True)
|
||||||
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
single_time, stall_time, scenario_time = 40, 10, 0
|
single_time, stall_time, scenario_time = 40, 10, 0
|
||||||
if number < 6: # 单轴
|
if number < 6: # 单轴
|
||||||
@ -227,7 +239,7 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
|
|||||||
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
hr.execution("rl_task.stop", tasks=["current"])
|
hr.execution("rl_task.stop", tasks=["current"])
|
||||||
time.sleep(2) # 确保数据都拿到
|
time.sleep(2) # 确保数据都拿到
|
||||||
change_curve_state(hr, False, False)
|
change_curve_state(hr, False)
|
||||||
gen_result_file(path, number, start_time, end_time, scenario_time)
|
gen_result_file(path, number, start_time, end_time, scenario_time)
|
||||||
else:
|
else:
|
||||||
if sub == "tool100":
|
if sub == "tool100":
|
||||||
@ -252,7 +264,7 @@ def main():
|
|||||||
e_time = time.time()
|
e_time = time.time()
|
||||||
time_total = e_time - s_time
|
time_total = e_time - s_time
|
||||||
w2t(f"-" * 90 + "\n", "purple")
|
w2t(f"-" * 90 + "\n", "purple")
|
||||||
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", "green")
|
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n", "green")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -66,42 +66,12 @@ def insert_logdb(_level, _module, _content):
|
|||||||
cursor.execute("insert into logs (level, module, content) values (?, ?, ?)", data)
|
cursor.execute("insert into logs (level, module, content) values (?, ?, ?)", data)
|
||||||
|
|
||||||
|
|
||||||
def insert_logdb_multi(data):
|
|
||||||
if db_state == "readwrite":
|
|
||||||
global conn, cursor, lock
|
|
||||||
# data = [_level, _module, repr(_content)]
|
|
||||||
# cursor.execute("insert into logs (level, module, content) values (?, ?, ?)", data)
|
|
||||||
try:
|
|
||||||
lock.acquire(True)
|
|
||||||
cursor.executemany("insert into logs (level, module, content) values (?, ?, ?)", data)
|
|
||||||
finally:
|
|
||||||
lock.release()
|
|
||||||
|
|
||||||
|
|
||||||
class GetThreadResult(threading.Thread):
|
|
||||||
def __init__(self, func, args=()):
|
|
||||||
super(GetThreadResult, self).__init__()
|
|
||||||
self.func = func
|
|
||||||
self.args = args
|
|
||||||
self.result = None
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.result = self.func(*self.args)
|
|
||||||
|
|
||||||
def get_result(self):
|
|
||||||
threading.Thread.join(self) # 等待线程执行完毕
|
|
||||||
try:
|
|
||||||
return self.result
|
|
||||||
except Exception:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# PREFIX = 'assets' # for pyinstaller packaging
|
# PREFIX = 'assets' # for pyinstaller packaging
|
||||||
PREFIX = '../assets' # for source code testing and debug
|
PREFIX = '../assets' # for source code testing and debug
|
||||||
log_path = f"{PREFIX}/logs"
|
log_path = f"{PREFIX}/logs"
|
||||||
levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
|
levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
|
||||||
db_state = "readwrite"
|
db_state = "readwrite"
|
||||||
data_dp, data_at = {}, {}
|
data_dp, data_at, data_dd = {}, {}, {}
|
||||||
conn, cursor, w2t, tl_prg, f_records, stop, running = None, None, None, None, None, True, False
|
conn, cursor, w2t, tl_prg, f_records, stop, running = None, None, None, None, None, True, False
|
||||||
|
|
||||||
ip_addr = "192.168.0.160"
|
ip_addr = "192.168.0.160"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
import inspect
|
|
||||||
from inspect import currentframe
|
from inspect import currentframe
|
||||||
import threading
|
import threading
|
||||||
import functools
|
import functools
|
||||||
@ -10,9 +9,6 @@ import selectors
|
|||||||
import time
|
import time
|
||||||
from common import clibs
|
from common import clibs
|
||||||
|
|
||||||
from os import listdir
|
|
||||||
from pymodbus.payload import BinaryPayloadBuilder
|
|
||||||
from pymodbus.constants import Endian
|
|
||||||
import os.path
|
import os.path
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
import hashlib
|
import hashlib
|
||||||
@ -161,12 +157,12 @@ class ModbusRequest(object):
|
|||||||
clibs.insert_logdb("INFO", "openapi", f"modbus: 40102 将 {pon} 写入")
|
clibs.insert_logdb("INFO", "openapi", f"modbus: 40102 将 {pon} 写入")
|
||||||
|
|
||||||
def write_axis(self, axis):
|
def write_axis(self, axis):
|
||||||
result = self.__c.convert_to_registers(int(axis), self.__c.DATATYPE.INT32, word_order="little")
|
result = self.__c.convert_to_registers(int(axis), self.__c.DATATYPE.INT32, "little")
|
||||||
self.__c.write_registers(40103, result)
|
self.__c.write_registers(40103, result)
|
||||||
clibs.insert_logdb("INFO", "openapi", f"modbus: 40103 将 {axis} 写入")
|
clibs.insert_logdb("INFO", "openapi", f"modbus: 40103 将 {axis} 写入")
|
||||||
|
|
||||||
def write_speed_max(self, speed):
|
def write_speed_max(self, speed):
|
||||||
result = self.__c.convert_to_registers(float(speed), self.__c.DATATYPE.FLOAT32, word_order="little")
|
result = self.__c.convert_to_registers(float(speed), self.__c.DATATYPE.FLOAT32, "little")
|
||||||
self.__c.write_registers(40105, result)
|
self.__c.write_registers(40105, result)
|
||||||
clibs.insert_logdb("INFO", "openapi", f"modbus: 40105 将 {speed} 写入")
|
clibs.insert_logdb("INFO", "openapi", f"modbus: 40105 将 {speed} 写入")
|
||||||
|
|
||||||
@ -315,7 +311,7 @@ class ModbusRequest(object):
|
|||||||
|
|
||||||
def read_scenario_time(self):
|
def read_scenario_time(self):
|
||||||
results = self.__c.read_holding_registers(40601, count=2)
|
results = self.__c.read_holding_registers(40601, count=2)
|
||||||
result = self.__c.convert_from_registers(results.registers, data_type=self.__c.DATATYPE.FLOAT32, word_order="little")
|
result = self.__c.convert_from_registers(registers=results.registers, data_type=self.__c.DATATYPE.FLOAT32, word_order="little")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def read_brake_done(self):
|
def read_brake_done(self):
|
||||||
@ -750,7 +746,7 @@ class HmiRequest(object):
|
|||||||
req = json.load(f_json)
|
req = json.load(f_json)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.insert_logdb("ERROR", "openapi", f"hr-execution: 暂不支持 {command} 功能,或确认该功能存在... {Err}")
|
clibs.insert_logdb("ERROR", "openapi", f"hr-execution: 暂不支持 {command} 功能,或确认该功能存在... {Err}")
|
||||||
clibs.w2t(f"hr-execution: 暂不支持 {command} 功能,或确认该功能存在... {Err}", "red")
|
clibs.w2t(f"hr-execution: 暂不支持 {command} 功能,或确认该功能存在... {Err}", "red", "CommandError")
|
||||||
|
|
||||||
if p_flag == 0: # for old protocols
|
if p_flag == 0: # for old protocols
|
||||||
match command:
|
match command:
|
||||||
|
@ -66,21 +66,21 @@ def get_configs(config_file, w2t):
|
|||||||
try:
|
try:
|
||||||
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
||||||
configs = json.load(f_config)
|
configs = json.load(f_config)
|
||||||
|
|
||||||
|
p_dir = config_file.split('/')[-2]
|
||||||
|
if not re.match("^[jJ][123]$", p_dir):
|
||||||
|
w2t("被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
|
||||||
|
axis = int(p_dir[-1])
|
||||||
|
|
||||||
|
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比,rr for reduction ratio
|
||||||
|
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
||||||
|
rr = rrs[axis-1]
|
||||||
|
av = avs[axis-1]
|
||||||
|
|
||||||
|
return av, rr
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
clibs.insert_logdb("ERROR", "current", f"get_config: 无法打开 {config_file},获取配置文件参数错误 {Err}")
|
clibs.insert_logdb("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {Err}")
|
||||||
w2t(f"无法打开 {config_file}", color="red", desc="OpenFileError")
|
w2t(f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查\n", color="red", desc="OpenFileError")
|
||||||
|
|
||||||
p_dir = config_file.split('/')[-2]
|
|
||||||
if not re.match("^[jJ][123]$", p_dir):
|
|
||||||
w2t("被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
|
|
||||||
axis = int(p_dir[-1])
|
|
||||||
|
|
||||||
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比,rr for reduction ratio
|
|
||||||
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
|
||||||
rr = rrs[axis-1]
|
|
||||||
av = avs[axis-1]
|
|
||||||
|
|
||||||
return av, rr
|
|
||||||
|
|
||||||
|
|
||||||
def now_doing_msg(docs, flag, w2t):
|
def now_doing_msg(docs, flag, w2t):
|
||||||
|
@ -32,8 +32,8 @@ def initialization(path, w2t, insert_logdb):
|
|||||||
return data_files, config_file
|
return data_files, config_file
|
||||||
|
|
||||||
|
|
||||||
def current_max(data_files, rcs, trq, w2t, insert_logdb):
|
def current_max(data_files, rts, trq, w2t, insert_logdb):
|
||||||
insert_logdb("INFO", "current", "MAX: 正在处理最大电流值逻辑...")
|
insert_logdb("INFO", "current", "MAX: 正在处理最大转矩值逻辑...")
|
||||||
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
if data_file.endswith(".data"):
|
if data_file.endswith(".data"):
|
||||||
@ -44,17 +44,17 @@ def current_max(data_files, rcs, trq, w2t, insert_logdb):
|
|||||||
insert_logdb("INFO", "current", f"MAX: 正在处理 {data_file}")
|
insert_logdb("INFO", "current", f"MAX: 正在处理 {data_file}")
|
||||||
cols = len(df.columns)
|
cols = len(df.columns)
|
||||||
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
||||||
rca = rcs[axis-1]
|
rt = rts[axis-1]
|
||||||
insert_logdb("INFO", "current", f"MAX: 最大列数为 {cols},{axis} 轴的额定电流为 {rca}")
|
insert_logdb("INFO", "current", f"MAX: 最大列数为 {cols},{axis} 轴的额定转矩为 {rt}")
|
||||||
|
|
||||||
col = df.columns.values[trq-1] # 获取 "device_servo_trq_feedback"
|
col = df.columns.values[trq-1] # 获取 "device_servo_trq_feedback"
|
||||||
c_max = df[col].abs().max()
|
c_max = df[col].abs().max()
|
||||||
|
|
||||||
scale = 1000
|
scale = 1000
|
||||||
_ = abs(c_max/scale*rca)
|
_ = abs(c_max/scale*rt)
|
||||||
current[axis].append(_)
|
current[axis].append(_)
|
||||||
w2t(f"{data_file}: {_:.4f}\n")
|
w2t(f"{data_file}: {_:.2f}\n")
|
||||||
insert_logdb("INFO", "current", f"MAX: 获取到的列名为 {col},最大电流为 {_}")
|
insert_logdb("INFO", "current", f"MAX: 获取到的列名为 {col},最大转矩为 {_}")
|
||||||
|
|
||||||
with open(data_file, "a+") as f_data:
|
with open(data_file, "a+") as f_data:
|
||||||
csv_writer = csv.writer(f_data, delimiter="\t")
|
csv_writer = csv.writer(f_data, delimiter="\t")
|
||||||
@ -69,12 +69,12 @@ def current_max(data_files, rcs, trq, w2t, insert_logdb):
|
|||||||
w2t(f"{value:.4f} ")
|
w2t(f"{value:.4f} ")
|
||||||
w2t("\n")
|
w2t("\n")
|
||||||
w2t("\n【MAX】数据处理完毕......")
|
w2t("\n【MAX】数据处理完毕......")
|
||||||
insert_logdb("INFO", "current", f"MAX: 获取最大电流值结束 current_max = {current}")
|
insert_logdb("INFO", "current", f"MAX: 获取最大转矩值结束 current_max = {current}")
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
|
||||||
def current_avg(data_files, rcs, trqh, w2t, insert_logdb):
|
def current_avg(data_files, rts, trqh, w2t, insert_logdb):
|
||||||
insert_logdb("INFO", "current", "AVG: 正在处理平均电流值逻辑...")
|
insert_logdb("INFO", "current", "AVG: 正在处理平均转矩值逻辑...")
|
||||||
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
if data_file.endswith(".data"):
|
if data_file.endswith(".data"):
|
||||||
@ -85,19 +85,19 @@ def current_avg(data_files, rcs, trqh, w2t, insert_logdb):
|
|||||||
insert_logdb("INFO", "current", f"AVG: 正在处理 {data_file}")
|
insert_logdb("INFO", "current", f"AVG: 正在处理 {data_file}")
|
||||||
cols = len(df.columns)
|
cols = len(df.columns)
|
||||||
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
||||||
rca = rcs[axis-1]
|
rt = rts[axis-1]
|
||||||
insert_logdb("INFO", "current", f"AVG: 最大列数为 {cols},{axis} 轴的额定电流为 {rca}")
|
insert_logdb("INFO", "current", f"AVG: 最大列数为 {cols},{axis} 轴的额定转矩为 {rt}")
|
||||||
|
|
||||||
col = df.columns.values[trqh-1]
|
col = df.columns.values[trqh-1]
|
||||||
c_std = df[col].std()
|
c_std = df[col].std()
|
||||||
c_avg = df[col].mean()
|
c_avg = df[col].mean()
|
||||||
|
|
||||||
scale = 1000
|
scale = 1000
|
||||||
_ = (abs(c_avg)+c_std*3)/scale*rca
|
_ = (abs(c_avg)+c_std*3)/scale*rt
|
||||||
current[axis].append(_)
|
current[axis].append(_)
|
||||||
w2t(f"{data_file}: {_:.4f}\n")
|
w2t(f"{data_file}: {_:.2f}\n")
|
||||||
|
|
||||||
insert_logdb("INFO", "current", f"AVG: 获取到的列名为 {col},平均电流为 {_}")
|
insert_logdb("INFO", "current", f"AVG: 获取到的列名为 {col},平均转矩为 {_}")
|
||||||
with open(data_file, "a+") as f_data:
|
with open(data_file, "a+") as f_data:
|
||||||
csv_writer = csv.writer(f_data, delimiter="\t")
|
csv_writer = csv.writer(f_data, delimiter="\t")
|
||||||
csv_writer.writerow([""] * (cols-1) + [_])
|
csv_writer.writerow([""] * (cols-1) + [_])
|
||||||
@ -111,11 +111,11 @@ def current_avg(data_files, rcs, trqh, w2t, insert_logdb):
|
|||||||
w2t(f"{value:.4f} ")
|
w2t(f"{value:.4f} ")
|
||||||
w2t("\n")
|
w2t("\n")
|
||||||
w2t("\n【AVG】数据处理完毕......\n")
|
w2t("\n【AVG】数据处理完毕......\n")
|
||||||
insert_logdb("INFO", "current", f"AVG: 获取平均电流值结束 current_avg = {current}")
|
insert_logdb("INFO", "current", f"AVG: 获取平均转矩值结束 current_avg = {current}")
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
|
||||||
def current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, insert_logdb):
|
def current_cycle(data_files, vel, trq, trqh, sensor, rrs, rts, params, w2t, insert_logdb):
|
||||||
result, hold, single, scenario, dur_time = None, [], [], [], 0
|
result, hold, single, scenario, dur_time = None, [], [], [], 0
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
filename = data_file.split("/")[-1]
|
filename = data_file.split("/")[-1]
|
||||||
@ -137,16 +137,17 @@ def current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, ins
|
|||||||
wb = openpyxl.load_workbook(result)
|
wb = openpyxl.load_workbook(result)
|
||||||
|
|
||||||
ws = wb["统计"]
|
ws = wb["统计"]
|
||||||
for idx in range(len(params)):
|
for idx in range(len(params)-1):
|
||||||
row = idx + 2
|
row = idx + 2
|
||||||
for col in range(2, 8):
|
for col in range(2, 8):
|
||||||
ws.cell(row=row, column=col).value = params[idx][col-2]
|
ws.cell(row=row, column=col).value = params[idx][col-2]
|
||||||
|
ws.cell(row=1, column=1).value = params[-1]
|
||||||
|
|
||||||
if hold:
|
if hold:
|
||||||
avg = current_avg(hold, rcs, trqh, w2t, insert_logdb)
|
avg = current_avg(hold, rts, trqh, w2t, insert_logdb)
|
||||||
for axis, cur_value in avg.items():
|
for axis, cur_value in avg.items():
|
||||||
sht_name = f"J{axis}"
|
sht_name = f"J{axis}"
|
||||||
wb[sht_name]["O4"].value = float(cur_value[0])
|
wb[sht_name]["P4"].value = float(cur_value[0])
|
||||||
|
|
||||||
if dur_time == 0:
|
if dur_time == 0:
|
||||||
p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb)
|
p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb)
|
||||||
@ -303,29 +304,31 @@ def p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb):
|
|||||||
if abs(row_end+row_start-2*row_middle) > 1000:
|
if abs(row_end+row_start-2*row_middle) > 1000:
|
||||||
insert_logdb("WARNING", "current", f"{axis} 轴数据占空比异常!")
|
insert_logdb("WARNING", "current", f"{axis} 轴数据占空比异常!")
|
||||||
|
|
||||||
data, first_c, second_c, third_c = [], vel-1, trq-1, sensor-1
|
data, first_c, second_c, third_c, fourth_c = [], vel-1, trq-1, sensor-1, sensor
|
||||||
for row in range(row_start, row_end+1):
|
for row in range(row_start, row_end+1):
|
||||||
data.append(df_origin.iloc[row, first_c])
|
data.append(df_origin.iloc[row, first_c])
|
||||||
data.append(df_origin.iloc[row, second_c])
|
data.append(df_origin.iloc[row, second_c])
|
||||||
data.append(df_origin.iloc[row, third_c])
|
data.append(df_origin.iloc[row, third_c])
|
||||||
|
data.append(df_origin.iloc[row, fourth_c])
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
for row in ws.iter_rows(min_row=2, min_col=2, max_row=150000, max_col=4):
|
for row in ws.iter_rows(min_row=2, min_col=2, max_row=150000, max_col=5):
|
||||||
for cell in row:
|
for cell in row:
|
||||||
try:
|
try:
|
||||||
if i % 3 == 0:
|
if i % 4 == 0:
|
||||||
ws.cell((i//3)+2, 1).value = float(((i//3)+1)/1000)
|
ws.cell((i//4)+2, 1).value = float(((i//4)+1)/1000)
|
||||||
_ = f"{data[i]:.2f}"
|
_ = f"{data[i]:.2f}"
|
||||||
cell.value = float(_)
|
cell.value = float(_)
|
||||||
i += 1
|
i += 1
|
||||||
except Exception:
|
except Exception:
|
||||||
if i % 3 == 0:
|
if i % 4 == 0:
|
||||||
ws.cell((i//3)+2, 1).value = None
|
ws.cell((i//4)+2, 1).value = None
|
||||||
cell.value = None
|
cell.value = None
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
def p_scenario(wb, scenario, vel, trq, sensor, rrs, dur_time, w2t):
|
def p_scenario(wb, scenario, vel, trq, sensor, rrs, dur_time, w2t):
|
||||||
|
w2t(f"本次处理的是电机电流场景数据,场景运动周期为 {dur_time}s\n", "blue")
|
||||||
for data_file in scenario:
|
for data_file in scenario:
|
||||||
cycle = 0.001
|
cycle = 0.001
|
||||||
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
||||||
@ -344,64 +347,60 @@ def p_scenario(wb, scenario, vel, trq, sensor, rrs, dur_time, w2t):
|
|||||||
if row_end > df.index[-1]:
|
if row_end > df.index[-1]:
|
||||||
w2t(f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "red", "DataOverLimit")
|
w2t(f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "red", "DataOverLimit")
|
||||||
|
|
||||||
data, first_c, second_c, third_c = [], vel-1, trq-1, sensor-1
|
data, first_c, second_c, third_c, fourth_c = [], vel-1, trq-1, sensor-1, sensor
|
||||||
for row in range(row_start, row_end+1):
|
for row in range(row_start, row_end+1):
|
||||||
data.append(df_origin.iloc[row, first_c])
|
data.append(df_origin.iloc[row, first_c])
|
||||||
data.append(df_origin.iloc[row, second_c])
|
data.append(df_origin.iloc[row, second_c])
|
||||||
data.append(df_origin.iloc[row, third_c])
|
data.append(df_origin.iloc[row, third_c])
|
||||||
|
data.append(df_origin.iloc[row, fourth_c])
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
for row in ws.iter_rows(min_row=2, min_col=2, max_row=250000, max_col=4):
|
for row in ws.iter_rows(min_row=2, min_col=2, max_row=250000, max_col=5):
|
||||||
for cell in row:
|
for cell in row:
|
||||||
try:
|
try:
|
||||||
if i % 3 == 0:
|
if i % 4 == 0:
|
||||||
ws.cell((i//3)+2, 1).value = float(((i//3)+1)/1000)
|
ws.cell((i//4)+2, 1).value = float(((i//4)+1)/1000)
|
||||||
_ = f"{data[i]:.2f}"
|
_ = f"{data[i]:.2f}"
|
||||||
cell.value = float(_)
|
cell.value = float(_)
|
||||||
i += 1
|
i += 1
|
||||||
except Exception:
|
except Exception:
|
||||||
cell.value = None
|
cell.value = None
|
||||||
if i % 3 == 0:
|
if i % 4 == 0:
|
||||||
ws.cell((i//3)+2, 1).value = None
|
ws.cell((i//4)+2, 1).value = None
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
def get_configs(config_file, w2t, insert_logdb):
|
def get_configs(config_file, w2t, insert_logdb):
|
||||||
try:
|
try:
|
||||||
|
if re.match("^[NXEC]B.*", config_file.split("/")[-1]):
|
||||||
|
robot_type = "工业"
|
||||||
|
else:
|
||||||
|
robot_type = "协作"
|
||||||
|
|
||||||
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
||||||
configs = json.load(f_config)
|
configs = json.load(f_config)
|
||||||
|
|
||||||
|
version = configs["VERSION"]
|
||||||
|
sc = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] # 采样周期,sc for sample cycle
|
||||||
|
r_rrs = configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"] # 减速比,rr for reduction ratio
|
||||||
|
m_avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
||||||
|
m_stall_ts = configs["MOTOR"]["STALL_TORQUE"] # 电机堵转转矩
|
||||||
|
m_rts = configs["MOTOR"]["RATED_TORQUE"] # 电机额定转矩rt for rated torque
|
||||||
|
m_max_ts = configs["MOTOR"]["PEAK_TORQUE"] # 电机峰值转矩
|
||||||
|
m_r_rpms = configs["MOTOR"]["RATED_SPEED"] # 电机额定转速
|
||||||
|
m_max_rpms = configs["MOTOR"]["MAX_SPEED"] # 电机最大转速
|
||||||
|
r_max_sst = configs["TRANSMISSION"]["MAX_TORQUE_FOR_START_AND_STOP"] # 减速器最大启停转矩,sst for start and stop torque
|
||||||
|
r_max_t = configs["TRANSMISSION"]["MAX_PEAK_TORQUE"] # 减速器瞬时最大转矩
|
||||||
|
r_avg_t = configs["TRANSMISSION"]["MAX_AVERAGE_TORQUE"] # 减速器平均负载转矩允许最大值
|
||||||
|
|
||||||
|
insert_logdb("INFO", "current", f"get_configs: 机型文件版本 {config_file}_{version}")
|
||||||
|
insert_logdb("INFO", "current", f"get_configs: 减速比 {r_rrs}")
|
||||||
|
insert_logdb("INFO", "current", f"get_configs: 额定转矩 {m_rts}")
|
||||||
|
insert_logdb("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:
|
except Exception as Err:
|
||||||
insert_logdb("ERROR", "current", f"get_config: 无法打开 {config_file},获取配置文件参数错误 {Err}")
|
insert_logdb("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {Err}")
|
||||||
w2t(f"无法打开 {config_file}", color="red", desc="OpenFileError")
|
w2t(f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查\n", color="red", desc="OpenFileError")
|
||||||
|
|
||||||
# 最大角速度,额定电流,减速比,额定转速
|
|
||||||
version = configs["VERSION"]
|
|
||||||
m_rts = configs["MOTOR"]["RATED_TORQUE"] # 电机额定转矩rt for rated torque
|
|
||||||
m_max_ts = configs["MOTOR"]["PEAK_TORQUE"] # 电机峰值转矩
|
|
||||||
m_stall_ts = configs["MOTOR"]["STALL_TORQUE"] # 电机堵转转矩
|
|
||||||
m_tcs = [1, 1, 1, 1, 1, 1] # 电机转矩常数,tc for torque constant
|
|
||||||
|
|
||||||
m_rcs, m_max_cs, m_stall_cs = [], [], []
|
|
||||||
for i in range(len(m_tcs)):
|
|
||||||
m_rcs.append(m_rts[i]/m_tcs[i]) # 电机额定电流,rc for rated current
|
|
||||||
m_max_cs.append(m_max_ts[i]/m_tcs[i]) # 电机最大电流
|
|
||||||
m_stall_cs.append(m_stall_ts[i]/m_tcs[i]) # 电机堵转电流
|
|
||||||
|
|
||||||
m_r_rpms = configs["MOTOR"]["RATED_SPEED"] # 电机额定转速
|
|
||||||
m_max_rpms = configs["MOTOR"]["MAX_SPEED"] # 电机最大转速
|
|
||||||
r_rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比,rr for reduction ratio
|
|
||||||
r_max_sst = configs["TRANSMISSION"]["MAX_TORQUE_FOR_START_AND_STOP"] # 减速器最大启停转矩,sst for start and stop torque
|
|
||||||
r_max_t = configs["TRANSMISSION"]["MAX_PEAK_TORQUE"] # 减速器瞬时最大转矩
|
|
||||||
sc = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] # 采样周期,sc for sample cycle
|
|
||||||
r_rts = [1, 1, 1, 1, 1, 1] # 减速器额定转矩
|
|
||||||
r_r_rpms = [1, 1, 1, 1, 1, 1] # 减速器额定转速
|
|
||||||
r_life_cycle = [10000, 10000, 10000, 10000, 10000, 10000] # 减速器L10寿命
|
|
||||||
r_avg_t = configs["TRANSMISSION"]["MAX_AVERAGE_TORQUE"] # 减速器平均负载转矩允许最大值
|
|
||||||
|
|
||||||
insert_logdb("INFO", "current", f"get_configs: 机型文件版本 {config_file}_{version}")
|
|
||||||
insert_logdb("INFO", "current", f"get_configs: 减速比 {r_rrs}")
|
|
||||||
insert_logdb("INFO", "current", f"get_configs: 额定电流 {m_rcs}")
|
|
||||||
return m_rcs, m_max_cs, m_stall_cs, m_rts, m_max_ts, m_r_rpms, m_max_rpms, m_tcs, r_rrs, r_max_sst, r_max_t, sc, r_rts, r_r_rpms, r_life_cycle, r_avg_t
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -418,13 +417,13 @@ def main():
|
|||||||
|
|
||||||
data_files, config_file = initialization(path, w2t, insert_logdb)
|
data_files, config_file = initialization(path, w2t, insert_logdb)
|
||||||
params = get_configs(config_file, w2t, insert_logdb)
|
params = get_configs(config_file, w2t, insert_logdb)
|
||||||
rcs, rrs = params[0], params[8]
|
rts, rrs = params[4], params[1]
|
||||||
if sub == "max":
|
if sub == "max":
|
||||||
current_max(data_files, rcs, trq, w2t, insert_logdb)
|
current_max(data_files, rts, trq, w2t, insert_logdb)
|
||||||
elif sub == "avg":
|
elif sub == "avg":
|
||||||
current_avg(data_files, rcs, trqh, w2t, insert_logdb)
|
current_avg(data_files, rts, trqh, w2t, insert_logdb)
|
||||||
elif sub == "cycle":
|
elif sub == "cycle":
|
||||||
current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, insert_logdb)
|
current_cycle(data_files, vel, trq, trqh, sensor, rrs, rts, params, w2t, insert_logdb)
|
||||||
|
|
||||||
w2t("-"*60 + "\n全部处理完毕\n")
|
w2t("-"*60 + "\n全部处理完毕\n")
|
||||||
time_end = time.time()
|
time_end = time.time()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import pandas
|
import pandas
|
||||||
import csv
|
import csv
|
||||||
import openpyxl
|
import openpyxl
|
||||||
|
import chardet
|
||||||
from common import clibs
|
from common import clibs
|
||||||
|
|
||||||
|
|
||||||
@ -9,7 +10,7 @@ def find_point(bof, step, margin, threshold, pos, data_file, flag, df, row, w2t)
|
|||||||
# pos: used for debug
|
# pos: used for debug
|
||||||
# flag: greater than or lower than
|
# flag: greater than or lower than
|
||||||
row_target = None
|
row_target = None
|
||||||
row_origin = df.index[-1] - margin + 1
|
row_origin = len(df) - margin + 1
|
||||||
if flag == "gt":
|
if flag == "gt":
|
||||||
while 0 < row < row_origin:
|
while 0 < row < row_origin:
|
||||||
value = float(df.iloc[row, 2])
|
value = float(df.iloc[row, 2])
|
||||||
@ -22,7 +23,7 @@ def find_point(bof, step, margin, threshold, pos, data_file, flag, df, row, w2t)
|
|||||||
else:
|
else:
|
||||||
if bof == "backward":
|
if bof == "backward":
|
||||||
clibs.insert_logdb("ERROR", "wavelogger", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...")
|
clibs.insert_logdb("ERROR", "wavelogger", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...")
|
||||||
w2t(f"[{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
w2t(f"[{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...\n", "red", "DataError")
|
||||||
elif bof == "forward":
|
elif bof == "forward":
|
||||||
row_target = row + margin # to end while loop in function `single_file_proc`
|
row_target = row + margin # to end while loop in function `single_file_proc`
|
||||||
elif flag == "lt":
|
elif flag == "lt":
|
||||||
@ -37,7 +38,7 @@ def find_point(bof, step, margin, threshold, pos, data_file, flag, df, row, w2t)
|
|||||||
else:
|
else:
|
||||||
if bof == "backward":
|
if bof == "backward":
|
||||||
clibs.insert_logdb("ERROR", "wavelogger", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...")
|
clibs.insert_logdb("ERROR", "wavelogger", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...")
|
||||||
w2t(f"[{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
w2t(f"[{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...\n", "red", "DataError")
|
||||||
elif bof == "forward":
|
elif bof == "forward":
|
||||||
row_target = row + margin # to end while loop in function `single_file_proc`
|
row_target = row + margin # to end while loop in function `single_file_proc`
|
||||||
return row_target
|
return row_target
|
||||||
@ -49,10 +50,14 @@ def get_cycle_info(data_file, step, margin, threshold, w2t):
|
|||||||
# 1. 从最后读取数据,无论是大于1还是小于1,都舍弃,找到相反的值的起始点
|
# 1. 从最后读取数据,无论是大于1还是小于1,都舍弃,找到相反的值的起始点
|
||||||
# 2. 从起始点,继续往前寻找,找到与之数值相反的中间点
|
# 2. 从起始点,继续往前寻找,找到与之数值相反的中间点
|
||||||
# 3. 从中间点,继续往前寻找,找到与之数值相反的结束点,至此,得到了高低数值的时间区间以及一轮的周期时间
|
# 3. 从中间点,继续往前寻找,找到与之数值相反的结束点,至此,得到了高低数值的时间区间以及一轮的周期时间
|
||||||
csv_reader = csv.reader(open(data_file))
|
with open(data_file, "rb") as f:
|
||||||
|
raw_data = f.read(1000)
|
||||||
|
result = chardet.detect(raw_data)
|
||||||
|
encoding = result['encoding']
|
||||||
|
csv_reader = csv.reader(open(data_file, encoding=encoding))
|
||||||
begin = int(next(csv_reader)[1])
|
begin = int(next(csv_reader)[1])
|
||||||
df = pandas.read_csv(data_file, sep=",", encoding="gbk", skip_blank_lines=False, header=begin - 1, on_bad_lines="skip")
|
df = pandas.read_csv(data_file, sep=",", encoding=encoding, skip_blank_lines=False, header=begin - 1, on_bad_lines="skip")
|
||||||
row = df.index[-1] - margin
|
row = len(df) - margin
|
||||||
if float(df.iloc[row, 2]) < threshold:
|
if float(df.iloc[row, 2]) < threshold:
|
||||||
row = find_point("backward", step, margin, threshold, "a1", data_file, "lt", df, row, w2t)
|
row = find_point("backward", step, margin, threshold, "a1", data_file, "lt", df, row, w2t)
|
||||||
|
|
||||||
@ -73,7 +78,7 @@ def initialization(path, w2t):
|
|||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
if not data_file.lower().endswith(".csv"):
|
if not data_file.lower().endswith(".csv"):
|
||||||
clibs.insert_logdb("ERROR", "wavelogger", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!")
|
clibs.insert_logdb("ERROR", "wavelogger", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!")
|
||||||
w2t(f"{data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red", "FileTypeError")
|
w2t(f"{data_file} 文件后缀错误,只允许 .csv 文件,需要确认!\n", "red", "FileTypeError")
|
||||||
|
|
||||||
return data_files
|
return data_files
|
||||||
|
|
||||||
@ -88,7 +93,7 @@ def preparation(data_file, step, margin, threshold, wb, w2t):
|
|||||||
|
|
||||||
def single_file_proc(ws, data_file, step, threshold, margin, data_length, df, cycle, w2t):
|
def single_file_proc(ws, data_file, step, threshold, margin, data_length, df, cycle, w2t):
|
||||||
row, row_lt, row_gt, count, count_i, data = 1, 1, 1, 1, 1, {}
|
row, row_lt, row_gt, count, count_i, data = 1, 1, 1, 1, 1, {}
|
||||||
row_max = df.index[-1] - margin
|
row_max = len(df) - margin
|
||||||
while row < row_max:
|
while row < row_max:
|
||||||
if count not in data.keys():
|
if count not in data.keys():
|
||||||
data[count] = []
|
data[count] = []
|
||||||
@ -98,9 +103,9 @@ def single_file_proc(ws, data_file, step, threshold, margin, data_length, df, cy
|
|||||||
row_lt = find_point("forward", step, margin, threshold, "c"+str(row), data_file, "lt", df, row, w2t)
|
row_lt = find_point("forward", step, margin, threshold, "c"+str(row), data_file, "lt", df, row, w2t)
|
||||||
start = int(row_gt + (row_lt - row_gt - data_length) / 2)
|
start = int(row_gt + (row_lt - row_gt - data_length) / 2)
|
||||||
end = start + data_length
|
end = start + data_length
|
||||||
value = df.iloc[start:end, 2].mean() + 3 * df.iloc[start:end, 2].std()
|
value = df.iloc[start:end, 2].astype(float).mean() + 3 * df.iloc[start:end, 2].astype(float).std()
|
||||||
if value > 1:
|
if value > 1:
|
||||||
msg = f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留"
|
msg = f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留\n"
|
||||||
clibs.insert_logdb("WARNING", "wavelogger", msg)
|
clibs.insert_logdb("WARNING", "wavelogger", msg)
|
||||||
w2t(msg, "orange")
|
w2t(msg, "orange")
|
||||||
data[count].append(value)
|
data[count].append(value)
|
||||||
|
BIN
code/durable_docs/__pycache__/create_plot.cpython-312.pyc
Normal file
BIN
code/durable_docs/__pycache__/create_plot.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/durable_docs/__pycache__/factory_test.cpython-312.pyc
Normal file
BIN
code/durable_docs/__pycache__/factory_test.cpython-312.pyc
Normal file
Binary file not shown.
82
code/durable_docs/create_plot.py
Normal file
82
code/durable_docs/create_plot.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import os.path
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import pandas
|
||||||
|
from matplotlib.widgets import Slider
|
||||||
|
from common import clibs
|
||||||
|
|
||||||
|
|
||||||
|
def initialization():
|
||||||
|
path, curves = None, None
|
||||||
|
try:
|
||||||
|
path = clibs.data_dd["path"]
|
||||||
|
curves = clibs.data_dd["curves"]
|
||||||
|
except Exception:
|
||||||
|
clibs.w2t("程序未开始运行,暂无数据可以展示......\n", "red")
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
for curve in curves:
|
||||||
|
if not os.path.exists(f"{path}/{curve}.csv"):
|
||||||
|
clibs.w2t(f"{curve}曲线数据暂未生成,稍后再试......\n", "orange")
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
return path, curves
|
||||||
|
|
||||||
|
|
||||||
|
def data_plot(path, curve):
|
||||||
|
titles = {"hw_joint_vel_feedback": "各关节最大速度曲线", "device_servo_trq_feedback": "各关节平均有效转矩曲线"}
|
||||||
|
ylabels = {"hw_joint_vel_feedback": "速度(rad/s)", "device_servo_trq_feedback": "转矩(Nm)"}
|
||||||
|
|
||||||
|
fig, axes = plt.subplots(figsize=(10, 4.5), dpi=100)
|
||||||
|
cols = [f"{curve}_{i}" for i in range(6)]
|
||||||
|
cols.insert(0, "time")
|
||||||
|
df = pandas.read_csv(f"{path}/{curve}.csv")
|
||||||
|
plt.plot(df[cols[1]], label="一轴")
|
||||||
|
plt.plot(df[cols[2]], label="二轴")
|
||||||
|
plt.plot(df[cols[3]], label="三轴")
|
||||||
|
plt.plot(df[cols[4]], label="四轴")
|
||||||
|
plt.plot(df[cols[5]], label="五轴")
|
||||||
|
plt.plot(df[cols[6]], label="六轴")
|
||||||
|
axes.set_title(titles[curve])
|
||||||
|
axes.set_ylabel(ylabels[curve])
|
||||||
|
axes.legend(loc="upper right")
|
||||||
|
|
||||||
|
slider_position = plt.axes((0.1, 0.01, 0.8, 0.05), facecolor="blue") # (left, bottom, width, height)
|
||||||
|
scrollbar = Slider(slider_position, 'Time', 1, int(len(df)), valstep=1)
|
||||||
|
|
||||||
|
def update(val):
|
||||||
|
pos = scrollbar.val
|
||||||
|
axes.set_xlim([pos, pos + 10])
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
scrollbar.on_changed(update)
|
||||||
|
fig.tight_layout(rect=(0, 0.02, 0.96, 1)) # tuple (left, bottom, right, top)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
path, curves = initialization()
|
||||||
|
if not path or not curves:
|
||||||
|
return
|
||||||
|
|
||||||
|
for curve in curves:
|
||||||
|
data_plot(path, curve)
|
||||||
|
|
||||||
|
plt.rcParams['font.sans-serif'] = ['SimHei']
|
||||||
|
plt.rcParams['axes.unicode_minus'] = False
|
||||||
|
plt.rcParams['figure.dpi'] = 100
|
||||||
|
plt.rcParams['font.size'] = 14
|
||||||
|
plt.rcParams['lines.marker'] = 'o'
|
||||||
|
plt.rcParams["figure.autolayout"] = True
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
# threads = [threading.Thread(target=data_plot, args=(path, curve)) for curve in curves]
|
||||||
|
# for t in threads:
|
||||||
|
# t.daemon = True
|
||||||
|
# t.start()
|
||||||
|
# for curve in curves:
|
||||||
|
# t = threading.Thread(target=data_plot, args=(path, curve))
|
||||||
|
# t.daemon = True
|
||||||
|
# t.start()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
271
code/durable_docs/factory_test.py
Normal file
271
code/durable_docs/factory_test.py
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
import json
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import pandas
|
||||||
|
import math
|
||||||
|
import csv
|
||||||
|
import numpy
|
||||||
|
from common import clibs
|
||||||
|
|
||||||
|
|
||||||
|
def initialization(path, hr, data_dirs, data_files, interval, curves, w2t):
|
||||||
|
def check_files():
|
||||||
|
nonlocal interval
|
||||||
|
if interval == "":
|
||||||
|
interval = 300
|
||||||
|
elif interval.isdigit():
|
||||||
|
if int(interval) < 300:
|
||||||
|
w2t(f"输入时间间隔 {interval} < 300,使用默认时间间隔 300s ......\n", "orange")
|
||||||
|
interval = 300
|
||||||
|
else:
|
||||||
|
interval = int(interval)
|
||||||
|
else:
|
||||||
|
w2t(f"{interval} 不是有效的输入,时间间隔必须是一个大于 300 的正整数!\n", "red", "NotIntegerError")
|
||||||
|
|
||||||
|
if len(curves) == 0:
|
||||||
|
w2t("未查询到需要记录数据的曲线,至少选择一个!\n", "red", "CurveNameError")
|
||||||
|
|
||||||
|
if len(data_dirs) != 0 or len(data_files) != 1:
|
||||||
|
w2t("初始路径下不允许有文件夹,且初始路径下只能存在一个工程文件 —— *.zip,确认后重新运行!\n", "red", "InitFileError")
|
||||||
|
|
||||||
|
if not data_files[0].endswith(".zip"):
|
||||||
|
w2t(f"{data_files[0]} 不是一个有效的工程文件,需确认!\n", "red", "ProjectFileError")
|
||||||
|
|
||||||
|
return data_files[0], interval
|
||||||
|
|
||||||
|
def get_configs():
|
||||||
|
robot_type, records = None, None
|
||||||
|
try:
|
||||||
|
msg_id, state = hr.execution("controller.get_params")
|
||||||
|
records = hr.get_from_id(msg_id, state)
|
||||||
|
except Exception:
|
||||||
|
w2t("网络不可达,需要先连接xCore!\n", "red", "NetworkError")
|
||||||
|
for record in records:
|
||||||
|
if "请求发送成功" not in record[0]:
|
||||||
|
robot_type = eval(record[0])["data"]["robot_type"]
|
||||||
|
server_file = f"/home/luoshi/bin/controller/robot_cfg/{robot_type}/{robot_type}.cfg"
|
||||||
|
local_file = path + f"/{robot_type}.cfg"
|
||||||
|
clibs.c_pd.pull_file_from_server(server_file, local_file)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(local_file, mode="r", encoding="utf-8") as f_config:
|
||||||
|
configs = json.load(f_config)
|
||||||
|
except Exception as Err:
|
||||||
|
clibs.insert_logdb("ERROR", "current", f"get_config: 无法打开 {local_file},获取配置文件参数错误 {Err}")
|
||||||
|
w2t(f"无法打开 {local_file}\n", color="red", desc="OpenFileError")
|
||||||
|
|
||||||
|
# 最大角速度,额定电流,减速比,额定转速
|
||||||
|
version = configs["VERSION"]
|
||||||
|
m_avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
||||||
|
m_rts = configs["MOTOR"]["RATED_TORQUE"] # 电机额定转矩rt for rated torque
|
||||||
|
m_tcs = [1, 1, 1, 1, 1, 1] # 电机转矩常数,tc for torque constant
|
||||||
|
m_rcs = []
|
||||||
|
for i in range(len(m_tcs)):
|
||||||
|
m_rcs.append(m_rts[i] / m_tcs[i]) # 电机额定电流,rc for rated current
|
||||||
|
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 机型文件版本 {robot_type}_{version}")
|
||||||
|
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {m_avs}")
|
||||||
|
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节额定电流 {m_rcs}")
|
||||||
|
return m_avs, m_rcs
|
||||||
|
|
||||||
|
prj_file, interval = check_files()
|
||||||
|
avs, rcs = get_configs()
|
||||||
|
params = {
|
||||||
|
"prj_file": prj_file,
|
||||||
|
"interval": interval,
|
||||||
|
"avs": avs,
|
||||||
|
"rcs": rcs,
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
def change_curve_state(hr, curves, stat_1, stat_2):
|
||||||
|
display_pdo_params = [{"name": name, "channel": chl} for name in curves for chl in range(6)]
|
||||||
|
hr.execution("diagnosis.open", open=stat_1, display_open=stat_2, overrun=True, turn_area=True, delay_motion=False)
|
||||||
|
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
||||||
|
|
||||||
|
|
||||||
|
def run_rl(path, params, curves, hr, md, w2t):
|
||||||
|
prj_file, interval = params["prj_file"], params["interval"]
|
||||||
|
# 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
|
||||||
|
change_curve_state(hr, curves, False, False)
|
||||||
|
md.r_soft_estop(0)
|
||||||
|
md.r_soft_estop(1)
|
||||||
|
md.r_clear_alarm()
|
||||||
|
md.write_act(False)
|
||||||
|
time.sleep(1) # 让曲线彻底关闭
|
||||||
|
|
||||||
|
# 2. reload工程后,pp2main,并且自动模式和上电
|
||||||
|
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
|
||||||
|
prj_path = f"{prj_name}/_build/{prj_name}.prj"
|
||||||
|
hr.execution("overview.reload", prj_path=prj_path, tasks=["factory"])
|
||||||
|
hr.execution("rl_task.pp_to_main", tasks=["factory"])
|
||||||
|
hr.execution("state.switch_auto")
|
||||||
|
hr.execution("state.switch_motor_on")
|
||||||
|
|
||||||
|
# 3. 开始运行程序
|
||||||
|
hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
|
||||||
|
hr.execution("rl_task.run", tasks=["factory"])
|
||||||
|
t_start = time.time()
|
||||||
|
while True:
|
||||||
|
if md.read_ready_to_go() == 1:
|
||||||
|
md.write_act(True)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if (time.time() - t_start) > 3:
|
||||||
|
w2t("3s 内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...\n", "red", "ReadySignalTimeoutError")
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# 4. 获取初始数据,周期时间,首次的各轴平均电流值,打开诊断曲线,并执行采集
|
||||||
|
time.sleep(10) # 等待 RL 程序中 scenario_time 初始化
|
||||||
|
t_start = time.time()
|
||||||
|
while True:
|
||||||
|
scenario_time = float(f"{float(md.read_scenario_time()):.2f}")
|
||||||
|
if scenario_time != 0:
|
||||||
|
w2t(f"耐久工程的周期时间:{scenario_time}s | 单轮次执行时间:{scenario_time+interval}\n")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
if (time.time() - t_start) > 300:
|
||||||
|
w2t(f"300s 内未收到耐久工程的周期时间,需要确认RL程序和工具通信交互是否正常执行...\n", "red", "GetScenarioTimeError")
|
||||||
|
|
||||||
|
# 6. 准备数据保存文件
|
||||||
|
for curve in curves:
|
||||||
|
with open(f"{path}/{curve}.csv", mode="a+", newline="") as f_csv:
|
||||||
|
titles = [f"{curve}_{i}" for i in range(6)]
|
||||||
|
titles.insert(0, "time")
|
||||||
|
csv_writer = csv.writer(f_csv)
|
||||||
|
csv_writer.writerow(titles)
|
||||||
|
|
||||||
|
# 7. 开始采集
|
||||||
|
count = 0
|
||||||
|
while clibs.running:
|
||||||
|
if not clibs.running:
|
||||||
|
w2t("后台数据清零完成,现在可以重新运行之前停止的程序。", "red")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
this_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
|
next_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()+scenario_time+interval+1))
|
||||||
|
w2t(f"[{this_time}] 当前次数:{count:09d} | 预计下次数据更新时间:{next_time}\n", "#008B8B")
|
||||||
|
count += 1
|
||||||
|
# 固定间隔,更新一次数据,打开曲线,获取周期内电流,关闭曲线
|
||||||
|
time.sleep(interval)
|
||||||
|
change_curve_state(hr, curves, True, True)
|
||||||
|
time.sleep(scenario_time)
|
||||||
|
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
|
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()-scenario_time))
|
||||||
|
change_curve_state(hr, curves, False, False)
|
||||||
|
# 保留数据并处理输出
|
||||||
|
gen_results(params, curves, start_time, end_time, w2t)
|
||||||
|
|
||||||
|
|
||||||
|
def gen_results(params, curves, start_time, end_time, w2t):
|
||||||
|
try:
|
||||||
|
clibs.lock.acquire(True)
|
||||||
|
clibs.cursor.execute(f"select content from logs where time between '{start_time}' and '{end_time}' and content like '%diagnosis.result%' order by id asc")
|
||||||
|
records = clibs.cursor.fetchall()
|
||||||
|
finally:
|
||||||
|
clibs.lock.release()
|
||||||
|
data_proc(records, params, curves, w2t)
|
||||||
|
|
||||||
|
|
||||||
|
def data_proc(records, params, curves, w2t):
|
||||||
|
for curve in curves:
|
||||||
|
if curve == "device_servo_trq_feedback":
|
||||||
|
# proc_device_servo_trq_feedback(records, params, w2t)
|
||||||
|
t = threading.Thread(target=proc_device_servo_trq_feedback, args=(records, params, w2t))
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
elif curve == "hw_joint_vel_feedback":
|
||||||
|
# proc_hw_joint_vel_feedback(records, params, w2t)
|
||||||
|
t = threading.Thread(target=proc_hw_joint_vel_feedback, args=(records, params, w2t))
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
|
||||||
|
def proc_device_servo_trq_feedback(records, params, w2t):
|
||||||
|
d_trq, rcs, results = [[], [], [], [], [], []], params["rcs"], [time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))]
|
||||||
|
for record in records:
|
||||||
|
data = eval(record[0])["data"]
|
||||||
|
for item in data:
|
||||||
|
d_item = reversed(item["value"])
|
||||||
|
for axis in range(6):
|
||||||
|
if item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
|
||||||
|
d_trq[axis].extend(d_item)
|
||||||
|
|
||||||
|
for axis in range(6):
|
||||||
|
df = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq[axis]})
|
||||||
|
_ = math.sqrt(df.apply(lambda x: numpy.power((rcs[axis] * float(x.iloc[0]) / 1000), 2)).sum() / len(df))
|
||||||
|
results.append(_)
|
||||||
|
|
||||||
|
path = "/".join(params["prj_file"].split("/")[:-1])
|
||||||
|
with open(f"{path}/device_servo_trq_feedback.csv", mode="a+", newline="") as f_csv:
|
||||||
|
csv_writer = csv.writer(f_csv)
|
||||||
|
csv_writer.writerow(results)
|
||||||
|
|
||||||
|
|
||||||
|
def proc_hw_joint_vel_feedback(records, params, w2t):
|
||||||
|
d_trq, rcs, results = [[], [], [], [], [], []], params["rcs"], [time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))]
|
||||||
|
for record in records:
|
||||||
|
data = eval(record[0])["data"]
|
||||||
|
for item in data:
|
||||||
|
d_item = reversed(item["value"])
|
||||||
|
for axis in range(6):
|
||||||
|
if item.get("channel", None) == axis and item.get("name", None) == "hw_joint_vel_feedback":
|
||||||
|
d_trq[axis].extend(d_item)
|
||||||
|
|
||||||
|
for axis in range(6):
|
||||||
|
df = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_trq[axis]})
|
||||||
|
_ = df.max().iloc[0]
|
||||||
|
results.append(_)
|
||||||
|
|
||||||
|
path = "/".join(params["prj_file"].split("/")[:-1])
|
||||||
|
with open(f"{path}/hw_joint_vel_feedback.csv", mode="a+", newline="") as f_csv:
|
||||||
|
csv_writer = csv.writer(f_csv)
|
||||||
|
csv_writer.writerow(results)
|
||||||
|
|
||||||
|
|
||||||
|
def detect_db_size():
|
||||||
|
@clibs.db_lock
|
||||||
|
def release_memory():
|
||||||
|
line_number = 20000
|
||||||
|
leftover = 4000 # 200s
|
||||||
|
clibs.cursor.execute("select count(id) from logs")
|
||||||
|
len_records = clibs.cursor.fetchone()[0]
|
||||||
|
if len_records > line_number:
|
||||||
|
del_num = len_records - leftover + 1
|
||||||
|
clibs.cursor.execute(f"delete from logs where id < {del_num}")
|
||||||
|
clibs.cursor.execute(f"update logs set id=(id-{del_num-1}) where id > {del_num-1}")
|
||||||
|
clibs.cursor.execute(f"update sqlite_sequence set seq = {leftover+1} WHERE name = 'logs' ")
|
||||||
|
clibs.cursor.execute("vacuum")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
release_memory()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
t = threading.Thread(target=detect_db_size)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
path = clibs.data_dd["path"]
|
||||||
|
interval = clibs.data_dd["interval"].strip()
|
||||||
|
curves = clibs.data_dd["curves"]
|
||||||
|
hr = clibs.c_hr
|
||||||
|
md = clibs.c_md
|
||||||
|
w2t = clibs.w2t
|
||||||
|
|
||||||
|
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
||||||
|
params = initialization(path, hr, data_dirs, data_files, interval, curves, w2t)
|
||||||
|
prj_file = params["prj_file"]
|
||||||
|
clibs.c_pd.push_prj_to_server(prj_file)
|
||||||
|
try:
|
||||||
|
run_rl(path, params, curves, hr, md, w2t)
|
||||||
|
except Exception as Err:
|
||||||
|
w2t(f"工厂耐久程序执行过程中出现异常,{Err}\n", "red")
|
||||||
|
change_curve_state(hr, curves, False, False)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
22
readme.md
22
readme.md
@ -22,6 +22,13 @@
|
|||||||
|
|
||||||
## 三、注意事项
|
## 三、注意事项
|
||||||
|
|
||||||
|
1. 仅适用于 xCore 2.3.0.7 及以上的版本
|
||||||
|
2. 单轴电机电流数据处理,至少需要三个完整周期
|
||||||
|
3. 执行制动测试/电机电流采集/耐久测试的时候,执行过程中停止,再次运行需要等待一分钟左右,输出框会有提示
|
||||||
|
4. 其他使用方法和之前工具一致
|
||||||
|
|
||||||
|
> **需要使用 assets/files/projects/ 下的工程,寄存器文件以及配置文件等!!!**
|
||||||
|
|
||||||
## 四、发版记录
|
## 四、发版记录
|
||||||
|
|
||||||
## 五、其他
|
## 五、其他
|
||||||
@ -31,13 +38,24 @@
|
|||||||
打包时,只需要修改 clibs.py 中的 PREFIX 即可,调试时再修改回来
|
打包时,只需要修改 clibs.py 中的 PREFIX 即可,调试时再修改回来
|
||||||
|
|
||||||
```
|
```
|
||||||
pyinstaller --noconfirm --onedir --windowed --optimize 2 --contents-directory . --upx-dir "D:/Syncthing/common/A_Program/upx-4.2.4-win64/" --add-data "../.venv/Lib/site-packages/customtkinter;customtkinter/" --add-data "../assets:assets" --version-file ../assets/files/version/file_version_info.txt -i ../assets/media/icon.ico ../code/aio.py -p ../code/data_process/brake.py -p ../code/data_process/iso.py -p ../code/data_process/current.py -p ../code/data_process/wavelogger.py -p ../code/commons/clibs.py -p ../code/commons/openapi.py -p ../code/automatic_test/do_current.py -p ../code/automatic_test/do_brake.py --exclude-module=scipy --exclude-module=matplotlib
|
pyinstaller --noconfirm --onedir --windowed --optimize 2 --contents-directory . --upx-dir "D:/Syncthing/common/A_Program/upx-4.2.4-win64/" --add-data "../.venv/Lib/site-packages/customtkinter;customtkinter/" --add-data "../assets:assets" --version-file ../assets/files/version/file_version_info.txt -i ../assets/media/icon.ico ../code/aio.py -p ../code/common/clibs.py -p ../code/commom/openapi.py -p ../code/data_process/brake.py -p ../code/data_process/iso.py -p ../code/data_process/current.py -p ../code/data_process/wavelogger.py -p ../code/automatic_test/do_current.py -p ../code/automatic_test/do_brake.py -p ../code/durable_docs/factory_test.py -p ../code/durable_docs/create_plot.py --exclude-module=scipy
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. tabview 组件字体修改
|
### 2. tabview 组件字体修改
|
||||||
|
|
||||||
customtkinter的tabview组件不支持修改字体大小,可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现:
|
customtkinter的tabview组件不支持修改字体大小,解决方法可参考如下:
|
||||||
|
|
||||||
|
Method 1:可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现:
|
||||||
|
|
||||||
a. 运行 `pip show customtkinter`,获取到库的路径
|
a. 运行 `pip show customtkinter`,获取到库的路径
|
||||||
b. 修改.../windows/widgets/ctk_tabview.py
|
b. 修改.../windows/widgets/ctk_tabview.py
|
||||||
c. 增加 from .font.ctk_font import CTkFont
|
c. 增加 from .font.ctk_font import CTkFont
|
||||||
d. 在大概 78 行的位置,增加 font=CTkFont(family="Consolas", size=18, weight='bold')
|
d. 在大概 78 行的位置,增加 font=CTkFont(family="Consolas", size=18, weight='bold')
|
||||||
|
|
||||||
|
Method 2:
|
||||||
|
|
||||||
|
self.tabview_bottom._segmented_button.configure(font=ctk.CTkFont(family="Consolas", size=18, weight="bold"))
|
||||||
|
|
||||||
|
### 3. scroll frame 不支持修改高度和宽度
|
||||||
|
|
||||||
|
https://github.com/TomSchimansky/CustomTkinter/pull/1765/files
|
Reference in New Issue
Block a user