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 输出,后续持续优化
This commit is contained in:
@ -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)
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user