From 71b2d9d42e75bd0dfc3485c20f45d594fa464b51 Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 11 Jul 2024 19:09:08 +0800 Subject: [PATCH 01/36] pending dev --- aio/assets/layout.xlsx | Bin 1224091 -> 1225937 bytes aio/code/aio.py | 35 +++++++++++++++++++++++++++++ aio/code/automatic_test/openapi.py | 10 +++++---- aio/code/profile/__init__.py | 1 + aio/code/profile/do_profile.py | 0 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 aio/code/profile/__init__.py create mode 100644 aio/code/profile/do_profile.py diff --git a/aio/assets/layout.xlsx b/aio/assets/layout.xlsx index c80baa461e01818b8378ff366ae6d8a7fec62c47..c7934cee3d34d7a0282ce91cc4ee83f9b0541d0a 100644 GIT binary patch delta 11272 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 P*!LI>4sM_r1bg~_e)^V; delta 9572 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 UQ$9F2YS^a)1P8bH2@Fg9KOHV&CjbBd diff --git a/aio/code/aio.py b/aio/code/aio.py index 165966c..5b55662 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -35,6 +35,12 @@ widgits_at = { 'path': {'label': '', 'entry': '', 'row': 2, 'col': 2, 'text': '数据文件夹路径'}, 'loadsel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 1, 'text': '负载信息'}, } +widgits_pr = { + 'path': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '数据文件夹路径'}, + 'loadsel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 1, 'text': '负载选择'}, + 'actionsel': {'label': '', 'optionmenu': '', 'row': 3, 'col': 1, 'text': '动作选择'}, + 'inertiasel': {'label': '', 'optionmenu': '', 'row': 4, 'col': 1, 'text': '惯量选择'}, +} class App(customtkinter.CTk): @@ -80,6 +86,7 @@ class App(customtkinter.CTk): self.tabview.grid(row=0, column=1, padx=10, pady=5, sticky="nsew") self.tabview.add("Data Process") self.tabview.add("Automatic Test") + self.tabview.add("Profile Test") # create main menu for data process self.menu_main_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["init", "brake", "current", "iso", "wavelogger"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback) self.menu_main_dp.grid(row=1, column=1, sticky='we', padx=5, pady=10) @@ -137,6 +144,33 @@ class App(customtkinter.CTk): widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text']) widgits_at[widgit]['optionmenu'].configure(state='disabled') # For automatic test tab END ===================================================================== + # For profile tab START ===================================================================== + for widgit in widgits_pr: + if widgit == 'path': + widgits_pr[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Profile Test'), text=f'{widgit.upper()}', font=self.my_font) + widgits_pr[widgit]['label'].grid(row=widgits_pr[widgit]['row'], column=widgits_pr[widgit]['col'], sticky='e', pady=5) + widgits_pr[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Profile Test'), width=670, placeholder_text=widgits_pr[widgit]['text'], font=self.my_font) + widgits_pr[widgit]['entry'].grid(row=widgits_pr[widgit]['row'], column=widgits_pr[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we') + # widgits_pr[widgit]['entry'].configure(state='disabled') + elif widgit in ['loadsel', 'actionsel', 'inertiasel']: + match widgit: + case 'loadsel': + values = ["tool100", "inertia"] + case 'actionsel': + values = ["signle", "box", "cart"] + case 'inertiasel': + values = ["high", "middle", "low"] + + widgits_pr[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Profile Test'), button_color='#708090', fg_color='#778899', values=values, width=self.w_param, font=self.my_font) + widgits_pr[widgit]['optionmenu'].grid(row=widgits_pr[widgit]['row'], column=widgits_pr[widgit]['col'], padx=5, pady=5, sticky='we') + widgits_pr[widgit]['optionmenu'].set(widgits_pr[widgit]['text']) + # widgits_pr[widgit]['optionmenu'].configure(state='disabled') + # create progress bar + self.progressbar_pr = customtkinter.CTkProgressBar(self.tabview.tab('Profile Test')) + self.progressbar_pr.grid(row=5, column=1, padx=5, pady=5, sticky="ew") + self.progressbar_pr.configure(mode="determinnate", width=10) + self.progressbar_pr.start() + # For profile tab END ===================================================================== # 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.grid(row=6, column=1, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew') @@ -193,6 +227,7 @@ class App(customtkinter.CTk): c_state = f_hb.read().strip() pb_color = 'green' if c_state == '1' else 'red' self.progressbar.configure(progress_color=pb_color) + self.progressbar_pr.configure(progress_color=pb_color) if c_state == '0': # self.textbox.delete(index1='1.0', index2='end') self.hr.t_bool = False diff --git a/aio/code/automatic_test/openapi.py b/aio/code/automatic_test/openapi.py index 703e9c7..bfac80b 100644 --- a/aio/code/automatic_test/openapi.py +++ b/aio/code/automatic_test/openapi.py @@ -216,7 +216,7 @@ class HmiRequest(object): # self.c_xs.connect(('192.168.84.129', 6666)) self.c_xs.setblocking(False) - self.w2t("Connection success", 0, 0, 'green', tab_name=self.tab_name) + # self.w2t("Connection success", 0, 0, 'green', tab_name=self.tab_name) with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: f_hb.write('1') md = ModbusRequest(self.w2t, self.tab_name) @@ -226,7 +226,7 @@ class HmiRequest(object): md.write_probe(False) md.write_axis(1) except Exception as Err: - self.w2t("Connection failed...", 0, 0, 'red', tab_name=self.tab_name) + # self.w2t("Connection failed...", 0, 0, 'red', tab_name=self.tab_name) with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: f_hb.write('0') @@ -268,7 +268,8 @@ class HmiRequest(object): with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: f_hb.write(_flag) if _flag == '0': - self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) + # self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) + self.w2t(f"", 0, 7, 'red', tab_name=self.tab_name) sleep(1.5) # with open(f"{current_path}/../../assets/templates/c_msg.log", "w", encoding='utf-8') as f: # for msg in self.c_msg: @@ -619,7 +620,8 @@ class HmiRequest(object): self.c.send(self.package(cmd)) sleep(0.5) except Exception as Err: - self.w2t(f"{cmd}\n请求发送失败...{Err}", 0, 0, 'red', tab_name=self.tab_name) + # self.w2t(f"{cmd}\n请求发送失败...{Err}", 0, 0, 'red', tab_name=self.tab_name) + self.w2t(f"", 0, 0, 'red', tab_name=self.tab_name) return req['id'] diff --git a/aio/code/profile/__init__.py b/aio/code/profile/__init__.py new file mode 100644 index 0000000..7824c48 --- /dev/null +++ b/aio/code/profile/__init__.py @@ -0,0 +1 @@ +__all__ = ['do_profile'] \ No newline at end of file diff --git a/aio/code/profile/do_profile.py b/aio/code/profile/do_profile.py new file mode 100644 index 0000000..e69de29 From a66a55bcd3f6fda39077cd4996cdc729550d21d6 Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 13 Jul 2024 11:36:35 +0800 Subject: [PATCH 02/36] =?UTF-8?q?v0.1.9.2(2024/07/13)=201.=20[APIs:=20do?= =?UTF-8?q?=5Fbrake.py]=20=20=20=20-=20=E4=BF=AE=E6=94=B9ready=5Fto=5Fgo?= =?UTF-8?q?=E4=BF=A1=E5=8F=B7=E7=9A=84=E6=8E=A5=E6=94=B6=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E9=80=82=E9=85=8D=E5=A4=A7=E8=B4=9F=E8=BD=BD=E6=9C=BA?= =?UTF-8?q?=E5=9E=8B=202.=20[APIs:=20do=5Fcurrent.py]=20=20=20=20-=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9ready=5Fto=5Fgo=E4=BF=A1=E5=8F=B7=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E6=94=B6=E9=80=BB=E8=BE=91=EF=BC=8C=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=A4=A7=E8=B4=9F=E8=BD=BD=E6=9C=BA=E5=9E=8B=20=20=20=20-=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=8D=95=E8=BD=B4=E6=B5=8B=E8=AF=95=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E4=B8=BA35s=EF=BC=8C=E9=80=82=E9=85=8D=E5=A4=A7?= =?UTF-8?q?=E8=B4=9F=E8=BD=BD=E6=9C=BA=E5=9E=8B=EF=BC=8C=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=A0=B5=E8=BD=AC=E7=94=B5=E6=B5=81=E6=8C=81=E7=BB=AD=E6=97=B6?= =?UTF-8?q?=E9=97=B415s=EF=BC=8C=E9=80=82=E5=BD=93=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=97=B6=E9=97=B4=20=20=20=20-=20=E5=B0=86ac?= =?UTF-8?q?t=E4=BF=A1=E5=8F=B7=E7=BD=AE=E4=B8=BAFalse=E7=9A=84=E5=8A=A8?= =?UTF-8?q?=E4=BD=9C=E6=94=BE=E5=9C=A8=E5=88=9D=E5=A7=8B=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A8=8B=E5=BA=8F=E5=81=A5=E5=A3=AE=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 13 ++++++++++++- aio/code/automatic_test/do_brake.py | 11 ++++++----- aio/code/automatic_test/do_current.py | 20 ++++++++++++-------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/aio/README.md b/aio/README.md index ba2820e..2e2c652 100644 --- a/aio/README.md +++ b/aio/README.md @@ -132,7 +132,7 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A > **需要注意的点** -1. 使用之前需要手动修改!!负载信息!!点位信息!!,确保所有点位不会发生撞击之后,再进行自动化测试 +1. 【重要】使用之前需要手动修改!!负载信息!!点位信息!!,确保所有点位不会发生撞击,确保所有程序正常运行之后,导出工程,再进行自动化测试 2. 工程文件不能手动重命名,需要重命名存档,可以导入HMI,然后另存为 3. 务必正确填写configs.xlsx中的Target页面,A1单元格可以选择正负方向急停,但不完全保证100%,大概有95%左右的准确度 4. 由于xCore系统问题,运行过程中可能会出现机器人宕机问题,如果遇到,可以手动重启控制柜,重新运行 @@ -140,6 +140,8 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A 6. 运行自动化程序之前,确保机器处于正常状态,无故障,未触发急停 7. 需要额外硬件接线,详细参考configs.xlsx中急停接线图sheet页 8. 注意观察二轴100%臂展时,是否可以获取到正确的数据 +9. 将autotest.xml导入到寄存器,并新建一个modbus,命名为autotest +10. 针对五轴机型,六轴数据可以填写1-5轴任意一轴的点位信息 #### 6) 电机电流自动化测试 @@ -462,3 +464,12 @@ v0.1.9.1(2024/07/12) 3. [APIs: openapi.py] - modbus类新增指示政府方向急停的信号pon,将modbus类入参中的tab_name删除,并修改tab_name的值为'openapi' - socket类种修改tab_name的值为'openapi' + +v0.1.9.2(2024/07/13) +1. [APIs: do_brake.py] + - 修改ready_to_go信号的接收逻辑,适配大负载机型 +2. [APIs: do_current.py] + - 修改ready_to_go信号的接收逻辑,适配大负载机型 + - 调整单轴测试时间为35s,适配大负载机型,调整堵转电流持续时间15s,适当减少测试时间 + - 将act信号置为False的动作放在初始化,增加程序健壮性 + diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 171310b..b937264 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -227,15 +227,16 @@ def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): _response = execution('state.switch_auto', hr, w2t) _response = execution('state.switch_motor_on', hr, w2t) _response = execution('rl_task.run', hr, w2t, tasks=['brake', 'stop0_related']) - for i in range(3): + _t_start = time() + while True: if md.read_ready_to_go() == 1: md.write_act(True) break else: - sleep(1) - else: - w2t("未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') - + if (time() - _t_start) // 20 > 1: + w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + else: + sleep(1) # 4. 第一次打开诊断曲线,并执行采集8s,之后触发软急停,关闭曲线采集,找出最大速度,传递给RL程序,最后清除相关记录 if count == 1: _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index 8c81968..f57caf9 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -308,6 +308,8 @@ def run_rl(path, hr, md, loadsel, w2t): _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) md.trigger_estop() md.reset_estop() + md.write_act(False) + sleep(1) # 让曲线彻底关闭 _response = execution('state.switch_manual', hr, w2t) _response = execution('state.switch_motor_off', hr, w2t) @@ -334,19 +336,19 @@ def run_rl(path, hr, md, loadsel, w2t): # 4. 开始运行程序,单轴运行15s _response = execution('rl_task.run', hr, w2t, tasks=['current']) - for i in range(3): + _t_start = time() + while True: if md.read_ready_to_go() == 1: md.write_act(True) - sleep(1) - md.write_act(False) break else: - sleep(1) - else: - w2t("未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + if (time() - _t_start) // 20 > 1: + w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + else: + sleep(1) # 5. 打开诊断曲线,并执行采集 - sleep(7) # 保证程序已经运行起来,其实主要是为了保持电流的采集而设定 + sleep(10) # 保证程序已经运行起来,其实主要是为了保持电流的采集而设定 _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) display_pdo_params = [ {"name": "hw_joint_vel_feedback", "channel": 0}, @@ -365,7 +367,9 @@ def run_rl(path, hr, md, loadsel, w2t): ] _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) scenario_time = 0 - if number < 6 or number > 8: + if number < 6: + sleep(35) + elif number > 8: sleep(15) else: _t_start = time() From d76ee3d223f21e93594f6e05e50458f84fdf3ecb Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 13 Jul 2024 13:40:04 +0800 Subject: [PATCH 03/36] =?UTF-8?q?1.=20[APIs:=20do=5Fbrake.py]=20=20=20=20-?= =?UTF-8?q?=20=E4=BF=AE=E6=94=B9ready=5Fto=5Fgo=E4=BF=A1=E5=8F=B7=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E6=94=B6=E9=80=BB=E8=BE=91=EF=BC=8C=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=A4=A7=E8=B4=9F=E8=BD=BD=E6=9C=BA=E5=9E=8B=202.=20[APIs:=20d?= =?UTF-8?q?o=5Fcurrent.py]=20=20=20=20-=20=E4=BF=AE=E6=94=B9ready=5Fto=5Fg?= =?UTF-8?q?o=E4=BF=A1=E5=8F=B7=E7=9A=84=E6=8E=A5=E6=94=B6=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E9=80=82=E9=85=8D=E5=A4=A7=E8=B4=9F=E8=BD=BD?= =?UTF-8?q?=E6=9C=BA=E5=9E=8B=20=20=20=20-=20=E8=B0=83=E6=95=B4=E5=8D=95?= =?UTF-8?q?=E8=BD=B4=E6=B5=8B=E8=AF=95=E6=97=B6=E9=97=B4=E4=B8=BA35s?= =?UTF-8?q?=EF=BC=8C=E9=80=82=E9=85=8D=E5=A4=A7=E8=B4=9F=E8=BD=BD=E6=9C=BA?= =?UTF-8?q?=E5=9E=8B=EF=BC=8C=E8=B0=83=E6=95=B4=E5=A0=B5=E8=BD=AC=E7=94=B5?= =?UTF-8?q?=E6=B5=81=E6=8C=81=E7=BB=AD=E6=97=B6=E9=97=B415s=EF=BC=8C?= =?UTF-8?q?=E9=80=82=E5=BD=93=E5=87=8F=E5=B0=91=E6=B5=8B=E8=AF=95=E6=97=B6?= =?UTF-8?q?=E9=97=B4=20=20=20=20-=20=E5=B0=86act=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E7=BD=AE=E4=B8=BAFalse=E7=9A=84=E5=8A=A8=E4=BD=9C=E6=94=BE?= =?UTF-8?q?=E5=9C=A8=E5=88=9D=E5=A7=8B=E5=8C=96=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=81=A5=E5=A3=AE=E6=80=A7=20=20=20=20-=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=80=E6=9C=89=E8=BE=93=E5=87=BA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=91=BD=E5=90=8D=EF=BC=8C=E5=9C=A8=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E5=90=8D=E4=B9=8B=E5=89=8D=E5=8A=A0=E5=85=A5=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=88=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 2 ++ aio/assets/file_version_info.txt | 8 ++++---- aio/assets/vers | 2 +- aio/code/automatic_test/do_current.py | 18 +++++++++--------- aio/code/data_process/current.py | 6 ++++-- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/aio/README.md b/aio/README.md index 2e2c652..47d4631 100644 --- a/aio/README.md +++ b/aio/README.md @@ -472,4 +472,6 @@ v0.1.9.2(2024/07/13) - 修改ready_to_go信号的接收逻辑,适配大负载机型 - 调整单轴测试时间为35s,适配大负载机型,调整堵转电流持续时间15s,适当减少测试时间 - 将act信号置为False的动作放在初始化,增加程序健壮性 + - 修改所有输出文件的命名,在扩展名之前加入时间戳 +3. [current: current.py]: 在find_point函数种,当无法找到正确点位时,继续执行,而不是直接终止执行 diff --git a/aio/assets/file_version_info.txt b/aio/assets/file_version_info.txt index ca423d4..5f58e11 100644 --- a/aio/assets/file_version_info.txt +++ b/aio/assets/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, 1, 9, 1), - prodvers=(0, 1, 9, 1), + filevers=(0, 1, 9, 2), + prodvers=(0, 1, 9, 2), # 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 toolbox'), - StringStruct('FileVersion', '0.1.9.1 (2024-07-12)'), + StringStruct('FileVersion', '0.1.9.2 (2024-07-13)'), StringStruct('InternalName', 'AIO.exe'), StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'), StringStruct('OriginalFilename', 'AIO.exe'), StringStruct('ProductName', 'AIO'), - StringStruct('ProductVersion', '0.1.9.1 (2024-07-12)')]) + StringStruct('ProductVersion', '0.1.9.2 (2024-07-13)')]) ]), VarFileInfo([VarStruct('Translation', [1033, 1200])]) ] diff --git a/aio/assets/vers b/aio/assets/vers index 282634a..ea80ca6 100644 --- a/aio/assets/vers +++ b/aio/assets/vers @@ -1 +1 @@ -0.1.9.1 @ 07/12/2024 \ No newline at end of file +0.1.9.2 @ 07/13/2024 \ No newline at end of file diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index f57caf9..583f7ae 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -129,7 +129,7 @@ def data_proc_regular(path, filename, channel, scenario_time): df1 = pandas.DataFrame.from_dict(_d2d_vel) df2 = pandas.DataFrame.from_dict(_d2d_trq) df = pandas.concat([df1, df2], axis=1) - _filename = f'{path}\\single\\j{channel+1}_single.data' + _filename = f'{path}\\single\\j{channel+1}_single_{time()}.data' df.to_csv(_filename, sep='\t', index=False) elif channel in list(range(6, 9)): with open(filename, 'r', encoding='utf-8') as f_obj: @@ -178,37 +178,37 @@ def data_proc_regular(path, filename, channel, scenario_time): df_01 = pandas.DataFrame.from_dict(_d2d_vel_0) df_02 = pandas.DataFrame.from_dict(_d2d_trq_0) df = pandas.concat([df_01, df_02], axis=1) - _filename = f'{path}\\s_{channel-5}\\j1_s_{channel-5}_{scenario_time}.data' + _filename = f'{path}\\s_{channel-5}\\j1_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) df_01 = pandas.DataFrame.from_dict(_d2d_vel_1) df_02 = pandas.DataFrame.from_dict(_d2d_trq_1) df = pandas.concat([df_01, df_02], axis=1) - _filename = f'{path}\\s_{channel-5}\\j2_s_{channel-5}_{scenario_time}.data' + _filename = f'{path}\\s_{channel-5}\\j2_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) df_01 = pandas.DataFrame.from_dict(_d2d_vel_2) df_02 = pandas.DataFrame.from_dict(_d2d_trq_2) df = pandas.concat([df_01, df_02], axis=1) - _filename = f'{path}\\s_{channel-5}\\j3_s_{channel-5}_{scenario_time}.data' + _filename = f'{path}\\s_{channel-5}\\j3_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) df_01 = pandas.DataFrame.from_dict(_d2d_vel_3) df_02 = pandas.DataFrame.from_dict(_d2d_trq_3) df = pandas.concat([df_01, df_02], axis=1) - _filename = f'{path}\\s_{channel-5}\\j4_s_{channel-5}_{scenario_time}.data' + _filename = f'{path}\\s_{channel-5}\\j4_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) df_01 = pandas.DataFrame.from_dict(_d2d_vel_4) df_02 = pandas.DataFrame.from_dict(_d2d_trq_4) df = pandas.concat([df_01, df_02], axis=1) - _filename = f'{path}\\s_{channel-5}\\j5_s_{channel-5}_{scenario_time}.data' + _filename = f'{path}\\s_{channel-5}\\j5_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) df_01 = pandas.DataFrame.from_dict(_d2d_vel_5) df_02 = pandas.DataFrame.from_dict(_d2d_trq_5) df = pandas.concat([df_01, df_02], axis=1) - _filename = f'{path}\\s_{channel-5}\\j6_s_{channel-5}_{scenario_time}.data' + _filename = f'{path}\\s_{channel-5}\\j6_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) elif channel in list(range(9, 15)): with open(filename, 'r', encoding='utf-8') as f_obj: @@ -227,7 +227,7 @@ def data_proc_regular(path, filename, channel, scenario_time): df1 = pandas.DataFrame.from_dict(_d2d_vel) df2 = pandas.DataFrame.from_dict(_d2d_trq) df = pandas.concat([df1, df2], axis=1) - _filename = f'{path}\\single\\j{channel-8}_hold.data' + _filename = f'{path}\\single\\j{channel-8}_hold_{time()}.data' df.to_csv(_filename, sep='\t', index=False) @@ -248,7 +248,7 @@ def data_proc_inertia(path, filename, channel): df1 = pandas.DataFrame.from_dict(_d2d_vel) df2 = pandas.DataFrame.from_dict(_d2d_trq) df = pandas.concat([df1, df2], axis=1) - _filename = f'{path}\\inertia\\j{channel+4}_inertia.data' + _filename = f'{path}\\inertia\\j{channel+4}_inertia_{time()}.data' df.to_csv(_filename, sep='\t', index=False) diff --git a/aio/code/data_process/current.py b/aio/code/data_process/current.py index 0fd3234..b7cd024 100644 --- a/aio/code/data_process/current.py +++ b/aio/code/data_process/current.py @@ -223,7 +223,8 @@ def find_point(data_file, pos, flag, df, _row_s, _row_e, w2t, exitcode, threshol else: return _row_s, _row_e else: - w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, exitcode, 'red') + # w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, exitcode, 'red') + w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, 0, 'red') elif flag == 'gt': while _row_e > end_point: speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean() @@ -234,7 +235,8 @@ def find_point(data_file, pos, flag, df, _row_s, _row_e, w2t, exitcode, threshol else: return _row_s, _row_e else: - w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, exitcode, 'red') + # w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, exitcode, 'red') + w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, 0, 'red') def p_single(wb, single, vel, trq, rpms, w2t): From 718db9ec45508848fcee66c09ba8cfb45ce84fa6 Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 13 Jul 2024 13:43:51 +0800 Subject: [PATCH 04/36] change version --- aio/code/aio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/code/aio.py b/aio/code/aio.py index adfeca2..094f2b2 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -70,7 +70,7 @@ class App(customtkinter.CTk): btns_func['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback)) btns_func['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback)) # create version info - self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.1.9.1\nDate: 07/12/2024", font=self.my_font, text_color="#4F4F4F") + self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.1.9.2\nDate: 07/13/2024", font=self.my_font, text_color="#4F4F4F") self.frame_func.rowconfigure(6, weight=1) self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s') # ===================================================================== From d35858e14eb174cd2f4f90b57b058a0ccc3466cc Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 13 Jul 2024 15:40:13 +0800 Subject: [PATCH 05/36] =?UTF-8?q?v0.1.9.2(2024/07/13)=201.=20[APIs:=20do?= =?UTF-8?q?=5Fcurrent.py]=20=20=20=20-=20=E5=88=A0=E9=99=A4=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E7=9A=84=E6=97=B6=E5=BA=8F=E7=9F=AB=E6=AD=A3=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5=E2=80=94=E2=80=94item['value'].reverse()=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E8=BE=93=E5=87=BA=E7=9A=84=E6=9B=B2=E7=BA=BF=E4=B8=BA?= =?UTF-8?q?=E5=B9=B3=E6=BB=91=E7=9A=84=E8=87=AA=E7=84=B6=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=202.=20[current:=20current.py]=20=20=20=20-=20max=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91=E7=9F=AB=E6=AD=A3?= =?UTF-8?q?=EF=BC=8C=E5=BA=94=E8=AF=A5=E6=98=AF=E5=8F=96=E7=BB=9D=E5=AF=B9?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E6=9C=80=E5=A4=A7=E5=80=BC=20=20=20=20-=20?= =?UTF-8?q?=E6=95=B4=E4=BD=93=E6=A2=B3=E7=90=86=E4=BA=86trq/trqh=E7=9A=84?= =?UTF-8?q?=E4=BC=A0=E9=80=92=E8=B7=AF=E5=BE=84=EF=BC=8C=E7=8E=B0=E5=B7=B2?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 6 +++++- aio/code/automatic_test/do_current.py | 2 -- aio/code/data_process/current.py | 20 +++++++++----------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/aio/README.md b/aio/README.md index 47d4631..c367c30 100644 --- a/aio/README.md +++ b/aio/README.md @@ -473,5 +473,9 @@ v0.1.9.2(2024/07/13) - 调整单轴测试时间为35s,适配大负载机型,调整堵转电流持续时间15s,适当减少测试时间 - 将act信号置为False的动作放在初始化,增加程序健壮性 - 修改所有输出文件的命名,在扩展名之前加入时间戳 -3. [current: current.py]: 在find_point函数种,当无法找到正确点位时,继续执行,而不是直接终止执行 + - 删除多余的时序矫正语句——item['value'].reverse(),使输出的曲线为平滑的自然顺序 +3. [current: current.py] + - 在find_point函数种,当无法找到正确点位时,继续执行,而不是直接终止执行 + - max功能计算逻辑矫正,应该是取绝对值的最大值 + - 整体梳理了trq/trqh的传递路径,现已修正完毕 diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index 583f7ae..245fe0f 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -120,10 +120,8 @@ def data_proc_regular(path, filename, channel, scenario_time): for item in data: item['value'].reverse() if item.get('channel', None) == channel and item.get('name', None) == 'hw_joint_vel_feedback': - item['value'].reverse() _d2d_vel['hw_joint_vel_feedback'].extend(item['value']) elif item.get('channel', None) == channel and item.get('name', None) == 'device_servo_trq_feedback': - item['value'].reverse() _d2d_trq['device_servo_trq_feedback'].extend(item['value']) df1 = pandas.DataFrame.from_dict(_d2d_vel) diff --git a/aio/code/data_process/current.py b/aio/code/data_process/current.py index b7cd024..cef7a6b 100644 --- a/aio/code/data_process/current.py +++ b/aio/code/data_process/current.py @@ -79,7 +79,7 @@ def initialization(path, sub, w2t): return data_files -def current_max(data_files, rcs, trqh, w2t): +def current_max(data_files, rcs, trq, w2t): current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: []} for data_file in data_files: if data_file.endswith('.data'): @@ -93,8 +93,8 @@ def current_max(data_files, rcs, trqh, w2t): axis = int(data_file.split('\\')[-1].split('_')[0].removeprefix('j')) rca = rcs[axis-1] - col = df.columns.values[trqh-1] - c_max = df[col].max() + col = df.columns.values[trq-1] + c_max = df[col].abs().max() scale = 1 if data_file.endswith('.csv') else 1000 _ = abs(c_max/scale*rca) @@ -118,7 +118,7 @@ def current_max(data_files, rcs, trqh, w2t): return current -def current_avg(data_files, rcs, trqh, w2t): +def current_avg(data_files, rcs, trq, w2t): current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: []} for data_file in data_files: if data_file.endswith('.data'): @@ -132,7 +132,7 @@ def current_avg(data_files, rcs, trqh, w2t): axis = int(data_file.split('\\')[-1].split('_')[0].removeprefix('j')) rca = rcs[axis-1] - col = df.columns.values[trqh - 1] + col = df.columns.values[trq-1] c_std = df[col].std() c_avg = df[col].mean() @@ -223,8 +223,7 @@ def find_point(data_file, pos, flag, df, _row_s, _row_e, w2t, exitcode, threshol else: return _row_s, _row_e else: - # w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, exitcode, 'red') - w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, 0, 'red') + w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到第{exitcode}个有效点...", 0, exitcode, 'red') elif flag == 'gt': while _row_e > end_point: speed_avg = df.iloc[_row_s:_row_e, 0].abs().mean() @@ -235,8 +234,7 @@ def find_point(data_file, pos, flag, df, _row_s, _row_e, w2t, exitcode, threshol else: return _row_s, _row_e else: - # w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, exitcode, 'red') - w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, 0, 'red') + w2t(f"[{pos}] {data_file}数据有误,需要检查,无法找到有效起始点或结束点...", 0, exitcode, 'red') def p_single(wb, single, vel, trq, rpms, w2t): @@ -395,9 +393,9 @@ def main(path, sub, dur, vel, trq, trqh, w2t): data_files = initialization(path, sub, w2t) rpms, rcs = get_configs(path + '\\configs.xlsx', w2t) if sub == 'max': - current_max(data_files, rcs, trqh, w2t) + current_max(data_files, rcs, trq, w2t) elif sub == 'avg': - current_avg(data_files, rcs, trqh, w2t) + current_avg(data_files, rcs, trq, w2t) elif sub == 'cycle': current_cycle(dur, data_files, rcs, vel, trq, trqh, rpms, w2t) else: From 485dffdd0b235a7787646bea260a4bb5ff1dd744 Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 13 Jul 2024 16:43:56 +0800 Subject: [PATCH 06/36] =?UTF-8?q?=20=20=20-=20=E5=87=8F=E9=80=9F=E6=AF=94r?= =?UTF-8?q?r=E6=95=B0=E6=8D=AE=E6=BA=90=E4=BF=AE=E6=94=B9=E4=B8=BAconfigs.?= =?UTF-8?q?xlsx=204.=20=E5=9C=A8current=E5=B7=A5=E7=A8=8Bmain=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=A2=9E=E5=8A=A0=20VelSet=20100=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 1 + aio/assets/configs.xlsx | Bin 226161 -> 226189 bytes aio/assets/target.zip | Bin 26230 -> 26247 bytes aio/code/data_process/current.py | 27 +++++++++++++++++---------- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/aio/README.md b/aio/README.md index c367c30..60b6375 100644 --- a/aio/README.md +++ b/aio/README.md @@ -478,4 +478,5 @@ v0.1.9.2(2024/07/13) - 在find_point函数种,当无法找到正确点位时,继续执行,而不是直接终止执行 - max功能计算逻辑矫正,应该是取绝对值的最大值 - 整体梳理了trq/trqh的传递路径,现已修正完毕 + - 减速比rr数据源修改为configs.xlsx diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index e591d4c42a4a4389b655ecc44c26f0988e96652c..23e3fd2b910f41ccd9bd708d89ff5386c895109c 100644 GIT binary patch delta 3987 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 K&;43mgZ>A=wN%Fd delta 3980 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 Date: Sat, 13 Jul 2024 16:45:01 +0800 Subject: [PATCH 07/36] =?UTF-8?q?=20=20=20-=20=E5=87=8F=E9=80=9F=E6=AF=94r?= =?UTF-8?q?r=E6=95=B0=E6=8D=AE=E6=BA=90=E4=BF=AE=E6=94=B9=E4=B8=BAconfigs.?= =?UTF-8?q?xlsx=204.=20=E5=9C=A8current=E5=B7=A5=E7=A8=8Bmain=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=A2=9E=E5=8A=A0=20VelSet=20100=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 3 ++- aio/assets/configs.xlsx | Bin 226161 -> 226189 bytes aio/assets/target.zip | Bin 26230 -> 26247 bytes aio/code/data_process/current.py | 27 +++++++++++++++++---------- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/aio/README.md b/aio/README.md index c367c30..b5e70d6 100644 --- a/aio/README.md +++ b/aio/README.md @@ -478,4 +478,5 @@ v0.1.9.2(2024/07/13) - 在find_point函数种,当无法找到正确点位时,继续执行,而不是直接终止执行 - max功能计算逻辑矫正,应该是取绝对值的最大值 - 整体梳理了trq/trqh的传递路径,现已修正完毕 - + - 减速比rr数据源修改为configs.xlsx +4. 在current工程main函数增加 VelSet 100语句 diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index e591d4c42a4a4389b655ecc44c26f0988e96652c..23e3fd2b910f41ccd9bd708d89ff5386c895109c 100644 GIT binary patch delta 3987 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 K&;43mgZ>A=wN%Fd delta 3980 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 Date: Sat, 13 Jul 2024 16:51:18 +0800 Subject: [PATCH 08/36] delete template sheet --- aio/assets/configs.xlsx | Bin 226189 -> 224778 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index 23e3fd2b910f41ccd9bd708d89ff5386c895109c..e59ffbb9cb652c1aa13e9dbb8c630b831bc4d68c 100644 GIT binary patch delta 4588 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 YxTY%Fy Date: Mon, 15 Jul 2024 13:32:55 +0800 Subject: [PATCH 09/36] =?UTF-8?q?v0.1.9.3(2024/07/15)=201.=20[APIs:=20open?= =?UTF-8?q?api.py]=20=20=20=20-=20=C3=90=C2=B8=C3=84odbusl=C2=BD=C3=93?= =?UTF-8?q?=C2=A7=C2=B0=DC=B1=C2=A8=C2=B4=C3=AD=C2=B3=C3=B6=C2=BD=C2=A3?= =?UTF-8?q?=C2=AC=CA=B9=D6=AE=D6=BB=C3=94automatic=20test=D2=B3=C3=83?= =?UTF-8?q?=C3=8F=CA=BE=20=20=20=20-=20=E5=B0=86=E8=AF=A5=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=A7=BB=E5=8A=A8=E8=87=B3toplevel=EF=BC=8C=E4=B8=BA?= =?UTF-8?q?=E5=90=8E=E9=9D=A2=E6=89=A9=E5=B1=95=E5=81=9A=E5=87=86=E5=A4=87?= =?UTF-8?q?=20=20=20=20-=20=E4=BF=AE=E6=94=B9heartbeat=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=EF=BC=8C=E4=BD=BF=E5=90=8E=E7=BB=AD=E6=89=93?= =?UTF-8?q?=E5=8C=85=E7=9A=84=E6=97=B6=E5=80=99=E6=9B=B4=E6=96=B9=E4=BE=BF?= =?UTF-8?q?=202.=20[APIs:=20aio.py]:=20=20=20=20-=20=E4=BF=AE=E6=94=B9hear?= =?UTF-8?q?tbeat=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E5=90=8E=E7=BB=AD=E6=89=93=E5=8C=85=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=E6=9B=B4=E6=96=B9=E4=BE=BF=20=20=20=20-=20=E4=BF=AE=E6=94=B9wr?= =?UTF-8?q?ite2textbox=E5=87=BD=E6=95=B0=E7=9A=84=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E5=85=88=E5=88=A4=E6=96=AD=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 10 ++++ aio/code/aio.py | 13 ++-- aio/code/automatic_test/__init__.py | 2 +- aio/code/{automatic_test => }/openapi.py | 75 ++++++++---------------- 4 files changed, 43 insertions(+), 57 deletions(-) rename aio/code/{automatic_test => }/openapi.py (84%) diff --git a/aio/README.md b/aio/README.md index b5e70d6..1289907 100644 --- a/aio/README.md +++ b/aio/README.md @@ -480,3 +480,13 @@ v0.1.9.2(2024/07/13) - 整体梳理了trq/trqh的传递路径,现已修正完毕 - 减速比rr数据源修改为configs.xlsx 4. 在current工程main函数增加 VelSet 100语句 + +v0.1.9.3(2024/07/15) +1. [APIs: openapi.py] + - 修改modbus连接失败报错输出形式,使之只在automatic test页面显示 + - 将该文件移动至toplevel,为后面扩展做准备 + - 修改heartbeat文件路径,使后续打包的时候更方便 +2. [APIs: aio.py]: + - 修改heartbeat文件路径,使后续打包的时候更方便 + - 修改write2textbox函数的打印逻辑,先判断网络相关 + diff --git a/aio/code/aio.py b/aio/code/aio.py index 094f2b2..fb6c984 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -9,8 +9,9 @@ from urllib.request import urlopen from socket import setdefaulttimeout from data_process import * from automatic_test import * +import openapi -current_path = dirname(__file__) +heartbeat = f'{dirname(__file__)}/../assets/templates/heartbeat' customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light" customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" customtkinter.set_widget_scaling(1.1) # widget dimensions and text size @@ -166,7 +167,7 @@ class App(customtkinter.CTk): self.seg_button.configure(state='disabled') # self.tabview.configure(state='disabled') self.textbox.delete(index1='1.0', index2='end') - with open(f'{current_path}/../assets/templates/heartbeat', 'r', encoding='utf-8') as f_h: + with open(heartbeat, 'r', encoding='utf-8') as f_h: c_state = f_h.read().strip() if c_state == '0' and value != '功能切换': @@ -181,13 +182,13 @@ class App(customtkinter.CTk): # self.tabview.configure(state='normal') def detect_network(self): - with open(f"{current_path}/../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: + with open(heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('0') self.hr = openapi.HmiRequest(self.write2textbox) self.md = openapi.ModbusRequest(self.write2textbox) while True: - with open(f'{current_path}/../assets/templates/heartbeat', 'r', encoding='utf-8') as f_hb: + with open(heartbeat, 'r', encoding='utf-8') as f_hb: c_state = f_hb.read().strip() pb_color = 'green' if c_state == '1' else 'red' self.progressbar.configure(progress_color=pb_color) @@ -333,7 +334,7 @@ class App(customtkinter.CTk): self.textbox.tag_config(tagName=color, foreground=color) tab_name_cur = self.tabview.get() - if tab_name == tab_name_cur: + if tab_name == 'openapi' and tab_name_cur == 'Automatic Test': if wait != 0: self.textbox.insert(index='end', text=text, tags=color) self.textbox.update() @@ -347,7 +348,7 @@ class App(customtkinter.CTk): self.textbox.insert(index='end', text=text + '\n', tags=color) self.textbox.update() self.textbox.see('end') - elif tab_name == 'openapi' and tab_name_cur == 'Automatic Test': + elif tab_name == tab_name_cur: if wait != 0: self.textbox.insert(index='end', text=text, tags=color) self.textbox.update() diff --git a/aio/code/automatic_test/__init__.py b/aio/code/automatic_test/__init__.py index f60ee0b..5c1ee4d 100644 --- a/aio/code/automatic_test/__init__.py +++ b/aio/code/automatic_test/__init__.py @@ -1 +1 @@ -__all__ = ['openapi', 'btn_functions', 'do_brake', 'do_current'] \ No newline at end of file +__all__ = ['btn_functions', 'do_brake', 'do_current'] \ No newline at end of file diff --git a/aio/code/automatic_test/openapi.py b/aio/code/openapi.py similarity index 84% rename from aio/code/automatic_test/openapi.py rename to aio/code/openapi.py index f688694..042c4b5 100644 --- a/aio/code/automatic_test/openapi.py +++ b/aio/code/openapi.py @@ -11,6 +11,7 @@ from pymodbus.constants import Endian MAX_FRAME_SIZE = 1024 setdefaulttimeout(2) current_path = dirname(__file__) +heartbeat = f'{current_path}/../assets/templates/heartbeat' class ModbusRequest(object): @@ -27,22 +28,19 @@ class ModbusRequest(object): try: self.c.write_register(40002, 1) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法正常下电,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法正常下电,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def motor_on(self): try: self.c.write_register(40003, 1) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法正常上电,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法正常上电,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def trigger_estop(self): try: self.c.write_register(40012, 0) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法触发软急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法触发软急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def reset_estop(self): try: @@ -54,66 +52,50 @@ class ModbusRequest(object): sleep(0.2) self.c.write_register(40001, 0) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法重置软急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法重置软急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def clear_alarm(self): try: self.c.write_register(40000, 1) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法清除告警,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法清除告警,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def get_cart_vel(self): try: results = self.c.read_holding_registers(40537, 7) - print(f"cart vel: {results.registers}") - except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取笛卡尔速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取笛卡尔速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def get_jnt_vel(self): try: results = self.c.read_holding_registers(40579, 7) - print(f"joint vel: {results.registers}") - except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取关节速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取关节速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def get_tcp_vel(self): try: results = self.c.read_holding_registers(40607, 7) - print(f"tcp vel: {results.registers}") - except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取TCP速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取TCP速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def get_tcp_mag_vel(self): try: results = self.c.read_holding_registers(40621, 1) - print(f"tcp mag: {results.registers}") - except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取TCP合成速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取TCP合成速度,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def write_act(self, number): try: self.c.write_register(41000, number) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法发送执行信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法发送执行信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def read_ready_to_go(self): try: results = self.c.read_holding_registers(41001, 1) return results.registers[0] except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取准备信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取准备信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def read_scenario_time(self): try: @@ -122,15 +104,13 @@ class ModbusRequest(object): result = f"{result.decode_32bit_float():.3f}" return result except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取准备信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取准备信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def write_stop0(self, number): try: self.c.write_register(41004, number) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法通过IO操作stop0急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法通过IO操作stop0急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def write_speed_max(self, speed): try: @@ -139,16 +119,14 @@ class ModbusRequest(object): payload = builder.build() self.c.write_registers(41005, payload, skip_encode=True) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法写入速度值,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法写入速度值,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def read_brake_done(self): try: results = self.c.read_holding_registers(41007, 1) return results.registers[0] except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法读取制动已执行信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法读取制动已执行信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def write_axis(self, axis): try: @@ -157,22 +135,19 @@ class ModbusRequest(object): payload = builder.to_registers() self.c.write_registers(41008, payload) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法写入速度值,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法写入速度值,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def write_probe(self, probe): try: self.c.write_register(41010, probe) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法写入速度探测信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法写入速度探测信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def write_pon(self, pon): # positive or negative try: self.c.write_register(41011, pon) except Exception as Err: - self.w2t(f"{Err}") - self.w2t("无法写入正负方向信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) + self.w2t(f"{Err}\n无法写入正负方向信号,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) class HmiRequest(object): @@ -210,7 +185,7 @@ class HmiRequest(object): def sock_conn(self): # while True: - with open(f"{current_path}/../../assets/templates/heartbeat", "r", encoding='utf-8') as f_hb: + with open(heartbeat, "r", encoding='utf-8') as f_hb: c_state = f_hb.read().strip() if c_state == '0': try: @@ -224,7 +199,7 @@ class HmiRequest(object): self.c_xs.setblocking(False) self.w2t("Connection success", 0, 0, 'green', tab_name=self.tab_name) - with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: + with open(heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('1') md = ModbusRequest(self.w2t) md.reset_estop() @@ -234,7 +209,7 @@ class HmiRequest(object): md.write_axis(1) except Exception as Err: self.w2t("Connection failed...", 0, 0, 'red', tab_name=self.tab_name) - with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: + with open(heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('0') def header_check(self, index, data): @@ -272,12 +247,12 @@ class HmiRequest(object): print(f"hb = {_flag}", end=' ') print(f"len(c_msg) = {len(self.c_msg)}", end=' ') print(f"len(c_msg_xs) = {len(self.c_msg_xs)}", end='\n') - with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_hb: + with open(heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write(_flag) if _flag == '0': self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) sleep(1.5) - # with open(f"{current_path}/../../assets/templates/c_msg.log", "w", encoding='utf-8') as f: + # with open(f"{current_path}/../assets/templates/c_msg.log", "w", encoding='utf-8') as f: # for msg in self.c_msg: # f.write(str(loads(msg)) + '\n') @@ -590,7 +565,7 @@ class HmiRequest(object): if flg == 0: # for old protocols req = None try: - with open(f'{current_path}/../../assets/templates/{command}.json', encoding='utf-8', + with open(f'{current_path}/../assets/templates/{command}.json', encoding='utf-8', mode='r') as f_json: req = load(f_json) except: From da5ddcea0aa1a14aad468f490bb946210ea8dc1a Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 17 Jul 2024 10:09:06 +0800 Subject: [PATCH 10/36] =?UTF-8?q?v0.1.9.4(2024/07/15)=201.=20[profile:=20a?= =?UTF-8?q?io.py]=EF=BC=9A=E5=AE=8C=E5=96=84durable=20text=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=80=BB=E8=BE=91=202.=20[profile:=20do=5Fbrake/do=5F?= =?UTF-8?q?current/btn=5Ffunctions.py]=EF=BC=9A=E5=88=A0=E9=99=A4validate?= =?UTF-8?q?=5Fresp=E5=87=BD=E6=95=B0=EF=BC=8C=E4=BF=AE=E6=94=B9execution?= =?UTF-8?q?=E5=87=BD=E6=95=B0=203.=20[profile:=20factory=5Ftest.py]=20=20?= =?UTF-8?q?=20=20-=20=E6=96=B0=E5=A2=9E=E8=80=90=E4=B9=85/=E8=80=81?= =?UTF-8?q?=E5=8C=96=E6=B5=8B=E8=AF=95=E7=A8=8B=E5=BA=8F=20=20=20=20-=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=85=AD=E8=BD=B4=E6=8A=98=E7=BA=BF=E5=9B=BE?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=204.=20[profile:=20openapi.py]=EF=BC=9A?= =?UTF-8?q?=E5=A4=9A=E6=AC=A1=E5=90=88=E5=B9=B6=E9=81=97=E7=95=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=A4=84=E7=90=86=205.=20templates=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E7=BB=84=E7=BB=87=E6=9E=B6=E6=9E=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- aio/README.md | 11 +- aio/assets/layout.xlsx | Bin 1225937 -> 1226005 bytes .../durable/durable_data_current.xlsx | Bin 0 -> 6796 bytes .../durable/durable_data_velocity.xlsx | Bin 0 -> 6796 bytes aio/assets/templates/heartbeat | 2 +- .../{ => json}/controller.heart.json | 0 .../{ => json}/device.get_params.json | 0 .../{ => json}/diagnosis.get_params.json | 0 .../templates/{ => json}/diagnosis.open.json | 0 .../templates/{ => json}/diagnosis.save.json | 0 .../{ => json}/diagnosis.set_params.json | 0 .../{ => json}/overview.get_autoload.json | 0 .../{ => json}/overview.get_cur_prj.json | 0 .../templates/{ => json}/overview.reload.json | 0 .../{ => json}/overview.set_autoload.json | 0 .../{ => json}/register.set_value.json | 0 .../{ => json}/rl_task.pp_to_main.json | 0 .../templates/{ => json}/rl_task.run.json | 0 .../templates/{ => json}/rl_task.stop.json | 0 .../templates/{ => json}/state.get_state.json | 0 .../{ => json}/state.get_tp_mode.json | 0 .../{ => json}/state.set_tp_mode.json | 0 .../{ => json}/state.switch_auto.json | 0 .../{ => json}/state.switch_manual.json | 0 .../{ => json}/state.switch_motor_off.json | 0 .../{ => json}/state.switch_motor_on.json | 0 aio/code/aio.py | 164 +++++++++--- aio/code/automatic_test/btn_functions.py | 15 +- aio/code/automatic_test/do_brake.py | 15 +- aio/code/automatic_test/do_current.py | 15 +- aio/code/durable_action/__init__.py | 1 + aio/code/durable_action/factory_test.py | 252 ++++++++++++++++++ aio/code/openapi.py | 10 +- aio/code/profile/__init__.py | 1 - aio/code/profile/do_profile.py | 0 36 files changed, 402 insertions(+), 87 deletions(-) create mode 100644 aio/assets/templates/durable/durable_data_current.xlsx create mode 100644 aio/assets/templates/durable/durable_data_velocity.xlsx rename aio/assets/templates/{ => json}/controller.heart.json (100%) rename aio/assets/templates/{ => json}/device.get_params.json (100%) rename aio/assets/templates/{ => json}/diagnosis.get_params.json (100%) rename aio/assets/templates/{ => json}/diagnosis.open.json (100%) rename aio/assets/templates/{ => json}/diagnosis.save.json (100%) rename aio/assets/templates/{ => json}/diagnosis.set_params.json (100%) rename aio/assets/templates/{ => json}/overview.get_autoload.json (100%) rename aio/assets/templates/{ => json}/overview.get_cur_prj.json (100%) rename aio/assets/templates/{ => json}/overview.reload.json (100%) rename aio/assets/templates/{ => json}/overview.set_autoload.json (100%) rename aio/assets/templates/{ => json}/register.set_value.json (100%) rename aio/assets/templates/{ => json}/rl_task.pp_to_main.json (100%) rename aio/assets/templates/{ => json}/rl_task.run.json (100%) rename aio/assets/templates/{ => json}/rl_task.stop.json (100%) rename aio/assets/templates/{ => json}/state.get_state.json (100%) rename aio/assets/templates/{ => json}/state.get_tp_mode.json (100%) rename aio/assets/templates/{ => json}/state.set_tp_mode.json (100%) rename aio/assets/templates/{ => json}/state.switch_auto.json (100%) rename aio/assets/templates/{ => json}/state.switch_manual.json (100%) rename aio/assets/templates/{ => json}/state.switch_motor_off.json (100%) rename aio/assets/templates/{ => json}/state.switch_motor_on.json (100%) create mode 100644 aio/code/durable_action/__init__.py create mode 100644 aio/code/durable_action/factory_test.py delete mode 100644 aio/code/profile/__init__.py delete mode 100644 aio/code/profile/do_profile.py diff --git a/.gitignore b/.gitignore index 7eb83ee..bea7ae6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ aio/venv aio/__pycache__/ aio/code/automatic_test/__pycache__/ aio/code/data_process/__pycache__/ -aio/assets/templates/c_msg.log \ No newline at end of file +aio/assets/templates/c_msg.log +aio/code/durable_action/__pycache__/ \ No newline at end of file diff --git a/aio/README.md b/aio/README.md index 1289907..294c7a2 100644 --- a/aio/README.md +++ b/aio/README.md @@ -486,7 +486,16 @@ v0.1.9.3(2024/07/15) - 修改modbus连接失败报错输出形式,使之只在automatic test页面显示 - 将该文件移动至toplevel,为后面扩展做准备 - 修改heartbeat文件路径,使后续打包的时候更方便 -2. [APIs: aio.py]: +2. [APIs: aio.py] - 修改heartbeat文件路径,使后续打包的时候更方便 - 修改write2textbox函数的打印逻辑,先判断网络相关 +v0.1.9.4(2024/07/15) +1. [profile: aio.py]:完善durable text相关逻辑 +2. [profile: do_brake/do_current/btn_functions.py]:删除validate_resp函数,修改execution函数 +3. [profile: factory_test.py] + - 新增耐久/老化测试程序 + - 实现六轴折线图显示 +4. [profile: openapi.py]:多次合并遗留问题处理 +5. templates文件夹组织架构调整 + diff --git a/aio/assets/layout.xlsx b/aio/assets/layout.xlsx index c7934cee3d34d7a0282ce91cc4ee83f9b0541d0a..735de053d795474cc6eaafa886d9667f8769904d 100644 GIT binary patch delta 13020 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 literal 0 HcmV?d00001 diff --git a/aio/assets/templates/durable/durable_data_velocity.xlsx b/aio/assets/templates/durable/durable_data_velocity.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f438a2ad364c7fd7e5be6d73da826901e3ad0a49 GIT binary patch literal 6796 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 literal 0 HcmV?d00001 diff --git a/aio/assets/templates/heartbeat b/aio/assets/templates/heartbeat index c227083..56a6051 100644 --- a/aio/assets/templates/heartbeat +++ b/aio/assets/templates/heartbeat @@ -1 +1 @@ -0 \ No newline at end of file +1 \ No newline at end of file diff --git a/aio/assets/templates/controller.heart.json b/aio/assets/templates/json/controller.heart.json similarity index 100% rename from aio/assets/templates/controller.heart.json rename to aio/assets/templates/json/controller.heart.json diff --git a/aio/assets/templates/device.get_params.json b/aio/assets/templates/json/device.get_params.json similarity index 100% rename from aio/assets/templates/device.get_params.json rename to aio/assets/templates/json/device.get_params.json diff --git a/aio/assets/templates/diagnosis.get_params.json b/aio/assets/templates/json/diagnosis.get_params.json similarity index 100% rename from aio/assets/templates/diagnosis.get_params.json rename to aio/assets/templates/json/diagnosis.get_params.json diff --git a/aio/assets/templates/diagnosis.open.json b/aio/assets/templates/json/diagnosis.open.json similarity index 100% rename from aio/assets/templates/diagnosis.open.json rename to aio/assets/templates/json/diagnosis.open.json diff --git a/aio/assets/templates/diagnosis.save.json b/aio/assets/templates/json/diagnosis.save.json similarity index 100% rename from aio/assets/templates/diagnosis.save.json rename to aio/assets/templates/json/diagnosis.save.json diff --git a/aio/assets/templates/diagnosis.set_params.json b/aio/assets/templates/json/diagnosis.set_params.json similarity index 100% rename from aio/assets/templates/diagnosis.set_params.json rename to aio/assets/templates/json/diagnosis.set_params.json diff --git a/aio/assets/templates/overview.get_autoload.json b/aio/assets/templates/json/overview.get_autoload.json similarity index 100% rename from aio/assets/templates/overview.get_autoload.json rename to aio/assets/templates/json/overview.get_autoload.json diff --git a/aio/assets/templates/overview.get_cur_prj.json b/aio/assets/templates/json/overview.get_cur_prj.json similarity index 100% rename from aio/assets/templates/overview.get_cur_prj.json rename to aio/assets/templates/json/overview.get_cur_prj.json diff --git a/aio/assets/templates/overview.reload.json b/aio/assets/templates/json/overview.reload.json similarity index 100% rename from aio/assets/templates/overview.reload.json rename to aio/assets/templates/json/overview.reload.json diff --git a/aio/assets/templates/overview.set_autoload.json b/aio/assets/templates/json/overview.set_autoload.json similarity index 100% rename from aio/assets/templates/overview.set_autoload.json rename to aio/assets/templates/json/overview.set_autoload.json diff --git a/aio/assets/templates/register.set_value.json b/aio/assets/templates/json/register.set_value.json similarity index 100% rename from aio/assets/templates/register.set_value.json rename to aio/assets/templates/json/register.set_value.json diff --git a/aio/assets/templates/rl_task.pp_to_main.json b/aio/assets/templates/json/rl_task.pp_to_main.json similarity index 100% rename from aio/assets/templates/rl_task.pp_to_main.json rename to aio/assets/templates/json/rl_task.pp_to_main.json diff --git a/aio/assets/templates/rl_task.run.json b/aio/assets/templates/json/rl_task.run.json similarity index 100% rename from aio/assets/templates/rl_task.run.json rename to aio/assets/templates/json/rl_task.run.json diff --git a/aio/assets/templates/rl_task.stop.json b/aio/assets/templates/json/rl_task.stop.json similarity index 100% rename from aio/assets/templates/rl_task.stop.json rename to aio/assets/templates/json/rl_task.stop.json diff --git a/aio/assets/templates/state.get_state.json b/aio/assets/templates/json/state.get_state.json similarity index 100% rename from aio/assets/templates/state.get_state.json rename to aio/assets/templates/json/state.get_state.json diff --git a/aio/assets/templates/state.get_tp_mode.json b/aio/assets/templates/json/state.get_tp_mode.json similarity index 100% rename from aio/assets/templates/state.get_tp_mode.json rename to aio/assets/templates/json/state.get_tp_mode.json diff --git a/aio/assets/templates/state.set_tp_mode.json b/aio/assets/templates/json/state.set_tp_mode.json similarity index 100% rename from aio/assets/templates/state.set_tp_mode.json rename to aio/assets/templates/json/state.set_tp_mode.json diff --git a/aio/assets/templates/state.switch_auto.json b/aio/assets/templates/json/state.switch_auto.json similarity index 100% rename from aio/assets/templates/state.switch_auto.json rename to aio/assets/templates/json/state.switch_auto.json diff --git a/aio/assets/templates/state.switch_manual.json b/aio/assets/templates/json/state.switch_manual.json similarity index 100% rename from aio/assets/templates/state.switch_manual.json rename to aio/assets/templates/json/state.switch_manual.json diff --git a/aio/assets/templates/state.switch_motor_off.json b/aio/assets/templates/json/state.switch_motor_off.json similarity index 100% rename from aio/assets/templates/state.switch_motor_off.json rename to aio/assets/templates/json/state.switch_motor_off.json diff --git a/aio/assets/templates/state.switch_motor_on.json b/aio/assets/templates/json/state.switch_motor_on.json similarity index 100% rename from aio/assets/templates/state.switch_motor_on.json rename to aio/assets/templates/json/state.switch_motor_on.json diff --git a/aio/code/aio.py b/aio/code/aio.py index c61d407..89c9406 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -7,17 +7,43 @@ import customtkinter from time import time, strftime, localtime, sleep from urllib.request import urlopen from socket import setdefaulttimeout +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from data_process import * from automatic_test import * +from durable_action import * import openapi +import matplotlib.pyplot as plt +import matplotlib +import pandas as pd +matplotlib.use('Agg') heartbeat = f'{dirname(__file__)}/../assets/templates/heartbeat' +durable_data_current_xlsx = f'{dirname(__file__)}/../assets/templates/durable/durable_data_current.xlsx' +durable_data_velocity_xlsx = f'{dirname(__file__)}/../assets/templates/durable/durable_data_velocity.xlsx' customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light" 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_window_scaling(1.1) # window geometry dimensions setdefaulttimeout(3) # global vars +durable_data_current = { + 'time': list(range(1, 26)), + 'axis1': [0 for _ in range(25)], + 'axis2': [0 for _ in range(25)], + 'axis3': [0 for _ in range(25)], + 'axis4': [0 for _ in range(25)], + 'axis5': [0 for _ in range(25)], + 'axis6': [0 for _ in range(25)], +} +durable_data_velocity = { + 'time': list(range(1, 26)), + 'axis1': [0 for _ in range(25)], + 'axis2': [0 for _ in range(25)], + 'axis3': [0 for _ in range(25)], + 'axis4': [0 for _ in range(25)], + 'axis5': [0 for _ in range(25)], + 'axis6': [0 for _ in range(25)], +} btns_func = { 'start': {'btn': '', 'row': 1, 'text': '开始运行'}, 'check': {'btn': '', 'row': 2, 'text': '检查参数'}, @@ -36,11 +62,9 @@ widgits_at = { 'path': {'label': '', 'entry': '', 'row': 2, 'col': 2, 'text': '数据文件夹路径'}, 'loadsel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 1, 'text': '负载信息'}, } -widgits_pr = { +widgits_da = { 'path': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '数据文件夹路径'}, - 'loadsel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 1, 'text': '负载选择'}, - 'actionsel': {'label': '', 'optionmenu': '', 'row': 3, 'col': 1, 'text': '动作选择'}, - 'inertiasel': {'label': '', 'optionmenu': '', 'row': 4, 'col': 1, 'text': '惯量选择'}, + 'loadsel': {'label': '', 'optionmenu': '', 'row': 1, 'col': 1, 'text': '负载选择'}, } @@ -51,6 +75,9 @@ class App(customtkinter.CTk): self.w_param = 84 self.hr = None self.md = None + self.canvas = None + self.flg = 0 + self.df_copy = None # ===================================================================== # configure window self.title("AIO - All in one automatic toolbox") @@ -86,7 +113,7 @@ class App(customtkinter.CTk): self.tabview.grid(row=0, column=1, padx=10, pady=5, sticky="nsew") self.tabview.add("Data Process") self.tabview.add("Automatic Test") - self.tabview.add("Profile Test") + self.tabview.add("Durable Action") # create main menu for data process self.menu_main_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["init", "brake", "current", "iso", "wavelogger"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback) self.menu_main_dp.grid(row=1, column=1, sticky='we', padx=5, pady=10) @@ -122,7 +149,7 @@ class App(customtkinter.CTk): # For automatic test tab START ===================================================================== # create buttons self.seg_button = customtkinter.CTkSegmentedButton(self.tabview.tab('Automatic Test'), dynamic_resizing=False, font=customtkinter.CTkFont(size=16, weight='bold'), command=lambda value='机器状态': self.thread_it(self.segmented_button_callback)) - self.seg_button.grid(row=1, column=2, columnspan=12, padx=(20, 10), pady=(10, 10), sticky="ew") + self.seg_button.grid(row=1, column=2, columnspan=12, padx=(65, 10), pady=(10, 10), sticky="ew") self.seg_button.configure(dynamic_resizing=False, values=["功能切换", "触发急停", "恢复急停", "待定功能", "功能待定", "机器状态", "告警信息"]) self.seg_button.set("功能切换") # create progress bar @@ -134,7 +161,7 @@ class App(customtkinter.CTk): for widgit in widgits_at: if widgit == 'path': widgits_at[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Automatic Test'), text=f'{widgit.upper()}', font=self.my_font) - widgits_at[widgit]['label'].grid(row=widgits_at[widgit]['row'], column=widgits_at[widgit]['col'], sticky='e', pady=5) + widgits_at[widgit]['label'].grid(row=widgits_at[widgit]['row'], column=widgits_at[widgit]['col'], sticky='e', padx=(20, 5), pady=5) widgits_at[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Automatic Test'), width=670, placeholder_text=widgits_at[widgit]['text'], font=self.my_font) widgits_at[widgit]['entry'].grid(row=widgits_at[widgit]['row'], column=widgits_at[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we') widgits_at[widgit]['entry'].configure(state='disabled') @@ -144,33 +171,23 @@ class App(customtkinter.CTk): widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text']) widgits_at[widgit]['optionmenu'].configure(state='disabled') # For automatic test tab END ===================================================================== - # For profile tab START ===================================================================== - for widgit in widgits_pr: - if widgit == 'path': - widgits_pr[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Profile Test'), text=f'{widgit.upper()}', font=self.my_font) - widgits_pr[widgit]['label'].grid(row=widgits_pr[widgit]['row'], column=widgits_pr[widgit]['col'], sticky='e', pady=5) - widgits_pr[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Profile Test'), width=670, placeholder_text=widgits_pr[widgit]['text'], font=self.my_font) - widgits_pr[widgit]['entry'].grid(row=widgits_pr[widgit]['row'], column=widgits_pr[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we') - # widgits_pr[widgit]['entry'].configure(state='disabled') - elif widgit in ['loadsel', 'actionsel', 'inertiasel']: - match widgit: - case 'loadsel': - values = ["tool100", "inertia"] - case 'actionsel': - values = ["signle", "box", "cart"] - case 'inertiasel': - values = ["high", "middle", "low"] - - widgits_pr[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Profile Test'), button_color='#708090', fg_color='#778899', values=values, width=self.w_param, font=self.my_font) - widgits_pr[widgit]['optionmenu'].grid(row=widgits_pr[widgit]['row'], column=widgits_pr[widgit]['col'], padx=5, pady=5, sticky='we') - widgits_pr[widgit]['optionmenu'].set(widgits_pr[widgit]['text']) - # widgits_pr[widgit]['optionmenu'].configure(state='disabled') + # For durable_action tab START ===================================================================== # create progress bar - self.progressbar_pr = customtkinter.CTkProgressBar(self.tabview.tab('Profile Test')) - self.progressbar_pr.grid(row=5, column=1, padx=5, pady=5, sticky="ew") - self.progressbar_pr.configure(mode="determinnate", width=10) - self.progressbar_pr.start() - # For profile tab END ===================================================================== + self.progressbar_da = customtkinter.CTkProgressBar(self.tabview.tab('Durable Action')) + self.progressbar_da.grid(row=2, column=1, padx=5, pady=5, sticky="ew") + self.progressbar_da.configure(mode="determinnate", width=self.w_param) + self.progressbar_da.start() + for widgit in widgits_da: + if widgit == 'path': + widgits_da[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Durable Action'), text=f'{widgit.upper()}', font=self.my_font) + widgits_da[widgit]['label'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col'], sticky='e', padx=(20, 5), pady=10) + widgits_da[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Durable Action'), width=670, placeholder_text=widgits_da[widgit]['text'], font=self.my_font) + widgits_da[widgit]['entry'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=10, sticky='we') + elif widgit in ['loadsel']: + widgits_da[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Durable Action'), button_color='#708090', fg_color='#778899', values=["tool100", "inertia"], font=self.my_font) + widgits_da[widgit]['optionmenu'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col'], padx=5, pady=10, sticky='we') + widgits_da[widgit]['optionmenu'].set(widgits_da[widgit]['text']) + # For durable_action tab END ===================================================================== # 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.grid(row=6, column=1, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew') @@ -188,6 +205,35 @@ class App(customtkinter.CTk): tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......") # functions below ↓ ---------------------------------------------------------------------------------------- + def create_canvas(self, figure): + self.canvas = FigureCanvasTkAgg(figure, self) + self.canvas.draw() + self.canvas.get_tk_widget().configure(height=640) + self.canvas.get_tk_widget().grid(row=3, column=1, rowspan=3, columnspan=13, padx=20, pady=10, sticky="nsew") + + def create_plot(self): + plt.rcParams['font.sans-serif'] = ['SimHei'] + plt.rcParams['axes.unicode_minus'] = False + plt.rcParams['figure.dpi'] = 100 + plt.rcParams['font.size'] = 14 + plt.rcParams['lines.marker'] = 'o' + + df = pd.read_excel(durable_data_current_xlsx) + if not df.equals(self.df_copy) or self.flg == 0: + self.flg = 1 + self.df_copy = df.copy() + figure = plt.figure(frameon=True, facecolor='#E9E9E9') + plt.subplots_adjust(left=0.04, right=0.98, bottom=0.05, top=0.98) + ax = figure.add_subplot(1, 1, 1) + df.plot(grid=True, x='time', y='axis1', ax=ax) + df.plot(grid=True, x='time', y='axis2', ax=ax) + df.plot(grid=True, x='time', y='axis3', ax=ax) + df.plot(grid=True, x='time', y='axis4', ax=ax) + df.plot(grid=True, x='time', y='axis5', ax=ax) + df.plot(grid=True, x='time', y='axis6', ax=ax) + + self.create_canvas(figure) + def thread_it(self, func, *args): """ 将函数打包进线程 """ self.myThread = Thread(target=func, args=args) @@ -216,17 +262,23 @@ class App(customtkinter.CTk): # self.tabview.configure(state='normal') def detect_network(self): + df = pd.DataFrame(durable_data_current) + df.to_excel(durable_data_current_xlsx, index=False) + with open(heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('0') self.hr = openapi.HmiRequest(self.write2textbox) self.md = openapi.ModbusRequest(self.write2textbox) while True: + if self.tabview.get() == 'Durable Action': + self.create_plot() + with open(heartbeat, 'r', encoding='utf-8') as f_hb: c_state = f_hb.read().strip() pb_color = 'green' if c_state == '1' else 'red' self.progressbar.configure(progress_color=pb_color) - self.progressbar_pr.configure(progress_color=pb_color) + self.progressbar_da.configure(progress_color=pb_color) if c_state == '0': self.hr.t_bool = False sleep(3) @@ -239,10 +291,22 @@ class App(customtkinter.CTk): tab_name = self.tabview.get() if tab_name == 'Data Process': + self.flg = 0 self.menu_main_dp.set("Start Here!") + try: + self.canvas.get_tk_widget().grid_forget() + except: + pass elif tab_name == 'Automatic Test': + self.flg = 0 self.menu_main_at.set("Start Here!") self.seg_button.configure(state='normal') + try: + self.canvas.get_tk_widget().grid_forget() + except: + pass + elif tab_name == 'Durable Action': + pass def initialization(self): tab_name = self.tabview.get() @@ -263,7 +327,7 @@ class App(customtkinter.CTk): self.menu_sub_dp.grid_forget() elif tab_name == 'Automatic Test': for widgit in widgits_at: - if widgit in ['path', 'av1', 'av2', 'av3', 'av4', 'av5', 'av6', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6', 'rr1', 'rr2', 'rr3', 'rr4', 'rr5', 'rr6']: + if widgit in ['path', ]: widgits_at[widgit]['label'].configure(text=f'{widgit.upper()}', text_color='black') widgits_at[widgit]['entry'].delete(0, tkinter.END) widgits_at[widgit]['entry'].configure(placeholder_text=widgits_at[widgit]['text'], state='normal') @@ -273,6 +337,15 @@ class App(customtkinter.CTk): widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text']) widgits_at[widgit]['optionmenu'].configure(state='disabled') self.seg_button.set("功能切换") + elif tab_name == 'Durable Action': + for widgit in widgits_da: + if widgit in ['path', ]: + widgits_da[widgit]['label'].configure(text=f'{widgit.upper()}', text_color='black') + widgits_da[widgit]['entry'].delete(0, tkinter.END) + widgits_da[widgit]['entry'].configure(placeholder_text=widgits_at[widgit]['text'], state='normal') + elif widgit in ['loadsel']: + widgits_da[widgit]['optionmenu'].configure(state='normal') + widgits_da[widgit]['optionmenu'].set(widgits_at[widgit]['text']) def func_main_callback(self, func_name): self.initialization() @@ -369,7 +442,7 @@ class App(customtkinter.CTk): self.textbox.tag_config(tagName=color, foreground=color) tab_name_cur = self.tabview.get() - if tab_name == 'openapi' and tab_name_cur == 'Automatic Test': + if tab_name == tab_name_cur: if wait != 0: self.textbox.insert(index='end', text=text, tags=color) self.textbox.update() @@ -383,7 +456,7 @@ class App(customtkinter.CTk): self.textbox.insert(index='end', text=text + '\n', tags=color) self.textbox.update() self.textbox.see('end') - elif tab_name == tab_name_cur: + elif tab_name == 'openapi' and tab_name_cur == 'Automatic Test' or tab_name_cur == 'Durable Action': if wait != 0: self.textbox.insert(index='end', text=text, tags=color) self.textbox.update() @@ -489,12 +562,24 @@ class App(customtkinter.CTk): return 0, 0 else: return 0, 0 + elif tab_name == 'Durable Action': + path = widgits_da['path']['entry'].get().strip() + loadsel = widgits_da['loadsel']['optionmenu'].get() + c1 = exists(path) + c2 = loadsel in ['tool100', 'inertia'] + if c1 and c2: + return 7, path, loadsel + else: + return 0, 0 def func_start_callback(self): self.textbox.delete(index1='1.0', index2='end') flag, *args = self.check_param() - func_dict = {1: brake.main, 2: current.main, 3: iso.main, 4: wavelogger.main, 5: do_brake.main, 6: do_current.main} + func_dict = { + 1: brake.main, 2: current.main, 3: iso.main, 4: wavelogger.main, 5: do_brake.main, 6: do_current.main, + 7: factory_test.main + } if flag == 1: func_dict[flag](path=args[0], vel=args[1], trq=args[2], estop=args[3], w2t=self.write2textbox) elif flag == 2: @@ -509,6 +594,9 @@ class App(customtkinter.CTk): elif flag == 6: self.pre_warning() func_dict[flag](path=args[0], hr=self.hr, md=self.md, loadsel=args[1], w2t=self.write2textbox) + elif flag == 7: + self.pre_warning() + func_dict[flag](path=args[0], hr=self.hr, md=self.md, w2t=self.write2textbox) else: tkinter.messagebox.showerror(title="参数错误", message="请检查对应参数是否填写正确!", ) diff --git a/aio/code/automatic_test/btn_functions.py b/aio/code/automatic_test/btn_functions.py index 884a2b0..2f57992 100644 --- a/aio/code/automatic_test/btn_functions.py +++ b/aio/code/automatic_test/btn_functions.py @@ -2,18 +2,6 @@ from json import loads from sys import argv -def validate_resp(_id, response, w2t): - match _id: - case 'DATA ERR': - w2t(f"数据处理错误,需要确认", 0, 4, 'red', tab_name='Automatic Test') - case 'DATA READ ERR': - w2t(f"无法读取数据,需要确认", 0, 3, 'red', tab_name='Automatic Test') - case 'NOT SUPPORT': - w2t(f"不支持的功能,需要确认", 0, 2, 'red', tab_name='Automatic Test') - if not response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') - - def execution(cmd, hr, w2t, **kwargs): _id = hr.execution(cmd, **kwargs) _msg = hr.get_from_id(_id) @@ -21,7 +9,8 @@ def execution(cmd, hr, w2t, **kwargs): w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name='Automatic Test') else: _response = loads(_msg) - validate_resp(_id, _response, w2t) + if not _response: + w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') return _response diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index b937264..408fd3e 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -101,18 +101,6 @@ def prj_to_xcore(prj_file): ssh.close() -def validate_resp(_id, response, w2t): - match _id: - case 'DATA ERR': - w2t(f"数据处理错误,需要确认", 0, 4, 'red', tab_name='Automatic Test') - case 'DATA READ ERR': - w2t(f"无法读取数据,需要确认", 0, 3, 'red', tab_name='Automatic Test') - case 'NOT SUPPORT': - w2t(f"不支持的功能,需要确认", 0, 2, 'red', tab_name='Automatic Test') - if not response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') - - def execution(cmd, hr, w2t, **kwargs): _id = hr.execution(cmd, **kwargs) _msg = hr.get_from_id(_id) @@ -120,7 +108,8 @@ def execution(cmd, hr, w2t, **kwargs): w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name='Automatic Test') else: _response = loads(_msg) - validate_resp(_id, _response, w2t) + if not _response: + w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') return _response diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index 245fe0f..1dff222 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -86,18 +86,6 @@ def prj_to_xcore(prj_file): ssh.close() -def validate_resp(_id, response, w2t): - match _id: - case 'DATA ERR': - w2t(f"数据处理错误,需要确认", 0, 4, 'red', tab_name='Automatic Test') - case 'DATA READ ERR': - w2t(f"无法读取数据,需要确认", 0, 3, 'red', tab_name='Automatic Test') - case 'NOT SUPPORT': - w2t(f"不支持的功能,需要确认", 0, 2, 'red', tab_name='Automatic Test') - if not response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') - - def execution(cmd, hr, w2t, **kwargs): _id = hr.execution(cmd, **kwargs) _msg = hr.get_from_id(_id) @@ -105,7 +93,8 @@ def execution(cmd, hr, w2t, **kwargs): w2t(f"无法获取{_id}请求的响应信息", 0, 7, 'red', tab_name='Automatic Test') else: _response = loads(_msg) - validate_resp(_id, _response, w2t) + if not _response: + w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') return _response diff --git a/aio/code/durable_action/__init__.py b/aio/code/durable_action/__init__.py new file mode 100644 index 0000000..913ac28 --- /dev/null +++ b/aio/code/durable_action/__init__.py @@ -0,0 +1 @@ +__all__ = ['factory_test'] \ No newline at end of file diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py new file mode 100644 index 0000000..f68036f --- /dev/null +++ b/aio/code/durable_action/factory_test.py @@ -0,0 +1,252 @@ +from sys import argv +from os.path import exists, dirname +from os import scandir +from paramiko import SSHClient, AutoAddPolicy +from json import loads +from time import sleep, time +import pandas as pd +from openpyxl import load_workbook +from math import sqrt + +tab_name = 'Durable Action' +durable_data_current_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current.xlsx' +durable_data_velocity_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_velocity.xlsx' +display_pdo_params = [ + {"name": "hw_joint_vel_feedback", "channel": 0}, + {"name": "hw_joint_vel_feedback", "channel": 1}, + {"name": "hw_joint_vel_feedback", "channel": 2}, + {"name": "hw_joint_vel_feedback", "channel": 3}, + {"name": "hw_joint_vel_feedback", "channel": 4}, + {"name": "hw_joint_vel_feedback", "channel": 5}, + {"name": "device_servo_trq_feedback", "channel": 0}, + {"name": "device_servo_trq_feedback", "channel": 1}, + {"name": "device_servo_trq_feedback", "channel": 2}, + {"name": "device_servo_trq_feedback", "channel": 3}, + {"name": "device_servo_trq_feedback", "channel": 4}, + {"name": "device_servo_trq_feedback", "channel": 5}, +] +durable_data_current = { + 'time': list(range(1, 26)), + 'axis1': [0 for _ in range(25)], + 'axis2': [0 for _ in range(25)], + 'axis3': [0 for _ in range(25)], + 'axis4': [0 for _ in range(25)], + 'axis5': [0 for _ in range(25)], + 'axis6': [0 for _ in range(25)], +} +durable_data_velocity = { + 'time': list(range(1, 26)), + 'axis1': [0 for _ in range(25)], + 'axis2': [0 for _ in range(25)], + 'axis3': [0 for _ in range(25)], + 'axis4': [0 for _ in range(25)], + 'axis5': [0 for _ in range(25)], + 'axis6': [0 for _ in range(25)], +} + +def traversal_files(path, w2t): + if not exists(path): + msg = f'数据文件夹{path}不存在,请确认后重试......' + w2t(msg, 0, 1, 'red', tab_name=tab_name) + else: + dirs = [] + files = [] + for item in scandir(path): + if item.is_dir(): + dirs.append(item.path) + elif item.is_file(): + files.append(item.path) + + return dirs, files + + +def check_files(data_dirs, data_files, w2t): + if len(data_dirs) != 0 or len(data_files) != 2: + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2.configs.xlsx', 0, + 10, 'red', tab_name) + + _files = [data_files[0].split('\\')[-1], data_files[1].split('\\')[-1]] + _files.sort() + if _files != ['configs.xlsx', 'target.zip']: + w2t('初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2.configs.xlsx', 0, 10, 'red', tab_name) + + data_files.sort() + return data_files + + +def prj_to_xcore(prj_file): + ssh = SSHClient() + ssh.set_missing_host_key_policy(AutoAddPolicy()) + ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') + sftp = ssh.open_sftp() + sftp.put(prj_file, '/tmp/target.zip') + cmd = 'cd /tmp; rm -rf target/; mkdir target; unzip -d target/ -q target.zip; ' + cmd += 'chmod 777 -R target/; rm target.zip' + ssh.exec_command(cmd) + + cmd = 'sudo rm -rf /home/luoshi/bin/controller/projects/target; ' + cmd += 'sudo mv /tmp/target/ /home/luoshi/bin/controller/projects/' + stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) + stdin.write('luoshi2019' + '\n') + stdin.flush() + print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo + print(stderr.read().decode()) # 顺便也执行以下stderr + + _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') + cmd = 'cd /home/luoshi/bin/controller/; ' + cmd += f'sudo mv projects/target/_build/{_prj_name}.prj projects/target/_build/target.prj' + stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) + stdin.write('luoshi2019' + '\n') + stdin.flush() + print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo + print(stderr.read().decode()) # 顺便也执行以下stderr + ssh.close() + + +def execution(cmd, hr, w2t, **kwargs): + _id = hr.execution(cmd, **kwargs) + _msg = hr.get_from_id(_id) + if not _msg: + w2t(f"无法获取{_id}请求的响应信息", 0, 7, 'red', tab_name=tab_name) + else: + _response = loads(_msg) + if not _response: + w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name=tab_name) + return _response + + +def run_rl(path, config_file, hr, md, w2t): + # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 + _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + md.trigger_estop() + md.reset_estop() + md.write_act(False) + sleep(1) # 让曲线彻底关闭 + _response = execution('state.switch_manual', hr, w2t) + _response = execution('state.switch_motor_off', hr, w2t) + + # 2. reload工程后,pp2main,并且自动模式和上电 + prj_path = 'target/_build/target.prj' + _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['current']) + _response = execution('overview.get_cur_prj', hr, w2t) + _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['current']) + _response = execution('state.switch_auto', hr, w2t) + _response = execution('state.switch_motor_on', hr, w2t) + + # 3. 开始运行程序 + _response = execution('rl_task.run', hr, w2t, tasks=['current']) + _t_start = time() + while True: + if md.read_ready_to_go() == 1: + md.write_act(True) + break + else: + if (time() - _t_start) // 20 > 1: + w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) + else: + sleep(1) + + # 4. 获取初始数据,周期时间,首次的各轴平均电流值,打开诊断曲线,并执行采集 + _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) + _t_start = time() + while True: + scenario_time = md.read_scenario_time() + if float(scenario_time) > 1: + w2t(f"场景的周期时间:{scenario_time}", 0, 0, 'green', tab_name) + break + else: + if (time() - _t_start) // 60 > 3: + w2t(f"未收到场景的周期时间,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) + else: + sleep(5) + sleep(1) # 一定要延迟一秒再读一次scenario time寄存器,因为一开始读取的数值不准确 + scenario_time = float(md.read_scenario_time()) + sleep(scenario_time * 0.2) # 再运行周期的20%即可 + + # 6. 关闭诊断曲线,停止程序运行,下电并且换成手动模式 + _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) + _response = execution('rl_task.stop', hr, w2t, tasks=['current']) + sleep(1) # 保证所有数据均已返回 + # 7. 保留数据并处理输出 + data = get_durable_data(path, config_file, durable_data_current, scenario_time, hr, w2t) + df = pd.DataFrame(data) + df.to_excel(durable_data_current_xlsx, index=False) + + # 8. 继续运行 + _response = execution('rl_task.run', hr, w2t, tasks=['current']) + while True: + # 每3分钟,更新一次数据,打开曲线,获取周期内电流,关闭曲线 + sleep(180) + _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) + sleep(scenario_time + 10) + _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) + # 7. 保留数据并处理输出 + data = get_durable_data(path, config_file, durable_data_current, scenario_time, hr, w2t) + df = pd.DataFrame(data) + df.to_excel(durable_data_current_xlsx, index=False) + + +def get_durable_data(path, config_file, data, scenario_time, hr, w2t): + _data_list = [] + for _msg in hr.c_msg: + if 'diagnosis.result' in _msg: + _data_list.insert(0, loads(_msg)) + else: + _index = 210 + for _msg in hr.c_msg: + if 'diagnosis.result' in _msg: + _index = hr.c_msg.index(_msg) + break + del hr.c_msg[_index:] + hr.c_msg_xs.clear() + + # with open('log.txt', 'w', encoding='utf-8') as f_obj: + # for _ in _data_list: + # f_obj.write(f"{_}\n") + + _wb = load_workbook(config_file, read_only=True) + _ws = _wb['Target'] + rcs = [] + for i in range(6): + rcs.append(float(_ws.cell(row=6, column=i + 2).value)) + + _d2d_trq = { + 'device_servo_trq_feedback_0': [], 'device_servo_trq_feedback_1': [], 'device_servo_trq_feedback_2': [], + 'device_servo_trq_feedback_3': [], 'device_servo_trq_feedback_4': [], 'device_servo_trq_feedback_5': [], + } + for line in _data_list: + for item in line['data']: + for i in range(6): + item['value'].reverse() + if item.get('channel', None) == i and item.get('name', None) == 'device_servo_trq_feedback': + _d2d_trq[f'device_servo_trq_feedback_{i}'].extend(item['value']) + + if len(_d2d_trq['device_servo_trq_feedback_0']) / 1000 > scenario_time + 1: + _df = pd.DataFrame(_d2d_trq) + for i in range(6): + _ = sqrt(_df[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/1000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) + del data[f"axis{i + 1}"][0] + data[f"axis{i + 1}"].append(_) + break + else: + with open(f'{path}\\device_servo_trq_feedback_0.txt', 'w', encoding='utf-8') as f_obj: + for _ in _d2d_trq['device_servo_trq_feedback_0']: + f_obj.write(f"{_}\n") + w2t("采集的数据时间长度不够,需要确认。", 0, 2, 'red', tab_name) + + return data + + +def main(path, hr, md, w2t): + data_dirs, data_files = traversal_files(path, w2t) + config_file, prj_file = check_files(data_dirs, data_files, w2t) + prj_to_xcore(prj_file) + run_rl(path, config_file, hr, md, w2t) + + +if __name__ == '__main__': + main(*argv[1:]) diff --git a/aio/code/openapi.py b/aio/code/openapi.py index 4cb454c..4ca716b 100644 --- a/aio/code/openapi.py +++ b/aio/code/openapi.py @@ -250,9 +250,8 @@ class HmiRequest(object): with open(heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write(_flag) if _flag == '0': - # self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) - self.w2t(f"", 0, 7, 'red', tab_name=self.tab_name) - sleep(1.5) + self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) + sleep(2) # with open(f"{current_path}/../assets/templates/c_msg.log", "w", encoding='utf-8') as f: # for msg in self.c_msg: # f.write(str(loads(msg)) + '\n') @@ -566,7 +565,7 @@ class HmiRequest(object): if flg == 0: # for old protocols req = None try: - with open(f'{current_path}/../assets/templates/{command}.json', encoding='utf-8', + with open(f'{current_path}/../assets/templates/json/{command}.json', encoding='utf-8', mode='r') as f_json: req = load(f_json) except: @@ -602,8 +601,7 @@ class HmiRequest(object): self.c.send(self.package(cmd)) sleep(0.5) except Exception as Err: - # self.w2t(f"{cmd}\n请求发送失败...{Err}", 0, 0, 'red', tab_name=self.tab_name) - self.w2t(f"", 0, 0, 'red', tab_name=self.tab_name) + self.w2t(f"{cmd}\n请求发送失败...{Err}", 0, 0, 'red', tab_name=self.tab_name) return req['id'] diff --git a/aio/code/profile/__init__.py b/aio/code/profile/__init__.py deleted file mode 100644 index 7824c48..0000000 --- a/aio/code/profile/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['do_profile'] \ No newline at end of file diff --git a/aio/code/profile/do_profile.py b/aio/code/profile/do_profile.py deleted file mode 100644 index e69de29..0000000 From 3010cb893141a1053659d1fc8b862d1a98401bc9 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 17 Jul 2024 14:17:00 +0800 Subject: [PATCH 11/36] =?UTF-8?q?v0.2.0.0(2024/07/17)=201.=20[profile:=20a?= =?UTF-8?q?io.py]=20=20=20=20-=20=E5=A2=9E=E5=8A=A0velocity=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=80=BB=E8=BE=91=20=20=20=20-=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=B4=9F=E8=BD=BD=E4=BF=A1=E6=81=AF=E4=B8=BA=E6=9B=B2=E7=BA=BF?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=202.=20[profile:=20factory=5Ftest.py]=20=20?= =?UTF-8?q?=20=20-=20=E5=A2=9E=E5=8A=A0velocity=E7=9B=B8=E5=85=B3=E9=80=BB?= =?UTF-8?q?=E8=BE=91=203.=20[profile:=20current.py]=20=20=20=20-=20?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=87=8F=E9=80=9F=E6=AF=94=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E7=9A=84=E8=A7=84=E5=88=99=204.=20[profile:=20openapi.py]=20?= =?UTF-8?q?=20=20=20-=20HmiRequest=E6=A8=A1=E5=9D=97=EF=BC=9A=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=8F=96=E6=B6=88=E8=AE=B0=E5=BD=95move.monitor?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=20=20=20=20-=20HmiRequest=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0=E4=BA=86durable=5Flock=E5=8F=98?= =?UTF-8?q?=E9=87=8F=EF=BC=8C=E6=8E=A7=E5=88=B6=E6=96=87=E4=BB=B6=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E4=BA=92=E6=96=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 12 ++++ aio/assets/file_version_info.txt | 8 +-- .../durable/durable_data_current.xlsx | Bin 6796 -> 5773 bytes .../durable/durable_data_velocity.xlsx | Bin 6796 -> 5777 bytes aio/assets/vers | 2 +- aio/code/aio.py | 59 +++++++++++------- aio/code/data_process/current.py | 4 +- aio/code/durable_action/factory_test.py | 47 +++++++++++--- aio/code/openapi.py | 8 ++- 9 files changed, 100 insertions(+), 40 deletions(-) diff --git a/aio/README.md b/aio/README.md index 294c7a2..1b75caf 100644 --- a/aio/README.md +++ b/aio/README.md @@ -499,3 +499,15 @@ v0.1.9.4(2024/07/15) 4. [profile: openapi.py]:多次合并遗留问题处理 5. templates文件夹组织架构调整 +v0.2.0.0(2024/07/17) +1. [profile: aio.py] + - 增加velocity相关逻辑 + - 修改负载信息为曲线信息 +2. [profile: factory_test.py] + - 增加velocity相关逻辑 +3. [profile: current.py] + - 修正减速比获取的规则 +4. [profile: openapi.py] + - HmiRequest模块:日志取消记录move.monitor相关 + - HmiRequest模块:增加了durable_lock变量,控制文件读写互斥 + diff --git a/aio/assets/file_version_info.txt b/aio/assets/file_version_info.txt index 5f58e11..e1ab27a 100644 --- a/aio/assets/file_version_info.txt +++ b/aio/assets/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, 1, 9, 2), - prodvers=(0, 1, 9, 2), + filevers=(0, 2, 0, 0), + prodvers=(0, 2, 0, 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 toolbox'), - StringStruct('FileVersion', '0.1.9.2 (2024-07-13)'), + StringStruct('FileVersion', '0.2.0.0 (2024-07-17)'), StringStruct('InternalName', 'AIO.exe'), StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'), StringStruct('OriginalFilename', 'AIO.exe'), StringStruct('ProductName', 'AIO'), - StringStruct('ProductVersion', '0.1.9.2 (2024-07-13)')]) + StringStruct('ProductVersion', '0.2.0.0 (2024-07-17)')]) ]), VarFileInfo([VarStruct('Translation', [1033, 1200])]) ] diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index f438a2ad364c7fd7e5be6d73da826901e3ad0a49..1d18002d239aa2d0537ea2ee66251bde7f961ed7 100644 GIT binary patch delta 1876 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 N!*tQA$CLtqzX02;J+J@( delta 2839 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 scenario_time + 1: _df = pd.DataFrame(_d2d_trq) for i in range(6): _ = sqrt(_df[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/1000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) - del data[f"axis{i + 1}"][0] - data[f"axis{i + 1}"].append(_) + del data[0][f"axis{i + 1}"][0] + data[0][f"axis{i + 1}"].append(_) + _df = pd.DataFrame(data[0]) + while True: + if not hr.durable_lock: + hr.durable_lock = 1 + _df.to_excel(durable_data_current_xlsx, index=False) + hr.durable_lock = 0 + break + else: + sleep(1) + + _df = pd.DataFrame(_d2d_vel) + for i in range(6): + _ = sqrt(_df[f'hw_joint_vel_feedback_{i}'].apply(lambda x: (rcs[i]*x/1000)**2).sum()/len(_df[f'hw_joint_vel_feedback_{i}'])) + del data[1][f"axis{i + 1}"][0] + data[1][f"axis{i + 1}"].append(_) + _df = pd.DataFrame(data[1]) + while True: + if not hr.durable_lock: + hr.durable_lock = 1 + _df.to_excel(durable_data_velocity_xlsx, index=False) + hr.durable_lock = 0 + break + else: + sleep(1) break else: with open(f'{path}\\device_servo_trq_feedback_0.txt', 'w', encoding='utf-8') as f_obj: @@ -238,8 +267,6 @@ def get_durable_data(path, config_file, data, scenario_time, hr, w2t): f_obj.write(f"{_}\n") w2t("采集的数据时间长度不够,需要确认。", 0, 2, 'red', tab_name) - return data - def main(path, hr, md, w2t): data_dirs, data_files = traversal_files(path, w2t) diff --git a/aio/code/openapi.py b/aio/code/openapi.py index 4ca716b..9da630e 100644 --- a/aio/code/openapi.py +++ b/aio/code/openapi.py @@ -1,4 +1,4 @@ -from json import load, dumps +from json import load, dumps, loads from socket import socket, setdefaulttimeout, AF_INET, SOCK_STREAM from threading import Thread import selectors @@ -171,6 +171,7 @@ class HmiRequest(object): self.half_length = 0 self.index = 0 self.reset_index = 0 + self.durable_lock = 0 self.sock_conn() self.t_heartbeat = Thread(target=self.heartbeat) @@ -257,8 +258,11 @@ class HmiRequest(object): # f.write(str(loads(msg)) + '\n') def msg_storage(self, response, flag=0): + # response是解码后的字符串 messages = self.c_msg if flag == 0 else self.c_msg_xs - if len(messages) < 20000: + if 'move.monitor' in response: + pass + elif len(messages) < 20000: messages.insert(0, response) else: messages.insert(0, response) From 9d252cc36fe77880d17615df3e0ebc9bc4965290 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 17 Jul 2024 14:40:25 +0800 Subject: [PATCH 12/36] add projects for different conditions --- .../{target.zip => target_brake_current.zip} | Bin aio/assets/target_durable.zip | Bin 0 -> 19562 bytes .../durable/durable_data_current.xlsx | Bin 5773 -> 5540 bytes .../durable/durable_data_velocity.xlsx | Bin 5777 -> 5540 bytes 4 files changed, 0 insertions(+), 0 deletions(-) rename aio/assets/{target.zip => target_brake_current.zip} (100%) create mode 100644 aio/assets/target_durable.zip diff --git a/aio/assets/target.zip b/aio/assets/target_brake_current.zip similarity index 100% rename from aio/assets/target.zip rename to aio/assets/target_brake_current.zip diff --git a/aio/assets/target_durable.zip b/aio/assets/target_durable.zip new file mode 100644 index 0000000000000000000000000000000000000000..54fa8d006af1f4eff7409aadbd2c09a94e76fd8c GIT binary patch literal 19562 zcmb`vWmKI@5-yCpySqEVCAho0ySqzp4{pJNySuwfffNdkkQ06+i$0MI&}tG&Gboxoo{=^8kjTN%;INrJ!r;@?T`e}dp& ze)BJop|gX7v5nLJ1VjAF(Qir3H01^K4iEqU?LWbE4pw#!wx-JC{BZsZ2%r=13khmX zcBV=(rav;6RXd42Od@QqlnX;Rv7I&EPd8Ic6XIo)`2+835q(skJxxd>N#-`j^k<&Z zpjSGPD-W?}HK>$xwuiTEcLvA6h~80eIO=3^#<26k8gI|@$f2#mqA4&cjI4{tTAIBM zX)Uvq+g4$~B&WCUoH-)0{9sl*h|sqcqmShr09!PO$;> zP9NC#VdF*I0#)$glcfVAl+5Q)PtzP9%H-VU4b~jVfZ9(XD+RT(2hP{J`XK6&n8ya$ zXdPKKA`?Q^Iu+e%rX1D-;fMQ`4eb!4YPtsr>0~9=PRnrJF7GF@rdIjs@)ys&l=ira zrC5Bp(j&zJh6)I}>ZO&f2r_;4lk>2?tZY*E!pj?#M2T7nm+W|?)nzpe!Xvc}C2v2) z;E2PYshz!#VLW!?e!Se^!rR_wqe%Q8xauIRdLc?pjcsayCrUzM&90vBtNP)`L6#W!})r zAH!c_YVmvw10avQjaH_=_r8B{%Ag#bG1^4oSnf)iz6El=&n)%K5)5#Th?|@%jq32+9UCLTD5k8*JyK{t-Zgm{Yt3TP$RH`IW7qbJYvOAdTA!%k4M1L$ z3CG2v8+VY5edf?lP^zbduq4P3e_FiGRP{VDS>N?&Q?xmy8?>&Gc1|1q7X0qXr)lzO zf~+R00Fs*CrY4O={ERtPX797M^;GkN+8i%SPr%geO+&@1Pur81`_0z$IJ|Dfc;_SM z^N)vz{<+SPNsFfe++0Wf$EL=Gqn3p{_f{W(*P8Iw-+$JG{<|uvhL@U<`M+wyyVshK zp(rWa!-v2lxasrBj%pZciO5WfU5_7Gk%qEpu%HVKI)AASl{h#vi%oFzODW@p0XODz zB$n(GXyK?NGJf|pBNtbtZO20S;f{AXkaD}#oHS{3?tvyLtVM8zfEks-KGPi78cLi{ zdTUW1QG1+}Q7vSmX9HM^b#BQ4RWM!xj4z#Q8%2#jTm(Q}u)&C2;OQa zT-?HiQ6)O-VJDNGEwCJ-!`1+-8@3qhRPKEfQ#a_wEM!74b`R=!eyn?9up=_5nI1Wf zA2Lx|F^)sw*oeqvB4%L%o}Uldr_4Y^sh5!|HJVl-Xj(S67wZg~?0NjOJ_<%5cIkq1 z!#4_LA42H~y(fsE0m}ZwM{)n|vVn>-GgRNhkNwor?|zWIMQF%}IBB54E4#C`_&70k z1#{Bh>vX)yHf$KRKeVhNu+{%~ZIBxhDXJczkSzc6IK8e-WoD+04*jXl0KDzi!`)!% zjOlpzJWp735W5HjWrrK}u$wX}`W5i2=imDGPtW__CemlWc>Mh6EElFXg_$efUXfn=o{6%}>b?l^Ad@fc9JA~j2?Y16$Q3>gf}k)cMQ^*l9f%;_4ru6D(G;Ao-&vu^V`{~6gQgdW zUzk0-Gv^MUT64z|6p7~_vw)}wt}7wTqSnhB|DuP22ZaOr(ceUnkSjRf*B%urI|g5o zKe||st}I5dYzmX=PQlHkOb%L-kTg1U>A7K zy)`lV+ujLTlQ>PFiz#y&jQ@ptZ=(uQooe^D`DuOoKmn6}wKBOLQ$`R#%=dC6gcNCl zm;wpC*;0ffJ926?tr10>Vdp4%s(|TKzM7zJcCb^IE6M&Lt$@u)O)dydjQp55BWO8N za66%zrGlsdBIc4tke!b-HQQtK{Y=O(AP=-VqL-S&FL!j>KJ3v#1)Y1k?!xRE7 zgg|KjDn5i=&}u_)5)*;c=(>EX_tV=~nz#tI4Ss9Kp$ajHbylj?LJ68f1$JVJd%%Xq z(xT&oH5TY&Fi0Dju{dQ9PSr>S5};x7Dg+A&7ZBnzP8$9za94=T7~ zqP|YC(^%)M)Q2YF)NSu2R{4_?%j-CbyykyI&<}Ay^)knMYRF==7=*Wk_Q-h zpOLD_KG8fquu=sHWRH&Ga<|#3Ui?&fSL8-lfms?~u)eKz$xOL1bq+HITzaK2bsd$Ne3UkQ@Q6-H3-p)ca01oxNv$j1>(}|uC zU+0eos@u8q>v)-r%eec9Y|2OIIU04RTbXdOXy&8?9@RCnGDe|#N*lsd?)3I#%`S6#0^g_2Jl z7+0ygt#4T=t4hJ#-a=jjF~%?}upoy3kpf1^-vUdGs*?h_6h!S^Ju`VdL?N@9I8i}> z+;%*~5P86MwZy!^e7=%es#=^zLUKxG$eM9bFrT|1w+cEIqMc?oBOxeRlXf&=ct5WM z=zV{aU?))HiA18?c1aZ{)GR*)ULfkI@+j!9QTweue_A@*#542i&esR&x25K`y4L!3 zzfC2TeRk6w^aYURb$zk1Z7Ln7LWAy?=(hs?6b)PDe~kGe66@tb`7PQ`-^onZ%G}Y3 z&e7fR>c$oF#$GuT-VWyC`~n7U!{Ns90yF~fm*}?w{uF&tNJS?0B2xS1c^P#6UZmOC zn%g-2r|k2)Yv_w#!tX9z9j@ge9AOlOM#jgeDaC0dWNGCoLdS>3rIo9chiXb#C;0vA zXDf7|hP>!hdC_&Ns(-2SHp4$v`KEWc;sFZ)(5?Qbl@7*6#wO-A#;;cHXlX~UG$4AP zRer-KfW(30V1kJWL9vfOyQhGvqZig^|H^5%X%zVl)*s{P?7d)Y%hYMTqaxp;Q+q>Y zeqvF|#u(0L!s3VfaOLuZoT(6E!;VE>RxGH zv2Hq$;Q=t^c5YX@xM(Vil> z18ZJ&3j@~xX6K_b*J}s#(nEK)WalvGI3iLlThcNTUmglWAKsA0?kJL8tP?-8y&C-j zKd(Ced24H{R29D+vNvV4bHXbYjMI^E96h#lPa}8^<#JrxCK7SNW!J%~JeT^zE@$J> zF&(?(`}!kP^smLM6`ph%mh>krZu6PVHYY9aY?<{R7}p-2t-!CjvI0I&69(ramprV- zDp5!8MdS#vT5spDwwULl*WW)4k1uVvxxe}1 z)8S$7eRF+rw72Hz6mrvVYy0{6{Kri^erNLs@0;?FyGE8HQqlf5={DG#M~)XGeOqUQiAA|uxwrI5{x$_ENt<9HGd5~9W-5yY7)03P<4+b|AL zG}j+?QD0sPmKHLUTV$J_nLqR6KIq5+11(lC65vp}1RRL-4A|zDhyOe$0m7VY(IG_5 zP1X0jnc3l5PEKmX>^}Ps!`hG~AN-623Wy9Trt~G4^OP&pcJd*k-f{XzO=t6)jD$+B zCuX4|DUjfRqroyQ#P@)^QHGRGFgWHB5{t&9`W`X1!kL?f&&D`x^EVX)Z18Sqn4M9l zv>3^8+;Q?vibCNe)zt2Th1(+(>+L@i-bgH~+kgu|h%BOG#_f3()99;q!(J-jV025% z>6O_bx9{DdW+Z20_!);k?Mi@8t!Aur(Gtf?IG>p*P$FJ^jl<4!SAFP$|G|Preog>T zSGyl2DD^m9EEDjEsB-{6h}xa1e3o%!N8gy3PqgA<@y>FeXyb#{K>gwCTU+J4P(B?A?2F)L3@AZM*& zyEhs;MVu=H3{bU?fnO}t*W+D$Ut2cnk_vl|apQYCdD75+LMKW3et@$fFa-?s%s=D) z1CMfz4HE(BoW4rN){;Y6p_gX|>rt<`>~Q>}67 zB=<#wI(L!b;nj|w2dXgmr71EE?_d^X-eYPm+oVv7Zoz=qZ+N9U=}6+kqi3FyjgbxtUDNe(N?d6kE#_7_Cv5eNo)|lS4MAPa zX$*>fka)h>EhT%%-#Z+QUTxE-icdmHfWn}{iX%gO*#Ik`Oe`x9xpdjD?oanK?-+{4 zj}!hBBfIwlGKRBsx6x*3+H_5;S+RWvq7}Gjq@$@pmOTcv+$e?|jx-)@W)5cyg|t^= zcS0IOlCFbuP3mK8S{sVLW644vO5V9a4t8j#S6Sq;6$#omF|D{Q841?d#J+^C3sd9> zyS{q^A{rV?Sl|%ic}U3b)sl z0ZBWa=gi@EoqIq<1Tn)$iegcG>7r1iftbvb2PeBp-;Tq~KhVBPs8ut_Ae9Tw*5RK; zW)yDP@-K3L=`r5w3ivW@^O=i=u$YL`r|9cUmsl&(_&3${#6ChcM6jPXH$}UW%9k06 zR%MeU!`_Rgl0b_Il0#Nvf^rwb4y@4XXjcM#^qW>Xlo|@>>UA7@ZN^OWIUxq9ky1$s zK(--a0VmYd&!l+?T~NA3{7suEdxV8oa4?9IZQJSH44T{&sYj5S3UGWIH|+LJ@JG9) z7TZE`h+oSb-_o0kzy~81am@lIR*rn!Y!ft^sKt zt^waoi0dk?DnZroY}^drc6@=XkZ+IyJ=^8A^PCM!9f1Z ztvhSxhM1@AjuyFR;Vr>MJZe4xmG$?Tn8c3=LFSt%$T8x(i^4Q%z^X+>sLHTa6B?jd zZAm*IH_$6RwWQPVN1MiIY|BGy@Xz-?vg0E7e zLp`xX)5DDr!g|yLu7Zy8ADdM+e1MUme8QNAtf_E1G?KYJ;9%;X%cF2WE>jv%j?i1@au%9}pm zG_nFr9`4>#Hp7ZxWQOxgLo2Ad(pA!iLTy*6aeK(3q3E3Gzwhw}Gr}ex12ft;`DqEp zK=niJzz6|&9xN@p(O>&saVulGdN<&m68maTkm_% z$Hf~-?0$}R7|=L@mlNbFa^K-jf>qLsAa6IL+C?TEN3)%!Q(Z-QZ=kNot8j5}{Bcvb zPoF}$gq;`A$QOQx(wo%r)QC=IGrn>?n~aVi{Ma$IyU8e0Ge_7MDkVbf7FM#V>Icm3 zc5j2>L-j4Xa{IHK2Lj)RTY!hL7OVGF)mhD1Mw1eCX5m#S5cQX_XxHr@(p6>n>J#K6 zh(B5pBpm2fiGM`LC&)N_YRXb%;K#~;+I4~mo;=OEQP3&ma0fH8Ff80D1Hs+nR=utb zE4xa!ir-sd8JU}x@q=+NZNAni>8ZJyTyBw4AePCXV+h|=qj_h)7`#Bi4EXd;6UN&) zS8ew_bO|il-Ay=R6$fT0;y1*SY!|T4LSMc8&2NI|)tYHBMBtmVpr0Y5YzvXsU=K&J zg6qO+G#I(fq<3vDRtqc?OA10ke6XtukfJ0Gi;ehglTYvBBwS&$n80S(1LhXi+)}or z0IeCHziwKoGo=E<0s{j2v=%u`a{3vLe_|T}m z{BC1~#>`Ld}C(5)-QyP0vGM7&4uE_Tw0Fr`B%-}{ysZu?MRbzqL^r%3Ezm`6f_+T?x!U|kHTyC_XdLszZD=XL*qwfo-l za&z`3rLFf|xAb|+XDe7!7tQSfx9rS@H@D-{&G+H)aor85 z4EYmMEyqW^S>4s2Ra)NH{e_wHl{Qbm=(@Knv_IEwAxRz-Juk~g&Oev=PWld}#!hs0 z4i-VN(r^I;2tjx0Jyj|JD)}xek)?RudimwBP=Hd?7-u?!kF|)S!DF6RFN+y~wgbKa zaah+?J?c`F5Or%7{%d0e{oc`}(DM>E@HO1rXFu7vx|uJUo}fOr9A=KmW%8U#t~(Ix z(uJx>A0NpD9KS9@4k+7vA1E!wW<8~c=^)CA`N>^w_Cz?SBhhkAwHOtGR)-=EcD68n9Adk*e4Az_8?X$K!}|GTD-nB^UnfUOXp>= zeJKFomjXcey^eOWwY75mV|jjYclXZ~G{sBF10sV#H9*ah3g;Jd&d!2y@~M?7S{DK9 z1Ezp+V&pK0mknTIE6#H>F&(Cwn(=k@k|6*~hq5yAFwxf+kub%!oH7r~6n14)e4y)C z9|HfS>|2%oR5spl#6$T-N!OR>jk2z`1{QxRd*^z2`H$s3#klMU&|k`$hjH{5bN*6U zLik?%o>YSKx8}x}zI|1Y0Yw^rE&hXksq{AEzf}SNfKvLCVSeS5|IaKjirTpvxM5Rm z`^z?3_`gd1Z`5xFbzE|b4~2(3=6M5`7^JMl^Ei8vfVy70#n_Xk*uA0KoLKtjk&6Qb8_z2&EdWTvjtw>8Hwv$qowy-dh?SOebd}0_VD~ftD z=)GW!PP{jnE6HBv8?`~wDro{k!NSH6r&PfW{$W(OUA$`>Qoo74o=hQjK3zh`79-Vh zLoJcATOmvx?@qxaJWAN`PPs8dSwn6)94_vKGhP3Xj05R<=H`h%gz8{TY6U-AExu6OHwqYM`WJ`^M3B`~vn zYw>!%IK1lLiI(N%^=jsPxIH>PIy>9be5ML1y~ppR{D5qU z_vdOPYC=@qTvM{&p?704_x6RSa+f+?9^|-N9xkw%vE;0i5)5d{m9QUDL+^=F6Ypt` z7HL4)+k=vn1dRl*fD1m#DaOVsIGvO7<+<}Gsm{TZ1h{Tkl+S{CtXGtnF>cPGL(V5k zPDIK!GFGNbR{ojQJ3W9VcliOf+NkeDJW;OLBI)eYvW;X8!LWObq0OE71vIw-u zZ~A_y?rrgIz#_gQ{_Cq9drZZ+xHV%`W>0>@23B7#;K^>`SRZUm$Ak4HFb(0CL*e=S z0s{mHWz--7n14K&mg)J6{Cw-jKRpbNMzk0C;@#z!eds@1^uJiozoKCV*PpAlxBb(P z#i+}@&I#?O1;pal!8|AkzeOpOu_whycRmSvQv0oX&<5#9$mTzjQNF*ScT#Q0pS4ic zkdT0Z6zQFwo*p}Ho8{qQUtHnf8+^>gOU>XYSH}U_qu`PBp=FNFfo$F6g-?xyy}hHs z91r+#ZgBTyW1Y(Ei%7Rq%*Wi?`|ng$2&+9fcl$+aSh9O&AL-)up#Zn|eHl}~1YiJ) zT5*TzfN}LM@IZBIygx0Etgd&%3b`gre$+!7n>2H1Zu`KAPqN?~J1{r7jZlaua7dWp z0ig%{@wOfGW49zAOBaS&18j|9D;UOF76RD4J+!b9qi>6 zR$H=V*23%@vr}W78N1sfj!bJ4Le-8hF?cABoos7{K_AyiL$|CUqmyUAa1lPNtVVWg zf?j)gFyYtWexC3k)U9v<%uH$oA**Y?l)!9mNMmYwB>@hJ1p4eyja$IYL*^bPUsdod zXMj#PyECl1omOhlyE_0Ea-P+b@)SvFb*|&q(9%m-n_XC+Qh*?;$FRHb8IqOVt7#t2G0Aqc z%>v$-U~hkkq5^dnFLgnM7OD>_gAQSJCWKI#D`>(PE!BR75T>P{-IBOX^6vz-IfAs_WgaPJ2(1W!ZRnpFN&$Zht(S9ohPP@LH~OSYN&VNhFaP zX<~SGPRRS!n)T_gvH4AV{oRt)UnX-Pn7A2{FJtoQ%k#=t{d;VFLv1?#i$Q|8bXB2{ zk@+G?GcqOmIY{&0&$T7 zagRh~wnSt#)fdTOsjZzCiVV;_CK>wI-1M!|zs-4#egsaJ7^QnLgXZOV;imvzC_P7W zQyYCNIyY;p+Um-oFY*+Uv{YZm#%q<|%`nL+h<%a#Dmy$T*{BQ!Yd>8tSJSvvGd$b4 z1@tSUx8nYHMz53LSAy^VbsmjU_6l+@y{r-$0087`9Fu2cZ>WVsWbSPeKjAhp&R_w;TW@B3Rb!!Bu4Ku)4d+Q5*lAz$5mZ~h12XF zOrc_0x-jesAtON=;5%DuHFmOjg4{GjTT`Q!N+Pd>f_#UCLeP7?bU8KCLwIX7_s+ov6x`Phh6(rL8cLA;vewGEg=V8OeGqp3D#1kHsmApU4=${!pr(ZY`P3o zD8X^|5M`41OH6~^eRnwc;aE-}P7CnISw9If5$q}hJ`kDZx^+kcZMJ}Tj)ZDBg0b4u z^jKsh^UdJq6L--My1d^+g1=X5brcOXXXVEL57m3@<^jrT9oUNJTZ0Ga9QNeH;K-X- zb6sm%;NyhG^j$EDvVu>xoEGkbPbe*MaSUEYFyeCD)b}~P|2BJhwRjt#J$?%m0`dey z%zWkm93_@U-{=$LV~#|NZoEsEY^zH3mBVyI38%)5SOR>>($>V;)||8o@YM;^dJfH_uEQR0FU^=yfvzmY{M8cDUeMNA*r0sq1cUVaIRSgaqH zO6k*b5Dhkz93MAImLMQi8Z79(q2&;iCOT`;5=}VSSL_?1=i_tuHE#IvJ=!h6Xka{W zZXUGgNgk;!2mtV4j3{9C2hZZ4MCr@;SZh8+tA@GJ1!N#D`(wPUDH ztd{9zKoP$CAiRw$Fwzs#0Bs;h!yr0f-(6y;8l@Nu3l=CBuD0(x0}lXM45K6v^aLwD z+D9MLASbt_CPa&gGwQy#>bkc6tsXfVixwS%|+@U3aoCis%YHY%N>aReZGlNfAyPkn}4=8HI-Xftg1T zuh8hr=f&Nr$!n-oGv`ne^o?f_!B71B-=_{%W$EMhKRBWH2OLGuyDam_=7fANVZ!4v z$8MC)YvK=muvYr~pf=J05^@4+V*`oVXEc298no8!D{q!D5 zV*M;Q55}RmSKcW1dQbOV+ds(^SL+#qX6`?M+IsJXanCZP=zd%ngg;wrGu(^kkCO(| zxrs08tn^te)cMN9XhNy#VBtn-GDdBSK1&XGRne@We738F>JN)(K^8tUB&`0vao}ev zbZ>14{u=kX+xqWcVTKeHt}?wmCjUePEpaVomW* ziACoyzURV4oAHE~-bC}rPSN;kl0H4v;Zoc#_z?$si`j$B@;4rP*yR==S2O@Mo}Y&A zBg>+{L1dcdDs1PcOEwA?GiO?JsbbPYrD@OHaF!qhR$0}WiT1Cm6Qn~n3K-BK{cBQs!PdugT+=Hn;2{LBpG@24lty@$O1~Q;3s`%to^LDRpVjm2 zbO-LGdOABAJLvuu|MmZP`ZWC|MEvthkeR*|Ai(P>6&HPnU+o~{ivy0R!{C_*6xi4I zzB4!AqC|lJn*MYO$nvQ8;U^RI(FOd6>z_X+Rg-nw+FIN%E-*iC98c~< zM5Gm}((^ojKOTR&j%M3A2G8_5|9(%7&m9*%I6r-N`+ajVf_$8wm&en?<*xT2PqdMD zbp+Y%cE6N-UUwwd?slVjfB_Tj<8*}e1w z)6LOXsm-{q4LyD4SDl)~JD1(K@y}YFZRzcNvKh^K_iS~@I-TGTqc`>#2!;&i>Q zSzz>G0Ks7N#rQjXz3xqJwLkpaxDgBhph3{mdOp_yY-;Lg{`3rM3(MCzJ{@M(GQQWS zI=*+d+}biLYuoYj+T$s_v19(~Y!|p~fo$~2Y88ZLxzUtOmEOiS)9d1X=cKjWeVpe9 zCyc01$Ni7!r)_z&2G2WvZ*JSIWb@A<_kf#*myqMTw4+ept+rR;2YrrC^+gXJ?YPE= zU?sS%7+_F>VI_aE6P!_ccm{LIp7|EK3naOP+qi`T&k;^l0ivW!3=V_KT=~*$B($wF zBU3oXsDPT|MUuvRgBD|-OQj4{n58I|@@GVM_9Pg$GtjG6PT9%YRVdyKLxVvE&yR6Hm5K5Fu zfX>;)R3|EFAuNH>0?D6&QARmawICk>mB0E(bC_{;xeq1AXra**#yylPE#t2Qzwb>@ z4=_xmXd~nVL7Z$Qp^e z9D0nbh$M=OJbAteSS5NSb6z8Ux-Q}fE{3e*?hgf8atfZoXNaoLYvSUbTX}Lf1q+6}iv? zh_hX8Q9POVB4lqp@eVX)S`M5I$qg)wxC0-QAm!%wgyL^YH*+Mz1$nvHq~3zSijsHX zUhyFa9$R}Qk(sQII4k>m*jR!QsR~v>Jnm|iqUO>GA0PK^gdA}`rKwe{HNl{AiCQ`s zA&*Q(%h3^ZR~2&$&8Aye#vT%sgU3lDiL%AH_4$#w0|Q!2Z%Zo4&cDQTlBOX<*#y3v z7yvqn>+h653JzasE{BSf{wcz?=^8iI*>G;A*u-Lmds;pTT?z+CGfplq{GM{HIJ}J!xcF{`M!gDIoWz`&P zZ;O&w251zODWgBeC6t^(WXKsKe;JN6`&=E#LLsU&yBc`_LY4MG#^(A;ij&cP8mf;w z==gonB~YTYI60eyN0gv7k8H67m*TAH1AF#JK}kHevNpCCw!$|nCFnWH%89a(IBAt= z8>5>(SDM5rb%(AgAe;!AX2fYlZUahbn%NEnedQ!8Bo8OzY)J$3ewg}i;++GlX!TU0 ztdra=h+pcFko)PR4-0O^`lrM-;z_m;9NB=}%dO3|C-Pl-Ccw^u>s(^y0EWrJMcH!P z(&P(|SeAYSK<2Na)Kf{Yl5)4m_YiJ3IA{ftRtU~)guLI>NhVDLz*~V>M{t7jI}c>o zW{BZAl;~=qS#Ubr7r6`08qEnT4CM^PnWam#Nmel)E^rZLvtX+S5QnDFx0r^p$ob*X zs;pl#yfPfQ+@5U`&+7YaQK81g)IpcLo=ghbiKb^;$kq<}YVyxgKkgHQ$n+0Z6t2O}Bszy{*%rvG=+is= zC)uAmajRUOZ=Q0^68cwW)KHqgtt2z0eu<{^9BgO|$+mS;Wh~NRrqSDdQPr zyvz$u7eUjiIpR6xl-ftk9NELaevT!b78OsQZngNm=YX0#(Do7oAPHqcCI=eHdhHEyfmIJySH$94_`6-p*>K1d860HwX*)AQ|j`B5zJs=lARgFChafz_PDy%) zJOe$?!_QbwdF?~=7T=99)p&(YmIL&=FVu>@NDh`f1+fCsF@lu9gi%A{`=n5wMt}l| zd$&VGQ&E{1{>I1a4ovJg=c6l7iK+b6^^%enj(*sM6k3E{OLKqM+0!NAooryV$}KKrsL%QTSj z@8kIi<5f$DAu#Rw5m-t|vLGg6YB7=0#a;@*kN~Qxiq!+tsrNv;`#X}sNZs^xxoBl< zSd@%eNykllZQhz#X>@bGyvyoC|;Zp^WE2y?;cR5X)e_gh7;8`T>WMQw}PV2 zP*9vmKZIc_0Y@R7tqPFTgT1dzn2#15 zdX%Fcn2J#`)OWB&rLp?-6U%INgPw&$yR4b$Itf4Ek*`mE6Dg4rg;I3P4rdq$#|(u>P6z> z?@*6TSnp1?(m!yNYur^xns#B0QodmCx`^^T09XxSjKOI@t*xR(yOLDirTCH#ystv) z86ei9cGlAdwk*vr0>2}MA(Y4xPbUEm2bQoJ?n77#ejhW?#iy=N81P79vI1XXR*?_A zmG$K;LkE~N%>Qd1G+AjmR&HRkeDJN5!~mYV9!~B%O29(8`j3S3JuMxZfnsBE;;3a< zw9AOkYL*Pb8(lzBg>0nNHIK83J_{pN9{MHN^C52#WzO)gA?qn z1m9O3?x*y&saRN&96cF^z?;VppE8f_~SG+O6Ux=x=u`8a?MYefXp!h<&*euP9u&yEe_Z`LtcSwDzKZn1}JBk zFe*m@caa!t73J?z%VACedDiN2mpdjoKaGgPfDlftNDk`gdFo@y#ZEsONvCVtql%z} z0z%!zUcbmb0nYPnPVoRph#E7(aHLAaMYp47*cB18k!RMI2)UQ3LB|Qj7Jl~bWsr!=EYkZ1FI+|{e@1;H zkXK)`ZTxj3IB+nIbg7tQs)|dZ*>{dxaQKUkMWy*7?4iibB_aOdXa3snt-uqgB&ei9 zi9bI_lR4ilq{CISBqkRq6Wf@~^nLqg1c&OnQN&$hj~|s3qpQm_)hmA|)X~pL#s>Ye zSz=Y8%^>A>SMgpFD7v`y_AYz~G@$W#(HiY?)tiePMVHQ`8W$BJFSNv#K9|$B2vPrR z$r-@QH$ZFvXYiKL(6W+fVSsnV(%6x0 zI*P?RRX|}Nos^VQUMxEM0I}GU=tP-h>1P}-NGvjZ{9=Nd>+W)?G-b$ltT;s>tmXo@ zZz=Ibs*5WK=GsTwCVY64MW~kq#WFYsWGh*G+}^bMGL|DCap*fob@;voJI`?ZxakK3V-Z)o~7Xj&44 zquhxigYO=Vl$1^S&M~-#7RKFB5K>K4JPGR1rawcRTq?Ejm;?J5Knbu1K_5m;D)C*! z@XU(fCt^XK&zS*)`OO2KWsE0RUSj3xJ`)0hwyk&I<;|ztRtt4)#99#2!X2V}V#P@N2`gv>M`E=ZWa<7`qWm(Oxh%2T1!w&m8cw%cpXN_wHXC;P$a=JK&+e&X!rNhi%= zZRx7qsP^ivA|(857?-V{dIUFl?XJCLEt=QsX&C$&`gQZ@?Z(aj-aLBU+k6dCd)?Fd zzh&J3f$)I;_w^<(8U0Gn{I9QnUv~1pL9gKof2U`DmY0wJaoNe=;QxNT$t(C}>m8uM z&*4A8|GMl%PV!F~Z?BSgy+!0T{Ut;8<@FB*{*H+Ir;xX|5WL>A@|ykKSN_8{l$Nzm8y7o6mUKK_?2Z_b7O6aV(K z<|}>vn*PH3{Ko%r`179<-X5}iiKh9L{*tixM#3LwJpU=;ZLIH~N*KTF;{MABySHaE z|0&^Zu=ZpOG1_!^3Z=Ddq3*iGQNrva+us5Wi8Quc*HRBHqIO8)f?&ra=1w`v-yh7X9DY z)!*oy7xdp;>pxL%X_Y?>%%K0x^!*d{wnSekm*07DzxyWv^H1#CvG|ol`Hd}j!TyU< l`6uXYhJUK*F7$iQmXid1p_Tyv@L&F1Uu3Vmd)#329x literal 0 HcmV?d00001 diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index 1d18002d239aa2d0537ea2ee66251bde7f961ed7..4ef2ed0da612d5d67d59d9d15c63d98e9f84715c 100644 GIT binary patch delta 1565 zcmYjRdpOg39R6*whGE!n+=e2#=YE9QgbvEY+&YqmG`C}OuS|@dY&taED6A4HbX*Q4 zm#3UmYvYi6n=NU=YWO$f21FyrLtsIvTHk*`c)+5fuD+vhK0 zq;&r-Ba}-+45IkqQ4P{G0wHq$#tOOCiaQu{IPkCguJSSUO2gt8Bsqjq#R+145Grf= zWTN&0Sd*s^h+I6fbkMHpG_vfhO@<#u5Tq{W#u+%BU*PrNw0wBlp;}tcwDSxaYb`~G z@Vn1=%H_OBS9Mp8TCWQ^u1KQKVWnT?$@aZ3%au&Ncp_BMrEY8l44uPl>$tQ-ti2m7Gtf1Mm| zO~#HcoG9q(^Ezms%&PNl$hjI=5FvizLW-k~% zeD%qK!&pL8-DIC%`7<@(#k8S)^O<)*T!8a_!G#Ged$oi`mlvms8JVd* zg3ck>Eml)YmodAq(v8+z>a&Jl%KGSL8|_l4gZ56Syfct#%l7uN8&Dccd>rAAE_nCB zcVOk{dkU(Cc)#{Z>-Cg^F;r46zr3IEWwvXCHYH`+wNl_i^bT$7x$97UFU4Z8^5Vj^ znakq~_>0uSLD$eL$NO2eO|W;ibE(g&f-Oo$A6T<`y*GmFc|8$C2hW;@D=qYfl&b>U z(KHY4r^-pAs-vBQQv&5VWx_zGi#lOlFxW)!p!|p`il@JwC3sT|t=gQ|GP{@eGTG|9 zwvL*}MV;2?!Of9QV^;0TrZOG?gFBU_(!g}#oKc~wT*B=l8=0>;<6dwg3=1N(+n9np z5{s0GJ=ujev`$Qg1XP?3nrIg@9g03xaZZ)UGb|QkKGZ~*Lg;%GDD9z*Da`QbiraO` zD%8T=s)dcrDb9ERoG7zf_4n*R8`@_~h4?O2J+pdt$h2Xw*e`Z4vQ{Ycd+a6Law&>a z>DJ&)U4*0#N#hVF}QihH*gXa%;aOxcdJkx+<_nb9ic=`=y%wwIL!k4>GC>zYLlv+ zL=hB&7t?ZjBPU6%-MbP0YaTqQ{6L6~Rs}*ogXdOZCd4`hzh zM|R03SsVQGkw0!j?GTsBwZHmLqMu7P1ZAZj*cal*ta!Z3Mmw47)Eyty zST4IHJ1Fa3_5VK7Y)9}F&8xjnALBmYMX`xe`)VJ=zmq=Tx<1BO$SZz?dAJ-No@{O& zd~7u>bTf@fBa?5e`9uUwvRU`t5+6NLQXW&viZS8sTU(}>^ix3JssQq>E$h}{-C(e9 zJcA?qSqOEF@RK0Xh>)KUjjQq=Tcaz&4!T{c3>v~(^rZuVmJx9~CBl$H+K4vpNHx%2 zMg&sruxQ`tI-AojEEh#E07waO`=o=0WB?$T6c$A`F&4czcMuo>Z1*^$4XFlxDa+s@ s)kT`?!U-kEP*K!FiA0OCu~b!IvkwT{OJQ44i0L3PMu?&=1h+;02kv#Q1poj5 delta 1810 zcmY*a4LH+z9RF{YhGoojd25K8OwG%k^tjwuyNnoRo0GRzJMuE4otKNhTv`ovHQX64 zsU;Q?in!*b)(gW?icv{8q(aO~xb2>&JATjadA`s0`+Ps2-{<*0zvuh8YMEh$ptz~P z&;S6yfkyTPL>bt~o}~XW@-cB-QEPz!fVLtYVKFGttf-is3|92f9dQxi!V8VZn(>I! zfx@{z9(j;8BvRp(B287x@ORAc>J4c+j4-prMF-#9$nZNxr7Ku^8e+QPl|#ppMkBxnFe-rhCk+fV8&B~UHG zuBu%x)_4|oL5#>qVeRGQFZp~|w@=5+-!bxqRlLO=B-co!9)PpG*LHuQf#!`f-}#F4 z{QTzSx(?3mJ>4t#m$0mqz!hpDboGQPyCF`hDCLausMDk6FaVg>1At8ce>Ykm%*Y93 z$-Y595c39*lef{?!^e9vaRxE>LI>*DcONtuEl%(mpev$zP#y&bvG zIOozp!R+Eu+VlQ54=1DU_TggvW0z}w@P8jWQ*rl1NZZU~KKI(U)O>LShW1;GA5C_7 zG>*=ed>W%qc(zCr<|bn5eC<8^!CU+}t77r;4`;A$sKH-sd}id!6u?s5VUSVM&US z<(iLg^TCWQmSL_;fq#t47NY*rh!cfYpm@J~Rjpk1mgqN`lq(3ae8uWw%bt`! z;1K2%7w^1+a$?n=1=}xAm@usC*5TH-LZ|@MqjFzn4G%@I_9UtqtKT%luct%k4pLLE zsqJLd2d3KQC$SCD4TeGMf`;tUh{YnTF1m%72`yB7`a8K|@c|ERMCTF@suCgDD#L&!U|HmA_9S3$Pr)uXqVJmC`;xZ}Dbcx) zctIr^jfMnn(8(YN6$YDtD~vK=7VmZ*16s9@!#BdSZSholCW7Zo64<~WAYd^tqm*?i zLx}We8Nt6a`R8@k5U?!c-?#j&h10_Q2nOAVbT>jrj${sNIyb8PPt0L_E{F;&vP;$? z8^ed;yI~rz7QIa(gBWS5W(EB&-!}g6@WSE_@QA=@1(QJe^ zMypE3BuAVFvOPn;F+qE1trABy91Sgv&`)6q~z8@WZ* zQ^$+=CpSk5R6b3T0^uby&c?=_45GYaN)U*&+(CA)gEOEH&SeR!$G9#?O_ zms!kx{DSQEI7^yN&B32d6}?U)thf^2wwEOKUD}c6vh@045GFnF*V&P6r!U$2$82u9 z_d!q=cCLA-tn4;N_Ep?+hh6{7wUztqrQXVU+#WzOj^3UmNsX8dpz(21zEB^oh diff --git a/aio/assets/templates/durable/durable_data_velocity.xlsx b/aio/assets/templates/durable/durable_data_velocity.xlsx index 9043fa32b907e64826a850a51701340953c8b413..4ef2ed0da612d5d67d59d9d15c63d98e9f84715c 100644 GIT binary patch delta 1540 zcmYjRdpOg39R6*wM#HeNqq!D|VYwe+Hn|*>iMe$o4QYnM+$$5KCsZ`uD6Eo8p);J6 zT%PJgt&KzOjT4TT>Ev=a=F+ix9KO%@`F@`F{eGVJd7t->H_za{K8)zPLjnN+02J_! z&4X3by<=y60W#zg%>Ga^UDgcv49P)qX;hrh(aGQYaa+T_jS zcj^37N-mRu=u?HE)Owk0GC6$j+7gXz&hL*r=>PXUCxys5ux>_4_L@6d`h9L7YSFYz>=_TpJb7vEaZgdRVUKN-b516%$Si3kiv(8GRcE z#8F)u7>XRkq9I>=@JXqVLYkzrzAaUmS?N7g?TLk(X=0*XmlkPV=C+vS{vIgqtG(^b z@u=asqxl^@9{X()IklekS(p8bqsAHr)ksBN7Qg%5q2~y*jos^>V&tOZ3`y+p%sI@1 zmmf`e%mqZ%4eptxzmol)PhxB;R$_=v<4H%?pL+U5`#J0togLG(LC4KIK0jW>Oi%U_ zwGF^-avGXC47oiOF4^5BUMr-9j1MkW5sn4gIM29>+kNR)Tu%?{KIM`4hhe_B{I~DD z`<9&F(ba1x_t=k`uO;P=s3%+!mi00}Pj?JuPwc{WEaiJqJcC=h?$}n}O)~ATI5&57 z>cZ$8=^Ue=-zoUwkzNkF0ru8vCi!VqplR{&eG5*v=URY`peu}G>t0iTu_>oM>9WXb zIK_?sv0~hy%DJt7LWG(@k^9;lRmrQO{syue{b%*U*qk@hWKTNAyv1Q9y>oFVi>oSV zc~uiWuigACurb_z#Jm-Sm30G{{D};edX^*aqzXgjJaHTOg!P&?>H(*~2q1E+B^Kls zU#Lv!$}F(VZo`*LK_zoQW33X{fr#Vfr*~5Xm?8<*0}TWglCwjR-WvQQi4_`AeycW7 zg;B6wwcrVBf;Z|1r^s$s{Ug)gGW!$0TymSLu5leVXc7}B@vAkArWp+Vk#L^4Sfb9W zaCpVfybxrS)&<%mi+S;|(Q7%6L*QN}aAO9V&a%@z)9HSS1Bp(ER_K*U6F~@>xqA@M z5INBlbz0+d{E-*Kc;c*GJ3NK~W(o1QJ5}nh_skwi5mGflV!CwjE3FT zQiV`FNkY@UU0#~O-nkb0TP{4IY+sPJW;s)1%YnJ#Xyo!7)yPtG3WR zkVW{=RLs!MD7l`Nt2qvpBn+gl<0>LZtj`nfFRBS1KKLyUGkWj&tEc-(x&pl|4>X?r z2X65?O$&VG(4V)U)`;_ET3>v}anGdd12U5L?FsT>l|S6(BOWP;q_3L_^$>AL#+Hw2 z0-sx)8IWasU7T delta 1814 zcmY*ac~H{_7XIasjU;F;5Ct?)6K+Ti8bKwZ!m7x9S_*+gQ@Ij>LOGTR#3DgCHpT#j za-|Ix1A+^JlBs|Zta1bi6k0BUi3;gb0wpNtCOhLUynnuV-@Na=H}8-4{bbI zpjZF^U_eJ45AlHA5vK~i@ophqso}ao0D#iq6&Bq)o^?IJp3aKDYL^@vBjR;LNr{M? zRMCg>Upz0uyLv@G+}opL9rFhx=8@iQ3_bdA`kLeAQf5qxN!^y*e7E(CXcp|8)km*9 zFhjfUVI)!+B@q_UxDt|+$4|?H6kN6-3cNYj4!T$0RmF0l@eG02l&%C+q=s-glGC z(PM_4)XoLS^TVBOS@iH63+6t^Eram~g5aFI-wVyHFRZA481y%boW1hi6~FbgVA>Je zj)~d`Bv0B)?nmvTSXyQD%1cqP;!`x^C+S;Q9bRx{WmHU_O{rneE2Wcbu@Xt> zoPri|N?@O@cHdB^E!$np_3P^5C+H^NRZp01$x4NRTkrgM{v3g#zc59sJN8D zvvB54yTlc8r%z+U9m5S8z(jJdnGX$#=g`Wz=pAG{5`TlnOHwgy7{ zd%syQ?mZ*Cmf2(Ipu0cvRiy<3SNz#ElnwH05;2f`Q}4k1v_qZ|R-p$?fZB3)ahN(? z?76N%7wNyhuYPhv_$D(vztXkgbboJq@VFu6+T(h;Lx%U=)5soF6U+eCy5CT2lmOEs zCzlXVw}i0&uaQW{RZV$%$CnN&#WxXR8ue@P{6}yKca5rYrmXaCs$0WIRhE7nl&Jt&;}f)GdI#S7 zk4M#Rs=-!qynVot2YG}`?k~R@Gj2q|r8@47KIbH=U8>J8o`|J`mUg};sraUzoK#)+cUl%t1)#Y89m{-Xr<imbF z`qPhoY>X*ixz|1Ied=SxFL{ef`TDx9YN@(TwxRlPcD#A{VcS@MqB*J+EUTDnHDR{a zSgbEau`HE7~B!ZSL}JGfyTbQAs}sPjhfM>Nc5%ureT9-m8K8P303^rQf5VE8rm9b(-QeO#{t~{$FH( e5NQ7A`WD)GA^OH(6`GGj>+|#VkvgZeYT!Sej4av! From 9088b90e3415eec7a58ad53b4404d98506089932 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 17 Jul 2024 16:29:10 +0800 Subject: [PATCH 13/36] fix OverflowError: (34, "Result too large") problem --- .../durable/durable_data_current.xlsx | Bin 5540 -> 6370 bytes .../durable/durable_data_velocity.xlsx | Bin 5540 -> 6376 bytes aio/code/durable_action/factory_test.py | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index 4ef2ed0da612d5d67d59d9d15c63d98e9f84715c..241fc607c0682d4b7e6109de70e590c6739db342 100644 GIT binary patch delta 2437 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 BX6pa| delta 1583 zcmaE1xI~*Lz?+#xgn@y9gCVSBBG0<|u#%4v45oL}UjxNXGcqs;0_l|e^O`@MLR+1(p? z)=}>ly9?!Q5x>P+!*wosf!O1$EwS>g-=fQuJ~1i05{?r6?D9p^W=DeP(sYZa@cLh| zvVvact|v^K61XHmD6P(LQ}?A8t}pGK%(;8m-dsrX7wp>8Anh%Y^JjCSpIA}PTPNPb z6Zo&5S=!50QCm|nZ~FOLc9UM28r_u8Epc$wJMmJfUT!zrKGE5y->hev6*^1d#hb#@ z>rQ%a-F^GMapb2>=YFVZn^o@<3)Ow~E4S#c+>8C3YmMJ7{M-IfYXa||U*~KQQi6d&f?;xnSrbZl4t zE(+NDq`orf-_GF3!bn$@Up0>vZDmS7yX}daH@UegL|H+O1nuX>wy_ZT+W7FWVn|3axFKb;CWS z)9>2pO*?o_S-q{=xi;Qp{=FsUr!NQpjkSGsDI?3yfBn|Zy**ni`+iy7tMj@0aOD%- zwI0WBJo_c_RwDWOaW~oIKfiA5NcM@5pIy>(@^x}>y^h&_*Wb+-zOgSnEBk8yk@eZ1 zRrl?R-<|Dz-|T>d0iO@UC9tUxJ*IBfUSpF_(00`%7tmU zD`sx4kZPHQZ0M}*3!j~P6e*C!2Q#!DWa`DXD2wjrjw@J^Ow};jayIdWPCUy-8=hjt z6b?(L#(-}N3mCP?EOgMQzTlsJnys+B zQ0N+O(=Rrswh7829I5=jUgo@3cvt3k=$>Q1M~4#vMJ@GA3*R`}&s{5jjZlqOS_n53pL4!*cK*L&C8mCt2QxWrL>iYXeTaBszl&>Y zY-^Rea$@+x6|0flQ6~B-@1MyVEs;`DBzLTHx_fqhTWss1b#QmoS=|m@vHNG_h{F-T&O5{At3xRgTNPrKMFE8^`uhlc6 scenario_time + 1: _df = pd.DataFrame(_d2d_trq) for i in range(6): - _ = sqrt(_df[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/1000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) + _ = sqrt(100*_df[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) del data[0][f"axis{i + 1}"][0] data[0][f"axis{i + 1}"].append(_) _df = pd.DataFrame(data[0]) @@ -248,7 +248,7 @@ def get_durable_data(path, config_file, data, scenario_time, hr, w2t): _df = pd.DataFrame(_d2d_vel) for i in range(6): - _ = sqrt(_df[f'hw_joint_vel_feedback_{i}'].apply(lambda x: (rcs[i]*x/1000)**2).sum()/len(_df[f'hw_joint_vel_feedback_{i}'])) + _ = sqrt(100*_df[f'hw_joint_vel_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'hw_joint_vel_feedback_{i}'])) del data[1][f"axis{i + 1}"][0] data[1][f"axis{i + 1}"].append(_) _df = pd.DataFrame(data[1]) From 5ab03d23f2e90249b0b853a86456c68d9cd2ffe3 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 17 Jul 2024 17:31:32 +0800 Subject: [PATCH 14/36] =?UTF-8?q?aio.py=20=E5=B0=86canvas=E8=AE=BE?= =?UTF-8?q?=E5=AE=9A=E5=88=B0tabview=E4=B8=8B=EF=BC=8C=E5=B9=B6=E5=B0=86?= =?UTF-8?q?=E9=AB=98=E5=BA=A6=E5=87=8F=E5=B0=8F=E5=88=B0600=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=E6=9B=B2=E7=BA=BF=E9=80=89=E6=8B=A9=E7=9A=84OP?= =?UTF-8?q?=E8=AE=BE=E5=AE=9A=E4=B8=BA=E4=B8=8D=E5=8F=AF=E4=BC=B8=E7=BC=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../durable/durable_data_current.xlsx | Bin 6370 -> 5541 bytes .../durable/durable_data_velocity.xlsx | Bin 6376 -> 5541 bytes aio/code/aio.py | 11 +++-------- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index 241fc607c0682d4b7e6109de70e590c6739db342..ece47de0ed7829c21f569e943e6b38d14f2ffe6b 100644 GIT binary patch delta 1574 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 diff --git a/aio/assets/templates/durable/durable_data_velocity.xlsx b/aio/assets/templates/durable/durable_data_velocity.xlsx index 0b47ea48e4f794aae574f8d99ce54ea8aa5308d5..ece47de0ed7829c21f569e943e6b38d14f2ffe6b 100644 GIT binary patch delta 1565 zcmZXUdpOg39LIl~SyPL}YD;5;sCL*vl4G=qoKhxRM&UT*m`}_IhJ@Ng$y-4a&85kM> z00fZ2y@o87OX1Eirson>#n+zfX7?ZSI^?Kl^Ft)3NfTAsGE)(sb4Bq^ps%e{g*>cM zWpw4^*;95CniW}DVN)$EOSkU+8aYLg6D~Cqh6vUyuuzWM6}!}ZN;vaQ;f-PVgbewb zXV6b^Jh-DD#z*;gI#8pJAk)&d@-?0U$#g z0F+i&5?nR`A;1--8>vEC?0Y5y0MD@ifCa#Cj57O5U%$_5A`U+7Kn{t3r?X_O_nLWO z!22iri|vW1ed+|iqYLw_4kI(dV(%-2`HF>E%9!uq?1|*|S9ZHe!GbdT^7uq2p6_VY zYgKv{ZU0lp%mgu4-}YfOLBTITmtJ}yc9xLyWZ19`oI@Ag5?)&PGt{wef`a>MIL9=zEh&$yPbd#bl$Z>L+lYqq$G$7FZtfkIVBcfidz!6O+&@Wr ztK4l)^kvk69zESI8R%x~ZeRVE)bm0b9!)llPFd%1hO{?UOw~aWWnDT2-wv_rZ*2$Rr zmYgTMj;f>oQ0O*6aE1M5ie#yKAP!I>sq?q-ZTXf>qS(uBCQ%)bHIdgAh#a|*@W2yA zGeGHcaQuThmtNSO6~O(1{1m%4M@it6*dz@!!c#%=&TC5TL*VhpgJkN=!4}j-4jalB zlg%@W@J*tg9~lP`Of|%IN+MM)nKY4GM&eZMFqKP3km)dWinR&S}P& zdCkUh=a^7!4L1jVUcovafmQmVbzsCrdZj+lzV>0!0IBVGRyraM0KC;0k8D^kro%4*Em^G{&l^NwEe~qcugV im?a1RD1U=h+XAxDIQjp;c&pcC6~TI}7TivneZXImFt5-6 delta 2430 zcmZWrdpOhm8~&nD<}fzLWg=!;a>yt{SaVhjnYSE5w2@Oe7E83`&@e^GXkp}7qFxn^ zR8%x15p&4-TwZ38cYfFJy?(vd@AJ=d-Pd*B&*ysX=a1(u+B>NWI%X%d4FUjwC_qZc z09EcFB`gtm^aHr*jAkUcYj-jOB`1YQPtVylBC9?q%Pz!wchAoe-}S@~z1IC@My`Vr z89MGw%kITV!r*J>d=1o#5`ICJU-R=(Li`+4!w?G>ro=+74u>mO9I)QDv^ z&3jNI-oA(;gA~2E!U$P{P%q=nVTGvH;U;N~{LR1|+Ev)2lO^Pag?Di#=SOic4>+7Y zF(xLbH|3R%B&O-?FbKDCkZT$JXv;m3#r)#A{c&07l>(nv;>L*mGyTuzOq{}9JfSX5 zi+(2ulIp<*RF~ASFY{I@A&_wG_9*SD<#a(-a~q{W$i- zZ0$a5XMLxJ<7R{97j~Fr(df%0^^TC$_o!C=EZO}VzxszuXDDU){U7E-OfD)?Ca6Ew zhUZKBD<$B(i6D`0_c+0>LWA@0iE9(FPwLGi`hv!7MGZNXJ(>ksTK zI@Z=0?3$Mr>7e%GbE7r~CVn`U?CE-KzK*kA(*UPe`k#&n=a`f?1XDUT-YpE|Y8u}n zR8T&JJzVgtT(Ox83(fX`EyOuX@?x@|^YmupD?=MkA3VI`ZCY?+IWBG$Jxzhv^8Pe^ ztKS^Nffu)f$_C-Z9iTD}+^-!JFbMbS00nU1FN~>8m!)u1H=f#T%8XW$bDQ^d5xWzLL9HzyiE^Xr@s|{#elhZp^ME|scd$i0O)2x85{wY) z^&wtdq)zT-X}xav+vj<9cZ~PQVSeu)?z5gA?U{Yxvi-3obJ4vF*Fm@7#1tG(E9d*o zWpkr_7Z#fobR5Ka=FuxQ?@c_5tj{bnXE z@vQTAj=bGm;idPE_OW1xkAh;R$Bo4r^i3Uh&5Fx53jS47V&#?HG?FHtNbcjKp_6Y@ z(cZ$t8iza<&%eK|CmFKLGn85Wbo9&>R?+t4%-47`BwYRC==0P*pO(EOM3K)zmXub7 zxP)DKb}PD9N97w5uz}m&QJF;Vii=ruy1NXf?P`MQtFK zzc?qEmTh6SN0k@4J7yD_FwnA*`xY+T+pl)+hxXjM|6;Xn$R~!B@@2HMXDDUNV^LS% ziAjrc*6IFZ+MgBK!$7DC-m@8z=KrFu@MRGPMW`WBk1!{yEQLZ2w8>qX%@MYenx!O} za;ZEwdg}4^t`HG_`jD8}I~xAgviWldccae9uUUV2O%;D&73$xNY*|N9af)3c1G~hm z)X-%2#q$`&(siAJNwziAO0C@E@y*L1X2$KEW*x9JsXR+8l|2PmZtyh(kDN{X9nItw zm+W;PENzP z^nj4InrRd!e`6*)y(*aUYmGbC`#DZtoj12M=Jcd~VdXloesAGgSMIX<X$&&(G5CtCHf?#R;|3FU}%>RN1txyKN#rY}&6KJKa$*98r z{{r*x^M7Am{7%{-2ts9xv${gv!4w35b7BA>{ttm)FALa7(&8aXTV3f8nBXpH+H;74 z`<7%ST;PF@001EQGRc2Qg!v(Wp8+C+!veg6g9Egq&IKN`6A**||D>fQg8s~CeFb0i olixt`Ut%8!4FiVJ9HF4CKTknng4R&lZfPiu3Y8MhlHKC|4NRk8SO5S3 diff --git a/aio/code/aio.py b/aio/code/aio.py index a53b21c..8c6d8e9 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -185,7 +185,7 @@ class App(customtkinter.CTk): widgits_da[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Durable Action'), width=670, placeholder_text=widgits_da[widgit]['text'], font=self.my_font) widgits_da[widgit]['entry'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=10, sticky='we') elif widgit in ['curvesel']: - widgits_da[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Durable Action'), button_color='#708090', fg_color='#778899', values=["device_servo_trq_feedback", "hw_joint_vel_feedback"], font=self.my_font) + widgits_da[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Durable Action'), dynamic_resizing=False, button_color='#708090', fg_color='#778899', values=["device_servo_trq_feedback", "hw_joint_vel_feedback"], font=self.my_font) widgits_da[widgit]['optionmenu'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col'], padx=5, pady=10, sticky='we') widgits_da[widgit]['optionmenu'].set(widgits_da[widgit]['text']) # For durable_action tab END ===================================================================== @@ -207,9 +207,9 @@ class App(customtkinter.CTk): # functions below ↓ ---------------------------------------------------------------------------------------- def create_canvas(self, figure): - self.canvas = FigureCanvasTkAgg(figure, self) + self.canvas = FigureCanvasTkAgg(figure, self.tabview.tab('Durable Action')) self.canvas.draw() - self.canvas.get_tk_widget().configure(height=640) + self.canvas.get_tk_widget().configure(height=600) self.canvas.get_tk_widget().grid(row=3, column=1, rowspan=3, columnspan=13, padx=20, pady=10, sticky="nsew") def create_plot(self): @@ -309,7 +309,6 @@ class App(customtkinter.CTk): def tabview_click(self): self.initialization() - tab_name = self.tabview.get() if tab_name == 'Data Process': self.flg = 0 @@ -323,10 +322,6 @@ class App(customtkinter.CTk): def initialization(self): tab_name = self.tabview.get() - try: - self.canvas.get_tk_widget().grid_forget() - except: - pass self.textbox.delete(index1='1.0', index2='end') if tab_name == 'Data Process': for widgit in widgits_dp: From dd0873637fd1c48ce210ab58c830b89d7d3c2e40 Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 18 Jul 2024 11:04:31 +0800 Subject: [PATCH 15/36] minor fix --- aio/README.md | 7 ++ aio/assets/configs.xlsx | Bin 224778 -> 225074 bytes .../durable/durable_data_current.xlsx | Bin 5541 -> 7127 bytes .../durable/durable_data_velocity.xlsx | Bin 5541 -> 7143 bytes aio/code/durable_action/factory_test.py | 61 +++++++++--------- 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/aio/README.md b/aio/README.md index 1b75caf..1398488 100644 --- a/aio/README.md +++ b/aio/README.md @@ -8,6 +8,7 @@ 4. wavelogger 波形处理,几乎不花费时间 5. 制动自动化测试 6. 电机电流自动化测试 +7. 耐久工程曲线指标采集(仅适用于六轴) --- @@ -154,6 +155,12 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A 基本同第五点 +#### 7) 耐久工程曲线指标采集 + +可实现固定周期指定曲线指标的采集,用于长时间观察指标的变化情况,输入文件: +- configs.xlsx,执行之前需要手动修改好configs.xlsx中的参数,以及间隔时间 +- target.zip,需要确认工程点位和动作无问题后,保存导出 + #### 其他 customtkinter的tabview组件不支持修改字体大小,可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现: a. 运行 `pip show customtkinter`,获取到库的路径 diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index e59ffbb9cb652c1aa13e9dbb8c630b831bc4d68c..158cdf5ec5b2084be44eac15bed6e88ac7a8d790 100644 GIT binary patch delta 7067 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 delta 1588 zcmZWpeKga19R7`2Q^P`GBU8kU%MPMsw8_hjGO@gLab5JXjF|Us=4ICL67tgvLQ~%I z)+O&RsTA2Ag*IXot}B*<9F8g7O)1^`{pUI7InU?$KIe1J=iwR`XiE`o#i8;50KkEp zN%L2w%4tGynOjWR#TSw+2movsqECP~F(}{yRnI#h$X7R<;#Y9>(eWo(1jEy}t0iRU znBNgsJ-b6O^mcV*UFUplV&N6pJD~ygZne_TI+gLyAI_X|m{PCJ&Al|!NwxIi3^hv1 z^4yd&bD;2W^->E|!d}KI=M;PXoy;3UTGW&{{;F@-ZwWOo%e;_#{q+;8d*9p*&THKz z0gEA5^>U;a z)pzCy+#aRooAj*dre!{rOt(+rjHNess~R zq#UcM^v8NY3u4VbpNxY1u%l`�(}Y+EP8jV*fL70C=tl0Ez%eL7`|@28aA#W0hfZ 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 diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 0833162..026baaf 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -3,12 +3,13 @@ from os.path import exists, dirname from os import scandir from paramiko import SSHClient, AutoAddPolicy from json import loads -from time import sleep, time +from time import sleep, time, strftime, localtime import pandas as pd from openpyxl import load_workbook from math import sqrt tab_name = 'Durable Action' +count = 0 durable_data_current_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current.xlsx' durable_data_velocity_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_velocity.xlsx' display_pdo_params = [ @@ -170,26 +171,32 @@ def run_rl(path, config_file, hr, md, w2t): # 6. 关闭诊断曲线,停止程序运行,下电并且换成手动模式 _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) - _response = execution('rl_task.stop', hr, w2t, tasks=['current']) sleep(1) # 保证所有数据均已返回 # 7. 保留数据并处理输出 - get_durable_data(path, config_file, data_all, scenario_time, hr, w2t) + _wb = load_workbook(config_file, read_only=True) + _ws = _wb['Target'] + wait_time = float(_ws.cell(row=2, column=10).value) + rcs = [] + for i in range(6): + rcs.append(float(_ws.cell(row=6, column=i + 2).value)) + + get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, w2t) # 8. 继续运行 - _response = execution('rl_task.run', hr, w2t, tasks=['current']) while True: # 每3分钟,更新一次数据,打开曲线,获取周期内电流,关闭曲线 - sleep(180) + sleep(wait_time) _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) - sleep(scenario_time + 10) + sleep(scenario_time+5) _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) + sleep(2) # 7. 保留数据并处理输出 - get_durable_data(path, config_file, data_all, scenario_time, hr, w2t) + get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, w2t) -def get_durable_data(path, config_file, data, scenario_time, hr, w2t): +def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): _data_list = [] for _msg in hr.c_msg: if 'diagnosis.result' in _msg: @@ -207,12 +214,6 @@ def get_durable_data(path, config_file, data, scenario_time, hr, w2t): # for _ in _data_list: # f_obj.write(f"{_}\n") - _wb = load_workbook(config_file, read_only=True) - _ws = _wb['Target'] - rcs = [] - for i in range(6): - rcs.append(float(_ws.cell(row=6, column=i + 2).value)) - _d2d_trq = { 'device_servo_trq_feedback_0': [], 'device_servo_trq_feedback_1': [], 'device_servo_trq_feedback_2': [], 'device_servo_trq_feedback_3': [], 'device_servo_trq_feedback_4': [], 'device_servo_trq_feedback_5': [], @@ -231,35 +232,35 @@ def get_durable_data(path, config_file, data, scenario_time, hr, w2t): _d2d_vel[f'hw_joint_vel_feedback_{i}'].extend(item['value']) if len(_d2d_trq['device_servo_trq_feedback_0']) / 1000 > scenario_time + 1: - _df = pd.DataFrame(_d2d_trq) + # ========= for trq ========= + _df_1 = pd.DataFrame(_d2d_trq) for i in range(6): - _ = sqrt(100*_df[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) + _ = sqrt(100*_df_1[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) del data[0][f"axis{i + 1}"][0] data[0][f"axis{i + 1}"].append(_) - _df = pd.DataFrame(data[0]) - while True: - if not hr.durable_lock: - hr.durable_lock = 1 - _df.to_excel(durable_data_current_xlsx, index=False) - hr.durable_lock = 0 - break - else: - sleep(1) - - _df = pd.DataFrame(_d2d_vel) + _df_1 = pd.DataFrame(data[0]) + # ========= for vel ========= + _df_2 = pd.DataFrame(_d2d_vel) for i in range(6): - _ = sqrt(100*_df[f'hw_joint_vel_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'hw_joint_vel_feedback_{i}'])) + _ = sqrt(100*_df_2[f'hw_joint_vel_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'hw_joint_vel_feedback_{i}'])) del data[1][f"axis{i + 1}"][0] data[1][f"axis{i + 1}"].append(_) - _df = pd.DataFrame(data[1]) + _df_2 = pd.DataFrame(data[1]) + while True: if not hr.durable_lock: hr.durable_lock = 1 - _df.to_excel(durable_data_velocity_xlsx, index=False) + _df_1.to_excel(durable_data_current_xlsx, index=False) + _df_2.to_excel(durable_data_velocity_xlsx, index=False) hr.durable_lock = 0 break else: sleep(1) + global count + count += 1 + this_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time())) + next_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()+wait_time+10+scenario_time)).split()[-1] + w2t(f"[{this_time}] 当前次数:{count:09d} | 预计下次数据更新时间:{next_time}", 0, 0, '#008B8B', tab_name) break else: with open(f'{path}\\device_servo_trq_feedback_0.txt', 'w', encoding='utf-8') as f_obj: From 1cefe4a16b7ae84bcbb89acdb0ed8e309bf5504e Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 18 Jul 2024 14:59:20 +0800 Subject: [PATCH 16/36] minor modifications --- .../durable/durable_data_current.xlsx | Bin 7127 -> 6104 bytes .../durable/durable_data_current_max.xlsx | Bin 0 -> 5758 bytes .../durable/durable_data_velocity.xlsx | Bin 7143 -> 0 bytes aio/code/aio.py | 32 +++++------ aio/code/durable_action/factory_test.py | 53 +++++++----------- 5 files changed, 37 insertions(+), 48 deletions(-) create mode 100644 aio/assets/templates/durable/durable_data_current_max.xlsx delete mode 100644 aio/assets/templates/durable/durable_data_velocity.xlsx diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index edca686fd0e0e62f631a8ed74aff76024334d398..0cb184a948742e0cb38ceebcc63d3187925432fb 100644 GIT binary patch delta 2120 zcmY+Fdpy(oAIHDjT(eCJnN374F+-FHsVw&+mtV7(`=zLvTc=5x3M-dnlTe7WQ)JCu zGU{kpC8r%GPQ>D<jnV;VxxwULp|ciG4Up$3^l!zL?5W;pt5~jsRjaM-6Sr>trfV#;PMP7AZIH<5 zD=3o%-V?UavGzdEH{%;8ph`NLwxkZLME{X@WX)8=x{#Y;kDLRd>l<4QCLUbS^w)U$ z)#S(kic{}{d<{O{UP|>2{CPw5Z$Nf3+ax>slJoreS7`tcp#cC1Fi0pAHLY+eddPBX zT43iKM4&!$!cwN`P53eod^Gdj`a?aJ5J6L29X(+*nHC+D8ye{)RWU(!no@_ofF!NI zT^c=>L$WqXRu}X7dKO}lB?sB~`$If2|IWdLV>5^s7Y8(pKqjlS{>e)6ZO-CdZnAD# zO_hDUwekL`#iY{Jo|Yu4hL{t&`Z(}Ti6ZUZ_b=X@F9GEInzf~_Tkp8zG0CBgC+zkq z&J6szG9@o7ocL_^`rRyF;}~bQ`P0zq?FsT+ZNAv%AL7C?`=YIGwW?>&BlfC>$+u?C zi42PO%#*eqW9qPP%e~P<>j&M_9xZ$sVs+1Zk3SbJRZmvcgDBKdYLPc*M*MwxHl26- z_dw&>x2qo#?Ji6PP|2gX!ujo)5vMGso+SB;JZB;Pt+O<`&+$I>50p8!a9^V> zATI-|Wm2}*9MD&LI%a_!Eqsk`EREC_OLEc3rdjqHoI4D(5g|*h{a&c zh3&UwwM`UpB`2@`LS3sntQ6=qro6ssM5`V1TE$`{o1?SpbBpf}_fO~<5^-tFK_$;ih|ZeJ!Ma?-^!`30CFu}1xVC{J4lh$_4BxJ9WJQRr zDY^8xS!es<^H7BcaLcn$BTGVD%~+5vB>rq@SBg;>KMzEFB@AkBr(aQ#ol+~PLUU!9 z_bvI&AR={S6Ze*7@~rs7AmZF6JTA-pcz_RpiQxA?yTr>eWo`I6V50IS43TH*+wz^j zM7>RzA)rSjkgW@dtG#+5o5;B>LTLEd@d zWB*IPNl>0edyx>kw5vMbAxMpIG7sS!73C2?O6_}ld7tkAY9 zRG28Bg%z2m$dqR}D6}V$8bGA1yN+}D|C3e81Qj0!`QG?|acW$kdIlY;E*5urC^|O^ zK&9D`%7-wQ+{YNNYzx2auH6aNLK@#h`uT7d#sCr}t)F$LHpb20EPD_A9y_Z%O@oxX za>0X*5aeMiyL?6V~xI-UU_*g&sgreQ_eA)_qYQ!tlKJ)iWAiz8YP;f!z$ zf%lElDjX6vP`At|yrhu&vuH1t9U}>JpV6Jpz3GGF7Gf)QJi3FItV--w4tju-;6fpm2o9U=`;*lGfjIb%_hhAoI^B%?%-G9}5VhU_m9|2L zeZ~UZv4Suy8U?LIS&J7{7&B z&cGbBZV%mW?$*P4)6k9&Or`;8B|Q_4)`5@Xxc ze8;p_QfSxO%@zE*yc8Fsc90>ouLZ5*mZqyWzw-O^-Rh^N7hDye+Z;V+g NGgxR{nN$@?-+x+s#;5=Q delta 3159 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 literal 0 HcmV?d00001 diff --git a/aio/assets/templates/durable/durable_data_velocity.xlsx b/aio/assets/templates/durable/durable_data_velocity.xlsx deleted file mode 100644 index 7e042996787a490eecc6fa7b986e5cfacea50e7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7143 zcmZ{J1yCGov-aX1+&y?$+&#EM2pZhof=iGPT*59+u;3&>7Iz8m?hsrzK=2LDCFj)l zpYQPBJ5w`LQ#DUdzgPJOM2=HsXPOjogUT8QQsK+1)FaA3i3V#Q$iJ<(TrQlgIeKT ziWa^N7HDaGSX!n>sy!F;Wvav3$FR8;>N=MzGo<#!You5I(ieuf!?gdX=MWqKfcxM2 zTDZ7b{ZY6Otg772i4*=XnBXsB$J!L?%pT2z)PdAvpkVDCGlDXp(EPAc^UI5{6|K>7 z#U?u)q=S+h&|SQTAor8ATyCkE-ebN3K?4V%NIm{l%er&hbvIu-3Gx3>l6UDH^Xunqtg#Wi?(hW1|aF79jOeO#T|Iso& zjvOAgR!&xb-?{$S=1||jeNm7g@CY*QV*_)-=;eQ3SA*|v=e1Om9(t%o9fqqH=jdw* z4h?FT=f@dJ!8%M(ZORZu1VV2{W#xDG1bxqbv77IOM<$*6m@aTE%{JF_tgPvB)8k5V zk`_abzoQqb7}x6C0lEYO2JrE^euTuJD*F%&%^I#5ka5t>{;XMA)(N$9%q5YxGz~BY z+P)mu($IG?p{d!X=D8#s(u%Xnhr`#EWNeJAIlXf1xm{clw;F>AQ*ys|<|Nmn2^w`N z-cr+#T-WOC{%&t0q2tguF{uz7G7yl2)T9W@pCUx%#u5?E(i`=92kSn}i5*<@;B_Kf z+dT0RtQ(q)aiu_9(`e4_%sO{$FOWp5$+sJ~oQExb0~dXb(^Q}O9k9BeVVj8_XP`di z;JrNcF{-zG+y|@eL_MPGTU2l9xW~R7Bh%eChXN>(t(4s6z8@Z8?e@zl8i1aw*X-~l zLW(iVwPzC90%h~Eq~WpNFQF*h``#YJS-VNn6ka*EED+K&fI#J;gghw5cg6vA+iVvGJ#u9Jc_qKA16X#T= zMqOKgXeT#x24)dV&La43!W1@A@5W#-a3KTt*wGdGzM7~FwN6Tf(b(8lcB~s+^D;~? z0H!YQOgH!Cd-e0VBsqH7oPM^ZEnLA`MJ#T73Dm6cH2YT+@C9gGDY@a7HN9oHYxn{6 zZK(aLago1ET|SBF=ISXfhF;>xk!@tU@3>Dm-k=o9O~ABUe&na>5yGXCtnz;41NO}N zB!53C&lIJ^#~Vq)K$Z+orDw$ZA{3~qfPc?gxOksA_3}80gZ^3x9B)@mSM0$!vd2T# zAqOG%jIf;)^}9#9%H%_*0FzU~+mKhw(T3VJA5%f-KYl9j#ATHdHz(yMbE_qKU-$M) zsHr|)?}U%qWDV}^n=-ycant^T5wPdzEch92g0aBkx1%v2+;*yPL8VWJd2jU)@3M`% z6g&1phOF-z0>fu`9DyHy%TE(4ZDBJOOF+4KQSv{%L2C`wvCsJ$!7E-u#f^@1(nuw~ z?dO9okkZ@o>RX6E+{478KxgS?$akS2_JFa%qsDWw+{tobLyBw&K|*ht~`Ap^#5+*yxBr%I~Ws=^Jii29IBKqwQH5 zFrW=-O<4&<<7G>cJ3}=ul#=JRA&txpq6S+~NUn!CaO_IdWVdDngGajFP5EbCQd=#f zpwfBeu&Wx?5T=NYXaZ%O_h(AJ8<>&T7F{8yW~y`pnN%BsQ&ZLtVZrP)a3lKEYmiIV z6|~2PY(r=Pu`wV`*J*ctV&Z1EL!%=9NHm4AFY+{x_E&Cr+E|x#gs;CznoV-=D_#O8 z$1-}LT)k<-+zF6i&C-3rR+Syvlw;Zkrxk7XVl{+nWA|^$`*SdH)rc_g6fBa6i0qL>hMxYS~hq3-l}Of;CaKHNysfXp#`h-DE)aN0FS>nUa<3*l(FxKNNR@I$zo@gxHtL39Ns5-qXY z=Fw52y?5-~HSoPts1~>74Dq0JREHRkoAkUE!`Zh*MvSnf4Xu%8vNlFj$48Mj>*|G<{S*k1URUy|U;S~hq9ekj4L10HfbaXIosd-xy zME!~(Q>4cKgfhxI>I7tqSc7w3lXwF2@}kP}-bF4< z-(bBn%v@{1)d<;7WIQu5WkPZ2E|N1Zw007C~3B=pQ&B5K)%F4r?84Zjd2CDLly34g4b2NbQ>$T7n)U8d503?%^395I^RZtc+14%_z`s?0ih9y5YWQ z`3`n!SG{0zdvbnxdkQ<93VgVVC@oF(&f!-Y%b^fz_4_f>+` z2e6x=$>FNzBaR`SA)Qqd9qW|kprAKmMqWL}EzSz>mO(xZA&e)fB+r2f`Hv|zTf)tz(xhz*J|sm z#LE3&E~cBe((K8KkNr`0b^KqH7Z9O6_*~!iYeS{d4&ZvV$(i(fKw9DthYnZD%csOjqS(E$;c>M5LvXp zZcR!b_-6OsDp_Qg2|%m*Kg!i5`5!hWat|C=)wnW4LQS|yMct}-^#up?cm^;6BW0?K zy`LF7FqQU#5CxXM>#~z9tM?@67wX~4HN5*ETUs|4`Z-GH4uUY8*Y?QLM8+pP!dfw2a(R4n4+JarR zYCHuq?wPSU2UjdTl3erfl%9!QS>grbsqBR;R!p3Sqs4e1W*m{)di^}>?{wREMk8l7 z{l)%tenh@xF>YDE-L>-`9R$J`8oit~WrjdR3FiG*7$feMbHn$E$SXQ0J{CG+<+RjRcvSo`5xXfRBY<%9t?jZ4^h@EJ8k_5SOH_6ugN4eQV z-ayaiGuv*EoBM$6x>SdTM?|g+Pc6gYny@MTw5J>~rdAE_Mv2th`Kyg_VH4(O zJCuh3+z4t46p#6Lz)zDXX8lDIGf%RNi&ib|M4rVkfd&D8V2yL(qmr7os*SjAMweXl z!afYhcEVP+AFa8+83JkP;FE~L6Xw6|jmwI}#2U*eIooARqsgODGwO0Ko4-BXslSq< zp|z>2wZy-k?C@;krZ^ix@rhKzeD#>=N}0n@{$v`(_t&-QG# zy2th8=|(3j42H4wNga{pcVi2q&KZ8ad^qzEPMsV-aD?**^}jCd6{DIYw+HeD<|X5@ zQpbbRnV&79HftvoPTi2rB%G^+2Y!JXR#L~ssW7zaInb>vnPMvP+v^_D>xP6HSZXJ;v zq;o|N>E~NY#zt|Ldzn#L9Uz#odEyb)U4U~fG;$TYpOQZT{?c8)PyrHxXl_Q<>=Kk4 z8VU;z2$ASltddzTCJ1eMe#$mo^BEWs1*WeY(2(pskHj!~!=l1I?U3 z>s3cuLYDOJI{h%eqmv&l2PAJNqTY^14^7dZ0ulC3qWeDM%zmEBRR^g8CzKGb*SV5e~<*q{Ce82QDWrUPGG?w(eusrIn zyT#t#2TObSGHJcYdMTEClv+v{ffGNFGMh`rnm_57WG~hkdhTpXllI|$jnIjEb!4q; zTyrl)qqHNsB{@Dqh~NU0XlWh%Mi+V#cF5qA7OiC|q`&Hqn9PdqQ&-LH)BJPT8Gi?BHLbRQYL5R1e6GA%#;B(p!qkf}DmS zB3@@cUo#1QE{<4;dQaoVXEUoAy{yS*7FH*av!X)(Ds(LmryQYc0O6XDY!@pOf9 zQBA%qx2R2+>Z+Yj$N%}lm948vXfqPDQCUhZYpXW`JrRzweeU-&E@M&&|$3=scdIm3{dP(M;I>Wem|Pc#1@WNUf5c3uje@UHi;= z9D9}gqn)Z=5yd7-U7AdOO!bq%9G(%T^SP-a_~B*YOCwALRygG5M2?i3(b@H0J@HSyoD)j60EGVWQapH)+iMbaqi z^XstszLU(PXrL}W{FyYG&k?Q3YMNupmKTI06X&f|85^DMdFb9toNF=vqX3&HF(7>X z_&O=GS0|cXA&_E(gsz6EiIcuJVTO#A8v9T)Ah0tK$(!Ew=)?~(zRKxbFe@p1taKn% z@_dQ?!SG02T(sR#)LGm${kW)7qFJI{>~uHg4tBQgfYt8&`{rBU+zJ%36#eRc%7s`}7mV!f>`Lh(S9IV#uGEz{1WnD`%D|b(*nt+4YSO4vB zOB=bvujh}+e58rb?={=h=ipYAldbfD7t7o%_N<-OMWLd|casiYa%35Tk>R?~&eHJI z3NzeP68oCMQ2tqm>NUo9b70q~%RYceXwuxtd-LjF>Fz&%`s*Pk%(eCA-Fh6*wzXRI z^_*JxbsS^6YLYLx`foFr@H-3`L}0SQvWPRGCmQ6tu~J`f9bI@az?rtX9;^K?JSln2 zt2|3(yXu?vwsiu$@R1bE`U>B5J4r0LQ(^RPjx*+-nUJq~01p&HxAIAbyOD$&c!^_8 z=8f(%mW@Tpe_Msd)|fny#cg7z)NicKMR=hHbGOqBf5^UQ6%9-=hY(^fv@dO1kEpd2 z@aVJz3uF#ZG7H8Y@YJgvyh2b#M-r~7RN95Vax`=F5oWSw|uV!UO}$Gk6eGEjBo_K zMIg7lUC{)wG&Dw`5qQ?Z+<)p^?-EhT;GjovNsF0)`#j=2Y~{Z0lm~&6hd(F{t7@p) zLb^zlC(m+_Cs{tSgw|~^fdnu~?ABid!Vi*-M)ycNV89*Jd5JyO6KwAglO&Jhq z<)XJl1%e}($A%If73%DF$LmB8K>(YX($FXEuFLwJi4UnAH9B5@XuZPvH>2z2_oKf* zGMVU+)sLhGn7COvx^uAqxo0IPJHvBfzJ%aenW%i}hUY4quaJ(!Xo%X)Pwxg>bf3fG z=D*X};wnF6XR|@Dc|UtmxGxnt_HuR`F6i);1F9TYOtatS>Am1ne#w^03mU(e#{uq~ zG4!)_InUOsxZf(Cql5RG+-t17(Frc#F28ksqEnLAUw9kLqx>-PV+?)zQx>G`;I^3W zxM=w7f(Dc)FY5|C2N$TscqKu^vzOZn&I&EeYkXGs9?r%~2*j@1vp5T*Cg)_)7+or^ zo;FoI;l6S{HdI+27mEG2>;BpKnY*|+{Bhnm(1cnSC#Gyr;ULPmbBLnKzHwTxA}Wrw z|CqjaZAy3YrgH^^Ns&cmBaEqUZg!y6I5QGkBu^S<7I)^(uFX0*a`r=)P45s=f3bM;$`Ogjp#h-M`sJHAH8$e>YTeP( zp^u1PFEzFDt7HYQR>S74<k?zjDpc*Jp8;cN?%a4In9*&V?^xFC!$547tL6FH>3Cc}U&?P@rt$d^48P{@c=qgE!h=L}N|_@648Q z(5ml%3Q!SnZ%DecWHEXs|tdpj|A2@`;xR#tWWc zbG|F1E|Iomd9iJ#lt0jsY>Z{C04R>elP5|`z=Fhy#?a1u#K3GuQUO5 z*vpyVM7?m-Y&uT`HN1zStjO23ZYUdpjqh+?_`s_pU65V*)xOvN#bz}|>5`AuHi)k` zTwTmnX`|g3J3+<}wYjl&fvt2R%iQSJ-_a{$=qi;RRUJut&bqF3=@*<78}7)8->T4O zmsbrBwS^lRBC~12^mHQF`waW2tQ3n@(2E?L$tFM1L&$pqGP_+FaW(}tDr`+Vq2n&p zA_nbdIYLWg`lUeqhC*ARmWK;Wp(}5(u5|>}FX;-rjuCq*hN;iIbC~W7$b7ML?~eRu zA%%&(>R6HMVi1YPJ`5Z@0pR~0$~>~>uOs-;!vFt><|+E=h~#f901ymU@!#nG3{0NF zpUx5ffe$|Z{(qS&JQeV?kMth_b?-4y{}S-Oc9ot=d0I~VM@lf965d}@{wXe=LZ8O% zf1nhE|BB*Ifv_iW@E;%&(f`x@KT+{1_^F@&12!lA3;ch0{ZlzlUFjb=@{e7)|HZLh WDI-0OeE scenario_time + 1: - # ========= for trq ========= - _df_1 = pd.DataFrame(_d2d_trq) + if len(_d2d_trq[0]) / 1000 > scenario_time + 1: + _df = DataFrame(_d2d_trq) for i in range(6): - _ = sqrt(100*_df_1[f'device_servo_trq_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'device_servo_trq_feedback_{i}'])) + _ = sqrt(100*_df[i].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[i])) del data[0][f"axis{i + 1}"][0] data[0][f"axis{i + 1}"].append(_) - _df_1 = pd.DataFrame(data[0]) - # ========= for vel ========= - _df_2 = pd.DataFrame(_d2d_vel) - for i in range(6): - _ = sqrt(100*_df_2[f'hw_joint_vel_feedback_{i}'].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[f'hw_joint_vel_feedback_{i}'])) + _ = rcs[i] * _df[i].abs().max() / 1000 del data[1][f"axis{i + 1}"][0] data[1][f"axis{i + 1}"].append(_) - _df_2 = pd.DataFrame(data[1]) + _df_1 = DataFrame(data[0]) + _df_2 = DataFrame(data[1]) while True: if not hr.durable_lock: hr.durable_lock = 1 _df_1.to_excel(durable_data_current_xlsx, index=False) - _df_2.to_excel(durable_data_velocity_xlsx, index=False) + _df_2.to_excel(durable_data_current_max_xlsx, index=False) hr.durable_lock = 0 break else: From e1866758b717991ae2f63bb320b705e8f785eab1 Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 18 Jul 2024 16:50:50 +0800 Subject: [PATCH 17/36] change x-axis content --- .../durable/durable_data_current.xlsx | Bin 6104 -> 5623 bytes .../durable/durable_data_current_max.xlsx | Bin 5758 -> 5578 bytes aio/code/durable_action/factory_test.py | 18 +++++++++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index 0cb184a948742e0cb38ceebcc63d3187925432fb..7a7f763507aa7a181777b344fe44aecace7d5726 100644 GIT binary patch delta 1624 zcmZ8hdpOg39R6)aBWx~HW*u}+#*$0K^tfb^+-8_kE2$7C=4ewc$42B5sZ8RyL@t?I zPZ3%?D?&F$Mwv51LPmAAhSE5k=izkD_n*)6d7t<5em?K_kN2(d!cIkks|-XP001ap zlzd&W4r-Jv@{K-q40XK?O`mCvbE737;U&Y3dM29AP<|{lHVx2Xho9>|19ye7xx%g$%Z%Bb8p%^|c zXL!%zk3AV}-0sea8guMUeoDArf_-ta;RBQo=UnrBw~=H!t%?A>6gq)J6f7KJ7c@6} zD&M^d8g>l;l}>hK_hc5}CYrG$x{?@iX(Wfb8huG!Y;>?BAxJ)?l_g)auLp zb%1|1XxxpU8<3Dk70?p!PZ~!9Zd51#-q;?2iRc{itNs>C*>}RS6@PYXz}?B}5cYAFJU`H+j`GZvLKe-mRCPx*Enl$? zevx9(evN&O5?1r3+P0hG6Zgq@89O_8lI~q$VjRXkFenw1i`+cFxJEXKI9*l358g|8 z^THD^t53?XmSTI5Vj_Y*l|r9yAcYTBCt3xCJ1&*8mdUobj{aSjYr5x$S**Gl+d10O zYxY*#xPt;E4oB)27be7uKZ<#A!yO}XVHdQek)K7TLKV&n+JsVG-aIuHS(v9s_Bd_U zKQR~5_sTpn_NcX)yP&9(A7a07JmUm(8ymj2rgsHR6QGAj`6K7)!?-s^@$&wvx!{Va zZuyQ*!YgFUUpP~^LN1_}VBjA!Qb6e2in%X$$FCBa1lEgp_E*R)vP2WDlP}jkc}n_V zD#zRyckbvS{)u;NA)?CuW%}%{aG51?U2nt_A45#!-9Y`~$ueFB)8ag4vYbc%5q0Sz zG7B*xuW}uP3CIoX{rF3Z74sl=Af>kl5&IA&Nz_$`?!a9l7#HXFV4R-fyQEY|xr{#C zB}t*gZ=WTfYo02FqG@k*DnoTPnB*$dQ(BH1n+oUdg)1bfmf$M4^txL{!cN(7(*$%| zXq7fp7MDiQ)BeZ}*M$tglfWeomGBu^YQKA6(py;cOq0sR87MA+u$>5% zfLR|Zyl}HAHWHG&{R2qJK7AETQVfVs^|sQT-+$}dTvBn&MS@N?6oG4vC$pGk@TD;i zX%3FyZohu-0!+xPrW4liI-KX>4Sdyy&-Cj)nK4+z;^VA`6x3ym;>OmJ+IH0#kKm{b zFvoM$UcuTq!O38ybf}j(L^$seOpMxasAPlq3CUMON^~}S?Dw!q?OaGYAc1b2+e`Ph zx&6JU7w`NvyG$j`yX_q|NZvJ%z4_yGwv(<>bc1t9+jji-un4F6X003(WJiJ6gtxdf zky-IekSFT;wfiQSUpocZ3)Jju=1K=f)XJINAy{zg-Ojf!HUsI$k3tyy-R2OU)efT&Po3N<=3kYW@S7D{jhfz^TaoM-fD zpumPO#wQKUwG|3mP+$a{p}%FD&YG;5@ExmmRci?Z0LXRC)fx{vr@{zVLn;4H?CR?H RVO2)$mK}1XtEmY9e*^x9(-Qyy delta 2101 zcmY+Fdpy(oAIHDj7_v>vmbpaalFdexLoAi$e&q6trMX{GbyZd(CT}qw!_%?h+fu{Vb(~xkrd-r} z@mhSj>93k#lwqo67PD7eBP}au$w4nf#fxIoZF}B5F_%~SMlEC%P0@ZYt>R4fMq9`6 z9jx1k#7Ax~jGC|1XzG_^FKvNDMqkn}ofkafh#l+q_IxE=I|@_P*CA3nt&{yn-p1&p zV;e$lggtN$h~_r68B6Y+)A4`&#q{8S29N8Dc?CYwQAYC){PFekDHa_HY-qWXF=*?nTyh(WfVo>CsWwLnFQ9DkU*alUnd+kd(DIi=&70s5U04S~5Xj&wLz) zwU6U-cSs-;mh4MBJdJ#Ien6)fWV%A{pQwtt#ap<|Pc_J>tG4Ib5Pq3lNGV(CX-%PN z%XpzH4+BeBD)c+wK6~>%2gDTAtuA)oe9Iq?O$}{2YPUyadf>O^NhJlbWv;+ z+vlF~VE*$^&5Jqj@u$+o+KFl|D2X;oEB5A1%f3y`WD0KmJCHE*X61dd-MNVXTFfY^ zXl`qE#0ksEM=AbN&*_Nsnt>&DYc<+0&ImsC50pE$@?U9MLY@cILfi6^+FQ?SE?&{; zUmYwB3K^8G1;>Yw=f0Zl*;R9nR>;EmwA;OOgH?~}L@Wg3&TYM^pl7N=VjaKyD{Zym zfNG%Ekhfucb2z!9juDLJe~K));-%(^H7+3KhmdyF1d*TBWd$$penFbZ-dT#m>A6@` zV0_GK!pL29XN$utULMMK&f0?v$9TeU7$5VR5HhjH+*79a+^{S2azoC}Of(Fq?z5|g z6;ZVF3{t`faV1$hp!l0IZ@{W)7@xyjxBSPK=bh_!RM_sw3YO=)WFCQ4-#u!GrI0e% zgQ}hvkX>~bgAMrD%>F(TRrwG%gr2bq$p>0RKy1}Au_njWu`WDp(cgODEKKWu;@%2ufwgcL zM49~wk1Mc0>=goF3i#cRE(wZk1zVv$n1cEVLzLJ?M4=OyV)zqgDzP2+2~UA3RzF}` zwdRgZ?BjOAYYfl14yf^LnG(2>ot@~Kb*TXgoGcYNC^<_$^gll~0m`@RC>G-vchnX* z1gVpc=Og{1qC5hq>3wf5?(y4;&n>_D*TYiZgUM}ZNn%>0vZRn6R&16At;lgu?nt3F zf~YyS9cK&vrGU-`l^y{3U3-snYMQ5c2JNpcm34clI5&wvWx0^5`*4@*4{=_(mdA3t zcP841=|WTar^DSiV@Q;|QBFyHted}i?k>h1PEJLJHud`QIS&p}l#j3K_LJIIOpXi% zUGP)vd;);r1HIU6Y-PrNlN{m+xJ#FzZ|3^OL0yP=T0DmI@r%+e8WK0sHccx(Ponnc z(4Q?iMv@u6quZT(GY7{lW!9X?ZTgF5wTQjVI!>Y6W`Oy7a09CS0lBRCbYJ#*9 z>(rEWvil_7&GuL65!I-W@~&HR0dl*A>HCQyk-b!9wrK4A#U7gLh8lL2BZL`|&LZAx zU-cy4`J2I_mYHMsi5myglQh6HYAyGw=$VbW1Ss7VQ-y6^_C&lV%FUexq>_m8*b2@whH>WqhQR@9qIPZks!i*1;KKk$8WxJdDzC#LM_ z_zW9vHjk!7)N5w%?d-qOjKO={=@Z$nU&uYF+)Ob!u3g=4Om{hrex<`g`B=A?%0kq( z7|0TN3Uq2DR-#*^siP89{6}ZlY;x~(?2T12iUwcdPU!q5=nEMg8P^{?u}u0>_L#8N zhH1UK@Jf5MHTWaq!_7Qu!hozE`0x1v_|5F)$t|xX^hZ74e#{SU1WX79lg}`%R6eX1 zuI}bzpbeRd9N&s4+4AF|9v)n7JR2q-(m&pE?PL0J(u(2^`q=`I)msLB8U zU(f09D-C3W0Dz=ZrU{A3r@|8mNz_vwt{^Z9_#WoWS(FwSj$|Ux>KjKGqqV>?B-0VS zZTp6;#pHPF{dKPu5CCX=_gt@OAa7OXRiqa4HX61u##tY;LNQ;W4WQ}hjlO>XIQ75i diff --git a/aio/assets/templates/durable/durable_data_current_max.xlsx b/aio/assets/templates/durable/durable_data_current_max.xlsx index f408976aa53d1ad5ed053585cd5276d6301247a7..a9e1e5f410ff525257c8b868dd29dce0629e74c0 100644 GIT binary patch delta 1583 zcmY+EdpOg39LIl~`;sk8D?8!n7@Ccf+-jB;DmKH!np7@NheBtTOEo{DMMN2?SWKlz zF4dZ>&YUjj;!;`{ODmajiOB5;JJxfO^ZDcZc|Mot{k*@QKVGxgN2|1{9xAH(003wL zIL=A!N=+PRBp@L;5PkA42JE}Dzk^IIsmLc6t|tZSrZKwX8LsVa>E0qC#)_eF*syU@ zG5vb0zEe8y5=Q1Y66hPCeKR~|qmYvIgaTDvmm@LB*l2i<{qbtg?_L1;T^%qt?J{Bpugz&*bYl6Bd8_vIDc=L9H$R=!;>O+ise|OGpti808?Sm`{ zxY%Xa{FrAh@1q#VrJtsrg2;}R=ijD`8ZwG~zVyq=y%zp{B;ZV7p(#Qg017bxpa%fg zKSFTopzG5|o$9V>n>J}#QMC+3f^Fjfryd$PgBNABgl?vEhBU(h+wqwQJYPMsUWi*&S=E_^^_=23*KUkfxSn6?pDMpWEj~zqr-Pf=2wu{CcDFql(vR zH}<2CZQ)5vobk)|zfl8EXl!oZ73v@#B5h~%kCk|R4SXs4mO_M!c1mQqmY^hKuI34b&P+8|CH1piXeuIXW0oh>yid%&wbrWkjRM-T#8~{46r(Vr^R_w9_*P5 z&ZOUZ4Cs|#XKt2NWt4h}WPgp~IbKH3;w~-yI7??s$d_Cv5)M>}UP-BO6Hkqf;*ET> z<1H2R8==7iz2hhzDn!^=0;by}9>ktQ=?NQi(rpqBV)r-R9TcI&2&Y67RxL?UG|3jf zQO@(@7El5BROPXlI`nm4;{Ep@IK2u#m^>`g?GI44Z? zHRalMy%o%j1FW*5tYQ|hjFd$+&RzYfbTv8Um50NyNF8(uQ!&}lv;>yQRPSV!G7$%@ zFp0g!m-icoYC4jVsV&6?Ei8C2zVCjtk*Wlqs%_$Kj(D_;)qX~oH1L2oWtCdI{O}2r zZcR0kV@i~huUp!kCSUP!1kD}sdn%g0-h6i(dG{8rnxzN(gt~_#w0_$1bTk<+@d9UJ zNmPPM6M~rvx4^L*ODmm7jdhYR$);TxVQbnc+sD(REoM)1+zQOcijsYg zoGQrOds(sajbZu=I{I7dy&2=2mGl8ZUR%etA&@({Dmo}5Mr1CjDG0QB*=ZV?_<302 z)P@}kdvz$WQc!v2y?nD=Lo$kCC06VqtQZyBWDYX^fC9jxx%?xNAPOA-*uf0j8-vFwU#bTLst^1?JGUB%hJJ!`TadpfH9ya3x^iI# i7Dh_V0uCwF5CQ-%=MXo?z4=IjSaN*~%+zDQH~$4z6usX7 delta 1736 zcmY+Fc~DbV6vkf`BtQyDcz{4`00EUHAXs7)2-UENEV6~DU|ubyvIS)kS@a1;f>05O z#85T?(Sn$2!LSNMKo-F$h-t*Iv-nlbpzBy-p=ic+j`T8wCSYdbV zM4>?d05AYE=`2==VJ6Ko4UWy&pS`sX?!TEhdfLx5lx*Zo>nHi> zF#jq_9MkjH(t?a(p(KpDNXqBIU;RUrLUskc9j_X0gE0BBcSfK|x97AtY#!{ie=d$% zxR;t?a_8Yh){XnM-+<=F9I|;s6Sc~+@>2Aw^vJje2RV*|leg?t^p;`-`GwEn%93iK zVu(#W)agcTb#iL+y0cDns@Bl7+~NcQ6~R7XU^Cm(CY*4;zGd(OId3;s+mz%K(?v}V z9h1kBI2OO`F9>Vcv5#GMqjkg6nlw^q`#YO$QiGPd;MEdjkhlyEV6FW9EVD4Acr9)f z02HqS0Br!Mn?{gV5tauMuutpB1vCJt8vwv+fCqsFa6zFwuE+y-lI2>ZYCB+y&C3tE zp-YqHT=g_7kVi$IwzkOM1&qoX#?v?3$}=l#W3g%Sf#UFExzOAm%J`!b8|BY>W{$99 zrCec4+UwRglaSAMsR673S$i{&QX8l3ftWymTn44s9(O{ zD-)){EsB)L8KL@AIF`Y>*l6i&uoVi7Dvw$Dk zB;PczsF@jIQ?wSv_ugF?%M6}wW3ZZU5A}EOaUW7NM+E ztWZ{}wSw>IfwtM|#ZVtz#RY^mK>83B>ULaP@nF3tRgBQCI=;Tczr(I0t|L3yjefH7 zr+aD)uRshP!AJ5Dd=z8A-o*1vMZGrB&d(qVxdOT=JG&Sfq`Q6w{mn1%IojPT5XPs&l~3ry4bqfZnt&6#ylP<4|CwOl@E)T z2;(02y7YvYM|8N+Jr7;)f*+e6no#Xi_KXZWtLz|Z>_a`egwejdS2_JQEb3wuh<^JO z=aJ|7LB_|k`Lq%r zg!|`BrlL@%{^;RIxZZcS*lopSjPq&wyGi{!&9b8E5Rrf5dEelPnxDgX={iKj7_U^ve3iv= G1K=NX75GR1 diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index cb6e157..3dc30e6 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -7,6 +7,7 @@ from time import sleep, time, strftime, localtime from pandas import DataFrame from openpyxl import load_workbook from math import sqrt +from numpy import power tab_name = 'Durable Action' count = 0 @@ -215,7 +216,6 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): # f_obj.write(f"{_}\n") _d2d_trq = {0: [], 1: [], 2: [], 3: [], 4: [], 5: []} - _d2d_trq_max = {0: [], 1: [], 2: [], 3: [], 4: [], 5: []} for line in _data_list: for item in line['data']: @@ -225,14 +225,24 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): _d2d_trq[i].extend(item['value']) if len(_d2d_trq[0]) / 1000 > scenario_time + 1: + this_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time())) + next_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()+wait_time+10+scenario_time)).split()[-1] _df = DataFrame(_d2d_trq) for i in range(6): - _ = sqrt(100*_df[i].apply(lambda x: (rcs[i]*x/10000)**2).sum()/len(_df[i])) + try: + _ = sqrt(_df[i].apply(lambda x: power((rcs[i]*x/1000), 2)).sum()/len(_df[i])) + except: + _df.to_excel(path+"\\err_data.xlsx") + w2t(f"{i}calculate error", 0, 11, 'red', tab_name) del data[0][f"axis{i + 1}"][0] data[0][f"axis{i + 1}"].append(_) + del data[0]['time'][0] + data[0]['time'].append(next_time) _ = rcs[i] * _df[i].abs().max() / 1000 del data[1][f"axis{i + 1}"][0] data[1][f"axis{i + 1}"].append(_) + del data[1]['time'][0] + data[1]['time'].append(this_time.split()[-1]) _df_1 = DataFrame(data[0]) _df_2 = DataFrame(data[1]) @@ -247,13 +257,11 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): sleep(1) global count count += 1 - this_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time())) - next_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()+wait_time+10+scenario_time)).split()[-1] w2t(f"[{this_time}] 当前次数:{count:09d} | 预计下次数据更新时间:{next_time}", 0, 0, '#008B8B', tab_name) break else: with open(f'{path}\\device_servo_trq_feedback_0.txt', 'w', encoding='utf-8') as f_obj: - for _ in _d2d_trq['device_servo_trq_feedback_0']: + for _ in _d2d_trq[0]: f_obj.write(f"{_}\n") w2t("采集的数据时间长度不够,需要确认。", 0, 2, 'red', tab_name) From 370fa051aee15ed1be4b01ba0e3134ab97c0a394 Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 18 Jul 2024 17:45:40 +0800 Subject: [PATCH 18/36] change axis x to time --- .../durable/durable_data_current.xlsx | Bin 5623 -> 5473 bytes .../durable/durable_data_current_max.xlsx | Bin 5578 -> 5429 bytes aio/code/aio.py | 38 +++++++++------- aio/code/durable_action/factory_test.py | 42 ++++++++++-------- 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx index 7a7f763507aa7a181777b344fe44aecace7d5726..082626d97cd6425109f3d20cb1724374f742d2e7 100644 GIT binary patch delta 1508 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 OYD^t9xNIas!u Date: Fri, 19 Jul 2024 11:09:34 +0800 Subject: [PATCH 19/36] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E6=95=B0=E6=8D=AE=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9x=E8=BD=B4=E5=9D=90=E6=A0=87=E5=88=BB?= =?UTF-8?q?=E5=BA=A6=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/code/aio.py | 2 +- aio/code/durable_action/factory_test.py | 45 +++++++++++++++++++++---- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/aio/code/aio.py b/aio/code/aio.py index 4ffc610..565fa86 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -247,7 +247,7 @@ class App(customtkinter.CTk): _ = df['time'].to_list() _xticks = [str(_i) for _i in _] ax = figure.add_subplot(1, 1, 1) - ax.set_xticks(range(1, len(_xticks)+1)) + ax.set_xticks(range(len(_xticks))) ax.set_xticklabels(_xticks) df.plot(grid=True, x='time', y='axis1', ax=ax) diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index d114912..17b7d3f 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -8,6 +8,7 @@ from pandas import DataFrame from openpyxl import load_workbook from math import sqrt from numpy import power +from csv import writer tab_name = 'Durable Action' count = 0 @@ -46,6 +47,10 @@ durable_data_current_max = { 'axis6': [0 for _ in range(18)], } data_all = [durable_data_current, durable_data_current_max] +title = [ + 'time', 'trq-1', 'trq-2', 'trq-3', 'trq-4', 'trq-5', 'trq-6', 'trq-max-1', 'trq-max-2', 'trq-max-3', 'trq-max-4', + 'trq-max-5', 'trq-max-6' +] def traversal_files(path, w2t): @@ -174,6 +179,9 @@ def run_rl(path, config_file, hr, md, w2t): _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) sleep(1) # 保证所有数据均已返回 # 7. 保留数据并处理输出 + with open(f'{path}\\results.csv', mode='a+', newline='') as f_csv: + csv_writer = writer(f_csv) + csv_writer.writerow(title) _wb = load_workbook(config_file, read_only=True) _ws = _wb['Target'] wait_time = float(_ws.cell(row=2, column=10).value) @@ -229,28 +237,53 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): next_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()+wait_time+10+scenario_time)).split()[-1] _df = DataFrame(_d2d_trq) _flg = 0 + _res = [] for i in range(6): + def overmax_data(df, index, number, flag): + if number > 100: + df.to_excel(f'{path}\\{this_time}.xlsx') + w2t(f"[{this_time}] {flag}-axis-{index} 数据过大错误,需要检查确定。", 0, 0, 'red', tab_name) + try: _ = sqrt(_df[i].apply(lambda x: power((rcs[i]*x/1000), 2)).sum()/len(_df[i])) except: _df.to_excel(path+"\\err_data.xlsx") w2t(f"{i}calculate error", 0, 11, 'red', tab_name) - del data[0][f"axis{i + 1}"][0] - data[0][f"axis{i + 1}"].append(_) - - _ = rcs[i] * _df[i].abs().max() / 1000 - del data[1][f"axis{i + 1}"][0] - data[1][f"axis{i + 1}"].append(_) if not _flg: del data[0]['time'][0] data[0]['time'].append(this_time.split()[-1]) del data[1]['time'][0] data[1]['time'].append(this_time.split()[-1]) + _res.append(this_time) _flg = 1 + del data[0][f"axis{i + 1}"][0] + overmax_data(_df, i, _, 'trq') + data[0][f"axis{i + 1}"].append(_) + _res.append(_) + + _ = rcs[i] * _df[i].abs().max() / 1000 + overmax_data(_df, i, _, 'trq-max') + del data[1][f"axis{i + 1}"][0] + data[1][f"axis{i + 1}"].append(_) + _res.append(_) + _df_1 = DataFrame(data[0]) _df_2 = DataFrame(data[1]) + with open(f'{path}\\results.csv', mode='a+', newline='') as f_csv: + def change_order(res): + _time = res[0:1] + _trq = [] + _trq_max = [] + for _item in res[1::2]: + _trq.append(_item) + for _item in res[2::2]: + _trq_max.append(_item) + return _time + _trq + _trq_max + + csv_writer = writer(f_csv) + csv_writer.writerow(change_order(_res)) while True: if not hr.durable_lock: From 97cb4fe1d4cd73a9641dfc29c1c28eeb43f68dd2 Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 19 Jul 2024 11:13:51 +0800 Subject: [PATCH 20/36] minor modification --- aio/code/durable_action/factory_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 17b7d3f..05b80ab 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -71,13 +71,13 @@ def traversal_files(path, w2t): def check_files(data_dirs, data_files, w2t): if len(data_dirs) != 0 or len(data_files) != 2: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2.configs.xlsx', 0, + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2. configs.xlsx', 0, 10, 'red', tab_name) _files = [data_files[0].split('\\')[-1], data_files[1].split('\\')[-1]] _files.sort() if _files != ['configs.xlsx', 'target.zip']: - w2t('初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2.configs.xlsx', 0, 10, 'red', tab_name) + w2t('初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2. configs.xlsx', 0, 10, 'red', tab_name) data_files.sort() return data_files From 73230a7133c763b49d4038ddf6921a4031688027 Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 19 Jul 2024 11:21:27 +0800 Subject: [PATCH 21/36] remove durable folder --- .gitignore | 3 ++- .../templates/durable/durable_data_current.xlsx | Bin 5473 -> 0 bytes .../durable/durable_data_current_max.xlsx | Bin 5429 -> 0 bytes 3 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 aio/assets/templates/durable/durable_data_current.xlsx delete mode 100644 aio/assets/templates/durable/durable_data_current_max.xlsx diff --git a/.gitignore b/.gitignore index bea7ae6..89a9f58 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ aio/__pycache__/ aio/code/automatic_test/__pycache__/ aio/code/data_process/__pycache__/ aio/assets/templates/c_msg.log -aio/code/durable_action/__pycache__/ \ No newline at end of file +aio/code/durable_action/__pycache__/ +aio/assets/templates/durable/ \ No newline at end of file diff --git a/aio/assets/templates/durable/durable_data_current.xlsx b/aio/assets/templates/durable/durable_data_current.xlsx deleted file mode 100644 index 082626d97cd6425109f3d20cb1724374f742d2e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5473 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 E0RU0C5C8xG diff --git a/aio/assets/templates/durable/durable_data_current_max.xlsx b/aio/assets/templates/durable/durable_data_current_max.xlsx deleted file mode 100644 index 76bd041f4f12f6d6f488840ad9fd6e225545a252..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5429 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 From 2f782c9693c31446fe0ef3be446ea53179ad05be Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 19 Jul 2024 16:32:31 +0800 Subject: [PATCH 22/36] another try --- aio/README.md | 11 ++++ aio/code/aio.py | 6 ++ aio/code/durable_action/factory_test.py | 86 ++++++++++++------------- 3 files changed, 58 insertions(+), 45 deletions(-) diff --git a/aio/README.md b/aio/README.md index 1398488..42a9985 100644 --- a/aio/README.md +++ b/aio/README.md @@ -161,6 +161,8 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A - configs.xlsx,执行之前需要手动修改好configs.xlsx中的参数,以及间隔时间 - target.zip,需要确认工程点位和动作无问题后,保存导出 +> 重新运行时,必须突出软件,重新运行 + #### 其他 customtkinter的tabview组件不支持修改字体大小,可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现: a. 运行 `pip show customtkinter`,获取到库的路径 @@ -518,3 +520,12 @@ v0.2.0.0(2024/07/17) - HmiRequest模块:日志取消记录move.monitor相关 - HmiRequest模块:增加了durable_lock变量,控制文件读写互斥 +v0.2.0.1(2024/07/19) +1. [main: aio.py] + - 修改了x轴显示,使之为时间刻度 + - 修改pre_warning函数,增加了durable test的初始化 +2. [main: factory_test.py] + - 增加了数据计算错误的判断逻辑 + - 增加了历史数据保存的逻辑 + - 增加了文件读写互斥的逻辑 + - 修改功能为输出有效电流和最大电流,并将数据结构简化 \ No newline at end of file diff --git a/aio/code/aio.py b/aio/code/aio.py index 565fa86..37556fb 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -619,6 +619,12 @@ class App(customtkinter.CTk): tkinter.messagebox.showerror(title="参数错误", message="请检查对应参数是否填写正确!", ) def pre_warning(self): + if self.tabview.get() == 'Durable Action': + df = DataFrame(durable_data_current) + df.to_excel(durable_data_current_xlsx, index=False) + df = DataFrame(durable_data_current_max) + df.to_excel(durable_data_current_max_xlsx, index=False) + if tkinter.messagebox.askyesno(title="开始运行", message="确认机器已按照测试规范更新固件,并提按照测试机型前修改好工程?"): pass else: diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 05b80ab..23f77b8 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -11,7 +11,6 @@ from numpy import power from csv import writer tab_name = 'Durable Action' -count = 0 durable_data_current_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current.xlsx' durable_data_current_max_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current_max.xlsx' display_pdo_params = [ @@ -28,25 +27,6 @@ display_pdo_params = [ {"name": "device_servo_trq_feedback", "channel": 4}, {"name": "device_servo_trq_feedback", "channel": 5}, ] -durable_data_current = { - 'time': list(range(1, 19)), - 'axis1': [0 for _ in range(18)], - 'axis2': [0 for _ in range(18)], - 'axis3': [0 for _ in range(18)], - 'axis4': [0 for _ in range(18)], - 'axis5': [0 for _ in range(18)], - 'axis6': [0 for _ in range(18)], -} -durable_data_current_max = { - 'time': list(range(1, 19)), - 'axis1': [0 for _ in range(18)], - 'axis2': [0 for _ in range(18)], - 'axis3': [0 for _ in range(18)], - 'axis4': [0 for _ in range(18)], - 'axis5': [0 for _ in range(18)], - 'axis6': [0 for _ in range(18)], -} -data_all = [durable_data_current, durable_data_current_max] title = [ 'time', 'trq-1', 'trq-2', 'trq-3', 'trq-4', 'trq-5', 'trq-6', 'trq-max-1', 'trq-max-2', 'trq-max-3', 'trq-max-4', 'trq-max-5', 'trq-max-6' @@ -71,8 +51,7 @@ def traversal_files(path, w2t): def check_files(data_dirs, data_files, w2t): if len(data_dirs) != 0 or len(data_files) != 2: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2. configs.xlsx', 0, - 10, 'red', tab_name) + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2. configs.xlsx', 0, 10, 'red', tab_name) _files = [data_files[0].split('\\')[-1], data_files[1].split('\\')[-1]] _files.sort() @@ -124,16 +103,13 @@ def execution(cmd, hr, w2t, **kwargs): return _response -def run_rl(path, config_file, hr, md, w2t): +def run_rl(path, config_file, data_all, count, hr, md, w2t): # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) md.trigger_estop() md.reset_estop() md.write_act(False) sleep(1) # 让曲线彻底关闭 - _response = execution('state.switch_manual', hr, w2t) - _response = execution('state.switch_motor_off', hr, w2t) # 2. reload工程后,pp2main,并且自动模式和上电 prj_path = 'target/_build/target.prj' @@ -163,7 +139,7 @@ def run_rl(path, config_file, hr, md, w2t): while True: scenario_time = md.read_scenario_time() if float(scenario_time) > 1: - w2t(f"场景的周期时间:{scenario_time}", 0, 0, 'green', tab_name) + w2t(f"场景的周期时间:{scenario_time}s", 0, 0, 'green', tab_name) break else: if (time() - _t_start) // 60 > 3: @@ -172,13 +148,9 @@ def run_rl(path, config_file, hr, md, w2t): sleep(5) sleep(1) # 一定要延迟一秒再读一次scenario time寄存器,因为一开始读取的数值不准确 scenario_time = float(md.read_scenario_time()) - sleep(scenario_time * 0.2) # 再运行周期的20%即可 + sleep(scenario_time*0.2) - # 6. 关闭诊断曲线,停止程序运行,下电并且换成手动模式 - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) - sleep(1) # 保证所有数据均已返回 - # 7. 保留数据并处理输出 + # 6. 准备初始数据,关闭诊断曲线,保留数据并处理输出 with open(f'{path}\\results.csv', mode='a+', newline='') as f_csv: csv_writer = writer(f_csv) csv_writer.writerow(title) @@ -189,23 +161,24 @@ def run_rl(path, config_file, hr, md, w2t): for i in range(6): rcs.append(float(_ws.cell(row=6, column=i + 2).value)) - get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, w2t) + _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + sleep(1) # 保证所有数据均已返回 + get_durable_data(path, data_all, scenario_time, wait_time, count, rcs, hr, md, w2t) - # 8. 继续运行 + # 7. 继续运行 while True: - # 每3分钟,更新一次数据,打开曲线,获取周期内电流,关闭曲线 + # 固定间隔,更新一次数据,打开曲线,获取周期内电流,关闭曲线 sleep(wait_time) _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) sleep(scenario_time+5) _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=[]) sleep(2) - # 7. 保留数据并处理输出 - get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, w2t) + # 保留数据并处理输出 + get_durable_data(path, data_all, scenario_time, wait_time, count, rcs, hr, md, w2t) -def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): +def get_durable_data(path, data, scenario_time, wait_time, count, rcs, hr, md, w2t): _data_list = [] for _msg in hr.c_msg: if 'diagnosis.result' in _msg: @@ -219,7 +192,7 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): del hr.c_msg[_index:] hr.c_msg_xs.clear() - # with open('log.txt', 'w', encoding='utf-8') as f_obj: + # with open(f'{path}\\log.txt', 'w', encoding='utf-8') as f_obj: # for _ in _data_list: # f_obj.write(f"{_}\n") @@ -241,12 +214,15 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): for i in range(6): def overmax_data(df, index, number, flag): if number > 100: + md.trigger_estop() + hr.durable_quit = 1 df.to_excel(f'{path}\\{this_time}.xlsx') - w2t(f"[{this_time}] {flag}-axis-{index} 数据过大错误,需要检查确定。", 0, 0, 'red', tab_name) + w2t(f"[{this_time}] {flag}-axis-{index} 数据过大错误,需要检查确定。", 0, 10, 'red', tab_name) try: _ = sqrt(_df[i].apply(lambda x: power((rcs[i]*x/1000), 2)).sum()/len(_df[i])) except: + md.trigger_estop() _df.to_excel(path+"\\err_data.xlsx") w2t(f"{i}calculate error", 0, 11, 'red', tab_name) @@ -294,22 +270,42 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, w2t): break else: sleep(1) - global count count += 1 w2t(f"[{this_time}] 当前次数:{count:09d} | 预计下次数据更新时间:{next_time}", 0, 0, '#008B8B', tab_name) break else: + md.trigger_estop() with open(f'{path}\\device_servo_trq_feedback_0.txt', 'w', encoding='utf-8') as f_obj: for _ in _d2d_trq[0]: f_obj.write(f"{_}\n") - w2t("采集的数据时间长度不够,需要确认。", 0, 2, 'red', tab_name) + w2t("采集的数据时间长度不够,需要确认。", 0, 10, 'red', tab_name) def main(path, hr, md, w2t): + count = 0 + durable_data_current = { + 'time': list(range(1, 19)), + 'axis1': [0 for _ in range(18)], + 'axis2': [0 for _ in range(18)], + 'axis3': [0 for _ in range(18)], + 'axis4': [0 for _ in range(18)], + 'axis5': [0 for _ in range(18)], + 'axis6': [0 for _ in range(18)], + } + durable_data_current_max = { + 'time': list(range(1, 19)), + 'axis1': [0 for _ in range(18)], + 'axis2': [0 for _ in range(18)], + 'axis3': [0 for _ in range(18)], + 'axis4': [0 for _ in range(18)], + 'axis5': [0 for _ in range(18)], + 'axis6': [0 for _ in range(18)], + } + data_all = [durable_data_current, durable_data_current_max] data_dirs, data_files = traversal_files(path, w2t) config_file, prj_file = check_files(data_dirs, data_files, w2t) prj_to_xcore(prj_file) - run_rl(path, config_file, hr, md, w2t) + run_rl(path, config_file, data_all, count, hr, md, w2t) if __name__ == '__main__': From 8b49d3b6e4acb704f2e9f79d600d9af4f8587435 Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 19 Jul 2024 17:19:19 +0800 Subject: [PATCH 23/36] =?UTF-8?q?=E5=B0=86count=E6=81=A2=E5=A4=8D=E4=B8=BA?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E6=A0=87=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/code/durable_action/factory_test.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 23f77b8..c596ad5 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -11,6 +11,7 @@ from numpy import power from csv import writer tab_name = 'Durable Action' +count = 0 durable_data_current_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current.xlsx' durable_data_current_max_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current_max.xlsx' display_pdo_params = [ @@ -103,7 +104,7 @@ def execution(cmd, hr, w2t, **kwargs): return _response -def run_rl(path, config_file, data_all, count, hr, md, w2t): +def run_rl(path, config_file, data_all, hr, md, w2t): # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) md.trigger_estop() @@ -163,7 +164,7 @@ def run_rl(path, config_file, data_all, count, hr, md, w2t): _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) sleep(1) # 保证所有数据均已返回 - get_durable_data(path, data_all, scenario_time, wait_time, count, rcs, hr, md, w2t) + get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, md, w2t) # 7. 继续运行 while True: @@ -175,10 +176,10 @@ def run_rl(path, config_file, data_all, count, hr, md, w2t): _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) sleep(2) # 保留数据并处理输出 - get_durable_data(path, data_all, scenario_time, wait_time, count, rcs, hr, md, w2t) + get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, md, w2t) -def get_durable_data(path, data, scenario_time, wait_time, count, rcs, hr, md, w2t): +def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, md, w2t): _data_list = [] for _msg in hr.c_msg: if 'diagnosis.result' in _msg: @@ -270,6 +271,7 @@ def get_durable_data(path, data, scenario_time, wait_time, count, rcs, hr, md, w break else: sleep(1) + global count count += 1 w2t(f"[{this_time}] 当前次数:{count:09d} | 预计下次数据更新时间:{next_time}", 0, 0, '#008B8B', tab_name) break @@ -282,7 +284,6 @@ def get_durable_data(path, data, scenario_time, wait_time, count, rcs, hr, md, w def main(path, hr, md, w2t): - count = 0 durable_data_current = { 'time': list(range(1, 19)), 'axis1': [0 for _ in range(18)], @@ -305,7 +306,7 @@ def main(path, hr, md, w2t): data_dirs, data_files = traversal_files(path, w2t) config_file, prj_file = check_files(data_dirs, data_files, w2t) prj_to_xcore(prj_file) - run_rl(path, config_file, data_all, count, hr, md, w2t) + run_rl(path, config_file, data_all, hr, md, w2t) if __name__ == '__main__': From 82ae2681bb20cfa501978506bc6f9a6d84d1a893 Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 26 Jul 2024 13:24:44 +0800 Subject: [PATCH 24/36] =?UTF-8?q?v0.2.0.2(2024/07/26)=201.=20[main:=20curr?= =?UTF-8?q?ent.py]=20=20=20=20-=20=E4=BF=AE=E6=AD=A3=E5=A0=B5=E8=BD=AC?= =?UTF-8?q?=E7=94=B5=E6=B5=81=E6=97=A0=E6=B3=95=E6=AD=A3=E7=A1=AE=E5=86=99?= =?UTF-8?q?=E5=85=A5=E7=BB=93=E6=9E=9C=E6=96=87=E4=BB=B6=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=202.=20[main:=20do=5Fbrake.py]=20=20=20=20-=20?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E9=80=9F=E5=BA=A6=E9=87=87=E9=9B=86=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E6=97=B6=E9=97=B4=E8=AE=BE=E7=BD=AE=E4=B8=BA=E5=8F=AF?= =?UTF-8?q?=E9=80=9A=E8=BF=87configs.xlsx=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=B0=83=E6=95=B4=E7=9A=84=20=20=20=20-=20=E5=88=9D?= =?UTF-8?q?=E6=AC=A1=E9=80=9F=E5=BA=A6=E9=87=87=E9=9B=86=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E4=BF=AE=E6=94=B9=E4=B8=BAtasks.stop?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=EF=BC=88=E6=9C=AA=E9=AA=8C=E8=AF=81=EF=BC=89?= =?UTF-8?q?=20=20=20=20-=20=E6=80=A5=E5=81=9C=E4=BF=A1=E5=8F=B7=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=89=8D=EF=BC=8Cpending=E6=97=B6=E9=97=B4=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E4=B8=BA=E5=9B=BA=E5=AE=9A=E5=80=BC10s=20=20=20=20-?= =?UTF-8?q?=20=E5=AE=9E=E7=8E=B0=E6=AD=A3=E8=B4=9F=E6=96=B9=E5=90=91?= =?UTF-8?q?=E9=80=9F=E5=BA=A6=E9=87=87=E9=9B=86=E9=80=BB=E8=BE=91=20=20=20?= =?UTF-8?q?=20-=20=E5=B7=A5=E7=A8=8B=E5=90=8D=E5=8F=98=E6=9B=B4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=AE=9E=E7=8E=B0=E4=BF=AE=E6=94=B9=E4=B8=BA=E9=80=9A?= =?UTF-8?q?=E9=85=8D=E7=AC=A6=EF=BC=8C=E6=96=B9=E4=BE=BF=E5=90=8E=E7=BB=AD?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=9C=BA=E5=9E=8B=E4=BF=9D=E5=AD=98=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20=20=20=20-=20=E5=A2=9E=E5=8A=A0=E8=B6=85=E5=B7=AE?= =?UTF-8?q?=E5=90=8E=E5=86=99=E8=AF=8A=E6=96=AD=E7=9A=84=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=8F=AF=E4=BB=A5=E9=80=9A=E8=BF=87configs.x?= =?UTF-8?q?lsx=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E8=B0=83=E6=95=B4=20=20?= =?UTF-8?q?=20=20-=20=E7=A8=8B=E5=BA=8F=E8=BE=93=E5=87=BA=E4=B8=AD?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=B6=E9=97=B4=E6=88=B3=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E8=B0=83=E8=AF=95=E5=AE=9A=E4=BD=8D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=97=B6=E9=97=B4=203.=20[main:=20do=5Fcurrent.py]=20=20=20=20?= =?UTF-8?q?-=20=E5=B7=A5=E7=A8=8B=E5=90=8D=E5=8F=98=E6=9B=B4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=AE=9E=E7=8E=B0=E4=BF=AE=E6=94=B9=E4=B8=BA=E9=80=9A?= =?UTF-8?q?=E9=85=8D=E7=AC=A6=EF=BC=8C=E6=96=B9=E4=BE=BF=E5=90=8E=E7=BB=AD?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=9C=BA=E5=9E=8B=E4=BF=9D=E5=AD=98=E6=96=87?= =?UTF-8?q?=E4=BB=B6=204.=20=E4=B8=BA=E5=B7=A5=E7=A8=8B=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9B=B4=E8=AF=A6=E7=BB=86=E7=9A=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=205.=20=E8=A1=A5=E5=85=85=E4=BA=86do=5Fcurrent/do=5Fb?= =?UTF-8?q?rake=E7=9A=84=E6=B5=81=E7=A8=8B=E5=9B=BE=206.=20[main:=20openap?= =?UTF-8?q?i.py]=20=20=20=20-=20=C2=BD=C2=ABmodbus=20motor=5Fon/off=C2=B5?= =?UTF-8?q?=C3=84=C2=B5=C3=8F=C2=B7=C2=BD=C2=B7=C2=A8=C2=B8=C3=84=C2=AA?= =?UTF-8?q?=C2=B8=DF=B5=C3=A7=C3=82=C2=B3=E5=B4=A5=C2=B7=C2=A2=207.=20conf?= =?UTF-8?q?igs.xlsx=E9=85=8D=E7=BD=AE=E8=A1=A8=E6=96=B0=E5=A2=9Ewrite=5Fdi?= =?UTF-8?q?agnosis/get=5Finit=5Fspeed=E4=B8=A4=E4=B8=AA=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 46 +- aio/assets/configs.xlsx | Bin 225074 -> 225318 bytes aio/assets/file_version_info.txt | 8 +- aio/assets/target_brake_current.zip | Bin 26247 -> 27698 bytes aio/assets/vers | 2 +- aio/assets/workflow/brake.excalidraw | 1063 +++++---- aio/assets/workflow/do_brake.excalidraw | 2584 +++++++++++++++++++++ aio/assets/workflow/do_current.excalidraw | 1666 +++++++++++++ aio/code/automatic_test/do_brake.py | 192 +- aio/code/automatic_test/do_current.py | 4 +- aio/code/data_process/current.py | 2 +- aio/code/openapi.py | 15 +- 12 files changed, 4976 insertions(+), 606 deletions(-) create mode 100644 aio/assets/workflow/do_brake.excalidraw create mode 100644 aio/assets/workflow/do_current.excalidraw diff --git a/aio/README.md b/aio/README.md index 42a9985..3919528 100644 --- a/aio/README.md +++ b/aio/README.md @@ -133,16 +133,18 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A > **需要注意的点** -1. 【重要】使用之前需要手动修改!!负载信息!!点位信息!!,确保所有点位不会发生撞击,确保所有程序正常运行之后,导出工程,再进行自动化测试 -2. 工程文件不能手动重命名,需要重命名存档,可以导入HMI,然后另存为 -3. 务必正确填写configs.xlsx中的Target页面,A1单元格可以选择正负方向急停,但不完全保证100%,大概有95%左右的准确度 -4. 由于xCore系统问题,运行过程中可能会出现机器人宕机问题,如果遇到,可以手动重启控制柜,重新运行 -5. 运行过程中,如果是因为机器问题无法达到额定百分比速度,会在日志输出框提示,注意观察 -6. 运行自动化程序之前,确保机器处于正常状态,无故障,未触发急停 -7. 需要额外硬件接线,详细参考configs.xlsx中急停接线图sheet页 -8. 注意观察二轴100%臂展时,是否可以获取到正确的数据 -9. 将autotest.xml导入到寄存器,并新建一个modbus,命名为autotest -10. 针对五轴机型,六轴数据可以填写1-5轴任意一轴的点位信息 +1. 修改该文件点位信息 +2. 修改“编程”→“工具列表”中的工具信息,制动只允许使用tool33/tool66/tool100/inertia这四个工具,不可重命名 +3. 除了调试行,其他行请勿修改,包括增加空行等,尤其是有特别注释的地方 +4. stop0_related半静态任务,需要注意DO0_0的命名,不同控制柜,可能不一样 +5. 需要导入 autotest.xml 寄存器文件,以及新建modbus总线设备,命名为autotest,其他默认即可 +6. 其他无需修改,如有其他需求,可联系fanmingfu@rokae.com沟通 +7. 需要额外硬件接线,详细参考configs.xlsx中急停接线图sheet页,其中DO0_0视硬件情况,可能为其他名称 +8. 运行自动化程序之前,确保机器处于正常状态,无故障,未触发急停 +9. 运行过程中,如果是因为机器问题无法达到额定百分比速度,会在日志输出框提示,注意观察 +10. 由于xCore系统问题,运行过程中可能会出现机器人宕机问题,如果遇到,可以手动重启控制柜,重新运行 +11. 务必正确填写configs.xlsx中的Target页面,A1单元格可以选择正负方向急停 +12. 工程文件可以手动重命名,按照机型存档,或者导出用于自动化测试 #### 6) 电机电流自动化测试 @@ -153,7 +155,8 @@ pyinstaller --noconfirm --onedir --windowed --add-data "C:/Users/Administrator/A > **需要注意的点** -基本同第五点 +基本同第五点,针对五轴以及以下的机型,缺失轴数据可以填写其他有效轴任意一轴的点位信息 + #### 7) 耐久工程曲线指标采集 @@ -528,4 +531,23 @@ v0.2.0.1(2024/07/19) - 增加了数据计算错误的判断逻辑 - 增加了历史数据保存的逻辑 - 增加了文件读写互斥的逻辑 - - 修改功能为输出有效电流和最大电流,并将数据结构简化 \ No newline at end of file + - 修改功能为输出有效电流和最大电流,并将数据结构简化 + +v0.2.0.2(2024/07/26) +1. [main: current.py] + - 修正堵转电流无法正确写入结果文件的问题 +2. [main: do_brake.py] + - 初始速度采集等待时间设置为可通过configs.xlsx配置文件调整的 + - 初次速度采集停止逻辑修改为tasks.stop指令(未验证) + - 急停信号触发前,pending时间设置为固定值10s + - 实现正负方向速度采集逻辑 + - 工程名变更逻辑实现修改为通配符,方便后续根据机型保存文件 + - 增加超差后写诊断的逻辑,并可以通过configs.xlsx配置文件调整 + - 程序输出中增加时间戳,方便调试定位日志时间 +3. [main: do_current.py] + - 工程名变更逻辑实现修改为通配符,方便后续根据机型保存文件 +4. 为工程文件添加更详细的注释 +5. 补充了do_current/do_brake的流程图 +6. [main: openapi.py] + - 将modbus motor_on/off的实现方法改为高电平脉冲触发 +7. configs.xlsx配置表新增write_diagnosis/get_init_speed两个参数 \ No newline at end of file diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index 158cdf5ec5b2084be44eac15bed6e88ac7a8d790..8cb640c66f9c4683c6eb9dc28e66e6ddfd5fcc3b 100644 GIT binary patch delta 8281 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 H4#58a_5b}Z diff --git a/aio/assets/file_version_info.txt b/aio/assets/file_version_info.txt index e1ab27a..56adeda 100644 --- a/aio/assets/file_version_info.txt +++ b/aio/assets/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, 2, 0, 0), - prodvers=(0, 2, 0, 0), + filevers=(0, 2, 0, 2), + prodvers=(0, 2, 0, 2), # 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 toolbox'), - StringStruct('FileVersion', '0.2.0.0 (2024-07-17)'), + StringStruct('FileVersion', '0.2.0.2 (2024-07-26)'), StringStruct('InternalName', 'AIO.exe'), StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'), StringStruct('OriginalFilename', 'AIO.exe'), StringStruct('ProductName', 'AIO'), - StringStruct('ProductVersion', '0.2.0.0 (2024-07-17)')]) + StringStruct('ProductVersion', '0.2.0.2 (2024-07-26)')]) ]), VarFileInfo([VarStruct('Translation', [1033, 1200])]) ] diff --git a/aio/assets/target_brake_current.zip b/aio/assets/target_brake_current.zip index 7b11793a1e66ea427b34b81d35f9c1723fddae0c..7f9f06e57e1beb64d286caf013fe239d377acfe3 100644 GIT binary patch delta 16730 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 delta 15263 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 X-_N08p1;Ea`pZQG%{8EBU||0b3-BwO diff --git a/aio/assets/vers b/aio/assets/vers index 82f7d35..e78860d 100644 --- a/aio/assets/vers +++ b/aio/assets/vers @@ -1 +1 @@ -0.2.0.0 @ 07/17/2024 \ No newline at end of file +0.2.0.2 @ 07/26/2024 \ No newline at end of file diff --git a/aio/assets/workflow/brake.excalidraw b/aio/assets/workflow/brake.excalidraw index 3b5ddc4..a899e29 100644 --- a/aio/assets/workflow/brake.excalidraw +++ b/aio/assets/workflow/brake.excalidraw @@ -4,30 +4,30 @@ "source": "http://10.2.23.150:10020", "elements": [ { - "id": "VKFtKdgvUf_KRKPEhzkwN", "type": "rectangle", - "x": 303.3333435058594, - "y": 190, - "width": 96.66668701171875, - "height": 39.33334350585938, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 110, + "versionNonce": 1663603452, + "index": "a0", + "isDeleted": false, + "id": "VKFtKdgvUf_KRKPEhzkwN", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 303.3333435058594, + "y": 190, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 96.66668701171875, + "height": 39.33334350585938, + "seed": 1865776252, "groupIds": [], "frameId": null, - "index": "a0", "roundness": { "type": 3 }, - "seed": 1865776252, - "version": 110, - "versionNonce": 1663603452, - "isDeleted": false, "boundElements": [ { "type": "text", @@ -43,35 +43,35 @@ "locked": false }, { - "id": "ROAaPkoBR-QkYLBotqCfD", "type": "text", - "x": 331.66668701171875, - "y": 197.1666717529297, - "width": 40, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 81, + "versionNonce": 747583812, + "index": "a1", + "isDeleted": false, + "id": "ROAaPkoBR-QkYLBotqCfD", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 331.66668701171875, + "y": 197.1666717529297, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 25, + "seed": 1634680516, "groupIds": [], "frameId": null, - "index": "a1", "roundness": null, - "seed": 1634680516, - "version": 81, - "versionNonce": 747583812, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718068822440, "link": null, "locked": false, - "text": "开始", "fontSize": 20, "fontFamily": 1, + "text": "开始", "textAlign": "center", "verticalAlign": "middle", "containerId": "VKFtKdgvUf_KRKPEhzkwN", @@ -240,30 +240,30 @@ "lineHeight": 1.25 }, { - "id": "g9-8GSeIkp0vW_kZMseY_", "type": "diamond", - "x": 160.66668701171875, - "y": 459.33331298828125, - "width": 365.33337402343756, - "height": 102.6666870117187, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 162, + "versionNonce": 458003780, + "index": "a6", + "isDeleted": false, + "id": "g9-8GSeIkp0vW_kZMseY_", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 160.66668701171875, + "y": 459.33331298828125, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 365.33337402343756, + "height": 102.6666870117187, + "seed": 102257532, "groupIds": [], "frameId": null, - "index": "a6", "roundness": { "type": 2 }, - "seed": 102257532, - "version": 162, - "versionNonce": 458003780, - "isDeleted": false, "boundElements": [ { "type": "text", @@ -287,35 +287,35 @@ "locked": false }, { - "id": "r00E8_45oroyHrO6jOFql", "type": "text", - "x": 263.5000305175781, - "y": 497.99998474121094, - "width": 160, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 102, + "versionNonce": 996993092, + "index": "a6V", + "isDeleted": false, + "id": "r00E8_45oroyHrO6jOFql", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 263.5000305175781, + "y": 497.99998474121094, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 160, + "height": 25, + "seed": 1477218756, "groupIds": [], "frameId": null, - "index": "a6V", "roundness": null, - "seed": 1477218756, - "version": 102, - "versionNonce": 996993092, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718069594842, "link": null, "locked": false, - "text": "尝试处理数据文件", "fontSize": 20, "fontFamily": 1, + "text": "尝试处理数据文件", "textAlign": "center", "verticalAlign": "middle", "containerId": "g9-8GSeIkp0vW_kZMseY_", @@ -1040,45 +1040,34 @@ "lineHeight": 1.25 }, { - "id": "ElM71P3ujX7DK-jVqI3DE", "type": "arrow", - "x": 350.00006103515625, - "y": 235.3332977294922, - "width": 0.666656494140625, - "height": 34.666656494140625, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", + "version": 31, + "versionNonce": 185914236, + "index": "aS", + "isDeleted": false, + "id": "ElM71P3ujX7DK-jVqI3DE", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 350.00006103515625, + "y": 235.3332977294922, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 0.666656494140625, + "height": 34.666656494140625, + "seed": 1138234492, "groupIds": [], "frameId": null, - "index": "aS", "roundness": { "type": 2 }, - "seed": 1138234492, - "version": 31, - "versionNonce": 185914236, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718070311849, "link": null, "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.666656494140625, - 34.666656494140625 - ] - ], - "lastCommittedPoint": null, "startBinding": { "elementId": "VKFtKdgvUf_KRKPEhzkwN", "focus": 0.024081446167233695, @@ -1089,49 +1078,49 @@ "focus": 0.059926852921581265, "gap": 9.00006103515625 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "iPyKh3jRmtupi7xaTXi2f", - "type": "arrow", - "x": 343.3334045410156, - "y": 321.9999542236328, - "width": 0, - "height": 34.66668701171875, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "aT", - "roundness": { - "type": 2 - }, - "seed": 1574642812, - "version": 45, - "versionNonce": 775346812, - "isDeleted": false, - "boundElements": null, - "updated": 1718070319040, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - 0, - 34.66668701171875 + -0.666656494140625, + 34.666656494140625 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 45, + "versionNonce": 775346812, + "index": "aT", + "isDeleted": false, + "id": "iPyKh3jRmtupi7xaTXi2f", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 343.3334045410156, + "y": 321.9999542236328, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 0, + "height": 34.66668701171875, + "seed": 1574642812, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070319040, + "link": null, + "locked": false, "startBinding": { "elementId": "S0nSbhhR41jGbkbzsVSqM", "focus": -0.0000011737528079939943, @@ -1142,49 +1131,49 @@ "focus": -0.06962023299391551, "gap": 4.000030517578125 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "Oy_r4Klm5gt2lDvRjgdNj", - "type": "arrow", - "x": 340.6667175292969, - "y": 406.66664123535156, - "width": 3.33331298828125, - "height": 41.33331298828125, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "aU", - "roundness": { - "type": 2 - }, - "seed": 661089148, - "version": 31, - "versionNonce": 1839327868, - "isDeleted": false, - "boundElements": null, - "updated": 1718070322633, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - -3.33331298828125, - 41.33331298828125 + 0, + 34.66668701171875 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 31, + "versionNonce": 1839327868, + "index": "aU", + "isDeleted": false, + "id": "Oy_r4Klm5gt2lDvRjgdNj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 340.6667175292969, + "y": 406.66664123535156, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 3.33331298828125, + "height": 41.33331298828125, + "seed": 661089148, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070322633, + "link": null, + "locked": false, "startBinding": { "elementId": "g8Kf1izRthcBqrUoNlbA5", "focus": 0.07233116710085088, @@ -1195,34 +1184,45 @@ "focus": -0.060512990174583205, "gap": 12.5339611174741 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -3.33331298828125, + 41.33331298828125 + ] + ] }, { - "id": "lW80FdUbsKFFMOLyAxSKR", "type": "arrow", - "x": 335.8001857666984, - "y": 570.1530407085518, - "width": 0.34165278590546677, - "height": 94.51366156195604, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", + "version": 87, + "versionNonce": 1483013628, + "index": "aV", + "isDeleted": false, + "id": "lW80FdUbsKFFMOLyAxSKR", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 335.8001857666984, + "y": 570.1530407085518, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 0.34165278590546677, + "height": 94.51366156195604, + "seed": 860781436, "groupIds": [], "frameId": null, - "index": "aV", "roundness": { "type": 2 }, - "seed": 860781436, - "version": 87, - "versionNonce": 1483013628, - "isDeleted": false, "boundElements": [ { "type": "text", @@ -1232,17 +1232,6 @@ "updated": 1718070548460, "link": null, "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.34165278590546677, - 94.51366156195604 - ] - ], - "lastCommittedPoint": null, "startBinding": { "elementId": "g9-8GSeIkp0vW_kZMseY_", "focus": 0.0403891467228266, @@ -1253,39 +1242,50 @@ "focus": -0.014457597382353414, "gap": 11.666702270507812 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -0.34165278590546677, + 94.51366156195604 + ] + ] }, { - "id": "H-8a2Qj78mNqHhMv4s66F", "type": "text", - "x": 321.929370054898, - "y": 604.9098714895298, - "width": 27.399978637695312, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 4, + "versionNonce": 180292860, + "index": "aVV", + "isDeleted": false, + "id": "H-8a2Qj78mNqHhMv4s66F", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 321.929370054898, + "y": 604.9098714895298, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 27.399978637695312, + "height": 25, + "seed": 2098883324, "groupIds": [], "frameId": null, - "index": "aVV", "roundness": null, - "seed": 2098883324, - "version": 4, - "versionNonce": 180292860, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718070547438, "link": null, "locked": false, - "text": "NO", "fontSize": 20, "fontFamily": 1, + "text": "NO", "textAlign": "center", "verticalAlign": "middle", "containerId": "lW80FdUbsKFFMOLyAxSKR", @@ -1294,45 +1294,34 @@ "lineHeight": 1.25 }, { - "id": "f3bpmwo_vCH7U0noLDDfg", "type": "arrow", - "x": 322.5860571265645, - "y": 720.0000152587891, - "width": 2.80302332155685, - "height": 49.99993896484375, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", + "version": 144, + "versionNonce": 150863100, + "index": "aW", + "isDeleted": false, + "id": "f3bpmwo_vCH7U0noLDDfg", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 322.5860571265645, + "y": 720.0000152587891, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 2.80302332155685, + "height": 49.99993896484375, + "seed": 250973052, "groupIds": [], "frameId": null, - "index": "aW", "roundness": { "type": 2 }, - "seed": 250973052, - "version": 144, - "versionNonce": 150863100, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718070540169, "link": null, "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 2.80302332155685, - 49.99993896484375 - ] - ], - "lastCommittedPoint": null, "startBinding": { "elementId": "ChMYpnJP73-IcK4rPOmP2", "focus": 0.1684979166726053, @@ -1343,34 +1332,45 @@ "focus": 0.027586411556604518, "gap": 3.666717529296875 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.80302332155685, + 49.99993896484375 + ] + ] }, { - "id": "peOkgTd3qx8MjdEPAwHLG", "type": "arrow", - "x": 538.5550904238726, - "y": 505.75210594777275, - "width": 440.1774733040993, - "height": 102.30624128392316, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", + "version": 360, + "versionNonce": 1378397508, + "index": "aX", + "isDeleted": false, + "id": "peOkgTd3qx8MjdEPAwHLG", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 538.5550904238726, + "y": 505.75210594777275, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 440.1774733040993, + "height": 102.30624128392316, + "seed": 497640956, "groupIds": [], "frameId": null, - "index": "aX", "roundness": { "type": 2 }, - "seed": 497640956, - "version": 360, - "versionNonce": 1378397508, - "isDeleted": false, "boundElements": [ { "type": "text", @@ -1380,17 +1380,6 @@ "updated": 1718070605137, "link": null, "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 440.1774733040993, - -102.30624128392316 - ] - ], - "lastCommittedPoint": null, "startBinding": { "elementId": "g9-8GSeIkp0vW_kZMseY_", "focus": 0.7744521975046411, @@ -1401,39 +1390,50 @@ "focus": 0.9267463929589432, "gap": 8.77320567787546 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 440.1774733040993, + -102.30624128392316 + ] + ] }, { - "id": "LR5MKymnabvQSo2fZJbvU", "type": "text", - "x": 740.6638389777777, - "y": 442.0989853058112, - "width": 35.95997619628906, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 5, + "versionNonce": 1123256316, + "index": "aXV", + "isDeleted": false, + "id": "LR5MKymnabvQSo2fZJbvU", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 740.6638389777777, + "y": 442.0989853058112, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 35.95997619628906, + "height": 25, + "seed": 249066876, "groupIds": [], "frameId": null, - "index": "aXV", "roundness": null, - "seed": 249066876, - "version": 5, - "versionNonce": 1123256316, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718070604117, "link": null, "locked": false, - "text": "YES", "fontSize": 20, "fontFamily": 1, + "text": "YES", "textAlign": "center", "verticalAlign": "middle", "containerId": "peOkgTd3qx8MjdEPAwHLG", @@ -1442,45 +1442,34 @@ "lineHeight": 1.25 }, { - "id": "Pq14NHJIb1TC_J8pmPjvr", "type": "arrow", - "x": 945.5749261622786, - "y": 565.27026552284, - "width": 186.42516539045573, - "height": 19.274707665674896, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", + "version": 257, + "versionNonce": 1674570436, + "index": "aZ", + "isDeleted": false, + "id": "Pq14NHJIb1TC_J8pmPjvr", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 945.5749261622786, + "y": 565.27026552284, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 186.42516539045573, + "height": 19.274707665674896, + "seed": 857229052, "groupIds": [], "frameId": null, - "index": "aZ", "roundness": { "type": 2 }, - "seed": 857229052, - "version": 257, - "versionNonce": 1674570436, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718070600148, "link": null, "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 186.42516539045573, - -19.274707665674896 - ] - ], - "lastCommittedPoint": null, "startBinding": { "elementId": "1mHFxB9ztEJIoiT7qlB96", "focus": -0.13451402411290317, @@ -1491,49 +1480,49 @@ "focus": -0.00004553043522623549, "gap": 6.6665496826171875 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "Op3-0vLWCxnne2RBT6xi6", - "type": "arrow", - "x": 1153.3334045410156, - "y": 555.3332672119141, - "width": 126.66665649414062, - "height": 110.66665649414062, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "ae", - "roundness": { - "type": 2 - }, - "seed": 385859908, - "version": 38, - "versionNonce": 367683268, - "isDeleted": false, - "boundElements": null, - "updated": 1718070456386, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - -126.66665649414062, - 110.66665649414062 + 186.42516539045573, + -19.274707665674896 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 38, + "versionNonce": 367683268, + "index": "ae", + "isDeleted": false, + "id": "Op3-0vLWCxnne2RBT6xi6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1153.3334045410156, + "y": 555.3332672119141, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 126.66665649414062, + "height": 110.66665649414062, + "seed": 385859908, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070456386, + "link": null, + "locked": false, "startBinding": { "elementId": "Lj6BzDEByQki5S-EgwpMH", "focus": 0.6674665434007476, @@ -1544,49 +1533,49 @@ "focus": -0.56170540081211, "gap": 8.500030517578125 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "BxnDm2GPRo19a3p7ctAJl", - "type": "arrow", - "x": 1267.3334350585938, - "y": 557.9999237060547, - "width": 56, - "height": 108, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "af", - "roundness": { - "type": 2 - }, - "seed": 1070237124, - "version": 45, - "versionNonce": 2135977924, - "isDeleted": false, - "boundElements": null, - "updated": 1718070461942, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - -56, - 108 + -126.66665649414062, + 110.66665649414062 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 45, + "versionNonce": 2135977924, + "index": "af", + "isDeleted": false, + "id": "BxnDm2GPRo19a3p7ctAJl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1267.3334350585938, + "y": 557.9999237060547, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 56, + "height": 108, + "seed": 1070237124, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070461942, + "link": null, + "locked": false, "startBinding": { "elementId": "Lj6BzDEByQki5S-EgwpMH", "focus": 0.2784226011380055, @@ -1597,49 +1586,49 @@ "focus": -0.19838487694747556, "gap": 7.660033810812138 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "Hx5RRKsheyWep1sDvpIRJ", - "type": "arrow", - "x": 1410.0000610351562, - "y": 557.9999237060547, - "width": 6.66668701171875, - "height": 91.33334350585938, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "ag", - "roundness": { - "type": 2 - }, - "seed": 1812090564, - "version": 37, - "versionNonce": 372948164, - "isDeleted": false, - "boundElements": null, - "updated": 1718070464306, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - 6.66668701171875, - 91.33334350585938 + -56, + 108 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 37, + "versionNonce": 372948164, + "index": "ag", + "isDeleted": false, + "id": "Hx5RRKsheyWep1sDvpIRJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1410.0000610351562, + "y": 557.9999237060547, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 6.66668701171875, + "height": 91.33334350585938, + "seed": 1812090564, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070464306, + "link": null, + "locked": false, "startBinding": { "elementId": "Lj6BzDEByQki5S-EgwpMH", "focus": -0.29210766608336375, @@ -1650,49 +1639,49 @@ "focus": -0.08919478710809753, "gap": 11.219570140634687 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "MQg59W36CWAt6YFU4SATI", - "type": "arrow", - "x": 1515.3334350585938, - "y": 555.9999237060547, - "width": 111.33331298828125, - "height": 90, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#e9ecef", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "ah", - "roundness": { - "type": 2 - }, - "seed": 477977540, - "version": 66, - "versionNonce": 1870734148, - "isDeleted": false, - "boundElements": null, - "updated": 1718070467099, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - 111.33331298828125, - 90 + 6.66668701171875, + 91.33334350585938 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 66, + "versionNonce": 1870734148, + "index": "ah", + "isDeleted": false, + "id": "MQg59W36CWAt6YFU4SATI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1515.3334350585938, + "y": 555.9999237060547, + "strokeColor": "#1e1e1e", + "backgroundColor": "#e9ecef", + "width": 111.33331298828125, + "height": 90, + "seed": 477977540, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070467099, + "link": null, + "locked": false, "startBinding": { "elementId": "Lj6BzDEByQki5S-EgwpMH", "focus": -0.5443679842464036, @@ -1703,34 +1692,45 @@ "focus": 0.28071605903977087, "gap": 12.942412364274333 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 111.33331298828125, + 90 + ] + ] }, { - "id": "afJRKHUH-3-DOo_qsIQTl", "type": "rectangle", - "x": 553.0000305175781, - "y": 311.33326721191406, - "width": 1223.3334655761719, - "height": 476.66668701171875, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 196, + "versionNonce": 1990172540, + "index": "ai", + "isDeleted": false, + "id": "afJRKHUH-3-DOo_qsIQTl", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "dashed", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 553.0000305175781, + "y": 311.33326721191406, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1223.3334655761719, + "height": 476.66668701171875, + "seed": 197202940, "groupIds": [], "frameId": null, - "index": "ai", "roundness": { "type": 3 }, - "seed": 197202940, - "version": 196, - "versionNonce": 1990172540, - "isDeleted": false, "boundElements": [ { "id": "xeVswQuTAgd1A2Kuq9lGG", @@ -1742,45 +1742,34 @@ "locked": false }, { - "id": "xeVswQuTAgd1A2Kuq9lGG", "type": "arrow", - "x": 528.0001220703124, - "y": 704.2098645909149, - "width": 88.00006103515614, - "height": 0.6925758232049475, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", + "version": 128, + "versionNonce": 1056684540, + "index": "aj", + "isDeleted": false, + "id": "xeVswQuTAgd1A2Kuq9lGG", "fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid", "roughness": 1, "opacity": 100, + "angle": 0, + "x": 528.0001220703124, + "y": 704.2098645909149, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 88.00006103515614, + "height": 0.6925758232049475, + "seed": 1420408516, "groupIds": [], "frameId": null, - "index": "aj", "roundness": { "type": 2 }, - "seed": 1420408516, - "version": 128, - "versionNonce": 1056684540, - "isDeleted": false, - "boundElements": null, + "boundElements": [], "updated": 1718070544911, "link": null, "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -88.00006103515614, - -0.6925758232049475 - ] - ], - "lastCommittedPoint": null, "startBinding": { "elementId": "afJRKHUH-3-DOo_qsIQTl", "focus": -0.6562028563598121, @@ -1791,49 +1780,49 @@ "focus": 0.42191535777722355, "gap": 12.333358764648438 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "Iz0Gac6daA5IVmdtIyOtD", - "type": "arrow", - "x": 1144.6505838250034, - "y": 433.32774544878237, - "width": 307.59065695281106, - "height": 123.00555228070982, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "ak", - "roundness": { - "type": 2 - }, - "seed": 1717906556, - "version": 476, - "versionNonce": 757008836, - "isDeleted": false, - "boundElements": null, - "updated": 1718070600148, - "link": null, - "locked": false, + "endArrowhead": "arrow", "points": [ [ 0, 0 ], [ - -307.59065695281106, - 123.00555228070982 + -88.00006103515614, + -0.6925758232049475 ] - ], - "lastCommittedPoint": null, + ] + }, + { + "type": "arrow", + "version": 476, + "versionNonce": 757008836, + "index": "ak", + "isDeleted": false, + "id": "Iz0Gac6daA5IVmdtIyOtD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1144.6505838250034, + "y": 433.32774544878237, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 307.59065695281106, + "height": 123.00555228070982, + "seed": 1717906556, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1718070600148, + "link": null, + "locked": false, "startBinding": { "elementId": "-CgiS2KzLNAWgCeskHf3s", "focus": 0.0021142989278789353, @@ -1844,8 +1833,86 @@ "focus": -0.044830342563112094, "gap": 10.33331298828125 }, + "lastCommittedPoint": null, "startArrowhead": null, - "endArrowhead": "arrow" + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -307.59065695281106, + 123.00555228070982 + ] + ] + }, + { + "type": "rectangle", + "version": 574, + "versionNonce": 542107186, + "index": "al", + "isDeleted": false, + "id": "9jaerfFJFWwBfNfcaNX1j", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 890.7144355773926, + "y": 115.28056026762181, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 473.90477752685547, + "height": 169.58440900427027, + "seed": 349984622, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1721869125195, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1017, + "versionNonce": 1716749127, + "index": "am", + "isDeleted": false, + "id": "wQoJDMf-TEll1eClNIG4q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 908.5033930234741, + "y": 138.26176619998978, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 437.8729370696015, + "height": 133.09364599014955, + "seed": 846936494, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721869282360, + "link": null, + "locked": false, + "fontSize": 21.294983358423927, + "fontFamily": 1, + "text": "1. configs.xlsx\n2. reach33_制动性能测试.xlsx\n3. reach66_制动性能测试.xlsx\n4. reach100_制动性能测试.xlsx\n5. 数据文件夹", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "1. configs.xlsx\n2. reach33_制动性能测试.xlsx\n3. reach66_制动性能测试.xlsx\n4. reach100_制动性能测试.xlsx\n5. 数据文件夹", + "autoResize": false, + "lineHeight": 1.25 } ], "appState": { diff --git a/aio/assets/workflow/do_brake.excalidraw b/aio/assets/workflow/do_brake.excalidraw new file mode 100644 index 0000000..bf2d905 --- /dev/null +++ b/aio/assets/workflow/do_brake.excalidraw @@ -0,0 +1,2584 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "http://10.2.23.150:10020", + "elements": [ + { + "type": "rectangle", + "version": 118, + "versionNonce": 1360105599, + "index": "a0", + "isDeleted": false, + "id": "G7GvfRyoquBz-CKotoH2E", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 83.4285888671875, + "y": -67.33507537841797, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 122.07794189453125, + "height": 49.35063934326172, + "seed": 760702512, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "CBAHPncOXHa_pJUrlM-O2" + }, + { + "id": "sVTpXJGfJ64bteP_k-FEb", + "type": "arrow" + } + ], + "updated": 1719982447630, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 105, + "versionNonce": 988073259, + "index": "a1", + "isDeleted": false, + "id": "CBAHPncOXHa_pJUrlM-O2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 124.46755981445312, + "y": -55.15975570678711, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 25, + "seed": 1658646736, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "开始", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "G7GvfRyoquBz-CKotoH2E", + "originalText": "开始", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 319, + "versionNonce": 1561553193, + "index": "a4", + "isDeleted": false, + "id": "IHIeSs49oqr0TLYPMSk6V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -444.6597213745117, + "y": -39.483978271484375, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 363.9048080444336, + "height": 135.13058797604788, + "seed": 1067092528, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1721869549899, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 646, + "versionNonce": 616064551, + "index": "a8", + "isDeleted": false, + "id": "ZEgbGldzHFnQJBlIGHlcm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -421.2506154221511, + "y": -25.537706112166845, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 331.6304725415214, + "height": 111.38025069352125, + "seed": 1086242000, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721869581117, + "link": null, + "locked": false, + "fontSize": 17.820840110963402, + "fontFamily": 1, + "text": "1. configs.xlsx\n2. 工程文件\n3. reach33_制动性能测试.xlsx \n4. reach66_制动性能测试.xlsx\n5. reach100_制动性能测试.xlsx", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "1. configs.xlsx\n2. 工程文件\n3. reach33_制动性能测试.xlsx \n4. reach66_制动性能测试.xlsx\n5. reach100_制动性能测试.xlsx", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "type": "diamond", + "version": 158, + "versionNonce": 684273585, + "index": "aA", + "isDeleted": false, + "id": "RwMIreS0QkAZwm-3ulGX-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 24.051910400390625, + "y": 40.48309326171875, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 257.5999755859375, + "height": 100, + "seed": 51082257, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "iNY8dtUFmWKoMwFFsArGd" + }, + { + "id": "cdPz-GgAqgjIqgTPRVFw-", + "type": "arrow" + }, + { + "id": "vRciE0DKBJzJ8v7fA54Kq", + "type": "arrow" + }, + { + "id": "sVTpXJGfJ64bteP_k-FEb", + "type": "arrow" + } + ], + "updated": 1719982450560, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 214, + "versionNonce": 1388834763, + "index": "aAV", + "isDeleted": false, + "id": "iNY8dtUFmWKoMwFFsArGd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 96.951904296875, + "y": 70.48309326171875, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 112, + "height": 40, + "seed": 1500869361, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "检查输入文件是\n否正确", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "RwMIreS0QkAZwm-3ulGX-", + "originalText": "检查输入文件是否正确", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 243, + "versionNonce": 469737771, + "index": "aC", + "isDeleted": false, + "id": "Kf1iK8aKtz3dLPTOYumTw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 501.41290283203125, + "y": -67.3922233581543, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 122.07794189453125, + "height": 49.35063934326172, + "seed": 179980831, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "VuHEUguk0rq5mHifBtniS" + }, + { + "id": "cdPz-GgAqgjIqgTPRVFw-", + "type": "arrow" + }, + { + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "type": "arrow" + } + ], + "updated": 1719982544519, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 234, + "versionNonce": 298321509, + "index": "aD", + "isDeleted": false, + "id": "VuHEUguk0rq5mHifBtniS", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 542.4518737792969, + "y": -55.21690368652344, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 25, + "seed": 1648995903, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "结束", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Kf1iK8aKtz3dLPTOYumTw", + "originalText": "结束", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 159, + "versionNonce": 12219423, + "index": "aH", + "isDeleted": false, + "id": "cdPz-GgAqgjIqgTPRVFw-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 264.76445650455105, + "y": 66.83925419197496, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 228.08738065365208, + "height": 99.95610599861558, + "seed": 339189983, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "82DP34j9Ep7573KCrZFuj" + } + ], + "updated": 1719982450562, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RwMIreS0QkAZwm-3ulGX-", + "focus": 0.6262400211589412, + "gap": 15.929954945665216 + }, + "endBinding": { + "elementId": "Kf1iK8aKtz3dLPTOYumTw", + "focus": 0.05115605003902535, + "gap": 8.561065673828125 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 105.68741727474583, + -79.95610599861558 + ], + [ + 228.08738065365208, + -99.95610599861558 + ] + ] + }, + { + "type": "text", + "version": 8, + "versionNonce": 1399701099, + "index": "aHV", + "isDeleted": false, + "id": "82DP34j9Ep7573KCrZFuj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 353.6798782348633, + "y": -30.616851806640625, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 33.54399108886719, + "height": 35, + "seed": 830879743, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "No", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cdPz-GgAqgjIqgTPRVFw-", + "originalText": "No", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 854, + "versionNonce": 1920767149, + "index": "aI", + "isDeleted": false, + "id": "OuZBPxPXuTv9FpsBMA2am", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -165.81548239968015, + "y": 442.3411075707638, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 215.67791748046875, + "height": 59.75057220458983, + "seed": 1897362833, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "QclqBhwtyuV2bEYeF_-0N" + }, + { + "id": "M3h-oZVLWQYI4EBdoYQJZ", + "type": "arrow" + } + ], + "updated": 1721953748956, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 876, + "versionNonce": 1295453549, + "index": "aJ", + "isDeleted": false, + "id": "QclqBhwtyuV2bEYeF_-0N", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -145.34649588844968, + "y": 459.71639367305875, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 174.7399444580078, + "height": 25, + "seed": 1385470833, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748956, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "将工程拷贝到xCore", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "OuZBPxPXuTv9FpsBMA2am", + "originalText": "将工程拷贝到xCore", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 382, + "versionNonce": 125241767, + "index": "aM", + "isDeleted": false, + "id": "vRciE0DKBJzJ8v7fA54Kq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 39.23397594216637, + "y": 109.3432557213118, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 151.79356560097065, + "height": 65.64894981180257, + "seed": 546610591, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "PfWkxzSRM6swE3zdpo__p" + } + ], + "updated": 1721870178253, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RwMIreS0QkAZwm-3ulGX-", + "focus": 0.544981318869258, + "gap": 12.087656934222672 + }, + "endBinding": { + "elementId": "fE8mp1oZAZIS-9AiqeeBo", + "focus": -0.3863495053337668, + "gap": 11.323810577392578 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -151.79356560097065, + 65.64894981180257 + ] + ] + }, + { + "type": "text", + "version": 6, + "versionNonce": 1804967499, + "index": "aMV", + "isDeleted": false, + "id": "PfWkxzSRM6swE3zdpo__p", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -58.280842315198406, + "y": 175.46232887218298, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 32.119964599609375, + "height": 25, + "seed": 1690013765, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982657566, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Yes", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "vRciE0DKBJzJ8v7fA54Kq", + "originalText": "Yes", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2061, + "versionNonce": 87686733, + "index": "aN", + "isDeleted": false, + "id": "M3h-oZVLWQYI4EBdoYQJZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -75.23170918127317, + "y": 513.0527698632443, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 103.33305926819273, + "height": 225.81833509965384, + "seed": 265077663, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721953749039, + "link": null, + "locked": false, + "startBinding": { + "elementId": "OuZBPxPXuTv9FpsBMA2am", + "focus": -0.011779183463357037, + "gap": 10.961090087890625 + }, + "endBinding": { + "elementId": "1bP6Dvn7AZ9RH4DrcRdB_", + "focus": -0.6210473590710341, + "gap": 21.64673979938243 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -103.33305926819273, + 225.81833509965384 + ] + ] + }, + { + "type": "rectangle", + "version": 1053, + "versionNonce": 951735853, + "index": "aO", + "isDeleted": false, + "id": "tRrOZ-dVRENzlkE2D7JiN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 98.2571716308596, + "y": 822.7412554423014, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 215.67791748046875, + "height": 50.20001220703125, + "seed": 1924605105, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "sMJglKTmK18wBh571qiFL" + }, + { + "id": "abhTOT48fVbhcaD6SFRLd", + "type": "arrow" + }, + { + "id": "NmxfcTzxuWNJwo4Wb-4Ga", + "type": "arrow" + }, + { + "id": "n3hZ2B8KLeQUTZ8vlZwpw", + "type": "arrow" + }, + { + "id": "OZF5-sHGF1QWh4D33VwKx", + "type": "arrow" + } + ], + "updated": 1721953748956, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1101, + "versionNonce": 2015365453, + "index": "aP", + "isDeleted": false, + "id": "sMJglKTmK18wBh571qiFL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 126.09613037109398, + "y": 835.341261545817, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 160, + "height": 25, + "seed": 1588684433, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748956, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "修改要执行的场景", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tRrOZ-dVRENzlkE2D7JiN", + "originalText": "修改要执行的场景", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1572, + "versionNonce": 793466797, + "index": "aX", + "isDeleted": false, + "id": "wsKk3rGTn1F-L5FxrCX5H", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 400.48233395475904, + "y": 636.3089837328594, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 205.2779541015625, + "height": 60, + "seed": 804808927, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Ybc-XtdsXVulj0EsjVQG3" + }, + { + "id": "F-gcNIPiBPo5bXyhvYKAd", + "type": "arrow" + }, + { + "id": "ZDRN9BNAFSm7MPd4mQItT", + "type": "arrow" + }, + { + "id": "_0vJdrVWw6yxiSmedBCz_", + "type": "arrow" + } + ], + "updated": 1721953748956, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 974, + "versionNonce": 1932425933, + "index": "aY", + "isDeleted": false, + "id": "Ybc-XtdsXVulj0EsjVQG3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 407.1213110055403, + "y": 646.3089837328594, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 192, + "height": 40, + "seed": 1607857407, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748956, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "计算出初始实际百分比速度\n,并发送给RL程序", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "wsKk3rGTn1F-L5FxrCX5H", + "originalText": "计算出初始实际百分比速度,并发送给RL程序", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1528, + "versionNonce": 1922013485, + "index": "aZ", + "isDeleted": false, + "id": "2ysxvHdQkJy90WXrs-fCv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 644.2574768066409, + "y": 459.71647135416663, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 213.2778930664063, + "height": 65, + "seed": 958808895, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "o7Ntq3Q62WL2u4scU9yxN" + }, + { + "id": "ZDRN9BNAFSm7MPd4mQItT", + "type": "arrow" + }, + { + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "type": "arrow" + }, + { + "id": "oxtHFkwF4Nb6F5sLpb7qO", + "type": "arrow" + }, + { + "id": "i_UW5iv9D7BQ4VakeukH-", + "type": "arrow" + } + ], + "updated": 1721953748956, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 957, + "versionNonce": 414723149, + "index": "aa", + "isDeleted": false, + "id": "o7Ntq3Q62WL2u4scU9yxN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 649.2574768066409, + "y": 472.21647135416663, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 196.43199157714844, + "height": 40, + "seed": 253330271, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748956, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "一定时间后给RL发送探测速\n度,并触发急停的信号", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "2ysxvHdQkJy90WXrs-fCv", + "originalText": "一定时间后给RL发送探测速度,并触发急停的信号", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1564, + "versionNonce": 564039437, + "index": "ac", + "isDeleted": false, + "id": "abhTOT48fVbhcaD6SFRLd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -70.50241563547328, + "y": 745.8669172119696, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 103.82900501690897, + "height": 59.524883796566996, + "seed": 206954833, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721953749039, + "link": null, + "locked": false, + "startBinding": { + "elementId": "1bP6Dvn7AZ9RH4DrcRdB_", + "focus": -0.3325149350347292, + "gap": 14.65092755031094 + }, + "endBinding": { + "elementId": "s5GqtSw8Y7CZeicUEgwFQ", + "focus": 0.4870837538738663, + "gap": 15.02048596085718 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 103.82900501690897, + -59.524883796566996 + ] + ] + }, + { + "type": "arrow", + "version": 1859, + "versionNonce": 1294331853, + "index": "ad", + "isDeleted": false, + "id": "NmxfcTzxuWNJwo4Wb-4Ga", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 198.0714319972467, + "y": 705.7894871646519, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 0.3716766338358184, + "height": 104.05308996359054, + "seed": 800156593, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "igjHqsZem0xmaAEzzrC-o" + } + ], + "updated": 1721953749039, + "link": null, + "locked": false, + "startBinding": { + "elementId": "s5GqtSw8Y7CZeicUEgwFQ", + "focus": -0.42034523098090276, + "gap": 17.88140725456001 + }, + "endBinding": { + "elementId": "tRrOZ-dVRENzlkE2D7JiN", + "focus": -0.06965058113267497, + "gap": 12.898678314058998 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0.3716766338358184, + 104.05308996359054 + ] + ] + }, + { + "id": "igjHqsZem0xmaAEzzrC-o", + "type": "text", + "x": 116.99028419441666, + "y": 746.1622472671509, + "width": 32.119964599609375, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "adV", + "roundness": null, + "seed": 1462410797, + "version": 72, + "versionNonce": 691540845, + "isDeleted": false, + "boundElements": null, + "updated": 1721953748956, + "link": null, + "locked": false, + "text": "Yes", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "NmxfcTzxuWNJwo4Wb-4Ga", + "originalText": "Yes", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2324, + "versionNonce": 425468045, + "index": "ae", + "isDeleted": false, + "id": "F-gcNIPiBPo5bXyhvYKAd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 180.74214250816976, + "y": 600.1157827263543, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 103.03265362341904, + "height": 59.18351840116395, + "seed": 1246004785, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "-R5RuT2t2buAlh5vWdrju" + } + ], + "updated": 1721953749039, + "link": null, + "locked": false, + "startBinding": { + "elementId": "s5GqtSw8Y7CZeicUEgwFQ", + "focus": -0.5168038068485948, + "gap": 14.027635503254452 + }, + "endBinding": { + "elementId": "_MfULWHYB1BylU7H_Os8K", + "focus": 0.03862755846941249, + "gap": 10.200041205976277 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 103.03265362341904, + -59.18351840116395 + ] + ] + }, + { + "id": "-R5RuT2t2buAlh5vWdrju", + "type": "text", + "x": 130.42687385646795, + "y": 531.2571956080915, + "width": 23.959976196289062, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aeV", + "roundness": null, + "seed": 1158134605, + "version": 68, + "versionNonce": 1622268973, + "isDeleted": false, + "boundElements": null, + "updated": 1721953748956, + "link": null, + "locked": false, + "text": "No", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "F-gcNIPiBPo5bXyhvYKAd", + "originalText": "No", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2103, + "versionNonce": 617423181, + "index": "af", + "isDeleted": false, + "id": "ZDRN9BNAFSm7MPd4mQItT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 573.6586860875127, + "y": 802.5091180102031, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 72.0303430507422, + "height": 93.89254594802867, + "seed": 1918402865, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721953749039, + "link": null, + "locked": false, + "startBinding": { + "elementId": "X5t5PlDvqNsMmmYnCxtAV", + "focus": 0.4398310501257054, + "gap": 9.623144781862493 + }, + "endBinding": { + "elementId": "wsKk3rGTn1F-L5FxrCX5H", + "focus": 0.27018337696103994, + "gap": 12.307588329315081 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -72.0303430507422, + -93.89254594802867 + ] + ] + }, + { + "type": "arrow", + "version": 23, + "versionNonce": 977005727, + "index": "ah", + "isDeleted": false, + "id": "sVTpXJGfJ64bteP_k-FEb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 150.45187377929688, + "y": -11.516876220703121, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 0.804804176492155, + "height": 41.8504465544745, + "seed": 445992479, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982450563, + "link": null, + "locked": false, + "startBinding": { + "elementId": "G7GvfRyoquBz-CKotoH2E", + "focus": -0.08754862573962541, + "gap": 6.467559814453125 + }, + "endBinding": { + "elementId": "RwMIreS0QkAZwm-3ulGX-", + "focus": -0.00340462795005759, + "gap": 10.274120072847268 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0.804804176492155, + 41.8504465544745 + ] + ] + }, + { + "type": "arrow", + "version": 3419, + "versionNonce": 1527050765, + "index": "aj", + "isDeleted": false, + "id": "_0vJdrVWw6yxiSmedBCz_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 460.1257658440753, + "y": 621.9596405497533, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 44.84476985950141, + "height": 78.1277508427305, + "seed": 929888657, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721953749039, + "link": null, + "locked": false, + "startBinding": { + "elementId": "wsKk3rGTn1F-L5FxrCX5H", + "focus": -0.1463333945517566, + "gap": 14.349343183106043 + }, + "endBinding": { + "elementId": "_MfULWHYB1BylU7H_Os8K", + "focus": -0.07123248806256179, + "gap": 13.09966658780877 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -44.84476985950141, + -78.1277508427305 + ] + ] + }, + { + "type": "arrow", + "version": 1776, + "versionNonce": 859938829, + "index": "am", + "isDeleted": false, + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 715.4133378842915, + "y": 313.53311157226574, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "width": 120.65030687843216, + "height": 317.84999084472656, + "seed": 1006891467, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "3NfVy3o0TIZLU7DXhNStB" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RhNNRTMdDvRCBisjoMESc", + "gap": 12.207172393798714, + "focus": 0.7414822248073476 + }, + "endBinding": { + "elementId": "Kf1iK8aKtz3dLPTOYumTw", + "gap": 13.724704742431754, + "focus": -0.252643325157541 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -119.0926756318396, + -72.51660156250011 + ], + [ + -90.10232884919162, + -173.45002237955737 + ], + [ + -95.28829671118365, + -250.8277664184572 + ], + [ + -120.65030687843216, + -317.84999084472656 + ] + ] + }, + { + "type": "text", + "version": 38, + "versionNonce": 857285347, + "index": "an", + "isDeleted": false, + "id": "3NfVy3o0TIZLU7DXhNStB", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 535.3110090350999, + "y": 127.58308919270837, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "width": 180, + "height": 25, + "seed": 438263077, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953587877, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "当所有场景采集完毕", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "E6Z8Wh6Av-c4t5msk3j0Z", + "originalText": "当所有场景采集完毕", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 974, + "versionNonce": 1564223753, + "index": "ao", + "isDeleted": false, + "id": "fE8mp1oZAZIS-9AiqeeBo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -228.231968272816, + "y": 186.31601611050695, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 173.2778930664062, + "height": 51.20001220703126, + "seed": 1690892521, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "URnwpIH42id9TLrEgAKAc", + "type": "text" + }, + { + "id": "vRciE0DKBJzJ8v7fA54Kq", + "type": "arrow" + }, + { + "id": "ERVoVoW-V8G1LL-vWEqN3", + "type": "arrow" + } + ], + "updated": 1721870191012, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 338, + "versionNonce": 668890983, + "index": "ap", + "isDeleted": false, + "id": "URnwpIH42id9TLrEgAKAc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -191.5930217396129, + "y": 199.41602221402258, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 100, + "height": 25, + "seed": 954987465, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721870178253, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "初始化配置", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "fE8mp1oZAZIS-9AiqeeBo", + "originalText": "初始化配置", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "line", + "version": 57, + "versionNonce": 1599341575, + "index": "aq", + "isDeleted": false, + "id": "YzZ_B9eP3UNLuRQzxEz4x", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 75.80097961425781, + "y": 61.673587799072266, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 154.00003051757812, + "height": 38, + "seed": 1175702567, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721869555973, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + -154.00003051757812, + -38 + ] + ] + }, + { + "type": "rectangle", + "version": 481, + "versionNonce": 2134832871, + "index": "ar", + "isDeleted": false, + "id": "NSJU9ml7UOh2MWb9fExSu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -850.8181571960449, + "y": 191.44166783448583, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 453.90482330322266, + "height": 82.46393148190725, + "seed": 1137221705, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1721869844132, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1360, + "versionNonce": 976060935, + "index": "as", + "isDeleted": false, + "id": "d2lyYLFFOcXxKL1kEPa3Y", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -843.0139320364582, + "y": 209.3167754405929, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 460.2965103131508, + "height": 50.96150002548767, + "seed": 1614039143, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721869844132, + "link": null, + "locked": false, + "fontSize": 13.589733340130044, + "fontFamily": 1, + "text": "1. 按照轴,创建结果数据文件夹\n2. 从configs.xlsx获取额定电流/转速/减速比/角速度/急停正负方向等信息\n3. 设定要采集的曲线信息", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "1. 按照轴,创建结果数据文件夹\n2. 从configs.xlsx获取额定电流/转速/减速比/角速度/急停正负方向等信息\n3. 设定要采集的曲线信息", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "type": "line", + "version": 103, + "versionNonce": 999870377, + "index": "at", + "isDeleted": false, + "id": "sjHa4K8Z8gwgIP5xf65hb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -241.4111619429155, + "y": 216.03721583973274, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 151.51510620117188, + "height": 10.303028453480152, + "seed": 478500679, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721870183261, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + -151.51510620117188, + 10.303028453480152 + ] + ] + }, + { + "type": "rectangle", + "version": 362, + "versionNonce": 1421692749, + "index": "au", + "isDeleted": false, + "id": "RhNNRTMdDvRCBisjoMESc", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "angle": 0, + "x": -340.8656463623047, + "y": 325.74028396606445, + "strokeColor": "#1971c2", + "backgroundColor": "transparent", + "width": 1398.160536619082, + "height": 664.7333984375, + "seed": 124878665, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "type": "arrow" + }, + { + "id": "ERVoVoW-V8G1LL-vWEqN3", + "type": "arrow" + } + ], + "updated": 1721953748956, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 242, + "versionNonce": 639704877, + "index": "av", + "isDeleted": false, + "id": "8LPZT3Re_9ys2AorxAlQT", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "angle": 0, + "x": -36.7990264892577, + "y": 377.4513486226401, + "strokeColor": "#f08c00", + "backgroundColor": "transparent", + "width": 700, + "height": 32.199999999999996, + "seed": 1415660551, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 2, + "text": "按照测试条件、轴的排组顺序循环执行三次制动测试操作", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "按照测试条件、轴的排组顺序循环执行三次制动测试操作", + "autoResize": true, + "lineHeight": 1.15 + }, + { + "type": "arrow", + "version": 480, + "versionNonce": 1811464397, + "index": "aw", + "isDeleted": false, + "id": "ERVoVoW-V8G1LL-vWEqN3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -150.6257794438431, + "y": 244.68703618675778, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 2.0674651584769776, + "height": 60.24850325150925, + "seed": 1089758057, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "startBinding": { + "elementId": "fE8mp1oZAZIS-9AiqeeBo", + "gap": 7.171007869219579, + "focus": 0.11603486920476935 + }, + "endBinding": { + "elementId": "RhNNRTMdDvRCBisjoMESc", + "gap": 20.804744527797425, + "focus": -0.6962190492310062 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.0674651584769776, + 60.24850325150925 + ] + ] + }, + { + "type": "rectangle", + "version": 586, + "versionNonce": 208581005, + "index": "b04", + "isDeleted": false, + "id": "1bP6Dvn7AZ9RH4DrcRdB_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -240.22863976545636, + "y": 760.5178447622806, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 216.68566894531247, + "height": 123.42863464355466, + "seed": 1189329091, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "8sT7N39cN5FWtgjD0BEwQ" + }, + { + "id": "M3h-oZVLWQYI4EBdoYQJZ", + "type": "arrow" + }, + { + "id": "abhTOT48fVbhcaD6SFRLd", + "type": "arrow" + }, + { + "id": "dUxT3co8677f2AaonmyE4", + "type": "arrow" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 694, + "versionNonce": 1002898189, + "index": "b05", + "isDeleted": false, + "id": "8sT7N39cN5FWtgjD0BEwQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -235.22863976545636, + "y": 772.2321620840579, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 192, + "height": 100, + "seed": 1813358691, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "初始化:\n触发/解除急停\n清除伺服告警\n重置act信号\n处理可能的安全告警写诊断", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "1bP6Dvn7AZ9RH4DrcRdB_", + "originalText": "初始化:\n触发/解除急停\n清除伺服告警\n重置act信号\n处理可能的安全告警写诊断", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1272, + "versionNonce": 1600985453, + "index": "b06", + "isDeleted": false, + "id": "X5t5PlDvqNsMmmYnCxtAV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 415.075406865403, + "y": 812.1322627920656, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 253.27795410156253, + "height": 76.19992065429686, + "seed": 578301219, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "GG_qcjEkAW1tNOEYADGUw" + }, + { + "id": "OZF5-sHGF1QWh4D33VwKx", + "type": "arrow" + }, + { + "id": "ZDRN9BNAFSm7MPd4mQItT", + "type": "arrow" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1311, + "versionNonce": 833262733, + "index": "b07", + "isDeleted": false, + "id": "GG_qcjEkAW1tNOEYADGUw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 420.075406865403, + "y": 825.232223119214, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 234.27987670898438, + "height": 50, + "seed": 1507627203, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "reload工程后,pp2main,\n并且自动模式和上电", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "X5t5PlDvqNsMmmYnCxtAV", + "originalText": "reload工程后,pp2main,并且自动模式和上电", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "diamond", + "version": 978, + "versionNonce": 1172470509, + "index": "b08", + "isDeleted": false, + "id": "s5GqtSw8Y7CZeicUEgwFQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -8.140500193287608, + "y": 598.232223119214, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 290.1094264220687, + "height": 112, + "seed": 1853709763, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "g2NPSQBb5tSbr96V0GxNs" + }, + { + "id": "NmxfcTzxuWNJwo4Wb-4Ga", + "type": "arrow" + }, + { + "id": "abhTOT48fVbhcaD6SFRLd", + "type": "arrow" + }, + { + "id": "F-gcNIPiBPo5bXyhvYKAd", + "type": "arrow" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 741, + "versionNonce": 869997677, + "index": "b09", + "isDeleted": false, + "id": "g2NPSQBb5tSbr96V0GxNs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 76.88685641222956, + "y": 631.232223119214, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 120, + "height": 46, + "seed": 456306019, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 2, + "text": "是否为单条件\n第一次执行", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "s5GqtSw8Y7CZeicUEgwFQ", + "originalText": "是否为单条件第一次执行", + "autoResize": true, + "lineHeight": 1.15 + }, + { + "id": "OZF5-sHGF1QWh4D33VwKx", + "type": "arrow", + "x": 326.5141886036843, + "y": 844.5501604905674, + "width": 77.60009765624994, + "height": 0.2532809215430234, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0A", + "roundness": { + "type": 2 + }, + "seed": 1655164131, + "version": 721, + "versionNonce": 881824461, + "isDeleted": false, + "boundElements": null, + "updated": 1721953749040, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 77.60009765624994, + -0.2532809215430234 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "tRrOZ-dVRENzlkE2D7JiN", + "focus": -0.11386402972067605, + "gap": 12.579099492355965 + }, + "endBinding": { + "elementId": "X5t5PlDvqNsMmmYnCxtAV", + "focus": 0.16577286050644777, + "gap": 10.96112060546875 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "rectangle", + "version": 1452, + "versionNonce": 1122411821, + "index": "b0B", + "isDeleted": false, + "id": "_MfULWHYB1BylU7H_Os8K", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 248.67519934587176, + "y": 454.53230246491717, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 253.27795410156253, + "height": 76.19992065429686, + "seed": 339935149, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "RmXSyd3GuCSg-wa9sJf2b" + }, + { + "id": "F-gcNIPiBPo5bXyhvYKAd", + "type": "arrow" + }, + { + "id": "_0vJdrVWw6yxiSmedBCz_", + "type": "arrow" + }, + { + "id": "oxtHFkwF4Nb6F5sLpb7qO", + "type": "arrow" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1488, + "versionNonce": 1163404973, + "index": "b0C", + "isDeleted": false, + "id": "RmXSyd3GuCSg-wa9sJf2b", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 253.67519934587176, + "y": 467.6322627920656, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 234.27987670898438, + "height": 50, + "seed": 209748493, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "reload工程后,pp2main,\n并且自动模式和上电", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "_MfULWHYB1BylU7H_Os8K", + "originalText": "reload工程后,pp2main,并且自动模式和上电", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "oxtHFkwF4Nb6F5sLpb7qO", + "type": "arrow", + "x": 512.114225224778, + "y": 497.48359840808337, + "width": 125.60003662109375, + "height": 0.714594187687112, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0D", + "roundness": { + "type": 2 + }, + "seed": 1372818253, + "version": 370, + "versionNonce": 1996030861, + "isDeleted": false, + "boundElements": null, + "updated": 1721953749040, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 125.60003662109375, + 0.714594187687112 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "_MfULWHYB1BylU7H_Os8K", + "focus": 0.10491939108920384, + "gap": 10.16107177734375 + }, + "endBinding": { + "elementId": "2ysxvHdQkJy90WXrs-fCv", + "focus": -0.20013052975390783, + "gap": 6.543214960769092 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "rectangle", + "version": 1143, + "versionNonce": 131473261, + "index": "b0E", + "isDeleted": false, + "id": "smvbNoKw6LDeWHeMhkgs3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 717.8751810353249, + "y": 651.5322109121829, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 165.27789306640628, + "height": 41.39999389648438, + "seed": 1202250509, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "8ApgTR11RrDXeM7h2uWRO" + }, + { + "id": "i_UW5iv9D7BQ4VakeukH-", + "type": "arrow" + }, + { + "id": "pksUeLNq_8safCB-XkaZo", + "type": "arrow" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1214, + "versionNonce": 36264589, + "index": "b0F", + "isDeleted": false, + "id": "8ApgTR11RrDXeM7h2uWRO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 760.514127568528, + "y": 659.7322078604251, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 80, + "height": 25, + "seed": 1410529645, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "急停触发", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "smvbNoKw6LDeWHeMhkgs3", + "originalText": "急停触发", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1199, + "versionNonce": 1721270509, + "index": "b0G", + "isDeleted": false, + "id": "cQBmppzmPZSR_CwMobNmi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 776.6752908986061, + "y": 826.332274999097, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 165.27789306640628, + "height": 41.39999389648438, + "seed": 1406773699, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Bxu3IOJriXHxH6QCl7tps" + }, + { + "id": "pksUeLNq_8safCB-XkaZo", + "type": "arrow" + }, + { + "id": "dUxT3co8677f2AaonmyE4", + "type": "arrow" + } + ], + "updated": 1721953748957, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1277, + "versionNonce": 1583688717, + "index": "b0H", + "isDeleted": false, + "id": "Bxu3IOJriXHxH6QCl7tps", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 819.3142374318093, + "y": 834.5322719473392, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 80, + "height": 25, + "seed": 656767331, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721953748957, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "数据处理", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cQBmppzmPZSR_CwMobNmi", + "originalText": "数据处理", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "i_UW5iv9D7BQ4VakeukH-", + "type": "arrow", + "x": 705.7142618458718, + "y": 536.6322170156985, + "width": 54.4000244140625, + "height": 110.39999389648438, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0I", + "roundness": { + "type": 2 + }, + "seed": 1186876749, + "version": 338, + "versionNonce": 1959609421, + "isDeleted": false, + "boundElements": null, + "updated": 1721953749040, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 54.4000244140625, + 110.39999389648438 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "2ysxvHdQkJy90WXrs-fCv", + "focus": 0.546810493886852, + "gap": 11.9157456615319 + }, + "endBinding": { + "elementId": "smvbNoKw6LDeWHeMhkgs3", + "focus": -0.30140846268939786, + "gap": 4.5 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "pksUeLNq_8safCB-XkaZo", + "type": "arrow", + "x": 785.7142618458718, + "y": 706.2322231192142, + "width": 60.7999267578125, + "height": 106.39996337890625, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0J", + "roundness": { + "type": 2 + }, + "seed": 240575341, + "version": 367, + "versionNonce": 1301828877, + "isDeleted": false, + "boundElements": null, + "updated": 1721953749040, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 60.7999267578125, + 106.39996337890625 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "smvbNoKw6LDeWHeMhkgs3", + "focus": 0.3623301872560003, + "gap": 13.300018310546875 + }, + "endBinding": { + "elementId": "cQBmppzmPZSR_CwMobNmi", + "focus": 0.07258713848178447, + "gap": 13.700088500976562 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "dUxT3co8677f2AaonmyE4", + "type": "arrow", + "x": 867.5592163392541, + "y": 879.8321987051517, + "width": 1045.705451324562, + "height": 63.15636025022944, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0O", + "roundness": { + "type": 2 + }, + "seed": 871599619, + "version": 745, + "versionNonce": 770061773, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Fwqff_6PMVSjIk4oBzQaG" + } + ], + "updated": 1721953749040, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -176.24497890744487, + 63.15636025022944 + ], + [ + -793.0449667004136, + 60.888645185080165 + ], + [ + -1045.705451324562, + 9.978025873211143 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "cQBmppzmPZSR_CwMobNmi", + "focus": -0.7106381634029143, + "gap": 12.099929809570312 + }, + "endBinding": { + "elementId": "1bP6Dvn7AZ9RH4DrcRdB_", + "focus": 0.920453305511539, + "gap": 5.863745172527501 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "Fwqff_6PMVSjIk4oBzQaG", + "type": "text", + "x": 332.70622996595705, + "y": 991.7266626351698, + "width": 80, + "height": 25, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0P", + "roundness": null, + "seed": 320259789, + "version": 65, + "versionNonce": 862731661, + "isDeleted": false, + "boundElements": null, + "updated": 1721953748957, + "link": null, + "locked": false, + "text": "循环三次", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dUxT3co8677f2AaonmyE4", + "originalText": "循环三次", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/aio/assets/workflow/do_current.excalidraw b/aio/assets/workflow/do_current.excalidraw new file mode 100644 index 0000000..db6ae3b --- /dev/null +++ b/aio/assets/workflow/do_current.excalidraw @@ -0,0 +1,1666 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "http://10.2.23.150:10020", + "elements": [ + { + "type": "rectangle", + "version": 118, + "versionNonce": 1360105599, + "index": "a0", + "isDeleted": false, + "id": "G7GvfRyoquBz-CKotoH2E", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 83.4285888671875, + "y": -67.33507537841797, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 122.07794189453125, + "height": 49.35063934326172, + "seed": 760702512, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "CBAHPncOXHa_pJUrlM-O2" + }, + { + "id": "sVTpXJGfJ64bteP_k-FEb", + "type": "arrow" + } + ], + "updated": 1719982447630, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 105, + "versionNonce": 988073259, + "index": "a1", + "isDeleted": false, + "id": "CBAHPncOXHa_pJUrlM-O2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 124.46755981445312, + "y": -55.15975570678711, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 25, + "seed": 1658646736, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "开始", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "G7GvfRyoquBz-CKotoH2E", + "originalText": "开始", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 118, + "versionNonce": 1557399729, + "index": "a4", + "isDeleted": false, + "id": "IHIeSs49oqr0TLYPMSk6V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -258.6597213745117, + "y": 45.849365234375, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 228.5714340209961, + "height": 95.58439636230469, + "seed": 1067092528, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1719981868207, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 399, + "versionNonce": 1819946757, + "index": "a8", + "isDeleted": false, + "id": "ZEgbGldzHFnQJBlIGHlcm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -244.47891406982174, + "y": 60.48309326171875, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 193.4991455078125, + "height": 68.81682520930795, + "seed": 1086242000, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 18.351153389148788, + "fontFamily": 1, + "text": "1. configs.xlsx\n2. T_电机电流.xlsx\n3. 工程文件", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "1. configs.xlsx\n2. T_电机电流.xlsx\n3. 工程文件", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "type": "diamond", + "version": 158, + "versionNonce": 684273585, + "index": "aA", + "isDeleted": false, + "id": "RwMIreS0QkAZwm-3ulGX-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 24.051910400390625, + "y": 40.48309326171875, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 257.5999755859375, + "height": 100, + "seed": 51082257, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "iNY8dtUFmWKoMwFFsArGd" + }, + { + "id": "cdPz-GgAqgjIqgTPRVFw-", + "type": "arrow" + }, + { + "id": "vRciE0DKBJzJ8v7fA54Kq", + "type": "arrow" + }, + { + "id": "sVTpXJGfJ64bteP_k-FEb", + "type": "arrow" + } + ], + "updated": 1719982450560, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 214, + "versionNonce": 1388834763, + "index": "aAV", + "isDeleted": false, + "id": "iNY8dtUFmWKoMwFFsArGd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 96.951904296875, + "y": 70.48309326171875, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 112, + "height": 40, + "seed": 1500869361, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "检查输入文件是\n否正确", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "RwMIreS0QkAZwm-3ulGX-", + "originalText": "检查输入文件是否正确", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 243, + "versionNonce": 469737771, + "index": "aC", + "isDeleted": false, + "id": "Kf1iK8aKtz3dLPTOYumTw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 501.41290283203125, + "y": -67.3922233581543, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 122.07794189453125, + "height": 49.35063934326172, + "seed": 179980831, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "VuHEUguk0rq5mHifBtniS" + }, + { + "id": "cdPz-GgAqgjIqgTPRVFw-", + "type": "arrow" + }, + { + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "type": "arrow" + } + ], + "updated": 1719982544519, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 234, + "versionNonce": 298321509, + "index": "aD", + "isDeleted": false, + "id": "VuHEUguk0rq5mHifBtniS", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 542.4518737792969, + "y": -55.21690368652344, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 25, + "seed": 1648995903, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "结束", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Kf1iK8aKtz3dLPTOYumTw", + "originalText": "结束", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 159, + "versionNonce": 12219423, + "index": "aH", + "isDeleted": false, + "id": "cdPz-GgAqgjIqgTPRVFw-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 264.76445650455105, + "y": 66.83925419197496, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 228.08738065365208, + "height": 99.95610599861558, + "seed": 339189983, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "82DP34j9Ep7573KCrZFuj" + } + ], + "updated": 1719982450562, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RwMIreS0QkAZwm-3ulGX-", + "focus": 0.6262400211589412, + "gap": 15.929954945665216 + }, + "endBinding": { + "elementId": "Kf1iK8aKtz3dLPTOYumTw", + "focus": 0.05115605003902535, + "gap": 8.561065673828125 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 105.68741727474583, + -79.95610599861558 + ], + [ + 228.08738065365208, + -99.95610599861558 + ] + ] + }, + { + "type": "text", + "version": 8, + "versionNonce": 1399701099, + "index": "aHV", + "isDeleted": false, + "id": "82DP34j9Ep7573KCrZFuj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 353.6798782348633, + "y": -30.616851806640625, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 33.54399108886719, + "height": 35, + "seed": 830879743, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "No", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cdPz-GgAqgjIqgTPRVFw-", + "originalText": "No", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 469, + "versionNonce": 817793503, + "index": "aI", + "isDeleted": false, + "id": "OuZBPxPXuTv9FpsBMA2am", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -244.98712158203125, + "y": 267.0077705383301, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 215.67791748046875, + "height": 59.75057220458983, + "seed": 1897362833, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "QclqBhwtyuV2bEYeF_-0N" + }, + { + "id": "vRciE0DKBJzJ8v7fA54Kq", + "type": "arrow" + }, + { + "id": "M3h-oZVLWQYI4EBdoYQJZ", + "type": "arrow" + } + ], + "updated": 1719982188678, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 492, + "versionNonce": 841216453, + "index": "aJ", + "isDeleted": false, + "id": "QclqBhwtyuV2bEYeF_-0N", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -224.51813507080078, + "y": 284.383056640625, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 174.7399444580078, + "height": 25, + "seed": 1385470833, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "将工程拷贝到xCore", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "OuZBPxPXuTv9FpsBMA2am", + "originalText": "将工程拷贝到xCore", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 749, + "versionNonce": 748415083, + "index": "aK", + "isDeleted": false, + "id": "BCw88w8hesWTAf2Xay3qh", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -232.58706665039062, + "y": 429.80786514282227, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 200.4779052734375, + "height": 110, + "seed": 857530801, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "yHxIbnwKIz2AfFo1WFUv4" + }, + { + "id": "M3h-oZVLWQYI4EBdoYQJZ", + "type": "arrow" + }, + { + "id": "abhTOT48fVbhcaD6SFRLd", + "type": "arrow" + }, + { + "id": "n3hZ2B8KLeQUTZ8vlZwpw", + "type": "arrow" + } + ], + "updated": 1719982613868, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 766, + "versionNonce": 1738586379, + "index": "aL", + "isDeleted": false, + "id": "yHxIbnwKIz2AfFo1WFUv4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -227.58706665039062, + "y": 447.30786514282227, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 180, + "height": 75, + "seed": 1700234129, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "关闭诊断曲线,触发\n软急停,并解除,切\n手动模式", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "BCw88w8hesWTAf2Xay3qh", + "originalText": "关闭诊断曲线,触发软急停,并解除,切手动模式", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 125, + "versionNonce": 346241861, + "index": "aM", + "isDeleted": false, + "id": "vRciE0DKBJzJ8v7fA54Kq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 61.12548359401855, + "y": 117.84151260276442, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 206.69268721882452, + "height": 140.24163253883714, + "seed": 546610591, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "PfWkxzSRM6swE3zdpo__p" + } + ], + "updated": 1719982658475, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RwMIreS0QkAZwm-3ulGX-", + "focus": 0.39910484083682946, + "gap": 12.087656934222686 + }, + "endBinding": { + "elementId": "OuZBPxPXuTv9FpsBMA2am", + "focus": -0.43197181050964706, + "gap": 8.924625396728516 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -206.69268721882452, + 140.24163253883714 + ] + ] + }, + { + "id": "PfWkxzSRM6swE3zdpo__p", + "type": "text", + "x": -58.280842315198406, + "y": 175.46232887218298, + "width": 32.119964599609375, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aMV", + "roundness": null, + "seed": 1690013765, + "version": 6, + "versionNonce": 1804967499, + "isDeleted": false, + "boundElements": null, + "updated": 1719982657566, + "link": null, + "locked": false, + "text": "Yes", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "vRciE0DKBJzJ8v7fA54Kq", + "originalText": "Yes", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 426, + "versionNonce": 313666481, + "index": "aN", + "isDeleted": false, + "id": "M3h-oZVLWQYI4EBdoYQJZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -146.50678883428878, + "y": 337.71943283081055, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 2.9703782670530074, + "height": 79.12740325927734, + "seed": 265077663, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982225670, + "link": null, + "locked": false, + "startBinding": { + "elementId": "OuZBPxPXuTv9FpsBMA2am", + "focus": 0.06862940464968151, + "gap": 10.961090087890625 + }, + "endBinding": { + "elementId": "BCw88w8hesWTAf2Xay3qh", + "focus": -0.1923710725188571, + "gap": 12.961029052734375 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -2.9703782670530074, + 79.12740325927734 + ] + ] + }, + { + "type": "rectangle", + "version": 626, + "versionNonce": 1401629285, + "index": "aO", + "isDeleted": false, + "id": "tRrOZ-dVRENzlkE2D7JiN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 75.412841796875, + "y": 461.80783462524414, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 215.67791748046875, + "height": 50.20001220703125, + "seed": 1924605105, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "sMJglKTmK18wBh571qiFL" + }, + { + "id": "abhTOT48fVbhcaD6SFRLd", + "type": "arrow" + }, + { + "id": "NmxfcTzxuWNJwo4Wb-4Ga", + "type": "arrow" + }, + { + "id": "n3hZ2B8KLeQUTZ8vlZwpw", + "type": "arrow" + } + ], + "updated": 1719982487638, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 675, + "versionNonce": 1789620517, + "index": "aP", + "isDeleted": false, + "id": "sMJglKTmK18wBh571qiFL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 103.25180053710938, + "y": 474.40784072875977, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 160, + "height": 25, + "seed": 1588684433, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "修改要执行的场景", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tRrOZ-dVRENzlkE2D7JiN", + "originalText": "修改要执行的场景", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 708, + "versionNonce": 713425809, + "index": "aQ", + "isDeleted": false, + "id": "RCDA1RfQ7PtPkmcBpZ0ZG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 59.41290283203125, + "y": 276.1831512451172, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 253.27795410156253, + "height": 76.19992065429686, + "seed": 1625462961, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "AkYipAwKndA09w9Cp3MoW" + }, + { + "id": "NmxfcTzxuWNJwo4Wb-4Ga", + "type": "arrow" + }, + { + "id": "F-gcNIPiBPo5bXyhvYKAd", + "type": "arrow" + } + ], + "updated": 1719982420727, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 751, + "versionNonce": 2094751659, + "index": "aR", + "isDeleted": false, + "id": "AkYipAwKndA09w9Cp3MoW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 64.41290283203125, + "y": 289.2831115722656, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 234.27987670898438, + "height": 50, + "seed": 1598970513, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "reload工程后,pp2main,\n并且自动模式和上电", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "RCDA1RfQ7PtPkmcBpZ0ZG", + "originalText": "reload工程后,pp2main,并且自动模式和上电", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 867, + "versionNonce": 2045773137, + "index": "aT", + "isDeleted": false, + "id": "VJKgVgVna5AHKSE1WlSKM", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 446.61285400390625, + "y": 110.58305358886719, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 173.2778930664062, + "height": 51.20001220703126, + "seed": 754615359, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "DmL0yWKEJ7KMf7m5v8fBP", + "type": "text" + }, + { + "id": "F-gcNIPiBPo5bXyhvYKAd", + "type": "arrow" + }, + { + "id": "_0vJdrVWw6yxiSmedBCz_", + "type": "arrow" + } + ], + "updated": 1719982472134, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 191, + "versionNonce": 1489765509, + "index": "aTV", + "isDeleted": false, + "id": "DmL0yWKEJ7KMf7m5v8fBP", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 473.2518005371094, + "y": 123.68305969238281, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 120, + "height": 25, + "seed": 1146471505, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "开始运行程序", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "VJKgVgVna5AHKSE1WlSKM", + "originalText": "开始运行程序", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 967, + "versionNonce": 1434035473, + "index": "aX", + "isDeleted": false, + "id": "wsKk3rGTn1F-L5FxrCX5H", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 426.2130126953125, + "y": 274.0830841064453, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 213.2778930664063, + "height": 69, + "seed": 804808927, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Ybc-XtdsXVulj0EsjVQG3" + }, + { + "id": "F-gcNIPiBPo5bXyhvYKAd", + "type": "arrow" + }, + { + "id": "ZDRN9BNAFSm7MPd4mQItT", + "type": "arrow" + }, + { + "id": "_0vJdrVWw6yxiSmedBCz_", + "type": "arrow" + } + ], + "updated": 1719982472134, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 296, + "versionNonce": 1833448011, + "index": "aY", + "isDeleted": false, + "id": "Ybc-XtdsXVulj0EsjVQG3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 431.2130126953125, + "y": 283.5830841064453, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 200, + "height": 50, + "seed": 1607857407, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "打开诊断曲线,并执行\n采集,收集15s的数据", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "wsKk3rGTn1F-L5FxrCX5H", + "originalText": "打开诊断曲线,并执行采集,收集15s的数据", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1091, + "versionNonce": 330063851, + "index": "aZ", + "isDeleted": false, + "id": "2ysxvHdQkJy90WXrs-fCv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 424.6129150390625, + "y": 439.5830841064453, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 213.2778930664063, + "height": 85, + "seed": 958808895, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "o7Ntq3Q62WL2u4scU9yxN" + }, + { + "id": "ZDRN9BNAFSm7MPd4mQItT", + "type": "arrow" + }, + { + "id": "n3hZ2B8KLeQUTZ8vlZwpw", + "type": "arrow" + }, + { + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "type": "arrow" + } + ], + "updated": 1719982544519, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 419, + "versionNonce": 272837605, + "index": "aa", + "isDeleted": false, + "id": "o7Ntq3Q62WL2u4scU9yxN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 429.6129150390625, + "y": 444.5830841064453, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 200, + "height": 75, + "seed": 253330271, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1719982515995, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "关闭诊断曲线,停止程\n序运行,下电并且换成\n手动模式", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "2ysxvHdQkJy90WXrs-fCv", + "originalText": "关闭诊断曲线,停止程序运行,下电并且换成手动模式", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 28, + "versionNonce": 1448801265, + "index": "ac", + "isDeleted": false, + "id": "abhTOT48fVbhcaD6SFRLd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -23.148101806640625, + "y": 480.48313903808594, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 92.79998779296875, + "height": 4.79998779296875, + "seed": 206954833, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982415614, + "link": null, + "locked": false, + "startBinding": { + "elementId": "BCw88w8hesWTAf2Xay3qh", + "focus": -0.16570621576454106, + "gap": 8.9610595703125 + }, + "endBinding": { + "elementId": "tRrOZ-dVRENzlkE2D7JiN", + "focus": -0.13857316707842932, + "gap": 5.760955810546875 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 92.79998779296875, + 4.79998779296875 + ] + ] + }, + { + "type": "arrow", + "version": 43, + "versionNonce": 381333105, + "index": "ad", + "isDeleted": false, + "id": "NmxfcTzxuWNJwo4Wb-4Ga", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 186.45187377929688, + "y": 451.6831512451172, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 3.20001220703125, + "height": 93.60003662109375, + "seed": 800156593, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982418134, + "link": null, + "locked": false, + "startBinding": { + "elementId": "tRrOZ-dVRENzlkE2D7JiN", + "focus": 0.0405193974911985, + "gap": 10.124683380126953 + }, + "endBinding": { + "elementId": "RCDA1RfQ7PtPkmcBpZ0ZG", + "focus": 0.033589241584410304, + "gap": 5.700042724609375 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -3.20001220703125, + -93.60003662109375 + ] + ] + }, + { + "type": "arrow", + "version": 166, + "versionNonce": 696485823, + "index": "ae", + "isDeleted": false, + "id": "F-gcNIPiBPo5bXyhvYKAd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 207.17953736663367, + "y": 265.2831268310547, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 232.07226317047576, + "height": 129.50963486385447, + "seed": 1246004785, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982468154, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RCDA1RfQ7PtPkmcBpZ0ZG", + "focus": -0.344114401938857, + "gap": 10.9000244140625 + }, + "endBinding": { + "elementId": "VJKgVgVna5AHKSE1WlSKM", + "focus": 0.7149061721950657, + "gap": 7.361053466796875 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 232.07226317047576, + -129.50963486385447 + ] + ] + }, + { + "type": "arrow", + "version": 37, + "versionNonce": 288218289, + "index": "af", + "isDeleted": false, + "id": "ZDRN9BNAFSm7MPd4mQItT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 537.6518859863281, + "y": 351.6831817626953, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 0.800048828125, + "height": 77.59994506835938, + "seed": 1918402865, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982423150, + "link": null, + "locked": false, + "startBinding": { + "elementId": "wsKk3rGTn1F-L5FxrCX5H", + "focus": -0.0490144661885691, + "gap": 8.60009765625 + }, + "endBinding": { + "elementId": "2ysxvHdQkJy90WXrs-fCv", + "focus": 0.04721468619376246, + "gap": 10.299957275390625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -0.800048828125, + 77.59994506835938 + ] + ] + }, + { + "type": "arrow", + "version": 23, + "versionNonce": 977005727, + "index": "ah", + "isDeleted": false, + "id": "sVTpXJGfJ64bteP_k-FEb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 150.45187377929688, + "y": -11.516876220703121, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 0.804804176492155, + "height": 41.8504465544745, + "seed": 445992479, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982450563, + "link": null, + "locked": false, + "startBinding": { + "elementId": "G7GvfRyoquBz-CKotoH2E", + "focus": -0.08754862573962541, + "gap": 6.467559814453125 + }, + "endBinding": { + "elementId": "RwMIreS0QkAZwm-3ulGX-", + "focus": -0.00340462795005759, + "gap": 10.274120072847268 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0.804804176492155, + 41.8504465544745 + ] + ] + }, + { + "type": "arrow", + "version": 36, + "versionNonce": 423965489, + "index": "aj", + "isDeleted": false, + "id": "_0vJdrVWw6yxiSmedBCz_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 524.8518371582031, + "y": 169.2831268310547, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffffff", + "width": 4.800048828125, + "height": 95.19998168945312, + "seed": 929888657, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1719982472134, + "link": null, + "locked": false, + "startBinding": { + "elementId": "VJKgVgVna5AHKSE1WlSKM", + "focus": 0.11451067993145546, + "gap": 7.50006103515625 + }, + "endBinding": { + "elementId": "wsKk3rGTn1F-L5FxrCX5H", + "focus": -0.009010296063984877, + "gap": 9.5999755859375 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 4.800048828125, + 95.19998168945312 + ] + ] + }, + { + "id": "n3hZ2B8KLeQUTZ8vlZwpw", + "type": "arrow", + "x": 540.0518798828125, + "y": 543.6831512451172, + "width": 681.6000061035156, + "height": 97.59992980957031, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ak", + "roundness": { + "type": 2 + }, + "seed": 1992830629, + "version": 317, + "versionNonce": 2002086373, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "VtM-I773QbeIZJnAnflWx" + } + ], + "updated": 1719982634421, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -330.40005111694336, + 97.59992980957031 + ], + [ + -681.6000061035156, + 12.00006103515625 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "2ysxvHdQkJy90WXrs-fCv", + "focus": -0.8675494800251833, + "gap": 19.100067138671875 + }, + "endBinding": { + "elementId": "BCw88w8hesWTAf2Xay3qh", + "focus": 0.9205095612151336, + "gap": 15.875347137451172 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "VtM-I773QbeIZJnAnflWx", + "type": "text", + "x": 338.85186767578125, + "y": 473.18312072753906, + "width": 40, + "height": 25, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "akV", + "roundness": null, + "seed": 26036997, + "version": 11, + "versionNonce": 1756944421, + "isDeleted": false, + "boundElements": null, + "updated": 1719982595450, + "link": null, + "locked": false, + "text": "继续", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "n3hZ2B8KLeQUTZ8vlZwpw", + "originalText": "继续", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "E6Z8Wh6Av-c4t5msk3j0Z", + "type": "arrow", + "x": 650.4519348144531, + "y": 479.6831512451172, + "width": 244.800048828125, + "height": 524.0000305175781, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "am", + "roundness": { + "type": 2 + }, + "seed": 1006891467, + "version": 413, + "versionNonce": 972534245, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "3NfVy3o0TIZLU7DXhNStB" + } + ], + "updated": 1719982563646, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 159.2000732421875, + -72 + ], + [ + 228, + -289.60003662109375 + ], + [ + 131.199951171875, + -499.2000198364258 + ], + [ + -16.800048828125, + -524.0000305175781 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "2ysxvHdQkJy90WXrs-fCv", + "focus": 0.5677327376482016, + "gap": 12.561126708984375 + }, + "endBinding": { + "elementId": "Kf1iK8aKtz3dLPTOYumTw", + "focus": -0.38766321137227633, + "gap": 10.161041259765625 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "3NfVy3o0TIZLU7DXhNStB", + "type": "text", + "x": 723.6518859863281, + "y": 151.9831085205078, + "width": 180, + "height": 25, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "an", + "roundness": null, + "seed": 438263077, + "version": 36, + "versionNonce": 1981042341, + "isDeleted": false, + "boundElements": null, + "updated": 1719982554969, + "link": null, + "locked": false, + "text": "当所有场景采集完毕", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "E6Z8Wh6Av-c4t5msk3j0Z", + "originalText": "当所有场景采集完毕", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 408fd3e..28469e7 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -1,5 +1,4 @@ -from random import randint -from time import sleep, time +from time import sleep, time, strftime, localtime from sys import argv from os import scandir, mkdir from os.path import exists @@ -9,12 +8,13 @@ from openpyxl import load_workbook import pandas RADIAN = 57.3 # 180 / 3.1415926 +tab_name = 'Automatic Test' def traversal_files(path, w2t): if not exists(path): msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red', tab_name='Automatic Test') + w2t(msg, 0, 1, 'red', tab_name) else: dirs = [] files = [] @@ -29,8 +29,8 @@ def traversal_files(path, w2t): def check_files(path, loadsel, data_dirs, data_files, w2t): if len(data_dirs) != 0 or len(data_files) != 5: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name='Automatic Test') - w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name='Automatic Test') + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name) + w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name) config_file = reach33 = reach66 = reach100 = prj_file = None for data_file in data_files: @@ -46,8 +46,8 @@ def check_files(path, loadsel, data_dirs, data_files, w2t): elif filename.endswith('.zip'): prj_file = data_file else: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name='Automatic Test') - w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 2, 'red', tab_name='Automatic Test') + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name) + w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 2, 'red', tab_name) if config_file and reach33 and reach66 and reach100 and prj_file: result_dirs = [] @@ -65,11 +65,11 @@ def check_files(path, loadsel, data_dirs, data_files, w2t): if _reach == 'reach100': mkdir(f"{path}\\j3\\{dir_name}") - w2t("数据目录合规性检查结束,未发现问题......", tab_name='Automatic Test') + w2t("数据目录合规性检查结束,未发现问题......", 0, 0, 'blue', tab_name) return config_file, reach33, reach66, reach100, prj_file, result_dirs else: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name='Automatic Test') - w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name='Automatic Test') + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!', 0, 0, 'red', tab_name) + w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name) def prj_to_xcore(prj_file): @@ -90,9 +90,9 @@ def prj_to_xcore(prj_file): print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo print(stderr.read().decode()) # 顺便也执行以下stderr - _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') + # _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += f'sudo mv projects/target/_build/{_prj_name}.prj projects/target/_build/target.prj' + cmd += f'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') stdin.flush() @@ -105,11 +105,11 @@ def execution(cmd, hr, w2t, **kwargs): _id = hr.execution(cmd, **kwargs) _msg = hr.get_from_id(_id) if not _msg: - w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name='Automatic Test') + w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name) else: _response = loads(_msg) if not _response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') + w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name) return _response @@ -119,7 +119,6 @@ def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): _d2d_stop = {'device_safety_estop': []} for data in curve_data: dict_results = data['data'] - # dict_results.reverse() for item in dict_results: item['value'].reverse() if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback': @@ -137,9 +136,8 @@ def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): df.to_csv(_filename, sep='\t', index=False) -def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): +def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): _count = 0 - speed_max = 0 display_pdo_params = [ {"name": "hw_joint_vel_feedback", "channel": 0}, {"name": "hw_joint_vel_feedback", "channel": 1}, @@ -157,82 +155,94 @@ def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): ] wb = load_workbook(config_file, read_only=True) ws = wb['Target'] + write_diagnosis = float(ws.cell(row=3, column=10).value) + get_init_speed = float(ws.cell(row=4, column=10).value) if ws.cell(row=1, column=1).value == 'positive': - md.write_pon(True) + md.write_pon(1) elif ws.cell(row=1, column=1).value == 'negative': - md.write_pon(False) + md.write_pon(0) else: - w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', 'Automatic Test') + w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', tab_name) for condition in result_dirs: _reach = condition.split('_')[0].removeprefix('reach') _load = condition.split('_')[1].removeprefix('load') _speed = condition.split('_')[2].removeprefix('speed') - + # if _speed != '100' or _reach != '100': + # continue for axis in range(1, 4): md.write_axis(axis) speed_max = 0 if axis == 3 and _reach != '100': continue + + w2t(f"-"*90, 0, 0, 'purple', tab_name) + for count in range(1, 4): _count += 1 - w2t(f"[{_count}/63-{count}] 正在执行{axis}轴{condition}的制动测试......", 0, 0, 'purple', 'Automatic Test') + this_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time())) + prj_path = 'target/_build/target.prj' + w2t(f"[{this_time} | {_count}/63] 正在执行 {axis} 轴 {condition} 的第 {count} 次制动测试...", 0, 0, 'purple', tab_name) # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 md.trigger_estop() md.reset_estop() - md.write_act(False) + md.clear_alarm() + md.write_act(0) + _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) + sleep(write_diagnosis) # 软急停超差后,等待写诊断时间,可通过configs.xlsx配置 _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - sleep(1) # 让曲线彻底关闭 - _response = execution('state.switch_manual', hr, w2t) - _response = execution('state.switch_motor_off', hr, w2t) - # 2. 修改未要执行的场景 - ssh = SSHClient() - ssh.set_missing_host_key_policy(AutoAddPolicy()) - ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') - if ws.cell(row=1, column=1).value == 'positive': - _rl_cmd = f"brake_E(j{axis}_{_reach}_p, j{axis}_{_reach}_n, p_speed, p_tool)" - elif ws.cell(row=1, column=1).value == 'negative': - _rl_cmd = f"brake_E(j{axis}_{_reach}_n, j{axis}_{_reach}_p, p_speed, p_tool)" - else: - w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', 'Automatic Test') - _rl_speed = f"VelSet {_speed}" - cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += 'sudo sed -i "/brake_E/d" projects/target/_build/brake/main.mod; ' - cmd += f'sudo sed -i "/DONOTDELETE/i {_rl_cmd}" projects/target/_build/brake/main.mod; ' - cmd += 'sudo sed -i "/VelSet/d" projects/target/_build/brake/main.mod; ' - cmd += f'sudo sed -i "/MoveAbsJ/i {_rl_speed}" projects/target/_build/brake/main.mod' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - - # 3. reload工程后,pp2main,并且自动模式和上电,最后运行程序 - prj_path = 'target/_build/target.prj' - _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['brake', 'stop0_related']) - _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['brake', 'stop0_related']) - _response = execution('state.switch_auto', hr, w2t) - _response = execution('state.switch_motor_on', hr, w2t) - _response = execution('rl_task.run', hr, w2t, tasks=['brake', 'stop0_related']) - _t_start = time() - while True: - if md.read_ready_to_go() == 1: - md.write_act(True) - break + while count == 1: + # 2. 修改未要执行的场景 + ssh = SSHClient() + ssh.set_missing_host_key_policy(AutoAddPolicy()) + ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') + if ws.cell(row=1, column=1).value == 'positive': + _rl_cmd = f"brake_E(j{axis}_{_reach}_p, j{axis}_{_reach}_n, p_speed, p_tool)" + elif ws.cell(row=1, column=1).value == 'negative': + _rl_cmd = f"brake_E(j{axis}_{_reach}_n, j{axis}_{_reach}_p, p_speed, p_tool)" else: - if (time() - _t_start) // 20 > 1: - w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', tab_name) + _rl_speed = f"VelSet {_speed}" + _rl_tool = f"tool p_tool = tool{loadsel.removeprefix('tool')}" + cmd = 'cd /home/luoshi/bin/controller/; ' + cmd += 'sudo sed -i "/brake_E/d" projects/target/_build/brake/main.mod; ' + cmd += f'sudo sed -i "/DONOTDELETE/i {_rl_cmd}" projects/target/_build/brake/main.mod; ' + cmd += 'sudo sed -i "/VelSet/d" projects/target/_build/brake/main.mod; ' + cmd += f'sudo sed -i "/MoveAbsJ/i {_rl_speed}" projects/target/_build/brake/main.mod; ' + cmd += 'sudo sed -i "/tool p_tool/d" projects/target/_build/brake/main.mod; ' + cmd += f'sudo sed -i "/VelSet/i {_rl_tool}" projects/target/_build/brake/main.mod; ' + stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) + stdin.write('luoshi2019' + '\n') + stdin.flush() + print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo + print(stderr.read().decode()) # 顺便也执行以下stderr + + # 3. reload工程后,pp2main,并且自动模式和上电,最后运行程序 + _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['brake', 'stop0_related']) + _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['brake', 'stop0_related']) + _response = execution('state.switch_auto', hr, w2t) + _response = execution('state.switch_motor_on', hr, w2t) + _response = execution('rl_task.run', hr, w2t, tasks=['brake', 'stop0_related']) + _t_start = time() + while True: + if md.read_ready_to_go() == 1: + md.write_act(True) + break else: - sleep(1) - # 4. 第一次打开诊断曲线,并执行采集8s,之后触发软急停,关闭曲线采集,找出最大速度,传递给RL程序,最后清除相关记录 - if count == 1: + if (time() - _t_start) // 20 > 1: + w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) + else: + sleep(1) + # 4. 打开诊断曲线,并执行采集,之后触发软急停,关闭曲线采集,找出最大速度,传递给RL程序,最后清除相关记录 _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) - sleep(10) # 前10秒获取实际最大速度 - - md.trigger_estop() + sleep(get_init_speed) # 获取实际最大速度,可通过configs.xlsx配置 + _response = execution('rl_task.stop', hr, w2t, tasks=['brake']) + sleep(1) + _response = execution('state.switch_motor_off', hr, w2t) + _response = execution('state.switch_manual', hr, w2t) _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) # 找出最大速度 for _msg in hr.c_msg: @@ -240,11 +250,16 @@ def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): dict_results = loads(_msg)['data'] for item in dict_results: if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback': - _ = abs(RADIAN*sum(item['value'])/len(item['value'])) - speed_max = max(_, speed_max) + _ = RADIAN * sum(item['value']) / len(item['value']) + if ws.cell(row=1, column=1).value == 'positive': + speed_max = max(_, speed_max) + elif ws.cell(row=1, column=1).value == 'negative': + speed_max = min(_, speed_max) + print(f"speed max = {speed_max}") + speed_max = abs(speed_max) speed_target = float(ws.cell(row=3, column=axis+1).value) * float(_speed) / 100 if speed_max < speed_target*0.95 or speed_max > speed_target*1.05: - w2t(f"Axis: {axis}-{count} | Speed: {speed_max} | Shouldbe: {speed_target}", 0, 0, 'indigo', 'Automatic Test') + w2t(f"Axis: {axis}-{count} | Speed: {speed_max} | Shouldbe: {speed_target}", 0, 0, 'indigo', tab_name) md.write_speed_max(speed_max) sleep(1) @@ -256,8 +271,17 @@ def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): hr.c_msg_xs.clear() break + if speed_max < 10: + md.clear_alarm() + w2t("未获取到正确的速度,即将重新获取...", 0, 0, 'red', tab_name) + continue + else: + break + # 5. 清除软急停,重新运行程序,并打开曲线发送继续运动信号,当速度达到最大值时,通过DO触发急停 - md.reset_estop() + md.reset_estop() # 其实没必要 + md.clear_alarm() + _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['brake', 'stop0_related']) _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['brake', 'stop0_related']) _response = execution('state.switch_auto', hr, w2t) @@ -265,31 +289,29 @@ def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): _response = execution('rl_task.run', hr, w2t, tasks=['brake', 'stop0_related']) for i in range(3): if md.read_ready_to_go() == 1: - md.write_act(True) + md.write_act(1) break else: sleep(1) else: - w2t("未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + w2t("未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) - sleep(randint(3, 6)) - md.write_probe(True) + sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间 + md.write_probe(1) _t_start = time() while True: if md.read_brake_done() == 1: - sleep(1) # 保证所有数据均已返回 - md.write_probe(False) + sleep(1) # 保证速度归零 + md.write_probe(0) _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - sleep(1) # 保证所有数据均已返回 break else: if (time() - _t_start) > 30: - w2t(f"30s内未触发急停,该条数据无效,需要确认RL/Python程序编写正确并正常执行,或者判别是否是机器本体问题...", 0, 0, 'red', 'Automatic Test') - md.write_probe(False) + w2t(f"30s内未触发急停,该条数据无效,需要确认RL/Python程序编写正确并正常执行,或者判别是否是机器本体问题,比如正负方向速度是否一致...", 0, 0, 'red', tab_name) + md.write_probe(0) _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - sleep(1) # 保证所有数据均已返回 break else: sleep(1) @@ -308,7 +330,7 @@ def run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t): break gen_result_file(path, curve_data, axis, _reach, _load, _speed, count) else: - w2t(f"\n{loadsel.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。", 0, 0, 'green', 'Automatic Test') + w2t(f"\n{loadsel.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。", 0, 0, 'green', tab_name) def main(path, hr, md, loadsel, w2t): @@ -316,10 +338,10 @@ def main(path, hr, md, loadsel, w2t): data_dirs, data_files = traversal_files(path, w2t) config_file, reach33, reach66, reach100, prj_file, result_dirs = check_files(path, loadsel, data_dirs, data_files, w2t) prj_to_xcore(prj_file) - run_rl(path, loadsel, hr, md, config_file, prj_file, result_dirs, w2t) + run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t) _e_time = time() time_total = _e_time - _s_time - w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", 0, 0, 'green', 'Automatic Test') + w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", 0, 0, 'green', tab_name) if __name__ == '__main__': diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index 1dff222..d46e0e0 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -75,9 +75,9 @@ def prj_to_xcore(prj_file): print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo print(stderr.read().decode()) # 顺便也执行以下stderr - _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') + # _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += f'sudo mv projects/target/_build/{_prj_name}.prj projects/target/_build/target.prj' + cmd += f'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') stdin.flush() diff --git a/aio/code/data_process/current.py b/aio/code/data_process/current.py index 52c65ea..78771f7 100644 --- a/aio/code/data_process/current.py +++ b/aio/code/data_process/current.py @@ -189,7 +189,7 @@ def current_cycle(dur, data_files, rcs, rrs, vel, trq, trqh, rpms, w2t): for axis, cur_value in avg.items(): try: shtname = f"J{axis}" - wb[shtname]["J4"].value = float(cur_value) + wb[shtname]["J4"].value = float(cur_value[0]) except: pass diff --git a/aio/code/openapi.py b/aio/code/openapi.py index 9da630e..fd86742 100644 --- a/aio/code/openapi.py +++ b/aio/code/openapi.py @@ -21,18 +21,27 @@ class ModbusRequest(object): self.tab_name = 'openapi' self.host = '192.168.0.160' self.port = 502 + self.interval = 0.3 self.c = ModbusTcpClient(self.host, self.port) self.c.connect() def motor_off(self): try: + self.c.write_register(40002, 0) + sleep(self.interval) self.c.write_register(40002, 1) + sleep(self.interval) + self.c.write_register(40002, 0) except Exception as Err: self.w2t(f"{Err}\n无法正常下电,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) def motor_on(self): try: + self.c.write_register(40003, 0) + sleep(self.interval) self.c.write_register(40003, 1) + sleep(self.interval) + self.c.write_register(40003, 0) except Exception as Err: self.w2t(f"{Err}\n无法正常上电,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) @@ -45,11 +54,11 @@ class ModbusRequest(object): def reset_estop(self): try: self.c.write_register(40012, 1) - sleep(0.2) + sleep(self.interval) self.c.write_register(40001, 0) - sleep(0.2) + sleep(self.interval) self.c.write_register(40001, 1) - sleep(0.2) + sleep(self.interval) self.c.write_register(40001, 0) except Exception as Err: self.w2t(f"{Err}\n无法重置软急停,连接Modbus失败,需要确认网络是否通畅,或是未正确导入寄存器文件...", 0, 100, 'red', self.tab_name) From 0d814d384d3c897933d4b1b67ad140a8ccbce499 Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 26 Jul 2024 13:33:19 +0800 Subject: [PATCH 25/36] fix version and will exit if not the latest one --- aio/assets/templates/heartbeat | 2 +- aio/code/aio.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/aio/assets/templates/heartbeat b/aio/assets/templates/heartbeat index 56a6051..c227083 100644 --- a/aio/assets/templates/heartbeat +++ b/aio/assets/templates/heartbeat @@ -1 +1 @@ -1 \ No newline at end of file +0 \ No newline at end of file diff --git a/aio/code/aio.py b/aio/code/aio.py index 37556fb..0fc6ec9 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -1,3 +1,4 @@ +import sys import tkinter from os.path import exists, dirname from os import getcwd @@ -105,7 +106,7 @@ class App(customtkinter.CTk): btns_func['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback)) btns_func['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback)) # create version info - self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.0\nDate: 07/17/2024", font=self.my_font, text_color="#4F4F4F") + self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.2\nDate: 07/26/2024", font=self.my_font, text_color="#4F4F4F") self.frame_func.rowconfigure(6, weight=1) self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s') # ===================================================================== @@ -202,6 +203,7 @@ class App(customtkinter.CTk): if cur_vers.strip() != new_vers.strip(): msg = f"""当前版本:{cur_vers}\n更新版本:{new_vers}\n\n请及时前往钉盘更新~~~""" tkinter.messagebox.showwarning(title="版本更新", message=msg) + self.destroy() except: tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......") # functions below ↓ ---------------------------------------------------------------------------------------- From d2794b2de7e63d15dc8f34e272ed2623ef8f0cce Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 26 Jul 2024 13:38:39 +0800 Subject: [PATCH 26/36] remove sys module --- aio/code/aio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aio/code/aio.py b/aio/code/aio.py index 0fc6ec9..71d38ea 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -1,4 +1,3 @@ -import sys import tkinter from os.path import exists, dirname from os import getcwd From b01f8dc19cfd9b4c9d567eee4d6efe0d0e70c22f Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 27 Jul 2024 21:31:09 +0800 Subject: [PATCH 27/36] =?UTF-8?q?v0.2.0.3(2024/07/27)=201.=20[APIs:=20do?= =?UTF-8?q?=5Fbrake.py]:=20=E7=B2=BE=E7=AE=80=E7=A8=8B=E5=BA=8F=EF=BC=8C?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=20OOM=20=E9=97=AE=E9=A2=98=202.=20[APIs:=20d?= =?UTF-8?q?o=5Fcurrent.py]:=20=E7=B2=BE=E7=AE=80=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=20OOM=20=E9=97=AE=E9=A2=98=203.=20[?= =?UTF-8?q?APIs:=20factory=5Ftest.py]:=20=E7=B2=BE=E7=AE=80=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=EF=BC=8C=E8=A7=A3=E5=86=B3=20OOM=20=E9=97=AE=E9=A2=98?= =?UTF-8?q?=204.=20[APIsL=20openapi.py]=20=20=20=20-=20=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BA=201=20s=EF=BC=8C=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=20OOM=20=E9=97=AE=E9=A2=98=E7=9A=84=E8=A7=A3=E5=86=B3=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E4=BA=8E=E9=95=BF=E4=B9=85=E7=9A=84=E6=89=93=E5=BC=80?= =?UTF-8?q?=E6=9B=B2=E7=BA=BF=E5=BC=80=E5=85=B3=EF=BC=8C=E6=AD=A4=E6=97=B6?= =?UTF-8?q?=E5=AF=B9=E4=BA=8E=20hr.c=5Fmsg=20=E7=9A=84=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E6=B8=85=E7=90=86=E6=98=AF=E4=B8=AA=E6=8C=91=E6=88=98=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=E5=BF=83=E8=B7=B3=E7=BC=A9=E7=9F=AD=EF=BC=8C=E6=9C=89?= =?UTF-8?q?=E5=88=A9=E4=BA=8E=E6=B8=85=E7=90=86=E6=97=A5=E5=BF=97=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E4=B8=A2=E5=A4=B1=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=20=20=20=20-=20=E6=96=B0=E5=A2=9E=20diagnosis.save=20=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=EF=BC=8C=E4=BD=86=E6=98=AF=E6=89=A7=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=9C=89=E9=97=AE=E9=A2=98=EF=BC=8C=E5=BE=85=E8=A7=A3?= =?UTF-8?q?=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 10 +- aio/assets/configs.xlsx | Bin 225318 -> 226625 bytes aio/assets/file_version_info.txt | 8 +- aio/assets/target_brake_current.zip | Bin 27698 -> 27713 bytes aio/assets/target_durable.zip | Bin 19562 -> 19875 bytes aio/assets/templates/heartbeat | 2 +- aio/assets/templates/json/diagnosis.open.json | 4 +- aio/code/aio.py | 2 +- aio/code/automatic_test/do_brake.py | 50 ++++----- aio/code/automatic_test/do_current.py | 96 +++++++++--------- aio/code/durable_action/factory_test.py | 30 ++---- aio/code/openapi.py | 12 ++- 12 files changed, 101 insertions(+), 113 deletions(-) diff --git a/aio/README.md b/aio/README.md index 3919528..0bf3d67 100644 --- a/aio/README.md +++ b/aio/README.md @@ -550,4 +550,12 @@ v0.2.0.2(2024/07/26) 5. 补充了do_current/do_brake的流程图 6. [main: openapi.py] - 将modbus motor_on/off的实现方法改为高电平脉冲触发 -7. configs.xlsx配置表新增write_diagnosis/get_init_speed两个参数 \ No newline at end of file +7. configs.xlsx配置表新增write_diagnosis/get_init_speed两个参数 + +v0.2.0.3(2024/07/27) +1. [APIs: do_brake.py]: 精简程序,解决 OOM 问题 +2. [APIs: do_current.py]: 精简程序,解决 OOM 问题 +3. [APIs: factory_test.py]: 精简程序,解决 OOM 问题 +4. [APIsL openapi.py] + - 心跳修改为 1 s,因为 OOM 问题的解决依赖于长久的打开曲线开关,此时对于 hr.c_msg 的定时清理是个挑战,将心跳缩短,有利于清理日志后,避免丢失心跳 + - 新增 diagnosis.save 命令,但是执行时,有问题,待解决 \ No newline at end of file diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index 8cb640c66f9c4683c6eb9dc28e66e6ddfd5fcc3b..c35dab9d5040a37a0945b415e3a87e9516f78df3 100644 GIT binary patch delta 12703 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 z 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 F_RcpEa_(TF9;Oed&W}nECus+ zAR-6~k|?Tx%2$wfYnaQ_f7Wz|QQS69K!Gh6D{)wK%PwB3{%FZQMueL$$>mk=;9rvdnk2VXwK49R^%X>3d`qMtrx%)ZW z^yaO#x)}pjhANxGb0+5g8FDLaeyHF0Z}IzR>f`GR+Rk^Jb4iGh-`WtIIP!UOZp+Bh zVco&G#;Q84DX>VsS>2_1?6kyeW90%GSN-1w%4E0l^LMIBKdMQXpA6L*O-aZhHxE84 ze(IiGgZ3|Et+b+3Gj*ck(b{m=Z)xONRX5Sqy=d{Jh$KRebX9xa+@()!96J^#$O_l) z)4JqU?7wWdYuqAV^rs}dD{N!h7_d1DMm9wd*sS$re5u3OS6#w#`Rg|(Be7T#DthJQ zjdHM|4Pe+@81%xiw^xN*Y5myW&Q5#cD$f4e3!gHY7>=-5q3XB@ZX)yUXLO zY)6cHM#G&Dz~sOkAY~pW;U0kQQveNJKH)?~JR1~7SydsnfGfb3Wg-#v=x~^o*W$9` zY>c1kX3QA9qhw6lf8FOhTatwm@~Zkc2qKh)RaNKmu0A6MQ~u4)qaH4;#BeVjbx`OX}zGArM?*N z`*vqZiow5Xh1?ov9<9MaeMm%hUtVC9?n%&v!XF3RdVLU znBxVVhudefN|P+cQj2c}b!^BuG$V;FGoy<--njO7D5-_r-(CN5yMeGS=zhA;pwq*j zRhL~BD(CcK@*nSYUKLXld&}NVKm6-(WJ~xH0+B_3P)aqO99euU@uJVJ1Zt)=?WqW$ zSC7YU`>e;uo9Bj9oV<-x)P7s;D&|kK=-PWoB_;>3UP>xys_z@D?kdbbxqoUeMP+h; z(sVhV+ihC9JA7Mm?+xDaI3sF#CpPhyUnZV0b$X$&(4qTs;21R`Mmf1&QXrKaQT@Dm zz+v!STdK`}NNg&0s(#y$79Sp5{8YX66T-b4=-*3$yPFopgP0oy%QpBf3f66~66FT% zt{hK@$2hXW*};+3Z4#FO?cQ7;h(%m)h(lZthz2|cESLSxQ!b#ErvWl~CUD>yPez>O z?S$_Re3@`MUnbDTmkBBfT;RB$z!lJVdHZkdf0wO3fDU>$GRRf5!K z1%XJRz8>zgb&t7&raXe&Q9=;x2b;`C6I>ALz$nc^)KP4QAiT8XWWi^t{}(4D`$6_| zjLF7`8f!Glfr^M`h{s9p__rn>8#{t^^))^%_6PzRxCSuPVG&A*24_UF#+dW( zfm0%_t>P2-AFtC~RsW4O78}KCmhu|yx2~9WE)RuE#f#-1yKz83j4q6y7=sdeKwgXy zWc;E9;n(EgFRKhP=#G&kXD$YnV|rj=7+M-&mA_FBzf?(OyB=C$j@W)h6mbUDWLX^n z{$eWplJR2H(U*xJiJVlC)uH&f4_Ae2-1#&qkWE66U=!?Gl1cocQ3G1Uo8fc^#VElJ zEQ<9cID=fAe8B|EK^Hbx{ND@SWKlbP5G0k868mwSHPs%Q>{^x)3u7fD#C^>Ac!gNF ojUNP?0_CwfaEaf=qT0d!2y%dv{0ABU%K*U?P~uSe+$fy?KUR8>n*aa+ delta 2351 zcmZuz30M7Ja3fMcWq(9oje3xfbb zPYD8#^hz|z7$tg-2pX7xA!sWR{gp&P=s1D1kH$%l>b>={RcQX?$e zjQ~Linr38-+9&EMx=roX>Tk{bK@~sh1Q6J`<_1ihi&#QO%qIXoLZSh#w@~8|3pxI- z(4*BDknjRWk$uBxvmIU5L2k7&+_JE&+cscMZ`i3yiFu>b^*F4dkVbI1PhA<>QSN%a zKtjr3=C|)7AMQ#xYQ;bH%Wa>A;wMcRDdN?gH*2mJ^%5VpgheRJ+?|%qVm|XYU!FR; zX>qwM|K=a8E%I)!NZ)F0Rexw?kffviWI+h56}GF)Eo+nNi>OEQfz0HsyD!FU=opm?bMw? z92^x*LAgYr9>6{c0za{L6AbXdAMj$<6=2=Ih_p*Qanl*&vWSE7 z@Xcp76v-TQT~qTiDP|gU%jem?&xR{!VlJ;*5JLL8?Q!}!oTk4=u7$1Sr$cmWDVaUH zji zbm}rCK5C-D;n1ubRkf7Z9J%`Q6SX=dVT6exd+L?gn+%a`b!T{kl40AXD!CkcAx)EDEk-Fnoqnj%6p&rY%_va1+Fev$^q1QCub-Hwy;<3m zI|7Hv98T{JkSA4JD_`!IBh!xOXLXovDEvX0bELuJ`}NGwW24Ad=f(qTrqc!vT=+Gu zsj#u-7VU+H`2>8#wwK@^n;9UE?D$zVDqtJfY#Y-mvMnNh8QU*(crxyNq9A4}*yxCK zj5O5i<``x&+n}8H={amcivFf=cTw9*kIF{LsBE!ZLVxf&&AcL+K0$kx);d}_G(Gki zyYVcOrW8tm%lRdeq!XRBt%pQeykTAl6mzIZ(_9W8r7 zum8^_g-!lsYHQ=nSZ-at`^{5agy|tfn1iWfGi7&m?#4+52kx~=ofnDt5d!5(nABcx?0s$6r)c*K{qqgVO2>~F! zGl328Lc&&n(+MnqpL5mi(sy|49lqs$0ou1Ds`ccFYF=+58}x_9^9C5h^8t8{=Lhf? zo0jV5C_h#GMrcLHjsTfzzR6$?rRf8EkZ8Xxff&Y;=*f5Tx_L z2rr@CA}T03i77gwnqs;PXOK>(m)T-N>LNqnZ{z)3{*?_uQci~W<2oPMHFiqyf0Xwu zix7;JnkxAei+C=$!wE~pNDx*||97-Ov`$O|L+lYF=3Bxb=m01E6B;Ns127e}k|0`H H@i_m#njN8N diff --git a/aio/assets/target_durable.zip b/aio/assets/target_durable.zip index 54fa8d006af1f4eff7409aadbd2c09a94e76fd8c..695dfb533d91fa5961d8ef9bd873b0226a61130a 100644 GIT binary patch delta 3556 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 K07GmY0Q?6#pDauO diff --git a/aio/assets/templates/heartbeat b/aio/assets/templates/heartbeat index c227083..56a6051 100644 --- a/aio/assets/templates/heartbeat +++ b/aio/assets/templates/heartbeat @@ -1 +1 @@ -0 \ No newline at end of file +1 \ No newline at end of file diff --git a/aio/assets/templates/json/diagnosis.open.json b/aio/assets/templates/json/diagnosis.open.json index 915ff6a..7fe21c2 100644 --- a/aio/assets/templates/json/diagnosis.open.json +++ b/aio/assets/templates/json/diagnosis.open.json @@ -5,8 +5,8 @@ "data": { "open": false, "display_open": false, - "overrun": true, - "turn_area": true, + "overrun": false, + "turn_area": false, "delay_motion": false } } \ No newline at end of file diff --git a/aio/code/aio.py b/aio/code/aio.py index 71d38ea..e90793b 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -105,7 +105,7 @@ class App(customtkinter.CTk): btns_func['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback)) btns_func['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback)) # create version info - self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.2\nDate: 07/26/2024", font=self.my_font, text_color="#4F4F4F") + self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.3\nDate: 07/27/2024", font=self.my_font, text_color="#4F4F4F") self.frame_func.rowconfigure(6, weight=1) self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s') # ===================================================================== diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 28469e7..33868d5 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -90,9 +90,8 @@ def prj_to_xcore(prj_file): print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo print(stderr.read().decode()) # 顺便也执行以下stderr - # _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += f'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' + cmd += 'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') stdin.flush() @@ -120,13 +119,18 @@ def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): for data in curve_data: dict_results = data['data'] for item in dict_results: - item['value'].reverse() + try: + item['value'].reverse() + except KeyError: + continue if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback': _d2d_vel['hw_joint_vel_feedback'].extend(item['value']) elif item.get('channel', None) == axis-1 and item.get('name', None) == 'device_servo_trq_feedback': _d2d_trq['device_servo_trq_feedback'].extend(item['value']) elif item.get('channel', None) == 0 and item.get('name', None) == 'device_safety_estop': _d2d_stop['device_safety_estop'].extend(item['value']) + if len(_d2d_trq['device_servo_trq_feedback']) / 1000 > 10: + break df1 = pandas.DataFrame.from_dict(_d2d_vel) df2 = pandas.DataFrame.from_dict(_d2d_trq) @@ -164,6 +168,8 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): else: w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', tab_name) + _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) for condition in result_dirs: _reach = condition.split('_')[0].removeprefix('reach') _load = condition.split('_')[1].removeprefix('load') @@ -189,9 +195,7 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): md.reset_estop() md.clear_alarm() md.write_act(0) - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) sleep(write_diagnosis) # 软急停超差后,等待写诊断时间,可通过configs.xlsx配置 - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) while count == 1: # 2. 修改未要执行的场景 @@ -236,16 +240,12 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): else: sleep(1) # 4. 打开诊断曲线,并执行采集,之后触发软急停,关闭曲线采集,找出最大速度,传递给RL程序,最后清除相关记录 - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) sleep(get_init_speed) # 获取实际最大速度,可通过configs.xlsx配置 _response = execution('rl_task.stop', hr, w2t, tasks=['brake']) - sleep(1) - _response = execution('state.switch_motor_off', hr, w2t) - _response = execution('state.switch_manual', hr, w2t) - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + # sleep(1) # 找出最大速度 - for _msg in hr.c_msg: + _c_msg = hr.c_msg.copy() + for _msg in _c_msg: if 'diagnosis.result' in _msg: dict_results = loads(_msg)['data'] for item in dict_results: @@ -262,14 +262,10 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): w2t(f"Axis: {axis}-{count} | Speed: {speed_max} | Shouldbe: {speed_target}", 0, 0, 'indigo', tab_name) md.write_speed_max(speed_max) - sleep(1) - for _msg in hr.c_msg: - if 'diagnosis.result' in _msg: - _index = hr.c_msg.index(_msg) - del hr.c_msg[_index:] - hr.c_msg_xs.clear() - break + hr.c_msg_xs.clear() + if len(hr.c_msg) > 240: + del hr.c_msg[240:] if speed_max < 10: md.clear_alarm() @@ -296,8 +292,6 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): else: w2t("未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间 md.write_probe(1) _t_start = time() @@ -305,29 +299,25 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): if md.read_brake_done() == 1: sleep(1) # 保证速度归零 md.write_probe(0) - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) break else: if (time() - _t_start) > 30: w2t(f"30s内未触发急停,该条数据无效,需要确认RL/Python程序编写正确并正常执行,或者判别是否是机器本体问题,比如正负方向速度是否一致...", 0, 0, 'red', tab_name) md.write_probe(0) - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) break else: sleep(1) # 6. 保留数据并处理输出 curve_data = [] - for _msg in hr.c_msg: + _c_msg = hr.c_msg.copy() + for _msg in _c_msg: if 'diagnosis.result' in _msg: curve_data.insert(0, loads(_msg)) else: - for _msg in hr.c_msg: - if 'diagnosis.result' in _msg: - _index = hr.c_msg.index(_msg) - del hr.c_msg[_index:] - hr.c_msg_xs.clear() - break + hr.c_msg_xs.clear() + if len(hr.c_msg) > 240: + del hr.c_msg[240:] gen_result_file(path, curve_data, axis, _reach, _load, _speed, count) else: w2t(f"\n{loadsel.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。", 0, 0, 'green', tab_name) diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index d46e0e0..b47a77d 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -7,6 +7,20 @@ from paramiko import SSHClient, AutoAddPolicy from json import loads import pandas +display_pdo_params = [ + {"name": "hw_joint_vel_feedback", "channel": 0}, + {"name": "hw_joint_vel_feedback", "channel": 1}, + {"name": "hw_joint_vel_feedback", "channel": 2}, + {"name": "hw_joint_vel_feedback", "channel": 3}, + {"name": "hw_joint_vel_feedback", "channel": 4}, + {"name": "hw_joint_vel_feedback", "channel": 5}, + {"name": "device_servo_trq_feedback", "channel": 0}, + {"name": "device_servo_trq_feedback", "channel": 1}, + {"name": "device_servo_trq_feedback", "channel": 2}, + {"name": "device_servo_trq_feedback", "channel": 3}, + {"name": "device_servo_trq_feedback", "channel": 4}, + {"name": "device_servo_trq_feedback", "channel": 5}, +] def traversal_files(path, w2t): if not exists(path): @@ -75,9 +89,8 @@ def prj_to_xcore(prj_file): print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo print(stderr.read().decode()) # 顺便也执行以下stderr - # _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += f'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' + cmd += 'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') stdin.flush() @@ -107,7 +120,10 @@ def data_proc_regular(path, filename, channel, scenario_time): for line in lines: data = eval(line.strip())['data'] for item in data: - item['value'].reverse() + try: + item['value'].reverse() + except KeyError: + continue if item.get('channel', None) == channel and item.get('name', None) == 'hw_joint_vel_feedback': _d2d_vel['hw_joint_vel_feedback'].extend(item['value']) elif item.get('channel', None) == channel and item.get('name', None) == 'device_servo_trq_feedback': @@ -136,7 +152,10 @@ def data_proc_regular(path, filename, channel, scenario_time): for line in lines: data = eval(line.strip())['data'] for item in data: - item['value'].reverse() + try: + item['value'].reverse() + except KeyError: + continue if item.get('channel', None) == 0 and item.get('name', None) == 'hw_joint_vel_feedback': _d2d_vel_0['hw_joint_vel_feedback'].extend(item['value']) elif item.get('channel', None) == 0 and item.get('name', None) == 'device_servo_trq_feedback': @@ -205,7 +224,10 @@ def data_proc_regular(path, filename, channel, scenario_time): for line in lines: data = eval(line.strip())['data'] for item in data: - item['value'].reverse() + try: + item['value'].reverse() + except KeyError: + continue if item.get('channel', None) == channel-9 and item.get('name', None) == 'hw_joint_vel_feedback': _d2d_vel['hw_joint_vel_feedback'].extend(item['value']) elif item.get('channel', None) == channel-9 and item.get('name', None) == 'device_servo_trq_feedback': @@ -226,7 +248,10 @@ def data_proc_inertia(path, filename, channel): for line in lines: data = eval(line.strip())['data'] for item in data: - item['value'].reverse() + try: + item['value'].reverse() + except KeyError: + continue if item.get('channel', None) == channel+3 and item.get('name', None) == 'hw_joint_vel_feedback': _d2d_vel['hw_joint_vel_feedback'].extend(item['value']) elif item.get('channel', None) == channel+3 and item.get('name', None) == 'device_servo_trq_feedback': @@ -287,20 +312,19 @@ def run_rl(path, hr, md, loadsel, w2t): conditions = c_inertia disc = disc_inertia + # preparation 触发软急停,并解除,目的是让可能正在运行着的机器停下来 + _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) + # _response = execution('diagnosis.save', hr, w2t, save=True) # 这条命令有问题 + md.trigger_estop() + md.reset_estop() + for condition in conditions: number = conditions.index(condition) w2t(f"正在执行{disc[number][0]}测试......", 0, 0, 'purple', 'Automatic Test') - # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - md.trigger_estop() - md.reset_estop() + # 1. 将act重置为False,并修改未要执行的场景 md.write_act(False) - sleep(1) # 让曲线彻底关闭 - _response = execution('state.switch_manual', hr, w2t) - _response = execution('state.switch_motor_off', hr, w2t) - - # 2. 修改未要执行的场景 ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') @@ -313,15 +337,14 @@ def run_rl(path, hr, md, loadsel, w2t): print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo print(stderr.read().decode()) # 顺便也执行以下stderr - # 3. reload工程后,pp2main,并且自动模式和上电 + # 2. reload工程后,pp2main,并且自动模式和上电 prj_path = 'target/_build/target.prj' _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['current']) - _response = execution('overview.get_cur_prj', hr, w2t) _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['current']) _response = execution('state.switch_auto', hr, w2t) _response = execution('state.switch_motor_on', hr, w2t) - # 4. 开始运行程序,单轴运行15s + # 3. 开始运行程序,单轴运行35s _response = execution('rl_task.run', hr, w2t, tasks=['current']) _t_start = time() while True: @@ -334,25 +357,8 @@ def run_rl(path, hr, md, loadsel, w2t): else: sleep(1) - # 5. 打开诊断曲线,并执行采集 + # 4. 打开诊断曲线,并执行采集 sleep(10) # 保证程序已经运行起来,其实主要是为了保持电流的采集而设定 - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - display_pdo_params = [ - {"name": "hw_joint_vel_feedback", "channel": 0}, - {"name": "hw_joint_vel_feedback", "channel": 1}, - {"name": "hw_joint_vel_feedback", "channel": 2}, - {"name": "hw_joint_vel_feedback", "channel": 3}, - {"name": "hw_joint_vel_feedback", "channel": 4}, - {"name": "hw_joint_vel_feedback", "channel": 5}, - {"name": "device_servo_trq_feedback", "channel": 0}, - {"name": "device_servo_trq_feedback", "channel": 1}, - {"name": "device_servo_trq_feedback", "channel": 2}, - {"name": "device_servo_trq_feedback", "channel": 3}, - {"name": "device_servo_trq_feedback", "channel": 4}, - {"name": "device_servo_trq_feedback", "channel": 5}, - {"name": "device_safety_estop", "channel": 0}, - ] - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) scenario_time = 0 if number < 6: sleep(35) @@ -374,24 +380,16 @@ def run_rl(path, hr, md, loadsel, w2t): scenario_time = md.read_scenario_time() sleep(float(scenario_time)*0.2) # 再运行周期的20%即可 - # 6. 关闭诊断曲线,停止程序运行,下电并且换成手动模式 - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + # 5.停止程序运行,保留数据并处理输出 _response = execution('rl_task.stop', hr, w2t, tasks=['current']) - _response = execution('state.switch_motor_off', hr, w2t) - _response = execution('state.switch_manual', hr, w2t) - sleep(1) # 保证所有数据均已返回 - # 7. 保留数据并处理输出 - for _msg in hr.c_msg: + _c_msg = hr.c_msg.copy() + for _msg in _c_msg: if 'diagnosis.result' in _msg: disc[number][1].insert(0, loads(_msg)) else: - _index = 210 - for _msg in hr.c_msg: - if 'diagnosis.result' in _msg: - _index = hr.c_msg.index(_msg) - break - del hr.c_msg[_index:] hr.c_msg_xs.clear() + if len(hr.c_msg) > 240: + del hr.c_msg[240:] gen_result_file(path, loadsel, disc, number, scenario_time) else: if loadsel == 'tool100': diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index c596ad5..094b416 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -81,9 +81,8 @@ def prj_to_xcore(prj_file): print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo print(stderr.read().decode()) # 顺便也执行以下stderr - _prj_name = prj_file.split('\\')[-1].removesuffix('.zip') cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += f'sudo mv projects/target/_build/{_prj_name}.prj projects/target/_build/target.prj' + cmd += 'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') stdin.flush() @@ -106,7 +105,8 @@ def execution(cmd, hr, w2t, **kwargs): def run_rl(path, config_file, data_all, hr, md, w2t): # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) + _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) + _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) md.trigger_estop() md.reset_estop() md.write_act(False) @@ -115,7 +115,6 @@ def run_rl(path, config_file, data_all, hr, md, w2t): # 2. reload工程后,pp2main,并且自动模式和上电 prj_path = 'target/_build/target.prj' _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['current']) - _response = execution('overview.get_cur_prj', hr, w2t) _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['current']) _response = execution('state.switch_auto', hr, w2t) _response = execution('state.switch_motor_on', hr, w2t) @@ -134,8 +133,7 @@ def run_rl(path, config_file, data_all, hr, md, w2t): sleep(1) # 4. 获取初始数据,周期时间,首次的各轴平均电流值,打开诊断曲线,并执行采集 - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) + sleep(20) # 初始化 scenario time 为 0 _t_start = time() while True: scenario_time = md.read_scenario_time() @@ -162,36 +160,26 @@ def run_rl(path, config_file, data_all, hr, md, w2t): for i in range(6): rcs.append(float(_ws.cell(row=6, column=i + 2).value)) - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - sleep(1) # 保证所有数据均已返回 get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, md, w2t) # 7. 继续运行 while True: # 固定间隔,更新一次数据,打开曲线,获取周期内电流,关闭曲线 - sleep(wait_time) - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) - sleep(scenario_time+5) - _response = execution('diagnosis.open', hr, w2t, open=False, display_open=False) - sleep(2) + sleep(wait_time+scenario_time+7) # 保留数据并处理输出 get_durable_data(path, data_all, scenario_time, wait_time, rcs, hr, md, w2t) def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, md, w2t): _data_list = [] - for _msg in hr.c_msg: + _c_msg = hr.c_msg.copy() + for _msg in _c_msg: if 'diagnosis.result' in _msg: _data_list.insert(0, loads(_msg)) else: - _index = 210 - for _msg in hr.c_msg: - if 'diagnosis.result' in _msg: - _index = hr.c_msg.index(_msg) - break - del hr.c_msg[_index:] hr.c_msg_xs.clear() + if len(hr.c_msg) > 240: + del hr.c_msg[240:] # with open(f'{path}\\log.txt', 'w', encoding='utf-8') as f_obj: # for _ in _data_list: diff --git a/aio/code/openapi.py b/aio/code/openapi.py index fd86742..ed70430 100644 --- a/aio/code/openapi.py +++ b/aio/code/openapi.py @@ -261,10 +261,12 @@ class HmiRequest(object): f_hb.write(_flag) if _flag == '0': self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) - sleep(2) - # with open(f"{current_path}/../assets/templates/c_msg.log", "w", encoding='utf-8') as f: - # for msg in self.c_msg: - # f.write(str(loads(msg)) + '\n') + t = time() + with open(f"{current_path}/../assets/templates/c_msg.log", "w", encoding='utf-8') as f: + for msg in self.c_msg: + f.write(str(t) + '-' + str(loads(msg)) + '\n') + sleep(1) + def msg_storage(self, response, flag=0): # response是解码后的字符串 @@ -604,6 +606,8 @@ class HmiRequest(object): req['data']['type'] = kwargs['type'] req['data']['bias'] = kwargs['bias'] req['data']['value'] = kwargs['value'] + case 'diagnosis.save': + req['data']['save'] = kwargs['save'] case _: pass From af68f19d537fd0a6bc12ff6e0b368d7133868bdc Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 27 Jul 2024 21:32:02 +0800 Subject: [PATCH 28/36] vers info --- aio/assets/vers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/assets/vers b/aio/assets/vers index e78860d..81dc3db 100644 --- a/aio/assets/vers +++ b/aio/assets/vers @@ -1 +1 @@ -0.2.0.2 @ 07/26/2024 \ No newline at end of file +0.2.0.3 @ 07/27/2024 \ No newline at end of file From a7984a613dd9199a4684f9f233b1a4313dee54b2 Mon Sep 17 00:00:00 2001 From: gitea Date: Tue, 30 Jul 2024 12:30:37 +0800 Subject: [PATCH 29/36] =?UTF-8?q?v0.2.0.4(2024/07/30)=201.=20[APIs:=20do?= =?UTF-8?q?=5Fbrake.py]:=20=E4=BF=AE=E5=A4=8D=E5=88=B6=E5=8A=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=A4=84=E7=90=86=E8=BF=87=E7=A8=8B=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E5=8F=AA=E5=8F=96=E6=9B=B2=E7=BA=BF=E7=9A=84=E6=9C=80=E5=90=8E?= =?UTF-8?q?=20240=20=E4=B8=AA=E6=95=B0=E6=8D=AE=202.=20[APIs:=20aio.py]:?= =?UTF-8?q?=20=E5=88=A4=E5=AE=9A=E7=89=88=E6=9C=AC=E5=A4=84=EF=BC=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20self.destroy()=EF=BC=8C=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=E8=AF=A5=E8=AF=AD=E5=8F=A5=E4=BC=9A=E5=AF=BC=E8=87=B4=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=8F=91=E7=94=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 6 +++++- aio/code/aio.py | 1 - aio/code/automatic_test/do_brake.py | 4 +--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/aio/README.md b/aio/README.md index 0bf3d67..906fcf2 100644 --- a/aio/README.md +++ b/aio/README.md @@ -558,4 +558,8 @@ v0.2.0.3(2024/07/27) 3. [APIs: factory_test.py]: 精简程序,解决 OOM 问题 4. [APIsL openapi.py] - 心跳修改为 1 s,因为 OOM 问题的解决依赖于长久的打开曲线开关,此时对于 hr.c_msg 的定时清理是个挑战,将心跳缩短,有利于清理日志后,避免丢失心跳 - - 新增 diagnosis.save 命令,但是执行时,有问题,待解决 \ No newline at end of file + - 新增 diagnosis.save 命令,但是执行时,有问题,待解决 + +v0.2.0.4(2024/07/30) +1. [APIs: do_brake.py]: 修复制动数据处理过程中,只取曲线的最后 240 个数据 +2. [APIs: aio.py]: 判定版本处,删除 self.destroy(),因为该语句会导致异常发生 \ No newline at end of file diff --git a/aio/code/aio.py b/aio/code/aio.py index e90793b..979c7a3 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -202,7 +202,6 @@ class App(customtkinter.CTk): if cur_vers.strip() != new_vers.strip(): msg = f"""当前版本:{cur_vers}\n更新版本:{new_vers}\n\n请及时前往钉盘更新~~~""" tkinter.messagebox.showwarning(title="版本更新", message=msg) - self.destroy() except: tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......") # functions below ↓ ---------------------------------------------------------------------------------------- diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 33868d5..223b6e3 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -116,7 +116,7 @@ def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): _d2d_vel = {'hw_joint_vel_feedback': []} _d2d_trq = {'device_servo_trq_feedback': []} _d2d_stop = {'device_safety_estop': []} - for data in curve_data: + for data in curve_data[-240:]: dict_results = data['data'] for item in dict_results: try: @@ -129,8 +129,6 @@ def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): _d2d_trq['device_servo_trq_feedback'].extend(item['value']) elif item.get('channel', None) == 0 and item.get('name', None) == 'device_safety_estop': _d2d_stop['device_safety_estop'].extend(item['value']) - if len(_d2d_trq['device_servo_trq_feedback']) / 1000 > 10: - break df1 = pandas.DataFrame.from_dict(_d2d_vel) df2 = pandas.DataFrame.from_dict(_d2d_trq) From 04bd1238d213e9edfbda8f9b6572d25105fc57b8 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 31 Jul 2024 08:05:36 +0800 Subject: [PATCH 30/36] =?UTF-8?q?v0.2.0.5(2024/07/31)=20=E6=AD=A4=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E6=94=B9=E5=8A=A8=E8=BE=83=E5=A4=A7=EF=BC=8C=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E9=83=A8=E5=88=86=E5=81=9A=E4=BA=86=E8=A7=84=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E6=94=BE=E7=BD=AE=E5=88=B0=E6=96=B0=E5=BB=BA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9=20commons=20=E5=BD=93=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E6=89=80=E6=9C=89=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=BC=95=E5=85=A5=20logging=20=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E8=AE=B0=E5=BD=95=E9=87=8D=E8=A6=81=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=201.=20[t=5Fchange=5Fui:=20clibs.py]=20=20=20=20-=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=BB=A3=E7=A0=81=E7=BB=84=E7=BB=87=E7=BB=93=E6=9E=84?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=B0=86?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E5=87=BD=E6=95=B0=E4=BB=A5=E5=8F=8A=E7=B1=BB?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=85=A5=E6=AD=A4=20=20=20=20-=20=E5=B0=86?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=B8=B8=E9=87=8F=E6=94=BE=E5=85=A5=E8=AF=A5?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=20=20=20=20-=20=E5=BC=95=E5=85=A5logging/con?= =?UTF-8?q?current=5Flog=5Fhandler=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E4=BD=9C=E5=88=9D=E5=A7=8B=E5=8C=96=E6=93=8D=E4=BD=9C=EF=BC=8C?= =?UTF-8?q?=E4=BE=9B=E5=85=B6=E4=BB=96=E6=A8=A1=E5=9D=97=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=EF=BC=8C=E6=8C=8950M=E5=88=87=E5=89=B2=EF=BC=8C=E6=9C=80?= =?UTF-8?q?=E5=A4=9A=E4=BF=9D=E7=95=9910=E4=BB=BD=20=20=20=20-=20prj=5Fto?= =?UTF-8?q?=5Fxcore=E5=87=BD=E6=95=B0=E8=AE=BE=E7=BD=AE=E5=B7=A5=E7=A8=8B?= =?UTF-8?q?=E5=90=8D=E9=83=A8=E5=88=86=E9=87=8D=E5=86=99=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BA=86=E5=A4=9A=E4=B8=AAprj=E5=B7=A5=E7=A8=8B?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E4=B8=8D=E8=83=BD=E6=89=A7=E8=A1=8C=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=202.=20[t=5Fchange=5Fui:=20openapi.py]=20=20?= =?UTF-8?q?=20=20-=20=E5=AE=8C=E5=85=A8=E9=87=8D=E5=86=99=E4=BA=86=20get?= =?UTF-8?q?=5Ffrom=5Fid=20=E5=87=BD=E6=95=B0=EF=BC=8C=E4=BD=BF=E6=9B=B4?= =?UTF-8?q?=E7=B2=BE=E5=87=86=20=20=20=20-=20=E5=9C=A8=20msg=5Fstorage=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E4=B8=AD=EF=BC=8C=E5=A2=9E=E5=8A=A0=20logger?= =?UTF-8?q?=EF=BC=8C=E4=BF=9D=E7=95=99=E6=89=80=E6=9C=89=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E6=B6=88=E6=81=AF=20=20=20=20-=20=E5=88=A0=E9=99=A4=20heartbea?= =?UTF-8?q?t=20=E5=87=BD=E6=95=B0=E4=B8=AD=E7=9A=84=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=8A=9F=E8=83=BD=E9=83=A8=E5=88=86=20=20=20?= =?UTF-8?q?=20-=20=E5=BF=83=E8=B7=B3=E5=86=8D=E6=AC=A1=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=202s...=203.=20[t=5Fchange=5Fui:=20aio.py]=20=20=20?= =?UTF-8?q?=20-=20=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=97=A5=E5=BF=97=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E9=83=A8=E5=88=86=20=20=20=20-=20detect=5Fne?= =?UTF-8?q?twork=20=E5=87=BD=E6=95=B0=E4=B8=AD=E4=BF=AE=E6=94=B9=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E5=AE=9E=E4=BE=8B=E5=8C=96HR=E9=97=B4=E9=9A=94?= =?UTF-8?q?=E4=B8=BA=204s=EF=BC=8C=E5=AF=B9=E5=BA=94=E5=BF=83=E8=B7=B3=204?= =?UTF-8?q?.=20[t=5Fchange=5Fui:=20do=5Fbrake.py]=20=20=20=20-=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E4=B8=80=E7=9B=B4=E6=89=93=E5=BC=80=E6=9B=B2=E7=BA=BF?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=E8=A7=84=E9=81=BF=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E4=BA=86=20OOM=20=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=EF=BC=8C=E5=8F=AA=E5=8F=96=E6=9C=80=E5=90=8E?= =?UTF-8?q?=2012s=205.=20[t=5Fchange=5Fui:=20do=5Fcurrent.py]=20=20=20=20-?= =?UTF-8?q?=20=E4=BF=9D=E6=8C=81=E7=94=B5=E6=B5=81=EF=BC=8C=E5=8F=AA?= =?UTF-8?q?=E5=8F=96=E6=9C=80=E5=90=8E=2015s=206.=20[t=5Fchange=5Fui:=20al?= =?UTF-8?q?l=20the=20part]:=20=E5=BC=95=E5=85=A5=20commons=20=E5=8C=85?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=AE=9A=E5=88=B6=E4=BA=86=20logging=20?= =?UTF-8?q?=E8=BE=93=E5=87=BA=EF=BC=8C=E5=90=8E=E7=BB=AD=E6=8C=81=E7=BB=AD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +- aio/README.md | 32 +++- aio/assets/file_version_info.txt | 8 +- aio/assets/requirements.txt | 14 +- aio/assets/vers | 2 +- aio/code/__init__.py | 1 - aio/code/aio.py | 102 ++++++------- aio/code/automatic_test/__init__.py | 1 - aio/code/automatic_test/btn_functions.py | 35 ++--- aio/code/automatic_test/do_brake.py | 123 ++++----------- aio/code/automatic_test/do_current.py | 185 ++++++++--------------- aio/code/commons/clibs.py | 131 ++++++++++++++++ aio/code/{ => commons}/openapi.py | 89 ++++++----- aio/code/data_process/__init__.py | 1 - aio/code/data_process/brake.py | 52 ++----- aio/code/data_process/current.py | 52 +------ aio/code/data_process/iso.py | 25 +-- aio/code/data_process/wavelogger.py | 38 ++--- aio/code/durable_action/__init__.py | 1 - aio/code/durable_action/factory_test.py | 112 +++----------- 20 files changed, 424 insertions(+), 586 deletions(-) delete mode 100644 aio/code/__init__.py delete mode 100644 aio/code/automatic_test/__init__.py create mode 100644 aio/code/commons/clibs.py rename aio/code/{ => commons}/openapi.py (92%) delete mode 100644 aio/code/data_process/__init__.py delete mode 100644 aio/code/durable_action/__init__.py diff --git a/.gitignore b/.gitignore index 89a9f58..d0af568 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ aio/venv aio/__pycache__/ aio/code/automatic_test/__pycache__/ aio/code/data_process/__pycache__/ -aio/assets/templates/c_msg.log +aio/assets/templates/c_msg.log* aio/code/durable_action/__pycache__/ -aio/assets/templates/durable/ \ No newline at end of file +aio/assets/templates/durable/ +aio/assets/templates/.__c_msg.lock +aio/code/commons/__pycache__/ \ No newline at end of file diff --git a/aio/README.md b/aio/README.md index 0bf3d67..4d1469d 100644 --- a/aio/README.md +++ b/aio/README.md @@ -31,9 +31,10 @@ ### 四、打包方法 +打包时,只需要修改 clibs.py 中的 PREFIX 即可,调试时再修改回来 + ``` -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 ..\assets\file_version_info.txt -i ..\assets\icon.ico ..\code\aio.py -p ..\code\data_process\brake.py -p ..\code\data_process\iso.py -p ..\code\data_process\current.py -p ..\code\data_process\wavelogger.py +pyinstaller --noconfirm --onedir --windowed --optimize 2 --contents-directory . --upx-dir "D:/Syncthing/common/A_Program/upx-4.2.4-win64/" --add-data "C:/Users/Administrator/AppData/Local/Programs/Python/Python312/Lib/site-packages/customtkinter;customtkinter/" --add-data "D:/Syncthing/company/D-测试工作/X-自动化测试/01-AIO/rokae/aio/assets/templates:templates" --version-file ../assets/file_version_info.txt -i ../assets/icon.ico ../code/aio.py -p ../code/data_process/brake.py -p ../code/data_process/iso.py -p ../code/data_process/current.py -p ../code/data_process/wavelogger.py -p ../code/commons/openapi.py -p ../code/commons/clibs.py -p ../code/automatic_test/btn_functions.py -p ../code/automatic_test/do_current.py -p ../code/automatic_test/do_brake.py -p ../code/durable_action/factory_test.py ``` --- @@ -557,5 +558,28 @@ v0.2.0.3(2024/07/27) 2. [APIs: do_current.py]: 精简程序,解决 OOM 问题 3. [APIs: factory_test.py]: 精简程序,解决 OOM 问题 4. [APIsL openapi.py] - - 心跳修改为 1 s,因为 OOM 问题的解决依赖于长久的打开曲线开关,此时对于 hr.c_msg 的定时清理是个挑战,将心跳缩短,有利于清理日志后,避免丢失心跳 - - 新增 diagnosis.save 命令,但是执行时,有问题,待解决 \ No newline at end of file + - 心跳修改为 1s,因为 OOM 问题的解决依赖于长久的打开曲线开关,此时对于 hr.c_msg 的定时清理是个挑战,将心跳缩短,有利于清理日志后,避免丢失心跳 + - 新增 diagnosis.save 命令,但是执行时,有问题,待解决 + +v0.2.0.5(2024/07/31) +此版本改动较大,公共部分做了规整,放置到新建文件夹 commons 当中,并所有自定义模块引入 logging 模块,记录重要信息 +1. [t_change_ui: clibs.py] + - 调整代码组织结构,新增模块,将公共函数以及类合并入此 + - 将一些常量放入该模块 + - 引入logging/concurrent_log_handler模块,并作初始化操作,供其他模块使用,按50M切割,最多保留10份 + - prj_to_xcore函数设置工程名部分重写,修复了多个prj工程可能不能执行的问题 +2. [t_change_ui: openapi.py] + - 完全重写了 get_from_id 函数,使更精准 + - 在 msg_storage 函数中,增加 logger,保留所有响应消息 + - 删除 heartbeat 函数中的日志保存功能部分 + - 心跳再次修改为 2s... +3. [t_change_ui: aio.py] + - 增加了日志初始化部分 + - detect_network 函数中修改重新实例化HR间隔为 4s,对应心跳 +4. [t_change_ui: do_brake.py] + - 使用一直打开曲线的方法规避解决了 OOM 的问题,同时修改数据处理方式,只取最后 12s +5. [t_change_ui: do_current.py] + - 保持电流,只取最后 15s +6. [t_change_ui: all the part]: 引入 commons 包,并定制了 logging 输出,后续持续优化 + + diff --git a/aio/assets/file_version_info.txt b/aio/assets/file_version_info.txt index a4ff150..ec3ed0c 100644 --- a/aio/assets/file_version_info.txt +++ b/aio/assets/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, 2, 0, 3), - prodvers=(0, 2, 0, 3), + filevers=(0, 2, 0, 5), + prodvers=(0, 2, 0, 5), # 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 toolbox'), - StringStruct('FileVersion', '0.2.0.3 (2024-07-27)'), + StringStruct('FileVersion', '0.2.0.5 (2024-08-02)'), StringStruct('InternalName', 'AIO.exe'), StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'), StringStruct('OriginalFilename', 'AIO.exe'), StringStruct('ProductName', 'AIO'), - StringStruct('ProductVersion', '0.2.0.3 (2024-07-27)')]) + StringStruct('ProductVersion', '0.2.0.5 (2024-08-02)')]) ]), VarFileInfo([VarStruct('Translation', [1033, 1200])]) ] diff --git a/aio/assets/requirements.txt b/aio/assets/requirements.txt index ad41cdf..63a94b4 100644 --- a/aio/assets/requirements.txt +++ b/aio/assets/requirements.txt @@ -1,9 +1,9 @@ -openpyxl==3.1.2 -pdfplumber==0.11.0 +concurrent_log_handler==0.9.25 customtkinter==5.2.2 -Jinja2==3.1.4 -lxml==5.2.2 -numpy==1.26.4 +matplotlib==3.9.1 +numpy==2.0.1 +openpyxl==3.1.2 pandas==2.2.2 -pillow==10.3.0 -pyinstaller==6.7.0 +paramiko==3.4.0 +pdfplumber==0.11.0 +pymodbus==3.6.9 diff --git a/aio/assets/vers b/aio/assets/vers index 81dc3db..4f1ec33 100644 --- a/aio/assets/vers +++ b/aio/assets/vers @@ -1 +1 @@ -0.2.0.3 @ 07/27/2024 \ No newline at end of file +0.2.0.5 @ 08/02/2024 \ No newline at end of file diff --git a/aio/code/__init__.py b/aio/code/__init__.py deleted file mode 100644 index e6e51aa..0000000 --- a/aio/code/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['automatic_test', 'data_process'] \ No newline at end of file diff --git a/aio/code/aio.py b/aio/code/aio.py index e90793b..a535af9 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -1,49 +1,37 @@ import tkinter -from os.path import exists, dirname -from os import getcwd +from os.path import exists +from os import getcwd, remove from threading import Thread import tkinter.messagebox import customtkinter from time import time, strftime, localtime, sleep from urllib.request import urlopen -from socket import setdefaulttimeout from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from data_process import * -from automatic_test import * -from durable_action import * -import openapi -import matplotlib.pyplot as plt +from data_process import brake, current, iso, wavelogger +from automatic_test import do_current, do_brake, btn_functions +from durable_action import factory_test +from commons import openapi, clibs +from matplotlib.pyplot import rcParams, figure, subplots_adjust from matplotlib import use from pandas import DataFrame, read_excel +import logging + +with open(clibs.log_data, 'w') as _: + for i in range(1, 11): + try: + remove(f'{clibs.log_data}.{i}') + except FileNotFoundError: + pass +logger = logging.getLogger(__file__) +logger.info("日志文件初始化完成...") use('Agg') -heartbeat = f'{dirname(__file__)}/../assets/templates/heartbeat' -durable_data_current_xlsx = f'{dirname(__file__)}/../assets/templates/durable/durable_data_current.xlsx' -durable_data_current_max_xlsx = f'{dirname(__file__)}/../assets/templates/durable/durable_data_current_max.xlsx' customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light" 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_window_scaling(1.1) # window geometry dimensions -setdefaulttimeout(3) + # global vars -durable_data_current = { - 'time': list(range(1, 19)), - 'axis1': [0 for _ in range(18)], - 'axis2': [0 for _ in range(18)], - 'axis3': [0 for _ in range(18)], - 'axis4': [0 for _ in range(18)], - 'axis5': [0 for _ in range(18)], - 'axis6': [0 for _ in range(18)], -} -durable_data_current_max = { - 'time': list(range(1, 19)), - 'axis1': [0 for _ in range(18)], - 'axis2': [0 for _ in range(18)], - 'axis3': [0 for _ in range(18)], - 'axis4': [0 for _ in range(18)], - 'axis5': [0 for _ in range(18)], - 'axis6': [0 for _ in range(18)], -} btns_func = { 'start': {'btn': '', 'row': 1, 'text': '开始运行'}, 'check': {'btn': '', 'row': 2, 'text': '检查参数'}, @@ -79,6 +67,7 @@ class App(customtkinter.CTk): self.flg = 0 self.df_copy = None self.old_curve = None + self.myThread = None # ===================================================================== # configure window self.title("AIO - All in one automatic toolbox") @@ -202,37 +191,36 @@ class App(customtkinter.CTk): if cur_vers.strip() != new_vers.strip(): msg = f"""当前版本:{cur_vers}\n更新版本:{new_vers}\n\n请及时前往钉盘更新~~~""" tkinter.messagebox.showwarning(title="版本更新", message=msg) - self.destroy() except: tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......") # functions below ↓ ---------------------------------------------------------------------------------------- - def create_canvas(self, figure): - self.canvas = FigureCanvasTkAgg(figure, self.tabview.tab('Durable Action')) + def create_canvas(self, _figure): + self.canvas = FigureCanvasTkAgg(_figure, self.tabview.tab('Durable Action')) self.canvas.draw() self.canvas.get_tk_widget().configure(height=600) self.canvas.get_tk_widget().grid(row=3, column=1, rowspan=3, columnspan=13, padx=20, pady=10, sticky="nsew") def create_plot(self): - plt.rcParams['font.sans-serif'] = ['SimHei'] - plt.rcParams['axes.unicode_minus'] = False - plt.rcParams['figure.dpi'] = 100 - plt.rcParams['font.size'] = 14 - plt.rcParams['lines.marker'] = 'o' + rcParams['font.sans-serif'] = ['SimHei'] + rcParams['axes.unicode_minus'] = False + rcParams['figure.dpi'] = 100 + rcParams['font.size'] = 14 + rcParams['lines.marker'] = 'o' curvesel = widgits_da['curvesel']['optionmenu'].get() while True: if not self.hr.durable_lock: self.hr.durable_lock = 1 if curvesel == 'device_servo_trq_feedback': - df = read_excel(durable_data_current_xlsx) + df = read_excel(clibs.durable_data_current_xlsx) _title = 'device_servo_trq_feedback' elif curvesel == '[max] device_servo_trq_feedback': _title = '[max] device_servo_trq_feedback' - df = read_excel(durable_data_current_max_xlsx) + df = read_excel(clibs.durable_data_current_max_xlsx) else: _title = 'device_servo_trq_feedback' - df = read_excel(durable_data_current_xlsx) + df = read_excel(clibs.durable_data_current_xlsx) self.hr.durable_lock = 0 break else: @@ -242,12 +230,12 @@ class App(customtkinter.CTk): self.flg = 1 self.df_copy = df.copy() self.old_curve = widgits_da['curvesel']['optionmenu'].get() - figure = plt.figure(frameon=True, facecolor='#E9E9E9') - plt.subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.95) + _figure = figure(frameon=True, facecolor='#E9E9E9') + subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.95) _ = df['time'].to_list() _xticks = [str(_i) for _i in _] - ax = figure.add_subplot(1, 1, 1) + ax = _figure.add_subplot(1, 1, 1) ax.set_xticks(range(len(_xticks))) ax.set_xticklabels(_xticks) @@ -258,7 +246,7 @@ class App(customtkinter.CTk): df.plot(grid=True, x='time', y='axis5', ax=ax) df.plot(grid=True, x='time', y='axis6', ax=ax, title=_title, legend='upper left', rot=30) - self.create_canvas(figure) + self.create_canvas(_figure) def thread_it(self, func, *args): """ 将函数打包进线程 """ @@ -273,7 +261,7 @@ class App(customtkinter.CTk): self.seg_button.configure(state='disabled') # self.tabview.configure(state='disabled') self.textbox.delete(index1='1.0', index2='end') - with open(heartbeat, 'r', encoding='utf-8') as f_h: + with open(clibs.heartbeat, 'r', encoding='utf-8') as f_h: c_state = f_h.read().strip() if c_state == '0' and value != '功能切换': @@ -288,12 +276,12 @@ class App(customtkinter.CTk): # self.tabview.configure(state='normal') def detect_network(self): - df = DataFrame(durable_data_current) - df.to_excel(durable_data_current_xlsx, index=False) - df = DataFrame(durable_data_current_max) - df.to_excel(durable_data_current_max_xlsx, index=False) + df = DataFrame(clibs.durable_data_current) + df.to_excel(clibs.durable_data_current_xlsx, index=False) + df = DataFrame(clibs.durable_data_current_max) + df.to_excel(clibs.durable_data_current_max_xlsx, index=False) - with open(heartbeat, "w", encoding='utf-8') as f_hb: + with open(clibs.heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('0') self.hr = openapi.HmiRequest(self.write2textbox) self.md = openapi.ModbusRequest(self.write2textbox) @@ -302,14 +290,14 @@ class App(customtkinter.CTk): if self.tabview.get() == 'Durable Action': self.create_plot() - with open(heartbeat, 'r', encoding='utf-8') as f_hb: + with open(clibs.heartbeat, 'r', encoding='utf-8') as f_hb: c_state = f_hb.read().strip() pb_color = 'green' if c_state == '1' else 'red' self.progressbar.configure(progress_color=pb_color) self.progressbar_da.configure(progress_color=pb_color) if c_state == '0': self.hr.t_bool = False - sleep(3) + sleep(4) del self.hr self.hr = openapi.HmiRequest(self.write2textbox) sleep(3) @@ -621,10 +609,10 @@ class App(customtkinter.CTk): def pre_warning(self): if self.tabview.get() == 'Durable Action': - df = DataFrame(durable_data_current) - df.to_excel(durable_data_current_xlsx, index=False) - df = DataFrame(durable_data_current_max) - df.to_excel(durable_data_current_max_xlsx, index=False) + df = DataFrame(clibs.durable_data_current) + df.to_excel(clibs.durable_data_current_xlsx, index=False) + df = DataFrame(clibs.durable_data_current_max) + df.to_excel(clibs.durable_data_current_max_xlsx, index=False) if tkinter.messagebox.askyesno(title="开始运行", message="确认机器已按照测试规范更新固件,并提按照测试机型前修改好工程?"): pass diff --git a/aio/code/automatic_test/__init__.py b/aio/code/automatic_test/__init__.py deleted file mode 100644 index 5c1ee4d..0000000 --- a/aio/code/automatic_test/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['btn_functions', 'do_brake', 'do_current'] \ No newline at end of file diff --git a/aio/code/automatic_test/btn_functions.py b/aio/code/automatic_test/btn_functions.py index 2f57992..a5271dc 100644 --- a/aio/code/automatic_test/btn_functions.py +++ b/aio/code/automatic_test/btn_functions.py @@ -1,61 +1,54 @@ from json import loads from sys import argv +from logging import getLogger +from commons import clibs - -def execution(cmd, hr, w2t, **kwargs): - _id = hr.execution(cmd, **kwargs) - _msg = hr.get_from_id(_id) - if not _msg: - w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name='Automatic Test') - else: - _response = loads(_msg) - if not _response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') - return _response +tab_name = clibs.tab_names['at'] +logger = getLogger(__file__) def trigger_estop(md, w2t): md.trigger_estop() - w2t("触发急停成功,可点击机器状态验证。", 0, 0, 'green', 'Automatic Test') + w2t("触发急停成功,可点击机器状态验证。", 0, 0, 'green', tab_name) def reset_estop(md, w2t): md.reset_estop() - w2t("恢复急停成功,可点击机器状态验证。", 0, 0, 'green', 'Automatic Test') + w2t("恢复急停成功,可点击机器状态验证。", 0, 0, 'green', tab_name) def get_state(hr, w2t): # 获取机器状态 - _response = execution('state.get_state', hr, w2t) + _response = clibs.execution('state.get_state', hr, w2t, tab_name) stat_desc = {'engine': '上电状态', 'operate': '操作模式', 'rc_state': '控制器状态', 'robot_action': '机器人动作', 'safety_mode': '安全模式', 'servo_mode': '伺服工作模式', 'task_space': '工作任务空间'} for component, state in _response['data'].items(): - w2t(f"{stat_desc[component]}: {state}", tab_name='Automatic Test') + w2t(f"{stat_desc[component]}: {state}", tab_name=tab_name) # 获取设备伺服信息 - _response = execution('device.get_params', hr, w2t) + _response = clibs.execution('device.get_params', hr, w2t, tab_name) dev_desc = {0: '伺服版本', 1: '伺服参数', 2: '安全板固件', 3: '控制器', 4: '通讯总线', 5: '解释器', 6: '运动控制', 8: '力控版本', 9: '末端固件', 10: '机型文件', 11: '环境包'} dev_vers = {} for device in _response['data']['devices']: dev_vers[device['type']] = device['version'] for i in sorted(dev_desc.keys()): - w2t(f"{dev_desc[i]}: {dev_vers[i]}", tab_name='Automatic Test') + w2t(f"{dev_desc[i]}: {dev_vers[i]}", tab_name=tab_name) # 设置示教器模式 - _response = execution('state.set_tp_mode', hr, w2t, tp_mode='without') + _response = clibs.execution('state.set_tp_mode', hr, w2t, tab_name, tp_mode='without') def warning_info(hr, w2t): for msg in hr.c_msg: if 'alarm' in msg.lower(): - w2t(str(loads(msg)), tab_name='Automatic Test') + w2t(str(loads(msg)), tab_name=tab_name) for msg in hr.c_msg_xs: if 'alarm' in msg.lower(): - w2t(str(loads(msg)), tab_name='Automatic Test') + w2t(str(loads(msg)), tab_name=tab_name) def main(hr, md, func, w2t): if hr is None: - w2t("无法连接机器人,检查是否已经使用Robot Assist软件连接机器,重试中...", 0, 49, 'red', tab_name='Automatic Test') + w2t("无法连接机器人,检查是否已经使用Robot Assist软件连接机器,重试中...", 0, 49, 'red', tab_name) # func: get_state/ match func: case 'trigger_estop': diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 33868d5..6a79748 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -1,30 +1,15 @@ from time import sleep, time, strftime, localtime from sys import argv -from os import scandir, mkdir -from os.path import exists +from os import mkdir from paramiko import SSHClient, AutoAddPolicy from json import loads from openpyxl import load_workbook -import pandas +from pandas import DataFrame, concat +from logging import getLogger +from commons import clibs -RADIAN = 57.3 # 180 / 3.1415926 -tab_name = 'Automatic Test' - - -def traversal_files(path, w2t): - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red', tab_name) - else: - dirs = [] - files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files +tab_name = clibs.tab_names['at'] +logger = getLogger(__file__) def check_files(path, loadsel, data_dirs, data_files, w2t): @@ -72,51 +57,11 @@ def check_files(path, loadsel, data_dirs, data_files, w2t): w2t(' 1. configs.xlsx\n 2. reach33/reach66/reach100_xxxx.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name) -def prj_to_xcore(prj_file): - ssh = SSHClient() - ssh.set_missing_host_key_policy(AutoAddPolicy()) - ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') - sftp = ssh.open_sftp() - sftp.put(prj_file, '/tmp/target.zip') - cmd = 'cd /tmp; rm -rf target/; mkdir target; unzip -d target/ -q target.zip; ' - cmd += 'chmod 777 -R target/; rm target.zip' - ssh.exec_command(cmd) - - cmd = 'sudo rm -rf /home/luoshi/bin/controller/projects/target; ' - cmd += 'sudo mv /tmp/target/ /home/luoshi/bin/controller/projects/' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - - cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += 'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - ssh.close() - - -def execution(cmd, hr, w2t, **kwargs): - _id = hr.execution(cmd, **kwargs) - _msg = hr.get_from_id(_id) - if not _msg: - w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name) - else: - _response = loads(_msg) - if not _response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name) - return _response - - def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): _d2d_vel = {'hw_joint_vel_feedback': []} _d2d_trq = {'device_servo_trq_feedback': []} _d2d_stop = {'device_safety_estop': []} - for data in curve_data: + for data in curve_data[-240:]: dict_results = data['data'] for item in dict_results: try: @@ -129,13 +74,11 @@ def gen_result_file(path, curve_data, axis, _reach, _load, _speed, count): _d2d_trq['device_servo_trq_feedback'].extend(item['value']) elif item.get('channel', None) == 0 and item.get('name', None) == 'device_safety_estop': _d2d_stop['device_safety_estop'].extend(item['value']) - if len(_d2d_trq['device_servo_trq_feedback']) / 1000 > 10: - break - df1 = pandas.DataFrame.from_dict(_d2d_vel) - df2 = pandas.DataFrame.from_dict(_d2d_trq) - df3 = pandas.DataFrame.from_dict(_d2d_stop) - df = pandas.concat([df1, df2, df3], axis=1) + df1 = DataFrame.from_dict(_d2d_vel) + df2 = DataFrame.from_dict(_d2d_trq) + df3 = DataFrame.from_dict(_d2d_stop) + df = concat([df1, df2, df3], axis=1) _filename = f"{path}\\j{axis}\\reach{_reach}_load{_load}_speed{_speed}\\reach{_reach}_load{_load}_speed{_speed}_{count}.data" df.to_csv(_filename, sep='\t', index=False) @@ -168,14 +111,13 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): else: w2t("configs.xlsx中Target页面A1单元格填写不正确,检查后重新运行...", 0, 111, 'red', tab_name) - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) + clibs.execution('diagnosis.open', hr, w2t, tab_name, open=True, display_open=True) + clibs.execution('diagnosis.set_params', hr, w2t, tab_name, display_pdo_params=display_pdo_params) for condition in result_dirs: _reach = condition.split('_')[0].removeprefix('reach') _load = condition.split('_')[1].removeprefix('load') _speed = condition.split('_')[2].removeprefix('speed') - # if _speed != '100' or _reach != '100': - # continue + for axis in range(1, 4): md.write_axis(axis) speed_max = 0 @@ -224,11 +166,11 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): print(stderr.read().decode()) # 顺便也执行以下stderr # 3. reload工程后,pp2main,并且自动模式和上电,最后运行程序 - _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['brake', 'stop0_related']) - _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['brake', 'stop0_related']) - _response = execution('state.switch_auto', hr, w2t) - _response = execution('state.switch_motor_on', hr, w2t) - _response = execution('rl_task.run', hr, w2t, tasks=['brake', 'stop0_related']) + clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['brake', 'stop0_related']) + clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['brake', 'stop0_related']) + clibs.execution('state.switch_auto', hr, w2t, tab_name) + clibs.execution('state.switch_motor_on', hr, w2t, tab_name) + clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['brake', 'stop0_related']) _t_start = time() while True: if md.read_ready_to_go() == 1: @@ -241,8 +183,7 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): sleep(1) # 4. 打开诊断曲线,并执行采集,之后触发软急停,关闭曲线采集,找出最大速度,传递给RL程序,最后清除相关记录 sleep(get_init_speed) # 获取实际最大速度,可通过configs.xlsx配置 - _response = execution('rl_task.stop', hr, w2t, tasks=['brake']) - # sleep(1) + clibs.execution('rl_task.stop', hr, w2t, tab_name, tasks=['brake']) # 找出最大速度 _c_msg = hr.c_msg.copy() for _msg in _c_msg: @@ -250,7 +191,7 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): dict_results = loads(_msg)['data'] for item in dict_results: if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback': - _ = RADIAN * sum(item['value']) / len(item['value']) + _ = clibs.RADIAN * sum(item['value']) / len(item['value']) if ws.cell(row=1, column=1).value == 'positive': speed_max = max(_, speed_max) elif ws.cell(row=1, column=1).value == 'negative': @@ -264,8 +205,8 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): md.write_speed_max(speed_max) hr.c_msg_xs.clear() - if len(hr.c_msg) > 240: - del hr.c_msg[240:] + if len(hr.c_msg) > 270: + del hr.c_msg[270:] if speed_max < 10: md.clear_alarm() @@ -278,11 +219,11 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): md.reset_estop() # 其实没必要 md.clear_alarm() - _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['brake', 'stop0_related']) - _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['brake', 'stop0_related']) - _response = execution('state.switch_auto', hr, w2t) - _response = execution('state.switch_motor_on', hr, w2t) - _response = execution('rl_task.run', hr, w2t, tasks=['brake', 'stop0_related']) + clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['brake', 'stop0_related']) + clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['brake', 'stop0_related']) + clibs.execution('state.switch_auto', hr, w2t, tab_name) + clibs.execution('state.switch_motor_on', hr, w2t, tab_name) + clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['brake', 'stop0_related']) for i in range(3): if md.read_ready_to_go() == 1: md.write_act(1) @@ -316,8 +257,8 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): curve_data.insert(0, loads(_msg)) else: hr.c_msg_xs.clear() - if len(hr.c_msg) > 240: - del hr.c_msg[240:] + if len(hr.c_msg) > 270: + del hr.c_msg[270:] gen_result_file(path, curve_data, axis, _reach, _load, _speed, count) else: w2t(f"\n{loadsel.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。", 0, 0, 'green', tab_name) @@ -325,9 +266,9 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): def main(path, hr, md, loadsel, w2t): _s_time = time() - data_dirs, data_files = traversal_files(path, w2t) + data_dirs, data_files = clibs.traversal_files(path, w2t) config_file, reach33, reach66, reach100, prj_file, result_dirs = check_files(path, loadsel, data_dirs, data_files, w2t) - prj_to_xcore(prj_file) + clibs.prj_to_xcore(prj_file) run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t) _e_time = time() time_total = _e_time - _s_time diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index b47a77d..ac528ba 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -1,12 +1,14 @@ -import os +from os import mkdir from time import sleep, time from sys import argv -from os import scandir -from os.path import exists from paramiko import SSHClient, AutoAddPolicy from json import loads -import pandas +from pandas import DataFrame, concat +from logging import getLogger +from commons import clibs +logger = getLogger(__file__) +tab_name = clibs.tab_names['at'] display_pdo_params = [ {"name": "hw_joint_vel_feedback", "channel": 0}, {"name": "hw_joint_vel_feedback", "channel": 1}, @@ -22,26 +24,11 @@ display_pdo_params = [ {"name": "device_servo_trq_feedback", "channel": 5}, ] -def traversal_files(path, w2t): - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red', tab_name='Automatic Test') - else: - dirs = [] - files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files - def check_files(path, loadsel, data_dirs, data_files, w2t): if len(data_dirs) != 0 or len(data_files) != 3: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下三个文件,确认后重新运行!', 0, 0, 'red', tab_name='Automatic Test') - w2t(' 1. configs.xlsx\n 2. T_电机电流.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name='Automatic Test') + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下三个文件,确认后重新运行!', 0, 0, 'red', tab_name) + w2t(' 1. configs.xlsx\n 2. T_电机电流.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name) config_file = current_file = prj_file = None for data_file in data_files: @@ -53,62 +40,22 @@ def check_files(path, loadsel, data_dirs, data_files, w2t): elif filename.endswith('.zip'): prj_file = data_file else: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下三个文件,确认后重新运行!', 0, 0, 'red', tab_name='Automatic Test') - w2t(' 1. configs.xlsx\n 2. T_电机电流.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name='Automatic Test') + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下三个文件,确认后重新运行!', 0, 0, 'red', tab_name) + w2t(' 1. configs.xlsx\n 2. T_电机电流.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name) if config_file and current_file and prj_file: - w2t("数据目录合规性检查结束,未发现问题......", tab_name='Automatic Test') + w2t("数据目录合规性检查结束,未发现问题......", tab_name=tab_name) if loadsel == 'tool100': - os.mkdir(f"{path}\\single") - os.mkdir(f"{path}\\s_1") - os.mkdir(f"{path}\\s_2") - os.mkdir(f"{path}\\s_3") + mkdir(f"{path}\\single") + mkdir(f"{path}\\s_1") + mkdir(f"{path}\\s_2") + mkdir(f"{path}\\s_3") elif loadsel == 'inertia': - os.mkdir(f"{path}\\inertia") + mkdir(f"{path}\\inertia") return config_file, current_file, prj_file else: - w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下三个文件,确认后重新运行!', 0, 0, 'red', tab_name='Automatic Test') - w2t(' 1. configs.xlsx\n 2. T_电机电流.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name='Automatic Test') - - -def prj_to_xcore(prj_file): - ssh = SSHClient() - ssh.set_missing_host_key_policy(AutoAddPolicy()) - ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') - sftp = ssh.open_sftp() - sftp.put(prj_file, '/tmp/target.zip') - cmd = 'cd /tmp; rm -rf target/; mkdir target; unzip -d target/ -q target.zip; ' - cmd += 'chmod 777 -R target/; rm target.zip' - ssh.exec_command(cmd) - - cmd = 'sudo rm -rf /home/luoshi/bin/controller/projects/target; ' - cmd += 'sudo mv /tmp/target/ /home/luoshi/bin/controller/projects/' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - - cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += 'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - ssh.close() - - -def execution(cmd, hr, w2t, **kwargs): - _id = hr.execution(cmd, **kwargs) - _msg = hr.get_from_id(_id) - if not _msg: - w2t(f"无法获取{_id}请求的响应信息", 0, 7, 'red', tab_name='Automatic Test') - else: - _response = loads(_msg) - if not _response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name='Automatic Test') - return _response + w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下三个文件,确认后重新运行!', 0, 0, 'red', tab_name) + w2t(' 1. configs.xlsx\n 2. T_电机电流.xlsx\n 3. xxxx.zip', 0, 1, 'red', tab_name) def data_proc_regular(path, filename, channel, scenario_time): @@ -129,9 +76,9 @@ def data_proc_regular(path, filename, channel, scenario_time): elif item.get('channel', None) == channel and item.get('name', None) == 'device_servo_trq_feedback': _d2d_trq['device_servo_trq_feedback'].extend(item['value']) - df1 = pandas.DataFrame.from_dict(_d2d_vel) - df2 = pandas.DataFrame.from_dict(_d2d_trq) - df = pandas.concat([df1, df2], axis=1) + df1 = DataFrame.from_dict(_d2d_vel) + df2 = DataFrame.from_dict(_d2d_trq) + df = concat([df1, df2], axis=1) _filename = f'{path}\\single\\j{channel+1}_single_{time()}.data' df.to_csv(_filename, sep='\t', index=False) elif channel in list(range(6, 9)): @@ -181,39 +128,39 @@ def data_proc_regular(path, filename, channel, scenario_time): elif item.get('channel', None) == 5 and item.get('name', None) == 'device_servo_trq_feedback': _d2d_trq_5['device_servo_trq_feedback'].extend(item['value']) - df_01 = pandas.DataFrame.from_dict(_d2d_vel_0) - df_02 = pandas.DataFrame.from_dict(_d2d_trq_0) - df = pandas.concat([df_01, df_02], axis=1) + df_01 = DataFrame.from_dict(_d2d_vel_0) + df_02 = DataFrame.from_dict(_d2d_trq_0) + df = concat([df_01, df_02], axis=1) _filename = f'{path}\\s_{channel-5}\\j1_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) - df_01 = pandas.DataFrame.from_dict(_d2d_vel_1) - df_02 = pandas.DataFrame.from_dict(_d2d_trq_1) - df = pandas.concat([df_01, df_02], axis=1) + df_01 = DataFrame.from_dict(_d2d_vel_1) + df_02 = DataFrame.from_dict(_d2d_trq_1) + df = concat([df_01, df_02], axis=1) _filename = f'{path}\\s_{channel-5}\\j2_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) - df_01 = pandas.DataFrame.from_dict(_d2d_vel_2) - df_02 = pandas.DataFrame.from_dict(_d2d_trq_2) - df = pandas.concat([df_01, df_02], axis=1) + df_01 = DataFrame.from_dict(_d2d_vel_2) + df_02 = DataFrame.from_dict(_d2d_trq_2) + df = concat([df_01, df_02], axis=1) _filename = f'{path}\\s_{channel-5}\\j3_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) - df_01 = pandas.DataFrame.from_dict(_d2d_vel_3) - df_02 = pandas.DataFrame.from_dict(_d2d_trq_3) - df = pandas.concat([df_01, df_02], axis=1) + df_01 = DataFrame.from_dict(_d2d_vel_3) + df_02 = DataFrame.from_dict(_d2d_trq_3) + df = concat([df_01, df_02], axis=1) _filename = f'{path}\\s_{channel-5}\\j4_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) - df_01 = pandas.DataFrame.from_dict(_d2d_vel_4) - df_02 = pandas.DataFrame.from_dict(_d2d_trq_4) - df = pandas.concat([df_01, df_02], axis=1) + df_01 = DataFrame.from_dict(_d2d_vel_4) + df_02 = DataFrame.from_dict(_d2d_trq_4) + df = concat([df_01, df_02], axis=1) _filename = f'{path}\\s_{channel-5}\\j5_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) - df_01 = pandas.DataFrame.from_dict(_d2d_vel_5) - df_02 = pandas.DataFrame.from_dict(_d2d_trq_5) - df = pandas.concat([df_01, df_02], axis=1) + df_01 = DataFrame.from_dict(_d2d_vel_5) + df_02 = DataFrame.from_dict(_d2d_trq_5) + df = concat([df_01, df_02], axis=1) _filename = f'{path}\\s_{channel-5}\\j6_s_{channel-5}_{scenario_time}_{time()}.data' df.to_csv(_filename, sep='\t', index=False) elif channel in list(range(9, 15)): @@ -221,7 +168,7 @@ def data_proc_regular(path, filename, channel, scenario_time): lines = f_obj.readlines() _d2d_vel = {'hw_joint_vel_feedback': []} _d2d_trq = {'device_servo_trq_feedback': []} - for line in lines: + for line in lines[-300:]: data = eval(line.strip())['data'] for item in data: try: @@ -233,9 +180,9 @@ def data_proc_regular(path, filename, channel, scenario_time): elif item.get('channel', None) == channel-9 and item.get('name', None) == 'device_servo_trq_feedback': _d2d_trq['device_servo_trq_feedback'].extend(item['value']) - df1 = pandas.DataFrame.from_dict(_d2d_vel) - df2 = pandas.DataFrame.from_dict(_d2d_trq) - df = pandas.concat([df1, df2], axis=1) + df1 = DataFrame.from_dict(_d2d_vel) + df2 = DataFrame.from_dict(_d2d_trq) + df = concat([df1, df2], axis=1) _filename = f'{path}\\single\\j{channel-8}_hold_{time()}.data' df.to_csv(_filename, sep='\t', index=False) @@ -257,9 +204,9 @@ def data_proc_inertia(path, filename, channel): elif item.get('channel', None) == channel+3 and item.get('name', None) == 'device_servo_trq_feedback': _d2d_trq['device_servo_trq_feedback'].extend(item['value']) - df1 = pandas.DataFrame.from_dict(_d2d_vel) - df2 = pandas.DataFrame.from_dict(_d2d_trq) - df = pandas.concat([df1, df2], axis=1) + df1 = DataFrame.from_dict(_d2d_vel) + df2 = DataFrame.from_dict(_d2d_trq) + df = concat([df1, df2], axis=1) _filename = f'{path}\\inertia\\j{channel+4}_inertia_{time()}.data' df.to_csv(_filename, sep='\t', index=False) @@ -313,21 +260,21 @@ def run_rl(path, hr, md, loadsel, w2t): disc = disc_inertia # preparation 触发软急停,并解除,目的是让可能正在运行着的机器停下来 - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) - # _response = execution('diagnosis.save', hr, w2t, save=True) # 这条命令有问题 + clibs.execution('diagnosis.open', hr, w2t, tab_name, open=True, display_open=True) + clibs.execution('diagnosis.set_params', hr, w2t, tab_name, display_pdo_params=display_pdo_params) + # clibs.execution('diagnosis.save', hr, w2t, tab_name, save=True) # 这条命令有问题 md.trigger_estop() md.reset_estop() for condition in conditions: number = conditions.index(condition) - w2t(f"正在执行{disc[number][0]}测试......", 0, 0, 'purple', 'Automatic Test') + w2t(f"正在执行{disc[number][0]}测试......", 0, 0, 'purple', tab_name) # 1. 将act重置为False,并修改未要执行的场景 md.write_act(False) ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) - ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') + ssh.connect(clibs.ip_addr, 22, username='luoshi', password='luoshi2019') cmd = 'cd /home/luoshi/bin/controller/; ' cmd += 'sudo sed -i "/scenario/d" projects/target/_build/current/main.mod; ' cmd += f'sudo sed -i "/DONOTDELETE/i {condition}" projects/target/_build/current/main.mod' @@ -339,13 +286,13 @@ def run_rl(path, hr, md, loadsel, w2t): # 2. reload工程后,pp2main,并且自动模式和上电 prj_path = 'target/_build/target.prj' - _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['current']) - _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['current']) - _response = execution('state.switch_auto', hr, w2t) - _response = execution('state.switch_motor_on', hr, w2t) + clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['current']) + clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['current']) + clibs.execution('state.switch_auto', hr, w2t, tab_name) + clibs.execution('state.switch_motor_on', hr, w2t, tab_name) # 3. 开始运行程序,单轴运行35s - _response = execution('rl_task.run', hr, w2t, tasks=['current']) + clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['current']) _t_start = time() while True: if md.read_ready_to_go() == 1: @@ -353,7 +300,7 @@ def run_rl(path, hr, md, loadsel, w2t): break else: if (time() - _t_start) // 20 > 1: - w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + w2t("20s内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) else: sleep(1) @@ -369,11 +316,11 @@ def run_rl(path, hr, md, loadsel, w2t): while True: scenario_time = md.read_scenario_time() if float(scenario_time) > 1: - w2t(f"场景{number-5}的周期时间:{scenario_time}", 0, 0, 'green', 'Automatic Test') + w2t(f"场景{number-5}的周期时间:{scenario_time}", 0, 0, 'green', tab_name) break else: if (time()-_t_start)//60 > 3: - w2t(f"未收到场景{number-5}的周期时间,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', 'Automatic Test') + w2t(f"未收到场景{number-5}的周期时间,需要确认RL程序编写正确并正常执行...", 0, 111, 'red', tab_name) else: sleep(5) sleep(1) # 一定要延迟一秒再读一次scenario time寄存器,因为一开始读取的数值不准确 @@ -381,27 +328,27 @@ def run_rl(path, hr, md, loadsel, w2t): sleep(float(scenario_time)*0.2) # 再运行周期的20%即可 # 5.停止程序运行,保留数据并处理输出 - _response = execution('rl_task.stop', hr, w2t, tasks=['current']) + clibs.execution('rl_task.stop', hr, w2t, tab_name, tasks=['current']) _c_msg = hr.c_msg.copy() for _msg in _c_msg: if 'diagnosis.result' in _msg: disc[number][1].insert(0, loads(_msg)) else: hr.c_msg_xs.clear() - if len(hr.c_msg) > 240: - del hr.c_msg[240:] + if len(hr.c_msg) > 270: + del hr.c_msg[270:] gen_result_file(path, loadsel, disc, number, scenario_time) else: if loadsel == 'tool100': - w2t("单轴和场景电机电流采集完毕,如需采集惯量负载,须切换负载类型,并更换惯量负载,重新执行。", 0, 0, 'green', 'Automatic Test') + w2t("单轴和场景电机电流采集完毕,如需采集惯量负载,须切换负载类型,并更换惯量负载,重新执行。", 0, 0, 'green', tab_name) elif loadsel == 'inertia': - w2t("惯量负载电机电流采集完毕,如需采集单轴/场景/保持电机电流,须切换负载类型,并更换偏置负载,重新执行。", 0, 0, 'green', 'Automatic Test') + w2t("惯量负载电机电流采集完毕,如需采集单轴/场景/保持电机电流,须切换负载类型,并更换偏置负载,重新执行。", 0, 0, 'green', tab_name) def main(path, hr, md, loadsel, w2t): - data_dirs, data_files = traversal_files(path, w2t) + data_dirs, data_files = clibs.traversal_files(path, w2t) config_file, current_file, prj_file = check_files(path, loadsel, data_dirs, data_files, w2t) - prj_to_xcore(prj_file) + clibs.prj_to_xcore(prj_file) run_rl(path, hr, md, loadsel, w2t) diff --git a/aio/code/commons/clibs.py b/aio/code/commons/clibs.py new file mode 100644 index 0000000..8876185 --- /dev/null +++ b/aio/code/commons/clibs.py @@ -0,0 +1,131 @@ +from os import scandir +from threading import Thread +from time import sleep +from os.path import exists +from paramiko import SSHClient, AutoAddPolicy +from socket import setdefaulttimeout +from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL, Formatter, StreamHandler, basicConfig +from concurrent_log_handler import ConcurrentRotatingFileHandler + +ip_addr = '192.168.0.160' +RADIAN = 57.3 # 180 / 3.1415926 +MAX_FRAME_SIZE = 1024 +TIMEOUT = 5 +setdefaulttimeout(TIMEOUT) +tab_names = {'dp': 'Data Process', 'at': 'Automatic Test', 'da': 'Duration Action', 'op': 'openapi'} +# PREFIX = '' # for pyinstaller packaging +PREFIX = '../assets/' # for source code debug +log_data = f'{PREFIX}templates/c_msg.log' +heartbeat = f'{PREFIX}templates/heartbeat' +durable_data_current_xlsx = f'{PREFIX}templates/durable/durable_data_current.xlsx' +durable_data_current_max_xlsx = f'{PREFIX}templates/durable/durable_data_current_max.xlsx' +durable_data_current = { + 'time': list(range(1, 19)), + 'axis1': [0 for _ in range(18)], + 'axis2': [0 for _ in range(18)], + 'axis3': [0 for _ in range(18)], + 'axis4': [0 for _ in range(18)], + 'axis5': [0 for _ in range(18)], + 'axis6': [0 for _ in range(18)], +} +durable_data_current_max = { + 'time': list(range(1, 19)), + 'axis1': [0 for _ in range(18)], + 'axis2': [0 for _ in range(18)], + 'axis3': [0 for _ in range(18)], + 'axis4': [0 for _ in range(18)], + 'axis5': [0 for _ in range(18)], + 'axis6': [0 for _ in range(18)], +} + +fmt = Formatter('%(asctime)s # %(levelname)s-%(filename)s-%(funcName)s # %(message)s') +# file_handler = logging.FileHandler(log_data) +# file_handler = RotatingFileHandler(filename=log_data, backupCount=10, maxBytes=50*1024*1024, encoding='utf-8') +file_handler = ConcurrentRotatingFileHandler(filename=log_data, backupCount=10, maxBytes=50*1024*1024, encoding='utf-8') +file_handler.setFormatter(fmt) +file_handler.setLevel(INFO) +console_handler = StreamHandler() +console_handler.setFormatter(fmt) +console_handler.setLevel(ERROR) + +# basicConfig(level=WARNING, # for product +basicConfig(level=WARNING, + datefmt='%Y-%m-%dT%H:%M:%S', + # handlers=[file_handler]) # for product + handlers=[file_handler, console_handler]) + + +class GetThreadResult(Thread): + def __init__(self, func, args=()): + super(GetThreadResult, self).__init__() + self.func = func + self.args = args + self.result = 0 + + def run(self): + sleep(1) + self.result = self.func(*self.args) + + def get_result(self): + Thread.join(self) # 等待线程执行完毕 + try: + return self.result + except Exception as Err: + return None + + +def traversal_files(path, w2t): + # 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录 + # 参数:路径 + # 返回值:路径下的文件夹列表 路径下的文件列表 + if not exists(path): + msg = f'数据文件夹{path}不存在,请确认后重试......' + w2t(msg, 0, 1, 'red') + else: + dirs = [] + files = [] + for item in scandir(path): + if item.is_dir(): + dirs.append(item.path) + elif item.is_file(): + files.append(item.path) + + return dirs, files + + +def prj_to_xcore(prj_file): + ssh = SSHClient() + ssh.set_missing_host_key_policy(AutoAddPolicy()) + ssh.connect(ip_addr, 22, username='luoshi', password='luoshi2019') + sftp = ssh.open_sftp() + sftp.put(prj_file, '/tmp/target.zip') + cmd = 'cd /tmp; rm -rf target/; mkdir target; unzip -d target/ -q target.zip; ' + cmd += 'chmod 777 -R target/; rm target.zip' + ssh.exec_command(cmd) + + cmd = 'sudo rm -rf /home/luoshi/bin/controller/projects/target; ' + cmd += 'sudo mv /tmp/target/ /home/luoshi/bin/controller/projects/' + stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) + stdin.write('luoshi2019' + '\n') + stdin.flush() + print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo + print(stderr.read().decode()) # 顺便也执行以下stderr + + cmd = 'cd /home/luoshi/bin/controller/; ' + cmd += 'sudo chmod -R 755 projects; rm /tmp/*.prj; sudo mv projects/target/_build/*.prj /tmp; cd /tmp; ' + cmd += 'prj=($(ls *.prj)); sudo mv ${prj[0]} /home/luoshi/bin/controller/projects/target/_build/target.prj; ' + stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) + stdin.write('luoshi2019' + '\n') + stdin.flush() + print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo + print(stderr.read().decode()) # 顺便也执行以下stderr + ssh.close() + + +def execution(cmd, hr, w2t, tab_name, **kwargs): + _id = hr.execution(cmd, **kwargs) + _msg = hr.get_from_id(_id) + if not _msg: + w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red', tab_name) + else: + return eval(_msg.split('#')[2]) diff --git a/aio/code/openapi.py b/aio/code/commons/openapi.py similarity index 92% rename from aio/code/openapi.py rename to aio/code/commons/openapi.py index ed70430..95b422e 100644 --- a/aio/code/openapi.py +++ b/aio/code/commons/openapi.py @@ -1,25 +1,22 @@ from json import load, dumps, loads -from socket import socket, setdefaulttimeout, AF_INET, SOCK_STREAM +from socket import socket, AF_INET, SOCK_STREAM from threading import Thread import selectors from time import time, sleep -from os.path import dirname from pymodbus.client.tcp import ModbusTcpClient from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder from pymodbus.constants import Endian +from logging import getLogger +from commons import clibs -MAX_FRAME_SIZE = 1024 -setdefaulttimeout(2) -current_path = dirname(__file__) -heartbeat = f'{current_path}/../assets/templates/heartbeat' - +logger = getLogger(__file__) class ModbusRequest(object): def __init__(self, w2t): super().__init__() self.w2t = w2t self.tab_name = 'openapi' - self.host = '192.168.0.160' + self.host = clibs.ip_addr self.port = 502 self.interval = 0.3 self.c = ModbusTcpClient(self.host, self.port) @@ -195,21 +192,19 @@ class HmiRequest(object): def sock_conn(self): # while True: - with open(heartbeat, "r", encoding='utf-8') as f_hb: + with open(clibs.heartbeat, "r", encoding='utf-8') as f_hb: c_state = f_hb.read().strip() if c_state == '0': try: self.c = socket(AF_INET, SOCK_STREAM) - self.c.connect(('192.168.0.160', 5050)) - # self.c.connect(('192.168.84.129', 5050)) + self.c.connect((clibs.ip_addr, 5050)) self.c.setblocking(False) self.c_xs = socket(AF_INET, SOCK_STREAM) - self.c_xs.connect(('192.168.0.160', 6666)) - # self.c_xs.connect(('192.168.84.129', 6666)) + self.c_xs.connect((clibs.ip_addr, 6666)) self.c_xs.setblocking(False) self.w2t("Connection success", 0, 0, 'green', tab_name=self.tab_name) - with open(heartbeat, "w", encoding='utf-8') as f_hb: + with open(clibs.heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('1') md = ModbusRequest(self.w2t) md.reset_estop() @@ -219,7 +214,7 @@ class HmiRequest(object): md.write_axis(1) except Exception as Err: self.w2t("Connection failed...", 0, 0, 'red', tab_name=self.tab_name) - with open(heartbeat, "w", encoding='utf-8') as f_hb: + with open(clibs.heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write('0') def header_check(self, index, data): @@ -247,33 +242,29 @@ class HmiRequest(object): # print(f"in head check data: {data}") self.broke = 100 - index += MAX_FRAME_SIZE + index += clibs.MAX_FRAME_SIZE return index, 0, 0 def heartbeat(self): while self.t_bool: _id = self.execution('controller.heart') _flag = '0' if self.get_from_id(_id) is None else '1' - print(f"hb = {_flag}", end=' ') - print(f"len(c_msg) = {len(self.c_msg)}", end=' ') - print(f"len(c_msg_xs) = {len(self.c_msg_xs)}", end='\n') - with open(heartbeat, "w", encoding='utf-8') as f_hb: + # print(f"hb = {_flag}", end=' ') + # print(f"len(c_msg) = {len(self.c_msg)}", end=' ') + # print(f"len(c_msg_xs) = {len(self.c_msg_xs)}", end='\n') + with open(clibs.heartbeat, "w", encoding='utf-8') as f_hb: f_hb.write(_flag) - if _flag == '0': - self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) - t = time() - with open(f"{current_path}/../assets/templates/c_msg.log", "w", encoding='utf-8') as f: - for msg in self.c_msg: - f.write(str(t) + '-' + str(loads(msg)) + '\n') - sleep(1) - + if _flag == '0': + self.w2t(f"{_id} 心跳丢失,连接失败,重新连接中...", 0, 7, 'red', tab_name=self.tab_name) + sleep(2) def msg_storage(self, response, flag=0): # response是解码后的字符串 messages = self.c_msg if flag == 0 else self.c_msg_xs + logger.warning(f"{loads(response)}") if 'move.monitor' in response: pass - elif len(messages) < 20000: + elif len(messages) < 10000: messages.insert(0, response) else: messages.insert(0, response) @@ -317,7 +308,7 @@ class HmiRequest(object): # print(f"broke == 0 index = {self.index-8}") # print(f"broke == 0 INIT pkg size = {self.pkg_size}") # print(f"broke == 0 data = {data}") - if self.index > MAX_FRAME_SIZE: + if self.index > clibs.MAX_FRAME_SIZE: break # 详见解包原理数据.txt,self.pkg_size 永远是除了当前data之外剩余未处理的数据大小 if self.pkg_size <= len(data) - self.index: @@ -361,15 +352,15 @@ class HmiRequest(object): # print('flag = 0 encounter broke == 3') self.broke = 3 - self.index += MAX_FRAME_SIZE + self.index += clibs.MAX_FRAME_SIZE self.reset_index = 1 - break # 因为 index + 2 的大小超过 MAX_FRAME_SIZE + break # 因为 index + 2 的大小超过 clibs.MAX_FRAME_SIZE elif self.index+_frame_size-6 > len(data): self.response = data[self.index:].decode() self.pkg_size -= (len(data) - self.index) # 详见解包原理数据.txt,self.pkg_size self.leftover = (_frame_size-6-(len(data)-self.index)) - self.index += MAX_FRAME_SIZE + self.index += clibs.MAX_FRAME_SIZE self.reset_index = 1 # print(f"in flag=0 else data = {data}") @@ -438,9 +429,9 @@ class HmiRequest(object): # print('flag = 1 encounter broke == 3') self.broke = 3 - self.index += MAX_FRAME_SIZE + self.index += clibs.MAX_FRAME_SIZE self.reset_index = 1 - break # 因为 index + 2 的大小超过 MAX_FRAME_SIZE + break # 因为 index + 2 的大小超过 clibs.MAX_FRAME_SIZE # print(f"in pkg size > 0 loop after if data = {data}") # print(f"in pkg size > 0 loop after if index = {self.index}") # print(f"in pkg size > 0 loop after if pkg size = {self.pkg_size}") @@ -457,7 +448,7 @@ class HmiRequest(object): self.response += data[self.index:].decode() self.leftover -= (len(data) - self.index) self.pkg_size -= (len(data) - self.index) - self.index += MAX_FRAME_SIZE + self.index += clibs.MAX_FRAME_SIZE self.reset_index = 1 # print(f"in pkg size > 0 loop after else data = {data}") # print(f"in pkg size > 0 loop after else index = {self.index}") @@ -511,15 +502,21 @@ class HmiRequest(object): def get_from_id(self, msg_id, flag=0): for i in range(3): - messages = self.c_msg if flag == 0 else self.c_msg_xs - for msg in messages: - if msg_id is None: - return None - elif msg_id in msg: - return msg + with open(clibs.log_data, mode='r', encoding='utf-8') as f_log: + for line in f_log: + if msg_id in line.strip(): + return line sleep(1) - else: - return None + else: # 尝试在上一次分割的日志中查找,只做一次 + sleep(1) + try: + with open(clibs.log_data+'.1', mode='r', encoding='utf-8') as f_log: + for line in f_log: + if msg_id in line.strip(): + return line + except FileNotFoundError: + pass + return None def package(self, cmd): _frame_head = (len(cmd) + 6).to_bytes(length=2, byteorder='big') @@ -533,7 +530,7 @@ class HmiRequest(object): def unpackage(self, sock): def to_read(conn, mask): - data = conn.recv(MAX_FRAME_SIZE) + data = conn.recv(clibs.MAX_FRAME_SIZE) if data: # print(data) self.get_response(data) @@ -580,7 +577,7 @@ class HmiRequest(object): if flg == 0: # for old protocols req = None try: - with open(f'{current_path}/../assets/templates/json/{command}.json', encoding='utf-8', + with open(f'{clibs.PREFIX}templates/json/{command}.json', encoding='utf-8', mode='r') as f_json: req = load(f_json) except: diff --git a/aio/code/data_process/__init__.py b/aio/code/data_process/__init__.py deleted file mode 100644 index 3913f0e..0000000 --- a/aio/code/data_process/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['brake', 'current', 'iso', 'wavelogger'] \ No newline at end of file diff --git a/aio/code/data_process/brake.py b/aio/code/data_process/brake.py index 233e0c6..b2f1333 100644 --- a/aio/code/data_process/brake.py +++ b/aio/code/data_process/brake.py @@ -1,49 +1,14 @@ # coding: utf-8 -from os import scandir -from os.path import isfile, exists +from os.path import isfile from sys import argv from openpyxl import load_workbook from time import time, sleep, strftime, localtime from threading import Thread from pandas import read_csv +from logging import getLogger +from commons import clibs - -class GetThreadResult(Thread): - def __init__(self, func, args=()): - super(GetThreadResult, self).__init__() - self.func = func - self.args = args - self.result = 0 - - def run(self): - sleep(1) - self.result = self.func(*self.args) - - def get_result(self): - Thread.join(self) # 等待线程执行完毕 - try: - return self.result - except Exception as Err: - return None - - -def traversal_files(path, w2t): - # 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录 - # 参数:路径 - # 返回值:路径下的文件夹列表 路径下的文件列表 - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red') - else: - dirs = [] - files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files +logger = getLogger(__file__) def check_files(path, raw_data_dirs, result_files, w2t): @@ -83,7 +48,7 @@ def check_files(path, raw_data_dirs, result_files, w2t): 规则解释:AA/BB/CC 指的是臂展/负载/速度的比例,例如reach66_load100_speed33:66%臂展,100%负载以及33%速度情况下的测试结果文件夹""" w2t(msg, 0, 4, 'red') - _, raw_data_files = traversal_files(raw_data_dir, w2t) + _, raw_data_files = clibs.traversal_files(raw_data_dir, w2t) if len(raw_data_files) != 3: msg = f"数据目录 {raw_data_dir} 下数据文件个数错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件" w2t(msg, 0, 5, 'red') @@ -109,6 +74,7 @@ def get_configs(configfile, w2t): return av, rr + def now_doing_msg(docs, flag, w2t): # 功能:输出正在处理的文件或目录 # 参数:文件或目录,start 或 done 标识 @@ -228,7 +194,7 @@ def data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t): global stop stop = 0 - t_excel = GetThreadResult(load_workbook, args=(result_file, )) + t_excel = clibs.GetThreadResult(load_workbook, args=(result_file, )) t_wait = Thread(target=w2t_local, args=('.', 1, w2t)) t_excel.start() t_wait.start() @@ -242,7 +208,7 @@ def data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t): for raw_data_dir in raw_data_dirs: if raw_data_dir.split('\\')[-1].split('_')[0] == prefix: now_doing_msg(raw_data_dir, 'start', w2t) - _, data_files = traversal_files(raw_data_dir, w2t) + _, data_files = clibs.traversal_files(raw_data_dir, w2t) # 数据文件串行处理模式--------------------------------- # count = 1 # for data_file in data_files: @@ -280,7 +246,7 @@ def main(path, vel, trq, estop, w2t): # 参数:initialization函数的返回值 # 返回值:- time_start = time() - raw_data_dirs, result_files = traversal_files(path, w2t) + raw_data_dirs, result_files = clibs.traversal_files(path, w2t) try: # threads = [] diff --git a/aio/code/data_process/current.py b/aio/code/data_process/current.py index 78771f7..19f5876 100644 --- a/aio/code/data_process/current.py +++ b/aio/code/data_process/current.py @@ -1,31 +1,14 @@ from openpyxl import load_workbook -from os import scandir -from os.path import exists from sys import argv from pandas import read_csv, concat, set_option from re import match from threading import Thread from time import sleep from csv import reader, writer +from logging import getLogger +from commons import clibs - -class GetThreadResult(Thread): - def __init__(self, func, args=()): - super(GetThreadResult, self).__init__() - self.func = func - self.args = args - self.result = 0 - - def run(self): - sleep(1) - self.result = self.func(*self.args) - - def get_result(self): - Thread.join(self) # 等待线程执行完毕 - try: - return self.result - except Exception as Err: - return None +logger = getLogger(__file__) def w2t_local(msg, wait, w2t): @@ -38,27 +21,8 @@ def w2t_local(msg, wait, w2t): break -def traversal_files(path, w2t): - # 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录 - # 参数:路径 - # 返回值:路径下的文件夹列表 路径下的文件列表 - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 8, 'red') - else: - dirs = [] - files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files - - def initialization(path, sub, w2t): - _, data_files = traversal_files(path, w2t) + _, data_files = clibs.traversal_files(path, w2t) count = 0 for data_file in data_files: @@ -69,8 +33,8 @@ def initialization(path, sub, w2t): count += 1 else: if not (match('j[1-7].*\\.data', filename) or match('j[1-7].*\\.csv', filename)): - print(f"不合规 {data_file}") - msg = f"所有文件必须以 jx_ 开头,以 .data/csv 结尾(x取值1-7),请检查后重新运行。" + msg = f"不合规 {data_file}\n" + msg += f"所有文件必须以 jx_ 开头,以 .data/csv 结尾(x取值1-7),请检查后重新运行。" w2t(msg, 0, 6, 'red') if not ((sub == 'cycle' and count == 2) or (sub != 'cycle' and count == 1)): @@ -174,7 +138,7 @@ def current_cycle(dur, data_files, rcs, rrs, vel, trq, trqh, rpms, w2t): w2t(f"正在打开文件 {result},需要 10s 左右", 1, 0, 'orange') global stop stop = 0 - t_excel = GetThreadResult(load_workbook, args=(result, )) + t_excel = clibs.GetThreadResult(load_workbook, args=(result, )) t_wait = Thread(target=w2t_local, args=('.', 1, w2t)) t_excel.start() t_wait.start() @@ -268,7 +232,7 @@ def p_single(wb, single, vel, trq, rpms, rrs, w2t): col_names = list(df.columns) df_1 = df[col_names[vel-1]].multiply(rpm*addition) df_2 = df[col_names[trq-1]].multiply(scale) - print(df_1.abs().max()) + # print(df_1.abs().max()) df = concat([df_1, df_2], axis=1) _step = 5 if data_file.endswith('.csv') else 50 diff --git a/aio/code/data_process/iso.py b/aio/code/data_process/iso.py index a6be621..5318d64 100644 --- a/aio/code/data_process/iso.py +++ b/aio/code/data_process/iso.py @@ -1,27 +1,12 @@ # _*_ encoding:utf-8 _*_ import pdfplumber from openpyxl import load_workbook -from os import scandir, remove -from os.path import exists +from os import remove from sys import argv +from logging import getLogger +from commons import clibs - -def traversal_files(path, w2t): - # 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录 - # 参数:路径 - # 返回值:路径下的文件夹列表 路径下的文件列表 - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red') - else: - dirs = files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files +logger = getLogger(__file__) def p_iso(file, p_files, ws, tmpfile): @@ -153,7 +138,7 @@ def p_iso_1000(file, p_files, ws, tmpfile): def main(path, w2t): - dirs, files = traversal_files(path, 1) + dirs, files = clibs.traversal_files(path, 1) try: wb = load_workbook(path + "/iso-results.xlsx") diff --git a/aio/code/data_process/wavelogger.py b/aio/code/data_process/wavelogger.py index 730d276..625b2a5 100644 --- a/aio/code/data_process/wavelogger.py +++ b/aio/code/data_process/wavelogger.py @@ -1,31 +1,11 @@ -import os -import random - from pandas import read_csv from csv import reader from sys import argv -from os.path import exists -from os import scandir, remove from openpyxl import Workbook -from random import randint +from logging import getLogger +from commons import clibs -def traversal_files(path, w2t): - # 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录 - # 参数:路径 - # 返回值:路径下的文件夹列表 路径下的文件列表 - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red') - else: - dirs = [] - files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files +logger = getLogger(__file__) def find_point(bof, step, pos, data_file, flag, df, row, w2t): @@ -95,7 +75,7 @@ def get_cycle_info(data_file, df, row, step, w2t): def initialization(path, w2t): - _, data_files = traversal_files(path, w2t) + _, data_files = clibs.traversal_files(path, w2t) for data_file in data_files: if not data_file.lower().endswith('.csv'): @@ -126,7 +106,7 @@ def single_file_proc(ws, data_file, df, low, high, cycle, w2t): _step = 5 _data = {} row_max = df.index[-1]-100 - print(data_file) + # print(data_file) while _row < row_max: if count not in _data.keys(): _data[count] = [] @@ -149,7 +129,7 @@ def single_file_proc(ws, data_file, df, low, high, cycle, w2t): ws.cell(row=1, column=i).value = f"第{i-1}次测试" ws.cell(row=i, column=1).value = f"第{i-1}次精度变化" - print(_data) + # print(_data) for i in sorted(_data.keys()): _row = 2 _column = i + 1 @@ -162,9 +142,9 @@ def execution(data_files, w2t): wb = Workbook() for data_file in data_files: ws, df, low, high, cycle = preparation(data_file, wb, w2t) - print(f"low = {low}") - print(f"high = {high}") - print(f"cycle = {cycle}") + # print(f"low = {low}") + # print(f"high = {high}") + # print(f"cycle = {cycle}") single_file_proc(ws, data_file, df, low, high, cycle, w2t) wd = data_files[0].split('\\') diff --git a/aio/code/durable_action/__init__.py b/aio/code/durable_action/__init__.py deleted file mode 100644 index 913ac28..0000000 --- a/aio/code/durable_action/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['factory_test'] \ No newline at end of file diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 094b416..930a1d2 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -1,7 +1,4 @@ from sys import argv -from os.path import exists, dirname -from os import scandir -from paramiko import SSHClient, AutoAddPolicy from json import loads from time import sleep, time, strftime, localtime from pandas import DataFrame @@ -9,11 +6,12 @@ from openpyxl import load_workbook from math import sqrt from numpy import power from csv import writer +from logging import getLogger +from commons import clibs -tab_name = 'Durable Action' +logger = getLogger(__file__) +tab_name = clibs.tab_names['da'] count = 0 -durable_data_current_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current.xlsx' -durable_data_current_max_xlsx = f'{dirname(__file__)}/../../assets/templates/durable/durable_data_current_max.xlsx' display_pdo_params = [ # {"name": "hw_joint_vel_feedback", "channel": 0}, # {"name": "hw_joint_vel_feedback", "channel": 1}, @@ -34,22 +32,6 @@ title = [ ] -def traversal_files(path, w2t): - if not exists(path): - msg = f'数据文件夹{path}不存在,请确认后重试......' - w2t(msg, 0, 1, 'red', tab_name=tab_name) - else: - dirs = [] - files = [] - for item in scandir(path): - if item.is_dir(): - dirs.append(item.path) - elif item.is_file(): - files.append(item.path) - - return dirs, files - - def check_files(data_dirs, data_files, w2t): if len(data_dirs) != 0 or len(data_files) != 2: w2t('初始路径下不允许有文件夹,且初始路径下只能存在如下文件,确认后重新运行!\n1. target.zip\n2. configs.xlsx', 0, 10, 'red', tab_name) @@ -63,50 +45,10 @@ def check_files(data_dirs, data_files, w2t): return data_files -def prj_to_xcore(prj_file): - ssh = SSHClient() - ssh.set_missing_host_key_policy(AutoAddPolicy()) - ssh.connect('192.168.0.160', 22, username='luoshi', password='luoshi2019') - sftp = ssh.open_sftp() - sftp.put(prj_file, '/tmp/target.zip') - cmd = 'cd /tmp; rm -rf target/; mkdir target; unzip -d target/ -q target.zip; ' - cmd += 'chmod 777 -R target/; rm target.zip' - ssh.exec_command(cmd) - - cmd = 'sudo rm -rf /home/luoshi/bin/controller/projects/target; ' - cmd += 'sudo mv /tmp/target/ /home/luoshi/bin/controller/projects/' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - - cmd = 'cd /home/luoshi/bin/controller/; ' - cmd += 'sudo mv projects/target/_build/*.prj projects/target/_build/target.prj' - stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) - stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr - ssh.close() - - -def execution(cmd, hr, w2t, **kwargs): - _id = hr.execution(cmd, **kwargs) - _msg = hr.get_from_id(_id) - if not _msg: - w2t(f"无法获取{_id}请求的响应信息", 0, 7, 'red', tab_name=tab_name) - else: - _response = loads(_msg) - if not _response: - w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red', tab_name=tab_name) - return _response - - def run_rl(path, config_file, data_all, hr, md, w2t): # 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 - _response = execution('diagnosis.open', hr, w2t, open=True, display_open=True) - _response = execution('diagnosis.set_params', hr, w2t, display_pdo_params=display_pdo_params) + clibs.execution('diagnosis.open', hr, w2t, tab_name, open=True, display_open=True) + clibs.execution('diagnosis.set_params', hr, w2t, tab_name, display_pdo_params=display_pdo_params) md.trigger_estop() md.reset_estop() md.write_act(False) @@ -114,13 +56,13 @@ def run_rl(path, config_file, data_all, hr, md, w2t): # 2. reload工程后,pp2main,并且自动模式和上电 prj_path = 'target/_build/target.prj' - _response = execution('overview.reload', hr, w2t, prj_path=prj_path, tasks=['current']) - _response = execution('rl_task.pp_to_main', hr, w2t, tasks=['current']) - _response = execution('state.switch_auto', hr, w2t) - _response = execution('state.switch_motor_on', hr, w2t) + clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['current']) + clibs.execution('rl_task.pp_to_main', hr, w2t, tab_name, tasks=['current']) + clibs.execution('state.switch_auto', hr, w2t, tab_name) + clibs.execution('state.switch_motor_on', hr, w2t, tab_name) # 3. 开始运行程序 - _response = execution('rl_task.run', hr, w2t, tasks=['current']) + clibs.execution('rl_task.run', hr, w2t, tab_name, tasks=['current']) _t_start = time() while True: if md.read_ready_to_go() == 1: @@ -178,8 +120,8 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, md, w2t): _data_list.insert(0, loads(_msg)) else: hr.c_msg_xs.clear() - if len(hr.c_msg) > 240: - del hr.c_msg[240:] + if len(hr.c_msg) > 270: + del hr.c_msg[270:] # with open(f'{path}\\log.txt', 'w', encoding='utf-8') as f_obj: # for _ in _data_list: @@ -253,8 +195,8 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, md, w2t): while True: if not hr.durable_lock: hr.durable_lock = 1 - _df_1.to_excel(durable_data_current_xlsx, index=False) - _df_2.to_excel(durable_data_current_max_xlsx, index=False) + _df_1.to_excel(clibs.durable_data_current_xlsx, index=False) + _df_2.to_excel(clibs.durable_data_current_max_xlsx, index=False) hr.durable_lock = 0 break else: @@ -272,28 +214,10 @@ def get_durable_data(path, data, scenario_time, wait_time, rcs, hr, md, w2t): def main(path, hr, md, w2t): - durable_data_current = { - 'time': list(range(1, 19)), - 'axis1': [0 for _ in range(18)], - 'axis2': [0 for _ in range(18)], - 'axis3': [0 for _ in range(18)], - 'axis4': [0 for _ in range(18)], - 'axis5': [0 for _ in range(18)], - 'axis6': [0 for _ in range(18)], - } - durable_data_current_max = { - 'time': list(range(1, 19)), - 'axis1': [0 for _ in range(18)], - 'axis2': [0 for _ in range(18)], - 'axis3': [0 for _ in range(18)], - 'axis4': [0 for _ in range(18)], - 'axis5': [0 for _ in range(18)], - 'axis6': [0 for _ in range(18)], - } - data_all = [durable_data_current, durable_data_current_max] - data_dirs, data_files = traversal_files(path, w2t) + data_all = [clibs.durable_data_current, clibs.durable_data_current_max] + data_dirs, data_files = clibs.traversal_files(path, w2t) config_file, prj_file = check_files(data_dirs, data_files, w2t) - prj_to_xcore(prj_file) + clibs.prj_to_xcore(prj_file) run_rl(path, config_file, data_all, hr, md, w2t) From 924fad09e0e5dc482b43046a321b36ae3d62839f Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 31 Jul 2024 08:28:39 +0800 Subject: [PATCH 31/36] fix version again... --- aio/code/aio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/code/aio.py b/aio/code/aio.py index a535af9..47c8f3e 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -94,7 +94,7 @@ class App(customtkinter.CTk): btns_func['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback)) btns_func['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback)) # create version info - self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.3\nDate: 07/27/2024", font=self.my_font, text_color="#4F4F4F") + self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.5\nDate: 08/02/2024", font=self.my_font, text_color="#4F4F4F") self.frame_func.rowconfigure(6, weight=1) self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s') # ===================================================================== From 25fc43be81ec506792c7ab1496a132c5186b89f3 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 31 Jul 2024 11:21:24 +0800 Subject: [PATCH 32/36] =?UTF-8?q?=E4=BC=98=E5=8C=96=20ssh=20=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E5=AF=86=E7=A0=81=E7=9A=84=E9=83=A8=E5=88=86=20create?= =?UTF-8?q?=5Fplot=20=E5=87=BD=E6=95=B0=E4=B8=AD=E5=A2=9E=E5=8A=A0=20close?= =?UTF-8?q?('all')=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=BE=AA=E7=8E=AF=E7=94=BB?= =?UTF-8?q?=E5=9B=BE=E4=B8=8D=E9=94=80=E6=AF=81=E5=8D=A0=E7=94=A8=E5=86=85?= =?UTF-8?q?=E5=AD=98=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 5 ++++- aio/code/aio.py | 3 ++- aio/code/automatic_test/do_brake.py | 5 ++--- aio/code/automatic_test/do_current.py | 5 ++--- aio/code/commons/clibs.py | 10 ++++------ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/aio/README.md b/aio/README.md index 4d1469d..cc40575 100644 --- a/aio/README.md +++ b/aio/README.md @@ -567,7 +567,7 @@ v0.2.0.5(2024/07/31) - 调整代码组织结构,新增模块,将公共函数以及类合并入此 - 将一些常量放入该模块 - 引入logging/concurrent_log_handler模块,并作初始化操作,供其他模块使用,按50M切割,最多保留10份 - - prj_to_xcore函数设置工程名部分重写,修复了多个prj工程可能不能执行的问题 + - prj_to_xcore函数设置工程名部分重写,修复了多个prj工程可能不能执行的问题,并优化输入密码的部分 2. [t_change_ui: openapi.py] - 完全重写了 get_from_id 函数,使更精准 - 在 msg_storage 函数中,增加 logger,保留所有响应消息 @@ -576,10 +576,13 @@ v0.2.0.5(2024/07/31) 3. [t_change_ui: aio.py] - 增加了日志初始化部分 - detect_network 函数中修改重新实例化HR间隔为 4s,对应心跳 + - create_plot 函数中增加 close('all'),解决循环画图不销毁占用内存的问题 4. [t_change_ui: do_brake.py] - 使用一直打开曲线的方法规避解决了 OOM 的问题,同时修改数据处理方式,只取最后 12s + - 优化 ssh 输入密码的部分 5. [t_change_ui: do_current.py] - 保持电流,只取最后 15s + - 优化 ssh 输入密码的部分 6. [t_change_ui: all the part]: 引入 commons 包,并定制了 logging 输出,后续持续优化 diff --git a/aio/code/aio.py b/aio/code/aio.py index 47c8f3e..cb69554 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -11,7 +11,7 @@ from data_process import brake, current, iso, wavelogger from automatic_test import do_current, do_brake, btn_functions from durable_action import factory_test from commons import openapi, clibs -from matplotlib.pyplot import rcParams, figure, subplots_adjust +from matplotlib.pyplot import rcParams, figure, subplots_adjust, close from matplotlib import use from pandas import DataFrame, read_excel import logging @@ -230,6 +230,7 @@ class App(customtkinter.CTk): self.flg = 1 self.df_copy = df.copy() self.old_curve = widgits_da['curvesel']['optionmenu'].get() + close('all') _figure = figure(frameon=True, facecolor='#E9E9E9') subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.95) diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 6a79748..477ff9a 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -161,9 +161,8 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): cmd += f'sudo sed -i "/VelSet/i {_rl_tool}" projects/target/_build/brake/main.mod; ' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr + stdout.read().decode() # 需要read一下才能正常执行 + stderr.read().decode() # 3. reload工程后,pp2main,并且自动模式和上电,最后运行程序 clibs.execution('overview.reload', hr, w2t, tab_name, prj_path=prj_path, tasks=['brake', 'stop0_related']) diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index ac528ba..e489a13 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -280,9 +280,8 @@ def run_rl(path, hr, md, loadsel, w2t): cmd += f'sudo sed -i "/DONOTDELETE/i {condition}" projects/target/_build/current/main.mod' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr + stdout.read().decode() # 需要read一下才能正常执行 + stderr.read().decode() # 2. reload工程后,pp2main,并且自动模式和上电 prj_path = 'target/_build/target.prj' diff --git a/aio/code/commons/clibs.py b/aio/code/commons/clibs.py index 8876185..2fa9c7f 100644 --- a/aio/code/commons/clibs.py +++ b/aio/code/commons/clibs.py @@ -107,18 +107,16 @@ def prj_to_xcore(prj_file): cmd += 'sudo mv /tmp/target/ /home/luoshi/bin/controller/projects/' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr + stdout.read().decode() # 需要read一下才能正常执行 + stderr.read().decode() cmd = 'cd /home/luoshi/bin/controller/; ' cmd += 'sudo chmod -R 755 projects; rm /tmp/*.prj; sudo mv projects/target/_build/*.prj /tmp; cd /tmp; ' cmd += 'prj=($(ls *.prj)); sudo mv ${prj[0]} /home/luoshi/bin/controller/projects/target/_build/target.prj; ' stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin.write('luoshi2019' + '\n') - stdin.flush() - print(stdout.read().decode()) # 必须得输出一下stdout,才能正确执行sudo - print(stderr.read().decode()) # 顺便也执行以下stderr + stdout.read().decode() # 需要read一下才能正常执行 + stderr.read().decode() ssh.close() From 60726d9d07b83c3f70262b5af30ac247dcbbb2df Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 1 Aug 2024 17:11:12 +0800 Subject: [PATCH 33/36] =?UTF-8?q?7.=20[APIs:=20btn=5Ffunctions.py]:=20?= =?UTF-8?q?=E9=87=8D=E5=86=99=E4=BA=86=E5=91=8A=E8=AD=A6=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E5=87=BD=E6=95=B0=EF=BC=8C=E4=BB=8E=E6=97=A5=E5=BF=97=E4=B8=AD?= =?UTF-8?q?=E6=8B=BF=E6=95=B0=E6=8D=AE=208.=20[APIs:=20aio.py]:=20?= =?UTF-8?q?=E5=B0=86=E6=97=A5=E5=BF=97=E6=A1=86=E8=BE=93=E5=87=BA=E7=9A=84?= =?UTF-8?q?=E5=86=85=E5=AE=B9=EF=BC=8C=E4=B9=9F=E4=BF=9D=E5=AD=98=E8=87=B3?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=96=87=E4=BB=B6=209.=20[APIs:=20do=5Fbrake?= =?UTF-8?q?.py]=20=20=20=20-=20=E4=BF=AE=E6=94=B9=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E9=80=9F=E5=BA=A6=E7=9A=84=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E5=8F=AA=E8=8E=B7=E5=8F=96configs=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=AD=E9=85=8D=E7=BD=AE=E7=9A=84=E6=97=B6=E9=97=B4=E5=86=85?= =?UTF-8?q?=E7=9A=84=E9=80=9F=E5=BA=A6=20=20=20=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20configs=20=E5=8F=82=E6=95=B0=20single=5Fbrake=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E9=92=88=E5=AF=B9=E7=89=B9=E5=AE=9A=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E5=81=9A=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 6 ++++- aio/assets/configs.xlsx | Bin 226625 -> 226780 bytes aio/code/aio.py | 1 + aio/code/automatic_test/btn_functions.py | 15 +++++++----- aio/code/automatic_test/do_brake.py | 29 +++++++++++++++++++---- aio/code/automatic_test/do_current.py | 4 ++-- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/aio/README.md b/aio/README.md index 632dbdd..08af704 100644 --- a/aio/README.md +++ b/aio/README.md @@ -590,4 +590,8 @@ v0.2.0.5(2024/07/31) - 保持电流,只取最后 15s - 优化 ssh 输入密码的部分 6. [t_change_ui: all the part]: 引入 commons 包,并定制了 logging 输出,后续持续优化 - +7. [APIs: btn_functions.py]: 重写了告警输出函数,从日志中拿数据 +8. [APIs: aio.py]: 将日志框输出的内容,也保存至日志文件 +9. [APIs: do_brake.py] + - 修改获取初始速度的逻辑,只获取configs文件中配置的时间内的速度 + - 新增 configs 参数 single_brake,可针对特定条件做测试 \ No newline at end of file diff --git a/aio/assets/configs.xlsx b/aio/assets/configs.xlsx index c35dab9d5040a37a0945b415e3a87e9516f78df3..16eadd3a2633d06138cf75d353a3cb5bb3c53f66 100644 GIT binary patch delta 6579 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 delta 6381 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 get_init_speed*20: # 最开始回零点的时候,二轴速度可以达到最大值,实际摆动时,某一方向可能达不到 + break if 'diagnosis.result' in _msg: + _number += 1 dict_results = loads(_msg)['data'] for item in dict_results: if item.get('channel', None) == axis-1 and item.get('name', None) == 'hw_joint_vel_feedback': @@ -195,7 +214,7 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): speed_max = max(_, speed_max) elif ws.cell(row=1, column=1).value == 'negative': speed_max = min(_, speed_max) - print(f"speed max = {speed_max}") + logger.info(f"speed max = {speed_max}") speed_max = abs(speed_max) speed_target = float(ws.cell(row=3, column=axis+1).value) * float(_speed) / 100 if speed_max < speed_target*0.95 or speed_max > speed_target*1.05: diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index e489a13..9b8ec12 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -64,7 +64,7 @@ def data_proc_regular(path, filename, channel, scenario_time): lines = f_obj.readlines() _d2d_vel = {'hw_joint_vel_feedback': []} _d2d_trq = {'device_servo_trq_feedback': []} - for line in lines: + for line in lines[-500:]: # 保留最后25s的数据 data = eval(line.strip())['data'] for item in data: try: @@ -168,7 +168,7 @@ def data_proc_regular(path, filename, channel, scenario_time): lines = f_obj.readlines() _d2d_vel = {'hw_joint_vel_feedback': []} _d2d_trq = {'device_servo_trq_feedback': []} - for line in lines[-300:]: + for line in lines[-300:]: # 保留最后15s的数据 data = eval(line.strip())['data'] for item in data: try: From 340d48876b65bf05d1d9412d371221aec8114780 Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 1 Aug 2024 19:15:08 +0800 Subject: [PATCH 34/36] =?UTF-8?q?10.=20[APIs:=20all]:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=20logger.setLevel(INFO)=EF=BC=8C=E5=8F=AA=E6=9C=89?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BF=99=E4=B8=AA=EF=BC=8C=E5=8D=95=E4=B8=AA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=86=85=E6=89=8D=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/README.md | 3 ++- aio/code/aio.py | 5 +++-- aio/code/automatic_test/btn_functions.py | 3 ++- aio/code/automatic_test/do_brake.py | 5 +++-- aio/code/automatic_test/do_current.py | 4 +++- aio/code/commons/clibs.py | 15 +++++---------- aio/code/commons/openapi.py | 6 ++++-- aio/code/data_process/brake.py | 3 ++- aio/code/data_process/current.py | 3 ++- aio/code/data_process/iso.py | 3 ++- aio/code/data_process/wavelogger.py | 3 ++- aio/code/durable_action/factory_test.py | 4 +++- 12 files changed, 33 insertions(+), 24 deletions(-) diff --git a/aio/README.md b/aio/README.md index 08af704..65d2151 100644 --- a/aio/README.md +++ b/aio/README.md @@ -594,4 +594,5 @@ v0.2.0.5(2024/07/31) 8. [APIs: aio.py]: 将日志框输出的内容,也保存至日志文件 9. [APIs: do_brake.py] - 修改获取初始速度的逻辑,只获取configs文件中配置的时间内的速度 - - 新增 configs 参数 single_brake,可针对特定条件做测试 \ No newline at end of file + - 新增 configs 参数 single_brake,可针对特定条件做测试 +10. [APIs: all]: 添加了 logger.setLevel(INFO),只有添加这个,单个模块内才生效 diff --git a/aio/code/aio.py b/aio/code/aio.py index f41051a..7db0277 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -14,7 +14,7 @@ from commons import openapi, clibs from matplotlib.pyplot import rcParams, figure, subplots_adjust, close from matplotlib import use from pandas import DataFrame, read_excel -import logging +from logging import getLogger, INFO with open(clibs.log_data, 'w') as _: for i in range(1, 11): @@ -22,7 +22,8 @@ with open(clibs.log_data, 'w') as _: remove(f'{clibs.log_data}.{i}') except FileNotFoundError: pass -logger = logging.getLogger(__file__) +logger = getLogger(__file__) +logger.setLevel(INFO) logger.info("日志文件初始化完成...") use('Agg') diff --git a/aio/code/automatic_test/btn_functions.py b/aio/code/automatic_test/btn_functions.py index 42b93f6..48d9378 100644 --- a/aio/code/automatic_test/btn_functions.py +++ b/aio/code/automatic_test/btn_functions.py @@ -1,10 +1,11 @@ from json import loads from sys import argv -from logging import getLogger +from logging import getLogger, INFO from commons import clibs tab_name = clibs.tab_names['at'] logger = getLogger(__file__) +logger.setLevel(INFO) def trigger_estop(md, w2t): diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 844ac92..5436903 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -5,11 +5,12 @@ from paramiko import SSHClient, AutoAddPolicy from json import loads from openpyxl import load_workbook from pandas import DataFrame, concat -from logging import getLogger +from logging import getLogger, INFO from commons import clibs tab_name = clibs.tab_names['at'] logger = getLogger(__file__) +logger.setLevel(INFO) def check_files(path, loadsel, data_dirs, data_files, w2t): @@ -105,7 +106,7 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): ws = wb['Target'] write_diagnosis = float(ws.cell(row=3, column=10).value) get_init_speed = float(ws.cell(row=4, column=10).value) - single_brake = ws.cell(row=5, column=10).value + single_brake = str(ws.cell(row=5, column=10).value) if ws.cell(row=1, column=1).value == 'positive': md.write_pon(1) diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index 9b8ec12..f26950c 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -4,10 +4,12 @@ from sys import argv from paramiko import SSHClient, AutoAddPolicy from json import loads from pandas import DataFrame, concat -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) + tab_name = clibs.tab_names['at'] display_pdo_params = [ {"name": "hw_joint_vel_feedback", "channel": 0}, diff --git a/aio/code/commons/clibs.py b/aio/code/commons/clibs.py index 2fa9c7f..9aeee42 100644 --- a/aio/code/commons/clibs.py +++ b/aio/code/commons/clibs.py @@ -38,21 +38,16 @@ durable_data_current_max = { 'axis6': [0 for _ in range(18)], } -fmt = Formatter('%(asctime)s # %(levelname)s-%(filename)s-%(funcName)s # %(message)s') -# file_handler = logging.FileHandler(log_data) -# file_handler = RotatingFileHandler(filename=log_data, backupCount=10, maxBytes=50*1024*1024, encoding='utf-8') file_handler = ConcurrentRotatingFileHandler(filename=log_data, backupCount=10, maxBytes=50*1024*1024, encoding='utf-8') -file_handler.setFormatter(fmt) file_handler.setLevel(INFO) console_handler = StreamHandler() -console_handler.setFormatter(fmt) -console_handler.setLevel(ERROR) +console_handler.setLevel(WARNING) -# basicConfig(level=WARNING, # for product -basicConfig(level=WARNING, +basicConfig( # level=INFO, datefmt='%Y-%m-%dT%H:%M:%S', - # handlers=[file_handler]) # for product - handlers=[file_handler, console_handler]) + format='%(asctime)s # %(levelname)s-%(filename)s-%(funcName)s # %(message)s', + handlers=[file_handler, console_handler], + ) class GetThreadResult(Thread): diff --git a/aio/code/commons/openapi.py b/aio/code/commons/openapi.py index 95b422e..5908960 100644 --- a/aio/code/commons/openapi.py +++ b/aio/code/commons/openapi.py @@ -6,10 +6,12 @@ from time import time, sleep from pymodbus.client.tcp import ModbusTcpClient from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder from pymodbus.constants import Endian -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) + class ModbusRequest(object): def __init__(self, w2t): @@ -261,7 +263,7 @@ class HmiRequest(object): def msg_storage(self, response, flag=0): # response是解码后的字符串 messages = self.c_msg if flag == 0 else self.c_msg_xs - logger.warning(f"{loads(response)}") + logger.info(f"{loads(response)}") if 'move.monitor' in response: pass elif len(messages) < 10000: diff --git a/aio/code/data_process/brake.py b/aio/code/data_process/brake.py index b2f1333..1b1cfaa 100644 --- a/aio/code/data_process/brake.py +++ b/aio/code/data_process/brake.py @@ -5,10 +5,11 @@ from openpyxl import load_workbook from time import time, sleep, strftime, localtime from threading import Thread from pandas import read_csv -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) def check_files(path, raw_data_dirs, result_files, w2t): diff --git a/aio/code/data_process/current.py b/aio/code/data_process/current.py index 19f5876..c4fc7c3 100644 --- a/aio/code/data_process/current.py +++ b/aio/code/data_process/current.py @@ -5,10 +5,11 @@ from re import match from threading import Thread from time import sleep from csv import reader, writer -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) def w2t_local(msg, wait, w2t): diff --git a/aio/code/data_process/iso.py b/aio/code/data_process/iso.py index 5318d64..91397af 100644 --- a/aio/code/data_process/iso.py +++ b/aio/code/data_process/iso.py @@ -3,10 +3,11 @@ import pdfplumber from openpyxl import load_workbook from os import remove from sys import argv -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) def p_iso(file, p_files, ws, tmpfile): diff --git a/aio/code/data_process/wavelogger.py b/aio/code/data_process/wavelogger.py index 625b2a5..013b527 100644 --- a/aio/code/data_process/wavelogger.py +++ b/aio/code/data_process/wavelogger.py @@ -2,10 +2,11 @@ from pandas import read_csv from csv import reader from sys import argv from openpyxl import Workbook -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) def find_point(bof, step, pos, data_file, flag, df, row, w2t): diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 930a1d2..7e725fa 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -6,10 +6,12 @@ from openpyxl import load_workbook from math import sqrt from numpy import power from csv import writer -from logging import getLogger +from logging import getLogger, INFO from commons import clibs logger = getLogger(__file__) +logger.setLevel(INFO) + tab_name = clibs.tab_names['da'] count = 0 display_pdo_params = [ From 3814d163c5eb571b5f655e00150beef4460e3940 Mon Sep 17 00:00:00 2001 From: gitea Date: Fri, 9 Aug 2024 10:47:22 +0800 Subject: [PATCH 35/36] =?UTF-8?q?v0.2.0.6(2024/08/09)=201.=20[t=5Fchange?= =?UTF-8?q?=5Fui:=20all=20files]=20=20=20=20-=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=20logger=20=E7=9A=84=E5=AE=9E=E7=8E=B0=20=20=20=20-?= =?UTF-8?q?=20=E5=B0=A4=E5=85=B6=E6=98=AF=20clibs.py=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=97=A5=E5=BF=97=E5=AD=97=E5=85=B8=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E5=86=99=E4=BA=86=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- aio/README.md | 5 ++ aio/code/aio.py | 8 +- aio/code/automatic_test/btn_functions.py | 7 +- aio/code/automatic_test/do_brake.py | 5 +- aio/code/automatic_test/do_current.py | 5 +- aio/code/commons/clibs.py | 95 ++++++++++++++++++++---- aio/code/commons/openapi.py | 12 ++- aio/code/data_process/brake.py | 5 +- aio/code/data_process/current.py | 4 +- aio/code/data_process/iso.py | 5 +- aio/code/data_process/wavelogger.py | 4 +- aio/code/durable_action/factory_test.py | 5 +- 13 files changed, 106 insertions(+), 57 deletions(-) diff --git a/.gitignore b/.gitignore index d0af568..e3f5f8c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ aio/assets/templates/c_msg.log* aio/code/durable_action/__pycache__/ aio/assets/templates/durable/ aio/assets/templates/.__c_msg.lock -aio/code/commons/__pycache__/ \ No newline at end of file +aio/code/commons/__pycache__/ +aio/assets/templates/debug.log diff --git a/aio/README.md b/aio/README.md index 65d2151..fecd128 100644 --- a/aio/README.md +++ b/aio/README.md @@ -596,3 +596,8 @@ v0.2.0.5(2024/07/31) - 修改获取初始速度的逻辑,只获取configs文件中配置的时间内的速度 - 新增 configs 参数 single_brake,可针对特定条件做测试 10. [APIs: all]: 添加了 logger.setLevel(INFO),只有添加这个,单个模块内才生效 + +v0.2.0.6(2024/08/09) +1. [t_change_ui: all files] + - 修改了 logger 的实现 + - 尤其是 clibs.py,使用日志字典,重写了日志记录的功能 \ No newline at end of file diff --git a/aio/code/aio.py b/aio/code/aio.py index 7db0277..d7d8236 100644 --- a/aio/code/aio.py +++ b/aio/code/aio.py @@ -14,16 +14,14 @@ from commons import openapi, clibs from matplotlib.pyplot import rcParams, figure, subplots_adjust, close from matplotlib import use from pandas import DataFrame, read_excel -from logging import getLogger, INFO -with open(clibs.log_data, 'w') as _: +with open(clibs.log_data_hmi, 'w') as _hmi, open(clibs.log_data_debug, 'w', encoding='utf-8') as _debug: for i in range(1, 11): try: - remove(f'{clibs.log_data}.{i}') + remove(f'{clibs.log_data_hmi}.{i}') except FileNotFoundError: pass -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod logger.info("日志文件初始化完成...") use('Agg') diff --git a/aio/code/automatic_test/btn_functions.py b/aio/code/automatic_test/btn_functions.py index 48d9378..7ac7878 100644 --- a/aio/code/automatic_test/btn_functions.py +++ b/aio/code/automatic_test/btn_functions.py @@ -1,11 +1,8 @@ -from json import loads from sys import argv -from logging import getLogger, INFO from commons import clibs tab_name = clibs.tab_names['at'] -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod def trigger_estop(md, w2t): @@ -40,7 +37,7 @@ def get_state(hr, w2t): def warning_info(hr, w2t): for postfix in ['', '.2', '.3', '.4', '.5', '.6', '.7', '.8', '.9', '.10']: - log_name = clibs.log_data + postfix + log_name = clibs.log_data_hmi + postfix try: with open(log_name, 'r', encoding='utf-8') as f_log: for line in f_log: diff --git a/aio/code/automatic_test/do_brake.py b/aio/code/automatic_test/do_brake.py index 5436903..76a07e9 100644 --- a/aio/code/automatic_test/do_brake.py +++ b/aio/code/automatic_test/do_brake.py @@ -5,12 +5,10 @@ from paramiko import SSHClient, AutoAddPolicy from json import loads from openpyxl import load_workbook from pandas import DataFrame, concat -from logging import getLogger, INFO from commons import clibs tab_name = clibs.tab_names['at'] -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod def check_files(path, loadsel, data_dirs, data_files, w2t): @@ -107,6 +105,7 @@ def run_rl(path, loadsel, hr, md, config_file, result_dirs, w2t): write_diagnosis = float(ws.cell(row=3, column=10).value) get_init_speed = float(ws.cell(row=4, column=10).value) single_brake = str(ws.cell(row=5, column=10).value) + logger.info(f"write_diagnosis = {write_diagnosis}, get_init_speed = {get_init_speed}, single_brake = {single_brake}") if ws.cell(row=1, column=1).value == 'positive': md.write_pon(1) diff --git a/aio/code/automatic_test/do_current.py b/aio/code/automatic_test/do_current.py index f26950c..0d15ab8 100644 --- a/aio/code/automatic_test/do_current.py +++ b/aio/code/automatic_test/do_current.py @@ -4,12 +4,9 @@ from sys import argv from paramiko import SSHClient, AutoAddPolicy from json import loads from pandas import DataFrame, concat -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) - +logger = clibs.log_prod tab_name = clibs.tab_names['at'] display_pdo_params = [ {"name": "hw_joint_vel_feedback", "channel": 0}, diff --git a/aio/code/commons/clibs.py b/aio/code/commons/clibs.py index 9aeee42..32f4d1a 100644 --- a/aio/code/commons/clibs.py +++ b/aio/code/commons/clibs.py @@ -4,10 +4,12 @@ from time import sleep from os.path import exists from paramiko import SSHClient, AutoAddPolicy from socket import setdefaulttimeout -from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL, Formatter, StreamHandler, basicConfig -from concurrent_log_handler import ConcurrentRotatingFileHandler +from logging import getLogger +from logging.config import dictConfig +import concurrent_log_handler -ip_addr = '192.168.0.160' +ip_addr = '192.168.0.160' # for product +# ip_addr = '192.168.84.129' # for test RADIAN = 57.3 # 180 / 3.1415926 MAX_FRAME_SIZE = 1024 TIMEOUT = 5 @@ -15,7 +17,8 @@ setdefaulttimeout(TIMEOUT) tab_names = {'dp': 'Data Process', 'at': 'Automatic Test', 'da': 'Duration Action', 'op': 'openapi'} # PREFIX = '' # for pyinstaller packaging PREFIX = '../assets/' # for source code debug -log_data = f'{PREFIX}templates/c_msg.log' +log_data_hmi = f'{PREFIX}templates/c_msg.log' +log_data_debug = f'{PREFIX}templates/debug.log' heartbeat = f'{PREFIX}templates/heartbeat' durable_data_current_xlsx = f'{PREFIX}templates/durable/durable_data_current.xlsx' durable_data_current_max_xlsx = f'{PREFIX}templates/durable/durable_data_current_max.xlsx' @@ -38,16 +41,80 @@ durable_data_current_max = { 'axis6': [0 for _ in range(18)], } -file_handler = ConcurrentRotatingFileHandler(filename=log_data, backupCount=10, maxBytes=50*1024*1024, encoding='utf-8') -file_handler.setLevel(INFO) -console_handler = StreamHandler() -console_handler.setLevel(WARNING) - -basicConfig( # level=INFO, - datefmt='%Y-%m-%dT%H:%M:%S', - format='%(asctime)s # %(levelname)s-%(filename)s-%(funcName)s # %(message)s', - handlers=[file_handler, console_handler], - ) +# version:表示版本,该键值为从1开始的整数。该key必选,除此之外,其它key都是可选。 +# formatters:日志格式化器,其value值为一个字典,该字典的每个键值对都代表一个Formatter,键值对中,key代表Formatter ID(自定义ID),value为字典,描述如何配置相应的Formatter实例。默认格式为 ‘%(message)s’ +# filters:日志过滤器,其value值为一个字典,该字典的每个键值对都代表一个Filter,键值对中,key代表Filter ID(自定义ID),value为字典,描述如何配置相应的Filter实例。 +# handlers:日志处理器,其value值为一个字典,该字典的每个键值对都代表一个Handler,键值对中,key代表Handler ID(自定义ID),value为字典,描述如何配置相应的Handler实例,包含以下配置key: +# class (必选):日志处理器类全称 +# level (可选):指定该日志处理器需要处理哪些级别的日志,低于该级别的日志将不被该handler处理。level可以为代表日志级别的整数或者表大写字符串,字符串日志级别和数字日志级别对应关系如下: +# CRITICAL 50 +# ERROR 40 +# WARNING 30 +# INFO 20 +# DEBUG 10 +# NOTSET 0 +f_complex = '%(asctime)s # %(name)s-%(levelname)s-%(module)s-%(funcName)s-%(lineno)d # %(message)s' +f_simple = '%(levelname)s-%(module)s-%(funcName)s-%(lineno)d: %(message)s' +log_dicts = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'standard': { + 'format': f_complex, + 'style': '%', + 'datefmt': '%Y-%m-%dT%H:%M:%S', + }, + 'test': { + 'format': f_simple, + 'style': '%', + 'datefmt': '%Y-%m-%dT%H:%M:%S', + }, + }, + 'filters': {}, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'test', + }, + 'hmi.log': { + 'level': 'DEBUG', + 'class': 'concurrent_log_handler.ConcurrentRotatingFileHandler', + 'filename': log_data_hmi, + 'maxBytes': 1024*1024*50, + 'backupCount': 10, + 'encoding': 'utf-8', + 'formatter': 'standard', + }, + 'debug.log': { + 'level': 'INFO', + 'class': 'logging.FileHandler', + 'filename': log_data_debug, + 'encoding': 'utf-8', + 'formatter': 'standard', + }, + }, + 'loggers': { + 'normal': { + 'handlers': ['hmi.log', 'debug.log'], + 'level': 'DEBUG', + 'propagate': False + }, + 'debug': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': False + }, + '': { + 'handlers': ['hmi.log', 'debug.log'], + 'level': 'DEBUG', + 'propagate': False + }, + } +} +dictConfig(log_dicts) +log_prod = getLogger('normal') +log_debug = getLogger('debug') class GetThreadResult(Thread): diff --git a/aio/code/commons/openapi.py b/aio/code/commons/openapi.py index 5908960..7e458e0 100644 --- a/aio/code/commons/openapi.py +++ b/aio/code/commons/openapi.py @@ -6,11 +6,9 @@ from time import time, sleep from pymodbus.client.tcp import ModbusTcpClient from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder from pymodbus.constants import Endian -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod class ModbusRequest(object): @@ -263,7 +261,7 @@ class HmiRequest(object): def msg_storage(self, response, flag=0): # response是解码后的字符串 messages = self.c_msg if flag == 0 else self.c_msg_xs - logger.info(f"{loads(response)}") + logger.debug(f"{loads(response)}") if 'move.monitor' in response: pass elif len(messages) < 10000: @@ -504,7 +502,7 @@ class HmiRequest(object): def get_from_id(self, msg_id, flag=0): for i in range(3): - with open(clibs.log_data, mode='r', encoding='utf-8') as f_log: + with open(clibs.log_data_hmi, mode='r', encoding='utf-8') as f_log: for line in f_log: if msg_id in line.strip(): return line @@ -512,7 +510,7 @@ class HmiRequest(object): else: # 尝试在上一次分割的日志中查找,只做一次 sleep(1) try: - with open(clibs.log_data+'.1', mode='r', encoding='utf-8') as f_log: + with open(clibs.log_data_hmi+'.1', mode='r', encoding='utf-8') as f_log: for line in f_log: if msg_id in line.strip(): return line @@ -617,7 +615,7 @@ class HmiRequest(object): self.c.send(self.package(cmd)) sleep(0.5) except Exception as Err: - self.w2t(f"{cmd}\n请求发送失败...{Err}", 0, 0, 'red', tab_name=self.tab_name) + self.w2t(f"{cmd}: 请求发送失败...{Err}", 0, 0, 'red', tab_name=self.tab_name) return req['id'] diff --git a/aio/code/data_process/brake.py b/aio/code/data_process/brake.py index 1b1cfaa..28192b4 100644 --- a/aio/code/data_process/brake.py +++ b/aio/code/data_process/brake.py @@ -1,15 +1,12 @@ -# coding: utf-8 from os.path import isfile from sys import argv from openpyxl import load_workbook from time import time, sleep, strftime, localtime from threading import Thread from pandas import read_csv -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod def check_files(path, raw_data_dirs, result_files, w2t): diff --git a/aio/code/data_process/current.py b/aio/code/data_process/current.py index c4fc7c3..811da22 100644 --- a/aio/code/data_process/current.py +++ b/aio/code/data_process/current.py @@ -5,11 +5,9 @@ from re import match from threading import Thread from time import sleep from csv import reader, writer -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod def w2t_local(msg, wait, w2t): diff --git a/aio/code/data_process/iso.py b/aio/code/data_process/iso.py index 91397af..8c13c02 100644 --- a/aio/code/data_process/iso.py +++ b/aio/code/data_process/iso.py @@ -1,13 +1,10 @@ -# _*_ encoding:utf-8 _*_ import pdfplumber from openpyxl import load_workbook from os import remove from sys import argv -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod def p_iso(file, p_files, ws, tmpfile): diff --git a/aio/code/data_process/wavelogger.py b/aio/code/data_process/wavelogger.py index 013b527..b1e53cf 100644 --- a/aio/code/data_process/wavelogger.py +++ b/aio/code/data_process/wavelogger.py @@ -2,11 +2,9 @@ from pandas import read_csv from csv import reader from sys import argv from openpyxl import Workbook -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) +logger = clibs.log_prod def find_point(bof, step, pos, data_file, flag, df, row, w2t): diff --git a/aio/code/durable_action/factory_test.py b/aio/code/durable_action/factory_test.py index 7e725fa..b9c0d71 100644 --- a/aio/code/durable_action/factory_test.py +++ b/aio/code/durable_action/factory_test.py @@ -6,12 +6,9 @@ from openpyxl import load_workbook from math import sqrt from numpy import power from csv import writer -from logging import getLogger, INFO from commons import clibs -logger = getLogger(__file__) -logger.setLevel(INFO) - +logger = clibs.log_prod tab_name = clibs.tab_names['da'] count = 0 display_pdo_params = [ From 4925d899b42d53181c211791789191fa1ef5eeac Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 10 Aug 2024 17:23:20 +0800 Subject: [PATCH 36/36] =?UTF-8?q?=E5=8D=83=E5=88=86=E8=A1=A8=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=87=87=E9=9B=86=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + dial_gauge/README.md | 2 + dial_gauge/conf.ini | 6 ++ dial_gauge/gauge.py | 99 +++++++++++++++++++++++++++++++ dial_gauge/gauge.xml | 43 ++++++++++++++ dial_gauge/target_dial_gauge.zip | Bin 0 -> 7888 bytes 6 files changed, 151 insertions(+) create mode 100644 dial_gauge/README.md create mode 100644 dial_gauge/conf.ini create mode 100644 dial_gauge/gauge.py create mode 100644 dial_gauge/gauge.xml create mode 100644 dial_gauge/target_dial_gauge.zip diff --git a/.gitignore b/.gitignore index e3f5f8c..9013072 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ aio/assets/templates/durable/ aio/assets/templates/.__c_msg.lock aio/code/commons/__pycache__/ aio/assets/templates/debug.log +dial_gauge/results.xlsx diff --git a/dial_gauge/README.md b/dial_gauge/README.md new file mode 100644 index 0000000..b16f45a --- /dev/null +++ b/dial_gauge/README.md @@ -0,0 +1,2 @@ +## 千分表数据自动采集 + diff --git a/dial_gauge/conf.ini b/dial_gauge/conf.ini new file mode 100644 index 0000000..295d61a --- /dev/null +++ b/dial_gauge/conf.ini @@ -0,0 +1,6 @@ +[md_rtu] +port = COM10 + +[md_tcp] +addr = 192.168.0.160 +port = 502 diff --git a/dial_gauge/gauge.py b/dial_gauge/gauge.py new file mode 100644 index 0000000..0f44f30 --- /dev/null +++ b/dial_gauge/gauge.py @@ -0,0 +1,99 @@ +from configparser import ConfigParser +from pymodbus.client import ModbusSerialClient, ModbusTcpClient +from time import sleep, strftime, localtime, time +from openpyxl import load_workbook, Workbook +from os import rename +# import pymodbus +# pymodbus.pymodbus_apply_logging_config("DEBUG") + + +def initializations(): + try: + now = strftime("%Y%m%d%H%M%S", localtime(time())) + rename('results.xlsx', f'results_{now}.xlsx') + except FileNotFoundError: + pass + + wb = Workbook() + ws = wb.active + ws.title = 'results' + ws['A1'].value = '时间' + ws['B1'].value = '次数' + ws['C1'].value = '结果' + wb.save('results.xlsx') + wb.close() + + +def do_connections(): + configs = ConfigParser() + configs.read('conf.ini') + + # ================ 配置Modbus TCP客户端 ================ + tcp_host = configs.get('md_tcp', 'addr') + tcp_port = configs.getint('md_tcp', 'port') + + client_tcp = ModbusTcpClient(tcp_host, tcp_port) + if client_tcp.connect(): + print(f"Modbus TCP已连接到{tcp_host}:{tcp_port}...") + else: + raise Exception(f"Modbus TCP无法连接到{tcp_host}:{tcp_port}...") + + # ================ 配置Modbus RTU客户端 ================ + rtu_port = configs.get('md_rtu', 'port') + + client_rtu = ModbusSerialClient( + method='rtu', + port=rtu_port, # 根据实际情况调整端口,Windows上可能是 'COM3' + baudrate=38400, # 根据协议设定波特率为38400 + timeout=1, + parity='N', # 无奇偶校验 + stopbits=2, # 2个停止位 + bytesize=8 # 8个数据位 + ) + if client_rtu.connect(): + print(f"Modbus RTU已连接到系统{rtu_port}端口...") + else: + raise Exception(f"Modbus RTU无法连接到系统{rtu_port}端口...") + + return client_tcp, client_rtu + + +def get_gauge_data(client_tcp, client_rtu): + count = 2 + client_tcp.write_register(41000, 1) # 将 act 信号置为 True + # ================ 功能实现 ================ + while True: + while True: + res_tcp = client_tcp.read_holding_registers(41001, 1) # 获取 time_to_go 的值 + sleep(0.5) + if not res_tcp.registers[0]: + continue + else: + break + try: + res_rtu = client_rtu.read_holding_registers(0x0000, 2, slave=1) + plus_or_minus = 1 if res_rtu.registers[0] == 0 else -1 + result = res_rtu.registers[1] * plus_or_minus / 10000 + now = strftime("%Y-%m-%d %H:%M:%S", localtime(time())) + wb = load_workbook('results.xlsx') + ws = wb['results'] + ws[f'A{count}'].value = now + ws[f'B{count}'].value = count-1 + ws[f'C{count}'].value = float(result) + wb.save('results.xlsx') + wb.close() + count += 1 + except: + client_tcp.write_register(41000, 0) # 将 act 信号置为 False + + sleep(2) # + + +def main(): + initializations() + client_tcp, client_rtu = do_connections() + get_gauge_data(client_tcp, client_rtu) + + +if __name__ == '__main__': + main() diff --git a/dial_gauge/gauge.xml b/dial_gauge/gauge.xml new file mode 100644 index 0000000..4a8fe65 --- /dev/null +++ b/dial_gauge/gauge.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dial_gauge/target_dial_gauge.zip b/dial_gauge/target_dial_gauge.zip new file mode 100644 index 0000000000000000000000000000000000000000..27ee43556dfb350065635c1820eb2337e35e8e85 GIT binary patch literal 7888 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 Kg3zBw0RI6z@dOS4 literal 0 HcmV?d00001