From b01f8dc19cfd9b4c9d567eee4d6efe0d0e70c22f Mon Sep 17 00:00:00 2001 From: gitea Date: Sat, 27 Jul 2024 21:31:09 +0800 Subject: [PATCH] =?UTF-8?q?v0.2.0.3(2024/07/27)=201.=20[APIs:=20do=5Fbrake?= =?UTF-8?q?.py]:=20=E7=B2=BE=E7=AE=80=E7=A8=8B=E5=BA=8F=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=20OOM=20=E9=97=AE=E9=A2=98=202.=20[APIs:=20do=5Fcurre?= =?UTF-8?q?nt.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=203.=20[APIs:=20f?= =?UTF-8?q?actory=5Ftest.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=204.=20[?= =?UTF-8?q?APIsL=20openapi.py]=20=20=20=20-=20=E5=BF=83=E8=B7=B3=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=201=20s=EF=BC=8C=E5=9B=A0=E4=B8=BA=20OOM=20?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E7=9A=84=E8=A7=A3=E5=86=B3=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E4=BA=8E=E9=95=BF=E4=B9=85=E7=9A=84=E6=89=93=E5=BC=80=E6=9B=B2?= =?UTF-8?q?=E7=BA=BF=E5=BC=80=E5=85=B3=EF=BC=8C=E6=AD=A4=E6=97=B6=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=20hr.c=5Fmsg=20=E7=9A=84=E5=AE=9A=E6=97=B6=E6=B8=85?= =?UTF-8?q?=E7=90=86=E6=98=AF=E4=B8=AA=E6=8C=91=E6=88=98=EF=BC=8C=E5=B0=86?= =?UTF-8?q?=E5=BF=83=E8=B7=B3=E7=BC=A9=E7=9F=AD=EF=BC=8C=E6=9C=89=E5=88=A9?= =?UTF-8?q?=E4=BA=8E=E6=B8=85=E7=90=86=E6=97=A5=E5=BF=97=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E4=B8=A2=E5=A4=B1=E5=BF=83=E8=B7=B3=20=20=20?= =?UTF-8?q?=20-=20=E6=96=B0=E5=A2=9E=20diagnosis.save=20=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E6=98=AF=E6=89=A7=E8=A1=8C=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E6=9C=89=E9=97=AE=E9=A2=98=EF=BC=8C=E5=BE=85=E8=A7=A3=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