init commit

This commit is contained in:
2025-03-20 18:13:49 +08:00
commit 09d322378a
103 changed files with 12549 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
venv/
.idea/
**/__pycache__/
assets/files/examples/

Binary file not shown.

View File

@ -0,0 +1,842 @@
<?xml version="1.0" encoding="UTF-8"?>
<m>
<l>
<c name="addr" type="2" value="40000"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40000"/>
<c name="function" type="10" value="ctrl_clear_alarm"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_clear_alarm"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40001"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40001"/>
<c name="function" type="10" value="ctrl_estop_reset"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_estop_reset"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40002"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40002"/>
<c name="function" type="10" value="ctrl_estop_reset_clear_alarm"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_onekey_reset"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40003"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40003"/>
<c name="function" type="10" value="ctrl_motor_off"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_motor_off"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40004"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40004"/>
<c name="function" type="10" value="ctrl_motor_on"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_motor_on"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40005"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40005"/>
<c name="function" type="10" value="ctrl_motoron_pptomain_start"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_onekey_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40006"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40006"/>
<c name="function" type="10" value="ctrl_motoron_start"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_motoron_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40007"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40007"/>
<c name="function" type="10" value="ctrl_pause_motoroff"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_pause_motoroff"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40008"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40008"/>
<c name="function" type="10" value="ctrl_pptomain"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_pp2main"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40009"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40009"/>
<c name="function" type="10" value="ctrl_program_start"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_prog_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40010"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40010"/>
<c name="function" type="10" value="ctrl_program_stop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_prog_stop"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40011"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40011"/>
<c name="function" type="10" value="ctrl_reduced_mode"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_reduced_mode"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40012"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40012"/>
<c name="function" type="10" value="ctrl_soft_estop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_soft_estop"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40013"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40013"/>
<c name="function" type="10" value="ctrl_switch_auto_motoron"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_auto_motoron"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40014"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40014"/>
<c name="function" type="10" value="ctrl_switch_operation_auto"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_switch_auto"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40015"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40015"/>
<c name="function" type="10" value="ctrl_switch_operation_manu"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_switch_manual"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40016"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40016"/>
<c name="function" type="10" value="enable_safe_region01"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_safe_region01"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40017"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40017"/>
<c name="function" type="10" value="enable_safe_region02"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_safe_region02"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40018"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40018"/>
<c name="function" type="10" value="enable_safe_region03"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_safe_region03"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40100"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40100"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="act"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40500"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40500"/>
<c name="function" type="10" value="sta_alarm"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_alarm_state"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40501"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40501"/>
<c name="function" type="10" value="sta_collision"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_clsn_alarm_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40502"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40502"/>
<c name="function" type="10" value="sta_collision_open"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_clsn_open_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40503"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40503"/>
<c name="function" type="10" value="sta_controller_is_running"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_controller_running"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40504"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40504"/>
<c name="function" type="10" value="sta_encoder_low_battery"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_encoder_low"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40505"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40505"/>
<c name="function" type="10" value="sta_estop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_estop_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40506"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40506"/>
<c name="function" type="10" value="sta_motor"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_motor_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40507"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40507"/>
<c name="function" type="10" value="sta_operation_mode"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_operation_mode"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40508"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40508"/>
<c name="function" type="10" value="sta_program"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_prog_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40509"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40509"/>
<c name="function" type="10" value="sta_program_not_run"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_prog_not_run"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40510"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40510"/>
<c name="function" type="10" value="sta_program_reset"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_prog_reset"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40511"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40511"/>
<c name="function" type="10" value="sta_reduced_mode"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_reduced_mode_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40512"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40512"/>
<c name="function" type="10" value="sta_robot_is_busy"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_robot_is_busy"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40513"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40513"/>
<c name="function" type="10" value="sta_robot_moving"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_robot_moving"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40514"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40514"/>
<c name="function" type="10" value="sta_safe_door"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_door"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40515"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40515"/>
<c name="function" type="10" value="sta_safe_region01"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_region01"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40516"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40516"/>
<c name="function" type="10" value="sta_safe_region02"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_region02"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40517"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40517"/>
<c name="function" type="10" value="sta_safe_region03"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_region03"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40518"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40518"/>
<c name="function" type="10" value="sta_soft_estop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_soft_estop_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40600"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40600"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="ready_to_go"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40601"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40602"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="scenario_time"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="float"/>
<c name="value"/>
<c name="value_single" type="10" value="0"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40603"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40603"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="capture_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
</l>
</m>

Binary file not shown.

View File

@ -0,0 +1,75 @@
{
"device_list": [
{
"enable": true,
"endian": 1,
"extend_attr": {
"RTU": {
"serial_name": ""
},
"TCP": {
"ip": "0.0.0.0",
"port": 502
},
"coils": {
"max_num": 16,
"start_addr": 0
},
"discrete_input": {
"max_num": 16,
"start_addr": 0
},
"hold_register": {
"max_num": 2000,
"start_addr": 40000
},
"input_register": {
"max_num": 2000,
"start_addr": 4000
},
"protol_type": "TCP",
"slaver_id": 1
},
"mode": "slaver",
"name": "autotest",
"type": "MODBUS"
}
],
"support_types": [
{
"device_type": "MODBUS",
"support_mode": {
"master": 10,
"slaver": 10
}
},
{
"device_type": "CCLINK",
"support_mode": {
"master": 0,
"slaver": 1
}
},
{
"device_type": "ETHERCAT",
"support_mode": {
"master": 0,
"slaver": 10
}
},
{
"device_type": "PROFINET",
"support_mode": {
"master": 0,
"slaver": 1
}
},
{
"device_type": "EtherNetIP",
"support_mode": {
"master": 0,
"slaver": 1
}
}
]
}

View File

@ -0,0 +1,520 @@
{
"MODBUS": [
{
"property": {
"device_name": "autotest",
"endian": 1
},
"regs": {
"rd": [
{
"addr": 40000,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_clear_alarm",
"len": 1,
"name": "r_clear_alarm",
"retain": false,
"type": "bool"
},
{
"addr": 40001,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_estop_reset",
"len": 1,
"name": "r_estop_reset",
"retain": false,
"type": "bool"
},
{
"addr": 40002,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_estop_reset_clear_alarm",
"len": 1,
"name": "r_onekey_reset",
"retain": false,
"type": "bool"
},
{
"addr": 40003,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_motor_off",
"len": 1,
"name": "r_motor_off",
"retain": false,
"type": "bool"
},
{
"addr": 40004,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_motor_on",
"len": 1,
"name": "r_motor_on",
"retain": false,
"type": "bool"
},
{
"addr": 40005,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_motoron_pptomain_start",
"len": 1,
"name": "r_onekey_start",
"retain": false,
"type": "bool"
},
{
"addr": 40006,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_motoron_start",
"len": 1,
"name": "r_motoron_start",
"retain": false,
"type": "bool"
},
{
"addr": 40007,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_pause_motoroff",
"len": 1,
"name": "r_pause_motoroff",
"retain": false,
"type": "bool"
},
{
"addr": 40008,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_pptomain",
"len": 1,
"name": "r_pp2main",
"retain": false,
"type": "bool"
},
{
"addr": 40009,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_program_start",
"len": 1,
"name": "r_prog_start",
"retain": false,
"type": "bool"
},
{
"addr": 40010,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_program_stop",
"len": 1,
"name": "r_prog_stop",
"retain": false,
"type": "bool"
},
{
"addr": 40011,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_reduced_mode",
"len": 1,
"name": "r_reduced_mode",
"retain": false,
"type": "bool"
},
{
"addr": 40012,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_soft_estop",
"len": 1,
"name": "r_soft_estop",
"retain": false,
"type": "bool"
},
{
"addr": 40013,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_switch_auto_motoron",
"len": 1,
"name": "r_auto_motoron",
"retain": false,
"type": "bool"
},
{
"addr": 40014,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_switch_operation_auto",
"len": 1,
"name": "r_switch_auto",
"retain": false,
"type": "bool"
},
{
"addr": 40015,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "ctrl_switch_operation_manu",
"len": 1,
"name": "r_switch_manual",
"retain": false,
"type": "bool"
},
{
"addr": 40016,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "enable_safe_region01",
"len": 1,
"name": "r_safe_region01",
"retain": false,
"type": "bool"
},
{
"addr": 40017,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "enable_safe_region02",
"len": 1,
"name": "r_safe_region02",
"retain": false,
"type": "bool"
},
{
"addr": 40018,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "enable_safe_region03",
"len": 1,
"name": "r_safe_region03",
"retain": false,
"type": "bool"
},
{
"addr": 40100,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "act",
"retain": false,
"type": "bool"
}
],
"rdwr": [
{
"addr": 40500,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_alarm",
"len": 1,
"name": "w_alarm_state",
"retain": false,
"type": "bool"
},
{
"addr": 40501,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_collision",
"len": 1,
"name": "w_clsn_alarm_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40502,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_collision_open",
"len": 1,
"name": "w_clsn_open_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40503,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_controller_is_running",
"len": 1,
"name": "w_controller_running",
"retain": false,
"type": "bool"
},
{
"addr": 40504,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_encoder_low_battery",
"len": 1,
"name": "w_encoder_low",
"retain": false,
"type": "bool"
},
{
"addr": 40505,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_estop",
"len": 1,
"name": "w_estop_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40506,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_motor",
"len": 1,
"name": "w_motor_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40507,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_operation_mode",
"len": 1,
"name": "w_operation_mode",
"retain": false,
"type": "bool"
},
{
"addr": 40508,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_program",
"len": 1,
"name": "w_prog_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40509,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_program_not_run",
"len": 1,
"name": "w_prog_not_run",
"retain": false,
"type": "bool"
},
{
"addr": 40510,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_program_reset",
"len": 1,
"name": "w_prog_reset",
"retain": false,
"type": "bool"
},
{
"addr": 40511,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_reduced_mode",
"len": 1,
"name": "w_reduced_mode_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40512,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_robot_is_busy",
"len": 1,
"name": "w_robot_is_busy",
"retain": false,
"type": "bool"
},
{
"addr": 40513,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_robot_moving",
"len": 1,
"name": "w_robot_moving",
"retain": false,
"type": "bool"
},
{
"addr": 40514,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_safe_door",
"len": 1,
"name": "w_safe_door",
"retain": false,
"type": "bool"
},
{
"addr": 40515,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_safe_region01",
"len": 1,
"name": "w_safe_region01",
"retain": false,
"type": "bool"
},
{
"addr": 40516,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_safe_region02",
"len": 1,
"name": "w_safe_region02",
"retain": false,
"type": "bool"
},
{
"addr": 40517,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_safe_region03",
"len": 1,
"name": "w_safe_region03",
"retain": false,
"type": "bool"
},
{
"addr": 40518,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "sta_soft_estop",
"len": 1,
"name": "w_soft_estop_stat",
"retain": false,
"type": "bool"
},
{
"addr": 40600,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "ready_to_go",
"retain": false,
"type": "bool"
},
{
"addr": 40601,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "scenario_time",
"retain": false,
"type": "float"
},
{
"addr": 40603,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "capture_start",
"retain": false,
"type": "bool"
}
]
}
}
]
}

View File

@ -0,0 +1,843 @@
<?xml version="1.0" encoding="UTF-8"?>
<m>
<l>
<c name="addr" type="2" value="40000"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40000"/>
<c name="function" type="10" value="ctrl_clear_alarm"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_clear_alarm"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40001"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40001"/>
<c name="function" type="10" value="ctrl_estop_reset"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_estop_reset"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40002"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40002"/>
<c name="function" type="10" value="ctrl_estop_reset_clear_alarm"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_onekey_reset"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40003"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40003"/>
<c name="function" type="10" value="ctrl_motor_off"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_motor_off"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40004"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40004"/>
<c name="function" type="10" value="ctrl_motor_on"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_motor_on"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40005"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40005"/>
<c name="function" type="10" value="ctrl_motoron_pptomain_start"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_onekey_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40006"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40006"/>
<c name="function" type="10" value="ctrl_motoron_start"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_motoron_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40007"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40007"/>
<c name="function" type="10" value="ctrl_pause_motoroff"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_pause_motoroff"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40008"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40008"/>
<c name="function" type="10" value="ctrl_pptomain"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_pp2main"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40009"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40009"/>
<c name="function" type="10" value="ctrl_program_start"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_prog_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40010"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40010"/>
<c name="function" type="10" value="ctrl_program_stop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_prog_stop"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40011"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40011"/>
<c name="function" type="10" value="ctrl_reduced_mode"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_reduced_mode"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40012"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40012"/>
<c name="function" type="10" value="ctrl_soft_estop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_soft_estop"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40013"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40013"/>
<c name="function" type="10" value="ctrl_switch_auto_motoron"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_auto_motoron"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40014"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40014"/>
<c name="function" type="10" value="ctrl_switch_operation_auto"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_switch_auto"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40015"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40015"/>
<c name="function" type="10" value="ctrl_switch_operation_manu"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_switch_manual"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40016"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40016"/>
<c name="function" type="10" value="enable_safe_region01"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_safe_region01"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40017"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40017"/>
<c name="function" type="10" value="enable_safe_region02"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_safe_region02"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40018"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40018"/>
<c name="function" type="10" value="enable_safe_region03"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="r_safe_region03"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40100"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40100"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="act"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40500"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40500"/>
<c name="function" type="10" value="sta_alarm"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_alarm_state"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40501"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40501"/>
<c name="function" type="10" value="sta_collision"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_clsn_alarm_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40502"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40502"/>
<c name="function" type="10" value="sta_collision_open"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_clsn_open_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40503"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40503"/>
<c name="function" type="10" value="sta_controller_is_running"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_controller_running"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40504"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40504"/>
<c name="function" type="10" value="sta_encoder_low_battery"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_encoder_low"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40505"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40505"/>
<c name="function" type="10" value="sta_estop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_estop_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40506"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40506"/>
<c name="function" type="10" value="sta_motor"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_motor_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40507"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40507"/>
<c name="function" type="10" value="sta_operation_mode"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_operation_mode"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40508"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40508"/>
<c name="function" type="10" value="sta_program"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_prog_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40509"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40509"/>
<c name="function" type="10" value="sta_program_not_run"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_prog_not_run"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="true"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40510"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40510"/>
<c name="function" type="10" value="sta_program_reset"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_prog_reset"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40511"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40511"/>
<c name="function" type="10" value="sta_reduced_mode"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_reduced_mode_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40512"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40512"/>
<c name="function" type="10" value="sta_robot_is_busy"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_robot_is_busy"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40513"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40513"/>
<c name="function" type="10" value="sta_robot_moving"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_robot_moving"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40514"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40514"/>
<c name="function" type="10" value="sta_safe_door"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_door"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40515"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40515"/>
<c name="function" type="10" value="sta_safe_region01"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_region01"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40516"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40516"/>
<c name="function" type="10" value="sta_safe_region02"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_region02"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40517"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40517"/>
<c name="function" type="10" value="sta_safe_region03"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_safe_region03"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40518"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40518"/>
<c name="function" type="10" value="sta_soft_estop"/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="w_soft_estop_stat"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40600"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40600"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="ready_to_go"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40601"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40602"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="scenario_time"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="float"/>
<c name="value"/>
<c name="value_single" type="10" value="0"/>
<c name="bias" type="2" value="0"/>
</l>
<l>
<c name="addr" type="2" value="40603"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40603"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="capture_start"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rdwr"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value="false"/>
<c name="bias" type="2" value="0"/>
</l>
</m>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "robot",
"command": "diagnosis.get_params",
"data": {
"version": "1.4.1"
}
}

View File

@ -0,0 +1,12 @@
{
"id": "xxxxxxxxxxx",
"module": "robot",
"command": "diagnosis.open",
"data": {
"open": false,
"display_open": false,
"overrun": false,
"turn_area": false,
"delay_motion": false
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "robot",
"command": "diagnosis.save",
"data": {
"save": true
}
}

View File

@ -0,0 +1,10 @@
{
"id": "xxxxxxxxxxx",
"module": "robot",
"command": "diagnosis.set_params",
"data": {
"display_pdo_params": [],
"frequency": 50,
"version": "1.4.1"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "overview.get_autoload"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "overview.get_cur_prj"
}

View File

@ -0,0 +1,9 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "overview.reload",
"data": {
"prj_path": "",
"tasks": []
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "overview.set_autoload",
"data": {
"autoload_prj_path": ""
}
}

View File

@ -0,0 +1,11 @@
{
"id": "xxxxxxxxxxx",
"module": "fieldbus",
"command": "register.set_value",
"data": {
"name": "",
"type": "bool",
"bias": 0,
"value": 0
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "rl_task.pp_to_main",
"data": {
"tasks": []
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "rl_task.run",
"data": {
"tasks": []
}
}

View File

@ -0,0 +1,9 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "rl_task.set_run_params",
"data": {
"loop_mode": true,
"override": 1.0
}
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "project",
"command": "rl_task.stop",
"data": {
"tasks": []
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.get_state"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.get_tp_mode"
}

View File

@ -0,0 +1,8 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.set_tp_mode",
"data": {
"tp_mode": "with"
}
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.switch_auto"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.switch_manual"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.switch_motor_off"
}

View File

@ -0,0 +1,5 @@
{
"id": "xxxxxxxxxxx",
"module": "system",
"command": "state.switch_motor_on"
}

View File

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

View File

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

View File

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

Binary file not shown.

View File

@ -0,0 +1,56 @@
b'\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340\x01o429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17\n\t\t\t]\n\t\t}\n\t],\n\t"module" : "robot"\n}\x04\x00\x00\x00-h\x02\x00{\n\t"command" : "diagnosis.result",\n\t"data" : \n\t[\n\t\t{\n\t\t\t"channel" : 0,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0'
b'.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 1,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t6.7411265092630715e-06,\n\t\t\t\t0.00049929277011941824,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0027270103772138884,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t0.00012044146029883355,\n\t\t\t\t-0.0022272681986605192,\n\t\t\t\t-0.0027270103772138884,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t-0.0027270103772138884,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t1.3482253018526145e-06,\n\t\t\t\t-0.002697798\x04\x008290070812,\n\t\t\t\t0.00050648330506263212,\n\t\t\t\t-0.0,\n\t\t\t\t0.0020753681479851243,\n\t\t\t\t2.8762139772855775e-05,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t3.5952674716069715e-05,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t0.0001496530085056402,\n\t\t\t\t0.0001276319952420475,\n\t\t\t\t-0.0027252127434780845,\n\t\t\t\t6.7411265092630715e-06,\n\t\t\t\t-0.0026977988290070812,\n\t\t\t\t8.5387602450665581e-06,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t0.00206862702147'
b'58614,\n\t\t\t\t-0.0,\n\t\t\t\t7.1905349432139438e-06,\n\t\t\t\t1.3482253018526145e-06,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t2.8762139772855775e-05,\n\t\t\t\t-0.0,\n\t\t\t\t6.7411265092630715e-06,\n\t\t\t\t-0.0,\n\t\t\t\t0.00049929277011941824,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 2,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t1.1984224905356572e-06,\n\t\t\t\t0.00010705907582118537,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0024236097500266104,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0024240092241901226,\n\t\t\x04\x00\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t0.0018387795746452099,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t0.00010705907582118537,\n\t\t\t\t-0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 3,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t'
b'-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.00021840051467521813,\n\t\t\t\t-0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 4,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t-0.0,\n\t\t\t\t-0.0\x04\x00,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n'
b'\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 5,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-\x04\x000.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 0,\n\t\t\t"name" : "device_servo_trq_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t'
b'\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 1,\n\t\t\t"name" : "device_servo_trq_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0\x04\x00.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 2,\n\t\t\t"name" : "device_servo_trq_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.'
b'0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 3,\n\t\t\t"name" : "device_servo_trq_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\x04\x00\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 4,\n\t\t\t"name" : "device_servo_trq_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n'
b'\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 5,\n\t\t\t"name" : "device_servo_trq_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.\x04\x000,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 0,\n\t\t\t"name" : "device_safety_estop",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n'
b'\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 1,\n\t\t\t"name" : "device_safety_estop",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1\x04\x00.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 2,\n\t\t\t"name" : "device_safety_estop",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.'
b'0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 3,\n\t\t\t"name" : "device_safety_estop",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t\x04\x001.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0,\n\t\t\t\t1.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 4,\n\t\t\t"name" : "device_safety_estop",\n\t\t\t"value" : '
b'\n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 5,\n\t\t\t"name" : "device_safety_estop",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5\x04\x00.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429'
b'065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.55163404\x01n29065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17\n\t\t\t]\n\t\t}\n\t],\n\t"module" : "robot"\n}\x04\x00\x00\x00-\x8f\x02\x00{\n\t"command"'
> - 封包解包顺序:帧长度二字节/包长度四字节/协议二字节/预留二字节,\x04\x00:\x00\x00\tR:\x02:\x00
> - 帧长度和包长度没有必然关系单帧的时候是帧长度减去包长度等于6包长度指的是所有内容的长度
> - HMI内部每次发送1024个字节进行分包有效内容长度规则是第一帧 frm_value-6(帧大小减去包头长度),第二帧(包含)及之后的帧,帧大小即是数据长度
==================================================================================================
单包多帧示例
\x04\x00\x00\x00-h\x02\x00
frm_value = int.from_bytes(b"\x04\x00") = 1024 | 每次发送的帧的报文总长度,包括包头(如果有),但不包括帧头
pkg_value = int.from_bytes(b"\x00\x00-h") = 11624 | 包长度是不包括所有的帧和包报文头的,单包单帧的情况也是一样的
pkg_size = 6 字节
有效数据长度 = 10240 + 402 + 1004 - 20 - 2(首个帧头) = 11624
有效数据长度+包报文头 = 11624 + 6 = 11630
有效数据长度+包报文头+帧报文头 = 11624 + 6 + 22 = 11652
首帧长度 1018=frm_value-pkg_size=1024-6如下是第一帧和第二帧的拼接
b'{\n\t"command" : "diagnosis.result",\n\t"data" : \n\t[\n\t\t{\n\t\t\t"channel" : 0,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 1,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t6.7411265092630715e-06,\n\t\t\t\t0.00049929277011941824,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0027270103772138884,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t0.00012044146029883355,\n\t\t\t\t-0.0022272681986605192,\n\t\t\t\t-0.0027270103772138884,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t-0.0027270103772138884,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t1.3482253018526145e-06,\n\t\t\t\t-0.002697798'
单帧长度 1024如下是第二帧和第三帧的拼接
b'8290070812,\n\t\t\t\t0.00050648330506263212,\n\t\t\t\t-0.0,\n\t\t\t\t0.0020753681479851243,\n\t\t\t\t2.8762139772855775e-05,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t3.5952674716069715e-05,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t0.0001496530085056402,\n\t\t\t\t0.0001276319952420475,\n\t\t\t\t-0.0027252127434780845,\n\t\t\t\t6.7411265092630715e-06,\n\t\t\t\t-0.0026977988290070812,\n\t\t\t\t8.5387602450665581e-06,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t0.0020686270214758614,\n\t\t\t\t-0.0,\n\t\t\t\t7.1905349432139438e-06,\n\t\t\t\t1.3482253018526145e-06,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t2.8762139772855775e-05,\n\t\t\t\t-0.0,\n\t\t\t\t6.7411265092630715e-06,\n\t\t\t\t-0.0,\n\t\t\t\t0.00049929277011941824,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"channel" : 2,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t1.1984224905356572e-06,\n\t\t\t\t0.00010705907582118537,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0024236097500266104,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0,\n\t\t\t\t-0.0024240092241901226,\n\t\t'
---------------------------------------------------------------------------------------------------
第一帧有效 - 402
b'{\n\t"command" : "diagnosis.result",\n\t"data" : \n\t[\n\t\t{\n\t\t\t"channel" : 0,\n\t\t\t"name" : "hw_joint_vel_feedback",\n\t\t\t"value" : \n\t\t\t[\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0.0,\n\t\t\t\t0'
---------------------------------------------------------------------------------------------------
中间有 10 帧,共计 10240 个字节,也有 10 个 \x04\x00共计 20 个字节
---------------------------------------------------------------------------------------------------
最后一帧有效 - 1004
b'065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.55163404\x01n29065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17,\n\t\t\t\t-5.5516340429065717e-17\n\t\t\t]\n\t\t}\n\t],\n\t"module" : "robot"\n}'
---------------------------------------------------------------------------------------------------
==================================================================================================
单包单帧示例
\x00\\\x00\x00\x00V\x02\x00
frm_value = int.from_bytes(b"\x00\\") = 92 | 每次发送的帧的报文总长度,包括包头(如果有),但不包括帧头
pkg_value = int.from_bytes(b"\x00\x00\x00V") = 86 | 包长度是不包括所有的帧和包报文头的,单包单帧的情况也是一样的
pkg_size = 6
有效数据长度 = 86
有效数据长度+包报文头 = 86 + 6 = 92
有效数据长度+包报文头+帧报文头 = 86 + 6 +2 = 94
帧长度 86=frm_value-pkg_size=92-6
b'\x00\\\x00\x00\x00V\x02\x00{\n\t"data" : \n\t{\n\t\t"name" : "xCore"\n\t},\n\t"id" : "controller.heart-1719734550.9790015"\n}'

View File

@ -0,0 +1,43 @@
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(0, 3, 1, 6),
prodvers=(0, 3, 1, 6),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x4,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
'040904b0',
[StringStruct('CompanyName', 'Rokae - https://www.rokae.com/'),
StringStruct('FileDescription', 'All in one automatic toolbox'),
StringStruct('FileVersion', '0.3.1.6 (2025-03-21)'),
StringStruct('InternalName', 'AIO.exe'),
StringStruct('LegalCopyright', '© 2024-2025 Manford Fan'),
StringStruct('OriginalFilename', 'AIO.exe'),
StringStruct('ProductName', 'AIO'),
StringStruct('ProductVersion', '0.3.1.6 (2025-03-21)')])
]),
VarFileInfo([VarStruct('Translation', [1033, 1200])])
]
)

View File

@ -0,0 +1,490 @@
v0.0.1(2024/05/18)
Draft
v0.0.2(2024/05/20)
1. 功能模块化,为后面其他功能奠定一个基本的框架
2. 使用了多线程提高效率
3. 优化了准备工作中的细节
4. 运行初始化时自动删除 raw_data_dir 中的 .xlsx 文件
5. 优化了输出格式
6. 使用 pyinstaller 库进行代码冻结并调试成功
v0.0.3(2024/05/21)
1. just_open函数打开失败的信息中添加文件名
2. 删除global变量函数全部通过传参实现
3. configuration.xlsx配置文件增加AXIS常量表示那个轴取值为 j1/j2/j3/j4/j5/j6/j7
4. [bugfix] 增加get_threshold_step函数用来获取在计算row_start时合适的阈值和步长主要是解决了二轴最差工况下最大速度是个尖端的问题
a. load100_speed100_reachxxx 二轴 threshold = 50 step = 20
b. 其他 threshold = 50 step = 100
如上是一个比较保守的设定因为设定的step比较小找到点之后要往后延200最好
5. 在find_row_start_dp函数中新增一个参数data_file方便后续调试
v0.0.4(2024/05/22)
1. 重新标定了get_threshold_step函数让处理更加准确
2. 新定义了now_doing_msg函数实时输出处理信息
3. 修改了find_row_start和find_row_start_dp函数增加的部分相同处理数据的时候先判断是否是空值或者是0此时可以加快步进
4. 修改了just_open函数不在做重试
v0.0.5(2024/05/23)
1. 完善了函数注释
2. 调整了阈值和步长
3. 删除了just_open函数以及对应的win32com库Thank GOD!终于可以不用这个库了)
4. 重写了获取开始点位的代码直接使用speed来判断而不用角度所以find_row_start_dp以及copy_data_to_excel_file函数也被一并删除
5. 修改了配置文件configs.xlsx的初始参数顺序及结构使程序通用性更强
6. 将initialazation中的预定义变量赋值调整到try...except...之外,更方便排查问题
7. 修改结束时间的格式,精确到秒
v0.0.6(2024/05/23)
1. 为了调整多功能框架aio.py文件将会作为入口程序存在不实现具体功能功能的实现将由具体的功能脚本实现aio.py只负责条件调用
2. 新增了自动化处理电流数据(电机/过载)的功能
v0.1.0(2024/05/29)
1. 修改为customtkinter图形化界面
2. 支持工业机器人制动数据处理(理论上支持,测试数据有问题,待验证)
3. 删除configs.xlsx配置表格直接在界面配置新增layout.xlsx文件存储customtkinter布局
4. 电流尚未支持
v0.1.1(2024/05/30)
1. 增加版本检测功能
2. 修改了无效数据下的动作
3. textbox只在开始和结束时改变状态而不是每次写入都更改
4. 调整了brake的结构
5. 重新在write2textbox中添加exitcode参数并补齐相关逻辑和修改brake中的调用方式
6. 修复参数检查无效的情况
7. 屏蔽电流相关的功能
v0.1.2(2024/06/01)
1. 增加iso数据处理功能
2. 重新修改了README.md
3. 单独将rokae拉出来作为一个独立的repo进行维护与scripts分离
v0.1.3(2024/06/01)
1. 完成电流处理的基本功能
2. 修复了一些已知bugs
v0.1.4(2024/06/06)
1. AV/RR支持小数
2. 可处理电机电流单轴以及多轴数据,可根据需要进行参数设定处理不同轴的数据
3. 界面初始位置修改以及删除所有entry的长度设定因为设定无效
4. 修改了layout.xlsx布局增加了duration/trqH/STO字段以及额外的RC行整体扩展了区域
5. 更改label/entry/optionmenu等控件的生成方式使用循环实现更加简洁和容易维护暂未实现
6. 支持工业/协作两条产品线的电机电流数据处理包括单轴场景max/avg计算
v0.1.5(2024/06/12)
1. [aio.py] 主界面切换不同功能时保持placehold一致
2. [brake.py] 由于制动采集模板和内容的更改,适配了新的数据,更新了算法
3. [aio.py] 新增tabview组件区分数据处理和自动化测试功能
4. [aio.py] 重新调整界面配色
5. [aio.py] 修改了write2textbox函数定制化显示每一行的颜色针对每一行可自定义输出内容颜色
6. [brake.py/iso.py/current.py] 由于第 5 点的更改,同时修改了其他文件相关引用的部分
7. [aio.py] 更改label/entry/optionmenu等控件的生成方式使用循环实现更加简洁和容易维护
8. [aio.py] 修改customtkinter库中C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\customtkinter\windows\widgets\ctk_tabview.py文件参考https://github.com/TomSchimansky/CustomTkinter/issues/2296实现修改tabview组件的字体大小
9. [aio.py] 修改menu_main->menu_main_dpmenu_sub->menu_sub_dp为后续其他tab功能按钮做扩展是针对第三点做出的相应调整
10. [layout.xlsx] 添加了各个功能的流程图
v0.1.5.1(2024/06/12)
1. [current.py] 修改cycle功能中数据清理范围为70000行并将threshold从2调整为5
2. [current.py] 修改位置超限提示,使更清楚了解问题原因
3. [current.py] 修改find_point函数中错误提示增加定位信息
4. [README.md] 精简打包命令
5. [requirements.txt] 新增必要库配置文件
v0.1.5.2(2024/06/13)
1. [brake.py/aio.py] 将sto修改为estop
2. [brake.py] 修改了速度计算逻辑新版本的vel列数据遵循如下规则av = vel * 180 / pi根据av再计算speed
3. [brake.py] 将threshold修改为常量50
4. [brake.py] 提高了输出提示语的明确性,删除了不必要的省略号
5. [brake.py] 更正了之前的数据copy错误重新优化了estop处是否达到指定百分比的判定逻辑
v0.1.5.3(2024/06/14)
1. [aio.py] 修改w_param为84适配14寸电脑屏幕
2. [brake.py] 将判定合规逻辑修改为角速度超过指定角速度的95%
3. [README.md] 稍作修改,包括打包方式,功能特性等
v0.1.6.0(2024/06/15)
1. [aio.py] 新增wavelogger处理界面
2. [wavelogger.py] 新增精度数据处理模块
v0.1.6.1(2024/06/16)
1. [wavelogger.py] bugfix single_file_proc函数中修改_start起始点的计算逻辑
2. [wavelogger.py] bugfix find_point函数中当判断条件为临界值 2.0 的时候针对forward和backward两种情况对row_target做与判断逻辑相同的处理目的是避免形成死循环
v0.1.6.2(2024/06/16)
1. [current.py] 修改了max/avg相关功能中对于返回值的处理逻辑并在输出框以行的形式打印出来
v0.1.6.3(2024/06/18)
1. [current.py] 适配电机电流中速度使用hw_joint_vel_feedback的数据取消对device_servo_vel_feedback的支持后续所有涉及到速度相关的数据均已前者为准现已完成对单轴和场景的适配
> WARNING目前版本的电机电流程序还支持DriverMaster采集的数据处理等明确后将不再支持也即所有的电机电流数据工业+协作),都是用诊断曲线来采集
v0.1.7.0(2024/06/19)-未发布
1. [openapi.py] 初步搭建起框架,完成了新老协议的封包/解包/异步采集日志的操作(未充分测试,但基本无问题)
2. [openapi.py] 修改了封包的规则,使之更加明晰,封包操作没有实现分包功能,目前看实际场景用不到
v0.1.7.0(2024/06/21)-未发布
1. [openapi.py] 定义 MAX_FRAME_SIZE 常量1024替换socket接收以及响应数据处理相关部分
2. [openapi.py] 使用 int.to_bytes 和 int.from_bytes 替换 binascii 模块的功能
3. [aio.py] 修改了Data Process中初始化的动作使得初始化时的状态统一成程序刚启动时的样子
v0.1.7.0(2024/06/23)-未发布
1. [aio.py] 增加了tabview的点击行为函数每次点击tab都会初始化
2. [aio.py] 增加了Automatic Test界面元素包括如下并完成了功能框架的搭建
- 标签:文件/角速度/减速比
- 按钮:急停及恢复
- 输入框:文件路径/角速度/减速比
- OptionMenu负载
- 进度条
3. [openapi.py] 增加心跳检测函数,并开启线程执行;取消在该文件中生成实例
4. [aio.py] 完成detect_network并在main函数开启线程
5. 将templates文件夹移动到assets内
v0.1.7.0(2024/06/24)-未发布
1. [openapi.py] 建联部分做容错逻辑,并将读写文件做自适应处理
2. [aio.py] 将读写文件做自适应处理引入openapi模块并生成实例做心跳检测将socket超时时间修改为3s
v0.1.7.0(2024/06/25)-未发布
1. [aio.py] 取消了在本文件中开启openapi线程的做法并修改如下
- 通过包的方式导入其他模块
- 使用current_path来规避文件路径问题
- 声名了 self.hr 变量用来接收openapi的实例化
- 修改了对于segment button的错误调用
- 设定progress bar的长度是10
- 完善了segmented_button_callback函数
- 在detect_network函数中增加heartbeat初始化
- tabview_click函数中新增textbox清屏功能以及实例化openapi并做检测
2. [openapi.py] 取消了初始化中无限循环检测因为阻塞了aio主界面进程socket也无法多次连接浪费了好多时间很生气
- 通过tabview切换来实现重新连接并保留了异常处理部分
- 将所有的 __xxxx 函数都替换成 xxxx 函数,去掉了 __
- 使用current_path来规避文件路径问题
3. [do_brake.py] 初步完成了机器状态收集的功能,还需要完善
- 使用current_path来规避文件路径问题
- 新增validate_resp函数校验数据
- 完善了调用接口
> **关于HMI接口**
> - 封包解包顺序:帧长度二字节/包长度四字节/协议二字节/预留二字节,\x04\x00:\x00\x00\tR:\x02:\x00
> - 帧长度和包长度没有必然关系单帧的时候是帧长度减去包长度等于6包长度指的是所有内容的长度
> - HMI内部每次发送1024个字节进行分包内容长度规则是第一帧1024-6=1018(帧大小减去包头长度),第二帧(包含)及之后的帧,帧长度即是数据长度
v0.1.7.0(2024/06/26)-初步可用
1. [aio.py] 在detect_network函数中需改查询时间间隔是1s在tabview_click中增加textbox配置normal的语句
2. [do_brake.py -> btn_functions.py] 新增执行相应函数并在get_state函数中设置无示教器模式
3. [openapi.py] 新增sock_conn函数并做连接时的异常处理新增类参数w2t
4. [aio.py] 修改customtkinter库中C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\customtkinter\windows\widgets\ctk_tabview.py文件参考https://github.com/TomSchimansky/CustomTkinter/issues/2296实现修改tabview组件的字体大小使用原生字体同时将segmented button字体修改为原生为了解决segmented button在禁用和启用时屏幕抖动的问题并将大小修改为16
5. [aio.py] 修改了segmented_button_callback的实现逻辑使代码更简洁
6. [aio.py] 修改了在tabview_click函数中对于实例化HmiRequest的动作使每次切换标签都会重新实例化也就是每次都会重新连接修复显示不正确的问题
7. [openapi.py] 新增了socket关闭的函数并增加msg_id为None的处理逻辑
8. [btn_functions.py] 完善了状态获取的功能,新增告警获取以及功能切换的逻辑
9. [aio.py] 修改了版本
10. [current.py] max/avg功能结束之前会将结果数据追加写入源文件avg算法更改为average+3×std
11. [wavelogger.py] 算法更改为 average+3×std
v0.1.7.1.0(2024/06/29)
1. [APIs: aio.py]
- 对于automatic test删除了输入框使用configs.xlsx配置文件作为参数输入
- 完善initialization/param_check/func_start_callback函数中对于automatic test的处理
- 将textbox组件一直设置为normal状态不再频繁切换disabled
- 将所有的f_h文件对象修改为f_hb并将connection_state修改为c_state
- 在detect_network函数中实例化HmiRequest并在无限循环中检测心跳是否正常如异常则销毁hr重新生成
- 取消在tabview切换时检测心跳的逻辑这样做无法保证实时性
2. [APIs: openapi.py]
- 将sock_conn函数移出__init__单独作为连接函数存在
- 新增全局变量self.t_bool控制所有的线程中无限循环的启停也就是可以人为的退出线程
- 移除close_sock函数
- heartbeat函数中新增打印所有消息的代码调试时打开平常关闭
- execution函数中新增对overview.set_autoload和overview.reload的支持
- execution函数中对send动作增加异常处理逻辑
3. [APIs: do_brake.py]
- 新增文件处理制动测试流程建立连接导入projectpp2mainrun采集并处理曲线数据本地修改RL程序推送至控制器等
- 目前完成:
- 文件合规性检查
- 导入工程并设置为运行工程
4. [APIs: current.py] 修改scenario/single电机电流最大长度为150s
5. 在本文件中更新关于制动自动化测试的相关内容
6. [t_change_ui: aio.py/brake.py/current.py] 整体修改了操作界面,删除了大部分的配置输入框,改用 configs.xlsx 配置文件替代并优化了max/avg功能中写入结果数据的方式
v0.1.7.1.1(2024/06/29)
1. [APIs: aio.py]
- 修改detect_network函数中sleep语句放到最后重新生成HmiRequest实例中增加sleep(4)这个停顿时间一定是比openapi中heartbeat函数的sleep要长1s以上才能正常工作
- 修改write2textbox函数新增默认参数tab_name只有当该值与当前tab一致时函数才会有输出
- 第二条改动影响到了automatic_test文件夹下所有的文件
2. [APIs: openapi.py]
- 规定了所有的网络异常均由heartbeat函数来定义其他异常不做中断处理
- execution函数中合并了case条件
- 增加了N多指令多为诊断曲线和rl程序相关
- 日志保留条数修改为20000
3. [APIs: do_brake.py]
- 实现自动推送工程到xCore并自动运行
- 初步实现了Modbus发送消息和检测状态
4. [APIs: do_current.py]
- 将do_brake.py的内容完全拷贝到此文件待修改
v0.1.7.2(2024/06/30)
1. 初步完成NB4h_R580_3BH7.zip工程的设计
2. 重新研究了解包操作,重新实现了一版
3. 修改openapi.pi中excution为execution函数
4. 增加了解包原理性文档
v0.1.7.3(2024/07/01)
1. [APIs: openapi.py]
- 继续完善封包解包操作并优化了所有调试信息默认打开状态直到bug数量明显减少
- 修复了两个bug删除了一个多余的break另一个是补齐了self.broke的重置
2. [APIs: do_current.py] 使用原工程的工程名进行move操作语义更加明确
> 目前看openapi.py封包解包没有任何问题了但是所有的调试信息都默认打开以便可以第一时间保留现场
> 打开诊断跑了10多分钟共计解包没有报错应该是没有问题了
v0.1.7.4(2024/07/02)
1. [APIs: openapi.py]
- 增加了modbus的python实现
- heartbeat函数修改发送间隔为1s
- 清除了绝大部分调试性输出,发现太多的这种输出也会导致心跳丢包...,不清楚这个原理是什么
- 在get_response函数中的while self.pkg > 0循环中删除了else语句因为它永不会被执行到
- 在get_response函数中修复一个bug在flag==0的else语句中补齐了index==6的情况
2. [APIs: do_current.py]
- 完成了六个轴的电机电流动作的执行,以及数据采集
- 完成了对应的RL程序的编写
3[APIs: aio.py]
- 引入modbus实例化并以参数的形式传递给相应的tabview
- 新增pre_warning函数在做自动化测试之前确保所有条件皆具备
v0.1.7.5(2024/07/03)
1. [APIs: aio.py]
- 增加触发急停和恢复急停功能逻辑
2. [APIs: do_current.py]
- 重新调整运行顺序,增加数据处理的逻辑(惯量负载逻辑暂不实现,等待软件部解决了修改工程之后不生效的问题再考虑)
3. [APIs: btn_functions.py]
- 增加触发急停和恢复急停的modbus实现仅适用于自动化测试
v0.1.7.6(2024/07/04)
1. [APIs: aio.py]
- Automatic Test逻辑中增加选择current时需要选负载类型的逻辑
2. [APIs: do_current.py]
- 单轴/场景电机电流的采集已完成
3. [APIs: openapi.py]
- 增加了modbus读取浮点数的功能
- 优化了get_from_id的逻辑
4. [autotest.xml] 新增了scenario_time只写寄存器
v0.1.8.0(2024/07/04)
1. [APIs: do_current.py] 完成了堵转电流和惯量负载电机电流的采集和处理,至此,电机电流的自动化工作基本完成
v0.1.8.1(2024/07/05)
1. [APIs: do_brake.py] 完成了制动性能测试框架的搭建,可以顺利执行完整的测试程序,但是未实现急停和数据处理
2. [APIs: aio.py] 修改了do_brake主函数的参数
3. 增加工程文件target.zip
v0.1.8.2(2024/07/08)
1. [APIs: do_brake.py] 完成了制动性能测试逻辑只不过制动信号传递生效延迟不可控暂时pending
2. [APIs: do_current.py]: 修改曲线数据时序主要是value data取反即可解决了波形锯齿明细的问题
3. [APIs: openapi.py]: modbus新增了触发急停信号的寄存器 stop0_signal并重写了解除急停socket新增了register.set_value协议
v0.1.9.0(2024/07/10)
1. 完成了制动性能的自动化采集
2. 完善了modbus浮点数读写相关的功能
3. 修改了target.zip工程该工程目前适配电机电流和制动性能
v0.1.9.1(2024/07/12)
1. [APIs: do_brake.py]
- 修改正负方向拍急停的逻辑基本原理为运行之前发送正负方向信号pon给RLRL根据信号以及速度正负号运作
- 由于上述修改正负方向急停准确率可达100%
2. [APIs: aio.py]
- 修改write2textbox的输出逻辑实现更加灵活的自定义输出同时修改相关部分
3. [APIs: openapi.py]
- modbus类新增指示政府方向急停的信号pon将modbus类入参中的tab_name删除并修改tab_name的值为'openapi'
- socket类种修改tab_name的值为'openapi'
v0.1.9.2(2024/07/13)
1. [APIs: do_brake.py]
- 修改ready_to_go信号的接收逻辑适配大负载机型
2. [APIs: do_current.py]
- 修改ready_to_go信号的接收逻辑适配大负载机型
- 调整单轴测试时间为35s适配大负载机型调整堵转电流持续时间15s适当减少测试时间
- 将act信号置为False的动作放在初始化增加程序健壮性
- 修改所有输出文件的命名,在扩展名之前加入时间戳
- 删除多余的时序矫正语句——item['value'].reverse(),使输出的曲线为平滑的自然顺序
3. [current: current.py]
- 在find_point函数种当无法找到正确点位时继续执行而不是直接终止执行
- max功能计算逻辑矫正应该是取绝对值的最大值
- 整体梳理了trq/trqh的传递路径现已修正完毕
- 减速比rr数据源修改为configs.xlsx
4. 在current工程main函数增加 VelSet 100语句
v0.1.9.3(2024/07/15)
1. [APIs: openapi.py]
- 修改modbus连接失败报错输出形式使之只在automatic test页面显示
- 将该文件移动至toplevel为后面扩展做准备
- 修改heartbeat文件路径使后续打包的时候更方便
2. [APIs: aio.py]
- 修改heartbeat文件路径使后续打包的时候更方便
- 修改write2textbox函数的打印逻辑先判断网络相关
v0.1.9.4(2024/07/15)
1. [profile: aio.py]完善durable text相关逻辑
2. [profile: do_brake/do_current/btn_functions.py]删除validate_resp函数修改execution函数
3. [profile: factory_test.py]
- 新增耐久/老化测试程序
- 实现六轴折线图显示
4. [profile: openapi.py]:多次合并遗留问题处理
5. templates文件夹组织架构调整
v0.2.0.0(2024/07/17)
1. [profile: aio.py]
- 增加velocity相关逻辑
- 修改负载信息为曲线信息
2. [profile: factory_test.py]
- 增加velocity相关逻辑
3. [profile: current.py]
- 修正减速比获取的规则
4. [profile: openapi.py]
- HmiRequest模块日志取消记录move.monitor相关
- HmiRequest模块增加了durable_lock变量控制文件读写互斥
v0.2.0.1(2024/07/19)
1. [main: aio.py]
- 修改了x轴显示使之为时间刻度
- 修改pre_warning函数增加了durable test的初始化
2. [main: factory_test.py]
- 增加了数据计算错误的判断逻辑
- 增加了历史数据保存的逻辑
- 增加了文件读写互斥的逻辑
- 修改功能为输出有效电流和最大电流,并将数据结构简化
v0.2.0.2(2024/07/26)
1. [main: current.py]
- 修正堵转电流无法正确写入结果文件的问题
2. [main: do_brake.py]
- 初始速度采集等待时间设置为可通过configs.xlsx配置文件调整的
- 初次速度采集停止逻辑修改为tasks.stop指令未验证
- 急停信号触发前pending时间设置为固定值10s
- 实现正负方向速度采集逻辑
- 工程名变更逻辑实现修改为通配符,方便后续根据机型保存文件
- 增加超差后写诊断的逻辑并可以通过configs.xlsx配置文件调整
- 程序输出中增加时间戳,方便调试定位日志时间
3. [main: do_current.py]
- 工程名变更逻辑实现修改为通配符,方便后续根据机型保存文件
4. 为工程文件添加更详细的注释
5. 补充了do_current/do_brake的流程图
6. [main: openapi.py]
- 将modbus motor_on/off的实现方法改为高电平脉冲触发
7. configs.xlsx配置表新增write_diagnosis/get_init_speed两个参数
v0.2.0.3(2024/07/27)
1. [APIs: do_brake.py]: 精简程序,解决 OOM 问题
2. [APIs: do_current.py]: 精简程序,解决 OOM 问题
3. [APIs: factory_test.py]: 精简程序,解决 OOM 问题
4. [APIsL openapi.py]
- 心跳修改为 1 s因为 OOM 问题的解决依赖于长久的打开曲线开关,此时对于 hr.c_msg 的定时清理是个挑战,将心跳缩短,有利于清理日志后,避免丢失心跳
- 新增 diagnosis.save 命令,但是执行时,有问题,待解决
v0.2.0.4(2024/07/30)
1. [APIs: do_brake.py]: 修复制动数据处理过程中,只取曲线的最后 240 个数据
2. [APIs: aio.py]: 判定版本处,删除 self.destroy(),因为该语句会导致异常发生
- 心跳修改为 1s因为 OOM 问题的解决依赖于长久的打开曲线开关,此时对于 hr.c_msg 的定时清理是个挑战,将心跳缩短,有利于清理日志后,避免丢失心跳
- 新增 diagnosis.save 命令,但是执行时,有问题,待解决
v0.2.0.5(2024/07/31)
此版本改动较大,公共部分做了规整,放置到新建文件夹 commons 当中,并所有自定义模块引入 logging 模块,记录重要信息
1. [t_change_ui: clibs.py]
- 调整代码组织结构,新增模块,将公共函数以及类合并入此
- 将一些常量放入该模块
- 引入logging/concurrent_log_handler模块并作初始化操作供其他模块使用按50M切割最多保留10份
- prj_to_xcore函数设置工程名部分重写修复了多个prj工程可能不能执行的问题并优化输入密码的部分
2. [t_change_ui: openapi.py]
- 完全重写了 get_from_id 函数,使更精准
- 在 msg_storage 函数中,增加 logger保留所有响应消息
- 删除 heartbeat 函数中的日志保存功能部分
- 心跳再次修改为 2s...
3. [t_change_ui: aio.py]
- 增加了日志初始化部分
- detect_network 函数中修改重新实例化HR间隔为 4s对应心跳
- create_plot 函数中增加 close('all'),解决循环画图不销毁占用内存的问题
4. [t_change_ui: do_brake.py]
- 使用一直打开曲线的方法规避解决了 OOM 的问题,同时修改数据处理方式,只取最后 12s
- 优化 ssh 输入密码的部分
5. [t_change_ui: do_current.py]
- 保持电流,只取最后 15s
- 优化 ssh 输入密码的部分
6. [t_change_ui: all the part]: 引入 commons 包,并定制了 logging 输出,后续持续优化
7. [APIs: btn_functions.py] 重写了告警输出函数,从日志中拿数据
8. [APIs: aio.py] 将日志框输出的内容,也保存至日志文件
9. [APIs: do_brake.py]
- 修改获取初始速度的逻辑只获取configs文件中配置的时间内的速度
- 新增 configs 参数 single_brake可针对特定条件做测试
10. [APIs: all]: 添加了 logger.setLevel(INFO),只有添加这个,单个模块内才生效
v0.2.0.6(2024/08/09)
1. [t_change_ui: all files]
- 修改了 logger 的实现
- 尤其是 clibs.py使用日志字典重写了日志记录的功能
v0.2.0.7(2024/08/16)
1. [t_change_ui: clibs.py]:修改了 hmi.log 的日志等级为 WARNING
2. [t_change_ui: openapi.py]:根据第一步的修改,将此模块日志记录等级调整至 warning
3. [current: current.py]
- README新增了整机自动化测试的前置条件即滑块需要滑动到最右端
- current修改了文件校验的逻辑
4. [t_change_ui: aio.py]
- 修改变量命名widgit -> widget
- 根据第 5 点变动,同步修改代码实现
- 调整 UI 界面代码顺序,使之符合 layout.xlsx 描述
- 将版本检查的部分单独封装成一个函数,在 detect_network 线程初始化时调用一次,并且程序启动也不会受到阻塞
5. [t_change_ui: layout.xlsx]:修改了组件布局方式
> 前两个修改点,修复的是网络提示的颜色不正确问题,因为日志将 textbox 中的内容也作为 debug 信息写入 hmi.log 了
v0.2.0.8(2024/08/20)
1. [t_change_ui: clibs.py]
- 从外部拷贝 icon.ico 文件到 templates 目录
- 在 assets 目录新建 logs 目录,存放日志文件,并增加了相应的逻辑保证正常执行
2. [t_change_ui: aio.py]:增加 App 窗口图标代码
3. [t_change_ui: openapi.py]:将重复输出的网络错误提示,从 textbox 中转移到 debug.log 日志文件中
4. [main: openapi.py]:新增 rl_task.set_run_params 指令支持,可设定速度滑块以及是否重复运行
5. [main: do_brake/do_current/factory_test.py]:在初始化运动时增加 `clibs.execution('rl_task.set_run_params', hr, w2t, tab_name, loop_mode=True, override=1.0)`
v0.2.0.9(2024/10/09)
1. [main: do_brake.py] 采集完成后pending 3s使速度完全将为 0
v0.2.1.0(2024/12/05)
1. [current: do_current.py] 增加了 hw_sensor_trq_feedback 曲线的采集
2. [current: current.py] 增加了 hw_sensor_trq_feedback 曲线数据的处理,以及修改了之前数据处理的逻辑
3. [current: clibs.py] 新增可手动修改连接 IP 地址的功能,存储在 assets/templates/ipaddr.txt 中,默认是 192.168.0.160
v0.2.1.1(2024/12/16)
1. [main: do_brake.py] 修改了 SSH 的固定 IP 为 clibs 中读取的内容,并删除了每次都 reload 工程的动作,改为只在修改 RL 工程时 reload 一次旨在减少最近频繁出现的“无法获取overview.reload-xxxxxx”请求的响应初步判断是 xCore 的问题,非 AIO 问题,已反馈待版本修复
2. [main: wavelogger.py] 新增异常数据校验功能
v0.3.0.0(2025/01/09)
1. 重构了 AIO 工具:
- UI 界面
- 电机电流数据处理功能
- xCore 通讯协议实现
2. 将之前的功能迁移到新代码
v0.3.1.0(2025/01/23)
1. 实现了从机型文件读取相关测试参数,并用于自动化测试或者数据处理
2. 完整实现了所有功能的迁移,并自测验证通过
3. 重新实现并优化了如下功能:
- 电机电流数据采集,优化代码,提高执行效率,并适配新的报告文件
- 制动数据采集,比之前采集正确率提高 30%,基本可以做到 100% 的数据准确度
- 耐久数据采集并记录,优化了执行以及数据展示
- 基恩士数据采集处理,适配任意编码格式的文件处理
v0.3.1.2(2025/02/11)
1. 修改自动测试(制动/转矩/耐久的read_ready_to_go信号等待时间为15s
2. 废弃write_diagnosis参数
3. 优化do_brake中触发超差写诊断等待操作流程
v0.3.1.3(2025/02/12)
1. 修改自动测试(制动)的打开关闭曲线逻辑,开始时打开,完整测试结束时关闭
v0.3.1.3(2025/02/13)
1. 修改自动测试电机电流的数据处理方法从以前的Multiprocessing->threading因为Intel CPU遇到Multiprocessing会重新打开一个AIO实例
v0.3.1.5(2025/03/10)
1. 因公司网络环境调整修改服务器校验IP
v0.3.1.6(2025/03/21)
1. 调整耐久(场景)测试工程,以及相应的数据采集逻辑,将采集规则由固定时间间隔,修改为固定运动动作周期
> Tips工程以及寄存器文件均有变动

View File

@ -0,0 +1,11 @@
chardet==5.2.0
customtkinter==5.2.2
matplotlib==3.10.0
numpy==2.2.2
openpyxl==3.1.5
pandas==2.2.3
paramiko==3.5.0
pdfplumber==0.11.5
Pillow==11.1.0
pymodbus==3.8.3
pyinstaller==6.12.0

View File

@ -0,0 +1 @@
0.3.1.6@03/21/2025

BIN
assets/media/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
assets/media/updated.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
assets/media/upgrade.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

518
code/aio.py Normal file
View File

@ -0,0 +1,518 @@
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())

218
code/analysis/brake.py Normal file
View File

@ -0,0 +1,218 @@
import json
import os.path
import time
import pandas
from PySide6.QtCore import Signal, QThread
import openpyxl
import re
from common import clibs
class BrakeDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, /):
super().__init__()
self.dir_path = dir_path
self.idx = 0
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 check_files(self, rawdata_dirs, result_files):
msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:<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>"
if len(result_files) != 4 or len(rawdata_dirs) == 0:
self.logger("ERROR", "brake-check_files", msg_wrong, "red", "InitFileError")
config_file, reach33_file, reach66_file, reach100_file = None, None, None, None
for result_file in result_files:
filename = result_file.split("/")[-1]
if re.match(".*\\.cfg", filename):
config_file = result_file
elif filename.startswith("reach33_") and filename.endswith(".xlsx"):
reach33_file = result_file
elif filename.startswith("reach66_") and filename.endswith(".xlsx"):
reach66_file = result_file
elif filename.startswith("reach100_") and filename.endswith(".xlsx"):
reach100_file = result_file
else:
if not (config_file and reach33_file and reach66_file and reach100_file):
self.logger("ERROR", "brake-check_files", msg_wrong, "red", "InitFileError")
reach_s = ['reach33', 'reach66', 'reach100']
load_s = ['load33', 'load66', 'load100']
speed_s = ['speed33', 'speed66', 'speed100']
prefix = []
for rawdata_dir in rawdata_dirs:
components = rawdata_dir.split("/")[-1].split('_') # reach_load_speed
prefix.append(components[0])
if components[0] not in reach_s or components[1] not in load_s or components[2] not in speed_s:
msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式<br>"
msg += "命名规则reachAA_loadBB_speedCCAA/BB/CC 指的是臂展/负载/速度的比例<br>"
msg += "规则解释reach66_load100_speed33表示 66% 臂展100% 负载以及 33% 速度情况下的测试结果文件夹<br>"
self.logger("ERROR", "brake-check_files", msg, "red", "WrongDataFolder")
_, rawdata_files = clibs.traversal_files(rawdata_dir, self.output)
if len(rawdata_files) != 3:
msg = f"数据目录 {rawdata_dir} 下数据文件个数错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
self.logger("ERROR", "brake-check_files", msg, "red", "WrongDataFile")
for rawdata_file in rawdata_files:
if not rawdata_file.endswith(".data"):
msg = f"数据文件 {rawdata_file} 后缀错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
self.logger("ERROR", "brake-check_files", msg, "red", "WrongDataFile")
result_files = []
for _ in [reach33_file, reach66_file, reach100_file]:
if _.split("/")[-1].split("_")[0] in set(prefix):
result_files.append(_)
self.logger("INFO", "brake-check_files", "数据目录合规性检查结束,未发现问题......", "green")
return config_file, result_files
def get_configs(self, config_file):
try:
with open(config_file, mode="r", encoding="utf-8") as f_config:
configs = json.load(f_config)
p_dir = config_file.split('/')[-2]
if not re.match("^[jJ][123]$", p_dir):
self.logger("ERROR", "brake-get_configs-1", "被处理的根文件夹命名必须是 [Jj][123] 的格式", "red", "DirNameError")
axis = int(p_dir[-1]) # 要处理的轴
rrs = [abs(_) for _ in configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"]] # 减速比rr for reduction ratio
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
rr = rrs[axis-1]
av = avs[axis-1]
return av, rr
except Exception as Err:
self.logger("ERROR", "brake-get_configs-2", f"无法打开 {config_file},或者使用了错误的机型配置文件,需检查<br>{Err}", "red", "OpenFileError")
def now_doing_msg(self, docs, flag):
now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
file_type = 'file' if os.path.isfile(docs) else 'dir'
if flag == 'start' and file_type == 'dir':
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 正在处理目录 {docs} 中的数据......")
elif flag == 'start' and file_type == 'file':
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 正在处理文件 {docs} 中的数据......")
elif flag == 'done' and file_type == 'dir':
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 目录 {docs} 数据文件已处理完毕")
elif flag == 'done' and file_type == 'file':
self.logger("INFO", "brake-now_doing_msg", f"[{now}] 文件 {docs} 数据已处理完毕")
@staticmethod
def data2result(df, ws_result, row_start, row_end):
data = []
for row in range(row_start, row_end):
data.append(df.iloc[row, 0])
data.append(df.iloc[row, 1])
data.append(df.iloc[row, 2])
i = 0
row_max = 1000 if row_end - row_start < 1000 else row_end - row_start + 100
for row in range(2, row_max):
try:
ws_result.cell(row=row, column=1).value = data[i]
ws_result.cell(row=row, column=2).value = data[i + 1]
ws_result.cell(row=row, column=3).value = data[i + 2]
i += 3
except Exception:
ws_result.cell(row=row, column=1).value = None
ws_result.cell(row=row, column=2).value = None
ws_result.cell(row=row, column=3).value = None
def get_row_range(self, data_file, df, conditions, av, rr):
row_start, row_end = 0, 0
ratio = float(conditions[2].removeprefix('speed')) / 100
av_max = av * ratio
threshold = 0.95
for row in range(df.index[-1] - 1, -1, -10):
if df.iloc[row, 2] != 0:
row_start = row - 20 if row - 20 > 0 else 0 # 急停前找 20 个点
break
else:
self.logger("ERROR", "brake-get_row_range", f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", "red", "StartNotFoundError")
for row in range(row_start, df.index[-1] - 1, 10):
speed_row = df.iloc[row, 0] * clibs.RADIAN * rr * 60 / 360
if abs(speed_row) < 1:
row_end = row + 100 if row + 100 <= df.index[-1] - 1 else df.index[-1] - 1
break
else:
self.logger("ERROR", "brake-get_row_range", f"数据文件 {data_file} 最后的速度未降为零", "red", "SpeedNotZeroError")
av_estop = abs(df.iloc[row_start - 20:row_start, 0].abs().mean() * clibs.RADIAN)
if abs(av_estop / av_max) < threshold:
filename = data_file.split("/")[-1]
msg = f"[av_estop: {av_estop:.2f} | shouldbe: {av_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查"
self.logger("WARNING", "brake-get_row_range", msg, "#8A2BE2")
return row_start, row_end
@staticmethod
def get_shtname(conditions, count):
# 33%负载_33%速度_1 - reach/load/speed
load = conditions[1].removeprefix('load')
speed = conditions[2].removeprefix('speed')
result_sheet_name = f"{load}%负载_{speed}%速度_{count}"
return result_sheet_name
def single_file_process(self, data_file, wb, count, av, rr):
df = pandas.read_csv(data_file, sep='\t')
conditions = data_file.split("/")[-2].split("_") # reach/load/speed
shtname = self.get_shtname(conditions, count)
ws = wb[shtname]
row_start, row_end = self.get_row_range(data_file, df, conditions, av, rr)
self.data2result(df, ws, row_start, row_end)
def data_process(self, result_file, rawdata_dirs, av, rr):
filename = result_file.split("/")[-1]
self.logger("INFO", "brake-data_process", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
try:
wb = openpyxl.load_workbook(result_file)
except Exception as Err:
self.logger("ERROR", "brake-data_process", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
prefix = filename.split('_')[0]
for rawdata_dir in rawdata_dirs:
if rawdata_dir.split("/")[-1].split('_')[0] == prefix:
self.now_doing_msg(rawdata_dir, 'start')
_, data_files = clibs.traversal_files(rawdata_dir, self.output)
for idx in range(3):
self.single_file_process(data_files[idx], wb, idx+1, av, rr)
# threads = [
# threading.Thread(target=self.single_file_process, args=(data_files[0], wb, 1, av, rr)),
# threading.Thread(target=self.single_file_process, args=(data_files[1], wb, 2, av, rr)),
# threading.Thread(target=self.single_file_process, args=(data_files[2], wb, 3, av, rr))
# ]
# [t.start() for t in threads]
# [t.join() for t in threads]
self.now_doing_msg(rawdata_dir, 'done')
self.logger("INFO", "brake-data_process", f"正在保存文件 {filename},这可能需要一些时间......<br>", "blue")
wb.save(result_file)
wb.close()
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
rawdata_dirs, result_files = clibs.traversal_files(self.dir_path, self.output)
config_file, result_files = self.check_files(rawdata_dirs, result_files)
av, rr = self.get_configs(config_file)
for result_file in result_files:
self.data_process(result_file, rawdata_dirs, av, rr)
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)

427
code/analysis/current.py Normal file
View File

@ -0,0 +1,427 @@
import json
import openpyxl
import pandas
import re
import csv
from PySide6.QtCore import Signal, QThread
import time
from common import clibs
class CurrentDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, proc, /):
super().__init__()
self.dir_path = dir_path
self.proc = proc
self.idx = 1
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_files = clibs.traversal_files(self.dir_path, self.output)
count, config_file = 0, None
for data_file in data_files:
filename = data_file.split("/")[-1]
if re.match(".*\\.cfg", filename):
config_file = data_file
count += 1
elif filename == "T_电机电流.xlsx":
count += 1
else:
if not re.match("^j[1-7].*\\.data$", filename):
msg = f"不合规 {data_file}<br>"
msg += "所有数据文件必须以 j[1-7]_ 开头,以 .data 结尾比如j1_abcdef.data请检查整改后重新运行"
self.logger("ERROR", "current-initialization", msg, "red", "FilenameIllegal")
if count != 2:
msg = "需要有一个机型配置文件\"*.cfg\",以及一个数据处理文件\"T_电机电流.xlsx\"表格,请检查整改后重新运行"
self.logger("ERROR", "current-initialization", msg, "red", "FilenameIllegal")
return data_files, config_file
def current_max(self, data_files, rts):
self.logger("INFO", "current-current_max", f"正在处理最大转矩值逻辑......")
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
for data_file in data_files:
if data_file.endswith(".data"):
df = pandas.read_csv(data_file, sep="\t")
else:
continue
self.logger("INFO", "current-current_max", f"正在处理 {data_file} ...")
cols = len(df.columns)
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
rt = rts[axis-1]
self.logger("INFO", "current-current_max", f"最大列数为 {cols}{axis} 轴的额定转矩为 {rt}")
col = df.columns.values[clibs.c_servo_trq-1] # 获取 "device_servo_trq_feedback"
c_max = df[col].abs().max()
scale = 1000
_ = abs(c_max/scale*rt)
current[axis].append(_)
self.logger("INFO", "current-current_max", f"{data_file}: {_:.2f}")
self.logger("INFO", "current-current_max", f"获取到的列名为 {col},最大转矩为 {_}")
with open(data_file, "a+") as f_data:
csv_writer = csv.writer(f_data, delimiter="\t")
csv_writer.writerow([""] * (cols-1) + [_])
for axis, cur in current.items():
if not cur:
continue
else:
_ = ""
for value in cur:
_ += f"{value:.4f} "
self.logger("INFO", "current-current_max", f"{axis}轴最大转矩数据:{_}")
self.logger("INFO", "current-current_max", f"获取最大转矩值结束 current_max = {current}")
self.logger("INFO", "current-current_max", f"最大转矩数据处理完毕......")
return current
def current_avg(self, data_files, rts):
self.logger("INFO", "current-current_avg", f"正在处理平均转矩值逻辑......")
current = {1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
for data_file in data_files:
if data_file.endswith(".data"):
df = pandas.read_csv(data_file, sep="\t")
else:
continue
self.logger("INFO", "current-current_avg", f"正在处理 {data_file} ...")
cols = len(df.columns)
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
rt = rts[axis-1]
self.logger("INFO", "current-current_avg", f"最大列数为 {cols}{axis} 轴的额定转矩为 {rt}")
col = df.columns.values[clibs.c_servo_trq-1]
c_std = df[col].std()
c_avg = df[col].mean()
scale = 1000
_ = (abs(c_avg)+c_std*3)/scale*rt
current[axis].append(_)
self.logger("INFO", "current-current_avg", f"{data_file}: {_:.2f}")
self.logger("INFO", "current-current_avg", f"获取到的列名为 {col},平均转矩为 {_}")
with open(data_file, "a+") as f_data:
csv_writer = csv.writer(f_data, delimiter="\t")
csv_writer.writerow([""] * (cols-1) + [_])
for axis, cur in current.items():
if not cur:
continue
else:
_ = ""
for value in cur:
_ += f"{value:.4f} "
self.logger("INFO", "current-current_avg", f"{axis}轴平均转矩数据:{_}")
self.logger("INFO", "current-current_avg", f"获取平均转矩值结束 current_avg = {current}", flag="cursor")
self.logger("INFO", "current-current_avg", f"平均转矩数据处理完毕......")
return current
def current_cycle(self, data_files, rrs, rts, params):
result, hold, single, scenario, dur_time = None, [], [], [], 0
for data_file in data_files:
filename = data_file.split("/")[-1]
if filename == "T_电机电流.xlsx":
result = data_file
elif re.match("j[1-7]_hold_.*\\.data", filename):
hold.append(data_file)
elif re.match("j[1-7]_s_.*\\.data", filename):
scenario.append(data_file)
dur_time = float(filename.split("_")[3])
elif re.match("j[1-7]_.*\\.data", filename):
single.append(data_file)
clibs.stop, filename = True, result.split("/")[-1]
self.logger("INFO", "current-current_cycle", f"正在打开文件 {filename},这可能需要一些时间......", "blue")
try:
wb = openpyxl.load_workbook(result)
except Exception as Err:
self.logger("ERROR", "current-current_cycle", f"{filename}文件打开失败,可能是文件已损坏,确认后重新执行!<br>{Err}", "red", "CannotOpenFile")
ws = wb["统计"]
for idx in range(len(params)-1):
row = idx + 2
for col in range(2, 8):
ws.cell(row=row, column=col).value = params[idx][col-2]
ws.cell(row=1, column=1).value = params[-1]
if hold:
avg = self.current_avg(hold, rts)
for axis, cur_value in avg.items():
sht_name = f"J{axis}"
wb[sht_name]["P4"].value = float(cur_value[0])
if dur_time == 0:
self.p_single(wb, single, rrs)
else:
self.p_scenario(wb, scenario, rrs, dur_time)
self.logger("INFO", "current-current_cycle", f"正在保存文件 {filename},这可能需要一些时间......", "blue")
wb.save(result)
wb.close()
def find_point(self, data_file, df, flag, row_s, row_e, threshold, step, end_point, skip_scale, axis, seq):
if flag == "lt":
while row_e > end_point:
speed_avg = df.iloc[row_s:row_e].abs().mean()
if speed_avg < threshold:
row_e -= step
row_s -= step
continue
else:
# one more time如果连续两次 200 个点的平均值都大于 threshold说明已经到了临界点了其实也不一定只不过相对遇到一次就判定临界点更安全一点点
# 从实际数据看,这开逻辑很小概率能触发到
speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean()
if speed_avg < threshold:
self.logger("WARNING", "current-find_point", f"【lt】{axis} 轴第 {seq} 次查找数据可能有异常row_s = {row_s}, row_e = {row_e}", "purple")
return row_s, row_e
else:
self.logger("ERROR", "current-find_point", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
elif flag == "gt":
while row_e > end_point:
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:
row_e -= step
row_s -= step
continue
else:
# one more time如果连续两次 200 个点的平均值都小于 threshold说明已经到了临界点了其实也不一定只不过相对遇到一次就判定临界点更安全一点点
# 从实际数据看,这开逻辑很小概率能触发到
speed_avg = df.iloc[row_s-end_point*skip_scale:row_e-end_point*skip_scale].abs().mean()
if speed_avg > threshold:
self.logger("WARNING", "current-find_point", f"【gt】{axis} 轴第 {seq} 次查找数据可能有异常row_s = {row_s}, row_e = {row_e}", "purple")
return row_s, row_e
else:
self.logger("ERROR", "current-find_point", f"{data_file} 数据有误,需要检查,无法找到第 {seq} 个有效点......", "red", "AnchorNotFound")
def get_row_number(self, threshold, flag, df, row_s, row_e, axis):
count_1, count_2 = 0, 0
if flag == "start" or flag == "end":
for number in df.iloc[row_s:row_e].abs():
count_2 += 1
if number > threshold:
count_1 += 1
if count_1 == 10:
return row_s + count_2 - 10
else:
count_1 = 0
elif flag == "middle":
for number in df.iloc[row_s:row_e].abs():
count_2 += 1
if number < threshold: # 唯一的区别
count_1 += 1
if count_1 == 10:
return row_s + count_2 - 10
else:
count_1 = 0
places = {"start": "起点", "middle": "中间点", "end": "终点"} # 因为是终点数据,所以可能有异常
self.logger("WARNING", "current-get_row_number", f"{axis} 轴获取{places[flag]}数据 {row_e} 可能有异常,需关注!", "purple")
return row_e
def p_single(self, wb, single, rrs):
# 1. 先找到第一个速度为零的点,数据从后往前找,一开始就是零的情况不予考虑
# 2. 记录第一个点的位置,继续向前查找第二个速度为零的点,同理,一开始为零的点不予考虑
# 3. 记录第二个点的位置,并将其中的数据拷贝至对应位置
for data_file in single:
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
sht_name = f"J{axis}"
ws = wb[sht_name]
pandas.set_option("display.precision", 2)
df_origin = pandas.read_csv(data_file, sep="\t")
rr = rrs[axis-1]
addition = 180 / 3.1415926 * 60 / 360 * rr
col_names = list(df_origin.columns)
df = df_origin[col_names[clibs.c_joint_vel-1]].multiply(addition)
step = 50 # 步进值
end_point = 200 # 有效数值的数目
threshold = 5 # 200个点的平均阈值线
skip_scale = 2
row_start, row_middle, row_end = 0, 0, 0
row_e = df.index[-1]
row_s = row_e - end_point
speed_avg = df.iloc[row_s:row_e].abs().mean()
if speed_avg < threshold:
# 第一次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点
row_s, row_e = self.find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-1")
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 第二次过滤:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
row_s, row_e = self.find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-2")
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 第三次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点
row_s, row_e = self.find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-3")
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 正式第一次采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
row_s, row_e = self.find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 1)
row_end = self.get_row_number(threshold, "end", df, row_s, row_e, axis)
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 正式第二次采集:消除速度为零的数据,找到速度即将大于零的上升临界点
row_s, row_e = self.find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 2)
row_middle = self.get_row_number(threshold, "middle", df, row_s, row_e, axis)
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 正式第三次采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
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)
elif speed_avg > threshold:
# 第一次过滤:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
row_s, row_e = self.find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-1")
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 第二次过滤:消除速度为零的数据,找到速度即将大于零的上升临界点
row_s, row_e = self.find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, "pre-2")
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 第一次正式采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
row_s, row_e = self.find_point(data_file, df, "gt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 1)
row_end = self.get_row_number(threshold, "end", df, row_s, row_e, axis)
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 第二次正式采集:消除速度为零的数据,找到速度即将大于零的上升临界点
row_s, row_e = self.find_point(data_file, df, "lt", row_s, row_e, threshold, step, end_point, skip_scale, axis, 2)
row_middle = self.get_row_number(threshold, "middle", df, row_s, row_e, axis)
row_e -= end_point*skip_scale
row_s -= end_point*skip_scale
# 第三次正式采集:消除速度大于零的数据,找到速度即将趋近于零的下降临界点
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)
self.logger("INFO", "current", f"{axis} 轴起点:{row_start}")
self.logger("INFO", "current", f"{axis} 轴中间点:{row_middle}")
self.logger("INFO", "current", f"{axis} 轴终点:{row_end}")
self.logger("INFO", "current", f"{axis} 轴数据非零段点数:{row_middle-row_start+1}")
self.logger("INFO", "current", f"{axis} 轴数据为零段点数:{row_end-row_middle+1}")
if abs(row_end+row_start-2*row_middle) > 1000:
self.logger("WARNING", "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
for row in range(row_start, row_end+1):
data.append(df_origin.iloc[row, first_c])
data.append(df_origin.iloc[row, second_c])
data.append(df_origin.iloc[row, third_c])
data.append(df_origin.iloc[row, fourth_c])
i = 0
for row in ws.iter_rows(min_row=2, min_col=2, max_row=150000, max_col=5):
for cell in row:
try:
if i % 4 == 0:
ws.cell((i//4)+2, 1).value = float(((i//4)+1)/1000)
_ = f"{data[i]:.2f}"
cell.value = float(_)
i += 1
except Exception:
if i % 4 == 0:
ws.cell((i//4)+2, 1).value = None
cell.value = None
i += 1
def p_scenario(self, wb, scenario, rrs, dur_time):
self.logger("INFO", "current", f"本次处理的是电机电流场景数据,场景运动周期为 {dur_time}s", "blue")
for data_file in scenario:
cycle = 0.001
axis = int(data_file.split("/")[-1].split("_")[0].removeprefix("j"))
sht_name = f"J{axis}"
ws = wb[sht_name]
pandas.set_option("display.precision", 2)
df_origin = pandas.read_csv(data_file, sep="\t")
rr = rrs[axis-1]
addition = 180 / 3.1415926 * 60 / 360 * rr
col_names = list(df_origin.columns)
df = df_origin[col_names[clibs.c_joint_vel-1]].multiply(addition)
row_start = 3000
row_end = row_start + int(dur_time/cycle)
if row_end > df.index[-1]:
self.logger("ERROR", "current-p_scenario", 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
for row in range(row_start, row_end+1):
data.append(df_origin.iloc[row, first_c])
data.append(df_origin.iloc[row, second_c])
data.append(df_origin.iloc[row, third_c])
data.append(df_origin.iloc[row, fourth_c])
i = 0
for row in ws.iter_rows(min_row=2, min_col=2, max_row=250000, max_col=5):
for cell in row:
try:
if i % 4 == 0:
ws.cell((i//4)+2, 1).value = float(((i//4)+1)/1000)
_ = f"{data[i]:.2f}"
cell.value = float(_)
i += 1
except Exception:
cell.value = None
if i % 4 == 0:
ws.cell((i//4)+2, 1).value = None
i += 1
def get_configs(self, config_file):
try:
if re.match("^[NXEC]B.*", config_file.split("/")[-1]):
robot_type = "工业"
else:
robot_type = "协作"
with open(config_file, mode="r", encoding="utf-8") as f_config:
configs = json.load(f_config)
version = configs["VERSION"]
sc = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] # 采样周期sc for sample cycle
r_rrs = configs["TRANSMISSION"]["REDUCTION_RATIO_NUMERATOR"] # 减速比rr for reduction ratio
m_avs = configs["MOTION"]["JOINT_MAX_SPEED"]
m_stall_ts = configs["MOTOR"]["STALL_TORQUE"] # 电机堵转转矩
m_rts = configs["MOTOR"]["RATED_TORQUE"] # 电机额定转矩rt for rated torque
m_max_ts = configs["MOTOR"]["PEAK_TORQUE"] # 电机峰值转矩
m_r_rpms = configs["MOTOR"]["RATED_SPEED"] # 电机额定转速
m_max_rpms = configs["MOTOR"]["MAX_SPEED"] # 电机最大转速
r_max_sst = configs["TRANSMISSION"]["MAX_TORQUE_FOR_START_AND_STOP"] # 减速器最大启停转矩sst for start and stop torque
r_max_t = configs["TRANSMISSION"]["MAX_PEAK_TORQUE"] # 减速器瞬时最大转矩
r_avg_t = configs["TRANSMISSION"]["MAX_AVERAGE_TORQUE"] # 减速器平均负载转矩允许最大值
self.logger("INFO", "current", f"get_configs: 机型文件版本 {config_file}_{version}")
self.logger("INFO", "current", f"get_configs: 减速比 {r_rrs}")
self.logger("INFO", "current", f"get_configs: 额定转矩 {m_rts}")
self.logger("INFO", "current", f"get_configs: 最大角速度 {m_avs}")
return sc, r_rrs, m_avs, m_stall_ts, m_rts, m_max_ts, m_r_rpms, m_max_rpms, r_max_sst, r_max_t, r_avg_t, robot_type
except Exception as Err:
self.logger("ERROR", "current", f"get_config: 无法打开 {config_file},或获取配置文件参数错误 {Err}", "red", "OpenFileError")
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
data_files, config_file = self.initialization()
params = self.get_configs(config_file)
rts, rrs = params[4], params[1]
if self.proc == "最大值":
self.current_max(data_files, rts)
elif self.proc == "平均值":
self.current_avg(data_files, rts)
elif self.proc == "周期":
self.current_cycle(data_files, rrs, rts, params)
self.logger("INFO", "current-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\n"
self.logger("INFO", "current-processing", msg)

213
code/analysis/iso.py Normal file
View File

@ -0,0 +1,213 @@
import pdfplumber
import openpyxl
import os
import time
from PySide6.QtCore import Signal, QThread
from common import clibs
class IsoDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, /):
super().__init__()
self.dir_path = dir_path
self.idx = 2
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 p_iso(self, file, p_files, ws, tmpfile):
p_files.append(file)
pdf = pdfplumber.open(file)
with open(tmpfile, mode="w", encoding="utf-8") as fb:
for page in pdf.pages:
fb.write(page.extract_text())
with open(tmpfile, mode="r", encoding="utf-8") as fb:
lines = fb.readlines()
lines = [line for line in lines if not line.startswith("Page ")]
for line in lines:
if line.strip() == "Pose Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=3, column=7).value = float(lines[index+4].split()[1])
ws.cell(row=4, column=7).value = float(lines[index+5].split()[1])
ws.cell(row=5, column=7).value = float(lines[index+6].split()[1])
ws.cell(row=6, column=7).value = float(lines[index+7].split()[1])
ws.cell(row=7, column=7).value = float(lines[index+8].split()[1])
ws.cell(row=8, column=7).value = float(lines[index+4].split()[2])
ws.cell(row=9, column=7).value = float(lines[index+5].split()[2])
ws.cell(row=10, column=7).value = float(lines[index+6].split()[2])
ws.cell(row=11, column=7).value = float(lines[index+7].split()[2])
ws.cell(row=12, column=7).value = float(lines[index+8].split()[2])
elif line.strip() == "Pose Accuracy Variation":
index = lines.index(line)
ws.cell(row=13, column=7).value = float(lines[index+4].split()[1])
ws.cell(row=14, column=7).value = float(lines[index+5].split()[1])
ws.cell(row=15, column=7).value = float(lines[index+6].split()[1])
elif line.strip() == "Distance Accuracy":
index = lines.index(line)
ws.cell(row=16, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=17, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Stabilisation Time and Overshoot":
index = lines.index(line)
ws.cell(row=18, column=7).value = float(lines[index + 7].split()[3])
ws.cell(row=19, column=7).value = float(lines[index + 7].split()[2])
elif line.strip() == "Velocity Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=20, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=21, column=7).value = float(lines[index + 4].split()[2])
ws.cell(row=22, column=7).value = float(lines[index + 4].split()[3])
elif line.strip()[:31] == "Path Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=29, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=30, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Corner Overshoot and Roundoff":
index = lines.index(line)
ws.cell(row=35, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=36, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Robot Weaving":
index = lines.index(line)
ws.cell(row=41, column=7).value = float(lines[index + 4].split()[2])
ws.cell(row=42, column=7).value = float(lines[index + 4].split()[3])
ws.cell(row=43, column=7).value = float(lines[index + 4].split()[4])
else:
pass
pdf.close()
def p_iso_100(self, file, p_files, ws, tmpfile):
p_files.append(file)
pdf = pdfplumber.open(file)
with open(tmpfile, mode="w", encoding="utf-8") as fb:
for page in pdf.pages:
fb.write(page.extract_text())
with open(tmpfile, mode="r", encoding="utf-8") as fb:
lines = fb.readlines()
lines = [line for line in lines if not line.startswith("Page ")]
for line in lines:
if line.strip() == "Velocity Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=26, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=27, column=7).value = float(lines[index + 4].split()[2])
ws.cell(row=28, column=7).value = float(lines[index + 4].split()[3])
elif line.strip()[:31] == "Path Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=33, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=34, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Corner Overshoot and Roundoff":
index = lines.index(line)
ws.cell(row=39, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=40, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Robot Weaving":
index = lines.index(line)
ws.cell(row=47, column=7).value = float(lines[index + 4].split()[2])
ws.cell(row=48, column=7).value = float(lines[index + 4].split()[3])
ws.cell(row=49, column=7).value = float(lines[index + 4].split()[4])
else:
pass
pdf.close()
def p_iso_1000(self, file, p_files, ws, tmpfile):
p_files.append(file)
pdf = pdfplumber.open(file)
with open(tmpfile, mode="w", encoding="utf-8") as fb:
for page in pdf.pages:
fb.write(page.extract_text())
with open(tmpfile, mode="r", encoding="utf-8") as fb:
lines = fb.readlines()
lines = [line for line in lines if not line.startswith("Page ")]
for line in lines:
if line.strip() == "Velocity Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=23, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=24, column=7).value = float(lines[index + 4].split()[2])
ws.cell(row=25, column=7).value = float(lines[index + 4].split()[3])
elif line.strip()[:31] == "Path Accuracy and Repeatability":
index = lines.index(line)
ws.cell(row=31, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=32, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Corner Overshoot and Roundoff":
index = lines.index(line)
ws.cell(row=37, column=7).value = float(lines[index + 4].split()[1])
ws.cell(row=38, column=7).value = float(lines[index + 4].split()[2])
elif line.strip() == "Robot Weaving":
index = lines.index(line)
ws.cell(row=44, column=7).value = float(lines[index + 4].split()[2])
ws.cell(row=45, column=7).value = float(lines[index + 4].split()[3])
ws.cell(row=46, column=7).value = float(lines[index + 4].split()[4])
else:
pass
pdf.close()
def initialization(self):
dirs, files = clibs.traversal_files(self.dir_path, self.output)
if len(dirs) != 0:
self.logger("ERROR", "iso", f"init: 工作目录下不可以有文件夹!", "red", "InitFileError")
for file in files:
file = file.lower()
if file.endswith("iso-results.xlsx"):
pass
elif file.endswith("iso-v1000.pdf"):
pass
elif file.endswith("iso-v100.pdf"):
pass
elif file.endswith("iso.pdf"):
pass
else:
self.logger("ERROR", "iso", f"init: 工作目录下只允许有如下四个文件不区分大小写pdf文件最少有一个<br>1. iso-results.xlsx<br>2. ISO.pdf<br>3. ISO-V100.pdf<br>4. ISO-V1000.pdf", "red", "InitFileError")
return files
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
files = self.initialization()
filename = f"{self.dir_path}/iso-results.xlsx"
tmpfile = f"{self.dir_path}/data.txt"
wb, ws = None, None
try:
wb = openpyxl.load_workbook(filename)
ws = wb.active
for i in range(3, 50):
ws.cell(row=i, column=7).value = None
except Exception as Err:
self.logger("ERROR", "iso", f"main: 无法打开文件 {filename}<br>{Err}", "red", "FileOpenError")
p_files = []
for file in files:
if file.split("/")[-1].lower() == "iso.pdf":
self.logger("INFO", "iso", f"正在处理{file}......")
self.p_iso(file, p_files, ws, tmpfile)
self.logger("INFO", "iso", f"文件{file}已处理完毕。")
elif file.split("/")[-1].lower() == "iso-v100.pdf":
self.logger("INFO", "iso", f"正在处理{file}......")
self.p_iso_100(file, p_files, ws, tmpfile)
self.logger("INFO", "iso", f"文件{file}已处理完毕。")
elif file.split("/")[-1].lower() == "iso-v1000.pdf":
self.logger("INFO", "iso", f"正在处理{file}......")
self.p_iso_1000(file, p_files, ws, tmpfile)
self.logger("INFO", "iso", f"文件{file}已处理完毕。")
else:
pass
wb.save(filename)
wb.close()
if len(p_files) == 0:
self.logger("ERROR", "iso", f"目录 {self.dir_path} 下没有需要处理的文件,需要确认......", "red", "FileNotFound")
else:
os.remove(tmpfile)
self.logger("INFO", "current-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\n"
self.logger("INFO", "current-processing", msg)

160
code/analysis/wavelogger.py Normal file
View File

@ -0,0 +1,160 @@
import pandas
import csv
import openpyxl
import chardet
import time
from PySide6.QtCore import Signal, QThread
from common import clibs
class WaveloggerDataProcess(QThread):
output = Signal(str, str)
def __init__(self, dir_path, /):
super().__init__()
self.dir_path = dir_path
self.idx = 3
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 find_point(self, bof, step, margin, threshold, pos, data_file, flag, df, row):
# bof: backward or forward
# pos: used for debug
# flag: greater than or lower than
row_target = None
row_origin = len(df) - margin + 1
if flag == "gt":
while 0 < row < row_origin:
value = float(df.iloc[row, 2])
if value > threshold:
row = row - step if bof == "backward" else row + step
continue
else:
row_target = row - step if bof == "backward" else row + step
break
else:
if bof == "backward":
self.logger("ERROR", "wavelogger-find_point", f"find_point-gt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
elif bof == "forward":
row_target = row + margin # to end while loop in function `single_file_proc`
elif flag == "lt":
while 0 < row < row_origin:
value = float(df.iloc[row, 2])
if value < threshold:
row = row - step if bof == "backward" else row + step
continue
else:
row_target = row - step if bof == "backward" else row + step
break
else:
if bof == "backward":
self.logger("ERROR", "wavelogger-find_point", f"find_point-lt: [{pos}] 在 {data_file} 中,无法正确识别数据,需要确认...", "red", "DataError")
elif bof == "forward":
row_target = row + margin # to end while loop in function `single_file_proc`
return row_target
def get_cycle_info(self, data_file, step, margin, threshold):
# end -> middle: low
# middle -> start: high
# 1. 从最后读取数据无论是大于1还是小于1都舍弃找到相反的值的起始点
# 2. 从起始点,继续往前寻找,找到与之数值相反的中间点
# 3. 从中间点,继续往前寻找,找到与之数值相反的结束点,至此,得到了高低数值的时间区间以及一轮的周期时间
with open(data_file, "rb") as f:
raw_data = f.read(1000)
result = chardet.detect(raw_data)
encoding = result['encoding']
csv_reader = csv.reader(open(data_file, encoding=encoding))
begin = int(next(csv_reader)[1])
df = pandas.read_csv(data_file, sep=",", encoding=encoding, skip_blank_lines=False, header=begin - 1, on_bad_lines="skip")
row = len(df) - margin
if float(df.iloc[row, 2]) < threshold:
row = self.find_point("backward", step, margin, threshold, "a1", data_file, "lt", df, row)
_row = self.find_point("backward", step, margin, threshold, "a2", data_file, "gt", df, row)
_row = self.find_point("backward", step, margin, threshold, "a3", data_file, "lt", df, _row)
row_end = self.find_point("backward", step, margin, threshold, "a4", data_file, "gt", df, _row)
row_middle = self.find_point("backward", step, margin, threshold, "a5", data_file, "lt", df, row_end)
row_start = self.find_point("backward", step, margin, threshold, "a6", data_file, "gt", df, row_middle)
# print(f"row_end = {row_end}")
# print(f"row_middle = {row_middle}")
# print(f"row_start = {row_start}")
return row_end-row_middle, row_middle-row_start, row_end-row_start, df
def initialization(self):
_, data_files = clibs.traversal_files(self.dir_path, self.output)
for data_file in data_files:
if not data_file.lower().endswith(".csv"):
self.logger("ERROR", "wavelogger-initialization", f"init: {data_file} 文件后缀错误,只允许 .csv 文件,需要确认!", "red", "FileTypeError")
return data_files
def preparation(self, data_file, step, margin, threshold, wb):
shtname = data_file.split("/")[-1].split(".")[0]
ws = wb.create_sheet(shtname)
low, high, cycle, df = self.get_cycle_info(data_file, step, margin, threshold)
return ws, df, low, high, cycle
def single_file_proc(self, ws, data_file, step, threshold, margin, data_length, df, cycle):
row, row_lt, row_gt, count, count_i, data = 1, 1, 1, 1, 1, {}
row_max = len(df) - margin
while row < row_max:
if count not in data.keys():
data[count] = []
value = float(df.iloc[row, 2])
if value < threshold:
row_lt = self.find_point("forward", step, margin, threshold, "c"+str(row), data_file, "lt", df, row)
start = int(row_gt + (row_lt - row_gt - data_length) / 2)
end = start + data_length
value = df.iloc[start:end, 2].astype(float).mean() + 3 * df.iloc[start:end, 2].astype(float).std()
if value > 1:
msg = f"\n"
self.logger("WARNING", "wavelogger-single_file_proc", f"{data_file} 文件第 {count} 轮 第 {count_i} 个数据可能有问题,需人工手动确认,确认有问题可删除,无问题则保留", "purple")
data[count].append(value)
count_i += 1
else:
row_gt = self.find_point("forward", step, margin, threshold, "c"+str(row), data_file, "gt", df, row)
if row_gt - row_lt > cycle * 2:
count += 1
count_i = 1
row = max(row_gt, row_lt)
for i in range(2, 10):
ws.cell(row=1, column=i).value = f"{i-1}次测试"
ws.cell(row=i, column=1).value = f"{i-1}次精度变化"
for i in sorted(data.keys()):
row, column = 2, i + 1
for value in data[i]:
ws.cell(row=row, column=column).value = float(value)
row += 1
def execution(self, data_files):
self.logger("INFO", "wavelogger-execution", "正在处理中......", "blue")
wb = openpyxl.Workbook()
step, margin, data_length, threshold = 5, 50, 50, 5
for data_file in data_files:
ws, df, low, high, cycle = self.preparation(data_file, step, margin, threshold, wb)
self.single_file_proc(ws, data_file, step, threshold, margin, data_length, df, cycle)
wd = "/".join(data_files[0].split("/")[:-1])
filename = wd + "/result.xlsx"
wb.save(filename)
wb.close()
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
data_files = self.initialization()
self.execution(data_files)
self.logger("INFO", "wavelogger-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\n"
self.logger("INFO", "wavelogger-processing", msg)

374
code/autotest/do_brake.py Normal file
View File

@ -0,0 +1,374 @@
import time
import os
import paramiko
import openpyxl
import pandas
import json
from PySide6.QtCore import Signal, QThread
from common import clibs
class DoBrakeTest(QThread):
output = Signal(str, str)
def __init__(self, dir_path, tool, /):
super().__init__()
self.dir_path = dir_path
self.tool = tool
self.idx = 4
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():
msg = "初始路径下不允许有文件夹,初始路径下只能存在如下五个文件,且文件为关闭状态,确认后重新运行!<br>"
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:
self.logger("ERROR", "do_brake-check_files", msg, "red", "InitFileError")
config_file, reach33_file, reach66_file, reach100_file, prj_file, result_dirs = None, None, None, None, None, []
for data_file in data_files:
filename = data_file.split("/")[-1]
if filename == "configs.xlsx":
config_file = data_file
elif filename.startswith("reach33_") and filename.endswith(".xlsx"):
reach33_file = data_file
elif filename.startswith("reach66_") and filename.endswith(".xlsx"):
reach66_file = data_file
elif filename.startswith("reach100_") and filename.endswith(".xlsx"):
reach100_file = data_file
elif filename.endswith(".zip"):
prj_file = data_file
else:
self.logger("ERROR", "do_brake-check_files", msg, "red", "InitFileError")
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}/j2")
os.mkdir(f"{self.dir_path}/j3")
load = f"load{self.tool.removeprefix('tool')}"
for reach in ["reach33", "reach66", "reach100"]:
for speed in ["speed33", "speed66", "speed100"]:
dir_name = "_".join([reach, load, speed])
result_dirs.append(dir_name)
os.mkdir(f"{self.dir_path}/j1/{dir_name}")
os.mkdir(f"{self.dir_path}/j2/{dir_name}")
if reach == "reach100":
os.mkdir(f"{self.dir_path}/j3/{dir_name}")
self.logger("INFO", "do_brake-check_files", "数据目录合规性检查结束,未发现问题......", "green")
return config_file, prj_file, result_dirs
else:
self.logger("ERROR", "do_brake-check_files", msg, "red", "InitFileError")
def get_configs():
robot_type = 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", "do_brake-get_configs", f"无法打开 {local_file}<br>{Err}", "red", "OpenFileError")
# 最大角速度,额定电流,减速比,额定转速
version = configs["VERSION"]
avs = configs["MOTION"]["JOINT_MAX_SPEED"]
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 机型文件版本 {robot_type}_{version}")
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}")
return avs
_config_file, _prj_file, _result_dirs = check_files()
_avs = get_configs()
return _config_file, _prj_file, _result_dirs, _avs
def gen_result_file(self, axis, t_end, reach, load, speed, speed_max, rounds):
d_vel, d_trq, d_stop, threshold = [], [], [], 0.95
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t_end-12))
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t_end))
try:
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")
records = clibs.cursor.fetchall()
finally:
clibs.lock.release()
for record in records: # 保留最后12s的数据
data = eval(record[0])["data"]
for item in data:
d_item = reversed(item["value"])
if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback":
d_vel.extend(d_item)
elif item.get("channel", None) == axis-1 and item.get("name", None) == "device_servo_trq_feedback":
d_trq.extend(d_item)
elif item.get("channel", None) == 0 and item.get("name", None) == "device_safety_estop":
d_stop.extend(d_item)
idx = 0
for idx in range(len(d_stop)-10, 0, -1):
if d_stop[idx] == 1:
break
av_estop = abs(sum(d_vel[idx - 20:idx])/20 * clibs.RADIAN)
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")
clibs.count += 1
if clibs.count < 3:
return "retry"
else:
clibs.count = 0
self.logger("WARNING", "do_brake-gen_result_file",f"尝试三次后仍无法获取正确数据,本次数据无效,继续执行...", "red")
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
df3 = pandas.DataFrame.from_dict({"device_safety_estop": d_stop})
df = pandas.concat([df1, df2, df3], axis=1)
filename = f"{self.dir_path}/j{axis}/reach{reach}_load{load}_speed{speed}/reach{reach}_load{load}_speed{speed}_{rounds}.data"
df.to_csv(filename, sep="\t", index=False)
@staticmethod
def change_curve_state(stat):
if not stat:
display_pdo_params = []
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.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.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
def run_rl(self, config_file, prj_file, result_dirs, avs):
count, total, speed_target = 0, 63, 0
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
wb = openpyxl.load_workbook(config_file, read_only=True)
ws = wb["Target"]
write_diagnosis = float(ws.cell(row=2, column=2).value)
get_init_speed = float(ws.cell(row=3, column=2).value)
single_brake = str(ws.cell(row=4, column=2).value)
pon = ws.cell(row=5, column=2).value
io_name = ws.cell(row=6, column=2).value.upper().strip()
wb.close()
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)
if pon == "positive":
clibs.c_md.write_pon(1)
elif pon == "negative":
clibs.c_md.write_pon(0)
else:
self.logger("ERROR", "do_brake-run_rl", "configs.xlsx 中 Target 页面 B5 单元格填写不正确,检查后重新运行...", "red", "DirectionError")
self.change_curve_state(True)
for condition in result_dirs:
reach = condition.split("_")[0].removeprefix("reach")
load = condition.split("_")[1].removeprefix("load")
speed = condition.split("_")[2].removeprefix("speed")
# for single condition test
single_axis = -1
if single_brake != "0":
total = 3
single_axis = int(single_brake.split("-")[0])
if reach != single_brake.split("-")[1] or load != single_brake.split("-")[2] or speed != single_brake.split("-")[3]:
continue
for axis in range(1, 4):
# for single condition test
if (single_axis != -1 and single_axis != axis) or (axis == 3 and reach != "100"):
continue
clibs.c_md.write_axis(axis)
self.logger("INFO", "brake-processing", "-" * 90, "purple", flag="signal")
speed_max = 0
for rounds in range(1, 4):
count += 1
_ = 3 if count % 3 == 0 else count % 3
this_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
prj_path = f"{prj_name}/_build/{prj_name}.prj"
msg = f"[{this_time} | {count}/{total}] 正在执行 {axis}{condition} 的第 {_} 次制动测试..."
self.logger("INFO", "do_brake-run_rl", msg)
# 1. 触发软急停,并解除,目的是让可能正在运行着的机器停下来,切手动模式并下电
clibs.c_md.r_soft_estop(0)
clibs.c_md.r_soft_estop(1)
clibs.c_ec.setdo_value(io_name, "true")
clibs.c_md.r_reset_estop()
clibs.c_md.r_clear_alarm()
clibs.c_md.write_act(0)
while count % 3 == 1:
# 2. 修改要执行的场景
rl_cmd = ""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=clibs.ip_addr, port=clibs.ssh_port, username=clibs.username, password=clibs.password)
if pon == "positive":
rl_cmd = f"brake_E(j{axis}_{reach}_p, j{axis}_{reach}_n, p_speed, p_tool)"
elif pon == "negative":
rl_cmd = f"brake_E(j{axis}_{reach}_n, j{axis}_{reach}_p, p_speed, p_tool)"
rl_speed = f"VelSet {speed}"
rl_tool = f"tool p_tool = {self.tool}"
cmd = "cd /home/luoshi/bin/controller/; "
cmd += f'sudo sed -i "/brake_E/d" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/DONOTDELETE/i {rl_cmd}" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/VelSet/d" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/MoveAbsJ/i {rl_speed}" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/tool p_tool/d" projects/{prj_name}/_build/brake/main.mod; '
cmd += f'sudo sed -i "/VelSet/i {rl_tool}" projects/{prj_name}/_build/brake/main.mod; '
stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
stdin.write(clibs.password + "\n")
stdout.read().decode() # 需要read一下才能正常执行
stderr.read().decode()
# 3. reload工程后pp2main并且自动模式和上电最后运行程序
clibs.c_hr.execution("overview.reload", prj_path=prj_path, tasks=["brake"])
clibs.c_hr.execution("rl_task.pp_to_main", tasks=["brake"])
clibs.c_hr.execution("state.switch_auto")
clibs.c_hr.execution("state.switch_motor_on")
clibs.c_hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
clibs.c_hr.execution("rl_task.run", tasks=["brake"])
t_start = time.time()
while True:
if clibs.c_md.read_ready_to_go() == 1:
clibs.c_md.write_act(True)
break
else:
time.sleep(1)
if (time.time() - t_start) > 15:
self.logger("ERROR", "do_brake-run_rl", "15s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
# 4. 找出最大速度传递给RL程序最后清除相关记录
time.sleep(5) # 消除前 5s 的不稳定数据
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
time.sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度可通过configs.xlsx配置
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
clibs.c_hr.execution("rl_task.stop", tasks=["brake"])
# 找出最大速度
@clibs.db_lock
def get_speed_max():
_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")
records = clibs.cursor.fetchall()
for record in records:
data = eval(record[0])["data"]
for item in data:
if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback":
_ = clibs.RADIAN * sum(item["value"]) / len(item["value"])
if pon == "positive":
_speed_max = max(_, _speed_max)
elif pon == "negative":
_speed_max = min(_, _speed_max)
return _speed_max
speed_max = abs(get_speed_max())
speed_target = avs[axis-1] * float(speed) / 100
clibs.insert_logdb("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:
self.logger("WARNING", "do_brake-run_rl", 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)
if speed_max < 10:
clibs.c_md.r_clear_alarm()
self.logger("WARNING", "do_brake-run_rl", f"未获取到正确的速度,即将重新获取...", "red")
continue
else:
break
while 1:
clibs.c_ec.setdo_value(io_name, "true")
clibs.c_md.r_reset_estop()
clibs.c_md.r_clear_alarm()
clibs.c_md.write_act(0)
# 5. 重新运行程序发送继续运动信号当速度达到最大值时通过DO触发急停
clibs.c_hr.execution("rl_task.pp_to_main", tasks=["brake"])
clibs.c_hr.execution("state.switch_auto")
clibs.c_hr.execution("state.switch_motor_on")
t_start = time.time()
while 1:
clibs.c_md.r_clear_alarm()
clibs.c_hr.execution("rl_task.run", tasks=["brake"])
time.sleep(1)
if clibs.c_md.w_program_state == 1:
break
else:
time.sleep(5)
if time.time() - t_start > 60:
self.logger("ERROR", "do_brake-run_rl","60s 内程序未能正常执行,需检查...", "red", "RlProgramStartTimeout")
for i in range(16):
if clibs.c_md.read_ready_to_go() == 1:
clibs.c_md.write_act(1)
break
else:
time.sleep(1)
else:
self.logger("ERROR", "do_brake-run_rl", "16s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
def exec_brake():
flag, start, data, record = True, time.time(), None, None
while flag:
time.sleep(0.05)
if time.time() - start > 20:
self.logger("ERROR", "do_brake-exec_brake", "20s 内未触发急停,需排查......", "red", "BrakeTimeoutError")
try:
clibs.lock.acquire(True)
clibs.cursor.execute(f"select content from logs where content like '%diagnosis.result%' order by id desc limit 1")
record = clibs.cursor.fetchone()
data = eval(record[0])["data"]
finally:
clibs.lock.release()
for item in data:
if item.get("channel", None) != axis-1 or item.get("name", None) != "hw_joint_vel_feedback":
continue
speed_moment = clibs.RADIAN * sum(item["value"]) / len(item["value"])
if abs(speed_moment) > speed_max - 2:
if (pon == "positive" and speed_moment > 0) or (pon == "negative" and speed_moment < 0):
clibs.c_ec.setdo_value(io_name, "false")
time.sleep(2)
flag = False
break
return time.time()
time.sleep(11) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
t_end = exec_brake()
# 6. 保留数据并处理输出
ret = self.gen_result_file(axis, t_end, reach, load, speed, speed_max, rounds)
if ret != "retry":
clibs.count = 0
break
else:
time.sleep(50) # why?
self.change_curve_state(False)
msg = f"\n{self.tool.removeprefix('tool')}%负载的制动性能测试执行完毕,如需采集其他负载,须切换负载类型,并更换其他负载,重新执行"
self.logger("INFO", "do_brake-run_rl", msg, "green")
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
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)
clibs.c_pd.push_prj_to_server(prj_file)
self.run_rl(config_file, prj_file, result_dirs, avs)
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)

268
code/autotest/do_current.py Normal file
View File

@ -0,0 +1,268 @@
import os
import threading
import time
import paramiko
import pandas
from PySide6.QtCore import Signal, QThread
from common import clibs
class DoBrakeTest(QThread):
output = Signal(str, str)
def __init__(self, dir_path, tool, /):
super().__init__()
self.dir_path = dir_path
self.tool = tool
self.idx = 5
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():
msg = "初始路径下不允许有文件夹,初始路径下只能存在如下两个文件,且文件为关闭状态,确认后重新运行!<br>"
msg += "1. T_电机电流.xlsx<br>2. xxxx.zip"
if len(data_dirs) != 0 or len(data_files) != 2:
self.logger("ERROR", "do_current-check_files", msg, "red", "InitFileError")
prj_file, count = None, 0
for data_file in data_files:
filename = data_file.split("/")[-1]
if filename == "T_电机电流.xlsx":
count += 1
elif filename.endswith(".zip"):
count += 1
prj_file = data_file
else:
self.logger("ERROR", "do_current-check_files", msg, "red", "InitFileError")
if count != 2:
self.logger("ERROR", "do_current-check_files", msg, "red", "InitFileError")
self.logger("INFO", "do_current-check_files", "数据目录合规性检查结束,未发现问题......", "green")
if self.tool == "tool100":
os.mkdir(f"{self.dir_path}/single")
os.mkdir(f"{self.dir_path}/s_1")
os.mkdir(f"{self.dir_path}/s_2")
os.mkdir(f"{self.dir_path}/s_3")
elif self.tool == "inertia":
os.mkdir(f"{self.dir_path}/inertia")
else:
self.logger("ERROR", "do_current-check_files", "负载选择错误,电机电流测试只能选择 tool100/inertia 规格!", "red", "LoadSelectError")
return prj_file
def get_configs():
robot_type = 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)
_prj_file = check_files()
get_configs()
return _prj_file
def single_axis_proc(self, records, number):
text = "single" if number < 6 else "hold"
number = number if number < 6 else number - 6
d_vel, d_trq, d_sensor, d_trans = [], [], [], []
for record in records:
data = eval(record[0])["data"]
for item in data:
d_item = reversed(item["value"])
if item.get("channel", None) == number and item.get("name", None) == "hw_joint_vel_feedback":
d_vel.extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "device_servo_trq_feedback":
d_trq.extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_sensor_trq_feedback":
d_sensor.extend(d_item)
elif item.get("channel", None) == number and item.get("name", None) == "hw_estimate_trans_trq_res":
d_trans.extend(d_item)
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
df4 = pandas.DataFrame.from_dict({"hw_estimate_trans_trq_res": d_trans})
df = pandas.concat([df1, df2, df3, df4], axis=1)
filename = f"{self.dir_path}/single/j{number + 1}_{text}_{time.time()}.data"
df.to_csv(filename, sep="\t", index=False)
def scenario_proc(self, records, number, scenario_time):
d_vel, d_trq, d_sensor, d_trans = [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []], [[], [], [], [], [], []]
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_vel[axis].extend(d_item)
elif item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
d_trq[axis].extend(d_item)
elif item.get("channel", None) == axis and item.get("name", None) == "hw_sensor_trq_feedback":
d_sensor[axis].extend(d_item)
elif item.get("channel", None) == axis and item.get("name", None) == "hw_estimate_trans_trq_res":
d_trans[axis].extend(d_item)
for axis in range(6):
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel[axis]})
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq[axis]})
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor[axis]})
df4 = pandas.DataFrame.from_dict({"hw_estimate_trans_trq_res": d_trans[axis]})
df = pandas.concat([df1, df2, df3, df4], axis=1)
filename = f"{self.dir_path}/s_{number-11}/j{axis+1}_s_{number-11}_{scenario_time}_{time.time()}.data"
df.to_csv(filename, sep="\t", index=False)
def gen_result_file(self, number, start_time, end_time, scenario_time):
def get_records(s_time, e_time):
clibs.cursor.execute(f"select content from logs where time between '{s_time}' and '{e_time}' and content like '%diagnosis.result%' order by id asc")
_ = clibs.cursor.fetchall()
return _
if number < 12:
records = get_records(start_time, end_time)
t = threading.Thread(target=self.single_axis_proc, args=(records, number))
t.daemon = True
t.start()
elif number < 15:
records = get_records(start_time, end_time)
t = threading.Thread(target=self.scenario_proc, args=(records, number, scenario_time))
t.daemon = True
t.start()
@staticmethod
def change_curve_state(stat):
curves = ["hw_joint_vel_feedback", "device_servo_trq_feedback", "hw_sensor_trq_feedback", "hw_estimate_trans_trq_res"]
display_pdo_params = [] if not stat else [{"name": curve, "channel": chl} for curve 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, prj_file):
prj_name = ".".join(prj_file.split("/")[-1].split(".")[:-1])
c_regular = [
"scenario(0, j1_p, j1_n, p_speed, p_tool, i_tool)",
"scenario(0, j2_p, j2_n, p_speed, p_tool, i_tool)",
"scenario(0, j3_p, j3_n, p_speed, p_tool, i_tool)",
"scenario(0, j4_p, j4_n, p_speed, p_tool, i_tool)",
"scenario(0, j5_p, j5_n, p_speed, p_tool, i_tool)",
"scenario(0, j6_p, j6_n, p_speed, p_tool, i_tool)",
"scenario(4, j1_hold, j1_hold, p_speed, p_tool, i_tool)",
"scenario(4, j2_hold, j2_hold, p_speed, p_tool, i_tool)",
"scenario(4, j3_hold, j3_hold, p_speed, p_tool, i_tool)",
"scenario(4, j4_hold, j4_hold, p_speed, p_tool, i_tool)",
"scenario(4, j5_hold, j5_hold, p_speed, p_tool, i_tool)",
"scenario(4, j6_hold, j6_hold, p_speed, p_tool, i_tool)",
"scenario(1, j6_p, j6_n, p_speed, p_tool, i_tool)",
"scenario(2, j6_p, j6_n, p_speed, p_tool, i_tool)",
"scenario(3, j6_p, j6_n, p_speed, p_tool, i_tool)",
]
c_inertia = [
"scenario(5, j4_p_inertia, j4_n_inertia, p_speed, p_tool, i_tool)",
"scenario(5, j5_p_inertia, j5_n_inertia, p_speed, p_tool, i_tool)",
"scenario(5, j6_p_inertia, j6_n_inertia, p_speed, p_tool, i_tool)",
]
disc_regular = ["一轴", "二轴", "三轴", "四轴", "五轴", "六轴", "一轴保持", "二轴保持", "三轴保持", "四轴保持", "五轴保持", "六轴保持", "场景一", "场景二", "场景三"]
disc_inertia = ["四轴惯量", "五轴惯量", "六轴惯量"]
conditions, disc = [], []
if self.tool == "tool100":
conditions, disc = c_regular, disc_regular
elif self.tool == "inertia":
conditions, disc = c_inertia, disc_inertia
# 打开诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来
clibs.c_md.r_soft_estop(0)
clibs.c_md.r_soft_estop(1)
clibs.c_md.r_clear_alarm()
for condition in conditions:
number = conditions.index(condition)
self.logger("INFO", "do_current-run_rl", f"正在执行{disc[number]}测试......")
# 1. 将act重置为False并修改将要执行的场景
clibs.c_md.write_act(False)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(clibs.ip_addr, clibs.ssh_port, username=clibs.username, password=clibs.password)
cmd = "cd /home/luoshi/bin/controller/; "
cmd += f'sudo sed -i "/scenario/d" projects/{prj_name}/_build/current/main.mod; '
cmd += f'sudo sed -i "/DONOTDELETE/i {condition}" projects/{prj_name}/_build/current/main.mod'
stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
stdin.write(clibs.password + "\n")
stdout.read().decode() # 需要read一下才能正常执行
stderr.read().decode()
# 2. reload工程后pp2main并且自动模式和上电
prj_path = f"{prj_name}/_build/{prj_name}.prj"
clibs.c_hr.execution("overview.reload", prj_path=prj_path, tasks=["current"])
clibs.c_hr.execution("rl_task.pp_to_main", tasks=["current"])
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=["current"])
t_start = time.time()
while True:
if clibs.c_md.read_ready_to_go() == 1:
clibs.c_md.write_act(True)
break
else:
time.sleep(1)
if (time.time() - t_start) > 15:
self.logger("ERROR", "do_current-run_rl", "15s 内未收到机器人的运行信号需要确认RL程序和工具通信是否正常执行...", "red", "ReadySignalTimeoutError")
# 4. 执行采集
time.sleep(10) # 消除前 10s 的不稳定数据
self.change_curve_state(True)
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
single_time, stall_time, scenario_time = 40, 10, 0
if number < 6: # 单轴
time.sleep(single_time)
elif number < 12: # 堵转
time.sleep(stall_time)
else: # 场景
t_start = time.time()
while True:
scenario_time = float(f"{float(clibs.c_md.read_scenario_time()):.2f}")
if float(scenario_time) != 0:
self.logger("INFO", "do_current-run_rl", f"场景{number - 11}的周期时间:{scenario_time}")
break
else:
time.sleep(1)
if (time.time()-t_start) > 180:
self.logger("ERROR", "do_current-run_rl", f"180s 内未收到场景{number - 11}的周期时间需要确认RL程序和工具通信交互是否正常执行...", "red", "GetScenarioTimeError")
time.sleep(20)
# 5.停止程序运行,保留数据并处理输出
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
clibs.c_hr.execution("rl_task.stop", tasks=["current"])
time.sleep(2) # 确保数据都拿到
self.change_curve_state(False)
self.gen_result_file(number, start_time, end_time, scenario_time)
else:
if self.tool == "tool100":
self.logger("INFO", "do_current-run_rl", "单轴和场景电机电流采集完毕,如需采集惯量负载,须切换负载类型,并更换惯量负载,重新执行", "green")
elif self.tool == "inertia":
self.logger("INFO", "do_current-run_rl", "惯量负载电机电流采集完毕,如需采集单轴/场景/保持电机电流,须切换负载类型,并更换偏置负载,重新执行", "green")
def processing(self):
time_start = time.time()
clibs.running[self.idx] = 1
data_dirs, data_files = clibs.traversal_files(self.dir_path, self.output)
prj_file = self.initialization(data_dirs, data_files)
clibs.c_pd.push_prj_to_server(prj_file)
self.run_rl(prj_file)
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)

62
code/common/clibs.py Normal file
View File

@ -0,0 +1,62 @@
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 # 各个指标所在列

2577
code/common/openapi.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
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
#

View File

@ -0,0 +1,239 @@
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)

113
code/test.py Normal file
View File

@ -0,0 +1,113 @@
import time
# import common.openapi as openapi
#
# hr = openapi.HmiRequest("10.2.21.252", 5050, 6666)
# for _ in range(3):
# hr.execution("controller.heart")
# time.sleep(1)
#
# hr.close()
import pymysql
conn = pymysql.connect(host='10.2.20.216', user='root', password='Rokae_123457', port=13306, charset='utf8')
cursor = conn.cursor()
cursor.execute("SET autocommit = 1;")
cursor.execute("use fanmingfu;")
# cursor.execute("insert into 20250315153551_log (module, level, content) values (%s, %s, %s)", ("aioaaaaaa", "debug", "testing information"))
# logger("ERROR", "clibs", f"数据文件夹{dir_path}不存在,请确认后重试......\n", signal, "red", "PathNotExistError", idx)
level = "ERROR"
module = "clibs"
content = "{'data': {'name': 'xCore'}, 'id': 'controller.heart-1742374255.8898985'}"
tb_name = "20250319162718_log"
cursor.execute(f"INSERT INTO {tb_name} (level, module, content) VALUES (%s, %s, %s)", (level, module, content))
# conn.commit()
# ============================================
# def tttt(flag, signal, cursor, **data):
# if flag == "signal":
# print(f"data = {data['signals']}")
# elif flag == "cursor":
# print(f"data = {data['cursors']}")
# elif flag == "both":
# print(f"data = {data}")
# print(f"data = {data['signals']}")
# print(f"data = {data['cursors']}")
#
#
# tttt("both", 1, 1, signals=123, cursors=456)
# ============================================
# import sys
# from time import sleep
# from PySide6.QtCore import *
# from PySide6.QtGui import *
# from PySide6.QtWidgets import *
#
#
# class MyWindow(QMainWindow):
# range_number = Signal(int)
#
# def __init__(self) -> None:
# super().__init__()
# self.setWindowTitle("QThread学习")
# self.resize(800, 600)
# self.setup_ui()
# self.setup_thread()
#
# def setup_ui(self):
# self.mylistwidget = QListWidget(self)
# self.mylistwidget.resize(500, 500)
# self.mylistwidget.move(20, 20)
#
# self.additem_button = QPushButton(self)
# self.additem_button.resize(150, 30)
# self.additem_button.setText("填充QListWidget")
# self.additem_button.move(530, 20)
#
# def setup_thread(self):
# self.thread1 = QThread(self) # 创建一个线程
# self.range_thread = WorkThread() # 实例化线程类
# self.range_thread.moveToThread(self.thread1) # 将类移动到线程中运行
# # 线程数据传回信号用add_item函数处理
# self.range_thread.range_requested.connect(self.add_item)
# self.additem_button.clicked.connect(self.start_thread)
# self.range_number.connect(self.range_thread.range_proc)
# # self.additem_button.clicked.connect(self.range_thread.range_proc) # 连接到线程类的函数
#
# def start_thread(self):
# self.thread1.start()
# range_number = 30
# self.range_number.emit(range_number) # 发射信号让线程接收需要range多少
#
# def add_item(self, requested_number): # 线程传回参数
# text = f"第{requested_number}项————Item"
# item = QListWidgetItem()
# item.setIcon(QPixmap())
# item.setText(text)
# self.mylistwidget.addItem(item)
#
#
# class WorkThread(QObject):
# range_requested = Signal(int) # 括号里是传出的参数的类型
#
# def __init__(self):
# super().__init__()
#
# def range_proc(self, number): # number即为从主线程接收的参数
# print(number)
# for i in range(number):
# self.range_requested.emit(i) # 发射信号
# sleep(0.5)
#
#
# if __name__ == "__main__":
# app = QApplication(sys.argv)
# window = MyWindow()
# window.show()
# app.exec()

135
code/ui/login_window.py Normal file
View File

@ -0,0 +1,135 @@
# -*- 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

954
code/ui/main_window.py Normal file
View File

@ -0,0 +1,954 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'main.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, QCheckBox, QComboBox, QFormLayout,
QFrame, QHBoxLayout, QHeaderView, QLabel,
QLineEdit, QMainWindow, QPlainTextEdit, QPushButton,
QScrollArea, QSizePolicy, QSpacerItem, QStackedWidget,
QStatusBar, QTabWidget, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget)
class Ui_MainWindow(QMainWindow):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.setEnabled(True)
MainWindow.resize(1002, 555)
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QSize(1000, 550))
font = QFont()
font.setFamilies([u"Consolas"])
font.setPointSize(14)
MainWindow.setFont(font)
icon = QIcon()
icon.addFile(u"../assets/media/icon.ico", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
MainWindow.setWindowIcon(icon)
MainWindow.setStyleSheet(u"background-color: rgb(233, 233, 233);")
MainWindow.setDocumentMode(False)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.formLayout = QFormLayout(self.centralwidget)
self.formLayout.setObjectName(u"formLayout")
self.vl_1_left = QVBoxLayout()
self.vl_1_left.setObjectName(u"vl_1_left")
self.label = QLabel(self.centralwidget)
self.label.setObjectName(u"label")
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy1)
self.label.setMinimumSize(QSize(200, 100))
self.label.setMaximumSize(QSize(240, 120))
font1 = QFont()
font1.setFamilies([u"Segoe Print"])
font1.setPointSize(24)
font1.setBold(True)
self.label.setFont(font1)
self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.label.setMargin(0)
self.vl_1_left.addWidget(self.label, 0, Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)
self.btn_start = QPushButton(self.centralwidget)
self.btn_start.setObjectName(u"btn_start")
sizePolicy1.setHeightForWidth(self.btn_start.sizePolicy().hasHeightForWidth())
self.btn_start.setSizePolicy(sizePolicy1)
self.btn_start.setMinimumSize(QSize(150, 36))
self.btn_start.setMaximumSize(QSize(180, 45))
font2 = QFont()
font2.setFamilies([u"Consolas"])
font2.setPointSize(14)
font2.setBold(True)
self.btn_start.setFont(font2)
self.btn_start.setFlat(False)
self.vl_1_left.addWidget(self.btn_start, 0, Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)
self.btn_stop = QPushButton(self.centralwidget)
self.btn_stop.setObjectName(u"btn_stop")
sizePolicy1.setHeightForWidth(self.btn_stop.sizePolicy().hasHeightForWidth())
self.btn_stop.setSizePolicy(sizePolicy1)
self.btn_stop.setMinimumSize(QSize(150, 36))
self.btn_stop.setMaximumSize(QSize(180, 45))
self.btn_stop.setFont(font2)
self.btn_stop.setFlat(False)
self.vl_1_left.addWidget(self.btn_stop, 0, Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)
self.btn_reset = QPushButton(self.centralwidget)
self.btn_reset.setObjectName(u"btn_reset")
sizePolicy1.setHeightForWidth(self.btn_reset.sizePolicy().hasHeightForWidth())
self.btn_reset.setSizePolicy(sizePolicy1)
self.btn_reset.setMinimumSize(QSize(150, 36))
self.btn_reset.setMaximumSize(QSize(180, 45))
self.btn_reset.setFont(font2)
self.btn_reset.setFlat(False)
self.vl_1_left.addWidget(self.btn_reset, 0, Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.vl_1_left.addItem(self.verticalSpacer)
self.vl_1_left.setStretch(0, 4)
self.vl_1_left.setStretch(1, 1)
self.vl_1_left.setStretch(2, 1)
self.vl_1_left.setStretch(3, 1)
self.vl_1_left.setStretch(4, 10)
self.formLayout.setLayout(0, QFormLayout.LabelRole, self.vl_1_left)
self.vl_1_right = QVBoxLayout()
self.vl_1_right.setObjectName(u"vl_1_right")
self.tw_funcs = QTabWidget(self.centralwidget)
self.tw_funcs.setObjectName(u"tw_funcs")
sizePolicy.setHeightForWidth(self.tw_funcs.sizePolicy().hasHeightForWidth())
self.tw_funcs.setSizePolicy(sizePolicy)
self.tw_funcs.setMinimumSize(QSize(0, 0))
font3 = QFont()
font3.setPointSize(14)
font3.setBold(True)
self.tw_funcs.setFont(font3)
self.tw_funcs.setElideMode(Qt.TextElideMode.ElideNone)
self.tw_funcs.setUsesScrollButtons(True)
self.tw_funcs.setDocumentMode(True)
self.tw_funcs.setTabsClosable(False)
self.tw_funcs.setTabBarAutoHide(False)
self.tab_data = QWidget()
self.tab_data.setObjectName(u"tab_data")
self.verticalLayout = QVBoxLayout(self.tab_data)
self.verticalLayout.setObjectName(u"verticalLayout")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.cb_data_func = QComboBox(self.tab_data)
self.cb_data_func.addItem("")
self.cb_data_func.addItem("")
self.cb_data_func.addItem("")
self.cb_data_func.addItem("")
self.cb_data_func.setObjectName(u"cb_data_func")
self.cb_data_func.setMinimumSize(QSize(100, 0))
font4 = QFont()
font4.setFamilies([u"Consolas"])
font4.setPointSize(12)
self.cb_data_func.setFont(font4)
self.horizontalLayout.addWidget(self.cb_data_func)
self.cb_data_current = QComboBox(self.tab_data)
self.cb_data_current.addItem("")
self.cb_data_current.addItem("")
self.cb_data_current.addItem("")
self.cb_data_current.setObjectName(u"cb_data_current")
self.cb_data_current.setMinimumSize(QSize(100, 0))
self.cb_data_current.setFont(font4)
self.horizontalLayout.addWidget(self.cb_data_current)
self.label_4 = QLabel(self.tab_data)
self.label_4.setObjectName(u"label_4")
self.label_4.setFont(font4)
self.label_4.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter)
self.horizontalLayout.addWidget(self.label_4)
self.le_data_path = QLineEdit(self.tab_data)
self.le_data_path.setObjectName(u"le_data_path")
self.le_data_path.setFont(font4)
self.le_data_path.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
self.horizontalLayout.addWidget(self.le_data_path)
self.btn_data_open = QPushButton(self.tab_data)
self.btn_data_open.setObjectName(u"btn_data_open")
self.btn_data_open.setMaximumSize(QSize(30, 16777215))
self.btn_data_open.setFont(font4)
self.horizontalLayout.addWidget(self.btn_data_open)
self.horizontalLayout.setStretch(0, 1)
self.horizontalLayout.setStretch(1, 1)
self.horizontalLayout.setStretch(2, 1)
self.horizontalLayout.setStretch(3, 10)
self.horizontalLayout.setStretch(4, 1)
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalSpacer_2 = QSpacerItem(20, 161, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout.addItem(self.verticalSpacer_2)
self.tw_funcs.addTab(self.tab_data, "")
self.tab_unit = QWidget()
self.tab_unit.setObjectName(u"tab_unit")
self.verticalLayout_2 = QVBoxLayout(self.tab_unit)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.hl_2_unit1 = QHBoxLayout()
self.hl_2_unit1.setObjectName(u"hl_2_unit1")
self.cb_unit_func = QComboBox(self.tab_unit)
self.cb_unit_func.addItem("")
self.cb_unit_func.addItem("")
self.cb_unit_func.setObjectName(u"cb_unit_func")
self.cb_unit_func.setMinimumSize(QSize(100, 0))
self.cb_unit_func.setFont(font4)
self.hl_2_unit1.addWidget(self.cb_unit_func)
self.cb_unit_tool = QComboBox(self.tab_unit)
self.cb_unit_tool.addItem("")
self.cb_unit_tool.addItem("")
self.cb_unit_tool.addItem("")
self.cb_unit_tool.addItem("")
self.cb_unit_tool.setObjectName(u"cb_unit_tool")
self.cb_unit_tool.setMinimumSize(QSize(100, 0))
self.cb_unit_tool.setFont(font4)
self.hl_2_unit1.addWidget(self.cb_unit_tool)
self.label_6 = QLabel(self.tab_unit)
self.label_6.setObjectName(u"label_6")
sizePolicy1.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
self.label_6.setSizePolicy(sizePolicy1)
self.label_6.setFont(font4)
self.label_6.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignTrailing|Qt.AlignmentFlag.AlignVCenter)
self.hl_2_unit1.addWidget(self.label_6)
self.le_unit_path = QLineEdit(self.tab_unit)
self.le_unit_path.setObjectName(u"le_unit_path")
self.le_unit_path.setFont(font4)
self.hl_2_unit1.addWidget(self.le_unit_path)
self.btn_unit_open = QPushButton(self.tab_unit)
self.btn_unit_open.setObjectName(u"btn_unit_open")
self.btn_unit_open.setMaximumSize(QSize(30, 16777215))
self.btn_unit_open.setFont(font4)
self.hl_2_unit1.addWidget(self.btn_unit_open)
self.hl_2_unit1.setStretch(0, 1)
self.hl_2_unit1.setStretch(1, 1)
self.hl_2_unit1.setStretch(2, 1)
self.hl_2_unit1.setStretch(3, 10)
self.hl_2_unit1.setStretch(4, 1)
self.verticalLayout_2.addLayout(self.hl_2_unit1)
self.verticalSpacer_3 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_2.addItem(self.verticalSpacer_3)
self.tw_funcs.addTab(self.tab_unit, "")
self.tab_durable = QWidget()
self.tab_durable.setObjectName(u"tab_durable")
self.horizontalLayout_11 = QHBoxLayout(self.tab_durable)
self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
self.horizontalLayout_10 = QHBoxLayout()
self.horizontalLayout_10.setObjectName(u"horizontalLayout_10")
self.verticalLayout_9 = QVBoxLayout()
self.verticalLayout_9.setObjectName(u"verticalLayout_9")
self.frame = QFrame(self.tab_durable)
self.frame.setObjectName(u"frame")
self.frame.setMinimumSize(QSize(200, 0))
self.frame.setMaximumSize(QSize(300, 16777215))
self.frame.setFrameShape(QFrame.Shape.StyledPanel)
self.frame.setFrameShadow(QFrame.Shadow.Raised)
self.verticalLayout_8 = QVBoxLayout(self.frame)
self.verticalLayout_8.setObjectName(u"verticalLayout_8")
self.verticalLayout_7 = QVBoxLayout()
self.verticalLayout_7.setObjectName(u"verticalLayout_7")
self.label_11 = QLabel(self.frame)
self.label_11.setObjectName(u"label_11")
sizePolicy1.setHeightForWidth(self.label_11.sizePolicy().hasHeightForWidth())
self.label_11.setSizePolicy(sizePolicy1)
self.label_11.setFont(font2)
self.label_11.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
self.verticalLayout_7.addWidget(self.label_11)
self.scrollArea = QScrollArea(self.frame)
self.scrollArea.setObjectName(u"scrollArea")
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 211, 78))
self.horizontalLayout_9 = QHBoxLayout(self.scrollAreaWidgetContents)
self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")
self.verticalLayout_5 = QVBoxLayout()
self.verticalLayout_5.setObjectName(u"verticalLayout_5")
self.cb_1 = QCheckBox(self.scrollAreaWidgetContents)
self.cb_1.setObjectName(u"cb_1")
self.cb_1.setFont(font4)
self.verticalLayout_5.addWidget(self.cb_1)
self.cb_2 = QCheckBox(self.scrollAreaWidgetContents)
self.cb_2.setObjectName(u"cb_2")
self.cb_2.setFont(font4)
self.verticalLayout_5.addWidget(self.cb_2)
self.verticalSpacer_5 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_5.addItem(self.verticalSpacer_5)
self.horizontalLayout_9.addLayout(self.verticalLayout_5)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout_7.addWidget(self.scrollArea)
self.verticalLayout_8.addLayout(self.verticalLayout_7)
self.verticalLayout_9.addWidget(self.frame)
self.horizontalLayout_10.addLayout(self.verticalLayout_9)
self.verticalLayout_6 = QVBoxLayout()
self.verticalLayout_6.setObjectName(u"verticalLayout_6")
self.horizontalLayout_6 = QHBoxLayout()
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
self.label_8 = QLabel(self.tab_durable)
self.label_8.setObjectName(u"label_8")
sizePolicy1.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth())
self.label_8.setSizePolicy(sizePolicy1)
self.label_8.setFont(font4)
self.label_8.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.horizontalLayout_6.addWidget(self.label_8)
self.le_durable_path = QLineEdit(self.tab_durable)
self.le_durable_path.setObjectName(u"le_durable_path")
self.le_durable_path.setFont(font4)
self.horizontalLayout_6.addWidget(self.le_durable_path)
self.btn_durable_open = QPushButton(self.tab_durable)
self.btn_durable_open.setObjectName(u"btn_durable_open")
self.btn_durable_open.setMaximumSize(QSize(30, 16777215))
self.btn_durable_open.setFont(font4)
self.horizontalLayout_6.addWidget(self.btn_durable_open)
self.verticalLayout_6.addLayout(self.horizontalLayout_6)
self.horizontalLayout_7 = QHBoxLayout()
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
self.label_9 = QLabel(self.tab_durable)
self.label_9.setObjectName(u"label_9")
sizePolicy1.setHeightForWidth(self.label_9.sizePolicy().hasHeightForWidth())
self.label_9.setSizePolicy(sizePolicy1)
self.label_9.setFont(font4)
self.label_9.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.horizontalLayout_7.addWidget(self.label_9)
self.le_durable_interval = QLineEdit(self.tab_durable)
self.le_durable_interval.setObjectName(u"le_durable_interval")
self.le_durable_interval.setFont(font4)
self.le_durable_interval.setInputMethodHints(Qt.InputMethodHint.ImhNone)
self.horizontalLayout_7.addWidget(self.le_durable_interval)
self.label_10 = QLabel(self.tab_durable)
self.label_10.setObjectName(u"label_10")
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.label_10.sizePolicy().hasHeightForWidth())
self.label_10.setSizePolicy(sizePolicy2)
self.label_10.setMinimumSize(QSize(30, 0))
self.horizontalLayout_7.addWidget(self.label_10)
self.verticalLayout_6.addLayout(self.horizontalLayout_7)
self.horizontalLayout_8 = QHBoxLayout()
self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
self.cb_durable_total = QCheckBox(self.tab_durable)
self.cb_durable_total.setObjectName(u"cb_durable_total")
font5 = QFont()
font5.setFamilies([u"Consolas"])
font5.setPointSize(12)
font5.setBold(True)
self.cb_durable_total.setFont(font5)
self.horizontalLayout_8.addWidget(self.cb_durable_total)
self.btn_draw = QPushButton(self.tab_durable)
self.btn_draw.setObjectName(u"btn_draw")
self.btn_draw.setFont(font5)
self.horizontalLayout_8.addWidget(self.btn_draw)
self.label_3 = QLabel(self.tab_durable)
self.label_3.setObjectName(u"label_3")
self.horizontalLayout_8.addWidget(self.label_3)
self.horizontalLayout_8.setStretch(0, 2)
self.horizontalLayout_8.setStretch(2, 8)
self.verticalLayout_6.addLayout(self.horizontalLayout_8)
self.verticalSpacer_4 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_6.addItem(self.verticalSpacer_4)
self.horizontalLayout_10.addLayout(self.verticalLayout_6)
self.horizontalLayout_10.setStretch(0, 1)
self.horizontalLayout_10.setStretch(1, 2)
self.horizontalLayout_11.addLayout(self.horizontalLayout_10)
self.tw_funcs.addTab(self.tab_durable, "")
self.tab_network = QWidget()
self.tab_network.setObjectName(u"tab_network")
self.horizontalLayout_13 = QHBoxLayout(self.tab_network)
self.horizontalLayout_13.setObjectName(u"horizontalLayout_13")
self.horizontalLayout_12 = QHBoxLayout()
self.horizontalLayout_12.setObjectName(u"horizontalLayout_12")
self.sw_network = QStackedWidget(self.tab_network)
self.sw_network.setObjectName(u"sw_network")
self.page = QWidget()
self.page.setObjectName(u"page")
self.horizontalLayout_14 = QHBoxLayout(self.page)
self.horizontalLayout_14.setObjectName(u"horizontalLayout_14")
self.verticalLayout_10 = QVBoxLayout()
self.verticalLayout_10.setObjectName(u"verticalLayout_10")
self.horizontalLayout_3 = QHBoxLayout()
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.label_2 = QLabel(self.page)
self.label_2.setObjectName(u"label_2")
sizePolicy1.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
self.label_2.setSizePolicy(sizePolicy1)
self.label_2.setMinimumSize(QSize(70, 0))
self.label_2.setFont(font5)
self.label_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.horizontalLayout_3.addWidget(self.label_2)
self.le_hmi_ip = QLineEdit(self.page)
self.le_hmi_ip.setObjectName(u"le_hmi_ip")
self.le_hmi_ip.setMinimumSize(QSize(150, 0))
self.le_hmi_ip.setFont(font4)
self.horizontalLayout_3.addWidget(self.le_hmi_ip)
self.btn_hmi_conn = QPushButton(self.page)
self.btn_hmi_conn.setObjectName(u"btn_hmi_conn")
self.btn_hmi_conn.setFont(font5)
self.horizontalLayout_3.addWidget(self.btn_hmi_conn)
self.label_5 = QLabel(self.page)
self.label_5.setObjectName(u"label_5")
self.label_5.setFont(font4)
self.horizontalLayout_3.addWidget(self.label_5)
self.cb_hmi_cmd = QComboBox(self.page)
self.cb_hmi_cmd.addItem("")
self.cb_hmi_cmd.addItem("")
self.cb_hmi_cmd.addItem("")
self.cb_hmi_cmd.setObjectName(u"cb_hmi_cmd")
self.cb_hmi_cmd.setMinimumSize(QSize(240, 0))
self.cb_hmi_cmd.setFont(font4)
self.horizontalLayout_3.addWidget(self.cb_hmi_cmd)
self.btn_hmi_send = QPushButton(self.page)
self.btn_hmi_send.setObjectName(u"btn_hmi_send")
self.btn_hmi_send.setFont(font5)
self.horizontalLayout_3.addWidget(self.btn_hmi_send)
self.horizontalLayout_3.setStretch(0, 1)
self.horizontalLayout_3.setStretch(1, 4)
self.horizontalLayout_3.setStretch(2, 1)
self.horizontalLayout_3.setStretch(3, 4)
self.horizontalLayout_3.setStretch(4, 8)
self.horizontalLayout_3.setStretch(5, 1)
self.verticalLayout_10.addLayout(self.horizontalLayout_3)
self.horizontalLayout_5 = QHBoxLayout()
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
self.pte_hmi_send = QPlainTextEdit(self.page)
self.pte_hmi_send.setObjectName(u"pte_hmi_send")
self.horizontalLayout_5.addWidget(self.pte_hmi_send)
self.pte_him_recv = QPlainTextEdit(self.page)
self.pte_him_recv.setObjectName(u"pte_him_recv")
self.horizontalLayout_5.addWidget(self.pte_him_recv)
self.verticalLayout_10.addLayout(self.horizontalLayout_5)
self.horizontalLayout_14.addLayout(self.verticalLayout_10)
self.sw_network.addWidget(self.page)
self.page_2 = QWidget()
self.page_2.setObjectName(u"page_2")
self.horizontalLayout_17 = QHBoxLayout(self.page_2)
self.horizontalLayout_17.setObjectName(u"horizontalLayout_17")
self.verticalLayout_11 = QVBoxLayout()
self.verticalLayout_11.setObjectName(u"verticalLayout_11")
self.horizontalLayout_15 = QHBoxLayout()
self.horizontalLayout_15.setObjectName(u"horizontalLayout_15")
self.label_7 = QLabel(self.page_2)
self.label_7.setObjectName(u"label_7")
sizePolicy1.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth())
self.label_7.setSizePolicy(sizePolicy1)
self.label_7.setMinimumSize(QSize(70, 0))
self.label_7.setFont(font5)
self.label_7.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.horizontalLayout_15.addWidget(self.label_7)
self.le_md_port = QLineEdit(self.page_2)
self.le_md_port.setObjectName(u"le_md_port")
self.le_md_port.setMinimumSize(QSize(150, 0))
self.le_md_port.setFont(font4)
self.horizontalLayout_15.addWidget(self.le_md_port)
self.btn_md_conn = QPushButton(self.page_2)
self.btn_md_conn.setObjectName(u"btn_md_conn")
self.btn_md_conn.setFont(font5)
self.horizontalLayout_15.addWidget(self.btn_md_conn)
self.label_12 = QLabel(self.page_2)
self.label_12.setObjectName(u"label_12")
self.label_12.setFont(font4)
self.horizontalLayout_15.addWidget(self.label_12)
self.cb_md_cmd = QComboBox(self.page_2)
self.cb_md_cmd.addItem("")
self.cb_md_cmd.addItem("")
self.cb_md_cmd.setObjectName(u"cb_md_cmd")
self.cb_md_cmd.setMinimumSize(QSize(240, 0))
self.cb_md_cmd.setFont(font4)
self.horizontalLayout_15.addWidget(self.cb_md_cmd)
self.btn_md_send = QPushButton(self.page_2)
self.btn_md_send.setObjectName(u"btn_md_send")
self.btn_md_send.setFont(font5)
self.horizontalLayout_15.addWidget(self.btn_md_send)
self.horizontalLayout_15.setStretch(0, 1)
self.horizontalLayout_15.setStretch(1, 4)
self.horizontalLayout_15.setStretch(2, 1)
self.horizontalLayout_15.setStretch(3, 4)
self.horizontalLayout_15.setStretch(4, 8)
self.horizontalLayout_15.setStretch(5, 1)
self.verticalLayout_11.addLayout(self.horizontalLayout_15)
self.horizontalLayout_16 = QHBoxLayout()
self.horizontalLayout_16.setObjectName(u"horizontalLayout_16")
self.pte_md_send = QPlainTextEdit(self.page_2)
self.pte_md_send.setObjectName(u"pte_md_send")
self.horizontalLayout_16.addWidget(self.pte_md_send)
self.pte_md_recv = QPlainTextEdit(self.page_2)
self.pte_md_recv.setObjectName(u"pte_md_recv")
self.horizontalLayout_16.addWidget(self.pte_md_recv)
self.verticalLayout_11.addLayout(self.horizontalLayout_16)
self.horizontalLayout_17.addLayout(self.verticalLayout_11)
self.sw_network.addWidget(self.page_2)
self.page_3 = QWidget()
self.page_3.setObjectName(u"page_3")
self.horizontalLayout_26 = QHBoxLayout(self.page_3)
self.horizontalLayout_26.setObjectName(u"horizontalLayout_26")
self.verticalLayout_14 = QVBoxLayout()
self.verticalLayout_14.setObjectName(u"verticalLayout_14")
self.horizontalLayout_24 = QHBoxLayout()
self.horizontalLayout_24.setObjectName(u"horizontalLayout_24")
self.label_17 = QLabel(self.page_3)
self.label_17.setObjectName(u"label_17")
sizePolicy1.setHeightForWidth(self.label_17.sizePolicy().hasHeightForWidth())
self.label_17.setSizePolicy(sizePolicy1)
self.label_17.setMinimumSize(QSize(70, 0))
self.label_17.setFont(font5)
self.label_17.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.horizontalLayout_24.addWidget(self.label_17)
self.le_ec_port = QLineEdit(self.page_3)
self.le_ec_port.setObjectName(u"le_ec_port")
self.le_ec_port.setMinimumSize(QSize(150, 0))
self.le_ec_port.setFont(font4)
self.horizontalLayout_24.addWidget(self.le_ec_port)
self.btn_ec_conn = QPushButton(self.page_3)
self.btn_ec_conn.setObjectName(u"btn_ec_conn")
self.btn_ec_conn.setFont(font5)
self.horizontalLayout_24.addWidget(self.btn_ec_conn)
self.label_18 = QLabel(self.page_3)
self.label_18.setObjectName(u"label_18")
self.label_18.setFont(font4)
self.horizontalLayout_24.addWidget(self.label_18)
self.cb_ec_cmd = QComboBox(self.page_3)
self.cb_ec_cmd.addItem("")
self.cb_ec_cmd.addItem("")
self.cb_ec_cmd.setObjectName(u"cb_ec_cmd")
self.cb_ec_cmd.setMinimumSize(QSize(240, 0))
self.cb_ec_cmd.setFont(font4)
self.horizontalLayout_24.addWidget(self.cb_ec_cmd)
self.btn_ec_send = QPushButton(self.page_3)
self.btn_ec_send.setObjectName(u"btn_ec_send")
self.btn_ec_send.setFont(font5)
self.horizontalLayout_24.addWidget(self.btn_ec_send)
self.horizontalLayout_24.setStretch(0, 1)
self.horizontalLayout_24.setStretch(1, 4)
self.horizontalLayout_24.setStretch(2, 1)
self.horizontalLayout_24.setStretch(3, 4)
self.horizontalLayout_24.setStretch(4, 8)
self.horizontalLayout_24.setStretch(5, 1)
self.verticalLayout_14.addLayout(self.horizontalLayout_24)
self.horizontalLayout_25 = QHBoxLayout()
self.horizontalLayout_25.setObjectName(u"horizontalLayout_25")
self.pte_ec_send = QPlainTextEdit(self.page_3)
self.pte_ec_send.setObjectName(u"pte_ec_send")
self.horizontalLayout_25.addWidget(self.pte_ec_send)
self.pte_ec_recv = QPlainTextEdit(self.page_3)
self.pte_ec_recv.setObjectName(u"pte_ec_recv")
self.horizontalLayout_25.addWidget(self.pte_ec_recv)
self.verticalLayout_14.addLayout(self.horizontalLayout_25)
self.horizontalLayout_26.addLayout(self.verticalLayout_14)
self.sw_network.addWidget(self.page_3)
self.horizontalLayout_12.addWidget(self.sw_network)
self.verticalLayout_4 = QVBoxLayout()
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
self.pushButton = QPushButton(self.tab_network)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setFont(font5)
self.verticalLayout_4.addWidget(self.pushButton)
self.pushButton_2 = QPushButton(self.tab_network)
self.pushButton_2.setObjectName(u"pushButton_2")
self.pushButton_2.setFont(font5)
self.verticalLayout_4.addWidget(self.pushButton_2)
self.pushButton_3 = QPushButton(self.tab_network)
self.pushButton_3.setObjectName(u"pushButton_3")
self.pushButton_3.setFont(font5)
self.verticalLayout_4.addWidget(self.pushButton_3)
self.horizontalLayout_12.addLayout(self.verticalLayout_4)
self.horizontalLayout_12.setStretch(0, 11)
self.horizontalLayout_12.setStretch(1, 1)
self.horizontalLayout_13.addLayout(self.horizontalLayout_12)
self.tw_funcs.addTab(self.tab_network, "")
self.vl_1_right.addWidget(self.tw_funcs)
self.tw_docs = QTabWidget(self.centralwidget)
self.tw_docs.setObjectName(u"tw_docs")
self.tw_docs.setFont(font3)
self.tw_docs.setElideMode(Qt.TextElideMode.ElideNone)
self.tw_docs.setDocumentMode(True)
self.tab_output = QWidget()
self.tab_output.setObjectName(u"tab_output")
self.horizontalLayout_4 = QHBoxLayout(self.tab_output)
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
self.pte_output = QPlainTextEdit(self.tab_output)
self.pte_output.setObjectName(u"pte_output")
self.pte_output.setFont(font4)
self.pte_output.setLineWrapMode(QPlainTextEdit.LineWrapMode.WidgetWidth)
self.pte_output.setReadOnly(True)
self.horizontalLayout_4.addWidget(self.pte_output)
self.tw_docs.addTab(self.tab_output, "")
self.tab_log = QWidget()
self.tab_log.setObjectName(u"tab_log")
self.verticalLayout_3 = QVBoxLayout(self.tab_log)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.treew_log = QTreeWidget(self.tab_log)
self.treew_log.setObjectName(u"treew_log")
self.treew_log.setFont(font4)
self.treew_log.header().setVisible(True)
self.verticalLayout_3.addWidget(self.treew_log)
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.label_page = QLabel(self.tab_log)
self.label_page.setObjectName(u"label_page")
self.label_page.setMinimumSize(QSize(100, 0))
font6 = QFont()
font6.setFamilies([u"Consolas"])
font6.setPointSize(10)
font6.setBold(True)
self.label_page.setFont(font6)
self.label_page.setStyleSheet(u"background-color: rgb(222, 222, 222);")
self.label_page.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.horizontalLayout_2.addWidget(self.label_page)
self.btn_docs_previous = QPushButton(self.tab_log)
self.btn_docs_previous.setObjectName(u"btn_docs_previous")
self.btn_docs_previous.setFont(font4)
self.horizontalLayout_2.addWidget(self.btn_docs_previous)
self.btn_docs_realtime = QPushButton(self.tab_log)
self.btn_docs_realtime.setObjectName(u"btn_docs_realtime")
self.btn_docs_realtime.setFont(font4)
self.horizontalLayout_2.addWidget(self.btn_docs_realtime)
self.btn_docs_next = QPushButton(self.tab_log)
self.btn_docs_next.setObjectName(u"btn_docs_next")
self.btn_docs_next.setFont(font4)
self.horizontalLayout_2.addWidget(self.btn_docs_next)
self.btn_docs_load = QPushButton(self.tab_log)
self.btn_docs_load.setObjectName(u"btn_docs_load")
self.btn_docs_load.setFont(font4)
self.horizontalLayout_2.addWidget(self.btn_docs_load)
self.btn_docs_search = QPushButton(self.tab_log)
self.btn_docs_search.setObjectName(u"btn_docs_search")
self.btn_docs_search.setFont(font4)
self.horizontalLayout_2.addWidget(self.btn_docs_search)
self.le_docs_search = QLineEdit(self.tab_log)
self.le_docs_search.setObjectName(u"le_docs_search")
self.le_docs_search.setFont(font4)
self.horizontalLayout_2.addWidget(self.le_docs_search)
self.horizontalLayout_2.setStretch(0, 1)
self.horizontalLayout_2.setStretch(1, 1)
self.horizontalLayout_2.setStretch(2, 1)
self.horizontalLayout_2.setStretch(3, 1)
self.horizontalLayout_2.setStretch(4, 1)
self.horizontalLayout_2.setStretch(5, 1)
self.horizontalLayout_2.setStretch(6, 10)
self.verticalLayout_3.addLayout(self.horizontalLayout_2)
self.tw_docs.addTab(self.tab_log, "")
self.vl_1_right.addWidget(self.tw_docs)
self.vl_1_right.setStretch(0, 1)
self.vl_1_right.setStretch(1, 3)
self.formLayout.setLayout(0, QFormLayout.FieldRole, self.vl_1_right)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
sizePolicy3.setHorizontalStretch(0)
sizePolicy3.setVerticalStretch(0)
sizePolicy3.setHeightForWidth(self.statusbar.sizePolicy().hasHeightForWidth())
self.statusbar.setSizePolicy(sizePolicy3)
self.statusbar.setMinimumSize(QSize(0, 27))
self.statusbar.setStyleSheet(u"background-color: rgb(200, 200, 200);")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.btn_start.clicked.connect(MainWindow.prog_start)
self.btn_stop.clicked.connect(MainWindow.prog_stop)
self.btn_reset.clicked.connect(MainWindow.prog_reset)
self.btn_durable_open.clicked.connect(MainWindow.file_browser)
self.btn_draw.clicked.connect(MainWindow.curve_draw)
self.cb_durable_total.checkStateChanged.connect(MainWindow.durable_cb_change)
self.btn_unit_open.clicked.connect(MainWindow.file_browser)
self.btn_data_open.clicked.connect(MainWindow.file_browser)
self.btn_docs_previous.clicked.connect(MainWindow.pre_page)
self.btn_docs_realtime.clicked.connect(MainWindow.realtime_page)
self.btn_docs_next.clicked.connect(MainWindow.next_page)
self.btn_docs_load.clicked.connect(MainWindow.load_sql)
self.btn_docs_search.clicked.connect(MainWindow.search_keyword)
self.le_docs_search.returnPressed.connect(MainWindow.search_keyword)
self.cb_hmi_cmd.currentTextChanged.connect(MainWindow.hmi_cb_change)
self.btn_hmi_send.clicked.connect(MainWindow.hmi_send)
self.pushButton.clicked.connect(MainWindow.hmi_page)
self.pushButton_2.clicked.connect(MainWindow.md_page)
self.pushButton_3.clicked.connect(MainWindow.ec_page)
self.cb_md_cmd.currentTextChanged.connect(MainWindow.md_cb_change)
self.btn_md_send.clicked.connect(MainWindow.md_send)
self.btn_ec_send.clicked.connect(MainWindow.ec_send)
self.btn_hmi_conn.clicked.connect(MainWindow.hmi_conn)
self.btn_md_conn.clicked.connect(MainWindow.md_conn)
self.btn_ec_conn.clicked.connect(MainWindow.ec_conn)
self.le_durable_interval.editingFinished.connect(MainWindow.check_interval)
self.cb_ec_cmd.currentTextChanged.connect(MainWindow.ec_cb_change)
self.le_hmi_ip.returnPressed.connect(MainWindow.hmi_conn)
self.tw_funcs.setCurrentIndex(0)
self.sw_network.setCurrentIndex(0)
self.tw_docs.setCurrentIndex(1)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Rokae AIO", None))
self.label.setText(QCoreApplication.translate("MainWindow", u"Rokae AIO", None))
self.btn_start.setText(QCoreApplication.translate("MainWindow", u"\u5f00\u59cb\u6267\u884c", None))
self.btn_stop.setText(QCoreApplication.translate("MainWindow", u"\u505c\u6b62\u6267\u884c", None))
self.btn_reset.setText(QCoreApplication.translate("MainWindow", u"\u72b6\u6001\u91cd\u7f6e", None))
self.cb_data_func.setItemText(0, QCoreApplication.translate("MainWindow", u"\u5236\u52a8", None))
self.cb_data_func.setItemText(1, QCoreApplication.translate("MainWindow", u"\u8f6c\u77e9", None))
self.cb_data_func.setItemText(2, QCoreApplication.translate("MainWindow", u"\u6fc0\u5149", None))
self.cb_data_func.setItemText(3, QCoreApplication.translate("MainWindow", u"\u7cbe\u5ea6", None))
self.cb_data_current.setItemText(0, QCoreApplication.translate("MainWindow", u"\u5468\u671f", None))
self.cb_data_current.setItemText(1, QCoreApplication.translate("MainWindow", u"\u6700\u5927\u503c", None))
self.cb_data_current.setItemText(2, QCoreApplication.translate("MainWindow", u"\u5e73\u5747\u503c", None))
self.label_4.setText(QCoreApplication.translate("MainWindow", u"\u8def\u5f84", None))
self.btn_data_open.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_data), QCoreApplication.translate("MainWindow", u"\u6570\u636e\u5904\u7406", None))
self.cb_unit_func.setItemText(0, QCoreApplication.translate("MainWindow", u"\u5236\u52a8", None))
self.cb_unit_func.setItemText(1, QCoreApplication.translate("MainWindow", u"\u8f6c\u77e9", None))
self.cb_unit_tool.setItemText(0, QCoreApplication.translate("MainWindow", u"tool33", None))
self.cb_unit_tool.setItemText(1, QCoreApplication.translate("MainWindow", u"tool66", None))
self.cb_unit_tool.setItemText(2, QCoreApplication.translate("MainWindow", u"tool100", None))
self.cb_unit_tool.setItemText(3, QCoreApplication.translate("MainWindow", u"inertia", None))
self.label_6.setText(QCoreApplication.translate("MainWindow", u"\u8def\u5f84", None))
self.btn_unit_open.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_unit), QCoreApplication.translate("MainWindow", u"\u6574\u673a\u6d4b\u8bd5", None))
self.label_11.setText(QCoreApplication.translate("MainWindow", u"\u9009\u62e9\u6307\u6807", None))
self.cb_1.setText(QCoreApplication.translate("MainWindow", u"\u5468\u671f\u5185\u5e73\u5747\u8f6c\u77e9", None))
self.cb_2.setText(QCoreApplication.translate("MainWindow", u"\u5468\u671f\u5185\u5e73\u5747\u8f6c\u77e9", None))
self.label_8.setText(QCoreApplication.translate("MainWindow", u"\u8def\u5f84", None))
self.btn_durable_open.setText(QCoreApplication.translate("MainWindow", u"...", None))
self.label_9.setText(QCoreApplication.translate("MainWindow", u"\u95f4\u9694", None))
#if QT_CONFIG(whatsthis)
self.le_durable_interval.setWhatsThis("")
#endif // QT_CONFIG(whatsthis)
self.le_durable_interval.setPlaceholderText(QCoreApplication.translate("MainWindow", u"\u6bcf\u6b21\u6570\u636e\u91c7\u96c6\u7684\u65f6\u95f4\u95f4\u9694\uff0c\u9ed8\u8ba4(\u6700\u5c0f)300s", None))
self.label_10.setText("")
self.cb_durable_total.setText(QCoreApplication.translate("MainWindow", u"\u5168\u90e8\u6253\u5f00/\u5173\u95ed", None))
self.btn_draw.setText(QCoreApplication.translate("MainWindow", u"\u7ed8\u56fe", None))
self.label_3.setText("")
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_durable), QCoreApplication.translate("MainWindow", u"\u8010\u4e45\u91c7\u96c6", None))
self.label_2.setText(QCoreApplication.translate("MainWindow", u"HMI IP", None))
self.le_hmi_ip.setText(QCoreApplication.translate("MainWindow", u"192.168.0.160", None))
self.btn_hmi_conn.setText(QCoreApplication.translate("MainWindow", u"\u8fde\u63a5", None))
self.label_5.setText("")
self.cb_hmi_cmd.setItemText(0, QCoreApplication.translate("MainWindow", u"controller.heart", None))
self.cb_hmi_cmd.setItemText(1, QCoreApplication.translate("MainWindow", u"device.get_params", None))
self.cb_hmi_cmd.setItemText(2, QCoreApplication.translate("MainWindow", u"safety_area_data", None))
self.btn_hmi_send.setText(QCoreApplication.translate("MainWindow", u"\u53d1\u9001", None))
self.label_7.setText(QCoreApplication.translate("MainWindow", u"MD Port", None))
self.le_md_port.setText(QCoreApplication.translate("MainWindow", u"502", None))
self.btn_md_conn.setText(QCoreApplication.translate("MainWindow", u"\u8fde\u63a5", None))
self.label_12.setText("")
self.cb_md_cmd.setItemText(0, QCoreApplication.translate("MainWindow", u"ctrl_motor_on", None))
self.cb_md_cmd.setItemText(1, QCoreApplication.translate("MainWindow", u"ctrl_motor_off", None))
self.btn_md_send.setText(QCoreApplication.translate("MainWindow", u"\u53d1\u9001", None))
self.label_17.setText(QCoreApplication.translate("MainWindow", u"EC Port", None))
self.le_ec_port.setText(QCoreApplication.translate("MainWindow", u"8080", None))
self.btn_ec_conn.setText(QCoreApplication.translate("MainWindow", u"\u8fde\u63a5", None))
self.label_18.setText("")
self.cb_ec_cmd.setItemText(0, QCoreApplication.translate("MainWindow", u"motor_on_state", None))
self.cb_ec_cmd.setItemText(1, QCoreApplication.translate("MainWindow", u"robot_running_state", None))
self.btn_ec_send.setText(QCoreApplication.translate("MainWindow", u"\u53d1\u9001", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"HMI", None))
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"Modbus", None))
self.pushButton_3.setText(QCoreApplication.translate("MainWindow", u"EC", None))
self.tw_funcs.setTabText(self.tw_funcs.indexOf(self.tab_network), QCoreApplication.translate("MainWindow", u"\u7f51\u7edc\u8bbe\u7f6e", None))
self.tw_docs.setTabText(self.tw_docs.indexOf(self.tab_output), QCoreApplication.translate("MainWindow", u"\u8f93\u51fa", None))
___qtreewidgetitem = self.treew_log.headerItem()
___qtreewidgetitem.setText(4, QCoreApplication.translate("MainWindow", u"Content", None));
___qtreewidgetitem.setText(3, QCoreApplication.translate("MainWindow", u"Module", None));
___qtreewidgetitem.setText(2, QCoreApplication.translate("MainWindow", u"Level", None));
___qtreewidgetitem.setText(1, QCoreApplication.translate("MainWindow", u"Timestamp", None));
___qtreewidgetitem.setText(0, QCoreApplication.translate("MainWindow", u"ID", None));
self.label_page.setText(QCoreApplication.translate("MainWindow", u"0/0", None))
self.btn_docs_previous.setText(QCoreApplication.translate("MainWindow", u"\u4e0a\u4e00\u9875", None))
self.btn_docs_realtime.setText(QCoreApplication.translate("MainWindow", u"\u5b9e\u65f6", None))
self.btn_docs_next.setText(QCoreApplication.translate("MainWindow", u"\u4e0b\u4e00\u9875", None))
self.btn_docs_load.setText(QCoreApplication.translate("MainWindow", u"\u52a0\u8f7d", None))
self.btn_docs_search.setText(QCoreApplication.translate("MainWindow", u"\u67e5\u627e", None))
self.le_docs_search.setPlaceholderText(QCoreApplication.translate("MainWindow", u"[id/level/module] \u67e5\u627e\u5185\u5bb9", None))
self.tw_docs.setTabText(self.tw_docs.indexOf(self.tab_log), QCoreApplication.translate("MainWindow", u"\u65e5\u5fd7", None))
# retranslateUi

170
code/ui/reset_window.py Normal file
View File

@ -0,0 +1,170 @@
# -*- 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

129
readme.md Normal file
View File

@ -0,0 +1,129 @@
# 珞石测试部自动化工具
针对珞石工业协作六轴机器人的整机测试,该工具可以执行如下自动化操作,以减少人工处理时长,提高测试数据处理的效率和准确度:
1. 制动数据,单轴数据处理 5min 以内
2. 电机电流数据,全部轴数据处理 3min 以内
3. ISO 激光数据整理1min 以内
4. wavelogger 波形处理,几乎不花费时间
5. 制动自动化测试40min 左右
6. 电机电流自动化测试15min 左右
7. 耐久工程相关指标采集记录,可定制曲线并绘图
## 一、处理逻辑以及原理
该部分简要介绍了工具实现的核心逻辑原理,以及执行的必要条件。
### 1. 数据处理
#### A. 制动数据
- 原理:找到 `device_safety_estop` 曲线值由 1 -> 0 的位置,并预留 20 个数据余量截取 1000 个点
- 必要条件:
- 根目录命名为 j1/2/3
- 数据文件夹命名参照执行制动数据采集
- 需要有三个结果文件,命名为 reach33/66/100_xxxxxxxx.xlsx
- 需要有一个机型文件,比如 NB4h-R580-3G.cfg此文件会在执行制动测试的时候自动生成注意保存
#### B. 电机电流
- 单轴原理:找到一个周期的起点和终点
- 堵转原理:求平均均值
- 场景原理:获取场景的执行周期时间,并做数据截取
- 必要条件:
- 数据文件命名参照电机电流测试生成的格式
- 需要有一个结果文件,命名为 T_电机电流.xlsx
- 需要有一个机型文件,比如 NB4h-R580-3G.cfg此文件会在执行制动测试的时候自动生成注意保存
#### C. 激光
- 原理:根据要获取的数据所在位置的特征,过滤提取
- 必要条件:
- 数据文件命名必须参照如下:
- ISO-.pdf
- ISO-V100.pdf
- ISO-V1000.pdf
- 需要有一个结果文件iso-results.xlsx
#### D. 基恩士数据
- 原理:根据数据大小以及出现的周期规律,进行相应的处理,处理完成之后结果文件会自动生成
- 必要条件:需要提前将 `.xdt` 波形数据转换成 `.csv` 文件,数据文件命名必须以 `.csv` 结尾
## 二、自动测试
### 1. 协议封包解包
详见 `assets/files/protocols/`
### 2. 制动测试
- 原理:使用 xCore socket 协议获取诊断数据,包括速度,力矩等信息,结合 modbus 和外部通信执行急停等动作
- 必要条件:
- RL 工程brake任务参考 `assets/files/projects/`,需要详细阅读对应的注释
- 需要有一个配置文件,命名为 configs.xlsx
- 需要有三个结果文件,命名为 reach33/66/100_xxxxxxxx.xlsx
### 3. 电机电流测试
- 原理:使用 xCore socket 协议获取诊断数据,包括速度,力矩等信息,结合 modbus 和外部通信执行急停等动作
- 必要条件:
- RL 工程current任务参考 `assets/files/projects/`,需要详细阅读对应的注释
- 需要有一个结果文件,命名为 T_电机电流.xlsx
## 三、耐久测试数据采集
- 原理:根据设置的时间间隔,采集相应的场景周期指标数据
- 必要条件:
- RL 工程factory任务参考 `assets/files/projects/`,需要详细阅读对应的注释
## 三、注意事项
> **!!仅内网使用!!**
1. 仅适用于 xCore 2.3.0.7 及以上的版本
2. 仅适配了六轴工业/协作机型其他机型可能会存在使用上的问题具体可以找fanmingfu@rokae.com确认
3. 单轴电机电流数据处理,至少需要三个完整周期,使用本工具采集一般不会有问题,主要是针对手动采集命名的数据
4. 执行制动测试/电机电流采集/耐久测试的时候,执行过程中停止,需要重新关闭软件再次打开,才能正常使用
5. RL工程/寄存器文件/configs.xlsx文件已更新需要使用新版其他使用方法和之前工具一致
6. 基恩士采集数据时不同轮次每5次测试数据时间间隔最好大于 2 倍的周期时间,否则会出现采集的轮数不正确的情况,但数据是完整的
7. 激光数据处理只支持英文版本的数据文件
8. 耐久(场景)指标数据采集的工程运行周期需要小于 300s否则会出现异常
> **需要使用 assets/files/projects/ 下的工程,寄存器文件以及配置文件等!!!**
## 四、发版记录
详见 `assets/files/version/release_change.txt` 文件
## 五、其他
### 1. 打包命令
打包时,只需要修改 clibs.py 中的 PREFIX 即可,调试时再修改回来,第三方库依赖详见 `assets/files/version/requirements.txt` 文件
```
pyinstaller --noconfirm --onedir --windowed --optimize 2 --contents-directory . --upx-dir "D:/Syncthing/common/A_Program/upx-4.2.4-win64/" --add-data "../.venv/Lib/site-packages/customtkinter;customtkinter/" --add-data "../assets:assets" --version-file ../assets/files/version/file_version_info.txt -i ../assets/media/icon.ico ../code/aio.py -p ../code/common/clibs.py -p ../code/commom/openapi.py -p ../code/data_process/brake.py -p ../code/data_process/iso.py -p ../code/data_process/current.py -p ../code/data_process/wavelogger.py -p ../code/automatic_test/do_current.py -p ../code/automatic_test/do_brake.py -p ../code/durable_docs/factory_test.py -p ../code/durable_docs/create_plot.py --exclude-module=scipy
```
### 2. tabview 组件字体修改
customtkinter的tabview组件不支持修改字体大小解决方法可参考如下
- Method 1可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现:
+ 运行 `pip show customtkinter`,获取到库的路径
+ 修改.../windows/widgets/ctk_tabview.py
+ 增加 from .font.ctk_font import CTkFont
+ 在大概 78 行的位置,增加 font=CTkFont(family="Consolas", size=18, weight='bold')
- Method 2
直接在源码中修改:`self.tabview_bottom._segmented_button.configure(font=ctk.CTkFont(family="Consolas", size=18, weight="bold"))`
### 3. scroll frame 不支持修改高度和宽度
https://github.com/TomSchimansky/CustomTkinter/pull/1765/files
---

Some files were not shown because too many files have changed in this diff Show More