制动性能测试和数据处理已完成

This commit is contained in:
gitea 2025-01-16 19:28:57 +08:00
parent 2413d6d305
commit 26f01635df
55 changed files with 1588 additions and 1251 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ test.py
.idea/ .idea/
.venv/ .venv/
assets/logs/ assets/logs/
assets/files/examples/
package/ package/
code/common/__pycache__/ code/common/__pycache__/
code/data_process/__pycache__/ code/data_process/__pycache__/

Binary file not shown.

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "safety",
"command": "collision.get_params"
}

View File

@ -0,0 +1,6 @@
{
"id": "xxxxxxxxxxx",
"module": "safety",
"command": "collision.set_params",
"data": null
}

View File

@ -0,0 +1,7 @@
{
"module": "safety",
"command": "collision.set_state",
"data": {
"collision_state": false
}
}

View File

@ -1,5 +1,5 @@
{ {
"id": "xxxxxxxxxxx", "id":"xxxxxxxxxxx",
"module": "system", "module":"system",
"command": "controller.get_params" "command":"controller.get_params"
} }

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "controller.reboot",
"data": {
"arg": 6
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "controller.set_params",
"data": {
"time": "2020-02-28 15:28:30"
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "dynamic",
"command": "drag.get_params"
}

View File

@ -0,0 +1,10 @@
{
"id": "xxxxxxxxxxx",
"module": "dynamic",
"command": "drag.set_params",
"data": {
"enable": true,
"space": 0,
"type": 0
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "fieldbus_device.get_params"
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "fieldbus_device.load_cfg",
"data": {
"file_name": "fieldbus_device.json"
}
}

View File

@ -0,0 +1,9 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "fieldbus_device.set_params",
"data": {
"device_name": "modbus_1",
"enable": true
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "io",
"command": "io_device.load_cfg"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "jog.get_params"
}

View File

@ -0,0 +1,10 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "jog.set_params",
"data": {
"step": 1000,
"override": 0.2,
"space": 5
}
}

View File

@ -0,0 +1,10 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "jog.start",
"data": {
"index": 0,
"direction": true,
"is_ext": false
}
}

View File

@ -0,0 +1,8 @@
{
"id": "log_code.data.code_list",
"s": {
"log_code.data": {
"code_list": []
}
}
}

View File

@ -0,0 +1,5 @@
{
"g": {
"log_code.data": "null"
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "modbus.get_params"
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "modbus.get_values",
"data": {
"mode": "all"
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "modbus.load_cfg",
"data": {
"file" : "registers.json"
}
}

View File

@ -0,0 +1,12 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "modbus.set_params",
"data": {
"enable_slave": true,
"ip": "192.168.0.160",
"port": 502,
"slave_id": 0,
"enable_master": false
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.get_joint_pos"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.get_monitor_cfg"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.get_params"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.get_pos"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.get_quickstop_distance"
}

View File

@ -0,0 +1,5 @@
{
"id" : "xxxxxxxxx",
"module": "motion",
"command": "move.get_quickturn_pos"
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.quick_turn",
"data": {
"name":"home"
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.set_monitor_cfg",
"data": {
"ref_coordinate": 1
}
}

View File

@ -0,0 +1,17 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.set_params",
"data": {
"MOTION": {
"JOINT_MAX_SPEED": [1.0,0.0,0.0,0.0,0.0,0.0],
"JOINT_MAX_ACC": [1.0,0.0,0.0,0.0,0.0,0.0],
"JOINT_MAX_JERK": [1.0,0.0,0.0],
"TCP_MAX_SPEED": 500,
"DEFAULT_ACC_PARAMS": [0.3,1.0],
"VEL_SMOOTH_FACTOR": 3.33,
"ACC_RAMPTIME_JOG": 0.01
}
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.set_quickstop_distance",
"data":{
"distance": 2
}
}

View File

@ -0,0 +1,15 @@
{
"id" : "xxxxxxxxx",
"module": "motion",
"command": "move.set_quickturn_pos",
"data": {
"enable_home": false,
"enable_drag": false,
"enable_transport": false,
"joint_home": [0.0,0.0,0.0,0.0,0.0,0.0,0.0],
"joint_drag": [0.0,0.0,0.0,0.0,0.0,0.0,0.0],
"joint_transport": [0.0,0.0,0.0,0.0,0.0,0.0,0.0],
"end_posture": 0,
"home_error_range":[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "motion",
"command": "move.stop",
"data":{
"stoptype": 0
}
}

View File

@ -0,0 +1,7 @@
{
"c": {
"safety.safety_area.overall_enable": {
"enable": true
}
}
}

View File

@ -0,0 +1,8 @@
{
"c": {
"safety.safety_area.safety_area_enable": {
"id": 0,
"enable": true
}
}
}

View File

@ -0,0 +1,5 @@
{
"c": {
"safety.safety_area.set_param": null
}
}

View File

@ -0,0 +1,7 @@
{
"c": {
"safety.safety_area.signal_enable": {
"signal": true
}
}
}

View File

@ -0,0 +1,5 @@
{
"g": {
"safety_area_data": null
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "robot",
"command": "servo.clear_alarm"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "network",
"command": "socket.get_params"
}

View File

@ -0,0 +1,17 @@
{
"id": "xxxxxxxxxxx",
"module": "network",
"command": "socket.set_params",
"data": {
"enable": true,
"ip": "",
"name": "c1",
"port": "8080",
"suffix": "\r",
"type": 1,
"reconnect_flag": false,
"auto_connect": true,
"disconnection_triggering_behavior": 0,
"disconnection_detection_time": 10
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "safety",
"command": "soft_limit.get_params"
}

View File

@ -0,0 +1,12 @@
{
"id": "xxxxxxxxxxx",
"module": "safety",
"command": "soft_limit.set_params",
"data": {
"enable": true,
"upper": [0,0,0,0,0,0,0],
"lower": [0,0,0,0,0,0,0],
"reduced_upper": [0,0,0,0,0,0,0],
"reduced_lower": [0,0,0,0,0,0,0]
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "io",
"command": "system_io.query_configuration"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "io",
"command": "system_io.query_event_cfg"
}

View File

@ -0,0 +1,9 @@
{
"id": "xxxxxxxxxxx",
"module": "io",
"command": "system_io.update_configuration",
"data": {
"input_system_io": {},
"output_system_io": {}
}
}

View File

@ -15,7 +15,7 @@ from datetime import datetime
import os import os
from common import clibs, openapi from common import clibs, openapi
from data_process import current, brake, iso, wavelogger from data_process import current, brake, iso, wavelogger
from automatic_test import do_current from automatic_test import do_current, do_brake
import threading import threading
import re import re
@ -298,7 +298,7 @@ class App:
def __is_running(operation): def __is_running(operation):
if clibs.running: if clibs.running:
messagebox.showerror(title="处理中", message=f"有程序正在运行,需等待结束后,在执行{operation}操作!") messagebox.showerror(title="处理中", message=f"有程序正在运行,需等待结束后,在执行{operation}操作!")
return return "running"
def __program_start(self): def __program_start(self):
def get_data_dp(): def get_data_dp():
@ -323,7 +323,8 @@ class App:
return data return data
def init_op(): def init_op():
self.__is_running("开始") if self.__is_running("开始") == "running":
return
self.text_output.delete("1.0", ctk.END) self.text_output.delete("1.0", ctk.END)
self.tabview_bottom.set("输出") self.tabview_bottom.set("输出")
clibs.tl_prg = self.__toplevel_progress clibs.tl_prg = self.__toplevel_progress
@ -339,7 +340,6 @@ class App:
def exec_function(): def exec_function():
init_op() init_op()
if self.tabview_top.get() == "数据处理": if self.tabview_top.get() == "数据处理":
if not clibs.running:
clibs.running = True clibs.running = True
clibs.data_dp = get_data_dp() clibs.data_dp = get_data_dp()
try: try:
@ -347,10 +347,7 @@ class App:
finally: finally:
clibs.running = False clibs.running = False
clibs.stop = False clibs.stop = False
else:
messagebox.showinfo(title="进行中...", message="当前有程序正在运行!")
elif self.tabview_top.get() == "自动测试": elif self.tabview_top.get() == "自动测试":
if not clibs.running:
clibs.running = True clibs.running = True
clibs.data_at = get_data_at() clibs.data_at = get_data_at()
try: try:
@ -358,8 +355,6 @@ class App:
finally: finally:
clibs.running = False clibs.running = False
clibs.stop = False clibs.stop = False
else:
messagebox.showinfo(title="进行中...", message="当前有程序正在运行!")
exec_function() exec_function()
@ -371,7 +366,8 @@ class App:
self.entry_path_atv.set("数据文件夹路径") self.entry_path_atv.set("数据文件夹路径")
self.entry_path_atv.set("数据文件夹路径") self.entry_path_atv.set("数据文件夹路径")
self.__is_running("重置") if self.__is_running("重置") == "running":
return
if clibs.db_state == "readwrite": if clibs.db_state == "readwrite":
res = messagebox.askyesno(title="状态重置", message="这将清空本次所有的输出以及日志记录,且不可恢复,请确认!", default=messagebox.NO, icon=messagebox.WARNING) res = messagebox.askyesno(title="状态重置", message="这将清空本次所有的输出以及日志记录,且不可恢复,请确认!", default=messagebox.NO, icon=messagebox.WARNING)
@ -522,7 +518,8 @@ class App:
get_next_page() get_next_page()
def __load_log_db(self): def __load_log_db(self):
self.__is_running("加载") if self.__is_running("加载") == "running":
return
db_file = filedialog.askopenfilename(title="加载数据库文件", defaultextension=".db", initialdir=f"{clibs.PREFIX}/logs") db_file = filedialog.askopenfilename(title="加载数据库文件", defaultextension=".db", initialdir=f"{clibs.PREFIX}/logs")
if not db_file: if not db_file:
return return
@ -979,10 +976,9 @@ class App:
clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port) clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port) clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port)
clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password) clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
# clibs.c_md.read_scenario_time()
# clibs.c_md.write_speed_max(123.456)
# clibs.c_hr.execution('state.set_tp_mode', tp_mode='without') # clibs.c_hr.execution('state.set_tp_mode', tp_mode='without')
# clibs.c_hr.execution("diagnosis.open", open=False, display_open=False, overrun=True, turn_area=True, delay_motion=False)
# clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=[], frequency=50, version="1.4.1")
self.btn_conn.configure(state="normal", fg_color="#2E8B57") self.btn_conn.configure(state="normal", fg_color="#2E8B57")
except Exception: except Exception:
self.btn_conn.configure(state="normal", fg_color="#979DA2") self.btn_conn.configure(state="normal", fg_color="#979DA2")

View File

@ -4,33 +4,33 @@ import paramiko
import openpyxl import openpyxl
import pandas import pandas
import json import json
from commons import clibs from common import clibs, openapi
def initialization(path, sub, data_dirs, data_files, hr, w2t): def initialization(path, sub, data_dirs, data_files, hr, w2t):
def check_files(): def check_files():
if len(data_dirs) != 0 or len(data_files) != 6: msg = "初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!\n"
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!", "red") msg += "1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n"
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError") if len(data_dirs) != 0 or len(data_files) != 5:
w2t(msg, "red", "InitFileError")
config_file, reach33, reach66, reach100, prj_file, result_dirs = None, None, None, None, None, [] config_file, reach33_file, reach66_file, reach100_file, prj_file, result_dirs = None, None, None, None, None, []
for data_file in data_files: for data_file in data_files:
filename = data_file.split("/")[-1] filename = data_file.split("/")[-1]
if filename == "configs.xlsx": if filename == "configs.xlsx":
config_file = data_file config_file = data_file
elif filename.startswith("reach33_") and filename.endswith(".xlsx"): elif filename.startswith("reach33_") and filename.endswith(".xlsx"):
reach33 = data_file reach33_file = data_file
elif filename.startswith("reach66_") and filename.endswith(".xlsx"): elif filename.startswith("reach66_") and filename.endswith(".xlsx"):
reach66 = data_file reach66_file = data_file
elif filename.startswith("reach100_") and filename.endswith(".xlsx"): elif filename.startswith("reach100_") and filename.endswith(".xlsx"):
reach100 = data_file reach100_file = data_file
elif filename.endswith(".zip"): elif filename.endswith(".zip"):
prj_file = data_file prj_file = data_file
else: else:
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!", "red") w2t(msg, "red", "InitFileError")
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError")
if config_file and reach33 and reach66 and reach100 and prj_file: if config_file and reach33_file and reach66_file and reach100_file and prj_file:
os.mkdir(f"{path}/j1") os.mkdir(f"{path}/j1")
os.mkdir(f"{path}/j2") os.mkdir(f"{path}/j2")
os.mkdir(f"{path}/j3") os.mkdir(f"{path}/j3")
@ -46,10 +46,9 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
os.mkdir(f"{path}/j3/{dir_name}") os.mkdir(f"{path}/j3/{dir_name}")
w2t("数据目录合规性检查结束,未发现问题......\n", "blue") w2t("数据目录合规性检查结束,未发现问题......\n", "blue")
return config_file, reach33, reach66, reach100, prj_file, result_dirs return config_file, prj_file, result_dirs
else: else:
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!", "red") w2t(msg, "red", "InitFileError")
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError")
def get_configs(): def get_configs():
robot_type = None robot_type = None
@ -76,40 +75,45 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}") clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}")
return avs return avs
_config_file, _reach33, _reach66, _reach100, _prj_file, _result_dirs = check_files() clibs.c_hr.set_socket_params(True, str(clibs.external_port), "\r", 1)
clibs.c_ec = openapi.ExternalCommunication(clibs.ip_addr, clibs.external_port)
_config_file, _prj_file, _result_dirs = check_files()
_avs = get_configs() _avs = get_configs()
return _config_file, _reach33, _reach66, _reach100, _prj_file, _result_dirs, _avs return _config_file, _prj_file, _result_dirs, _avs
@clibs.db_lock @clibs.db_lock
def gen_result_file(path, axis, reach, load, speed, rounds): def gen_result_file(path, axis, t_end, reach, load, speed, rounds):
d_vel, d_trq, d_stop = [], [], [] d_vel, d_trq, d_stop = [], [], []
len_records = 12 * 1000 // 50 start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t_end-12))
clibs.cursor.execute(f"select content from logs where content like 'diagnosis.result' limit {len_records}") end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t_end))
clibs.cursor.execute(f"select content from logs where time between '{start_time}' and '{end_time}' and content like '%diagnosis.result%' order by id asc")
records = clibs.cursor.fetchall() records = clibs.cursor.fetchall()
for record in records: # 保留最后12s的数据 for record in records: # 保留最后12s的数据
data = eval(record)["data"] data = eval(record[0])["data"]
for item in data: for item in data:
d_item = reversed(item["value"])
if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback": if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback":
d_vel.extend(item["value"]) d_vel.extend(d_item)
elif item.get("channel", None) == axis-1 and item.get("name", None) == "device_servo_trq_feedback": elif item.get("channel", None) == axis-1 and item.get("name", None) == "device_servo_trq_feedback":
d_trq.extend(item["value"]) d_trq.extend(d_item)
elif item.get("channel", None) == 0 and item.get("name", None) == "device_safety_estop": elif item.get("channel", None) == 0 and item.get("name", None) == "device_safety_estop":
d_stop.extend(item["value"]) d_stop.extend(d_item)
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel}) df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq}) df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
df3 = pandas.DataFrame.from_dict({"device_safety_estop": d_stop}) df3 = pandas.DataFrame.from_dict({"device_safety_estop": d_stop})
df = pandas.concat([df1, df2, df3], axis=1) df = pandas.concat([df1, df2, df3], axis=1)
filename = f"{path}\\j{axis}\\reach{reach}_load{load}_speed{speed}\\reach{reach}_load{load}_speed{speed}_{rounds}.data" filename = f"{path}/j{axis}/reach{reach}_load{load}_speed{speed}/reach{reach}_load{load}_speed{speed}_{rounds}.data"
df.to_csv(filename, sep="\t", index=False) df.to_csv(filename, sep="\t", index=False)
def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t): def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
count, total = 0, 63 count, total, speed_target = 0, 63, 0
prj_name = prj_file.split("/")[-1].split(".")[0] prj_name = prj_file.split("/")[-1].split(".")[0]
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback"] for chl in range(6)] display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback"] for chl in range(6)]
display_pdo_params.append({"name": "device_safety_estop", "channel": 0}) display_pdo_params.append({"name": "device_safety_estop", "channel": 0})
@ -119,7 +123,9 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
get_init_speed = float(ws.cell(row=3, column=2).value) get_init_speed = float(ws.cell(row=3, column=2).value)
single_brake = str(ws.cell(row=4, column=2).value) single_brake = str(ws.cell(row=4, column=2).value)
pon = ws.cell(row=5, column=2).value pon = ws.cell(row=5, column=2).value
w2t(f"write_diagnosis = {write_diagnosis}, get_init_speed = {get_init_speed}, single_brake = {single_brake}\n") io_name = ws.cell(row=6, column=2).value.upper()
wb.close()
w2t(f"基本参数配置write_diagnosis = {write_diagnosis}, get_init_speed = {get_init_speed}, single_brake = {single_brake}, pon = {pon}\n")
if pon == "positive": if pon == "positive":
md.write_pon(1) md.write_pon(1)
@ -136,7 +142,7 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
speed = condition.split("_")[2].removeprefix("speed") speed = condition.split("_")[2].removeprefix("speed")
# for single condition test # for single condition test
single_axis = 0 single_axis = -1
if single_brake != "0": if single_brake != "0":
total = 3 total = 3
single_axis = int(single_brake.split("-")[0]) single_axis = int(single_brake.split("-")[0])
@ -145,25 +151,28 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
for axis in range(1, 4): for axis in range(1, 4):
# for single condition test # for single condition test
if (single_axis != 0 and single_axis != axis) or (axis == 3 and reach != "100"): if (single_axis != -1 and single_axis != axis) or (axis == 3 and reach != "100"):
continue continue
md.write_axis(axis) md.write_axis(axis)
w2t(f"-"*90+"\n", "purple") w2t(f"-"*90+"\n", "purple")
for rounds in range(1, 4): for rounds in range(1, 4):
count += 1 count += 1
_ = 3 if count % 3 == 0 else count % 3
this_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) this_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
prj_path = f"{prj_name}/_build/{prj_name}.prj" prj_path = f"{prj_name}/_build/{prj_name}.prj"
w2t(f"[{this_time} | {count}/{total}] 正在执行 {axis}{condition} 的第 {count} 次制动测试...\n") w2t(f"[{this_time} | {count}/{total}] 正在执行 {axis}{condition} 的第 {_} 次制动测试...\n")
# 1. 触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电 # 1. 触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
md.trigger_estop() md.r_soft_estop(0)
md.reset_estop() md.r_soft_estop(1)
md.clear_alarm() clibs.c_ec.setdo_value(io_name, "true")
md.r_reset_estop()
md.r_clear_alarm()
md.write_act(0) md.write_act(0)
time.sleep(write_diagnosis) # 软急停超差后等待写诊断时间可通过configs.xlsx配置 time.sleep(write_diagnosis) # 急停超差后等待写诊断时间可通过configs.xlsx配置2.3 版本之后设置为 0 即可
while count == 1: while count % 3 == 1:
# 2. 修改要执行的场景 # 2. 修改要执行的场景
rl_cmd = "" rl_cmd = ""
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
@ -176,24 +185,24 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
rl_speed = f"VelSet {speed}" rl_speed = f"VelSet {speed}"
rl_tool = f"tool p_tool = tool{sub.removeprefix("tool")}" rl_tool = f"tool p_tool = tool{sub.removeprefix("tool")}"
cmd = "cd /home/luoshi/bin/controller/; " cmd = "cd /home/luoshi/bin/controller/; "
cmd += 'sudo sed -i "/brake_E/d" projects/target/_build/brake/main.mod; ' cmd += f'sudo sed -i "/brake_E/d" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/DONOTDELETE/i {rl_cmd}" projects/target/_build/brake/main.mod; ' cmd += f'sudo sed -i "/DONOTDELETE/i {rl_cmd}" projects/{prj_name}/_build/brake/main.mod; '
cmd += 'sudo sed -i "/VelSet/d" projects/target/_build/brake/main.mod; ' cmd += f'sudo sed -i "/VelSet/d" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/MoveAbsJ/i {rl_speed}" projects/target/_build/brake/main.mod; ' cmd += f'sudo sed -i "/MoveAbsJ/i {rl_speed}" projects/{prj_name}/_build/brake/main.mod; '
cmd += 'sudo sed -i "/tool p_tool/d" projects/target/_build/brake/main.mod; ' cmd += f'sudo sed -i "/tool p_tool/d" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/VelSet/i {rl_tool}" projects/target/_build/brake/main.mod; ' cmd += f'sudo sed -i "/VelSet/i {rl_tool}" projects/{prj_name}/_build/brake/main.mod; '
stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True) stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
stdin.write(clibs.password + "\n") stdin.write(clibs.password + "\n")
stdout.read().decode() # 需要read一下才能正常执行 stdout.read().decode() # 需要read一下才能正常执行
stderr.read().decode() stderr.read().decode()
# 3. reload工程后pp2main并且自动模式和上电最后运行程序 # 3. reload工程后pp2main并且自动模式和上电最后运行程序
hr.execution("overview.reload", prj_path=prj_path, tasks=["brake", "stop0_related"]) hr.execution("overview.reload", prj_path=prj_path, tasks=["brake"])
hr.execution("rl_task.pp_to_main", tasks=["brake", "stop0_related"]) hr.execution("rl_task.pp_to_main", tasks=["brake"])
hr.execution("state.switch_auto") hr.execution("state.switch_auto")
hr.execution("state.switch_motor_on") hr.execution("state.switch_motor_on")
hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0) hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
hr.execution("rl_task.run", tasks=["brake", "stop0_related"]) hr.execution("rl_task.run", tasks=["brake"])
t_start = time.time() t_start = time.time()
while True: while True:
if md.read_ready_to_go() == 1: if md.read_ready_to_go() == 1:
@ -201,21 +210,24 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
break break
else: else:
time.sleep(1) time.sleep(1)
if (time.time() - t_start) // 20 > 1: if (time.time() - t_start) > 20:
w2t("20s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError") w2t("20s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
# 4. 找出最大速度传递给RL程序最后清除相关记录 # 4. 找出最大速度传递给RL程序最后清除相关记录
time.sleep(10) # 消除前 10s 的不稳定数据
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
time.sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度可通过configs.xlsx配置 time.sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度可通过configs.xlsx配置
clibs.execution("rl_task.stop", tasks=["brake"]) end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
hr.execution("rl_task.stop", tasks=["brake"])
time.sleep(5) # 确保数据都拿到
# 找出最大速度 # 找出最大速度
@clibs.db_lock @clibs.db_lock
def get_speed_max(): def get_speed_max():
_speed_max = 0 _speed_max = 0
len_records = int(get_init_speed * 20) + 1 # 1000 / 50 = 20 clibs.cursor.execute(f"select content from logs where time between '{start_time}' and '{end_time}' and content like '%diagnosis.result%' order by id asc")
clibs.cursor.execute(f"select content from logs where content like 'diagnosis.result' limit {len_records}")
records = clibs.cursor.fetchall() records = clibs.cursor.fetchall()
for record in records: for record in records:
data = eval(record)["data"] data = eval(record[0])["data"]
for item in data: for item in data:
if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback": if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback":
_ = clibs.RADIAN * sum(item["value"]) / len(item["value"]) _ = clibs.RADIAN * sum(item["value"]) / len(item["value"])
@ -234,20 +246,17 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
md.write_speed_max(speed_max) md.write_speed_max(speed_max)
if speed_max < 10: if speed_max < 10:
md.clear_alarm() md.r_clear_alarm()
w2t("未获取到正确的速度,即将重新获取...\n", "red") w2t("未获取到正确的速度,即将重新获取...\n", "red")
continue continue
else: else:
break break
# 5. 清除软急停重新运行程序并打开曲线发送继续运动信号当速度达到最大值时通过DO触发急停 # 5. 重新运行程序发送继续运动信号当速度达到最大值时通过DO触发急停
md.reset_estop() # 其实没必要 hr.execution("rl_task.pp_to_main", tasks=["brake"])
md.clear_alarm()
hr.execution("rl_task.pp_to_main", tasks=["brake", "stop0_related"])
hr.execution("state.switch_auto") hr.execution("state.switch_auto")
hr.execution("state.switch_motor_on") hr.execution("state.switch_motor_on")
hr.execution("rl_task.run", tasks=["brake", "stop0_related"]) hr.execution("rl_task.run", tasks=["brake"])
for i in range(3): for i in range(3):
if md.read_ready_to_go() == 1: if md.read_ready_to_go() == 1:
md.write_act(1) md.write_act(1)
@ -258,21 +267,38 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
w2t("3s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError") w2t("3s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
time.sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间 time.sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
md.write_probe(1)
t_start = time.time()
while True:
if md.read_brake_done() == 1:
time.sleep(4) # 保证速度归零
md.write_probe(0)
break
else:
time.sleep(1)
if (time.time() - t_start) > 30:
md.write_probe(0)
w2t(f"30s 内未触发急停,该条数据无效,需要确认 RL/Python 程序配置正确并正常执行,或者判别是否是机器本体问题,比如正负方向速度是否一致...", "red", "NoEstopTriggeredError")
def exec_brake():
flag, start, data, record = True, time.time(), None, None
while flag:
time.sleep(0.2)
if time.time() - start > 20:
w2t("20s 内未触发急停,需排查......", "red", "BrakeTimeoutError")
try:
clibs.lock.acquire(True)
clibs.cursor.execute(f"select content from logs where content like '%diagnosis.result%' order by id desc limit 1")
record = clibs.cursor.fetchone()
data = eval(record[0])["data"]
finally:
clibs.lock.release()
for item in data:
if item.get("channel", None) != axis-1 or item.get("name", None) != "hw_joint_vel_feedback":
continue
speed_moment = clibs.RADIAN * sum(item["value"]) / len(item["value"])
if (pon == "positive" and speed_moment > 0) or (pon == "negative" and speed_moment < 0):
if abs(speed_moment) > speed_target * 0.95:
clibs.c_ec.setdo_value(io_name, "false")
time.sleep(5)
flag = False
break
return time.time()
t_end = exec_brake()
# 6. 保留数据并处理输出 # 6. 保留数据并处理输出
gen_result_file(path, axis, reach, load, speed, rounds) gen_result_file(path, axis, t_end, reach, load, speed, rounds)
else: else:
w2t(f"\n{sub.removeprefix("tool")}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。\n", "green") w2t(f"\n{sub.removeprefix("tool")}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行。\n", "green")
hr.execution("diagnosis.open", open=False, display_open=False, overrun=True, turn_area=True, delay_motion=False) hr.execution("diagnosis.open", open=False, display_open=False, overrun=True, turn_area=True, delay_motion=False)
@ -280,21 +306,22 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
def main(): def main():
# path, hr, md, loadsel, w2t s_time = time.time()
path = clibs.data_at["_path"] path = clibs.data_at["_path"]
sub = clibs.data_at["_sub"] sub = clibs.data_at["_sub"]
w2t = clibs.w2t w2t = clibs.w2t
hr = clibs.c_hr hr = clibs.c_hr
md = clibs.c_md md = clibs.c_md
s_time = time.time()
data_dirs, data_files = clibs.traversal_files(path, w2t) data_dirs, data_files = clibs.traversal_files(path, w2t)
config_file, reach33, reach66, reach100, prj_file, result_dirs, avs = initialization(path, sub, data_dirs, data_files, hr, w2t) config_file, prj_file, result_dirs, avs = initialization(path, sub, data_dirs, data_files, hr, w2t)
clibs.c_pd.push_prj_to_server(prj_file) clibs.c_pd.push_prj_to_server(prj_file)
run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t) run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t)
e_time = time.time() e_time = time.time()
time_total = e_time - s_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", "green") w2t(f"-" * 90 + "\n", "purple")
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n", "green")
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -201,7 +201,7 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
# 4. 执行采集 # 4. 执行采集
time.sleep(10) # 消除前 10s 的不稳定数据 time.sleep(10) # 消除前 10s 的不稳定数据
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
single_time, stall_time, scenario_time = 30, 10, 0 single_time, stall_time, scenario_time = 40, 10, 0
if number < 6: # 单轴 if number < 6: # 单轴
time.sleep(single_time) time.sleep(single_time)
elif number < 12: # 堵转 elif number < 12: # 堵转
@ -234,6 +234,7 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
def main(): def main():
s_time = time.time()
path = clibs.data_at["_path"] path = clibs.data_at["_path"]
sub = clibs.data_at["_sub"] sub = clibs.data_at["_sub"]
w2t = clibs.w2t w2t = clibs.w2t
@ -245,6 +246,11 @@ def main():
clibs.c_pd.push_prj_to_server(prj_file) clibs.c_pd.push_prj_to_server(prj_file)
run_rl(path, prj_file, hr, md, sub, w2t) run_rl(path, prj_file, hr, md, sub, w2t)
e_time = time.time()
time_total = e_time - s_time
w2t(f"-" * 90 + "\n", "purple")
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", "green")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
import openpyxl import json
import os.path import os.path
import time import time
import pandas import pandas
import threading import threading
import openpyxl
import re import re
from common import clibs from common import clibs
def check_files(path, rawdata_dirs, result_files, w2t): def check_files(rawdata_dirs, result_files, w2t):
msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:\n" msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:\n"
msg_wrong += "1. reach33_XXXXXXX.xlsx\n2. reach66_XXXXXXX.xlsx\n3. reach100_XXXXXXX.xlsx\n4. *.cfg\n" msg_wrong += "1. reach33_XXXXXXX.xlsx\n2. reach66_XXXXXXX.xlsx\n3. reach100_XXXXXXX.xlsx\n4. *.cfg\n"
msg_wrong += "- reach33_load33_speed33\nreach33_load33_speed66\n......\nreach100_load100_speed66\nreach100_load100_speed100\n" msg_wrong += "- reach33_load33_speed33\nreach33_load33_speed66\n......\nreach100_load100_speed66\nreach100_load100_speed100\n"
@ -33,8 +34,10 @@ def check_files(path, rawdata_dirs, result_files, w2t):
reach_s = ['reach33', 'reach66', 'reach100'] reach_s = ['reach33', 'reach66', 'reach100']
load_s = ['load33', 'load66', 'load100'] load_s = ['load33', 'load66', 'load100']
speed_s = ['speed33', 'speed66', 'speed100'] speed_s = ['speed33', 'speed66', 'speed100']
prefix = []
for rawdata_dir in rawdata_dirs: for rawdata_dir in rawdata_dirs:
components = rawdata_dir.split("/")[-1].split('_') # reach_load_speed components = rawdata_dir.split("/")[-1].split('_') # reach_load_speed
prefix.append(components[0])
if components[0] not in reach_s or components[1] not in load_s or components[2] not in speed_s: if components[0] not in reach_s or components[1] not in load_s or components[2] not in speed_s:
msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式\n" msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式\n"
msg += "命名规则reachAA_loadBB_speedCCAA/BB/CC 指的是臂展/负载/速度的比例\n" msg += "命名规则reachAA_loadBB_speedCCAA/BB/CC 指的是臂展/负载/速度的比例\n"
@ -47,161 +50,139 @@ def check_files(path, rawdata_dirs, result_files, w2t):
w2t(msg, "red", "WrongDataFile") w2t(msg, "red", "WrongDataFile")
for rawdata_file in rawdata_files: for rawdata_file in rawdata_files:
if not rawdata_file.endswith(".data"): if not rawdata_file.endswith(".data"):
msg = f"数据文件 {rawdata_file} 后缀错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件" msg = f"数据文件 {rawdata_file} 后缀错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件\n"
w2t(msg, "red", "WrongDataFile") w2t(msg, "red", "WrongDataFile")
w2t("数据目录合规性检查结束,未发现问题......") result_files = []
for _ in [reach33_file, reach66_file, reach100_file]:
if _.split("/")[-1].split("_")[0] in set(prefix):
result_files.append(_)
w2t("数据目录合规性检查结束,未发现问题......\n")
return config_file, result_files
def get_configs(configfile, w2t): def get_configs(config_file, w2t):
axis = configfile.split('\\')[-2][-1] try:
if axis not in ['1', '2', '3']: with open(config_file, mode="r", encoding="utf-8") as f_config:
w2t("被处理的根文件夹命名必须是 [Jj][123] 的格式", 0, 9, 'red') configs = json.load(f_config)
else: except Exception as Err:
axis = int(axis) clibs.insert_logdb("ERROR", "current", f"get_config: 无法打开 {config_file},获取配置文件参数错误 {Err}")
w2t(f"无法打开 {config_file}", color="red", desc="OpenFileError")
_wb = load_workbook(configfile, read_only=True) p_dir = config_file.split('/')[-2]
_ws = _wb['Target'] if not re.match("^[jJ][123]$", p_dir):
rr = float(_ws.cell(row=2, column=axis + 1).value) w2t("被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
av = float(_ws.cell(row=3, column=axis + 1).value) axis = int(p_dir[-1])
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比rr for reduction ratio
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
rr = rrs[axis-1]
av = avs[axis-1]
return av, rr return av, rr
def now_doing_msg(docs, flag, w2t): def now_doing_msg(docs, flag, w2t):
# 功能:输出正在处理的文件或目录 now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
# 参数文件或目录start 或 done 标识 file_type = 'file' if os.path.isfile(docs) else 'dir'
# 返回值:-
now = strftime('%Y-%m-%d %H:%M:%S', localtime(time()))
file_type = 'file' if isfile(docs) else 'dir'
if flag == 'start' and file_type == 'dir': if flag == 'start' and file_type == 'dir':
w2t(f"[{now}] 正在处理目录 {docs} 中的数据......") w2t(f"[{now}] 正在处理目录 {docs} 中的数据......\n")
elif flag == 'start' and file_type == 'file': elif flag == 'start' and file_type == 'file':
w2t(f"[{now}] 正在处理文件 {docs} 中的数据......") w2t(f"[{now}] 正在处理文件 {docs} 中的数据......\n")
elif flag == 'done' and file_type == 'dir': elif flag == 'done' and file_type == 'dir':
w2t(f"[{now}] 目录 {docs} 数据文件已处理完毕") w2t(f"[{now}] 目录 {docs} 数据文件已处理完毕\n")
elif flag == 'done' and file_type == 'file': elif flag == 'done' and file_type == 'file':
w2t(f"[{now}] 文件 {docs} 数据已处理完毕") w2t(f"[{now}] 文件 {docs} 数据已处理完毕\n")
def w2t_local(msg, wait, w2t): def data2result(df, ws_result, row_start, row_end, vel, trq, estop):
while True:
global stop
if stop == 0 and wait != 0:
sleep(1)
w2t(msg, wait, 0, 'orange')
else:
break
def copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, estop):
# 功能:将数据文件中有效数据拷贝至结果文件对应的 sheet
# 参数:如上
# 返回值:-
# 结果文件数据清零
data = [] data = []
for _row in range(row_start, row_end + 1): for row in range(row_start, row_end):
data.append(df.iloc[_row, vel - 1]) data.append(df.iloc[row, vel - 1])
data.append(df.iloc[_row, trq - 1]) data.append(df.iloc[row, trq - 1])
data.append(df.iloc[_row, estop - 1]) data.append(df.iloc[row, estop - 1])
i = 0 i = 0
row_max = 2000 if row_end - row_start < 2000 else row_end - row_start + 20 row_max = 1000 if row_end - row_start < 1000 else row_end - row_start + 100
for _row in range(2, row_max): for row in range(2, row_max):
try: try:
ws_result.cell(row=_row, column=1).value = data[i] ws_result.cell(row=row, column=1).value = data[i]
ws_result.cell(row=_row, column=2).value = data[i + 1] ws_result.cell(row=row, column=2).value = data[i + 1]
ws_result.cell(row=_row, column=3).value = data[i + 2] ws_result.cell(row=row, column=3).value = data[i + 2]
i += 3 i += 3
except: except Exception:
ws_result.cell(row=_row, column=1).value = None ws_result.cell(row=row, column=1).value = None
ws_result.cell(row=_row, column=2).value = None ws_result.cell(row=row, column=2).value = None
ws_result.cell(row=_row, column=3).value = None ws_result.cell(row=row, column=3).value = None
def find_row_start(data_file, df, conditions, av, rr, vel, estop, w2t): def get_row_range(data_file, df, conditions, av, rr, vel, estop, w2t):
# 功能:查找数据文件中有效数据的行号,也即最后一个速度下降的点位 row_start, row_end = 0, 0
# 参数:如上
# 返回值:速度下降点位,最后的数据点位
ratio = float(conditions[2].removeprefix('speed')) / 100 ratio = float(conditions[2].removeprefix('speed')) / 100
av_max = av * ratio av_max = av * ratio
row_max = df.index[-1]
threshold = 0.95 threshold = 0.95
for _row in range(row_max, -1, -1): for row in range(df.index[-1] - 1, -1, -10):
if df.iloc[_row, estop - 1] != 0: if df.iloc[row, estop - 1] != 0:
row_start = _row - 20 if _row - 20 > 0 else 0 row_start = row - 20 if row - 20 > 0 else 0 # 急停前找 20 个点
break break
else: else:
w2t(f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", 0, 9, 'red') w2t(f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认\n", "red", "StartNotFoundError")
for _row in range(row_start, row_max): for row in range(row_start, df.index[-1] - 1, 10):
speed_row = (df.iloc[_row, vel - 1] * 180) / 3.1415926 * rr * 60 / 360 speed_row = df.iloc[row, vel - 1] * clibs.RADIAN * rr * 60 / 360
if abs(speed_row) < 1: if abs(speed_row) < 1:
row_end = _row + 100 if _row + 100 <= row_max else row_max row_end = row + 100 if row + 100 <= df.index[-1] - 1 else df.index[-1] - 1
break break
else: else:
w2t(f"数据文件 {data_file} 最后的速度未降为零 ", 0, 10, 'red') w2t(f"数据文件 {data_file} 最后的速度未降为零\n", "red", "SpeedNotZeroError")
av_estop = abs((df.iloc[row_start - 10:row_start + 10, vel - 1].abs().mean() * 180) / 3.1415926) av_estop = abs(df.iloc[row_start - 20:row_start, vel - 1].abs().mean() * clibs.RADIAN)
if abs(av_estop / av_max) < threshold: if abs(av_estop / av_max) < threshold:
filename = data_file.split('\\')[-1] filename = data_file.split("/")[-1]
w2t(f"[av_estop: {av_estop:.2f} | shouldbe: {av_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查", 0, 0, '#8A2BE2') w2t(f"[av_estop: {av_estop:.2f} | shouldbe: {av_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查\n", "#8A2BE2")
return row_start, row_end return row_start, row_end
def find_result_sheet_name(conditions, count): def get_shtname(conditions, count):
# 功能获取结果文件准确的sheet页名称 # 33%负载_33%速度_1 - reach/load/speed
# 参数:臂展和速度的列表 load = conditions[1].removeprefix('load')
# 返回值结果文件对应的sheet name
# 33%负载_33%速度_1 - ['loadxx', 'reachxx', 'speedxx']
load = conditions[0].removeprefix('load')
speed = conditions[2].removeprefix('speed') speed = conditions[2].removeprefix('speed')
result_sheet_name = f"{load}%负载_{speed}%速度_{count}" result_sheet_name = f"{load}%负载_{speed}%速度_{count}"
return result_sheet_name return result_sheet_name
def single_file_process(data_file, wb_result, count, av, rr, vel, trq, estop, w2t): def single_file_process(data_file, wb, count, av, rr, vel, trq, estop, w2t):
# 功能:完成单个数据文件的处理 df = pandas.read_csv(data_file, sep='\t')
# 参数:如上 conditions = data_file.split("/")[-2].split("_") # reach/load/speed
# 返回值:- shtname = get_shtname(conditions, count)
df = read_csv(data_file, sep='\t') ws = wb[shtname]
conditions = sorted(data_file.split('\\')[-2].split('_')) # ['loadxx', 'reachxx', 'speedxx'] row_start, row_end = get_row_range(data_file, df, conditions, av, rr, vel, estop, w2t)
result_sheet_name = find_result_sheet_name(conditions, count) data2result(df, ws, row_start, row_end, vel, trq, estop)
ws_result = wb_result[result_sheet_name]
row_start, row_end = find_row_start(data_file, df, conditions, av, rr, vel, estop, w2t)
copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, estop)
def data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t): def data_process(result_file, rawdata_dirs, av, rr, vel, trq, estop, w2t):
# 功能:完成一个结果文件的数据处理 filename = result_file.split("/")[-1]
# 参数:结果文件,数据目录,以及预读取的参数
# 返回值:-
file_name = result_file.split('\\')[-1]
w2t(f"正在打开文件 {file_name} 需要 1min 左右", 1, 0, 'orange')
global stop clibs.stop = True
stop = 0 w2t(f"正在打开文件 {filename} 需要 1min 左右......\n", "blue")
t_excel = clibs.GetThreadResult(load_workbook, args=(result_file,)) t_excel = clibs.GetThreadResult(openpyxl.load_workbook, args=(result_file, ))
t_wait = Thread(target=w2t_local, args=('.', 1, w2t)) t_excel.daemon = True
t_excel.start() t_excel.start()
t_wait.start() t_progress = threading.Thread(target=clibs.tl_prg, args=("Processing......", ))
t_excel.join() t_progress.daemon = True
wb_result = t_excel.get_result() t_progress.start()
stop = 1 wb = t_excel.get_result()
sleep(1.1)
w2t('')
prefix = result_file.split('\\')[-1].split('_')[0] prefix = filename.split('_')[0]
for raw_data_dir in raw_data_dirs: for rawdata_dir in rawdata_dirs:
if raw_data_dir.split('\\')[-1].split('_')[0] == prefix: if rawdata_dir.split("/")[-1].split('_')[0] == prefix:
now_doing_msg(raw_data_dir, 'start', w2t) now_doing_msg(rawdata_dir, 'start', w2t)
_, data_files = clibs.traversal_files(raw_data_dir, w2t) _, data_files = clibs.traversal_files(rawdata_dir, w2t)
# 数据文件串行处理模式--------------------------------- # 数据文件串行处理模式---------------------------------
# count = 1 # count = 1
# for data_file in data_files: # for data_file in data_files:
@ -212,59 +193,41 @@ def data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t):
# --------------------------------------------------- # ---------------------------------------------------
# 数据文件并行处理模式--------------------------------- # 数据文件并行处理模式---------------------------------
threads = [ threads = [
Thread(target=single_file_process, args=(data_files[0], wb_result, 1, av, rr, vel, trq, estop, w2t)), threading.Thread(target=single_file_process, args=(data_files[0], wb, 1, av, rr, vel, trq, estop, w2t)),
Thread(target=single_file_process, args=(data_files[1], wb_result, 2, av, rr, vel, trq, estop, w2t)), threading.Thread(target=single_file_process, args=(data_files[1], wb, 2, av, rr, vel, trq, estop, w2t)),
Thread(target=single_file_process, args=(data_files[2], wb_result, 3, av, rr, vel, trq, estop, w2t)) threading.Thread(target=single_file_process, args=(data_files[2], wb, 3, av, rr, vel, trq, estop, w2t))
] ]
[t.start() for t in threads] [t.start() for t in threads]
[t.join() for t in threads] [t.join() for t in threads]
# --------------------------------------------------- # ---------------------------------------------------
now_doing_msg(raw_data_dir, 'done', w2t) now_doing_msg(rawdata_dir, 'done', w2t)
now_doing_msg(result_file, 'done', w2t) w2t(f"正在保存文件 {filename} 需要 1min 左右......\n\n", "blue")
w2t(f"正在保存文件 {file_name} 需要 1min 左右", 1, 0, 'orange') t_excel = threading.Thread(target=wb.save, args=(result_file, ))
stop = 0 t_excel.daemon = True
t_excel = Thread(target=wb_result.save, args=(result_file,))
t_wait = Thread(target=w2t_local, args=('.', 1, w2t))
t_excel.start() t_excel.start()
t_wait.start()
t_excel.join() t_excel.join()
stop = 1 wb.close()
sleep(1.1) clibs.stop = False
w2t('\n') t_progress.join()
def main(): def main():
# path, vel, trq, estop, w2t time_start = time.time()
path = clibs.data_dp["_path"] path = clibs.data_dp["_path"]
vel = int(clibs.data_dp["_vel"]) vel = int(clibs.data_dp["_vel"])
trq = int(clibs.data_dp["_trq"]) trq = int(clibs.data_dp["_trq"])
estop = int(clibs.data_dp["_estop"]) estop = int(clibs.data_dp["_estop"])
w2t = clibs.w2t w2t = clibs.w2t
insert_logdb = clibs.insert_logdb
time_start = time.time()
rawdata_dirs, result_files = clibs.traversal_files(path, w2t) rawdata_dirs, result_files = clibs.traversal_files(path, w2t)
config_file, result_files = check_files(rawdata_dirs, result_files, w2t)
av, rr = get_configs(config_file, w2t)
# threads = [] for result_file in result_files:
check_files(path, rawdata_dirs, result_files, w2t) data_process(result_file, rawdata_dirs, av, rr, vel, trq, estop, w2t)
# av, rr = get_configs(path + '\\configs.xlsx', w2t)
#
# prefix = []
# for raw_data_dir in rawdata_dirs:
# prefix.append(raw_data_dir.split('\\')[-1].split("_")[0])
#
# for result_file in result_files:
# if result_file.split('\\')[-1].split('_')[0] not in set(prefix):
# continue
# else:
# now_doing_msg(result_file, 'start', w2t)
# data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t)
# # threads.append(Thread(target=data_process, args=(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t)))
# # [t.start() for t in threads]
# # [t.join() for t in threads]
w2t("----------------------------------------------------------\n") w2t("-"*60 + "\n全部处理完毕\n")
w2t("全部处理完毕\n")
time_end = time.time() time_end = time.time()
time_total = time_end - time_start time_total = time_end - time_start
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n" msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n"

View File

@ -4,6 +4,7 @@ import openpyxl
import pandas import pandas
import re import re
import csv import csv
import time
from common import clibs from common import clibs
@ -161,12 +162,10 @@ def current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, ins
t_excel.daemon = True t_excel.daemon = True
t_excel.start() t_excel.start()
t_excel.join() t_excel.join()
wb.close()
clibs.stop = False clibs.stop = False
t_progress.join() t_progress.join()
w2t("----------------------------------------------------------\n")
w2t("全部处理完毕")
def find_point(data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq, w2t, insert_logdb): def find_point(data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq, w2t, insert_logdb):
if flag == "lt": if flag == "lt":
@ -255,7 +254,7 @@ def p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb):
row_e = df.index[-1] row_e = df.index[-1]
row_s = row_e - end_point row_s = row_e - end_point
speed_avg = df.iloc[row_s:row_e].abs().mean() speed_avg = df.iloc[row_s:row_e].abs().mean()
if speed_avg < 2: if speed_avg < threshold:
# 第一次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点 # 第一次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点
row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-1", w2t, insert_logdb) row_s, row_e = find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-1", w2t, insert_logdb)
row_e -= end_point*skip_scale row_e -= end_point*skip_scale
@ -281,7 +280,7 @@ def p_single(wb, single, vel, trq, sensor, rrs, w2t, insert_logdb):
# 正式第三次采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 # 正式第三次采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 3, w2t, insert_logdb) row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 3, w2t, insert_logdb)
row_start = get_row_number(threshold, "start", df, row_s, row_e, axis, insert_logdb) row_start = get_row_number(threshold, "start", df, row_s, row_e, axis, insert_logdb)
elif speed_avg > 2: elif speed_avg > threshold:
# 第一次过滤:消除速度大于零的数据,找到速度即将趋近于零的下降临界点 # 第一次过滤:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-1", w2t, insert_logdb) row_s, row_e = find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-1", w2t, insert_logdb)
row_e -= end_point*skip_scale row_e -= end_point*skip_scale
@ -409,6 +408,7 @@ def get_configs(config_file, w2t, insert_logdb):
def main(): def main():
time_start = time.time()
sub = clibs.data_dp["_sub"] sub = clibs.data_dp["_sub"]
path = clibs.data_dp["_path"] path = clibs.data_dp["_path"]
vel = int(clibs.data_dp["_vel"]) vel = int(clibs.data_dp["_vel"])
@ -429,6 +429,12 @@ def main():
elif sub == "cycle": elif sub == "cycle":
current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, insert_logdb) current_cycle(data_files, vel, trq, trqh, sensor, rrs, rcs, params, w2t, insert_logdb)
w2t("-"*60 + "\n全部处理完毕\n")
time_end = time.time()
time_total = time_end - time_start
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n"
w2t(msg)
if __name__ == '__main__': if __name__ == '__main__':
main() main()