[modify]: 完成了电流处理的基本工作,包括框架搭建和思路整理,重写了max/avg以支持工业数据,新增加了duration的逻辑,中间状态,先保存一下

This commit is contained in:
gitea 2024-06-04 08:29:23 +08:00
parent afb862201a
commit 55514abc93
4 changed files with 223 additions and 74 deletions

View File

@ -1,25 +1,40 @@
### 程序功能 ### 程序功能
自动化处理制动性能采集的数据减少人工处理时长目前测试单轴可从原来的4-6h减少到15min
自动化测试数据处理工具,减少人工处理时长,提高测试数据处理的效率和准确度:
1. 制动数据单轴数据处理5min以内
2. 电机电流数据全部轴数据处理1min以内
3. ISO激光数据整理1min以内
### 使用方法 ### 使用方法
修改 configs.xlsx 配置文件中的一些参数(数据文件路径/减速比/最大角速度/额定电流),然后直接执行即可
点击可执行程序 AIO.exe然后选择功能根据提示填写必要参数点击运行即可
### 第三方库 ### 第三方库
```commandline ```commandline
# https://customtkinter.tomschimansky.com/documentation/packaging
pip3 install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pip3 install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
pip3 install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pip3 install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
pip3 install pywin32 -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pip3 install xlmx -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
pip3 install pdfplumber -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
pip3 install jinja2 -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
pip3 install Pillow -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pip3 install Pillow -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
python.exe -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn python.exe -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
pip3 install --upgrade --force-reinstall numpy -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
``` ```
### 打包方法 ### 打包方法
```commandline ```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
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
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 "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
``` ```
---
### 注意事项 ### 注意事项
#### 制动数据
```text ```text
1. 数据文件存储存储规则 1. 数据文件存储存储规则
数据文件,就是我们拍急停的时候,采集到的 .data 文件,正方向拍三次急停,会采集到三个 .data 文件,存储在同一个文件夹内,即每组(三个 .data 文件)文件必须存储在同一个文件夹内,数据文件的命名无要求, 数据文件,就是我们拍急停的时候,采集到的 .data 文件,正方向拍三次急停,会采集到三个 .data 文件,存储在同一个文件夹内,即每组(三个 .data 文件)文件必须存储在同一个文件夹内,数据文件的命名无要求,
@ -65,6 +80,26 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A
程序运行主要的耗时集中在打开,保存和关闭结果文件,第一次打开的时候会比较慢,是因为 excel 在做首次公式的计算保存关闭之后再打开会比较快一些另外如果在运行出错并重复运行程序的时候无响应或者出现异常请打开任务管理器关闭一切和excel相关的进程重新运行即可 程序运行主要的耗时集中在打开,保存和关闭结果文件,第一次打开的时候会比较慢,是因为 excel 在做首次公式的计算保存关闭之后再打开会比较快一些另外如果在运行出错并重复运行程序的时候无响应或者出现异常请打开任务管理器关闭一切和excel相关的进程重新运行即可
``` ```
#### 电机电流
1. 单独使用max/avg功能时对于文件命名同第二点存放数据的文件夹只允许有 .data 或者 .csv 文件且每次只能处理rc相同的轴的数据
2. cycle功能只处理单文件单轴数据可以批量处理所有轴但要确保遵守如下规则
a. 数据整理文件以 .xlsx 为后缀
b. 其他文件
A. 单轴j1_xxxxx.data/csv
B. 保持j1_hold_xxxx.data/csv
C. 所有文件放在同一个文件夹即可
d. 界面输入rc参数时需要输入所有轴的数据
#### ISO数据
所有文件放在同一个文件夹即可,命名规则如下:
a. ISO.pdf
b. ISO-V1000.pdf
c. ISO-V100.pdf
d. iso-results.xlsx
---
RELEASE CHANGES RELEASE CHANGES
@ -132,3 +167,10 @@ v0.1.2(2024/06/01)
2. 重新修改了README.md 2. 重新修改了README.md
3. 单独将rokae拉出来作为一个独立的repo进行维护与scripts分离 3. 单独将rokae拉出来作为一个独立的repo进行维护与scripts分离
v0.1.3(预计2024/06/06)-准备实现如下
1. AV/RR支持小数
2. 可处理电机电流单轴以及多轴数据,可根据需要进行参数设定处理不同轴的数据
3. 界面初始位置修改以及删除所有entry的长度设定因为设定无效
4. 修改了layout.xlsx布局增加了duration字段以及额外的RC行整体扩展了区域
5. 更改label/entry/optionmenu等控件的生成方式使用循环实现更加简洁和容易维护
6. 支持工业/协作两条产品线的数据处理

View File

@ -19,16 +19,17 @@ class App(customtkinter.CTk):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.my_font = customtkinter.CTkFont(family="Consolas", size=16, weight="bold") self.my_font = customtkinter.CTkFont(family="Consolas", size=16, weight="bold")
self.w_param = 96 self.w_param = 90
# ===================================================================== # =====================================================================
# 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')
screen_width = self.winfo_screenwidth() # screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight() # screen_height = self.winfo_screenheight()
width = screen_width - 200 # width = screen_width - 200
height = screen_height - 200 # height = screen_height - 200
self.geometry(f"{width}x{height}+{100}+{100}") # self.geometry(f"{width}x{height}+{100}+{100}")
self.geometry("1100x500+100+100")
self.protocol("WM_DELETE_WINDOW", self.func_end_call_back) self.protocol("WM_DELETE_WINDOW", self.func_end_call_back)
self.grid_rowconfigure(3, weight=1) self.grid_rowconfigure(3, weight=1)
@ -52,75 +53,81 @@ class App(customtkinter.CTk):
self.btn_log = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='保存日志', font=self.my_font, command=lambda: self.thread_it(self.func_log_callback)) self.btn_log = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='保存日志', font=self.my_font, command=lambda: self.thread_it(self.func_log_callback))
self.btn_log.grid(row=3, column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5) self.btn_log.grid(row=3, column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5)
# create start button # create start button
self.btn_end = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='结束运行', font=self.my_font, command=lambda: self.thread_it(self.func_end_call_back)) self.btn_end = customtkinter.CTkButton(self.frame_func, corner_radius=10, text='结束运行', 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) 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.2\nDate: 06/01/2024", font=self.my_font, text_color="DarkCyan") 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="DarkCyan")
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 frame
self.frame_param = customtkinter.CTkFrame(self, height=240, corner_radius=10) self.frame_param = customtkinter.CTkFrame(self, height=240, corner_radius=10)
self.frame_param.grid(row=0, column=1, rowspan=3, columnspan=9, sticky='new', ipadx=20, ipady=10, padx=10, pady=10) self.frame_param.grid(row=0, column=1, rowspan=3, columnspan=11, sticky='new', ipadx=20, ipady=10, padx=10, pady=(10, 5))
# create main menu # create main menu
self.menu_main = customtkinter.CTkOptionMenu(self.frame_param, values=["INIT", "brake", "current", "iso"], font=self.my_font, command=self.func_main_callback) self.menu_main = customtkinter.CTkOptionMenu(self.frame_param, values=["INIT", "brake", "current", "iso"], font=self.my_font, command=self.func_main_callback)
self.menu_main.grid(row=0, column=1, sticky='we', padx=(20, 10), pady=(10, 0)) self.menu_main.grid(row=0, column=1, sticky='we', padx=(20, 10), pady=(10, 5))
self.menu_main.set("Start Here!") self.menu_main.set("Start Here!")
# create sub menu # create sub menu
self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param) self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param)
# create path related # create path related
self.label_path = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="Path", font=self.my_font) self.label_path = customtkinter.CTkLabel(self.frame_param, text="Path", font=self.my_font)
self.label_path.grid(row=0, column=2, sticky='e', pady=(10, 5)) self.label_path.grid(row=0, column=2, sticky='e', pady=(10, 5))
self.entry_path = customtkinter.CTkEntry(self.frame_param, width=680, placeholder_text="数据文件夹路径", font=self.my_font) self.entry_path = customtkinter.CTkEntry(self.frame_param, width=670, placeholder_text="数据文件夹路径", font=self.my_font)
self.entry_path.grid(row=0, column=3, columnspan=7, padx=(5, 10), pady=(10, 5), sticky='we') self.entry_path.grid(row=0, column=3, columnspan=9, padx=(5, 10), pady=(10, 5), sticky='we')
self.entry_path.configure(state='disabled') self.entry_path.configure(state='disabled')
# create av related # create av related
self.label_av = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="AV", font=self.my_font) self.label_av = customtkinter.CTkLabel(self.frame_param, text="AV", font=self.my_font)
self.label_av.grid(row=1, column=2, sticky='e', pady=(5, 5)) self.label_av.grid(row=1, column=2, sticky='e', pady=(5, 5))
self.entry_av = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"角速度", font=self.my_font) self.entry_av = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"角速度", font=self.my_font)
self.entry_av.grid(row=1, column=3, padx=(5, 20), pady=(5, 5), sticky='w') self.entry_av.grid(row=1, column=3, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_av.configure(state='disabled') self.entry_av.configure(state='disabled')
# create rc related # create rc related
self.label_rc = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="RC", font=self.my_font) self.label_rc = customtkinter.CTkLabel(self.frame_param, text="RC", font=self.my_font)
self.label_rc.grid(row=1, column=4, sticky='e', pady=(5, 5)) self.label_rc.grid(row=1, column=4, sticky='e', pady=(5, 5))
self.entry_rc = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"额定电流", font=self.my_font) self.entry_rc = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"额定电流", font=self.my_font)
self.entry_rc.grid(row=1, column=5, padx=(5, 20), pady=(5, 5), sticky='w') self.entry_rc.grid(row=1, column=5, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rc.configure(state='disabled') self.entry_rc.configure(state='disabled')
# create rpm related # create rpm related
self.label_rpm = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="RPM", font=self.my_font) self.label_rpm = customtkinter.CTkLabel(self.frame_param, text="RPM", font=self.my_font)
self.label_rpm.grid(row=1, column=6, sticky='e', pady=(5, 5)) self.label_rpm.grid(row=1, column=6, sticky='e', pady=(5, 5))
self.entry_rpm = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"额定转速", font=self.my_font) 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, 20), pady=(5, 5), sticky='w') self.entry_rpm.grid(row=1, column=7, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rpm.configure(state='disabled') self.entry_rpm.configure(state='disabled')
# create rr related # create rr related
self.label_rr = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="RR", font=self.my_font) 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.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 = 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, 20), pady=(5, 5), sticky='w') self.entry_rr.grid(row=1, column=9, padx=(5, 10), pady=(5, 5), sticky='w')
self.entry_rr.configure(state='disabled') 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 # create axis related
self.label_axis = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="AXIS", font=self.my_font) 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.label_axis.grid(row=2, column=2, sticky='e', pady=(5, 5))
self.option_axis = customtkinter.CTkOptionMenu(self.frame_param, values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font) self.option_axis = customtkinter.CTkOptionMenu(self.frame_param, 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, 20), pady=(5, 5), sticky='w') self.option_axis.grid(row=2, column=3, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_axis.configure(state='disabled') self.option_axis.configure(state='disabled')
# create vel related # create vel related
self.label_vel = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="Vel", font=self.my_font) 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.label_vel.grid(row=2, column=4, sticky='e', pady=(5, 5))
self.option_vel = customtkinter.CTkOptionMenu(self.frame_param, values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font) self.option_vel = customtkinter.CTkOptionMenu(self.frame_param, 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, 20), pady=(5, 5), sticky='w') self.option_vel.grid(row=2, column=5, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_vel.configure(state='disabled') self.option_vel.configure(state='disabled')
# create trq related # create trq related
self.label_trq = customtkinter.CTkLabel(self.frame_param, width=self.w_param//10, text="Trq", font=self.my_font) 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.label_trq.grid(row=2, column=6, sticky='e', pady=(5, 5))
self.option_trq = customtkinter.CTkOptionMenu(self.frame_param, values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font) self.option_trq = customtkinter.CTkOptionMenu(self.frame_param, 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, 20), pady=(5, 5), sticky='w') self.option_trq.grid(row=2, column=7, padx=(5, 10), pady=(5, 5), sticky='w')
self.option_trq.configure(state='disabled') self.option_trq.configure(state='disabled')
# ===================================================================== # =====================================================================
# create textbox # create textbox
self.textbox = customtkinter.CTkTextbox(self, height=640, wrap='none', font=customtkinter.CTkFont(family="consolas", size=14), text_color="blue") self.textbox = customtkinter.CTkTextbox(self, height=640, wrap='none', font=customtkinter.CTkFont(family="consolas", size=14), text_color="blue")
self.textbox.grid(row=3, column=1, rowspan=5, columnspan=13, ipadx=10, ipady=10, padx=10, pady=10, sticky='nsew') self.textbox.grid(row=3, column=1, rowspan=5, columnspan=15, 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
@ -146,6 +153,7 @@ class App(customtkinter.CTk):
self.label_rc.configure(text="RC", text_color="black") self.label_rc.configure(text="RC", text_color="black")
self.label_rpm.configure(text="RPM", text_color="black") self.label_rpm.configure(text="RPM", text_color="black")
self.label_rr.configure(text="RR", text_color="black") self.label_rr.configure(text="RR", text_color="black")
self.label_dur.configure(text="Dur", text_color="black")
self.label_axis.configure(text="AXIS", text_color="black") self.label_axis.configure(text="AXIS", text_color="black")
self.label_vel.configure(text="Vel", text_color="black") self.label_vel.configure(text="Vel", text_color="black")
self.label_trq.configure(text="Trq", text_color="black") self.label_trq.configure(text="Trq", text_color="black")
@ -155,6 +163,7 @@ class App(customtkinter.CTk):
self.entry_rc.configure(placeholder_text="额定电流", state="disabled") self.entry_rc.configure(placeholder_text="额定电流", state="disabled")
self.entry_rpm.configure(placeholder_text="额定转速", state="disabled") self.entry_rpm.configure(placeholder_text="额定转速", state="disabled")
self.entry_rr.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_axis.configure(state="disabled")
self.option_vel.configure(state="disabled") self.option_vel.configure(state="disabled")
self.option_trq.configure(state="disabled") self.option_trq.configure(state="disabled")
@ -186,7 +195,7 @@ class App(customtkinter.CTk):
self.option_trq.configure(state="normal") self.option_trq.configure(state="normal")
elif func_name == 'current': elif func_name == 'current':
self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param, values=["max", "avg"], font=self.my_font, command=self.func_sub_callback) self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param, values=["max", "avg", "cycle"], font=self.my_font, command=self.func_sub_callback)
self.menu_sub.grid(row=1, column=1, sticky='we', padx=(20, 10), pady=(5, 5)) self.menu_sub.grid(row=1, column=1, sticky='we', padx=(20, 10), pady=(5, 5))
self.menu_sub.set("--select--") self.menu_sub.set("--select--")
@ -211,9 +220,21 @@ class App(customtkinter.CTk):
self.label_rpm.configure(text="RPM", text_color='black') self.label_rpm.configure(text="RPM", text_color='black')
self.entry_rpm.configure(state="disabled") self.entry_rpm.configure(state="disabled")
elif func_name == "max": elif func_name == "max":
pass self.label_dur.configure(text="Dur", text_color='black')
self.entry_dur.configure(state="disabled")
self.label_vel.configure(text="Vel", text_color='black')
self.option_vel.configure(state="disabled")
elif func_name == 'avg': elif func_name == 'avg':
pass self.label_dur.configure(text="Dur", text_color='black')
self.entry_dur.configure(state="disabled")
self.label_vel.configure(text="Vel", text_color='black')
self.option_vel.configure(state="disabled")
elif func_name == 'cycle':
self.label_dur.configure(text="*Dur", text_color='red')
self.entry_dur.configure(state="normal")
self.label_vel.configure(text="*Vel", text_color='red')
self.option_vel.configure(state="normal")
def write2textbox(self, text, wait=0, exitcode=0): def write2textbox(self, text, wait=0, exitcode=0):
if wait != 0: if wait != 0:
@ -245,47 +266,67 @@ class App(customtkinter.CTk):
sub_func = self.menu_sub.get() sub_func = self.menu_sub.get()
c1 = exists(path) c1 = exists(path)
c2 = av.isdigit() try:
c3 = rr.isdigit() _a = float(av)
c4 = rpm = 1 _b = float(rr)
c5 = sub_func in ['industrial', 'cobot'] c2 = True
c6 = True if vel != trq else False except:
c2 = False
c3 = rpm = 1
c4 = sub_func in ['industrial', 'cobot']
c5 = True if vel != trq else False
if self.menu_sub.get() == 'industrial': if self.menu_sub.get() == 'industrial':
rpm = self.entry_rpm.get().strip('- ') rpm = self.entry_rpm.get().strip('- ')
c4 = rpm.isdigit() c3 = rpm.isdigit()
elif self.menu_sub.get() == 'cobot': elif self.menu_sub.get() == 'cobot':
pass pass
else: else:
pass pass
if c1 and c2 and c3 and c4 and c5 and c6: if c1 and c2 and c3 and c4 and c5:
return 1, path, int(av), int(rr), int(rpm), int(axis), int(vel), int(trq) return 1, path, float(av), float(rr), int(rpm), int(axis), int(vel), int(trq)
else: else:
return 0, 0 return 0, 0
# =======================================================
elif func_name == 'current': elif func_name == 'current':
path = self.entry_path.get() path = self.entry_path.get()
rc = self.entry_rc.get() rc = self.entry_rc.get()
dur = self.entry_dur.get()
vel = self.option_vel.get() vel = self.option_vel.get()
trq = self.option_trq.get() trq = self.option_trq.get()
sub_func = self.menu_sub.get() sub = self.menu_sub.get()
c1 = exists(path) c1 = exists(path)
c2 = sub_func in ['max', 'avg', 'cycle'] c2 = sub in ['max', 'avg', 'cycle']
if sub_func == 'cycle':
c3 = True if vel != trq else False
else:
c3 = 1
try:
_ = float(rc)
c4 = True
except ValueError:
c4 = False
if c1 and c2 and c3 and c4: rcs = rc.split()
return 2, path, sub_func, float(rc), int(vel), int(trq) for _ in rcs:
try:
_t = float(_)
except:
c3 = False
break
else:
c3 = True
c4 = c5 = True
if sub == 'cycle':
try:
_ = float(dur)
c4 = True
except:
c4 = False
c5 = True if vel != trq else False
if c1 and c2 and c3 and c4 and c5:
rcs = []
for x in rc.split():
rcs.append(float(x))
dur = 0 if sub != 'cycle' else dur
return 2, path, sub, rcs, int(vel), int(trq), float(dur)
else: else:
return 0, 0 return 0, 0
# =======================================================
elif func_name == 'iso': elif func_name == 'iso':
path = self.entry_path.get() path = self.entry_path.get()
c1 = exists(path) c1 = exists(path)
@ -297,7 +338,6 @@ class App(customtkinter.CTk):
return 0, 0 return 0, 0
def func_start_callback(self): def func_start_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')
@ -308,7 +348,7 @@ class App(customtkinter.CTk):
func_dict[flag](path=args[0], av=args[1], rr=args[2], rpm=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], rpm=args[3], axis=args[4], vel=args[5], trq=args[6], w2t=self.write2textbox)
elif flag == 2: elif flag == 2:
# tkinter.messagebox.showinfo(title="TBD", message="功能待实现......") # tkinter.messagebox.showinfo(title="TBD", message="功能待实现......")
func_dict[flag](path=args[0], sub=args[1], rc=args[2], vel=args[3], trq=args[4], w2t=self.write2textbox) func_dict[flag](path=args[0], sub=args[1], rc=args[2], vel=args[3], trq=args[4], dur=args[5], 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)
else: else:

View File

@ -1,8 +1,8 @@
import openpyxl from openpyxl import load_workbook
from os import scandir from os import scandir
from os.path import exists from os.path import exists
from sys import argv from sys import argv
import pandas from pandas import read_csv
def traversal_files(path, w2t): def traversal_files(path, w2t):
@ -24,47 +24,114 @@ def traversal_files(path, w2t):
return dirs, files return dirs, files
def initialization(path, w2t): def initialization(path, sub, w2t):
_, data_files = traversal_files(path, w2t) _, data_files = traversal_files(path, w2t)
count = 0
for data_file in data_files: for data_file in data_files:
if not data_file.endswith('.data'): if sub != 'cycle':
msg = f"所有文件必须以 .data 结尾,请检查后重新运行。" if not (data_file.endswith('.data') or data_file.endswith('.csv')):
w2t(msg, 0, 2) msg = f"所有文件必须以 .data 结尾,请检查后重新运行。"
w2t(msg, 0, 2)
else:
if data_file.endswith('.xlsx'):
count += 1
elif not (data_file.endswith('.data') or data_file.endswith('.csv')):
msg = f"所有文件必须以 .data 结尾,请检查后重新运行。"
w2t(msg, 0, 3)
if sub == 'cycle' and count != 1:
w2t("未找到电机电流数据处理excel表格确认后重新运行", 0, 4)
return data_files return data_files
def current_max(data_files, rc, trq, w2t): def current_max(data_files, rc, trq, w2t):
current = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0}
for data_file in data_files: for data_file in data_files:
df = pandas.read_csv(data_file, sep='\t') if data_file.endswith('.data'):
df = read_csv(data_file, sep='\t')
elif data_file.endswith('.csv'):
df = read_csv(data_file, sep=',', encoding='gbk', header=8)
axis = int(data_file.split('\\')[-1].split('_')[0].removeprefix('j'))
rca = rc[axis-1]
col = df.columns.values[trq-1] col = df.columns.values[trq-1]
c_max = df[col].max() c_max = df[col].max()
w2t(f"{data_file}: {c_max/1000*rc:.4f}")
scale = 1 if data_file.endswith('.csv') else 1000
_ = abs(c_max/scale*rca)
current[axis] = _
w2t(f"{data_file}: {_:.4f}")
w2t("【MAX】数据处理完毕......") w2t("【MAX】数据处理完毕......")
return current
def current_avg(data_files, rc, trq, w2t): def current_avg(data_files, rc, trq, w2t):
current = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0}
for data_file in data_files: for data_file in data_files:
df = pandas.read_csv(data_file, sep='\t') if data_file.endswith('.data'):
col = df.columns.values[trq-1] df = read_csv(data_file, sep='\t')
elif data_file.endswith('.csv'):
df = read_csv(data_file, sep=',', encoding='gbk', header=8)
axis = int(data_file.split('\\')[-1].split('_')[0].removeprefix('j'))
rca = rc[axis-1]
col = df.columns.values[trq - 1]
c_std = df[col].std() c_std = df[col].std()
c_avg = df[col].mean() c_avg = df[col].mean()
w2t(f"{data_file}: {(abs(c_avg)+c_std)/1000*rc:.4f}") scale = 1 if data_file.endswith('.csv') else 1000
_ = (abs(c_avg)+c_std)/scale*rca
current[axis] = _
w2t(f"{data_file}: {_:.4f}")
w2t("【AVG】数据处理完毕......") w2t("【AVG】数据处理完毕......")
return current
def main(path, sub, rc, vel, trq, w2t): def current_cycle(dur, data_files, rc, vel, trq, w2t):
data_files = initialization(path, w2t) result = None
hold = []
single = []
for data_file in data_files:
if data_file.endswith('.xlsx'):
result = data_file
elif (data_file.endswith('.csv') or data_file.endswith('.data')) and data_file.startswith('hold', 3, 10):
hold.append(data_file)
else:
single.append(data_file)
if hold != []:
avg = current_avg(hold, rc, trq, w2t)
wb = load_workbook(result)
for k, v in avg.items():
try:
shtname = f"J{k}"
wb[shtname]["J4"].value = v
except:
pass
for data_file in single:
axis = int(data_file.split('\\')[-1].split('_')[0].removeprefix('j'))
rcs = rc[axis-1]
pass
# =======================================
def main(path, sub, rc, vel, trq, dur, w2t):
data_files = initialization(path, sub, w2t)
if sub == 'max': if sub == 'max':
current_max(data_files, rc, trq, w2t) current_max(data_files, rc, trq, w2t)
elif sub == 'avg': elif sub == 'avg':
current_avg(data_files, rc, trq, w2t) current_avg(data_files, rc, trq, w2t)
elif sub == 'cycle':
current_cycle(dur, data_files, rc, vel, trq, w2t)
else: else:
pass pass
if __name__ == '__main__': if __name__ == '__main__':
main(path=argv[1], sub=argv[2], rc=argv[3], vel=argv[4], trq=argv[5], w2t=argv[6]) main(*argv[1:])

Binary file not shown.