basically done
This commit is contained in:
parent
09d322378a
commit
957071075d
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,3 +2,6 @@ venv/
|
|||||||
.idea/
|
.idea/
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
assets/files/examples/
|
assets/files/examples/
|
||||||
|
assets/logs/*
|
||||||
|
test.py
|
||||||
|
package/*
|
1
assets/files/protocols/ec/motor_off.txt
Normal file
1
assets/files/protocols/ec/motor_off.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
motor_off
|
1
assets/files/protocols/ec/motor_on.txt
Normal file
1
assets/files/protocols/ec/motor_on.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
motor_on
|
1
assets/files/protocols/ec/motor_on_state.txt
Normal file
1
assets/files/protocols/ec/motor_on_state.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
motor_on_state
|
1
assets/files/protocols/ec/operating_mode.txt
Normal file
1
assets/files/protocols/ec/operating_mode.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
operating_mode
|
1
assets/files/protocols/ec/robot_running_state.txt
Normal file
1
assets/files/protocols/ec/robot_running_state.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
robot_running_state
|
1
assets/files/protocols/ec/set_do.txt
Normal file
1
assets/files/protocols/ec/set_do.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
set_do:DO4_0,true
|
1
assets/files/protocols/ec/switch_mode_auto.txt
Normal file
1
assets/files/protocols/ec/switch_mode_auto.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
switch_mode:auto
|
1
assets/files/protocols/ec/switch_mode_manual.txt
Normal file
1
assets/files/protocols/ec/switch_mode_manual.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
switch_mode:manual
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "safety",
|
"module": "safety",
|
||||||
"command": "collision.get_params"
|
"command": "collision.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -2,5 +2,6 @@
|
|||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "safety",
|
"module": "safety",
|
||||||
"command": "collision.set_params",
|
"command": "collision.set_params",
|
||||||
"data": null
|
"data": null,
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -3,5 +3,6 @@
|
|||||||
"command": "collision.set_state",
|
"command": "collision.set_state",
|
||||||
"data": {
|
"data": {
|
||||||
"collision_state": false
|
"collision_state": false
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id":"xxxxxxxxxxx",
|
"id":"xxxxxxxxxxx",
|
||||||
"module":"system",
|
"module":"system",
|
||||||
"command":"controller.get_params"
|
"command":"controller.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "controller.heart"
|
"command": "controller.heart",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "controller.reboot",
|
"command": "controller.reboot",
|
||||||
"data": {
|
"data": {
|
||||||
"arg": 6
|
"arg": 6
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "controller.set_params",
|
"command": "controller.set_params",
|
||||||
"data": {
|
"data": {
|
||||||
"time": "2020-02-28 15:28:30"
|
"time": "2020-02-28 15:28:30"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "device.get_params"
|
"command": "device.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "diagnosis.get_params",
|
"command": "diagnosis.get_params",
|
||||||
"data": {
|
"data": {
|
||||||
"version": "1.4.1"
|
"version": "1.4.1"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -8,5 +8,6 @@
|
|||||||
"overrun": false,
|
"overrun": false,
|
||||||
"turn_area": false,
|
"turn_area": false,
|
||||||
"delay_motion": false
|
"delay_motion": false
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "diagnosis.save",
|
"command": "diagnosis.save",
|
||||||
"data": {
|
"data": {
|
||||||
"save": true
|
"save": true
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -6,5 +6,6 @@
|
|||||||
"display_pdo_params": [],
|
"display_pdo_params": [],
|
||||||
"frequency": 50,
|
"frequency": 50,
|
||||||
"version": "1.4.1"
|
"version": "1.4.1"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "dynamic",
|
"module": "dynamic",
|
||||||
"command": "drag.get_params"
|
"command": "drag.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -6,5 +6,6 @@
|
|||||||
"enable": true,
|
"enable": true,
|
||||||
"space": 0,
|
"space": 0,
|
||||||
"type": 0
|
"type": 0
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "fieldbus",
|
"module": "fieldbus",
|
||||||
"command": "fieldbus_device.get_params"
|
"command": "fieldbus_device.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "fieldbus_device.load_cfg",
|
"command": "fieldbus_device.load_cfg",
|
||||||
"data": {
|
"data": {
|
||||||
"file_name": "fieldbus_device.json"
|
"file_name": "fieldbus_device.json"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -5,5 +5,6 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"device_name": "modbus_1",
|
"device_name": "modbus_1",
|
||||||
"enable": true
|
"enable": true
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "io",
|
"module": "io",
|
||||||
"command": "io_device.load_cfg"
|
"command": "io_device.load_cfg",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "jog.get_params"
|
"command": "jog.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"g": {
|
"id": "xxxxxxxxxxx",
|
||||||
|
"g": {
|
||||||
"log_code.data": "null"
|
"log_code.data": "null"
|
||||||
}
|
},
|
||||||
|
"p_type": 1
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "fieldbus",
|
"module": "fieldbus",
|
||||||
"command": "modbus.get_params"
|
"command": "modbus.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "modbus.get_values",
|
"command": "modbus.get_values",
|
||||||
"data": {
|
"data": {
|
||||||
"mode": "all"
|
"mode": "all"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "modbus.load_cfg",
|
"command": "modbus.load_cfg",
|
||||||
"data": {
|
"data": {
|
||||||
"file" : "registers.json"
|
"file" : "registers.json"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -8,5 +8,6 @@
|
|||||||
"port": 502,
|
"port": 502,
|
||||||
"slave_id": 0,
|
"slave_id": 0,
|
||||||
"enable_master": false
|
"enable_master": false
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "move.get_joint_pos"
|
"command": "move.get_joint_pos",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "move.get_monitor_cfg"
|
"command": "move.get_monitor_cfg",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "move.get_params"
|
"command": "move.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "move.get_pos"
|
"command": "move.get_pos",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "move.get_quickstop_distance"
|
"command": "move.get_quickstop_distance",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id" : "xxxxxxxxx",
|
"id" : "xxxxxxxxx",
|
||||||
"module": "motion",
|
"module": "motion",
|
||||||
"command": "move.get_quickturn_pos"
|
"command": "move.get_quickturn_pos",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "move.quick_turn",
|
"command": "move.quick_turn",
|
||||||
"data": {
|
"data": {
|
||||||
"name":"home"
|
"name":"home"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "move.set_monitor_cfg",
|
"command": "move.set_monitor_cfg",
|
||||||
"data": {
|
"data": {
|
||||||
"ref_coordinate": 1
|
"ref_coordinate": 1
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -12,6 +12,6 @@
|
|||||||
"VEL_SMOOTH_FACTOR": 3.33,
|
"VEL_SMOOTH_FACTOR": 3.33,
|
||||||
"ACC_RAMPTIME_JOG": 0.01
|
"ACC_RAMPTIME_JOG": 0.01
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "move.set_quickstop_distance",
|
"command": "move.set_quickstop_distance",
|
||||||
"data":{
|
"data":{
|
||||||
"distance": 2
|
"distance": 2
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -11,5 +11,6 @@
|
|||||||
"joint_transport": [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,
|
"end_posture": 0,
|
||||||
"home_error_range":[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
|
"home_error_range":[0.0,0.0,0.0,0.0,0.0,0.0,0.0]
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "move.stop",
|
"command": "move.stop",
|
||||||
"data":{
|
"data":{
|
||||||
"stoptype": 0
|
"stoptype": 0
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "project",
|
"module": "project",
|
||||||
"command": "overview.get_autoload"
|
"command": "overview.get_autoload",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "project",
|
"module": "project",
|
||||||
"command": "overview.get_cur_prj"
|
"command": "overview.get_cur_prj",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -5,5 +5,6 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"prj_path": "",
|
"prj_path": "",
|
||||||
"tasks": []
|
"tasks": []
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "overview.set_autoload",
|
"command": "overview.set_autoload",
|
||||||
"data": {
|
"data": {
|
||||||
"autoload_prj_path": ""
|
"autoload_prj_path": ""
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -7,5 +7,6 @@
|
|||||||
"type": "bool",
|
"type": "bool",
|
||||||
"bias": 0,
|
"bias": 0,
|
||||||
"value": 0
|
"value": 0
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "rl_task.pp_to_main",
|
"command": "rl_task.pp_to_main",
|
||||||
"data": {
|
"data": {
|
||||||
"tasks": []
|
"tasks": []
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "rl_task.run",
|
"command": "rl_task.run",
|
||||||
"data": {
|
"data": {
|
||||||
"tasks": []
|
"tasks": []
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -5,5 +5,6 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"loop_mode": true,
|
"loop_mode": true,
|
||||||
"override": 1.0
|
"override": 1.0
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "rl_task.stop",
|
"command": "rl_task.stop",
|
||||||
"data": {
|
"data": {
|
||||||
"tasks": []
|
"tasks": []
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"c": {
|
"id": "xxxxxxxxxxx",
|
||||||
|
"c": {
|
||||||
"safety.safety_area.overall_enable": {
|
"safety.safety_area.overall_enable": {
|
||||||
"enable": true
|
"enable": true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"p_type": 1
|
||||||
}
|
}
|
@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"c": {
|
"id": "xxxxxxxxxxx",
|
||||||
|
"c": {
|
||||||
"safety.safety_area.safety_area_enable": {
|
"safety.safety_area.safety_area_enable": {
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"enable": true
|
"enable": true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"p_type": 1
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"c": {
|
"id": "xxxxxxxxxxx",
|
||||||
|
"c": {
|
||||||
"safety.safety_area.set_param": null
|
"safety.safety_area.set_param": null
|
||||||
}
|
},
|
||||||
|
"p_type": 1
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"c": {
|
"id": "xxxxxxxxxxx",
|
||||||
|
"c": {
|
||||||
"safety.safety_area.signal_enable": {
|
"safety.safety_area.signal_enable": {
|
||||||
"signal": true
|
"signal": true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"p_type": 1
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"g": {
|
"id": "xxxxxxxxxxx",
|
||||||
|
"g": {
|
||||||
"safety_area_data": null
|
"safety_area_data": null
|
||||||
}
|
},
|
||||||
|
"p_type": 1
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "robot",
|
"module": "robot",
|
||||||
"command": "servo.clear_alarm"
|
"command": "servo.clear_alarm",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "network",
|
"module": "network",
|
||||||
"command": "socket.get_params"
|
"command": "socket.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -13,5 +13,6 @@
|
|||||||
"auto_connect": true,
|
"auto_connect": true,
|
||||||
"disconnection_triggering_behavior": 0,
|
"disconnection_triggering_behavior": 0,
|
||||||
"disconnection_detection_time": 10
|
"disconnection_detection_time": 10
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "safety",
|
"module": "safety",
|
||||||
"command": "soft_limit.get_params"
|
"command": "soft_limit.get_params",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -8,5 +8,6 @@
|
|||||||
"lower": [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_upper": [0,0,0,0,0,0,0],
|
||||||
"reduced_lower": [0,0,0,0,0,0,0]
|
"reduced_lower": [0,0,0,0,0,0,0]
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "state.get_state"
|
"command": "state.get_state",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "state.get_tp_mode"
|
"command": "state.get_tp_mode",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -4,5 +4,6 @@
|
|||||||
"command": "state.set_tp_mode",
|
"command": "state.set_tp_mode",
|
||||||
"data": {
|
"data": {
|
||||||
"tp_mode": "with"
|
"tp_mode": "with"
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "state.switch_auto"
|
"command": "state.switch_auto",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "state.switch_manual"
|
"command": "state.switch_manual",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "state.switch_motor_off"
|
"command": "state.switch_motor_off",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "system",
|
"module": "system",
|
||||||
"command": "state.switch_motor_on"
|
"command": "state.switch_motor_on",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "io",
|
"module": "io",
|
||||||
"command": "system_io.query_configuration"
|
"command": "system_io.query_configuration",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "xxxxxxxxxxx",
|
"id": "xxxxxxxxxxx",
|
||||||
"module": "io",
|
"module": "io",
|
||||||
"command": "system_io.query_event_cfg"
|
"command": "system_io.query_event_cfg",
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -5,5 +5,6 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"input_system_io": {},
|
"input_system_io": {},
|
||||||
"output_system_io": {}
|
"output_system_io": {}
|
||||||
}
|
},
|
||||||
|
"p_type": 0
|
||||||
}
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
40002: 0
|
||||||
|
40002: 1
|
||||||
|
40002: 0
|
3
assets/files/protocols/md/ctrl_motor_off.txt
Normal file
3
assets/files/protocols/md/ctrl_motor_off.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
40003: 0
|
||||||
|
40003: 1
|
||||||
|
40003: 0
|
3
assets/files/protocols/md/ctrl_motor_on.txt
Normal file
3
assets/files/protocols/md/ctrl_motor_on.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
40004: 0
|
||||||
|
40004: 1
|
||||||
|
40004: 0
|
1
assets/files/protocols/md/ctrl_soft_estop.txt
Normal file
1
assets/files/protocols/md/ctrl_soft_estop.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
40012: 1
|
1
assets/files/protocols/md/sta_alarm.txt
Normal file
1
assets/files/protocols/md/sta_alarm.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
40500:1:bool
|
1
assets/files/protocols/md/sta_estop.txt
Normal file
1
assets/files/protocols/md/sta_estop.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
40505:1:bool
|
1
assets/files/protocols/md/sta_motor.txt
Normal file
1
assets/files/protocols/md/sta_motor.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
40506:1:bool
|
1
assets/files/protocols/md/sta_soft_estop.txt
Normal file
1
assets/files/protocols/md/sta_soft_estop.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
40518:1:bool
|
1
assets/files/version/server_vers
Normal file
1
assets/files/version/server_vers
Normal file
@ -0,0 +1 @@
|
|||||||
|
0.3.1.7@03/24/2025
|
BIN
assets/media/splash.png
Normal file
BIN
assets/media/splash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
518
code/aio.py
518
code/aio.py
@ -1,518 +0,0 @@
|
|||||||
import json
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
import ui.login_window as login_window
|
|
||||||
import ui.reset_window as reset_window
|
|
||||||
import ui.main_window as main_window
|
|
||||||
from PySide6 import QtWidgets
|
|
||||||
from PySide6.QtCore import Qt, QThread, Signal, QObject
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import pymysql
|
|
||||||
import hashlib
|
|
||||||
import datetime
|
|
||||||
import common.clibs as clibs
|
|
||||||
import common.openapi as openapi
|
|
||||||
from PySide6.QtWidgets import QMessageBox
|
|
||||||
from PySide6.QtGui import QColor, QTextCursor, QTextCharFormat, QDoubleValidator
|
|
||||||
from analysis import brake, current, wavelogger, iso
|
|
||||||
|
|
||||||
|
|
||||||
class MultiWindows:
|
|
||||||
login_window = None
|
|
||||||
reset_window = None
|
|
||||||
main_window = None
|
|
||||||
|
|
||||||
|
|
||||||
class ConnDB(QObject):
|
|
||||||
completed = Signal(tuple)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def do_conn(self, action):
|
|
||||||
conn, cursor = None, None
|
|
||||||
try:
|
|
||||||
conn = pymysql.connect(host='10.2.20.216', user='root', password='Rokae_123457', port=13306, charset='utf8', connect_timeout=clibs.INTERVAL*10)
|
|
||||||
cursor = conn.cursor()
|
|
||||||
except Exception:
|
|
||||||
...
|
|
||||||
finally:
|
|
||||||
self.completed.emit((conn, cursor))
|
|
||||||
|
|
||||||
|
|
||||||
class RunProg(QObject):
|
|
||||||
completed = Signal(tuple)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def program(self, action): # 0: prog 1: idx
|
|
||||||
prog, idx, network = action
|
|
||||||
if idx in range(7):
|
|
||||||
run = prog.processing
|
|
||||||
elif idx == -1:
|
|
||||||
run = prog.net_conn
|
|
||||||
elif idx == -99:
|
|
||||||
run = prog
|
|
||||||
|
|
||||||
try:
|
|
||||||
run()
|
|
||||||
self.completed.emit((True, prog, "", idx, network)) # 运行是否成功/返回值/报错信息/idx
|
|
||||||
except Exception as err:
|
|
||||||
self.completed.emit((False, None, err, idx, network)) # 运行是否成功/返回值/报错信息/idx
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadIt(QObject):
|
|
||||||
completed = Signal(tuple)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def run_program(self, action):
|
|
||||||
try:
|
|
||||||
res = action[0](*action[1])
|
|
||||||
self.completed.emit((True, res, "")) # 运行是否成功/返回值/报错信息
|
|
||||||
except Exception as err:
|
|
||||||
self.completed.emit((False, "", err))
|
|
||||||
|
|
||||||
|
|
||||||
class LoginWindow(login_window.Ui_Form):
|
|
||||||
action = Signal(int)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(LoginWindow, self).__init__()
|
|
||||||
self.setupUi(self)
|
|
||||||
self.le_username.setFocus()
|
|
||||||
self.conn, self.cursor = None, None
|
|
||||||
if not clibs.status["mysql"]:
|
|
||||||
self.setup_DB()
|
|
||||||
|
|
||||||
def get_user_infos(self, results):
|
|
||||||
self.conn, self.cursor = results
|
|
||||||
if self.conn is None and self.cursor is None:
|
|
||||||
QMessageBox.critical(self, "网络错误", "无法连接至服务器数据库,稍后再试......")
|
|
||||||
try:
|
|
||||||
MultiWindows.reset_window.close()
|
|
||||||
except Exception:
|
|
||||||
...
|
|
||||||
finally:
|
|
||||||
self.close()
|
|
||||||
else:
|
|
||||||
self.cursor.execute("SET autocommit = 1;")
|
|
||||||
clibs.status["mysql"] = 1
|
|
||||||
|
|
||||||
def setup_DB(self):
|
|
||||||
self.t = QThread(self)
|
|
||||||
self.conn_db = ConnDB()
|
|
||||||
self.conn_db.moveToThread(self.t)
|
|
||||||
self.conn_db.completed.connect(self.get_user_infos)
|
|
||||||
self.action.connect(self.conn_db.do_conn)
|
|
||||||
self.t.start()
|
|
||||||
self.action.emit(1)
|
|
||||||
|
|
||||||
def user_login(self):
|
|
||||||
username = self.le_username.text()
|
|
||||||
password = self.le_password.text()
|
|
||||||
md = hashlib.md5(password.encode())
|
|
||||||
password = md.hexdigest()
|
|
||||||
|
|
||||||
self.cursor.execute("use user_info;")
|
|
||||||
self.cursor.execute("select * from UserInfo;")
|
|
||||||
user_infos = self.cursor.fetchall()
|
|
||||||
for user_info in user_infos:
|
|
||||||
if user_info[0] == username and user_info[1] == password and user_info[2] == 0:
|
|
||||||
MultiWindows.main_window = MainWindow(self.conn, self.cursor, username)
|
|
||||||
MultiWindows.main_window.show()
|
|
||||||
self.close()
|
|
||||||
else:
|
|
||||||
t = datetime.datetime.now().strftime("%H:%M:%S")
|
|
||||||
self.label_hint.setText(f"[{t}] 用户名或密码错误,或用户已登录......")
|
|
||||||
self.label_hint.setStyleSheet("color: red;")
|
|
||||||
|
|
||||||
def reset_password(self):
|
|
||||||
MultiWindows.reset_window = ResetWindow(self, self.conn, self.cursor)
|
|
||||||
MultiWindows.reset_window.show()
|
|
||||||
self.setVisible(False)
|
|
||||||
|
|
||||||
|
|
||||||
class ResetWindow(reset_window.Ui_Form):
|
|
||||||
def __init__(self, login_window, conn, cursor):
|
|
||||||
super(ResetWindow, self).__init__()
|
|
||||||
self.setupUi(self)
|
|
||||||
self.le_username.setFocus()
|
|
||||||
self.login_window = login_window
|
|
||||||
self.conn = conn
|
|
||||||
self.cursor = cursor
|
|
||||||
|
|
||||||
def reset_password(self):
|
|
||||||
username = self.le_username.text()
|
|
||||||
old_password = self.le_old_password.text()
|
|
||||||
md = hashlib.md5(old_password.encode())
|
|
||||||
password = md.hexdigest()
|
|
||||||
new_password_1 = self.le_new_password_1.text()
|
|
||||||
new_password_2 = self.le_new_password_2.text()
|
|
||||||
|
|
||||||
self.cursor.execute("use user_info;")
|
|
||||||
self.cursor.execute("select * from UserInfo;")
|
|
||||||
user_infos = self.cursor.fetchall()
|
|
||||||
|
|
||||||
for user_info in user_infos:
|
|
||||||
if user_info[0] == username and user_info[1] == password and user_info[2] == 0:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
t = datetime.datetime.now().strftime("%H:%M:%S")
|
|
||||||
self.label_hint.setText(f"[{t}] 用户名或密码错误,或用户已登录......")
|
|
||||||
self.label_hint.setStyleSheet("color: red;")
|
|
||||||
return
|
|
||||||
|
|
||||||
if new_password_1 != new_password_2 or len(new_password_1) < 8:
|
|
||||||
t = datetime.datetime.now().strftime("%H:%M:%S")
|
|
||||||
self.label_hint.setText(f"[{t}] 两次输入的新密码不匹配,或长度小于8位......")
|
|
||||||
self.label_hint.setStyleSheet("color: red;")
|
|
||||||
else:
|
|
||||||
md = hashlib.md5(new_password_1.encode())
|
|
||||||
password = md.hexdigest()
|
|
||||||
self.cursor.execute(f"UPDATE UserInfo SET password = '{password}' WHERE username = '{username}'")
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def reset_cancel(self):
|
|
||||||
self.login_window.setVisible(True)
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def closeEvent(self, event):
|
|
||||||
self.login_window.setVisible(True)
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(main_window.Ui_MainWindow):
|
|
||||||
action = Signal(tuple)
|
|
||||||
|
|
||||||
def __init__(self, conn, cursor, username):
|
|
||||||
super(MainWindow, self).__init__()
|
|
||||||
self.setupUi(self)
|
|
||||||
self.conn = conn
|
|
||||||
self.cursor = cursor
|
|
||||||
self.username = username
|
|
||||||
self.predoes()
|
|
||||||
# self.t = threading.Thread(target=self.state_detection)
|
|
||||||
# self.t.daemon = True
|
|
||||||
# self.t.start()
|
|
||||||
|
|
||||||
def predoes(self):
|
|
||||||
# ========================= db int =========================
|
|
||||||
t = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
||||||
self.cursor.execute(f"UPDATE UserInfo SET online = 1 WHERE username = '{self.username}';")
|
|
||||||
self.cursor.execute(f"CREATE DATABASE IF NOT EXISTS {self.username};")
|
|
||||||
self.cursor.execute(f"use {self.username};")
|
|
||||||
self.cursor.execute(f"CREATE TABLE {t}_log (id INT AUTO_INCREMENT PRIMARY KEY, timestamp TIMESTAMP NOT NULL default CURRENT_TIMESTAMP, level ENUM('DEBUG', 'INFO', 'WARNING', 'ERROR'), module VARCHAR(255) NOT NULL, content TEXT);")
|
|
||||||
self.cursor.execute(f"INSERT INTO {t}_log (module, level, content) VALUES (%s, %s, %s)", ("aio", "info", "testing"))
|
|
||||||
self.cursor.execute("SHOW TABLES;")
|
|
||||||
tables = [x[0] for x in self.cursor.fetchall()]
|
|
||||||
if len(tables) > clibs.MAX_LOG_NUMBER:
|
|
||||||
for table in sorted(tables)[:-10]:
|
|
||||||
self.cursor.execute(f"DROP TABLE {table};")
|
|
||||||
|
|
||||||
# ========================= clibs =========================
|
|
||||||
clibs.cursor = self.cursor
|
|
||||||
clibs.tb_name = f"{t}_log"
|
|
||||||
|
|
||||||
# ========================= clibs =========================
|
|
||||||
# validator = QDoubleValidator(bottom=300, decimals=2)
|
|
||||||
# self.le_durable_interval.setValidator(validator)
|
|
||||||
|
|
||||||
# ========================= styleSheet =========================
|
|
||||||
tws = [self.tw_funcs, self.tw_docs]
|
|
||||||
for tw in tws:
|
|
||||||
tw.setStyleSheet("""
|
|
||||||
QTabBar::tab:selected {
|
|
||||||
background: #0078D4;
|
|
||||||
color: white;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
QTabBar::tab:!selected {
|
|
||||||
background: #F0F0F0;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
QTabWidget::pane {
|
|
||||||
border: 1px solid #CCCCCC;
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
|
|
||||||
# ============================↓↓↓debug↓↓↓============================
|
|
||||||
# print(f"self.cb_data_func.currentIndex() = {self.cb_data_func.currentIndex()}")
|
|
||||||
|
|
||||||
def run_program_thread(self, prog, idx, prog_done, network):
|
|
||||||
self.tw_docs.setCurrentIndex(0)
|
|
||||||
# self.pte_output.clear()
|
|
||||||
if idx != -99:
|
|
||||||
prog.output.connect(self.w2t)
|
|
||||||
self.t = QThread(self)
|
|
||||||
self.run = RunProg()
|
|
||||||
self.run.moveToThread(self.t)
|
|
||||||
self.run.completed.connect(prog_done)
|
|
||||||
self.action.connect(self.run.program)
|
|
||||||
self.t.start()
|
|
||||||
self.action.emit((prog, idx, network))
|
|
||||||
|
|
||||||
def w2t(self, msg, color="black"):
|
|
||||||
self.pte_output.appendHtml(f"<span style='color:{color};'>{msg}</span>")
|
|
||||||
cursor = self.pte_output.textCursor()
|
|
||||||
cursor.movePosition(QTextCursor.End)
|
|
||||||
self.pte_output.setTextCursor(cursor)
|
|
||||||
self.pte_output.ensureCursorVisible()
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def prog_start(self):
|
|
||||||
def prog_done(results):
|
|
||||||
flag, result, error, idx, network = results
|
|
||||||
clibs.running[idx] = 0
|
|
||||||
# if flag is False:
|
|
||||||
# self.w2t(f"{clibs.functions[idx]}运行失败:{error}", "red")
|
|
||||||
# elif flag is True:
|
|
||||||
# ...
|
|
||||||
|
|
||||||
if sum(clibs.running) > 0:
|
|
||||||
if sum(clibs.running) == 1:
|
|
||||||
QMessageBox.critical(self, "运行中", f"{clibs.functions[clibs.running.index(1)]}正在执行中,不可同时运行两个处理/测试程序!")
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.w2t(f"clibs.running = {clibs.running}", "red")
|
|
||||||
self.w2t(f"clibs.functions = {clibs.functions}", "red")
|
|
||||||
QMessageBox.critical(self, "严重错误", "理论上不允许同时运行两个处理程序,需要检查!")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.tw_funcs.currentIndex() == 0 and self.cb_data_func.currentIndex() == 0:
|
|
||||||
self.run_program_thread(brake.BrakeDataProcess(self.le_data_path.text()), 0, prog_done, None)
|
|
||||||
elif self.tw_funcs.currentIndex() == 0 and self.cb_data_func.currentIndex() == 1:
|
|
||||||
self.run_program_thread(current.CurrentDataProcess(self.le_data_path.text(), self.cb_data_current.currentText()), 1, prog_done, None)
|
|
||||||
elif self.tw_funcs.currentIndex() == 0 and self.cb_data_func.currentIndex() == 2:
|
|
||||||
self.run_program_thread(iso.IsoDataProcess(self.le_data_path.text()), 2, prog_done, None)
|
|
||||||
elif self.tw_funcs.currentIndex() == 0 and self.cb_data_func.currentIndex() == 3:
|
|
||||||
self.run_program_thread(wavelogger.WaveloggerDataProcess(self.le_data_path.text()), 3, prog_done, None)
|
|
||||||
elif self.tw_funcs.currentIndex() == 1 and self.cb_unit_func.currentIndex() == 0:
|
|
||||||
self.w2t(f"{clibs.functions[4]}功能待开发.....", "red")
|
|
||||||
elif self.tw_funcs.currentIndex() == 1 and self.cb_unit_func.currentIndex() == 1:
|
|
||||||
self.w2t(f"{clibs.functions[5]}功能待开发.....", "red")
|
|
||||||
elif self.tw_funcs.currentIndex() == 2:
|
|
||||||
self.w2t(f"{clibs.functions[6]}功能待开发.....", "red")
|
|
||||||
|
|
||||||
def prog_stop(self):
|
|
||||||
QMessageBox.warning(self, "停止运行", "运行过程中不建议停止运行,可能会损坏文件,如果确实需要停止运行,可以直接关闭窗口!")
|
|
||||||
|
|
||||||
def prog_reset(self):
|
|
||||||
self.pte_output.clear()
|
|
||||||
|
|
||||||
def file_browser(self):
|
|
||||||
idx_dict = {0: self.le_data_path, 1: self.le_unit_path, 2: self.le_durable_path}
|
|
||||||
dir_path = QtWidgets.QFileDialog.getExistingDirectory()
|
|
||||||
tab_index = self.tw_funcs.currentIndex()
|
|
||||||
if dir_path:
|
|
||||||
idx_dict[tab_index].setText(dir_path)
|
|
||||||
|
|
||||||
def curve_draw(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def durable_cb_change(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def pre_page(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def realtime_page(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def next_page(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def load_sql(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def search_keyword(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def prog_done_conn(self, results):
|
|
||||||
flag, result, error, idx, network = results
|
|
||||||
if flag is False:
|
|
||||||
self.w2t(f"{network.upper()}连接失败", "red")
|
|
||||||
elif flag is True:
|
|
||||||
clibs.status[network] = 1
|
|
||||||
if network == "hmi":
|
|
||||||
self.btn_hmi_conn.setText("断开")
|
|
||||||
clibs.c_hr = result
|
|
||||||
elif network == "md":
|
|
||||||
self.btn_md_conn.setText("断开")
|
|
||||||
clibs.c_md = result
|
|
||||||
elif network == "ec":
|
|
||||||
self.btn_ec_conn.setText("断开")
|
|
||||||
clibs.c_ec = result
|
|
||||||
|
|
||||||
def prog_done_disconn(self, results):
|
|
||||||
flag, result, error, idx, network = results
|
|
||||||
if flag is False:
|
|
||||||
self.w2t(f"{network.upper()}断开连接失败", "red")
|
|
||||||
elif flag is True:
|
|
||||||
clibs.status[network] = 0
|
|
||||||
if network == "hmi":
|
|
||||||
self.btn_hmi_conn.setText("连接")
|
|
||||||
clibs.c_hr = result
|
|
||||||
elif network == "md":
|
|
||||||
self.btn_md_conn.setText("连接")
|
|
||||||
clibs.c_md = result
|
|
||||||
elif network == "ec":
|
|
||||||
self.btn_ec_conn.setText("连接")
|
|
||||||
clibs.c_ec = result
|
|
||||||
|
|
||||||
def hmi_conn(self):
|
|
||||||
if self.btn_hmi_conn.text() == "连接":
|
|
||||||
clibs.ip_addr = self.le_hmi_ip.text().strip()
|
|
||||||
ip_pattern = re.compile(r"(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])")
|
|
||||||
if not ip_pattern.fullmatch(clibs.ip_addr):
|
|
||||||
self.w2t(f"{clibs.ip_addr} 不是一个有效的 IP 地址", "red")
|
|
||||||
return
|
|
||||||
self.run_program_thread(openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port), -1, self.prog_done_conn, "hmi")
|
|
||||||
elif self.btn_hmi_conn.text() == "断开":
|
|
||||||
self.run_program_thread(clibs.c_hr.close, -99, self.prog_done_disconn, "hmi")
|
|
||||||
|
|
||||||
def md_conn(self):
|
|
||||||
if clibs.status["hmi"] == 0:
|
|
||||||
QMessageBox.warning(self, "告警", "打开Modbus连接之前,需要先打开HMI连接!")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.btn_md_conn.text() == "连接":
|
|
||||||
clibs.modbus_port = self.le_md_port.text().strip()
|
|
||||||
self.run_program_thread(openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port), -1, self.prog_done_conn, "md")
|
|
||||||
elif self.btn_md_conn.text() == "断开":
|
|
||||||
self.run_program_thread(clibs.c_md.close, -99, self.prog_done_disconn, "md")
|
|
||||||
|
|
||||||
def ec_conn(self):
|
|
||||||
if clibs.status["hmi"] == 0:
|
|
||||||
QMessageBox.warning(self, "告警", "打开外部通信连接之前,需要先打开HMI连接!")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.btn_ec_conn.text() == "连接":
|
|
||||||
clibs.external_port = self.le_ec_port.text().strip()
|
|
||||||
self.run_program_thread(openapi.ExternalCommunication(clibs.ip_addr, clibs.external_port), -1, self.prog_done_conn, "ec")
|
|
||||||
elif self.btn_ec_conn.text() == "断开":
|
|
||||||
self.run_program_thread(clibs.c_ec.close, -99, self.prog_done_disconn, "ec")
|
|
||||||
|
|
||||||
def hmi_page(self):
|
|
||||||
self.sw_network.setCurrentIndex(0)
|
|
||||||
|
|
||||||
def md_page(self):
|
|
||||||
self.sw_network.setCurrentIndex(1)
|
|
||||||
|
|
||||||
def ec_page(self):
|
|
||||||
self.sw_network.setCurrentIndex(2)
|
|
||||||
|
|
||||||
def hmi_send(self):
|
|
||||||
def prog_done(results):
|
|
||||||
...
|
|
||||||
|
|
||||||
def hmi_send_thread():
|
|
||||||
if clibs.status["hmi"] == 0:
|
|
||||||
QMessageBox.critical(self, "错误", "使用该功能之前,需要先打开HMI连接!")
|
|
||||||
return
|
|
||||||
|
|
||||||
cmd = self.pte_hmi_send.toPlainText()
|
|
||||||
req = json.dumps(json.loads(cmd), separators=(",", ":"))
|
|
||||||
print(f"type of cmd = {type(cmd)}")
|
|
||||||
print(f"type of req = {type(req)}")
|
|
||||||
if "id" in req: # 老协议
|
|
||||||
print(f"wrong req = {req}")
|
|
||||||
msg_id = json.loads(req)["id"]
|
|
||||||
clibs.c_hr.c.send(clibs.c_hr.package(req))
|
|
||||||
print(f"msg_id ={msg_id}")
|
|
||||||
clibs.logger("INFO", "aio", f"hmi: [send] 老协议请求发送成功 {req}")
|
|
||||||
records = clibs.c_hr.get_from_id(msg_id, "done")
|
|
||||||
print(f"req = {req}")
|
|
||||||
print(f"records = {records}")
|
|
||||||
self.pte_him_recv.clear()
|
|
||||||
self.pte_him_recv.appendPlainText(records)
|
|
||||||
else: # 新协议
|
|
||||||
clibs.c_hr.c_xs.send(clibs.c_hr.package_xs(json.loads(cmd)))
|
|
||||||
data = ""
|
|
||||||
time.sleep(clibs.INTERVAL/5)
|
|
||||||
_ = clibs.c_hr.c_xs.recv(1024)
|
|
||||||
while len(_) == 1024:
|
|
||||||
data += _
|
|
||||||
_ = clibs.c_hr.c_xs.recv(1024)
|
|
||||||
|
|
||||||
print(f"data = {data}")
|
|
||||||
self.pte_him_recv.clear()
|
|
||||||
self.pte_him_recv.appendPlainText(data.decode())
|
|
||||||
self.run_program_thread(hmi_send_thread, -99, prog_done, None)
|
|
||||||
|
|
||||||
def md_send(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def ec_send(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def hmi_cb_change(self):
|
|
||||||
cmd = self.cb_hmi_cmd.currentText()
|
|
||||||
self.pte_hmi_send.clear()
|
|
||||||
self.pte_him_recv.clear()
|
|
||||||
with open(f"{clibs.PREFIX}/files/protocols/hmi/{cmd}.json", mode="r", encoding="utf-8") as f_hmi:
|
|
||||||
t = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
|
|
||||||
hmi_dict = json.load(f_hmi)
|
|
||||||
if "id" in hmi_dict.keys():
|
|
||||||
hmi_dict["id"] = f"{cmd}-{t}"
|
|
||||||
|
|
||||||
self.pte_hmi_send.appendPlainText(json.dumps(hmi_dict, indent=2, separators=(",", ":")))
|
|
||||||
|
|
||||||
def md_cb_change(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def ec_cb_change(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def check_interval(self):
|
|
||||||
try:
|
|
||||||
interval = float(self.le_durable_interval.text())
|
|
||||||
interval = 300 if interval < 300 else int(interval)
|
|
||||||
except Exception:
|
|
||||||
interval = 300
|
|
||||||
self.le_durable_interval.setText(str(interval))
|
|
||||||
|
|
||||||
def state_detection(self):
|
|
||||||
while True:
|
|
||||||
time.sleep(clibs.INTERVAL)
|
|
||||||
if clibs.status["hmi"] == 0 and self.btn_hmi_conn.text() == "断开":
|
|
||||||
self.btn_hmi_conn.setText("连接")
|
|
||||||
elif clibs.status["hmi"] == 1 and self.btn_hmi_conn.text() == "连接":
|
|
||||||
self.btn_hmi_conn.setText("断开")
|
|
||||||
|
|
||||||
def closeEvent(self, event):
|
|
||||||
idx = -1 if clibs.running.count(1) == 0 else clibs.running.index(1)
|
|
||||||
info_text = "当前无程序正在运行,可放心退出!" if idx == -1 else f"当前正在运行{clibs.functions[idx]},确认退出?"
|
|
||||||
reply = QMessageBox.question(self, "退出", info_text)
|
|
||||||
if reply == QMessageBox.Yes:
|
|
||||||
try:
|
|
||||||
self.cursor.execute(f"use user_info;")
|
|
||||||
self.cursor.execute(f"UPDATE UserInfo SET online = 0 WHERE username = '{self.username}'")
|
|
||||||
self.cursor.close()
|
|
||||||
self.conn.close()
|
|
||||||
finally:
|
|
||||||
clibs.lock.release()
|
|
||||||
|
|
||||||
if clibs.status["md"] == 1:
|
|
||||||
self.run_program_thread(clibs.c_md.close, -99, self.prog_done_disconn, "md")
|
|
||||||
if clibs.status["ec"] == 1:
|
|
||||||
self.run_program_thread(clibs.c_ec.close, -99, self.prog_done_disconn, "ec")
|
|
||||||
if clibs.status["hmi"] == 1:
|
|
||||||
self.run_program_thread(clibs.c_hr.close, -99, self.prog_done_disconn, "hmi")
|
|
||||||
|
|
||||||
self.close()
|
|
||||||
event.accept()
|
|
||||||
else:
|
|
||||||
event.ignore()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
window = LoginWindow()
|
|
||||||
window.show()
|
|
||||||
sys.exit(app.exec())
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
import os
|
|
||||||
import os.path
|
|
||||||
import threading
|
|
||||||
|
|
||||||
|
|
||||||
def traversal_files(dir_path, signal):
|
|
||||||
# 功能:以列表的形式分别返回指定路径下的文件和文件夹,不包含子目录
|
|
||||||
# 参数:路径/信号/游标/功能编号
|
|
||||||
# 返回值:路径下的文件夹列表 路径下的文件列表
|
|
||||||
global cursor, tb_name
|
|
||||||
|
|
||||||
if not os.path.exists(dir_path):
|
|
||||||
logger("ERROR", "clibs", f"数据文件夹{dir_path}不存在,请确认后重试......", "red", signal=signal)
|
|
||||||
else:
|
|
||||||
dirs, files = [], []
|
|
||||||
for item in os.scandir(dir_path):
|
|
||||||
if item.is_dir():
|
|
||||||
dirs.append(item.path.replace("\\", "/"))
|
|
||||||
elif item.is_file():
|
|
||||||
files.append(item.path.replace("\\", "/"))
|
|
||||||
|
|
||||||
return dirs, files
|
|
||||||
|
|
||||||
|
|
||||||
def db_lock(func):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
try:
|
|
||||||
lock.acquire(True)
|
|
||||||
ret = func(*args, **kwargs)
|
|
||||||
finally:
|
|
||||||
lock.release()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
@db_lock
|
|
||||||
def logger(level, module, content, color="black", flag="both", signal=""):
|
|
||||||
global cursor, tb_name
|
|
||||||
if flag == "signal":
|
|
||||||
signal.emit(content, color)
|
|
||||||
elif flag == "cursor":
|
|
||||||
cursor.execute(f"INSERT INTO {tb_name} (level, module, content) VALUES (%s, %s, %s)", (level, module, content))
|
|
||||||
elif flag == "both":
|
|
||||||
signal.emit(content, color)
|
|
||||||
cursor.execute(f"INSERT INTO {tb_name} (level, module, content) VALUES (%s, %s, %s)", (level, module, content))
|
|
||||||
|
|
||||||
|
|
||||||
# PREFIX = "assets" # for pyinstaller packaging
|
|
||||||
PREFIX = "../assets" # for source code testing and debug
|
|
||||||
lock = threading.Lock()
|
|
||||||
|
|
||||||
running = [0, 0, 0, 0, 0, 0, 0] # 制动数据/转矩数据/激光数据/精度数据/制动自动化/转矩自动化/耐久数据采集
|
|
||||||
functions = ["制动数据处理", "转矩数据处理", "激光数据处理", "精度数据处理", "制动自动化测试", "转矩自动化测试", "耐久数据采集"]
|
|
||||||
|
|
||||||
log_name = ""
|
|
||||||
ip_addr, ssh_port, socket_port, xService_port, external_port, modbus_port, upgrade_port = "", 22, 5050, 6666, 8080, 502, 4567
|
|
||||||
username, password = "luoshi", "123456"
|
|
||||||
INTERVAL, RADIAN, MAX_FRAME_SIZE, MAX_LOG_NUMBER = 0.5, 57.3, 1024, 10
|
|
||||||
c_md, c_hr, c_ec, c_pd, cursor, tb_name = None, None, None, None, None, ""
|
|
||||||
status = {"mysql": 0, "hmi": 0, "md": 0, "ec": 0}
|
|
||||||
c_joint_vel, c_servo_trq, c_sensor_trq, c_estimate_trans_trq, c_safety_estop = 1, 2, 3, 4, 3 # 各个指标所在列
|
|
@ -1,85 +0,0 @@
|
|||||||
import os.path
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import pandas
|
|
||||||
from matplotlib.widgets import Slider
|
|
||||||
from PySide6.QtCore import Signal, QThread
|
|
||||||
from common import clibs
|
|
||||||
|
|
||||||
|
|
||||||
# class DrawCurves(QThread):
|
|
||||||
# output = Signal(str, str)
|
|
||||||
#
|
|
||||||
# def __init__(self, /):
|
|
||||||
# super().__init__()
|
|
||||||
#
|
|
||||||
# @staticmethod
|
|
||||||
# def logger(level, module, content, color="black", error="", flag="both", signal=output):
|
|
||||||
# clibs.logger(level, module, content, color, flag, signal)
|
|
||||||
# if level.upper() == "ERROR":
|
|
||||||
# raise Exception(error)
|
|
||||||
#
|
|
||||||
# def initialization(self):
|
|
||||||
# path, curves = None, None
|
|
||||||
# try:
|
|
||||||
# path = clibs.data_dd["path"]
|
|
||||||
# curves = clibs.data_dd["curves"]
|
|
||||||
# except Exception:
|
|
||||||
# clibs.w2t("程序未开始运行,暂无数据可以展示......\n", "red")
|
|
||||||
# return None, None
|
|
||||||
#
|
|
||||||
# for curve in curves:
|
|
||||||
# if not os.path.exists(f"{path}/{curve}.csv"):
|
|
||||||
# clibs.w2t(f"{curve}曲线数据暂未生成,稍后再试......\n", "orange")
|
|
||||||
# return None, None
|
|
||||||
#
|
|
||||||
# return path, curves
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def data_plot(path, curve):
|
|
||||||
# titles = {"hw_joint_vel_feedback": "各关节最大速度曲线", "device_servo_trq_feedback": "各关节平均有效转矩曲线"}
|
|
||||||
# ylabels = {"hw_joint_vel_feedback": "速度(rad/s)", "device_servo_trq_feedback": "转矩(Nm)"}
|
|
||||||
#
|
|
||||||
# fig, axes = plt.subplots(figsize=(10, 4.5), dpi=100)
|
|
||||||
# cols = [f"{curve}_{i}" for i in range(6)]
|
|
||||||
# cols.insert(0, "time")
|
|
||||||
# df = pandas.read_csv(f"{path}/{curve}.csv")
|
|
||||||
# plt.plot(df[cols[1]], label="一轴")
|
|
||||||
# plt.plot(df[cols[2]], label="二轴")
|
|
||||||
# plt.plot(df[cols[3]], label="三轴")
|
|
||||||
# plt.plot(df[cols[4]], label="四轴")
|
|
||||||
# plt.plot(df[cols[5]], label="五轴")
|
|
||||||
# plt.plot(df[cols[6]], label="六轴")
|
|
||||||
# axes.set_title(titles[curve])
|
|
||||||
# axes.set_ylabel(ylabels[curve])
|
|
||||||
# axes.legend(loc="upper right")
|
|
||||||
#
|
|
||||||
# slider_position = plt.axes((0.1, 0.01, 0.8, 0.05), facecolor="blue") # (left, bottom, width, height)
|
|
||||||
# scrollbar = Slider(slider_position, 'Time', 1, int(len(df)), valstep=1)
|
|
||||||
#
|
|
||||||
# def update(val):
|
|
||||||
# pos = scrollbar.val
|
|
||||||
# axes.set_xlim([pos, pos + 10])
|
|
||||||
# fig.canvas.draw_idle()
|
|
||||||
#
|
|
||||||
# scrollbar.on_changed(update)
|
|
||||||
# fig.tight_layout(rect=(0, 0.02, 0.96, 1)) # tuple (left, bottom, right, top)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def main():
|
|
||||||
# path, curves = initialization()
|
|
||||||
# if not path or not curves:
|
|
||||||
# return
|
|
||||||
#
|
|
||||||
# for curve in curves:
|
|
||||||
# data_plot(path, curve)
|
|
||||||
#
|
|
||||||
# plt.show()
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# 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'
|
|
||||||
# plt.rcParams["figure.autolayout"] = True
|
|
||||||
#
|
|
@ -1,239 +0,0 @@
|
|||||||
import json
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
import pandas
|
|
||||||
import numpy
|
|
||||||
import math
|
|
||||||
import csv
|
|
||||||
from PySide6.QtCore import Signal, QThread
|
|
||||||
from common import clibs
|
|
||||||
|
|
||||||
|
|
||||||
class DoBrakeTest(QThread):
|
|
||||||
output = Signal(str, str)
|
|
||||||
|
|
||||||
def __init__(self, dir_path, interval, proc, /):
|
|
||||||
super().__init__()
|
|
||||||
self.dir_path = dir_path
|
|
||||||
self.interval = interval
|
|
||||||
self.proc = proc
|
|
||||||
self.idx = 6
|
|
||||||
|
|
||||||
def logger(self, level, module, content, color="black", error="", flag="both"):
|
|
||||||
clibs.logger(level, module, content, color, flag, signal=self.output)
|
|
||||||
if level.upper() == "ERROR":
|
|
||||||
raise Exception(f"{error} | {content}")
|
|
||||||
|
|
||||||
def initialization(self, data_dirs, data_files):
|
|
||||||
def check_files():
|
|
||||||
if len(curves) == 0:
|
|
||||||
self.logger("ERROR", "factory-check_files", "未查询到需要记录数据的曲线,至少选择一个!", "red", "CurveNameError")
|
|
||||||
|
|
||||||
if len(data_dirs) != 0 or len(data_files) != 1:
|
|
||||||
self.logger("ERROR", "factory-check_files", "初始路径下不允许有文件夹,且初始路径下只能存在一个工程文件 —— *.zip,确认后重新运行!", "red", "InitFileError")
|
|
||||||
|
|
||||||
if not data_files[0].endswith(".zip"):
|
|
||||||
self.logger("ERROR", "factory-check_files", f"{data_files[0]} 不是一个有效的工程文件,需确认!", "red", "ProjectFileError")
|
|
||||||
|
|
||||||
return data_files[0], interval
|
|
||||||
|
|
||||||
def get_configs():
|
|
||||||
robot_type, records = None, None
|
|
||||||
msg_id, state = clibs.c_hr.execution("controller.get_params")
|
|
||||||
records = clibs.c_hr.get_from_id(msg_id, state)
|
|
||||||
for record in records:
|
|
||||||
if "请求发送成功" not in record[0]:
|
|
||||||
robot_type = eval(record[0])["data"]["robot_type"]
|
|
||||||
server_file = f"/home/luoshi/bin/controller/robot_cfg/{robot_type}/{robot_type}.cfg"
|
|
||||||
local_file = self.dir_path + f"/{robot_type}.cfg"
|
|
||||||
clibs.c_pd.pull_file_from_server(server_file, local_file)
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(local_file, mode="r", encoding="utf-8") as f_config:
|
|
||||||
configs = json.load(f_config)
|
|
||||||
except Exception as Err:
|
|
||||||
self.logger("ERROR", "factory-get_configs", f"无法打开 {local_file}<br>{Err}", "red", "OpenFileError")
|
|
||||||
|
|
||||||
# 最大角速度,额定电流,减速比,额定转速
|
|
||||||
version = configs["VERSION"]
|
|
||||||
m_avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
|
||||||
m_rts = configs["MOTOR"]["RATED_TORQUE"] # 电机额定转矩rt for rated torque
|
|
||||||
m_tcs = [1, 1, 1, 1, 1, 1] # 电机转矩常数,tc for torque constant
|
|
||||||
m_rcs = []
|
|
||||||
for i in range(len(m_tcs)):
|
|
||||||
m_rcs.append(m_rts[i] / m_tcs[i]) # 电机额定电流,rc for rated current
|
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 机型文件版本 {robot_type}_{version}")
|
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {m_avs}")
|
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节额定电流 {m_rcs}")
|
|
||||||
return m_avs, m_rcs
|
|
||||||
|
|
||||||
prj_file, interval = check_files()
|
|
||||||
avs, rcs = get_configs()
|
|
||||||
params = {
|
|
||||||
"prj_file": prj_file,
|
|
||||||
"interval": interval,
|
|
||||||
"avs": avs,
|
|
||||||
"rcs": rcs,
|
|
||||||
}
|
|
||||||
self.logger("INFO", "factory-initialization", "数据目录合规性检查结束,未发现问题......", "green")
|
|
||||||
return params
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def change_curve_state(curves, stat):
|
|
||||||
display_pdo_params = [{"name": name, "channel": chl} for name in curves for chl in range(6)]
|
|
||||||
clibs.c_hr.execution("diagnosis.open", open=stat, display_open=stat, overrun=True, turn_area=True, delay_motion=False)
|
|
||||||
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
|
||||||
|
|
||||||
def run_rl(self, params, curves):
|
|
||||||
prj_file, interval = params["prj_file"], params["interval"]
|
|
||||||
# 1. 关闭诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
|
|
||||||
self.change_curve_state(curves, False)
|
|
||||||
clibs.c_md.r_soft_estop(0)
|
|
||||||
clibs.c_md.r_soft_estop(1)
|
|
||||||
clibs.c_md.r_clear_alarm()
|
|
||||||
clibs.c_md.write_act(False)
|
|
||||||
time.sleep(1) # 让曲线彻底关闭
|
|
||||||
|
|
||||||
# 2. reload工程后,pp2main,并且自动模式和上电
|
|
||||||
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
|
|
||||||
prj_path = f"{prj_name}/_build/{prj_name}.prj"
|
|
||||||
clibs.c_hr.execution("overview.reload", prj_path=prj_path, tasks=["factory"])
|
|
||||||
clibs.c_hr.execution("rl_task.pp_to_main", tasks=["factory"])
|
|
||||||
clibs.c_hr.execution("state.switch_auto")
|
|
||||||
clibs.c_hr.execution("state.switch_motor_on")
|
|
||||||
|
|
||||||
# 3. 开始运行程序
|
|
||||||
clibs.c_hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
|
|
||||||
clibs.c_hr.execution("rl_task.run", tasks=["factory"])
|
|
||||||
t_start = time.time()
|
|
||||||
while True:
|
|
||||||
if clibs.c_md.read_ready_to_go() == 1:
|
|
||||||
clibs.c_md.write_act(True)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if (time.time() - t_start) > 15:
|
|
||||||
self.logger("ERROR", "factory-run_rl", "15s 内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
|
||||||
else:
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# 4. 获取初始数据,周期时间,首次的各轴平均电流值,打开诊断曲线,并执行采集
|
|
||||||
time.sleep(10) # 等待 RL 程序中 scenario_time 初始化
|
|
||||||
t_start = time.time()
|
|
||||||
while True:
|
|
||||||
scenario_time = float(f"{float(clibs.c_md.read_scenario_time()):.2f}")
|
|
||||||
if scenario_time != 0:
|
|
||||||
self.logger("INFO", "factory-run_rl", f"耐久工程的周期时间:{scenario_time}s | 单轮次执行时间:{scenario_time+interval}~{scenario_time*2+interval}")
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
time.sleep(1)
|
|
||||||
if (time.time() - t_start) > 900:
|
|
||||||
self.logger("ERROR", "factory-run_rl", f"900s 内未收到耐久工程的周期时间,需要确认RL程序和工具通信交互是否正常执行...", "red", "GetScenarioTimeError")
|
|
||||||
|
|
||||||
# 6. 准备数据保存文件
|
|
||||||
for curve in curves:
|
|
||||||
with open(f"{self.dir_path}/{curve}.csv", mode="a+", newline="") as f_csv:
|
|
||||||
titles = [f"{curve}_{i}" for i in range(6)]
|
|
||||||
titles.insert(0, "time")
|
|
||||||
csv_writer = csv.writer(f_csv)
|
|
||||||
csv_writer.writerow(titles)
|
|
||||||
|
|
||||||
# 7. 开始采集
|
|
||||||
count = 0
|
|
||||||
while clibs.running:
|
|
||||||
this_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
|
||||||
next_time_1 = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()+scenario_time+interval+1))
|
|
||||||
next_time_2 = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()+scenario_time+interval+1+scenario_time))
|
|
||||||
self.logger("INFO", "factory-run_rl", f"[{this_time}] 当前次数:{count:09d} | 预计下次数据更新时间:{next_time_1}~{next_time_2}", "#008B8B")
|
|
||||||
count += 1
|
|
||||||
# 固定间隔,更新一次数据,打开曲线,获取周期内电流,关闭曲线
|
|
||||||
time.sleep(interval)
|
|
||||||
while True:
|
|
||||||
capture_start = clibs.c_md.read_capture_start()
|
|
||||||
if capture_start == 1:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
self.change_curve_state(curves, True)
|
|
||||||
time.sleep(scenario_time)
|
|
||||||
end_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()-scenario_time))
|
|
||||||
self.change_curve_state(curves, False)
|
|
||||||
# 保留数据并处理输出
|
|
||||||
self.gen_results(params, curves, start_time, end_time)
|
|
||||||
else:
|
|
||||||
self.change_curve_state(curves, False)
|
|
||||||
self.logger("INFO", "factory", "后台数据清零完成,现在可以重新运行其他程序。", "green")
|
|
||||||
|
|
||||||
def gen_results(self, params, curves, start_time, end_time):
|
|
||||||
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()
|
|
||||||
self.data_proc(records, params, curves)
|
|
||||||
|
|
||||||
def data_proc(self, records, params, curves):
|
|
||||||
for curve in curves:
|
|
||||||
if curve == "device_servo_trq_feedback":
|
|
||||||
# proc_device_servo_trq_feedback(records, params, w2t)
|
|
||||||
t = threading.Thread(target=self.proc_device_servo_trq_feedback, args=(records, params))
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
elif curve == "hw_joint_vel_feedback":
|
|
||||||
# proc_hw_joint_vel_feedback(records, params, w2t)
|
|
||||||
t = threading.Thread(target=self.proc_hw_joint_vel_feedback, args=(records, params))
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
def proc_device_servo_trq_feedback(self, records, params):
|
|
||||||
d_trq, rcs, results = [[], [], [], [], [], []], params["rcs"], [time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))]
|
|
||||||
for record in records:
|
|
||||||
data = eval(record[0])["data"]
|
|
||||||
for item in data:
|
|
||||||
d_item = reversed(item["value"])
|
|
||||||
for axis in range(6):
|
|
||||||
if item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
|
|
||||||
d_trq[axis].extend(d_item)
|
|
||||||
|
|
||||||
for axis in range(6):
|
|
||||||
df = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq[axis]})
|
|
||||||
_ = math.sqrt(numpy.square(df[df.columns[0]].values * 1.27 / 1000).sum() / len(df))
|
|
||||||
results.append(_)
|
|
||||||
|
|
||||||
path = "/".join(params["prj_file"].split("/")[:-1])
|
|
||||||
with open(f"{path}/device_servo_trq_feedback.csv", mode="a+", newline="") as f_csv:
|
|
||||||
csv_writer = csv.writer(f_csv)
|
|
||||||
csv_writer.writerow(results)
|
|
||||||
|
|
||||||
def proc_hw_joint_vel_feedback(self, records, params):
|
|
||||||
d_trq, rcs, results = [[], [], [], [], [], []], params["rcs"], [time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))]
|
|
||||||
for record in records:
|
|
||||||
data = eval(record[0])["data"]
|
|
||||||
for item in data:
|
|
||||||
d_item = reversed(item["value"])
|
|
||||||
for axis in range(6):
|
|
||||||
if item.get("channel", None) == axis and item.get("name", None) == "hw_joint_vel_feedback":
|
|
||||||
d_trq[axis].extend(d_item)
|
|
||||||
|
|
||||||
for axis in range(6):
|
|
||||||
df = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_trq[axis]})
|
|
||||||
_ = df.max().iloc[0]
|
|
||||||
results.append(_)
|
|
||||||
|
|
||||||
path = "/".join(params["prj_file"].split("/")[:-1])
|
|
||||||
with open(f"{path}/hw_joint_vel_feedback.csv", mode="a+", newline="") as f_csv:
|
|
||||||
csv_writer = csv.writer(f_csv)
|
|
||||||
csv_writer.writerow(results)
|
|
||||||
|
|
||||||
def processing(self):
|
|
||||||
time_start = time.time()
|
|
||||||
clibs.running[self.idx] = 1
|
|
||||||
|
|
||||||
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
|
|
||||||
params = self.initialization(data_dirs, data_files)
|
|
||||||
prj_file = params["prj_file"]
|
|
||||||
clibs.c_pd.push_prj_to_server(prj_file)
|
|
||||||
self.run_rl(params)
|
|
||||||
|
|
||||||
self.logger("INFO", "brake-processing", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
|
||||||
time_total = time.time() - time_start
|
|
||||||
msg = f"处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
|
|
||||||
self.logger("INFO", "brake-processing", msg)
|
|
@ -1,135 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
## Form generated from reading UI file 'login.ui'
|
|
||||||
##
|
|
||||||
## Created by: Qt User Interface Compiler version 6.8.2
|
|
||||||
##
|
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
||||||
QMetaObject, QObject, QPoint, QRect,
|
|
||||||
QSize, QTime, QUrl, Qt)
|
|
||||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
||||||
QFont, QFontDatabase, QGradient, QIcon,
|
|
||||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
||||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
||||||
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QLineEdit,
|
|
||||||
QPushButton, QSizePolicy, QVBoxLayout, QWidget)
|
|
||||||
|
|
||||||
class Ui_Form(QWidget):
|
|
||||||
def setupUi(self, Form):
|
|
||||||
if not Form.objectName():
|
|
||||||
Form.setObjectName(u"Form")
|
|
||||||
Form.setWindowModality(Qt.WindowModality.WindowModal)
|
|
||||||
Form.resize(500, 270)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
|
|
||||||
Form.setSizePolicy(sizePolicy)
|
|
||||||
Form.setMinimumSize(QSize(500, 270))
|
|
||||||
Form.setMaximumSize(QSize(500, 270))
|
|
||||||
font = QFont()
|
|
||||||
font.setFamilies([u"Consolas"])
|
|
||||||
font.setPointSize(14)
|
|
||||||
Form.setFont(font)
|
|
||||||
icon = QIcon()
|
|
||||||
icon.addFile(u"../assets/media/icon.ico", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
|
||||||
Form.setWindowIcon(icon)
|
|
||||||
self.widget = QWidget(Form)
|
|
||||||
self.widget.setObjectName(u"widget")
|
|
||||||
self.widget.setGeometry(QRect(41, 41, 411, 211))
|
|
||||||
self.verticalLayout = QVBoxLayout(self.widget)
|
|
||||||
self.verticalLayout.setSpacing(2)
|
|
||||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
||||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.horizontalLayout_2 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_2.setSpacing(2)
|
|
||||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
|
||||||
self.label = QLabel(self.widget)
|
|
||||||
self.label.setObjectName(u"label")
|
|
||||||
self.label.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.label)
|
|
||||||
|
|
||||||
self.le_username = QLineEdit(self.widget)
|
|
||||||
self.le_username.setObjectName(u"le_username")
|
|
||||||
self.le_username.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.le_username)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
|
||||||
|
|
||||||
self.horizontalLayout_3 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_3.setSpacing(2)
|
|
||||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
|
||||||
self.label_2 = QLabel(self.widget)
|
|
||||||
self.label_2.setObjectName(u"label_2")
|
|
||||||
self.label_2.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_3.addWidget(self.label_2)
|
|
||||||
|
|
||||||
self.le_password = QLineEdit(self.widget)
|
|
||||||
self.le_password.setObjectName(u"le_password")
|
|
||||||
self.le_password.setFont(font)
|
|
||||||
self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
|
|
||||||
|
|
||||||
self.horizontalLayout_3.addWidget(self.le_password)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
||||||
|
|
||||||
self.label_hint = QLabel(self.widget)
|
|
||||||
self.label_hint.setObjectName(u"label_hint")
|
|
||||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
|
||||||
sizePolicy1.setHorizontalStretch(0)
|
|
||||||
sizePolicy1.setVerticalStretch(0)
|
|
||||||
sizePolicy1.setHeightForWidth(self.label_hint.sizePolicy().hasHeightForWidth())
|
|
||||||
self.label_hint.setSizePolicy(sizePolicy1)
|
|
||||||
font1 = QFont()
|
|
||||||
font1.setFamilies([u"Consolas"])
|
|
||||||
font1.setPointSize(12)
|
|
||||||
self.label_hint.setFont(font1)
|
|
||||||
|
|
||||||
self.verticalLayout.addWidget(self.label_hint)
|
|
||||||
|
|
||||||
self.horizontalLayout = QHBoxLayout()
|
|
||||||
self.horizontalLayout.setSpacing(2)
|
|
||||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
||||||
self.btn_login = QPushButton(self.widget)
|
|
||||||
self.btn_login.setObjectName(u"btn_login")
|
|
||||||
self.btn_login.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout.addWidget(self.btn_login)
|
|
||||||
|
|
||||||
self.btn_reset = QPushButton(self.widget)
|
|
||||||
self.btn_reset.setObjectName(u"btn_reset")
|
|
||||||
self.btn_reset.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout.addWidget(self.btn_reset)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
||||||
|
|
||||||
|
|
||||||
self.retranslateUi(Form)
|
|
||||||
self.btn_login.clicked.connect(Form.user_login)
|
|
||||||
self.le_password.returnPressed.connect(Form.user_login)
|
|
||||||
self.le_username.returnPressed.connect(Form.user_login)
|
|
||||||
self.btn_reset.clicked.connect(Form.reset_password)
|
|
||||||
|
|
||||||
QMetaObject.connectSlotsByName(Form)
|
|
||||||
# setupUi
|
|
||||||
|
|
||||||
def retranslateUi(self, Form):
|
|
||||||
Form.setWindowTitle(QCoreApplication.translate("Form", u"\u767b\u5f55", None))
|
|
||||||
self.label.setText(QCoreApplication.translate("Form", u"\u7528\u6237\u540d", None))
|
|
||||||
self.label_2.setText(QCoreApplication.translate("Form", u"\u5bc6 \u7801", None))
|
|
||||||
self.label_hint.setText("")
|
|
||||||
self.btn_login.setText(QCoreApplication.translate("Form", u"\u767b\u5f55", None))
|
|
||||||
self.btn_reset.setText(QCoreApplication.translate("Form", u"\u91cd\u7f6e", None))
|
|
||||||
# retranslateUi
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
## Form generated from reading UI file 'reset.ui'
|
|
||||||
##
|
|
||||||
## Created by: Qt User Interface Compiler version 6.8.2
|
|
||||||
##
|
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
||||||
QMetaObject, QObject, QPoint, QRect,
|
|
||||||
QSize, QTime, QUrl, Qt)
|
|
||||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
||||||
QFont, QFontDatabase, QGradient, QIcon,
|
|
||||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
||||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
||||||
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QLineEdit,
|
|
||||||
QPushButton, QSizePolicy, QVBoxLayout, QWidget)
|
|
||||||
|
|
||||||
class Ui_Form(QWidget):
|
|
||||||
def setupUi(self, Form):
|
|
||||||
if not Form.objectName():
|
|
||||||
Form.setObjectName(u"Form")
|
|
||||||
Form.setWindowModality(Qt.WindowModality.WindowModal)
|
|
||||||
Form.resize(500, 270)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
|
|
||||||
Form.setSizePolicy(sizePolicy)
|
|
||||||
Form.setMinimumSize(QSize(500, 270))
|
|
||||||
Form.setMaximumSize(QSize(500, 270))
|
|
||||||
font = QFont()
|
|
||||||
font.setFamilies([u"Consolas"])
|
|
||||||
font.setPointSize(14)
|
|
||||||
Form.setFont(font)
|
|
||||||
icon = QIcon()
|
|
||||||
icon.addFile(u"../assets/media/icon.ico", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
|
||||||
Form.setWindowIcon(icon)
|
|
||||||
self.widget = QWidget(Form)
|
|
||||||
self.widget.setObjectName(u"widget")
|
|
||||||
self.widget.setGeometry(QRect(40, 27, 411, 211))
|
|
||||||
self.verticalLayout = QVBoxLayout(self.widget)
|
|
||||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
||||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.horizontalLayout_5 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
|
||||||
self.label = QLabel(self.widget)
|
|
||||||
self.label.setObjectName(u"label")
|
|
||||||
self.label.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_5.addWidget(self.label)
|
|
||||||
|
|
||||||
self.le_username = QLineEdit(self.widget)
|
|
||||||
self.le_username.setObjectName(u"le_username")
|
|
||||||
self.le_username.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_5.addWidget(self.le_username)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
|
||||||
|
|
||||||
self.horizontalLayout_4 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
|
||||||
self.label_2 = QLabel(self.widget)
|
|
||||||
self.label_2.setObjectName(u"label_2")
|
|
||||||
self.label_2.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_4.addWidget(self.label_2)
|
|
||||||
|
|
||||||
self.le_old_password = QLineEdit(self.widget)
|
|
||||||
self.le_old_password.setObjectName(u"le_old_password")
|
|
||||||
self.le_old_password.setFont(font)
|
|
||||||
self.le_old_password.setEchoMode(QLineEdit.EchoMode.Password)
|
|
||||||
|
|
||||||
self.horizontalLayout_4.addWidget(self.le_old_password)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
||||||
|
|
||||||
self.horizontalLayout_3 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
|
||||||
self.label_3 = QLabel(self.widget)
|
|
||||||
self.label_3.setObjectName(u"label_3")
|
|
||||||
self.label_3.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_3.addWidget(self.label_3)
|
|
||||||
|
|
||||||
self.le_new_password_1 = QLineEdit(self.widget)
|
|
||||||
self.le_new_password_1.setObjectName(u"le_new_password_1")
|
|
||||||
self.le_new_password_1.setFont(font)
|
|
||||||
self.le_new_password_1.setEchoMode(QLineEdit.EchoMode.Password)
|
|
||||||
|
|
||||||
self.horizontalLayout_3.addWidget(self.le_new_password_1)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
||||||
|
|
||||||
self.horizontalLayout_2 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
|
||||||
self.label_4 = QLabel(self.widget)
|
|
||||||
self.label_4.setObjectName(u"label_4")
|
|
||||||
self.label_4.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.label_4)
|
|
||||||
|
|
||||||
self.le_new_password_2 = QLineEdit(self.widget)
|
|
||||||
self.le_new_password_2.setObjectName(u"le_new_password_2")
|
|
||||||
self.le_new_password_2.setFont(font)
|
|
||||||
self.le_new_password_2.setEchoMode(QLineEdit.EchoMode.Password)
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.le_new_password_2)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
|
||||||
|
|
||||||
self.label_hint = QLabel(self.widget)
|
|
||||||
self.label_hint.setObjectName(u"label_hint")
|
|
||||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
|
||||||
sizePolicy1.setHorizontalStretch(0)
|
|
||||||
sizePolicy1.setVerticalStretch(0)
|
|
||||||
sizePolicy1.setHeightForWidth(self.label_hint.sizePolicy().hasHeightForWidth())
|
|
||||||
self.label_hint.setSizePolicy(sizePolicy1)
|
|
||||||
font1 = QFont()
|
|
||||||
font1.setFamilies([u"Consolas"])
|
|
||||||
font1.setPointSize(12)
|
|
||||||
self.label_hint.setFont(font1)
|
|
||||||
|
|
||||||
self.verticalLayout.addWidget(self.label_hint)
|
|
||||||
|
|
||||||
self.horizontalLayout = QHBoxLayout()
|
|
||||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
||||||
self.btn_reset = QPushButton(self.widget)
|
|
||||||
self.btn_reset.setObjectName(u"btn_reset")
|
|
||||||
self.btn_reset.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout.addWidget(self.btn_reset)
|
|
||||||
|
|
||||||
self.btn_cancel = QPushButton(self.widget)
|
|
||||||
self.btn_cancel.setObjectName(u"btn_cancel")
|
|
||||||
self.btn_cancel.setFont(font)
|
|
||||||
|
|
||||||
self.horizontalLayout.addWidget(self.btn_cancel)
|
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
||||||
|
|
||||||
QWidget.setTabOrder(self.le_username, self.le_old_password)
|
|
||||||
QWidget.setTabOrder(self.le_old_password, self.le_new_password_1)
|
|
||||||
QWidget.setTabOrder(self.le_new_password_1, self.le_new_password_2)
|
|
||||||
|
|
||||||
self.retranslateUi(Form)
|
|
||||||
self.btn_reset.clicked.connect(Form.reset_password)
|
|
||||||
self.btn_cancel.clicked.connect(Form.reset_cancel)
|
|
||||||
|
|
||||||
QMetaObject.connectSlotsByName(Form)
|
|
||||||
# setupUi
|
|
||||||
|
|
||||||
def retranslateUi(self, Form):
|
|
||||||
Form.setWindowTitle(QCoreApplication.translate("Form", u"\u91cd\u7f6e\u5bc6\u7801", None))
|
|
||||||
self.label.setText(QCoreApplication.translate("Form", u"\u7528\u6237\u540d", None))
|
|
||||||
self.label_2.setText(QCoreApplication.translate("Form", u"\u65e7\u5bc6\u7801", None))
|
|
||||||
self.label_3.setText(QCoreApplication.translate("Form", u"\u65b0\u5bc6\u7801", None))
|
|
||||||
self.label_4.setText(QCoreApplication.translate("Form", u"\u786e \u8ba4", None))
|
|
||||||
self.label_hint.setText("")
|
|
||||||
self.btn_reset.setText(QCoreApplication.translate("Form", u"\u786e\u5b9a", None))
|
|
||||||
self.btn_cancel.setText(QCoreApplication.translate("Form", u"\u53d6\u6d88", None))
|
|
||||||
# retranslateUi
|
|
||||||
|
|
0
codes/__init__.py
Normal file
0
codes/__init__.py
Normal file
0
codes/analysis/__init__.py
Normal file
0
codes/analysis/__init__.py
Normal file
@ -5,7 +5,7 @@ import pandas
|
|||||||
from PySide6.QtCore import Signal, QThread
|
from PySide6.QtCore import Signal, QThread
|
||||||
import openpyxl
|
import openpyxl
|
||||||
import re
|
import re
|
||||||
from common import clibs
|
from codes.common import clibs
|
||||||
|
|
||||||
|
|
||||||
class BrakeDataProcess(QThread):
|
class BrakeDataProcess(QThread):
|
||||||
@ -17,17 +17,19 @@ class BrakeDataProcess(QThread):
|
|||||||
self.idx = 0
|
self.idx = 0
|
||||||
|
|
||||||
def logger(self, level, module, content, color="black", error="", flag="both"):
|
def logger(self, level, module, content, color="black", error="", flag="both"):
|
||||||
|
flag = "cursor" if level.upper() == "DEBUG" else "both"
|
||||||
clibs.logger(level, module, content, color, flag, signal=self.output)
|
clibs.logger(level, module, content, color, flag, signal=self.output)
|
||||||
if level.upper() == "ERROR":
|
if level.upper() == "ERROR":
|
||||||
raise Exception(f"{error} | {content}")
|
raise Exception(f"{error} | {content}")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def check_files(self, rawdata_dirs, result_files):
|
def check_files(self, rawdata_dirs, result_files):
|
||||||
msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:<br>"
|
msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:<br>"
|
||||||
msg_wrong += "- reach33/66/100_XXXXXXX.xlsx<br>- *.cfg<br>"
|
msg_wrong += "- reach33/66/100_XXXXXXX.xlsx<br>- *.cfg<br>"
|
||||||
msg_wrong += "- reach33_load33_speed33<br>- reach33_load33_speed66<br>...<br>- reach100_load100_speed66<br>- reach100_load100_speed100<br>"
|
msg_wrong += "- reach33_load33_speed33<br>- reach33_load33_speed66<br>...<br>- reach100_load100_speed66<br>- reach100_load100_speed100<br>"
|
||||||
|
|
||||||
if len(result_files) != 4 or len(rawdata_dirs) == 0:
|
if len(result_files) != 4 or len(rawdata_dirs) == 0:
|
||||||
self.logger("ERROR", "brake-check_files", msg_wrong, "red", "InitFileError")
|
self.logger("ERROR", "brake", msg_wrong, "red", "InitFileError")
|
||||||
|
|
||||||
config_file, reach33_file, reach66_file, reach100_file = None, None, None, None
|
config_file, reach33_file, reach66_file, reach100_file = None, None, None, None
|
||||||
for result_file in result_files:
|
for result_file in result_files:
|
||||||
@ -42,7 +44,7 @@ class BrakeDataProcess(QThread):
|
|||||||
reach100_file = result_file
|
reach100_file = result_file
|
||||||
else:
|
else:
|
||||||
if not (config_file and reach33_file and reach66_file and reach100_file):
|
if not (config_file and reach33_file and reach66_file and reach100_file):
|
||||||
self.logger("ERROR", "brake-check_files", msg_wrong, "red", "InitFileError")
|
self.logger("ERROR", "brake", msg_wrong, "red", "InitFileError")
|
||||||
|
|
||||||
reach_s = ['reach33', 'reach66', 'reach100']
|
reach_s = ['reach33', 'reach66', 'reach100']
|
||||||
load_s = ['load33', 'load66', 'load100']
|
load_s = ['load33', 'load66', 'load100']
|
||||||
@ -55,26 +57,27 @@ class BrakeDataProcess(QThread):
|
|||||||
msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式<br>"
|
msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式<br>"
|
||||||
msg += "命名规则:reachAA_loadBB_speedCC,AA/BB/CC 指的是臂展/负载/速度的比例<br>"
|
msg += "命名规则:reachAA_loadBB_speedCC,AA/BB/CC 指的是臂展/负载/速度的比例<br>"
|
||||||
msg += "规则解释:reach66_load100_speed33,表示 66% 臂展,100% 负载以及 33% 速度情况下的测试结果文件夹<br>"
|
msg += "规则解释:reach66_load100_speed33,表示 66% 臂展,100% 负载以及 33% 速度情况下的测试结果文件夹<br>"
|
||||||
self.logger("ERROR", "brake-check_files", msg, "red", "WrongDataFolder")
|
self.logger("ERROR", "brake", msg, "red", "WrongDataFolder")
|
||||||
|
|
||||||
_, rawdata_files = clibs.traversal_files(rawdata_dir, self.output)
|
_, rawdata_files = clibs.traversal_files(rawdata_dir, self.output)
|
||||||
if len(rawdata_files) != 3:
|
if len(rawdata_files) != 3:
|
||||||
msg = f"数据目录 {rawdata_dir} 下数据文件个数错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
|
msg = f"数据目录 {rawdata_dir} 下数据文件个数错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
|
||||||
self.logger("ERROR", "brake-check_files", msg, "red", "WrongDataFile")
|
self.logger("ERROR", "brake", 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 为后缀的数据文件"
|
||||||
self.logger("ERROR", "brake-check_files", msg, "red", "WrongDataFile")
|
self.logger("ERROR", "brake", msg, "red", "WrongDataFile")
|
||||||
|
|
||||||
result_files = []
|
result_files = []
|
||||||
for _ in [reach33_file, reach66_file, reach100_file]:
|
for _ in [reach33_file, reach66_file, reach100_file]:
|
||||||
if _.split("/")[-1].split("_")[0] in set(prefix):
|
if _.split("/")[-1].split("_")[0] in set(prefix):
|
||||||
result_files.append(_)
|
result_files.append(_)
|
||||||
|
|
||||||
self.logger("INFO", "brake-check_files", "数据目录合规性检查结束,未发现问题......", "green")
|
self.logger("INFO", "brake", "数据目录合规性检查结束,未发现问题......", "green")
|
||||||
return config_file, result_files
|
return config_file, result_files
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def get_configs(self, config_file):
|
def get_configs(self, config_file):
|
||||||
try:
|
try:
|
||||||
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
with open(config_file, mode="r", encoding="utf-8") as f_config:
|
||||||
@ -82,7 +85,7 @@ class BrakeDataProcess(QThread):
|
|||||||
|
|
||||||
p_dir = config_file.split('/')[-2]
|
p_dir = config_file.split('/')[-2]
|
||||||
if not re.match("^[jJ][123]$", p_dir):
|
if not re.match("^[jJ][123]$", p_dir):
|
||||||
self.logger("ERROR", "brake-get_configs-1", "被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
|
self.logger("ERROR", "brake", "被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
|
||||||
|
|
||||||
axis = int(p_dir[-1]) # 要处理的轴
|
axis = int(p_dir[-1]) # 要处理的轴
|
||||||
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比,rr for reduction ratio
|
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比,rr for reduction ratio
|
||||||
@ -91,21 +94,22 @@ class BrakeDataProcess(QThread):
|
|||||||
av = avs[axis-1]
|
av = avs[axis-1]
|
||||||
return av, rr
|
return av, rr
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
self.logger("ERROR", "brake-get_configs-2", f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查<br>{Err}", "red", "OpenFileError")
|
self.logger("ERROR", "brake", f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查<br>{Err}", "red", "OpenFileError")
|
||||||
|
|
||||||
def now_doing_msg(self, docs, flag):
|
def now_doing_msg(self, docs, flag):
|
||||||
now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
|
now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
|
||||||
file_type = 'file' if os.path.isfile(docs) else 'dir'
|
file_type = 'file' if os.path.isfile(docs) else 'dir'
|
||||||
if flag == 'start' and file_type == 'dir':
|
if flag == 'start' and file_type == 'dir':
|
||||||
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 正在处理目录 {docs} 中的数据......")
|
self.logger("INFO", "brake", f"[{now}] 正在处理目录 {docs} 中的数据......")
|
||||||
elif flag == 'start' and file_type == 'file':
|
elif flag == 'start' and file_type == 'file':
|
||||||
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 正在处理文件 {docs} 中的数据......")
|
self.logger("INFO", "brake", f"[{now}] 正在处理文件 {docs} 中的数据......")
|
||||||
elif flag == 'done' and file_type == 'dir':
|
elif flag == 'done' and file_type == 'dir':
|
||||||
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 目录 {docs} 数据文件已处理完毕")
|
self.logger("INFO", "brake", f"[{now}] 目录 {docs} 数据文件已处理完毕")
|
||||||
elif flag == 'done' and file_type == 'file':
|
elif flag == 'done' and file_type == 'file':
|
||||||
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 文件 {docs} 数据已处理完毕")
|
self.logger("INFO", "brake", f"[{now}] 文件 {docs} 数据已处理完毕")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@clibs.handle_exception
|
||||||
def data2result(df, ws_result, row_start, row_end):
|
def data2result(df, ws_result, row_start, row_end):
|
||||||
data = []
|
data = []
|
||||||
for row in range(row_start, row_end):
|
for row in range(row_start, row_end):
|
||||||
@ -126,6 +130,7 @@ class BrakeDataProcess(QThread):
|
|||||||
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
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def get_row_range(self, data_file, df, conditions, av, rr):
|
def get_row_range(self, data_file, df, conditions, av, rr):
|
||||||
row_start, row_end = 0, 0
|
row_start, row_end = 0, 0
|
||||||
ratio = float(conditions[2].removeprefix('speed')) / 100
|
ratio = float(conditions[2].removeprefix('speed')) / 100
|
||||||
@ -137,7 +142,7 @@ class BrakeDataProcess(QThread):
|
|||||||
row_start = row - 20 if row - 20 > 0 else 0 # 急停前找 20 个点
|
row_start = row - 20 if row - 20 > 0 else 0 # 急停前找 20 个点
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "brake-get_row_range", f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", "red", "StartNotFoundError")
|
self.logger("ERROR", "brake", f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", "red", "StartNotFoundError")
|
||||||
|
|
||||||
for row in range(row_start, df.index[-1] - 1, 10):
|
for row in range(row_start, df.index[-1] - 1, 10):
|
||||||
speed_row = df.iloc[row, 0] * clibs.RADIAN * rr * 60 / 360
|
speed_row = df.iloc[row, 0] * clibs.RADIAN * rr * 60 / 360
|
||||||
@ -145,17 +150,18 @@ class BrakeDataProcess(QThread):
|
|||||||
row_end = row + 100 if row + 100 <= df.index[-1] - 1 else df.index[-1] - 1
|
row_end = row + 100 if row + 100 <= df.index[-1] - 1 else df.index[-1] - 1
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "brake-get_row_range", f"数据文件 {data_file} 最后的速度未降为零", "red", "SpeedNotZeroError")
|
self.logger("ERROR", "brake", f"数据文件 {data_file} 最后的速度未降为零", "red", "SpeedNotZeroError")
|
||||||
|
|
||||||
av_estop = abs(df.iloc[row_start - 20:row_start, 0].abs().mean() * clibs.RADIAN)
|
av_estop = abs(df.iloc[row_start - 20:row_start, 0].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]
|
||||||
msg = f"[av_estop: {av_estop:.2f} | shouldbe: {av_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查"
|
msg = f"[av_estop: {av_estop:.2f} | shouldbe: {av_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查"
|
||||||
self.logger("WARNING", "brake-get_row_range", msg, "#8A2BE2")
|
self.logger("WARNING", "brake", msg, "#8A2BE2")
|
||||||
|
|
||||||
return row_start, row_end
|
return row_start, row_end
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@clibs.handle_exception
|
||||||
def get_shtname(conditions, count):
|
def get_shtname(conditions, count):
|
||||||
# 33%负载_33%速度_1 - reach/load/speed
|
# 33%负载_33%速度_1 - reach/load/speed
|
||||||
load = conditions[1].removeprefix('load')
|
load = conditions[1].removeprefix('load')
|
||||||
@ -164,6 +170,7 @@ class BrakeDataProcess(QThread):
|
|||||||
|
|
||||||
return result_sheet_name
|
return result_sheet_name
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def single_file_process(self, data_file, wb, count, av, rr):
|
def single_file_process(self, data_file, wb, count, av, rr):
|
||||||
df = pandas.read_csv(data_file, sep='\t')
|
df = pandas.read_csv(data_file, sep='\t')
|
||||||
conditions = data_file.split("/")[-2].split("_") # reach/load/speed
|
conditions = data_file.split("/")[-2].split("_") # reach/load/speed
|
||||||
@ -173,13 +180,14 @@ class BrakeDataProcess(QThread):
|
|||||||
row_start, row_end = self.get_row_range(data_file, df, conditions, av, rr)
|
row_start, row_end = self.get_row_range(data_file, df, conditions, av, rr)
|
||||||
self.data2result(df, ws, row_start, row_end)
|
self.data2result(df, ws, row_start, row_end)
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def data_process(self, result_file, rawdata_dirs, av, rr):
|
def data_process(self, result_file, rawdata_dirs, av, rr):
|
||||||
filename = result_file.split("/")[-1]
|
filename = result_file.split("/")[-1]
|
||||||
self.logger("INFO", "brake-data_process", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
|
self.logger("INFO", "brake", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
|
||||||
try:
|
try:
|
||||||
wb = openpyxl.load_workbook(result_file)
|
wb = openpyxl.load_workbook(result_file)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
self.logger("ERROR", "brake-data_process", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
|
self.logger("ERROR", "brake", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
|
||||||
|
|
||||||
prefix = filename.split('_')[0]
|
prefix = filename.split('_')[0]
|
||||||
for rawdata_dir in rawdata_dirs:
|
for rawdata_dir in rawdata_dirs:
|
||||||
@ -197,10 +205,11 @@ class BrakeDataProcess(QThread):
|
|||||||
# [t.join() for t in threads]
|
# [t.join() for t in threads]
|
||||||
self.now_doing_msg(rawdata_dir, 'done')
|
self.now_doing_msg(rawdata_dir, 'done')
|
||||||
|
|
||||||
self.logger("INFO", "brake-data_process", f"正在保存文件 {filename},这可能需要一些时间......<br>", "blue")
|
self.logger("INFO", "brake", f"正在保存文件 {filename},这可能需要一些时间......<br>", "blue")
|
||||||
wb.save(result_file)
|
wb.save(result_file)
|
||||||
wb.close()
|
wb.close()
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def processing(self):
|
def processing(self):
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
clibs.running[self.idx] = 1
|
clibs.running[self.idx] = 1
|
||||||
@ -212,7 +221,7 @@ class BrakeDataProcess(QThread):
|
|||||||
for result_file in result_files:
|
for result_file in result_files:
|
||||||
self.data_process(result_file, rawdata_dirs, av, rr)
|
self.data_process(result_file, rawdata_dirs, av, rr)
|
||||||
|
|
||||||
self.logger("INFO", "brake-processing", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
self.logger("INFO", "brake", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
||||||
time_total = time.time() - time_start
|
time_total = time.time() - time_start
|
||||||
msg = f"处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
|
msg = f"处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
|
||||||
self.logger("INFO", "brake-processing", msg)
|
self.logger("INFO", "brake", msg)
|
@ -5,7 +5,7 @@ import re
|
|||||||
import csv
|
import csv
|
||||||
from PySide6.QtCore import Signal, QThread
|
from PySide6.QtCore import Signal, QThread
|
||||||
import time
|
import time
|
||||||
from common import clibs
|
from codes.common import clibs
|
||||||
|
|
||||||
|
|
||||||
class CurrentDataProcess(QThread):
|
class CurrentDataProcess(QThread):
|
||||||
@ -18,10 +18,12 @@ class CurrentDataProcess(QThread):
|
|||||||
self.idx = 1
|
self.idx = 1
|
||||||
|
|
||||||
def logger(self, level, module, content, color="black", error="", flag="both"):
|
def logger(self, level, module, content, color="black", error="", flag="both"):
|
||||||
|
flag = "cursor" if level.upper() == "DEBUG" else "both"
|
||||||
clibs.logger(level, module, content, color, flag, signal=self.output)
|
clibs.logger(level, module, content, color, flag, signal=self.output)
|
||||||
if level.upper() == "ERROR":
|
if level.upper() == "ERROR":
|
||||||
raise Exception(f"{error} | {content}")
|
raise Exception(f"{error} | {content}")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def initialization(self):
|
def initialization(self):
|
||||||
_, data_files = clibs.traversal_files(self.dir_path, self.output)
|
_, data_files = clibs.traversal_files(self.dir_path, self.output)
|
||||||
count, config_file = 0, None
|
count, config_file = 0, None
|
||||||
@ -36,16 +38,17 @@ class CurrentDataProcess(QThread):
|
|||||||
if not re.match("^j[1-7].*\\.data$", filename):
|
if not re.match("^j[1-7].*\\.data$", filename):
|
||||||
msg = f"不合规 {data_file}<br>"
|
msg = f"不合规 {data_file}<br>"
|
||||||
msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾,比如j1_abcdef.data,请检查整改后重新运行"
|
msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾,比如j1_abcdef.data,请检查整改后重新运行"
|
||||||
self.logger("ERROR", "current-initialization", msg, "red", "FilenameIllegal")
|
self.logger("ERROR", "current", msg, "red", "FilenameIllegal")
|
||||||
|
|
||||||
if count != 2:
|
if count != 2:
|
||||||
msg = "需要有一个机型配置文件\"*.cfg\",以及一个数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行"
|
msg = "需要有一个机型配置文件\"*.cfg\",以及一个数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行"
|
||||||
self.logger("ERROR", "current-initialization", msg, "red", "FilenameIllegal")
|
self.logger("ERROR", "current", msg, "red", "FilenameIllegal")
|
||||||
|
|
||||||
return data_files, config_file
|
return data_files, config_file
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def current_max(self, data_files, rts):
|
def current_max(self, data_files, rts):
|
||||||
self.logger("INFO", "current-current_max", f"正在处理最大转矩值逻辑......")
|
self.logger("INFO", "current", f"正在处理最大转矩值逻辑......")
|
||||||
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
if data_file.endswith(".data"):
|
if data_file.endswith(".data"):
|
||||||
@ -53,11 +56,11 @@ class CurrentDataProcess(QThread):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.logger("INFO", "current-current_max", f"正在处理 {data_file} ...")
|
self.logger("DEBUG", "current", f"正在处理 {data_file} ...")
|
||||||
cols = len(df.columns)
|
cols = len(df.columns)
|
||||||
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
||||||
rt = rts[axis-1]
|
rt = rts[axis-1]
|
||||||
self.logger("INFO", "current-current_max", f"最大列数为 {cols},{axis} 轴的额定转矩为 {rt}")
|
self.logger("DEBUG", "current", f"最大列数为 {cols},{axis} 轴的额定转矩为 {rt}")
|
||||||
|
|
||||||
col = df.columns.values[clibs.c_servo_trq-1] # 获取 "device_servo_trq_feedback"
|
col = df.columns.values[clibs.c_servo_trq-1] # 获取 "device_servo_trq_feedback"
|
||||||
c_max = df[col].abs().max()
|
c_max = df[col].abs().max()
|
||||||
@ -65,8 +68,8 @@ class CurrentDataProcess(QThread):
|
|||||||
scale = 1000
|
scale = 1000
|
||||||
_ = abs(c_max/scale*rt)
|
_ = abs(c_max/scale*rt)
|
||||||
current[axis].append(_)
|
current[axis].append(_)
|
||||||
self.logger("INFO", "current-current_max", f"{data_file}: {_:.2f}")
|
self.logger("DEBUG", "current", f"{data_file}: {_:.2f}")
|
||||||
self.logger("INFO", "current-current_max", f"获取到的列名为 {col},最大转矩为 {_}")
|
self.logger("DEBUG", "current", f"获取到的列名为 {col},最大转矩为 {_}")
|
||||||
|
|
||||||
with open(data_file, "a+") as f_data:
|
with open(data_file, "a+") as f_data:
|
||||||
csv_writer = csv.writer(f_data, delimiter="\t")
|
csv_writer = csv.writer(f_data, delimiter="\t")
|
||||||
@ -79,14 +82,15 @@ class CurrentDataProcess(QThread):
|
|||||||
_ = ""
|
_ = ""
|
||||||
for value in cur:
|
for value in cur:
|
||||||
_ += f"{value:.4f} "
|
_ += f"{value:.4f} "
|
||||||
self.logger("INFO", "current-current_max", f"{axis}轴最大转矩数据:{_}")
|
self.logger("INFO", "current", f"{axis}轴最大转矩数据:{_}")
|
||||||
|
|
||||||
self.logger("INFO", "current-current_max", f"获取最大转矩值结束 current_max = {current}")
|
self.logger("DEBUG", "current", f"获取最大转矩值结束 current_max = {current}")
|
||||||
self.logger("INFO", "current-current_max", f"最大转矩数据处理完毕......")
|
self.logger("INFO", "current", f"最大转矩数据处理完毕......")
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def current_avg(self, data_files, rts):
|
def current_avg(self, data_files, rts):
|
||||||
self.logger("INFO", "current-current_avg", f"正在处理平均转矩值逻辑......")
|
self.logger("INFO", "current", f"正在处理平均转矩值逻辑......")
|
||||||
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
if data_file.endswith(".data"):
|
if data_file.endswith(".data"):
|
||||||
@ -94,11 +98,11 @@ class CurrentDataProcess(QThread):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.logger("INFO", "current-current_avg", f"正在处理 {data_file} ...")
|
self.logger("DEBUG", "current", f"正在处理 {data_file} ...")
|
||||||
cols = len(df.columns)
|
cols = len(df.columns)
|
||||||
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
|
||||||
rt = rts[axis-1]
|
rt = rts[axis-1]
|
||||||
self.logger("INFO", "current-current_avg", f"最大列数为 {cols},{axis} 轴的额定转矩为 {rt}")
|
self.logger("DEBUG", "current", f"最大列数为 {cols},{axis} 轴的额定转矩为 {rt}")
|
||||||
|
|
||||||
col = df.columns.values[clibs.c_servo_trq-1]
|
col = df.columns.values[clibs.c_servo_trq-1]
|
||||||
c_std = df[col].std()
|
c_std = df[col].std()
|
||||||
@ -107,8 +111,8 @@ class CurrentDataProcess(QThread):
|
|||||||
scale = 1000
|
scale = 1000
|
||||||
_ = (abs(c_avg)+c_std*3)/scale*rt
|
_ = (abs(c_avg)+c_std*3)/scale*rt
|
||||||
current[axis].append(_)
|
current[axis].append(_)
|
||||||
self.logger("INFO", "current-current_avg", f"{data_file}: {_:.2f}")
|
self.logger("DEBUG", "current", f"{data_file}: {_:.2f}")
|
||||||
self.logger("INFO", "current-current_avg", f"获取到的列名为 {col},平均转矩为 {_}")
|
self.logger("DEBUG", "current", f"获取到的列名为 {col},平均转矩为 {_}")
|
||||||
|
|
||||||
with open(data_file, "a+") as f_data:
|
with open(data_file, "a+") as f_data:
|
||||||
csv_writer = csv.writer(f_data, delimiter="\t")
|
csv_writer = csv.writer(f_data, delimiter="\t")
|
||||||
@ -121,12 +125,13 @@ class CurrentDataProcess(QThread):
|
|||||||
_ = ""
|
_ = ""
|
||||||
for value in cur:
|
for value in cur:
|
||||||
_ += f"{value:.4f} "
|
_ += f"{value:.4f} "
|
||||||
self.logger("INFO", "current-current_avg", f"{axis}轴平均转矩数据:{_}")
|
self.logger("INFO", "current", f"{axis}轴平均转矩数据:{_}")
|
||||||
|
|
||||||
self.logger("INFO", "current-current_avg", f"获取平均转矩值结束 current_avg = {current}", flag="cursor")
|
self.logger("DEBUG", "current", f"获取平均转矩值结束 current_avg = {current}")
|
||||||
self.logger("INFO", "current-current_avg", f"平均转矩数据处理完毕......")
|
self.logger("INFO", "current", f"平均转矩数据处理完毕......")
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def current_cycle(self, data_files, rrs, rts, params):
|
def current_cycle(self, data_files, rrs, rts, params):
|
||||||
result, hold, single, scenario, dur_time = None, [], [], [], 0
|
result, hold, single, scenario, dur_time = None, [], [], [], 0
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
@ -142,11 +147,11 @@ class CurrentDataProcess(QThread):
|
|||||||
single.append(data_file)
|
single.append(data_file)
|
||||||
|
|
||||||
clibs.stop, filename = True, result.split("/")[-1]
|
clibs.stop, filename = True, result.split("/")[-1]
|
||||||
self.logger("INFO", "current-current_cycle", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
|
self.logger("INFO", "current", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
|
||||||
try:
|
try:
|
||||||
wb = openpyxl.load_workbook(result)
|
wb = openpyxl.load_workbook(result)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
self.logger("ERROR", "current-current_cycle", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
|
self.logger("ERROR", "current", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
|
||||||
|
|
||||||
ws = wb["统计"]
|
ws = wb["统计"]
|
||||||
for idx in range(len(params)-1):
|
for idx in range(len(params)-1):
|
||||||
@ -166,10 +171,11 @@ class CurrentDataProcess(QThread):
|
|||||||
else:
|
else:
|
||||||
self.p_scenario(wb, scenario, rrs, dur_time)
|
self.p_scenario(wb, scenario, rrs, dur_time)
|
||||||
|
|
||||||
self.logger("INFO", "current-current_cycle", f"正在保存文件 {filename},这可能需要一些时间......", "blue")
|
self.logger("INFO", "current", f"正在保存文件 {filename},这可能需要一些时间......", "blue")
|
||||||
wb.save(result)
|
wb.save(result)
|
||||||
wb.close()
|
wb.close()
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def find_point(self, data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq):
|
def find_point(self, data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq):
|
||||||
if flag == "lt":
|
if flag == "lt":
|
||||||
while row_e > end_point:
|
while row_e > end_point:
|
||||||
@ -183,15 +189,13 @@ class CurrentDataProcess(QThread):
|
|||||||
# 从实际数据看,这开逻辑很小概率能触发到
|
# 从实际数据看,这开逻辑很小概率能触发到
|
||||||
speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean()
|
speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean()
|
||||||
if speed_avg < threshold:
|
if speed_avg < threshold:
|
||||||
self.logger("WARNING", "current-find_point", f"【lt】{axis} 轴第 {seq} 次查找数据可能有异常,row_s = {row_s}, row_e = {row_e}!", "purple")
|
self.logger("WARNING", "current", f"【lt】{axis} 轴第 {seq} 次查找数据可能有异常,row_s = {row_s}, row_e = {row_e}!", "purple")
|
||||||
return row_s, row_e
|
return row_s, row_e
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "current-find_point", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
|
self.logger("ERROR", "current", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
|
||||||
elif flag == "gt":
|
elif flag == "gt":
|
||||||
while row_e > end_point:
|
while 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 axis == 1 and seq == 1:
|
|
||||||
# insert_logdb("DEBUG", "current", f"【gt】{axis} 轴,speed_avg = {speed_avg},row_s = {row_s}, row_e = {row_e}!")
|
|
||||||
if speed_avg > threshold:
|
if speed_avg > threshold:
|
||||||
row_e -= step
|
row_e -= step
|
||||||
row_s -= step
|
row_s -= step
|
||||||
@ -201,11 +205,12 @@ class CurrentDataProcess(QThread):
|
|||||||
# 从实际数据看,这开逻辑很小概率能触发到
|
# 从实际数据看,这开逻辑很小概率能触发到
|
||||||
speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean()
|
speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean()
|
||||||
if speed_avg > threshold:
|
if speed_avg > threshold:
|
||||||
self.logger("WARNING", "current-find_point", f"【gt】{axis} 轴第 {seq} 次查找数据可能有异常,row_s = {row_s}, row_e = {row_e}!", "purple")
|
self.logger("WARNING", "current", f"【gt】{axis} 轴第 {seq} 次查找数据可能有异常,row_s = {row_s}, row_e = {row_e}!", "purple")
|
||||||
return row_s, row_e
|
return row_s, row_e
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "current-find_point", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
|
self.logger("ERROR", "current", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def get_row_number(self, threshold, flag, df, row_s, row_e, axis):
|
def get_row_number(self, threshold, flag, df, row_s, row_e, axis):
|
||||||
count_1, count_2 = 0, 0
|
count_1, count_2 = 0, 0
|
||||||
if flag == "start" or flag == "end":
|
if flag == "start" or flag == "end":
|
||||||
@ -228,9 +233,10 @@ class CurrentDataProcess(QThread):
|
|||||||
count_1 = 0
|
count_1 = 0
|
||||||
|
|
||||||
places = {"start": "起点", "middle": "中间点", "end": "终点"} # 因为是终点数据,所以可能有异常
|
places = {"start": "起点", "middle": "中间点", "end": "终点"} # 因为是终点数据,所以可能有异常
|
||||||
self.logger("WARNING", "current-get_row_number", f"{axis} 轴获取{places[flag]}数据 {row_e} 可能有异常,需关注!", "purple")
|
self.logger("DEBUG", "current", f"{axis} 轴获取{places[flag]}数据 {row_e} 可能有异常,需关注!", "purple")
|
||||||
return row_e
|
return row_e
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def p_single(self, wb, single, rrs):
|
def p_single(self, wb, single, rrs):
|
||||||
# 1. 先找到第一个速度为零的点,数据从后往前找,一开始就是零的情况不予考虑
|
# 1. 先找到第一个速度为零的点,数据从后往前找,一开始就是零的情况不予考虑
|
||||||
# 2. 记录第一个点的位置,继续向前查找第二个速度为零的点,同理,一开始为零的点不予考虑
|
# 2. 记录第一个点的位置,继续向前查找第二个速度为零的点,同理,一开始为零的点不予考虑
|
||||||
@ -304,13 +310,13 @@ class CurrentDataProcess(QThread):
|
|||||||
row_s, row_e = self.find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 3)
|
row_s, row_e = self.find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 3)
|
||||||
row_start = self.get_row_number(threshold, "start", df, row_s, row_e, axis)
|
row_start = self.get_row_number(threshold, "start", df, row_s, row_e, axis)
|
||||||
|
|
||||||
self.logger("INFO", "current", f"{axis} 轴起点:{row_start}")
|
self.logger("DEBUG", "current", f"{axis} 轴起点:{row_start}")
|
||||||
self.logger("INFO", "current", f"{axis} 轴中间点:{row_middle}")
|
self.logger("DEBUG", "current", f"{axis} 轴中间点:{row_middle}")
|
||||||
self.logger("INFO", "current", f"{axis} 轴终点:{row_end}")
|
self.logger("DEBUG", "current", f"{axis} 轴终点:{row_end}")
|
||||||
self.logger("INFO", "current", f"{axis} 轴数据非零段点数:{row_middle-row_start+1}")
|
self.logger("DEBUG", "current", f"{axis} 轴数据非零段点数:{row_middle-row_start+1}")
|
||||||
self.logger("INFO", "current", f"{axis} 轴数据为零段点数:{row_end-row_middle+1}")
|
self.logger("DEBUG", "current", f"{axis} 轴数据为零段点数:{row_end-row_middle+1}")
|
||||||
if abs(row_end+row_start-2*row_middle) > 1000:
|
if abs(row_end+row_start-2*row_middle) > 1000:
|
||||||
self.logger("WARNING", "current", f"{axis} 轴数据占空比异常!", "purple")
|
self.logger("DEBUG", "current", f"{axis} 轴数据占空比异常!", "purple")
|
||||||
|
|
||||||
data, first_c, second_c, third_c, fourth_c = [], clibs.c_joint_vel-1, clibs.c_servo_trq-1, clibs.c_sensor_trq-1, clibs.c_estimate_trans_trq-1
|
data, first_c, second_c, third_c, fourth_c = [], clibs.c_joint_vel-1, clibs.c_servo_trq-1, clibs.c_sensor_trq-1, clibs.c_estimate_trans_trq-1
|
||||||
for row in range(row_start, row_end+1):
|
for row in range(row_start, row_end+1):
|
||||||
@ -334,6 +340,7 @@ class CurrentDataProcess(QThread):
|
|||||||
cell.value = None
|
cell.value = None
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def p_scenario(self, wb, scenario, rrs, dur_time):
|
def p_scenario(self, wb, scenario, rrs, dur_time):
|
||||||
self.logger("INFO", "current", f"本次处理的是电机电流场景数据,场景运动周期为 {dur_time}s", "blue")
|
self.logger("INFO", "current", f"本次处理的是电机电流场景数据,场景运动周期为 {dur_time}s", "blue")
|
||||||
for data_file in scenario:
|
for data_file in scenario:
|
||||||
@ -352,7 +359,7 @@ class CurrentDataProcess(QThread):
|
|||||||
row_start = 3000
|
row_start = 3000
|
||||||
row_end = row_start + int(dur_time/cycle)
|
row_end = row_start + int(dur_time/cycle)
|
||||||
if row_end > df.index[-1]:
|
if row_end > df.index[-1]:
|
||||||
self.logger("ERROR", "current-p_scenario", f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "blue", "DataOverLimit")
|
self.logger("ERROR", "current", f"位置超限:{data_file} 共有 {df.index[-1]} 条数据,无法取到第 {row_end} 条数据,需要确认场景周期时间...", "blue", "DataOverLimit")
|
||||||
|
|
||||||
data, first_c, second_c, third_c, fourth_c = [], clibs.c_joint_vel-1, clibs.c_servo_trq-1, clibs.c_sensor_trq-1, clibs.c_estimate_trans_trq-1
|
data, first_c, second_c, third_c, fourth_c = [], clibs.c_joint_vel-1, clibs.c_servo_trq-1, clibs.c_sensor_trq-1, clibs.c_estimate_trans_trq-1
|
||||||
for row in range(row_start, row_end+1):
|
for row in range(row_start, row_end+1):
|
||||||
@ -376,6 +383,7 @@ class CurrentDataProcess(QThread):
|
|||||||
ws.cell((i//4)+2, 1).value = None
|
ws.cell((i//4)+2, 1).value = None
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def get_configs(self, config_file):
|
def get_configs(self, config_file):
|
||||||
try:
|
try:
|
||||||
if re.match("^[NXEC]B.*", config_file.split("/")[-1]):
|
if re.match("^[NXEC]B.*", config_file.split("/")[-1]):
|
||||||
@ -407,6 +415,7 @@ class CurrentDataProcess(QThread):
|
|||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
self.logger("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {Err}", "red", "OpenFileError")
|
self.logger("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {Err}", "red", "OpenFileError")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def processing(self):
|
def processing(self):
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
clibs.running[self.idx] = 1
|
clibs.running[self.idx] = 1
|
||||||
@ -421,7 +430,7 @@ class CurrentDataProcess(QThread):
|
|||||||
elif self.proc == "周期":
|
elif self.proc == "周期":
|
||||||
self.current_cycle(data_files, rrs, rts, params)
|
self.current_cycle(data_files, rrs, rts, params)
|
||||||
|
|
||||||
self.logger("INFO", "current-processing", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
self.logger("INFO", "current", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
||||||
time_total = time.time() - time_start
|
time_total = time.time() - 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"
|
||||||
self.logger("INFO", "current-processing", msg)
|
self.logger("INFO", "current", msg)
|
@ -3,7 +3,7 @@ import openpyxl
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from PySide6.QtCore import Signal, QThread
|
from PySide6.QtCore import Signal, QThread
|
||||||
from common import clibs
|
from codes.common import clibs
|
||||||
|
|
||||||
|
|
||||||
class IsoDataProcess(QThread):
|
class IsoDataProcess(QThread):
|
||||||
@ -15,6 +15,7 @@ class IsoDataProcess(QThread):
|
|||||||
self.idx = 2
|
self.idx = 2
|
||||||
|
|
||||||
def logger(self, level, module, content, color="black", error="", flag="both"):
|
def logger(self, level, module, content, color="black", error="", flag="both"):
|
||||||
|
flag = "cursor" if level.upper() == "DEBUG" else "both"
|
||||||
clibs.logger(level, module, content, color, flag, signal=self.output)
|
clibs.logger(level, module, content, color, flag, signal=self.output)
|
||||||
if level.upper() == "ERROR":
|
if level.upper() == "ERROR":
|
||||||
raise Exception(f"{error} | {content}")
|
raise Exception(f"{error} | {content}")
|
@ -4,7 +4,7 @@ import openpyxl
|
|||||||
import chardet
|
import chardet
|
||||||
import time
|
import time
|
||||||
from PySide6.QtCore import Signal, QThread
|
from PySide6.QtCore import Signal, QThread
|
||||||
from common import clibs
|
from codes.common import clibs
|
||||||
|
|
||||||
|
|
||||||
class WaveloggerDataProcess(QThread):
|
class WaveloggerDataProcess(QThread):
|
||||||
@ -16,6 +16,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
self.idx = 3
|
self.idx = 3
|
||||||
|
|
||||||
def logger(self, level, module, content, color="black", error="", flag="both"):
|
def logger(self, level, module, content, color="black", error="", flag="both"):
|
||||||
|
flag = "cursor" if level.upper() == "DEBUG" else "both"
|
||||||
clibs.logger(level, module, content, color, flag, signal=self.output)
|
clibs.logger(level, module, content, color, flag, signal=self.output)
|
||||||
if level.upper() == "ERROR":
|
if level.upper() == "ERROR":
|
||||||
raise Exception(f"{error} | {content}")
|
raise Exception(f"{error} | {content}")
|
||||||
@ -37,7 +38,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if bof == "backward":
|
if bof == "backward":
|
||||||
self.logger("ERROR", "wavelogger-find_point", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
self.logger("ERROR", "wavelogger", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
||||||
elif bof == "forward":
|
elif bof == "forward":
|
||||||
row_target = row + margin # to end while loop in function `single_file_proc`
|
row_target = row + margin # to end while loop in function `single_file_proc`
|
||||||
elif flag == "lt":
|
elif flag == "lt":
|
||||||
@ -51,7 +52,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if bof == "backward":
|
if bof == "backward":
|
||||||
self.logger("ERROR", "wavelogger-find_point", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
self.logger("ERROR", "wavelogger", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
|
||||||
elif bof == "forward":
|
elif bof == "forward":
|
||||||
row_target = row + margin # to end while loop in function `single_file_proc`
|
row_target = row + margin # to end while loop in function `single_file_proc`
|
||||||
return row_target
|
return row_target
|
||||||
@ -88,7 +89,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
|
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
if not data_file.lower().endswith(".csv"):
|
if not data_file.lower().endswith(".csv"):
|
||||||
self.logger("ERROR", "wavelogger-initialization", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red", "FileTypeError")
|
self.logger("ERROR", "wavelogger", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red", "FileTypeError")
|
||||||
|
|
||||||
return data_files
|
return data_files
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
value = df.iloc[start:end, 2].astype(float).mean() + 3 * df.iloc[start:end, 2].astype(float).std()
|
value = df.iloc[start:end, 2].astype(float).mean() + 3 * df.iloc[start:end, 2].astype(float).std()
|
||||||
if value > 1:
|
if value > 1:
|
||||||
msg = f"\n"
|
msg = f"\n"
|
||||||
self.logger("WARNING", "wavelogger-single_file_proc", f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留", "purple")
|
self.logger("WARNING", "wavelogger", f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留", "purple")
|
||||||
|
|
||||||
data[count].append(value)
|
data[count].append(value)
|
||||||
count_i += 1
|
count_i += 1
|
||||||
@ -135,7 +136,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
def execution(self, data_files):
|
def execution(self, data_files):
|
||||||
self.logger("INFO", "wavelogger-execution", "正在处理中......", "blue")
|
self.logger("INFO", "wavelogger", "正在处理中......", "blue")
|
||||||
wb = openpyxl.Workbook()
|
wb = openpyxl.Workbook()
|
||||||
step, margin, data_length, threshold = 5, 50, 50, 5
|
step, margin, data_length, threshold = 5, 50, 50, 5
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
@ -154,7 +155,7 @@ class WaveloggerDataProcess(QThread):
|
|||||||
data_files = self.initialization()
|
data_files = self.initialization()
|
||||||
self.execution(data_files)
|
self.execution(data_files)
|
||||||
|
|
||||||
self.logger("INFO", "wavelogger-processing", "-" * 60 + "<br>全部处理完毕<br>", "purple")
|
self.logger("INFO", "wavelogger", "-" * 60 + "<br>全部处理完毕<br>", "purple")
|
||||||
time_total = time.time() - time_start
|
time_total = time.time() - 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"
|
||||||
self.logger("INFO", "wavelogger-processing", msg)
|
self.logger("INFO", "wavelogger", msg)
|
0
codes/autotest/__init__.py
Normal file
0
codes/autotest/__init__.py
Normal file
@ -5,7 +5,7 @@ import openpyxl
|
|||||||
import pandas
|
import pandas
|
||||||
import json
|
import json
|
||||||
from PySide6.QtCore import Signal, QThread
|
from PySide6.QtCore import Signal, QThread
|
||||||
from common import clibs
|
from codes.common import clibs
|
||||||
|
|
||||||
|
|
||||||
class DoBrakeTest(QThread):
|
class DoBrakeTest(QThread):
|
||||||
@ -18,16 +18,18 @@ class DoBrakeTest(QThread):
|
|||||||
self.idx = 4
|
self.idx = 4
|
||||||
|
|
||||||
def logger(self, level, module, content, color="black", error="", flag="both"):
|
def logger(self, level, module, content, color="black", error="", flag="both"):
|
||||||
|
flag = "cursor" if level.upper() == "DEBUG" else "both"
|
||||||
clibs.logger(level, module, content, color, flag, signal=self.output)
|
clibs.logger(level, module, content, color, flag, signal=self.output)
|
||||||
if level.upper() == "ERROR":
|
if level.upper() == "ERROR":
|
||||||
raise Exception(f"{error} | {content}")
|
raise Exception(f"{error} | {content}")
|
||||||
|
|
||||||
def initialization(self, data_dirs, data_files):
|
def initialization(self, data_dirs, data_files):
|
||||||
|
@clibs.handle_exception
|
||||||
def check_files():
|
def check_files():
|
||||||
msg = "初始路径下不允许有文件夹,初始路径下只能存在如下五个文件,且文件为关闭状态,确认后重新运行!<br>"
|
msg = "初始路径下不允许有文件夹,只能存在如下五个文件,且文件为关闭状态,确认后重新运行!<br>"
|
||||||
msg += "1. configs.xlsx<br>2. reach33/reach66/reach100_xxxx.xlsx<br>3. xxxx.zip"
|
msg += "1. configs.xlsx<br>2. reach33/reach66/reach100_xxxx.xlsx<br>3. xxxx.zip"
|
||||||
if len(data_dirs) != 0 or len(data_files) != 5:
|
if len(data_dirs) != 0 or len(data_files) != 5:
|
||||||
self.logger("ERROR", "do_brake-check_files", msg, "red", "InitFileError")
|
self.logger("ERROR", "do_brake", msg, "red", "InitFileError")
|
||||||
|
|
||||||
config_file, reach33_file, reach66_file, reach100_file, 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:
|
||||||
@ -43,7 +45,7 @@ class DoBrakeTest(QThread):
|
|||||||
elif filename.endswith(".zip"):
|
elif filename.endswith(".zip"):
|
||||||
prj_file = data_file
|
prj_file = data_file
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "do_brake-check_files", msg, "red", "InitFileError")
|
self.logger("ERROR", "do_brake", msg, "red", "InitFileError")
|
||||||
|
|
||||||
if config_file and reach33_file and reach66_file and reach100_file and prj_file:
|
if config_file and reach33_file and reach66_file and reach100_file and prj_file:
|
||||||
os.mkdir(f"{self.dir_path}/j1")
|
os.mkdir(f"{self.dir_path}/j1")
|
||||||
@ -60,15 +62,15 @@ class DoBrakeTest(QThread):
|
|||||||
if reach == "reach100":
|
if reach == "reach100":
|
||||||
os.mkdir(f"{self.dir_path}/j3/{dir_name}")
|
os.mkdir(f"{self.dir_path}/j3/{dir_name}")
|
||||||
|
|
||||||
self.logger("INFO", "do_brake-check_files", "数据目录合规性检查结束,未发现问题......", "green")
|
|
||||||
return config_file, prj_file, result_dirs
|
return config_file, prj_file, result_dirs
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "do_brake-check_files", msg, "red", "InitFileError")
|
self.logger("ERROR", "do_brake", msg, "red", "InitFileError")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def get_configs():
|
def get_configs():
|
||||||
robot_type = None
|
robot_type = None
|
||||||
msg_id, state = clibs.c_hr.execution("controller.get_params")
|
msg_id = clibs.c_hr.execution("controller.get_params")
|
||||||
records = clibs.c_hr.get_from_id(msg_id, state)
|
records = clibs.c_hr.get_from_id(msg_id)
|
||||||
for record in records:
|
for record in records:
|
||||||
if "请求发送成功" not in record[0]:
|
if "请求发送成功" not in record[0]:
|
||||||
robot_type = eval(record[0])["data"]["robot_type"]
|
robot_type = eval(record[0])["data"]["robot_type"]
|
||||||
@ -80,28 +82,29 @@ class DoBrakeTest(QThread):
|
|||||||
with open(local_file, mode="r", encoding="utf-8") as f_config:
|
with open(local_file, mode="r", encoding="utf-8") as f_config:
|
||||||
configs = json.load(f_config)
|
configs = json.load(f_config)
|
||||||
except Exception as Err:
|
except Exception as Err:
|
||||||
self.logger("ERROR", "do_brake-get_configs", f"无法打开 {local_file}<br>{Err}", "red", "OpenFileError")
|
self.logger("ERROR", "do_brake", f"无法打开 {local_file}<br>{Err}", "red", "OpenFileError")
|
||||||
|
|
||||||
# 最大角速度,额定电流,减速比,额定转速
|
# 最大角速度,额定电流,减速比,额定转速
|
||||||
version = configs["VERSION"]
|
version = configs["VERSION"]
|
||||||
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 机型文件版本 {robot_type}_{version}")
|
self.logger("INFO", "do_brake", f"get_configs: 机型文件版本 {robot_type}_{version}")
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}")
|
self.logger("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}")
|
||||||
return avs
|
return avs
|
||||||
|
|
||||||
|
self.logger("INFO", "do_brake", "正在做初始化校验和配置,这可能需要一点时间......", "green")
|
||||||
_config_file, _prj_file, _result_dirs = check_files()
|
_config_file, _prj_file, _result_dirs = check_files()
|
||||||
_avs = get_configs()
|
_avs = get_configs()
|
||||||
|
self.logger("INFO", "do_brake", "数据目录合规性检查结束,未发现问题......", "green")
|
||||||
return _config_file, _prj_file, _result_dirs, _avs
|
return _config_file, _prj_file, _result_dirs, _avs
|
||||||
|
|
||||||
def gen_result_file(self, axis, t_end, reach, load, speed, speed_max, rounds):
|
@clibs.handle_exception
|
||||||
|
def gen_result_file(self, axis, end_time, reach, load, speed, speed_max, rounds):
|
||||||
d_vel, d_trq, d_stop, threshold = [], [], [], 0.95
|
d_vel, d_trq, d_stop, threshold = [], [], [], 0.95
|
||||||
|
s_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time-clibs.INTERVAL*12))
|
||||||
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t_end-12))
|
e_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time))
|
||||||
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t_end))
|
|
||||||
try:
|
try:
|
||||||
clibs.lock.acquire(True)
|
clibs.lock.acquire(True)
|
||||||
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 timestamp BETWEEN '{s_time}' AND '{e_time}' AND content LIKE '%diagnosis.result%' ORDER BY id ASC")
|
||||||
records = clibs.cursor.fetchall()
|
records = clibs.cursor.fetchall()
|
||||||
finally:
|
finally:
|
||||||
clibs.lock.release()
|
clibs.lock.release()
|
||||||
@ -124,13 +127,13 @@ class DoBrakeTest(QThread):
|
|||||||
|
|
||||||
av_estop = abs(sum(d_vel[idx - 20:idx])/20 * clibs.RADIAN)
|
av_estop = abs(sum(d_vel[idx - 20:idx])/20 * clibs.RADIAN)
|
||||||
if av_estop / speed_max < threshold:
|
if av_estop / speed_max < threshold:
|
||||||
self.logger("WARNING", "do_brake-gen_result_file", f"[av_estop: {av_estop:.2f} | shouldbe: {speed_max:.2f}] 处理数据时,本次触发 ESTOP 时未采集到指定百分比的最大速度,即将重试!", "#8A2BE2")
|
self.logger("WARNING", "do_brake", f"[av_estop: {av_estop:.2f} | shouldbe: {speed_max:.2f}] 处理数据时,本次触发 ESTOP 时未采集到指定百分比的最大速度,即将重试!", "#8A2BE2")
|
||||||
clibs.count += 1
|
clibs.count += 1
|
||||||
if clibs.count < 3:
|
if clibs.count < 3:
|
||||||
return "retry"
|
return "retry"
|
||||||
else:
|
else:
|
||||||
clibs.count = 0
|
clibs.count = 0
|
||||||
self.logger("WARNING", "do_brake-gen_result_file",f"尝试三次后仍无法获取正确数据,本次数据无效,继续执行...", "red")
|
self.logger("WARNING", "do_brake",f"尝试三次后仍无法获取正确数据,本次数据无效,继续执行...", "red")
|
||||||
|
|
||||||
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})
|
||||||
@ -140,15 +143,17 @@ class DoBrakeTest(QThread):
|
|||||||
df.to_csv(filename, sep="\t", index=False)
|
df.to_csv(filename, sep="\t", index=False)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@clibs.handle_exception
|
||||||
def change_curve_state(stat):
|
def change_curve_state(stat):
|
||||||
if not stat:
|
if not stat:
|
||||||
display_pdo_params = []
|
display_pdo_params = []
|
||||||
else:
|
else:
|
||||||
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})
|
||||||
clibs.c_hr.execution("diagnosis.open", open=stat, display_open=stat, overrun=True, turn_area=True, delay_motion=False)
|
clibs.c_hr.execution("diagnosis.open", open=stat, display_open=stat)
|
||||||
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params)
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def run_rl(self, config_file, prj_file, result_dirs, avs):
|
def run_rl(self, config_file, prj_file, result_dirs, avs):
|
||||||
count, total, speed_target = 0, 63, 0
|
count, total, speed_target = 0, 63, 0
|
||||||
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
|
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
|
||||||
@ -161,14 +166,14 @@ class DoBrakeTest(QThread):
|
|||||||
io_name = ws.cell(row=6, column=2).value.upper().strip()
|
io_name = ws.cell(row=6, column=2).value.upper().strip()
|
||||||
wb.close()
|
wb.close()
|
||||||
msg = f"基本参数配置:write_diagnosis(废弃) = {write_diagnosis}, get_init_speed = {get_init_speed}, single_brake = {single_brake}, pon = {pon}"
|
msg = f"基本参数配置:write_diagnosis(废弃) = {write_diagnosis}, get_init_speed = {get_init_speed}, single_brake = {single_brake}, pon = {pon}"
|
||||||
self.logger("INFO", "do_brake-run_rl", msg)
|
self.logger("INFO", "do_brake", msg)
|
||||||
|
|
||||||
if pon == "positive":
|
if pon == "positive":
|
||||||
clibs.c_md.write_pon(1)
|
clibs.c_md.write_pon(1)
|
||||||
elif pon == "negative":
|
elif pon == "negative":
|
||||||
clibs.c_md.write_pon(0)
|
clibs.c_md.write_pon(0)
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "do_brake-run_rl", "configs.xlsx 中 Target 页面 B5 单元格填写不正确,检查后重新运行...", "red", "DirectionError")
|
self.logger("ERROR", "do_brake", "configs.xlsx 中 Target 页面 B5 单元格填写不正确,检查后重新运行...", "red", "DirectionError")
|
||||||
|
|
||||||
self.change_curve_state(True)
|
self.change_curve_state(True)
|
||||||
for condition in result_dirs:
|
for condition in result_dirs:
|
||||||
@ -198,7 +203,7 @@ class DoBrakeTest(QThread):
|
|||||||
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"
|
||||||
msg = f"[{this_time} | {count}/{total}] 正在执行 {axis} 轴 {condition} 的第 {_} 次制动测试..."
|
msg = f"[{this_time} | {count}/{total}] 正在执行 {axis} 轴 {condition} 的第 {_} 次制动测试..."
|
||||||
self.logger("INFO", "do_brake-run_rl", msg)
|
self.logger("INFO", "do_brake", msg)
|
||||||
|
|
||||||
# 1. 触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
|
# 1. 触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
|
||||||
clibs.c_md.r_soft_estop(0)
|
clibs.c_md.r_soft_estop(0)
|
||||||
@ -247,7 +252,7 @@ class DoBrakeTest(QThread):
|
|||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if (time.time() - t_start) > 15:
|
if (time.time() - t_start) > 15:
|
||||||
self.logger("ERROR", "do_brake-run_rl", "15s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
self.logger("ERROR", "do_brake", "15s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
||||||
time.sleep(5) # 消除前 5s 的不稳定数据
|
time.sleep(5) # 消除前 5s 的不稳定数据
|
||||||
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()))
|
||||||
@ -257,9 +262,10 @@ class DoBrakeTest(QThread):
|
|||||||
|
|
||||||
# 找出最大速度
|
# 找出最大速度
|
||||||
@clibs.db_lock
|
@clibs.db_lock
|
||||||
|
@clibs.handle_exception
|
||||||
def get_speed_max():
|
def get_speed_max():
|
||||||
_speed_max = 0
|
_speed_max = 0
|
||||||
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 timestamp 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:
|
for record in records:
|
||||||
data = eval(record[0])["data"]
|
data = eval(record[0])["data"]
|
||||||
@ -274,15 +280,14 @@ class DoBrakeTest(QThread):
|
|||||||
|
|
||||||
speed_max = abs(get_speed_max())
|
speed_max = abs(get_speed_max())
|
||||||
speed_target = avs[axis-1] * float(speed) / 100
|
speed_target = avs[axis-1] * float(speed) / 100
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"axis = {axis}, direction = {pon}, max speed = {speed_max}")
|
self.logger("INFO", "do_brake", f"axis = {axis}, direction = {pon}, max speed = {speed_max}")
|
||||||
if speed_max < speed_target*0.95 or speed_max > speed_target*1.05:
|
if speed_max < speed_target*0.95 or speed_max > speed_target*1.05:
|
||||||
self.logger("WARNING", "do_brake-run_rl", f"Axis: {axis}-{count} | 采集获取最大 Speed: {speed_max} | Shouldbe: {speed_target}", "indigo")
|
self.logger("WARNING", "do_brake", f"Axis: {axis}-{count} | 采集获取最大 Speed: {speed_max} | Shouldbe: {speed_target}", "indigo")
|
||||||
clibs.insert_logdb("WARNING", "do_brake", f"Axis: {axis}-{count} | 采集获取最大 Speed: {speed_max} | Shouldbe: {speed_target}")
|
|
||||||
clibs.c_md.write_speed_max(speed_max)
|
clibs.c_md.write_speed_max(speed_max)
|
||||||
|
|
||||||
if speed_max < 10:
|
if speed_max < 10:
|
||||||
clibs.c_md.r_clear_alarm()
|
clibs.c_md.r_clear_alarm()
|
||||||
self.logger("WARNING", "do_brake-run_rl", f"未获取到正确的速度,即将重新获取...", "red")
|
self.logger("WARNING", "do_brake", f"未获取到正确的速度,即将重新获取...", "red")
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
@ -306,7 +311,7 @@ class DoBrakeTest(QThread):
|
|||||||
else:
|
else:
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
if time.time() - t_start > 60:
|
if time.time() - t_start > 60:
|
||||||
self.logger("ERROR", "do_brake-run_rl","60s 内程序未能正常执行,需检查...", "red", "RlProgramStartTimeout")
|
self.logger("ERROR", "do_brake","60s 内程序未能正常执行,需检查...", "red", "RlProgramStartTimeout")
|
||||||
|
|
||||||
for i in range(16):
|
for i in range(16):
|
||||||
if clibs.c_md.read_ready_to_go() == 1:
|
if clibs.c_md.read_ready_to_go() == 1:
|
||||||
@ -315,14 +320,15 @@ class DoBrakeTest(QThread):
|
|||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
else:
|
else:
|
||||||
self.logger("ERROR", "do_brake-run_rl", "16s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
|
self.logger("ERROR", "do_brake", "16s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def exec_brake():
|
def exec_brake():
|
||||||
flag, start, data, record = True, time.time(), None, None
|
flag, start, data, record = True, time.time(), None, None
|
||||||
while flag:
|
while flag:
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
if time.time() - start > 20:
|
if time.time() - start > 20:
|
||||||
self.logger("ERROR", "do_brake-exec_brake", "20s 内未触发急停,需排查......", "red", "BrakeTimeoutError")
|
self.logger("ERROR", "do_brake", "20s 内未触发急停,需排查......", "red", "BrakeTimeoutError")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
clibs.lock.acquire(True)
|
clibs.lock.acquire(True)
|
||||||
@ -340,15 +346,15 @@ class DoBrakeTest(QThread):
|
|||||||
if abs(speed_moment) > speed_max - 2:
|
if abs(speed_moment) > speed_max - 2:
|
||||||
if (pon == "positive" and speed_moment > 0) or (pon == "negative" and speed_moment < 0):
|
if (pon == "positive" and speed_moment > 0) or (pon == "negative" and speed_moment < 0):
|
||||||
clibs.c_ec.setdo_value(io_name, "false")
|
clibs.c_ec.setdo_value(io_name, "false")
|
||||||
time.sleep(2)
|
time.sleep(clibs.INTERVAL*2) # wait speed goes down to 0
|
||||||
flag = False
|
flag = False
|
||||||
break
|
break
|
||||||
return time.time()
|
return time.time()
|
||||||
|
|
||||||
time.sleep(11) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
|
time.sleep(11) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
|
||||||
t_end = exec_brake()
|
end_time = exec_brake()
|
||||||
# 6. 保留数据并处理输出
|
# 6. 保留数据并处理输出
|
||||||
ret = self.gen_result_file(axis, t_end, reach, load, speed, speed_max, rounds)
|
ret = self.gen_result_file(axis, end_time, reach, load, speed, speed_max, rounds)
|
||||||
if ret != "retry":
|
if ret != "retry":
|
||||||
clibs.count = 0
|
clibs.count = 0
|
||||||
break
|
break
|
||||||
@ -356,19 +362,22 @@ class DoBrakeTest(QThread):
|
|||||||
else:
|
else:
|
||||||
time.sleep(50) # why?
|
time.sleep(50) # why?
|
||||||
self.change_curve_state(False)
|
self.change_curve_state(False)
|
||||||
msg = f"\n{self.tool.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行"
|
msg = f"<br>{self.tool.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行"
|
||||||
self.logger("INFO", "do_brake-run_rl", msg, "green")
|
self.logger("INFO", "do_brake", msg, "green")
|
||||||
|
|
||||||
|
@clibs.handle_exception
|
||||||
def processing(self):
|
def processing(self):
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
clibs.running[self.idx] = 1
|
clibs.running[self.idx] = 1
|
||||||
|
if clibs.status["hmi"] != 1 or clibs.status["md"] != 1 or clibs.status["ec"] != 1:
|
||||||
|
self.logger("ERROR", "do_brake", "processing: 需要在网络设置中连接HMI,Modbus通信以及外部通信!", "red", "NetworkError")
|
||||||
|
|
||||||
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
|
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
|
||||||
config_file, prj_file, result_dirs, avs = self.initialization(data_dirs, data_files)
|
config_file, prj_file, result_dirs, avs = self.initialization(data_dirs, data_files)
|
||||||
clibs.c_pd.push_prj_to_server(prj_file)
|
clibs.c_pd.push_prj_to_server(prj_file)
|
||||||
self.run_rl(config_file, prj_file, result_dirs, avs)
|
self.run_rl(config_file, prj_file, result_dirs, avs)
|
||||||
|
|
||||||
self.logger("INFO", "brake-processing", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
self.logger("INFO", "do_brake", "-"*60 + "<br>全部处理完毕<br>", "purple")
|
||||||
time_total = time.time() - time_start
|
time_total = time.time() - time_start
|
||||||
msg = f"处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
|
msg = f"处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s"
|
||||||
self.logger("INFO", "brake-processing", msg)
|
self.logger("INFO", "do_brake", msg)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user