10 Commits

Author SHA1 Message Date
ecdec2e41b modify version info 2024-06-13 20:07:50 +08:00
07eb0c8940 modify version info 2024-06-13 20:06:11 +08:00
39f3cb836b v0.1.5.2(2024/06/13)
[brake.py/aio.py]: 将sto修改为estop
[brake.py]: 修改了速度计算逻辑,新版本的vel列数据遵循如下规则,av = vel * 180 / pi,根据av再计算speed
[brake.py]: 将threshold修改为常量50
[brake.py]: 提高了输出提示语的明确性,删除了不必要的省略号
[brake.py]: 更正了之前的数据copy错误,重新优化了estop处是否达到指定百分比的判定逻辑
2024-06-13 19:58:34 +08:00
7e568fb699 v0.1.5.1(2024/06/12)
[current.py]:  修改cycle功能中,数据清理范围为70000行,并将threshold从2调整为5
[current.py]:  修改位置超限提示,使更清楚了解问题原因
[current.py]:  修改find_point函数中错误提示,增加定位信息
[README.md]: 精简打包命令
[requirements.txt]: 新增必要库配置文件
2024-06-13 18:10:42 +08:00
9971b51457 [modify] add modification method to change tabview font 2024-06-11 10:52:09 +08:00
e1716332d7 fix vers date 2024-06-11 10:39:08 +08:00
2ac5dc3895 [layout.xlsx]: 添加了各个功能的流程图
[aio.py] 修改了rc的placeholder内容,和其他rcx统一
2024-06-11 10:28:46 +08:00
154657fd18 [modify] [aio.py]: 修改menu_main->menu_main_dp,menu_sub->menu_sub_dp,为后续其他tab功能按钮做扩展,是针对第三点做出的相应调整 2024-06-09 22:36:20 +08:00
412c7c2600 [aio.py]: 新增tabview组件,区分数据处理和自动化测试功能 2024-06-09 21:32:10 +08:00
8e64d18fb8 [aio.py]: 更改label/entry/optionmenu等控件的生成方式,使用循环实现,更加简洁和容易维护 2024-06-09 13:54:39 +08:00
11 changed files with 5396 additions and 333 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
test.py
.idea/ .idea/
aio/.idea/ aio/.idea/
aio/__pycache__/ aio/__pycache__/

View File

@ -23,12 +23,8 @@ python.exe -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/sim
### 打包方法 ### 打包方法
```commandline ```
pyinstaller.exe -F --version-file file_version_info.txt -i .\icon.ico .\aio.py
pyinstaller.exe -F --version-file file_version_info.txt -i .\icon.ico .\aio.py -p .\brake.py -p .\current.py pyinstaller.exe -F --version-file file_version_info.txt -i .\icon.ico .\aio.py -p .\brake.py -p .\current.py
<<<<<<< HEAD
pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/AppData/Local/Programs/Python/Python312/Lib/site-packages/customtkinter;customtkinter/" --version-file file_version_info.txt -i .\icon.ico .\aio.py -p .\brake.py .\iso.py
pyinstaller --noconfirm --onedir --windowed --add-data "/opt/git/rokae/aio/venv/lib/python3.11/site-packages/customtkinter;customtkinter/" --version-file file_version_info.txt -i ./icon.ico ./aio.py -p ./brake.py -p ./iso.py -p ./current.py
pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/AppData/Local/Programs/Python/Python312/Lib/site-packages/customtkinter;customtkinter/" --version-file file_version_info.txt -i .\icon.ico .\aio.py -p .\brake.py -p .\iso.py -p .\current.py pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/AppData/Local/Programs/Python/Python312/Lib/site-packages/customtkinter;customtkinter/" --version-file file_version_info.txt -i .\icon.ico .\aio.py -p .\brake.py -p .\iso.py -p .\current.py
``` ```
@ -102,6 +98,13 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A
c. ISO-V100.pdf c. ISO-V100.pdf
d. iso-results.xlsx d. iso-results.xlsx
#### 其他
customtkinter的tabview组件不支持修改字体大小可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现:
a. 运行 `pip show customtkinter`,获取到库的路径
b. 修改.../windows/widgets/ctk_tabview.py
c. 增加 from .font.ctk_font import CTkFont
d. 在大概 78 行的位置,增加 font=CTkFont(family="Consolas", size=18, weight='bold')
--- ---
RELEASE CHANGES RELEASE CHANGES
@ -185,8 +188,25 @@ v0.1.4(2024/06/06)
v0.1.5(2024/06/12) v0.1.5(2024/06/12)
1. [aio.py]: 主界面切换不同功能时保持placehold一致 1. [aio.py]: 主界面切换不同功能时保持placehold一致
2. [brake.py]: 由于制动采集模板和内容的更改,适配了新的数据,更新了算法 2. [brake.py]: 由于制动采集模板和内容的更改,适配了新的数据,更新了算法
3. [layout.xlsx]: 添加了各个功能的流程图 3. [aio.py]: 新增tabview组件区分数据处理和自动化测试功能
4. [aio.py]: 重新调整界面配色 4. [aio.py]: 重新调整界面配色
5. [aio.py]: 修改了write2textbox函数定制化显示每一行的颜色针对每一行可自定义输出内容颜色 5. [aio.py]: 修改了write2textbox函数定制化显示每一行的颜色针对每一行可自定义输出内容颜色
6. [brake.py/iso.py/current.py]: 由于第 5 点的更改,同时修改了其他文件相关引用的部分 6. [brake.py/iso.py/current.py]: 由于第 5 点的更改,同时修改了其他文件相关引用的部分
7. [aio.py]: 更改label/entry/optionmenu等控件的生成方式使用循环实现更加简洁和容易维护 7. [aio.py]: 更改label/entry/optionmenu等控件的生成方式使用循环实现更加简洁和容易维护
8. [aio.py]: 修改customtkinter库中C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\customtkinter\windows\widgets\ctk_tabview.py文件参考https://github.com/TomSchimansky/CustomTkinter/issues/2296实现修改tabview组件的字体大小
9. [aio.py]: 修改menu_main->menu_main_dpmenu_sub->menu_sub_dp为后续其他tab功能按钮做扩展是针对第三点做出的相应调整
10. [layout.xlsx]: 添加了各个功能的流程图
v0.1.5.1(2024/06/12)
[current.py]: 修改cycle功能中数据清理范围为70000行并将threshold从2调整为5
[current.py]: 修改位置超限提示,使更清楚了解问题原因
[current.py]: 修改find_point函数中错误提示增加定位信息
[README.md]: 精简打包命令
[requirements.txt]: 新增必要库配置文件
v0.1.5.2(2024/06/13)
[brake.py/aio.py]: 将sto修改为estop
[brake.py]: 修改了速度计算逻辑新版本的vel列数据遵循如下规则av = vel * 180 / pi根据av再计算speed
[brake.py]: 将threshold修改为常量50
[brake.py]: 提高了输出提示语的明确性,删除了不必要的省略号
[brake.py]: 更正了之前的数据copy错误重新优化了estop处是否达到指定百分比的判定逻辑

View File

@ -6,13 +6,39 @@ import customtkinter
import brake, current, iso import brake, current, iso
from time import time, strftime, localtime from time import time, strftime, localtime
from urllib.request import urlopen from urllib.request import urlopen
import socket from socket import setdefaulttimeout
customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light" customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
customtkinter.set_widget_scaling(1.1) # widget dimensions and text size customtkinter.set_widget_scaling(1.1) # widget dimensions and text size
customtkinter.set_window_scaling(1.1) # window geometry dimensions customtkinter.set_window_scaling(1.1) # window geometry dimensions
socket.setdefaulttimeout(1) setdefaulttimeout(10)
# global vars
btns = {
'start': {'btn': '', 'row': 1, 'text': '开始运行'},
'check': {'btn': '', 'row': 2, 'text': '检查参数'},
'log': {'btn': '', 'row': 3, 'text': '保存日志'},
'end': {'btn': '', 'row': 4, 'text': '结束运行'},
}
widgits = {
'path': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '数据文件夹路径'},
'av': {'label': '', 'entry': '', 'row': 2, 'col': 2, 'text': '角速度'},
'rc': {'label': '', 'entry': '', 'row': 2, 'col': 4, 'text': '额定电流'},
'rpm': {'label': '', 'entry': '', 'row': 2, 'col': 6, 'text': '额定转速'},
'rr': {'label': '', 'entry': '', 'row': 2, 'col': 8, 'text': '减速比'},
'dur': {'label': '', 'entry': '', 'row': 2, 'col': 10, 'text': '周期时间'},
'axis': {'label': '', 'optionmenu': '', 'row': 3, 'col': 2, 'text': ''},
'vel': {'label': '', 'optionmenu': '', 'row': 3, 'col': 4, 'text': ''},
'trq': {'label': '', 'optionmenu': '', 'row': 3, 'col': 6, 'text': ''},
'trqh': {'label': '', 'optionmenu': '', 'row': 3, 'col': 8, 'text': ''},
'estop': {'label': '', 'optionmenu': '', 'row': 3, 'col': 10, 'text': ''},
'rc1': {'label': '', 'entry': '', 'row': 4, 'col': 2, 'text': '额定电流'},
'rc2': {'label': '', 'entry': '', 'row': 4, 'col': 4, 'text': '额定电流'},
'rc3': {'label': '', 'entry': '', 'row': 4, 'col': 6, 'text': '额定电流'},
'rc4': {'label': '', 'entry': '', 'row': 4, 'col': 8, 'text': '额定电流'},
'rc5': {'label': '', 'entry': '', 'row': 4, 'col': 10, 'text': '额定电流'},
'rc6': {'label': '', 'entry': '', 'row': 4, 'col': 12, 'text': '额定电流'},
}
class App(customtkinter.CTk): class App(customtkinter.CTk):
@ -24,14 +50,12 @@ class App(customtkinter.CTk):
# configure window # configure window
self.title("AIO - All in one automatic toolbox") self.title("AIO - All in one automatic toolbox")
# self.iconbitmap('./icon.ico') # self.iconbitmap('./icon.ico')
self.geometry("1180x550+30+30") self.geometry("1200x550+30+30")
self.protocol("WM_DELETE_WINDOW", self.func_end_call_back) self.protocol("WM_DELETE_WINDOW", self.func_end_callback)
self.config(bg='#E9E9E9') self.config(bg='#E9E9E9')
self.grid_rowconfigure(5, weight=1)
self.grid_rowconfigure(4, weight=1)
self.grid_columnconfigure((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), weight=1) self.grid_columnconfigure((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), weight=1)
self.minsize(1180, 550) self.minsize(1200, 550)
# ===================================================================== # =====================================================================
# create frame sidebar(left) # create frame sidebar(left)
self.frame_func = customtkinter.CTkFrame(self, width=120, corner_radius=0, fg_color='#E9E9E9') self.frame_func = customtkinter.CTkFrame(self, width=120, corner_radius=0, fg_color='#E9E9E9')
@ -39,139 +63,55 @@ class App(customtkinter.CTk):
# create AIO logo # create AIO logo
self.label_logo = customtkinter.CTkLabel(self.frame_func, text="Rokae AIO", height=60, font=customtkinter.CTkFont(family="Segoe Script Bold", size=24, weight="bold"), text_color="#4F4F4F") self.label_logo = customtkinter.CTkLabel(self.frame_func, text="Rokae AIO", height=60, font=customtkinter.CTkFont(family="Segoe Script Bold", size=24, weight="bold"), text_color="#4F4F4F")
self.label_logo.grid(row=0, column=0, padx=15, pady=15) self.label_logo.grid(row=0, column=0, padx=15, pady=15)
# create start button # create buttons
self.btn_start = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='开始运行', fg_color='#4F4F4F', font=self.my_font, command=lambda: self.thread_it(self.func_start_callback)) for func in btns:
self.btn_start.grid(row=1, column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5) btns[func]['btn'] = customtkinter.CTkButton(self.frame_func, corner_radius=10, text=btns[func]['text'], fg_color='#4F4F4F', font=self.my_font)
# create param check button btns[func]['btn'].grid(row=btns[func]['row'], column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5)
self.btn_check = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='检查参数', fg_color='#4F4F4F', font=self.my_font, command=lambda: self.thread_it(self.func_check_callback)) btns['start']['btn'].configure(command=lambda: self.thread_it(self.func_start_callback))
self.btn_check.grid(row=2, column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5) btns['check']['btn'].configure(command=lambda: self.thread_it(self.func_check_callback))
# create start button btns['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback))
self.btn_log = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='保存日志', fg_color='#4F4F4F', font=self.my_font, command=lambda: self.thread_it(self.func_log_callback)) btns['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback))
self.btn_log.grid(row=3, column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5)
# create start button
self.btn_end = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='结束运行', fg_color='#4F4F4F', font=self.my_font, command=self.func_end_call_back)
self.btn_end.grid(row=4, column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5)
# create version info # create version info
self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.1.4\nDate: 06/06/2024", font=self.my_font, text_color="#4F4F4F") self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.1.5.2\nDate: 06/13/2024", font=self.my_font, text_color="#4F4F4F")
self.frame_func.rowconfigure(6, weight=1) self.frame_func.rowconfigure(6, weight=1)
self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s') self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s')
# ===================================================================== # =====================================================================
# create frame # create tabviews
self.frame_param = customtkinter.CTkFrame(self, corner_radius=5, fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD') self.tabview = customtkinter.CTkTabview(self, width=10000, height=100, anchor='w', fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD')
self.frame_param.grid(row=0, column=1, rowspan=3, columnspan=13, sticky='new', ipadx=20, ipady=10, padx=10, pady=(5, 10)) self.tabview.grid(row=0, column=1, padx=10, pady=5, sticky="nsew")
self.tabview.add("Data Process")
self.tabview.add("Automatic Test")
# create main menu # create main menu
self.menu_main = customtkinter.CTkOptionMenu(self.frame_param, values=["INIT", "brake", "current", "iso"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback) self.menu_main_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["INIT", "brake", "current", "iso"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback)
self.menu_main.grid(row=0, column=1, sticky='we', padx=(20, 10), pady=(10, 5)) self.menu_main_dp.grid(row=1, column=1, sticky='we', padx=5, pady=5)
self.menu_main.set("Start Here!") self.menu_main_dp.set("Start Here!")
# create sub menu # create sub menu
self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param) self.menu_sub_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'))
# create path related # =====================================================================
self.label_path = customtkinter.CTkLabel(self.frame_param, text="Path", font=self.my_font) # create widgits
self.label_path.grid(row=0, column=2, sticky='e', pady=(10, 5)) for widgit in widgits:
self.entry_path = customtkinter.CTkEntry(self.frame_param, width=670, placeholder_text="数据文件夹路径", font=self.my_font) if widgit == 'path':
self.entry_path.grid(row=0, column=3, columnspan=11, padx=(5, 10), pady=(10, 5), sticky='we') widgits[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f'{widgit.upper()}', font=self.my_font)
self.entry_path.configure(state='disabled') widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=5)
# create av related widgits[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Data Process'), width=670, placeholder_text=widgits[widgit]['text'], font=self.my_font)
self.label_av = customtkinter.CTkLabel(self.frame_param, text="AV", font=self.my_font) widgits[widgit]['entry'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we')
self.label_av.grid(row=1, column=2, sticky='e', pady=(5, 5)) widgits[widgit]['entry'].configure(state='disabled')
self.entry_av = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"角速度", font=self.my_font) elif widgit in ['av', 'rc', 'rpm', 'rr', 'dur', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6']:
self.entry_av.grid(row=1, column=3, padx=(5, 10), pady=(5, 5), sticky='w') widgits[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f"{widgit.upper()}", font=self.my_font)
self.entry_av.configure(state='disabled') widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=5)
# create rc related widgits[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Data Process'), width=self.w_param, placeholder_text=f"{widgits[widgit]['text']}", font=self.my_font)
self.label_rc = customtkinter.CTkLabel(self.frame_param, text="RC", font=self.my_font) widgits[widgit]['entry'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, padx=(5, 10), pady=5, sticky='w')
self.label_rc.grid(row=1, column=4, sticky='e', pady=(5, 5)) widgits[widgit]['entry'].configure(state='disabled')
self.entry_rc = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"额定电流", font=self.my_font) elif widgit in ['axis', 'vel', 'trq', 'trqh', 'estop']:
self.entry_rc.grid(row=1, column=5, padx=(5, 10), pady=(5, 5), sticky='w') widgits[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f"{widgit.upper()}", font=self.my_font)
self.entry_rc.configure(state='disabled') widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=5)
# create rpm related widgits[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
self.label_rpm = customtkinter.CTkLabel(self.frame_param, text="RPM", font=self.my_font) widgits[widgit]['optionmenu'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, padx=(5, 10), pady=5, sticky='w')
self.label_rpm.grid(row=1, column=6, sticky='e', pady=(5, 5)) widgits[widgit]['optionmenu'].configure(state='disabled')
self.entry_rpm = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"额定转速", font=self.my_font)
self.entry_rpm.grid(row=1, column=7, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rpm.configure(state='disabled')
# create rr related
self.label_rr = customtkinter.CTkLabel(self.frame_param, text="RR", font=self.my_font)
self.label_rr.grid(row=1, column=8, sticky='e', pady=(5, 5))
self.entry_rr = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"减速比", font=self.my_font)
self.entry_rr.grid(row=1, column=9, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rr.configure(state='disabled')
# create duration related
self.label_dur = customtkinter.CTkLabel(self.frame_param, text="Dur", font=self.my_font)
self.label_dur.grid(row=1, column=10, sticky='e', pady=(5, 5))
self.entry_dur = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"周期", font=self.my_font)
self.entry_dur.grid(row=1, column=11, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_dur.configure(state='disabled')
# create axis related
self.label_axis = customtkinter.CTkLabel(self.frame_param, text="AXIS", font=self.my_font)
self.label_axis.grid(row=2, column=2, sticky='e', pady=(5, 5))
self.option_axis = customtkinter.CTkOptionMenu(self.frame_param, button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
self.option_axis.grid(row=2, column=3, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_axis.configure(state='disabled')
# create vel related
self.label_vel = customtkinter.CTkLabel(self.frame_param, text="Vel", font=self.my_font)
self.label_vel.grid(row=2, column=4, sticky='e', pady=(5, 5))
self.option_vel = customtkinter.CTkOptionMenu(self.frame_param, button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
self.option_vel.grid(row=2, column=5, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_vel.configure(state='disabled')
# create trq related
self.label_trq = customtkinter.CTkLabel(self.frame_param, text="Trq", font=self.my_font)
self.label_trq.grid(row=2, column=6, sticky='e', pady=(5, 5))
self.option_trq = customtkinter.CTkOptionMenu(self.frame_param, button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
self.option_trq.grid(row=2, column=7, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_trq.configure(state='disabled')
# create trqH related
self.label_trqh = customtkinter.CTkLabel(self.frame_param, text="TrqH", font=self.my_font)
self.label_trqh.grid(row=2, column=8, sticky='e', pady=(5, 5))
self.option_trqh = customtkinter.CTkOptionMenu(self.frame_param, button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
self.option_trqh.grid(row=2, column=9, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_trqh.configure(state='disabled')
# create STO related
self.label_sto = customtkinter.CTkLabel(self.frame_param, text="STO", font=self.my_font)
self.label_sto.grid(row=2, column=10, sticky='e', pady=(5, 5))
self.option_sto = customtkinter.CTkOptionMenu(self.frame_param, button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
self.option_sto.grid(row=2, column=11, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_sto.configure(state='disabled')
# create rc1
self.label_rc_1 = customtkinter.CTkLabel(self.frame_param, text="RC1", font=self.my_font)
self.label_rc_1.grid(row=3, column=2, sticky='e', pady=(5, 5))
self.entry_rc_1 = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"optional", font=self.my_font)
self.entry_rc_1.grid(row=3, column=3, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc_1.configure(state='disabled')
self.label_rc_2 = customtkinter.CTkLabel(self.frame_param, text="RC2", font=self.my_font)
self.label_rc_2.grid(row=3, column=4, sticky='e', pady=(5, 5))
self.entry_rc_2 = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"optional", font=self.my_font)
self.entry_rc_2.grid(row=3, column=5, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc_2.configure(state='disabled')
self.label_rc_3 = customtkinter.CTkLabel(self.frame_param, text="RC3", font=self.my_font)
self.label_rc_3.grid(row=3, column=6, sticky='e', pady=(5, 5))
self.entry_rc_3 = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"optional", font=self.my_font)
self.entry_rc_3.grid(row=3, column=7, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc_3.configure(state='disabled')
self.label_rc_4 = customtkinter.CTkLabel(self.frame_param, text="RC4", font=self.my_font)
self.label_rc_4.grid(row=3, column=8, sticky='e', pady=(5, 5))
self.entry_rc_4 = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"optional", font=self.my_font)
self.entry_rc_4.grid(row=3, column=9, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc_4.configure(state='disabled')
self.label_rc_5 = customtkinter.CTkLabel(self.frame_param, text="RC5", font=self.my_font)
self.label_rc_5.grid(row=3, column=10, sticky='e', pady=(5, 5))
self.entry_rc_5 = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"optional", font=self.my_font)
self.entry_rc_5.grid(row=3, column=11, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc_5.configure(state='disabled')
self.label_rc_6 = customtkinter.CTkLabel(self.frame_param, text="RC6", font=self.my_font)
self.label_rc_6.grid(row=3, column=12, sticky='e', pady=(5, 5))
self.entry_rc_6 = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"optional", font=self.my_font)
self.entry_rc_6.grid(row=3, column=13, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc_6.configure(state='disabled')
# ===================================================================== # =====================================================================
# create textbox # create textbox
self.textbox = customtkinter.CTkTextbox(self, wrap='none', font=customtkinter.CTkFont(family="consolas", size=14), text_color="blue", fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD', border_spacing=5) self.textbox = customtkinter.CTkTextbox(self, wrap='none', font=customtkinter.CTkFont(family="consolas", size=14), text_color="blue", fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD', border_spacing=5)
self.textbox.grid(row=4, column=1, rowspan=3, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew') self.textbox.grid(row=5, column=1, rowspan=2, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew')
self.textbox.configure(state='disabled') self.textbox.configure(state='disabled')
# ===================================================================== # =====================================================================
# version check # version check
@ -192,43 +132,15 @@ class App(customtkinter.CTk):
self.myThread.start() self.myThread.start()
def initialization(self): def initialization(self):
self.label_path.configure(text="Path", text_color="black") for widgit in widgits:
self.label_av.configure(text="AV", text_color="black") if widgit in ['path', 'av', 'rc', 'rpm', 'rr', 'dur', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6']:
self.label_rc.configure(text="RC", text_color="black") widgits[widgit]['label'].configure(text=f'{widgit.upper()}', text_color='black')
self.label_rpm.configure(text="RPM", text_color="black") widgits[widgit]['entry'].configure(placeholder_text=widgits[widgit]['text'], state='disabled')
self.label_rr.configure(text="RR", text_color="black") elif widgit in ['axis', 'vel', 'trq', 'trqh', 'estop']:
self.label_dur.configure(text="Dur", text_color="black") widgits[widgit]['label'].configure(text=f'{widgit.upper()}', text_color="black")
self.label_axis.configure(text="AXIS", text_color="black") widgits[widgit]['optionmenu'].configure(state='disabled')
self.label_vel.configure(text="Vel", text_color="black")
self.label_trq.configure(text="Trq", text_color="black")
self.label_trqh.configure(text="TrqH", text_color="black")
self.label_sto.configure(text="STO", text_color="black")
self.label_rc_1.configure(text="RC1", text_color="black")
self.label_rc_2.configure(text="RC2", text_color="black")
self.label_rc_3.configure(text="RC3", text_color="black")
self.label_rc_4.configure(text="RC4", text_color="black")
self.label_rc_5.configure(text="RC5", text_color="black")
self.label_rc_6.configure(text="RC6", text_color="black")
self.entry_path.configure(placeholder_text="数据文件夹路径", state="disabled") self.menu_sub_dp.grid_forget()
self.entry_av.configure(placeholder_text="角速度", state="disabled")
self.entry_rc.configure(placeholder_text="额定电流", state="disabled")
self.entry_rpm.configure(placeholder_text="额定转速", state="disabled")
self.entry_rr.configure(placeholder_text="减速比", state="disabled")
self.entry_dur.configure(placeholder_text="周期", state="disabled")
self.option_axis.configure(state="disabled")
self.option_vel.configure(state="disabled")
self.option_trq.configure(state="disabled")
self.option_trqh.configure(state="disabled")
self.option_sto.configure(state="disabled")
self.entry_rc_1.configure(placeholder_text="optional", state="disabled")
self.entry_rc_2.configure(placeholder_text="optional", state="disabled")
self.entry_rc_3.configure(placeholder_text="optional", state="disabled")
self.entry_rc_4.configure(placeholder_text="optional", state="disabled")
self.entry_rc_5.configure(placeholder_text="optional", state="disabled")
self.entry_rc_6.configure(placeholder_text="optional", state="disabled")
self.menu_sub.grid_forget()
self.textbox.delete(index1='1.0', index2='end') self.textbox.delete(index1='1.0', index2='end')
self.textbox.configure(state='disabled') self.textbox.configure(state='disabled')
@ -236,83 +148,61 @@ class App(customtkinter.CTk):
self.initialization() self.initialization()
if func_name == 'brake': if func_name == 'brake':
self.label_path.configure(text="Path", text_color='red') for widgit in widgits:
self.label_av.configure(text="AV", text_color='red') if widgit in ['path', 'av', 'rr']:
self.label_rr.configure(text="RR", text_color='red') widgits[widgit]['label'].configure(text_color='red')
self.label_axis.configure(text="AXIS", text_color='red') widgits[widgit]['entry'].configure(state='normal')
self.label_vel.configure(text="Vel", text_color='red') elif widgit in ['axis', 'vel', 'trq', 'estop']:
self.label_trq.configure(text="Trq", text_color='red') widgits[widgit]['label'].configure(text_color="red")
self.label_sto.configure(text="STO", text_color='red') widgits[widgit]['optionmenu'].configure(state='normal')
self.entry_path.configure(state="normal")
self.entry_av.configure(state="normal")
self.entry_rr.configure(state="normal")
self.option_axis.configure(state="normal")
self.option_vel.configure(state="normal")
self.option_trq.configure(state="normal")
self.option_sto.configure(state="normal")
elif func_name == 'current': elif func_name == 'current':
self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param, values=["max", "avg", "cycle"], font=self.my_font, command=self.func_sub_callback) self.menu_sub_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["max", "avg", "cycle"], font=self.my_font, button_color='red', fg_color='green', command=self.func_sub_callback)
self.menu_sub.grid(row=1, column=1, sticky='we', padx=(20, 10), pady=(5, 5)) self.menu_sub_dp.grid(row=2, column=1, sticky='we', padx=5, pady=5)
self.menu_sub.set("--select--") self.menu_sub_dp.set("--select--")
self.menu_sub_dp.configure(text_color='yellow')
self.label_path.configure(text="Path", text_color='red')
self.label_rc.configure(text="RC", text_color='blue')
self.label_trqh.configure(text="TrqH", text_color='red')
self.label_rc_1.configure(text="RC1", text_color='red')
self.label_rc_2.configure(text="RC2", text_color='red')
self.label_rc_3.configure(text="RC3", text_color='red')
self.label_rc_4.configure(text="RC4", text_color='red')
self.label_rc_5.configure(text="RC5", text_color='red')
self.label_rc_6.configure(text="RC6", text_color='red')
self.entry_path.configure(state="normal")
self.entry_rc.configure(state="normal", placeholder_text="optional")
self.option_trqh.configure(state="normal")
self.entry_rc_1.configure(state="normal", placeholder_text="额定电流")
self.entry_rc_2.configure(state="normal", placeholder_text="额定电流")
self.entry_rc_3.configure(state="normal", placeholder_text="额定电流")
self.entry_rc_4.configure(state="normal", placeholder_text="额定电流")
self.entry_rc_5.configure(state="normal", placeholder_text="额定电流")
self.entry_rc_6.configure(state="normal", placeholder_text="额定电流")
for widgit in widgits:
if widgit in ['path', 'rc', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6']:
color = 'blue' if widgit == 'rc' else 'red'
widgits[widgit]['label'].configure(text_color=color)
widgits[widgit]['entry'].configure(state='normal')
elif widgit in ['trqh',]:
widgits[widgit]['label'].configure(text_color="red")
widgits[widgit]['optionmenu'].configure(state='normal')
elif func_name == 'iso': elif func_name == 'iso':
self.label_path.configure(text="Path", text_color='red') for widgit in widgits:
self.entry_path.configure(state="normal") if widgit in ['path',]:
widgits[widgit]['label'].configure(text_color='red')
widgits[widgit]['entry'].configure(state='normal')
else: else:
self.initialization() self.initialization()
self.menu_main.set("Start Here!") self.menu_main_dp.set("Start Here!")
self.menu_main.configure(text_color='yellow')
def func_sub_callback(self, func_name): def func_sub_callback(self, func_name):
if func_name == "max": if func_name == "max":
self.label_rpm.configure(text="RPM", text_color='black') for widgit in widgits:
self.entry_rpm.configure(placeholder_text='额定转速', state="disabled") if widgit in ['rpm', 'dur']:
self.label_dur.configure(text="Dur", text_color='black') widgits[widgit]['label'].configure(text_color='black')
self.entry_dur.configure(state="disabled") widgits[widgit]['entry'].configure(state='disabled')
self.label_vel.configure(text="Vel", text_color='black') elif widgit in ['vel', 'trq']:
self.option_vel.configure(state="disabled") widgits[widgit]['label'].configure(text_color='black')
self.label_trq.configure(text="Trq", text_color='black') widgits[widgit]['optionmenu'].configure(state='disabled')
self.option_trq.configure(state="disabled")
elif func_name == 'avg': elif func_name == 'avg':
self.label_rpm.configure(text="RPM", text_color='black') for widgit in widgits:
self.entry_rpm.configure(placeholder_text='额定转速', state="disabled") if widgit in ['rpm', 'dur']:
self.label_dur.configure(text="Dur", text_color='black') widgits[widgit]['label'].configure(text_color='black')
self.entry_dur.configure(state="disabled") widgits[widgit]['entry'].configure(state='disabled')
self.label_vel.configure(text="Vel", text_color='black') elif widgit in ['vel', 'trq']:
self.option_vel.configure(state="disabled") widgits[widgit]['label'].configure(text_color='black')
self.label_trq.configure(text="Trq", text_color='black') widgits[widgit]['optionmenu'].configure(state='disabled')
self.option_trq.configure(state="disabled")
elif func_name == 'cycle': elif func_name == 'cycle':
self.label_rpm.configure(text="RPM", text_color='blue') for widgit in widgits:
self.entry_rpm.configure(state="normal", placeholder_text='额定转速') if widgit in ['rpm', 'dur']:
self.label_dur.configure(text="Dur", text_color='blue') widgits[widgit]['label'].configure(text_color='blue')
self.entry_dur.configure(state="normal", placeholder_text='周期') widgits[widgit]['entry'].configure(state='normal')
self.label_vel.configure(text="Vel", text_color='red') elif widgit in ['vel', 'trq']:
self.option_vel.configure(state="normal") widgits[widgit]['label'].configure(text_color="red")
self.label_trq.configure(text="Trq", text_color='red') widgits[widgit]['optionmenu'].configure(state='normal')
self.option_trq.configure(state="normal")
def write2textbox(self, text, wait=0, exitcode=0, color='blue'): def write2textbox(self, text, wait=0, exitcode=0, color='blue'):
self.textbox.tag_add(color, 'insert', 'end') self.textbox.tag_add(color, 'insert', 'end')
@ -347,60 +237,54 @@ class App(customtkinter.CTk):
return True return True
def check_param(self): def check_param(self):
func_name = self.menu_main.get() func_name = self.menu_main_dp.get()
if func_name == 'brake': if func_name == 'brake':
path = self.entry_path.get().strip(' ') path = widgits['path']['entry'].get().strip()
av = self.entry_av.get().strip('- ') av = widgits['av']['entry'].get().strip('- ')
rr = self.entry_rr.get().strip('- ') rr = widgits['rr']['entry'].get().strip('- ')
axis = self.option_axis.get() axis = widgits['axis']['optionmenu'].get()
vel = self.option_vel.get() vel = widgits['vel']['optionmenu'].get()
trq = self.option_trq.get() trq = widgits['trq']['optionmenu'].get()
sto = self.option_sto.get() estop = widgits['estop']['optionmenu'].get()
sub_func = self.menu_sub.get()
c1 = exists(path) c1 = exists(path)
c2 = self.is_float('required', av, rr) c2 = self.is_float('required', av, rr)
# c3 = rpm = 1 c3 = True if len({vel, trq, estop}) == 3 else False
c3 = True if len({vel, trq, sto}) == 3 else False
c4 = sub_func in ['industrial', 'cobot']
c5 = True if vel != trq else False
if c1 and c2 and c3 and c4 and c5: if c1 and c2 and c3:
return 1, path, float(av), float(rr), int(sto), int(axis), int(vel), int(trq) return 1, path, float(av), float(rr), int(axis), int(vel), int(trq), int(estop)
else: else:
return 0, 0 return 0, 0
# ======================================================= # =======================================================
elif func_name == 'current': elif func_name == 'current':
path = self.entry_path.get() path = widgits['path']['entry'].get().strip()
rc = self.entry_rc.get() rc = widgits['rc']['entry'].get().strip('- ')
rpm = self.entry_rpm.get() rpm = widgits['rpm']['entry'].get().strip()
dur = self.entry_dur.get() dur = widgits['dur']['entry'].get().strip()
vel = self.option_vel.get() rc1 = widgits['rc1']['entry'].get().strip()
trq = self.option_trq.get() rc2 = widgits['rc2']['entry'].get().strip()
trqh = self.option_trqh.get() rc3 = widgits['rc3']['entry'].get().strip()
sub = self.menu_sub.get() rc4 = widgits['rc4']['entry'].get().strip()
rc1 = self.entry_rc_1.get() rc5 = widgits['rc5']['entry'].get().strip()
rc2 = self.entry_rc_2.get() rc6 = widgits['rc6']['entry'].get().strip()
rc3 = self.entry_rc_3.get() vel = widgits['vel']['optionmenu'].get()
rc4 = self.entry_rc_4.get() trq = widgits['trq']['optionmenu'].get()
rc5 = self.entry_rc_5.get() trqh = widgits['trqh']['optionmenu'].get()
rc6 = self.entry_rc_6.get() sub = self.menu_sub_dp.get()
c0 = exists(path) c1 = exists(path)
c1 = sub in ['max', 'avg', 'cycle'] c2 = sub in ['max', 'avg', 'cycle']
c2 = self.is_float('optional', rc) c3 = self.is_float('optional', rc, rpm)
c3 = self.is_float('optional', rpm) c4 = self.is_float('required', rc1, rc2, rc3, rc4, rc5, rc6)
_ = [rc1, rc2, rc3, rc4, rc5, rc6]
c4 = self.is_float('required', *_)
c5 = c6 = True c5 = c6 = True
if sub == 'cycle': if sub == 'cycle':
c5 = True if vel != trq else False c5 = True if len({vel, trq}) == 2 else False
c6 = self.is_float('optional', dur) c6 = self.is_float('optional', dur)
if c0 and c1 and c2 and c3 and c4 and c5 and c6: if c1 and c2 and c3 and c4 and c5 and c6:
rcs = [] rcs = []
for x in _: for x in [rc1, rc2, rc3, rc4, rc5, rc6]:
rcs.append(float(x)) rcs.append(float(x))
rc = 0 if rc == '' else rc rc = 0 if rc == '' else rc
dur = 0 if sub != 'cycle' or dur == '' else dur dur = 0 if sub != 'cycle' or dur == '' else dur
@ -411,7 +295,7 @@ class App(customtkinter.CTk):
return 0, 0 return 0, 0
# ======================================================= # =======================================================
elif func_name == 'iso': elif func_name == 'iso':
path = self.entry_path.get() path = widgits['path']['entry'].get().strip()
c1 = exists(path) c1 = exists(path)
if c1: if c1:
return 3, path return 3, path
@ -426,11 +310,9 @@ class App(customtkinter.CTk):
flag, *args = self.check_param() flag, *args = self.check_param()
func_dict = {1: brake.main, 2: current.main, 3: iso.main} func_dict = {1: brake.main, 2: current.main, 3: iso.main}
if flag == 1: if flag == 1:
func_dict[flag](path=args[0], av=args[1], rr=args[2], sto=args[3], axis=args[4], vel=args[5], trq=args[6], w2t=self.write2textbox) func_dict[flag](path=args[0], av=args[1], rr=args[2], axis=args[3], vel=args[4], trq=args[5], estop=args[6], w2t=self.write2textbox)
elif flag == 2: elif flag == 2:
# tkinter.messagebox.showinfo(title="TBD", message="功能待实现......")
func_dict[flag](path=args[0], sub=args[1], rcs=args[2], vel=args[3], trq=args[4], trqh=args[5], dur=args[6], rpm=args[7], w2t=self.write2textbox) func_dict[flag](path=args[0], sub=args[1], rcs=args[2], vel=args[3], trq=args[4], trqh=args[5], dur=args[6], rpm=args[7], w2t=self.write2textbox)
elif flag == 3: elif flag == 3:
func_dict[flag](path=args[0], w2t=self.write2textbox) func_dict[flag](path=args[0], w2t=self.write2textbox)
@ -442,11 +324,13 @@ class App(customtkinter.CTk):
def func_check_callback(self): def func_check_callback(self):
self.textbox.configure(state='normal') self.textbox.configure(state='normal')
self.textbox.delete(index1='1.0', index2='end') self.textbox.delete(index1='1.0', index2='end')
flag, *args = self.check_param() flag, *args = self.check_param()
if flag: if flag:
tkinter.messagebox.showinfo(title="参数正确", message="所有参数形式上填写无误,可以开始运行!") tkinter.messagebox.showinfo(title="参数正确", message="所有参数形式上填写无误,可以开始运行!")
else: else:
tkinter.messagebox.showerror(title="参数错误", message="需要检查对应参数是否填写正确!", ) tkinter.messagebox.showerror(title="参数错误", message="需要检查对应参数是否填写正确!", )
self.textbox.configure(state='disabled') self.textbox.configure(state='disabled')
def func_log_callback(self): def func_log_callback(self):
@ -465,7 +349,7 @@ class App(customtkinter.CTk):
else: else:
tkinter.messagebox.showwarning(title="未能保存", message="日志数据为空,不可保存!") tkinter.messagebox.showwarning(title="未能保存", message="日志数据为空,不可保存!")
def func_end_call_back(self): def func_end_callback(self):
if tkinter.messagebox.askyesno(title="关闭程序", message="相关数据可能未保存,正在运行程序时有概率会损坏数据文件,确定要终止程序运行吗?"): if tkinter.messagebox.askyesno(title="关闭程序", message="相关数据可能未保存,正在运行程序时有概率会损坏数据文件,确定要终止程序运行吗?"):
self.destroy() self.destroy()

View File

@ -27,12 +27,12 @@ class GetThreadResult(Thread):
return None return None
def data_process(result_file, raw_data_dirs, av, rr, axis, vel, trq, w2t, sto): def data_process(result_file, raw_data_dirs, av, rr, axis, vel, trq, w2t, estop):
# 功能:完成一个结果文件的数据处理 # 功能:完成一个结果文件的数据处理
# 参数:结果文件,数据目录,以及预读取的参数 # 参数:结果文件,数据目录,以及预读取的参数
# 返回值:- # 返回值:-
file_name = result_file.split('\\')[-1] file_name = result_file.split('\\')[-1]
w2t(f"打开文件 {file_name} 需要 1min 左右", 1, 0, 'orange') w2t(f"正在打开文件 {file_name} 需要 1min 左右", 1, 0, 'orange')
global stop global stop
stop = 0 stop = 0
@ -55,21 +55,21 @@ def data_process(result_file, raw_data_dirs, av, rr, axis, vel, trq, w2t, sto):
# count = 1 # count = 1
# for data_file in data_files: # for data_file in data_files:
# now_doing_msg(data_file, 'start', w2t) # now_doing_msg(data_file, 'start', w2t)
# single_file_process(data_file, wb_result, count, av, rr, axis, vel, trq, w2t, sto) # single_file_process(data_file, wb_result, count, av, rr, axis, vel, trq, w2t, estop)
# count += 1 # count += 1
# now_doing_msg(data_file, 'done', w2t) # now_doing_msg(data_file, 'done', w2t)
# --------------------------------------------------- # ---------------------------------------------------
# 数据文件并行处理模式--------------------------------- # 数据文件并行处理模式---------------------------------
threads = [Thread(target=single_file_process, args=(data_files[0], wb_result, 1, av, rr, axis, vel, trq, w2t, sto)), threads = [Thread(target=single_file_process, args=(data_files[0], wb_result, 1, av, rr, axis, vel, trq, w2t, estop)),
Thread(target=single_file_process, args=(data_files[1], wb_result, 2, av, rr, axis, vel, trq, w2t, sto)), Thread(target=single_file_process, args=(data_files[1], wb_result, 2, av, rr, axis, vel, trq, w2t, estop)),
Thread(target=single_file_process, args=(data_files[2], wb_result, 3, av, rr, axis, vel, trq, w2t, sto))] Thread(target=single_file_process, args=(data_files[2], wb_result, 3, av, rr, axis, vel, trq, w2t, estop))]
[t.start() for t in threads] [t.start() for t in threads]
[t.join() for t in threads] [t.join() for t in threads]
# --------------------------------------------------- # ---------------------------------------------------
now_doing_msg(raw_data_dir, 'done', w2t) now_doing_msg(raw_data_dir, 'done', w2t)
now_doing_msg(result_file, 'done', w2t) now_doing_msg(result_file, 'done', w2t)
w2t(f"保存文件 {file_name} 需要 1min 左右", 1, 0, 'orange') w2t(f"正在保存文件 {file_name} 需要 1min 左右", 1, 0, 'orange')
stop = 0 stop = 0
t_excel = Thread(target=wb_result.save, args=(result_file, )) t_excel = Thread(target=wb_result.save, args=(result_file, ))
t_wait = Thread(target=w2t_local, args=('.', 1, w2t)) t_wait = Thread(target=w2t_local, args=('.', 1, w2t))
@ -138,9 +138,9 @@ def now_doing_msg(docs, flag, w2t):
elif flag == 'start' and file_type == 'file': elif flag == 'start' and file_type == 'file':
w2t(f"[{now}] 正在处理文件 {docs} 中的数据......") w2t(f"[{now}] 正在处理文件 {docs} 中的数据......")
elif flag == 'done' and file_type == 'dir': elif flag == 'done' and file_type == 'dir':
w2t(f"[{now}] 目录 {docs} 数据文件已处理完毕......") w2t(f"[{now}] 目录 {docs} 数据文件已处理完毕")
elif flag == 'done' and file_type == 'file': elif flag == 'done' and file_type == 'file':
w2t(f"[{now}] 文件 {docs} 数据已处理完毕......") w2t(f"[{now}] 文件 {docs} 数据已处理完毕")
def w2t_local(msg, wait, w2t): def w2t_local(msg, wait, w2t):
@ -153,7 +153,7 @@ def w2t_local(msg, wait, w2t):
break break
def single_file_process(data_file, wb_result, count, av, rr, axis, vel, trq, w2t, sto): def single_file_process(data_file, wb_result, count, av, rr, axis, vel, trq, w2t, estop):
# 功能:完成单个数据文件的处理 # 功能:完成单个数据文件的处理
# 参数:如上 # 参数:如上
# 返回值:- # 返回值:-
@ -163,11 +163,11 @@ def single_file_process(data_file, wb_result, count, av, rr, axis, vel, trq, w2t
result_sheet_name = find_result_sheet_name(conditions, count) result_sheet_name = find_result_sheet_name(conditions, count)
ws_result = wb_result[result_sheet_name] ws_result = wb_result[result_sheet_name]
row_start, row_end = find_row_start(data_file, df, conditions, av, rr, axis, vel, w2t, sto) row_start, row_end = find_row_start(data_file, df, conditions, av, rr, axis, vel, w2t, estop)
copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, sto) copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, estop)
def copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, sto): def copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, estop):
# 功能:将数据文件中有效数据拷贝至结果文件对应的 sheet # 功能:将数据文件中有效数据拷贝至结果文件对应的 sheet
# 参数:如上 # 参数:如上
# 返回值:- # 返回值:-
@ -177,20 +177,20 @@ def copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, sto):
for _row in range(row_start, row_end + 1): for _row in range(row_start, row_end + 1):
data.append(df.iloc[_row, vel-1]) data.append(df.iloc[_row, vel-1])
data.append(df.iloc[_row, trq-1]) data.append(df.iloc[_row, trq-1])
data.append(df.iloc[_row, trq-1]) data.append(df.iloc[_row, estop-1])
i = 0 i = 0
row_max = 2000 if row_end-row_start < 2000 else row_end-row_start+20 row_max = 2000 if row_end-row_start < 2000 else row_end-row_start+20
for _row in range(2, row_max): for _row in range(2, row_max):
try: try:
ws_result.cell(row=_row, column=0).value = data[i] ws_result.cell(row=_row, column=1).value = data[i]
ws_result.cell(row=_row, column=0).value = data[i+1] ws_result.cell(row=_row, column=2).value = data[i+1]
ws_result.cell(row=_row, column=0).value = data[i+2] ws_result.cell(row=_row, column=3).value = data[i+2]
i += 3 i += 3
except: except:
ws_result.cell(row=_row, column=0).value = None ws_result.cell(row=_row, column=1).value = None
ws_result.cell(row=_row, column=0).value = None ws_result.cell(row=_row, column=2).value = None
ws_result.cell(row=_row, column=0).value = None ws_result.cell(row=_row, column=3).value = None
def find_result_sheet_name(conditions, count): def find_result_sheet_name(conditions, count):
@ -205,31 +205,35 @@ def find_result_sheet_name(conditions, count):
return result_sheet_name return result_sheet_name
def find_row_start(data_file, df, conditions, av, rr, axis, vel, w2t, sto): def find_row_start(data_file, df, conditions, av, rr, axis, vel, w2t, estop):
# 功能:查找数据文件中有效数据的行号,也即最后一个速度下降的点位 # 功能:查找数据文件中有效数据的行号,也即最后一个速度下降的点位
# 参数:如上 # 参数:如上
# 返回值:速度下降点位,最后的数据点位 # 返回值:速度下降点位,最后的数据点位
ratio = float(conditions[2].removeprefix('speed'))/100 ratio = float(conditions[2].removeprefix('speed'))/100
speed_max = av * rr * ratio * 60 / 360 speed_max = av * rr * ratio * 60 / 360
row_max = df.index[-1] row_max = df.index[-1]
threshold = 30 if axis == 2 and conditions[0].removeprefix('load') == '100' else 10 # threshold = 30 if axis == 2 and conditions[0].removeprefix('load') == '100' else 10
threshold = 50
for _row in range(row_max, -1, -1): for _row in range(row_max, -1, -1):
if df.iloc[_row, sto-1] != 0: if df.iloc[_row, estop-1] != 0:
row_start = _row-100 if _row-100 > 0 else 0 row_start = _row-20 if _row-20 > 0 else 0
break break
else: else:
w2t(f"数据文件 {data_file} 采集的数据中没有 STO 为非 0 的情况,需要确认......", 0, 9, 'red') w2t(f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", 0, 9, 'red')
for _row in range(row_start, row_max): for _row in range(row_start, row_max):
if abs(df.iloc[_row, vel-1]) < 1: speed_row = (df.iloc[_row, vel-1] * 180) / 3.1415926 * rr * 60 / 360
if abs(speed_row) < 1:
row_end = _row+100 if _row+100 <= row_max else row_max row_end = _row+100 if _row+100 <= row_max else row_max
break break
else: else:
w2t(f"数据文件 {data_file} 最后的速度未降为零 ", 0, 10, 'red') w2t(f"数据文件 {data_file} 最后的速度未降为零 ", 0, 10, 'red')
if abs(df.iloc[row_start+50]-speed_max) > threshold: speed_estop = abs((df.iloc[row_start-10:row_start+10, vel-1].abs().mean() * 180) / 3.1415926 * rr * 60 / 360)
w2t(f"数据文件 {data_file} 未采集到指定百分比的最大速度,需要检查......") if abs(speed_estop-speed_max) > threshold:
filename = data_file.split('\\')[-1]
w2t(f"[speed_estop: {speed_estop:.2f} | shouldbe: {speed_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查", 0, 0, '#8A2BE2')
return row_start, row_end return row_start, row_end
@ -253,7 +257,7 @@ def traversal_files(path, w2t):
return dirs, files return dirs, files
def main(path, av, rr, sto, axis, vel, trq, w2t): def main(path, av, rr, axis, vel, trq, estop, w2t):
# 功能:执行处理所有数据文件 # 功能:执行处理所有数据文件
# 参数initialization函数的返回值 # 参数initialization函数的返回值
# 返回值:- # 返回值:-
@ -273,7 +277,7 @@ def main(path, av, rr, sto, axis, vel, trq, w2t):
continue continue
else: else:
now_doing_msg(result_file, 'start', w2t) now_doing_msg(result_file, 'start', w2t)
data_process(result_file, raw_data_dirs, av, rr, axis, vel, trq, w2t, sto) data_process(result_file, raw_data_dirs, av, rr, axis, vel, trq, w2t, estop)
# threads.append(Thread(target=data_process, args=(result_file, raw_data_dirs, AV, RR, RC, AXIS))) # threads.append(Thread(target=data_process, args=(result_file, raw_data_dirs, AV, RR, RC, AXIS)))
# [t.start() for t in threads] # [t.start() for t in threads]
# [t.join() for t in threads] # [t.join() for t in threads]
@ -291,4 +295,4 @@ def main(path, av, rr, sto, axis, vel, trq, w2t):
if __name__ == "__main__": if __name__ == "__main__":
stop = 0 stop = 0
main(path=argv[1], av=argv[2], rr=argv[3], sto=argv[4], axis=argv[5], vel=argv[6], trq=argv[7], w2t=argv[8]) main(path=argv[1], av=argv[2], rr=argv[3], axis=argv[4], vel=argv[5], trq=argv[6], estop=argv[7], w2t=argv[8])

View File

@ -181,7 +181,7 @@ def current_cycle(dur, data_files, rcs, vel, trq, trqh, rpm, w2t):
w2t("全部处理完毕") w2t("全部处理完毕")
def find_point(flag, df, _row_s, _row_e, w2t, exitcode, threshold, step, end_point): def find_point(data_file, pos, flag, df, _row_s, _row_e, w2t, exitcode, threshold, step, end_point):
if flag == 'lt': if flag == 'lt':
while _row_e > end_point: while _row_e > end_point:
speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean() speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean()
@ -192,7 +192,7 @@ def find_point(flag, df, _row_s, _row_e, w2t, exitcode, threshold, step, end_poi
else: else:
return _row_s, _row_e return _row_s, _row_e
else: else:
w2t(f"数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, exitcode, 'red') w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, exitcode, 'red')
elif flag == 'gt': elif flag == 'gt':
while _row_e > end_point: while _row_e > end_point:
speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean() speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean()
@ -203,7 +203,7 @@ def find_point(flag, df, _row_s, _row_e, w2t, exitcode, threshold, step, end_poi
else: else:
return _row_s, _row_e return _row_s, _row_e
else: else:
w2t(f"数据有误,需要检查,无法找到有效起始点或结束点...", 0, exitcode, 'red') w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, exitcode, 'red')
def p_single(wb, single, vel, trq, rpm, w2t): def p_single(wb, single, vel, trq, rpm, w2t):
@ -245,28 +245,28 @@ def p_single(wb, single, vel, trq, rpm, w2t):
speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean() speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean()
if speed_avg < 2: if speed_avg < 2:
# 过滤尾部为零无效数据 # 过滤尾部为零无效数据
_row_s, _row_e = find_point('lt', df, _row_s, _row_e, w2t, 1, threshold=2, step=_step, end_point=_end_point) _row_s, _row_e = find_point(data_file, 'a1', 'lt', df, _row_s, _row_e, w2t, 1, threshold=5, step=_step, end_point=_end_point)
# 找到第一个起始点 row_end继续找到有数据的部分后面有一段有效数据区 # 找到第一个起始点 row_end继续找到有数据的部分后面有一段有效数据区
row_end = _row_e - _adjust row_end = _row_e - _adjust
_row_e -= _end_point _row_e -= _end_point
_row_s -= _end_point _row_s -= _end_point
_row_s, _row_e = find_point('gt', df, _row_s, _row_e, w2t, 3, threshold=2, step=_step, end_point=_end_point) _row_s, _row_e = find_point(data_file, 'a2', 'gt', df, _row_s, _row_e, w2t, 3, threshold=5, step=_step, end_point=_end_point)
# 速度已经快要降为零了,继续寻找下一个速度上升点 # 速度已经快要降为零了,继续寻找下一个速度上升点
_row_e -= _end_point _row_e -= _end_point
_row_s -= _end_point _row_s -= _end_point
_row_s, _row_e = find_point('lt', df, _row_s, _row_e, w2t, 3, threshold=2, step=_step, end_point=_end_point) _row_s, _row_e = find_point(data_file, 'a3', 'lt', df, _row_s, _row_e, w2t, 3, threshold=5, step=_step, end_point=_end_point)
elif speed_avg > 2: elif speed_avg > 2:
# 过滤尾部非零无效数据 # 过滤尾部非零无效数据
_row_s, _row_e = find_point('gt', df, _row_s, _row_e, w2t, 2, threshold=2, step=_step, end_point=_end_point) _row_s, _row_e = find_point(data_file, 'b1', 'gt', df, _row_s, _row_e, w2t, 2, threshold=5, step=_step, end_point=_end_point)
# 找到第一个起始点 row_end继续找到有数据的部分后面有一段零数据区 # 找到第一个起始点 row_end继续找到有数据的部分后面有一段零数据区
row_end = _row_e - _adjust row_end = _row_e - _adjust
_row_e -= _end_point _row_e -= _end_point
_row_s -= _end_point _row_s -= _end_point
_row_s, _row_e = find_point('lt', df, _row_s, _row_e, w2t, 4, threshold=2, step=_step, end_point=_end_point) _row_s, _row_e = find_point(data_file, 'b2', 'lt', df, _row_s, _row_e, w2t, 4, threshold=5, step=_step, end_point=_end_point)
# 目前已经有一点的速度值了,继续往前搜寻下一个速度为零的点 # 目前已经有一点的速度值了,继续往前搜寻下一个速度为零的点
_row_e -= _end_point _row_e -= _end_point
_row_s -= _end_point _row_s -= _end_point
_row_s, _row_e = find_point('gt', df, _row_s, _row_e, w2t, 4, threshold=2, step=_step, end_point=_end_point) _row_s, _row_e = find_point(data_file, 'b3', 'gt', df, _row_s, _row_e, w2t, 4, threshold=5, step=_step, end_point=_end_point)
row_start = _row_s + _adjust row_start = _row_s + _adjust
data = [] data = []
@ -275,7 +275,7 @@ def p_single(wb, single, vel, trq, rpm, w2t):
data.append(df.iloc[row, 1]) data.append(df.iloc[row, 1])
i = 0 i = 0
for row in ws.iter_rows(min_row=2, min_col=2, max_row=15000, max_col=3): for row in ws.iter_rows(min_row=2, min_col=2, max_row=70000, max_col=3):
for cell in row: for cell in row:
try: try:
_ = f"{data[i]:.2f}" _ = f"{data[i]:.2f}"
@ -317,7 +317,7 @@ def p_scenario(wb, single, vel, trq, rpm, dur, w2t):
row_start = 300 row_start = 300
row_end = row_start + int(dur/cycle) row_end = row_start + int(dur/cycle)
if row_end > df.index[-1]: if row_end > df.index[-1]:
w2t(f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据...", 0, 9, 'red') w2t(f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", 0, 9, 'red')
data = [] data = []
for row in range(row_start, row_end): for row in range(row_start, row_end):
@ -325,7 +325,7 @@ def p_scenario(wb, single, vel, trq, rpm, dur, w2t):
data.append(df.iloc[row, 1]) data.append(df.iloc[row, 1])
i = 0 i = 0
for row in ws.iter_rows(min_row=2, min_col=2, max_row=15000, max_col=3): for row in ws.iter_rows(min_row=2, min_col=2, max_row=70000, max_col=3):
for cell in row: for cell in row:
try: try:
_ = f"{data[i]:.2f}" _ = f"{data[i]:.2f}"

View File

@ -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, 1, 4, 0), filevers=(0, 1, 5, 2),
prodvers=(0, 1, 4, 0), prodvers=(0, 1, 5, 2),
# 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.1.4 (2024-06-06)'), StringStruct('FileVersion', '0.1.5.2 (2024-06-13)'),
StringStruct('InternalName', 'AIO.exe'), StringStruct('InternalName', 'AIO.exe'),
StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'), StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'),
StringStruct('OriginalFilename', 'AIO.exe'), StringStruct('OriginalFilename', 'AIO.exe'),
StringStruct('ProductName', 'AIO'), StringStruct('ProductName', 'AIO'),
StringStruct('ProductVersion', '0.1.4 (2024-06-06)')]) StringStruct('ProductVersion', '0.1.5.2 (2024-06-13)')])
]), ]),
VarFileInfo([VarStruct('Translation', [1033, 1200])]) VarFileInfo([VarStruct('Translation', [1033, 1200])])
] ]

Binary file not shown.

9
aio/requirements.txt Normal file
View File

@ -0,0 +1,9 @@
openpyxl==3.1.2
pdfplumber==0.11.0
customtkinter==5.2.2
Jinja2==3.1.4
lxml==5.2.2
numpy==1.26.4
pandas==2.2.2
pillow==10.3.0
pyinstaller==6.7.0

View File

@ -1 +1 @@
0.1.4 @ 06/06/2024 0.1.5.2 @ 06/13/2024

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff