diff --git a/rokae/brake/brake.py b/rokae/brake/brake.py index ee44fdc..9c8aa0d 100644 --- a/rokae/brake/brake.py +++ b/rokae/brake/brake.py @@ -2,25 +2,15 @@ import os import sys import openpyxl -from win32com.client import DispatchEx import time from threading import Thread -import pythoncom import pandas -def just_open(filename): - pythoncom.CoInitialize() - xlapp = DispatchEx("Excel.Application") - xlapp.Visible = False - xlbook = xlapp.Workbooks.Open(filename) - xlapp.DisplayAlerts = 0 - xlbook.SaveAs(filename) - xlbook.Close() - xlapp.Quit() - - def traversal_files(path): + # 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录 + # 参数:路径 + # 返回值:路径下的文件夹列表 路径下的文件列表 if not os.path.exists(path): msg = f'数据文件夹{path}不存在,请确认后重试......' warn_pause_exit(msg, 1, 11) @@ -37,55 +27,57 @@ def traversal_files(path): def get_threshold_step(excel_file, AXIS): + # 功能:负载和速度100%,且是j2的时候,做特殊处理 + # 参数:新生成的excel,轴号 + # 返回值:速度差阈值,处理步长 conditions = sorted(excel_file.split('\\')[-2].split('_')) # 只有负载和速度是100%时,才会启用更敏感的step flg = 1 if conditions[0][-3:] == '100' and conditions[2][-3:] == '100' else 0 if flg == 1 and AXIS == 'j2': - threshold = 50 - step = 20 + threshold = 30 + step = 5 else: - threshold = 50 - step = 100 + threshold = 10 + step = 5 return threshold, step def find_row_start(excel_file, ws_data, conditions, AV, RR, AXIS): + # 功能:查找数据文件中有效数据的行号,也即最后一个速度下降的点位 + # 参数:如上 + # 返回值:速度下降点位,最后的数据点位 ratio = float(conditions[1].removeprefix('speed'))/100 speed_max = AV * ratio * RR / 6 - - row_max = ws_data.max_row - row_start = row_max - 1000 + row_max = row_start = ws_data.max_row threshold, step = get_threshold_step(excel_file, AXIS) - while row_start > 0: + while row_start > step+1: speed = ws_data[f"A{row_start}"].value if speed is None or int(speed) < 1: - row_start -= step + row_start -= 50 continue - - row_end = row_start - step - if row_end < 2: - msg = f"可能是{excel_file.replace('xlsx', 'data')}, 这个文件数据采集有问题,也有可能是程序步长设定问题......" \ - f"建议重新采集,或者先删除该文件夹,重新运行程序,先手动处理" - warn_pause_exit(msg, 1, 10) - _a = ws_data[f"A{row_start}"].value - _b = ws_data[f"A{row_end}"].value - if abs(_a-speed_max) < threshold and abs(_b-speed_max) < threshold and abs(_a-_b) < threshold: - row_start -= (step + 200) + _ = [] + for i in range(row_start, row_start-step+1, -1): + _.append(ws_data[f"A{i}"].value) + speed_avg = abs(sum(_))/len(_) + if abs(speed_avg-speed_max) < threshold: + row_start = row_start - 10 break else: row_start -= step else: os.remove(excel_file) - msg = f"可能是{excel_file.replace('xlsx', 'data')},这个文件数据采集有问题,比如采集的时机不对,请检查......" + msg = f"可能是{excel_file.replace('xlsx', 'data')},这个文件数据采集有问题,比如采集的时机不对,也有可能是程序步长设定问题,请检查......" warn_pause_exit(msg, 1, 9) return row_max, row_start def find_result_sheet_name(conditions, count): - # 该函数比较简单,功能是获取结果文件准确的sheet页名称 + # 功能:获取结果文件准确的sheet页名称 + # 参数:臂展和速度的列表 + # 返回值:结果文件对应的sheet name # 33%臂展_33%速度_正1 reach = conditions[0].removeprefix('reach') speed = conditions[1].removeprefix('speed') @@ -95,12 +87,17 @@ def find_result_sheet_name(conditions, count): def copy_data_to_result(ws_data, ws_result, row_max, row_start): + # 功能:将数据文件中有效数据拷贝至结果文件对应的 sheet + # 参数:如上 + # 返回值:- # 结果文件数据清零 - for row in ws_result.iter_rows(min_row=2, min_col=1, max_row=6000 - row_start + 2, max_col=2): + for row in ws_result.iter_rows(min_row=2, min_col=1, max_row=2000, max_col=2): for cell in row: cell.value = None # 将合适的数据复制到结果文件 + row_max = row_start + 399 if row_max-row_start > 400 else row_max + data = [] for row in ws_data.iter_rows(min_row=row_start, min_col=1, max_row=row_max, max_col=2): for cell in row: @@ -112,74 +109,16 @@ def copy_data_to_result(ws_data, ws_result, row_max, row_start): i = i + 1 -def copy_data_to_excel_file(wb_data, ws_result, row_max, row_start, excel_file, RC, RR): - try: - del wb_data['dp'] - wb_data.create_sheet('dp') - ws_dp = wb_data['dp'] - except Exception as Err: - wb_data.create_sheet('dp') - ws_dp = wb_data['dp'] - - data = [] - for row in ws_result.iter_rows(min_row=1, min_col=1, max_row=row_max-row_start+2, max_col=5): - for cell in row: - data.append(cell.value) - i = 0 - for row in ws_dp.iter_rows(min_row=1, min_col=1, max_row=row_max-row_start+2, max_col=5): - for cell in row: - cell.value = data[i] - i = i + 1 - - ws_dp.cell(row=5, column=7).value = RC - ws_dp.cell(row=6, column=7).value = RR - - wb_data.save(excel_file) - wb_data.close() - just_open(excel_file) # 为了能读取到公式计算的数值,必须要用 win32com 打开关闭一次 - wb_data = openpyxl.load_workbook(excel_file, data_only=True) - ws_dp = wb_data['dp'] - - return wb_data, ws_dp - - -def find_row_start_dp(data_file, ws_dp, row_max, row_start, conditions, AV): - ratio = float(conditions[1].removeprefix('speed'))/100 - av_max = AV * ratio - row_max_dp = row_max - row_start + 1 + 1 # title row - row_start_dp = row_max_dp - 5 - while row_start_dp > 6: - # 处理异常数据:当从数据文件中拷贝的有效数据超过5000时,会触发下面代码块 - angular = ws_dp.cell(row=row_start_dp, column=4).value - if angular is None or str(angular) == '0': - row_start_dp -= 50 - continue - _a = float(ws_dp.cell(row=row_start_dp, column=4).value) - _b = float(ws_dp.cell(row=row_start_dp - 1, column=4).value) - _c = float(ws_dp.cell(row=row_start_dp - 2, column=4).value) - _d = float(ws_dp.cell(row=row_start_dp - 3, column=4).value) - _e = float(ws_dp.cell(row=row_start_dp - 4, column=4).value) - avg = (_a + _b + _c + _d + _e) / 5 - if abs(avg - av_max) < 1: - row_start_dp = row_start_dp + 10 - 5 # +10 是因为结果文件 C2 的值是 10,-5是做了保守处理,相当于再往前移动 5 个点位 - break - else: - row_start_dp -= 5 # 保守一点,每次移动 5 个点位,如果想要加快程序运行,可适当调整更大一些,建议不超过 15 - else: - msg = "数据有误,未找到平衡的点,请确认!" - warn_pause_exit(msg, 1, 1) - - return row_start_dp - - def single_file_process(data_file, wb_result, count, AV, RR, RC, AXIS): + # 功能:完成单个数据文件的处理 + # 参数:如上 + # 返回值:- excel_file = data_file.replace('.data', '.xlsx') sheet_name = data_file.split('\\')[-1].removesuffix('.data') df = pandas.read_csv(data_file, sep='\t') df.to_excel(excel_file, sheet_name=sheet_name, index=False) conditions = sorted(data_file.split('\\')[-2].split('_')[1:]) - # print(f"conditions = {conditions}") result_sheet_name = find_result_sheet_name(conditions, count) ws_result = wb_result[result_sheet_name] @@ -188,16 +127,17 @@ def single_file_process(data_file, wb_result, count, AV, RR, RC, AXIS): row_max, row_start = find_row_start(excel_file, ws_data, conditions, AV, RR, AXIS) copy_data_to_result(ws_data, ws_result, row_max, row_start) - wb_data, ws_dp = copy_data_to_excel_file(wb_data, ws_result, row_max, row_start, excel_file, RC, RR) - row_start_dp = find_row_start_dp(data_file, ws_dp, row_max, row_start, conditions, AV) - - ws_result["G2"] = int(row_start_dp) + ws_result["C2"] = int(2) + ws_result["G2"] = int(10+4) wb_data.save(excel_file) wb_data.close() def now_doing_msg(docs, flag): + # 功能:输出正在处理的文件或目录 + # 参数:文件或目录,start 或 done 标识 + # 返回值:- now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) file_type = 'file' if os.path.isfile(docs) else 'dir' if flag == 'start' and file_type == 'dir': @@ -211,6 +151,9 @@ def now_doing_msg(docs, flag): def data_process(result_file, raw_data_dirs, AV, RR, RC, AXIS): + # 功能:完成一个结果文件的数据处理 + # 参数:结果文件,数据目录,以及预读取的参数 + # 返回值:- prefix = result_file.split('\\')[-1].split('_')[0] wb_result = openpyxl.load_workbook(result_file) # 打开和关闭结果文件夹十分耗时间 for raw_data_dir in raw_data_dirs: @@ -220,12 +163,11 @@ def data_process(result_file, raw_data_dirs, AV, RR, RC, AXIS): # 数据文件串行处理模式--------------------------------- # count = 1 # for data_file in data_files: - # now_doing_msg(data_file, 'start') - # single_file_process(data_file, wb_result, count, AV, RR, RC, AXIS) - # count += 1 - # now_doing_msg(data_file, 'done') + # now_doing_msg(data_file, 'start') + # single_file_process(data_file, wb_result, count, AV, RR, RC, AXIS) + # count += 1 + # now_doing_msg(data_file, 'done') # --------------------------------------------------- - # 数据文件并行处理模式--------------------------------- threads = [Thread(target=single_file_process, args=(data_files[0], wb_result, 1, AV, RR, RC, AXIS)), Thread(target=single_file_process, args=(data_files[1], wb_result, 2, AV, RR, RC, AXIS)), @@ -242,6 +184,9 @@ def data_process(result_file, raw_data_dirs, AV, RR, RC, AXIS): def warn_pause_exit(msg, pause_num, exit_num): + # 功能:打印告警信息,并推出程序 + # 参数:告警信息,暂停的次数,退出的值 + # 返回值:- print(msg + '\n') for i in range(pause_num): _ = input("Press ENTER to continue......\n") @@ -249,6 +194,9 @@ def warn_pause_exit(msg, pause_num, exit_num): def check_files(raw_data_dirs, result_files): + # 功能:检查数据文件以及结果文件的合规性 + # 参数:数据文件夹,结果文件 + # 返回值:- if len(result_files) != 3: msg = "结果文件数目错误,结果文件有且只有三个,请确认!" for result_file in result_files: @@ -299,6 +247,9 @@ def check_files(raw_data_dirs, result_files): def delete_excel_files(raw_data_dirs): + # 功能:删除数据文件夹里的 .xlsx 文件 + # 参数:数据文件夹 + # 返回值:- for raw_data_dir in raw_data_dirs: _, raw_data_files = traversal_files(raw_data_dir) for raw_data_file in raw_data_files: @@ -307,6 +258,9 @@ def delete_excel_files(raw_data_dirs): def initialization(): + # 功能:初始化,记录开始时间,读取预定义参数 + # 参数:- + # 返回值:结果文件,数据文件夹,以及预定义参数 time_start = time.time() # 记录开始时间 try: # read init configurations from config file @@ -331,6 +285,9 @@ def initialization(): def execution(args): + # 功能:执行处理所有数据文件 + # 参数:initialization函数的返回值 + # 返回值:- raw_data_dirs, result_files, time_start, AV, RR, RC, AXIS = args prefix = [] for raw_data_dir in raw_data_dirs: diff --git a/rokae/brake/configs.xlsx b/rokae/brake/configs.xlsx index a23a93b..06657b6 100644 Binary files a/rokae/brake/configs.xlsx and b/rokae/brake/configs.xlsx differ diff --git a/rokae/brake/file_version_info.txt b/rokae/brake/file_version_info.txt index 796b35c..05e1c53 100644 --- a/rokae/brake/file_version_info.txt +++ b/rokae/brake/file_version_info.txt @@ -6,8 +6,8 @@ VSVersionInfo( ffi=FixedFileInfo( # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) # Set not needed items to zero 0. - filevers=(0, 0, 4, 0), - prodvers=(0, 0, 4, 0), + filevers=(0, 0, 5, 0), + prodvers=(0, 0, 5, 0), # Contains a bitmask that specifies the valid bits 'flags'r mask=0x3f, # Contains a bitmask that specifies the Boolean attributes of the file. @@ -31,12 +31,12 @@ VSVersionInfo( '040904b0', [StringStruct('CompanyName', 'Rokae - https://www.rokae.com/'), StringStruct('FileDescription', 'All in one automatic operating tool'), - StringStruct('FileVersion', '0.0.4 (2024-05-20)'), + StringStruct('FileVersion', '0.0.5 (2024-05-20)'), StringStruct('InternalName', 'AIO.exe'), StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'), StringStruct('OriginalFilename', 'AIO.exe'), StringStruct('ProductName', 'AIO'), - StringStruct('ProductVersion', '0.0.4 (2024-05-20)')]) + StringStruct('ProductVersion', '0.0.5 (2024-05-20)')]) ]), VarFileInfo([VarStruct('Translation', [1033, 1200])]) ]