import threading import openpyxl import pandas import re import csv from common import clibs def initialization(path, w2t, insert_logdb): _, data_files = clibs.traversal_files(path, w2t) count = 0 for data_file in data_files: filename = data_file.split("/")[-1] if filename == "configs.xlsx": count += 1 elif filename == "T_电机电流.xlsx": ... else: if not re.match("j[1-7].*\\.data", filename): msg = f"不合规 {data_file}\n" msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾,比如j1_abcdef.data\n配置文件需要命名为\"configs.xlsx\",结果文件需要命名为\"T_电机电流.xlsx\"\n" msg += "需要有配置文件\"configs.xlsx\"表格,以及数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行\n" w2t(msg, "red", "FilenameIllegal") if count != 1: msg = "需要有配置文件\"configs.xlsx\"表格,以及数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行\n" w2t(msg, "red", "FilenameIllegal") insert_logdb("INFO", "current", f"current: 获取必要文件:{data_files}") return data_files def current_max(data_files, rcs, trq, w2t, insert_logdb): insert_logdb("INFO", "current", "MAX: 正在处理最大电流值逻辑...") current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []} for data_file in data_files: if data_file.endswith(".data"): df = pandas.read_csv(data_file, sep="\t") else: continue insert_logdb("INFO", "current", f"MAX: 正在处理 {data_file}") cols = len(df.columns) axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j")) rca = rcs[axis-1] insert_logdb("INFO", "current", f"MAX: 最大列数为 {cols},{axis} 轴的额定电流为 {rca}") col = df.columns.values[trq-1] # 获取 "device_servo_trq_feedback" c_max = df[col].abs().max() scale = 1000 _ = abs(c_max/scale*rca) current[axis].append(_) w2t(f"{data_file}: {_:.4f}\n") insert_logdb("INFO", "current", f"MAX: 获取到的列名为 {col},最大电流为 {_}") with open(data_file, "a+") as f_data: csv_writer = csv.writer(f_data, delimiter="\t") csv_writer.writerow([""] * (cols-1) + [_]) for axis, cur in current.items(): if not cur: continue else: w2t(f"{axis}轴数据:") for value in cur: w2t(f"{value:.4f} ") w2t("\n") w2t("\n【MAX】数据处理完毕......") insert_logdb("INFO", "current", f"MAX: 获取最大电流值结束 current_max = {current}") return current def current_avg(data_files, rcs, trq, w2t, insert_logdb): insert_logdb("INFO", "current", "AVG: 正在处理平均电流值逻辑...") current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []} for data_file in data_files: if data_file.endswith(".data"): df = pandas.read_csv(data_file, sep="\t") else: continue insert_logdb("INFO", "current", f"AVG: 正在处理 {data_file}") cols = len(df.columns) axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j")) rca = rcs[axis-1] insert_logdb("INFO", "current", f"AVG: 最大列数为 {cols},{axis} 轴的额定电流为 {rca}") col = df.columns.values[trq-1] c_std = df[col].std() c_avg = df[col].mean() scale = 1000 _ = (abs(c_avg)+c_std*3)/scale*rca current[axis].append(_) w2t(f"{data_file}: {_:.4f}\n") insert_logdb("INFO", "current", f"AVG: 获取到的列名为 {col},平均电流为 {_}") with open(data_file, "a+") as f_data: csv_writer = csv.writer(f_data, delimiter="\t") csv_writer.writerow([""] * (cols-1) + [_]) for axis, cur in current.items(): if not cur: continue else: w2t(f"{axis}轴数据:") for value in cur: w2t(f"{value:.4f} ") w2t("\n") w2t("\n【AVG】数据处理完毕......\n") insert_logdb("INFO", "current", f"AVG: 获取平均电流值结束 current_avg = {current}") return current def current_cycle(data_files, vel, trq, trqh, rrs, rcs, rpms, w2t, insert_logdb): result, hold, single, scenario, dur_time = None, [], [], [], 0 for data_file in data_files: filename = data_file.split("/")[-1] if filename == "T_电机电流.xlsx": result = data_file elif re.match("j[1-7]_hold_.*\\.data", filename): hold.append(data_file) elif re.match("j[1-7]_s_.*\\.data", filename): scenario.append(data_file) dur_time = float(filename.split("_")[3]) elif re.match("j[1-7]_.*\\.data", filename): single.append(data_file) clibs.stop = True w2t(f"正在打开文件 {result},需要 10s 左右......\n") t_excel = clibs.GetThreadResult(openpyxl.load_workbook, args=(result, )) t_excel.daemon = True t_excel.start() t_progress = threading.Thread(target=clibs.tl_prg, args=("Processing......", )) t_progress.daemon = True t_progress.start() wb = t_excel.get_result() if hold: avg = current_avg(hold, rcs, trqh, w2t, insert_logdb) for axis, cur_value in avg.items(): sht_name = f"J{axis}" wb[sht_name]["O4"].value = float(cur_value[0]) if dur_time == 0: p_single(wb, single, vel, rrs, w2t, insert_logdb) else: p_scenario(wb, scenario, vel, rrs, dur_time, w2t, insert_logdb) clibs.stop = True w2t(f"正在保存文件 {result},需要 10s 左右......\n") t_excel = threading.Thread(target=wb.save, args=(result, )) t_excel.daemon = True t_excel.start() t_excel.join() clibs.stop = False t_progress.join() w2t("----------------------------------------------------------\n") w2t("全部处理完毕") def find_point(data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq, w2t, insert_logdb): if flag == "lt": while row_e > end_point: speed_avg = df.iloc[row_s:row_e].abs().mean() if speed_avg < threshold: row_e -= step row_s -= step continue else: # one more time,如果连续两次 200 个点的平均值都大于 2,说明已经到了临界点了(其实也不一定,只不过相对遇到一次就判定临界点更安全一点点) # 从实际数据看,这开逻辑很小概率能触发到 speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean() if speed_avg < threshold: insert_logdb("WARNING", "current", f"【lt】{axis} 轴第 {seq} 次查找数据有异常,row_s = {row_s}, row_e = {row_e}!") row_e -= end_point*skip_scale row_s -= end_point*skip_scale continue else: return row_s, row_e else: w2t(f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点...", "red", "AnchorNotFound") elif flag == "gt": while row_e > end_point: speed_avg = df.iloc[row_s:row_e].abs().mean() # if axis == 1 and seq == 1: # insert_logdb("DEBUG", "current", f"【gt】{axis} 轴,speed_avg = {speed_avg},row_s = {row_s}, row_e = {row_e}!") if speed_avg > threshold: row_e -= step row_s -= step continue else: # one more time,如果连续两次 200 个点的平均值都小于 2,说明已经到了临界点了(其实也不一定,只不过相对遇到一次就判定临界点更安全一点点) # 从实际数据看,这开逻辑很小概率能触发到 speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean() if speed_avg > threshold: insert_logdb("WARNING", "current", f"【gt】{axis} 轴第 {seq} 次查找数据有异常,row_s = {row_s}, row_e = {row_e}!") row_e -= end_point*skip_scale row_s -= end_point*skip_scale continue else: return row_s, row_e else: w2t(f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点...", "red", "AnchorNotFound") def get_row_number(threshold, flag, df, row_s, row_e, axis, insert_logdb): count_1, count_2 = 0, 0 if flag == "start" or flag == "end": for number in df.iloc[row_s:row_e].abs(): count_2 += 1 if number > threshold: count_1 += 1 if count_1 == 10: return row_s + count_2 - 10 else: count_1 = 0 elif flag == "middle": for number in df.iloc[row_s:row_e].abs(): count_2 += 1 if number < threshold: # 唯一的区别 count_1 += 1 if count_1 == 10: return row_s + count_2 - 10 else: count_1 = 0 places = {"start": "起点", "middle": "中间点", "end": "终点"} insert_logdb("WARNING", "current", f"{axis} 轴获取{places[flag]}数据 {row_e} 可能有异常,需关注!") return row_e def p_single(wb, single, vel, rrs, w2t, insert_logdb): # 1. 先找到第一个速度为零的点,数据从后往前找,一开始就是零的情况不予考虑 # 2. 记录第一个点的位置,继续向前查找第二个速度为零的点,同理,一开始为零的点不予考虑 # 3. 记录第二个点的位置,并将其中的数据拷贝至对应位置 for data_file in single: axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j")) sht_name = f"J{axis}" ws = wb[sht_name] pandas.set_option("display.precision", 2) df_origin = pandas.read_csv(data_file, sep="\t") rr = rrs[axis-1] addition = 180 / 3.1415926 * 60 / 360 * rr col_names = list(df_origin.columns) df = df_origin[col_names[vel-1]].multiply(addition) step = 50 # 步进值 end_point = 200 # 有效数值的数目 threshold = 2 # 200个点的平均阈值线 skip_scale = 2 row_start, row_middle, row_end = 0, 0, 0 row_e = df.index[-1] row_s = row_e - end_point speed_avg = df.iloc[row_s:row_e].abs().mean() if speed_avg < 2: # 第一次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点 row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 0, w2t, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 第二次过滤:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 0, w2t, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 第三次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点 row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 0, w2t, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 正式第一次采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 1, w2t, insert_logdb) row_end = get_row_number(threshold, "end", df, row_s, row_e, axis, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 正式第二次采集:消除速度为零的数据,找到速度即将大于零的上升临界点 row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 2, w2t, insert_logdb) row_middle = get_row_number(threshold, "middle", df, row_s, row_e, axis, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 正式第三次采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 3, w2t, insert_logdb) row_start = get_row_number(threshold, "start", df, row_s, row_e, axis, insert_logdb) elif speed_avg > 2: # 第一次过滤:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 0, w2t, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 第二次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点 row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 0, w2t, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 第一次正式采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 1, w2t, insert_logdb) row_end = get_row_number(threshold, "end", df, row_s, row_e, axis, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 第二次正式采集:消除速度为零的数据,找到速度即将大于零的上升临界点 row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 2, w2t, insert_logdb) row_middle = get_row_number(threshold, "middle", df, row_s, row_e, axis, insert_logdb) row_e -= end_point*skip_scale row_s -= end_point*skip_scale # 第三次正式采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 3, w2t, insert_logdb) row_start = get_row_number(threshold, "start", df, row_s, row_e, axis, insert_logdb) insert_logdb("INFO", "current", f"{axis} 轴起点:{row_start}") insert_logdb("INFO", "current", f"{axis} 轴中间点:{row_middle}") insert_logdb("INFO", "current", f"{axis} 轴终点:{row_end}") insert_logdb("INFO", "current", f"{axis} 轴数据非零段点数:{row_middle-row_start+1}") insert_logdb("INFO", "current", f"{axis} 轴数据为零段点数:{row_end-row_middle+1}") if abs(row_end+row_start-2*row_middle) > 1000: insert_logdb("WARNING", "current", f"{axis} 轴数据占空比异常!") data = [] for row in range(row_start, row_end+1): data.append(df_origin.iloc[row, 0]) data.append(df_origin.iloc[row, 1]) data.append(df_origin.iloc[row, 2]) i = 0 for row in ws.iter_rows(min_row=2, min_col=2, max_row=150000, max_col=4): for cell in row: try: if i % 3 == 0: ws.cell((i//3)+2, 1).value = float(((i//3)+1)/1000) _ = f"{data[i]:.2f}" cell.value = float(_) i += 1 except Exception as Err: if i % 3 == 0: ws.cell((i//3)+2, 1).value = None cell.value = None i += 1 def p_scenario(wb, scenario, vel, rrs, dur_time, w2t, insert_logdb): for data_file in scenario: cycle = 0.001 axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j")) sht_name = f"J{axis}" ws = wb[sht_name] pandas.set_option("display.precision", 2) df_origin = pandas.read_csv(data_file, sep="\t") rr = rrs[axis-1] addition = 180 / 3.1415926 * 60 / 360 * rr col_names = list(df_origin.columns) df = df_origin[col_names[vel-1]].multiply(addition) row_start = 3000 row_end = row_start + int(dur_time/cycle) if row_end > df.index[-1]: w2t(f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "red", "DataOverLimit") data = [] for row in range(row_start, row_end+1): data.append(df_origin.iloc[row, 0]) data.append(df_origin.iloc[row, 1]) data.append(df_origin.iloc[row, 2]) i = 0 for row in ws.iter_rows(min_row=2, min_col=2, max_row=250000, max_col=4): for cell in row: try: if i % 3 == 0: ws.cell((i//3)+2, 1).value = float(((i//3)+1)/1000) _ = f"{data[i]:.2f}" cell.value = float(_) i += 1 except Exception as Err: cell.value = None if i % 3 == 0: ws.cell((i//3)+2, 1).value = None i += 1 def get_configs(configfile, w2t, insert_logdb): try: wb = openpyxl.load_workbook(configfile, read_only=True) ws = wb["Target"] except Exception as Err: insert_logdb("ERROR", "current", f"无法打开 {configfile},获取配置文件参数错误 {Err}") w2t(f"无法打开 {configfile}", color="red", desc="OpenFileError") # 最大角速度,额定电流,减速比,额定转速 rrs, avs, rcs, rpms = [], [], [], [] for i in range(2, 8): rrs.append(abs(float(ws.cell(row=2, column=i).value))) avs.append(abs(float(ws.cell(row=3, column=i).value))) rpms.append(abs(float(ws.cell(row=4, column=i).value))) rcs.append(abs(float(ws.cell(row=6, column=i).value))) insert_logdb("INFO", "current", f"current: 获取减速比:{rrs}") insert_logdb("INFO", "current", f"current: 获取角速度:{avs}") insert_logdb("INFO", "current", f"current: 获取额定电流:{rcs}") insert_logdb("INFO", "current", f"current: 获取额定转速:{rpms}") return rrs, avs, rcs, rpms def main(): sub = clibs.data_dp["_sub"] path = clibs.data_dp["_path"] vel = int(clibs.data_dp["_vel"]) trq = int(clibs.data_dp["_trq"]) trqh = int(clibs.data_dp["_trqh"]) w2t = clibs.w2t insert_logdb = clibs.insert_logdb insert_logdb("INFO", "current", "current: 参数初始化成功") data_files = initialization(path, w2t, insert_logdb) rrs, avs, rcs, rpms = get_configs(path + "\\configs.xlsx", w2t, insert_logdb) if sub == "max": current_max(data_files, rcs, trq, w2t, insert_logdb) elif sub == "avg": current_avg(data_files, rcs, trq, w2t, insert_logdb) elif sub == "cycle": current_cycle(data_files, vel, trq, trqh, rrs, rcs, rpms, w2t, insert_logdb) if __name__ == '__main__': main()