自动化测试电机电流功能迁移完成
This commit is contained in:
parent
855448664c
commit
2413d6d305
152
assets/files/examples/自动测试/电机电流/NB4h_R580_3G/NB4h-R580-3G.cfg
Normal file
152
assets/files/examples/自动测试/电机电流/NB4h_R580_3G/NB4h-R580-3G.cfg
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
{
|
||||||
|
"ROBOT_NAME": "NB4h-R580-3G",
|
||||||
|
"CONFIGURATION": {
|
||||||
|
"AXES_NUMBER": 6,
|
||||||
|
"CLASS": "INDUSTRIAL",
|
||||||
|
"TYPE": "Standard_6_axes",
|
||||||
|
"PAYLOAD": 4
|
||||||
|
},
|
||||||
|
"VERSION": "ME_AE_SS_xC.v3.0.1.R0",
|
||||||
|
"KINEMATICS": {
|
||||||
|
"ROBOT_DIMENSIONS": [0.0, 0.0, 0.0, 0.0, 0.0, 333.0, 0.0, 0.0, 280.0, 300.0, 0.0, 15.0, 0.0, 0.0, 0.0, 75.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||||
|
"DH_PARAMS": [0.0, 0.0, 333.0, 0.0, -90.0, 0.0, 0.0, -90.0, 0.0, 280.0, 0.0, 0.0, -90.0, 15.0, 300.0, 0.0, 90.0, 0.0, 0.0, 0.0, -90.0, 0.0, 75.0, 180.0, 0.0, 0.0, 0.0, 0.0],
|
||||||
|
"DH_PARAMS_SUPPORT": 0,
|
||||||
|
"JOINT_RANGE_MIN": [-171, -90.3, -200.5, -171.5, -123.25, -360],
|
||||||
|
"JOINT_RANGE_MAX": [171, 130.3, 55.5, 171.5, 123.25, 360],
|
||||||
|
"JOINT_RANGE_MIN_CUSTOMIZE": [-170, -90, -200, -170, -120, -360],
|
||||||
|
"JOINT_RANGE_MAX_CUSTOMIZE": [170, 130, 55, 170, 120, 360],
|
||||||
|
"JOINT_CALIBRATE_ANGLE": [8.55, 0, 0, 66, 0, 0],
|
||||||
|
"TRANSPORT_POSTURE": [0, -20, 51, 0, 59, 0],
|
||||||
|
"DRAG_POSTURE": [0, 0, 0, 0, 0, 0],
|
||||||
|
"ROBOT_DIMENSIONS_AID": []
|
||||||
|
},
|
||||||
|
"DYNAMICS": {
|
||||||
|
"JOINT_DAMPING_GAIN": [1, 1, 1, 1, 1, 1],
|
||||||
|
"JOINT_STIFFNESS_GAIN": [1, 1, 1, 1, 1, 1],
|
||||||
|
"JOINT_DAMPING": [],
|
||||||
|
"JOINT_STIFFNESS": [],
|
||||||
|
"VIBRATION_SUPPRESSION_ENABLE": false,
|
||||||
|
"FLEX_SUPPORT": false,
|
||||||
|
"INERTIA_DEAD_ZONE": [],
|
||||||
|
"FEEDFOREWARD_TRQ_FACTOR": [],
|
||||||
|
"TRAJECTORY_PARAMS": [5, 0.1, -0.04072466, 0.43086896, 0.36515585, 0.67591341, 0.27004892, 0.93559897, 0.267038749999999, 1.25511993, -0.14383751, 0.47007479, 0.310998109999999, 0.290793199999999, -0.239750529999999, 0.7878315, 0.706314809999999, -0.46671499, -0.00693842999999999, -0.19215951, 0.56794257, 0.883894509999999, 0.49373632, 0.01380959, 0.83099347, 0.38849866, 0.76181887, 0.581606489999999, 0.0172037599999999, 0.54098027, 0.656982029999999, 0.99054692, -0.07611184, 0.95722059, 0.75434694, 0.493781409999999, 0.582492939999999, 0.0299886699999999, 0.0905649399999999, -0.12391953, 0.09264124, 0.681803229999999, 0.21261835, -0.10514286, -0.74680413, 0.0146706, -1.57221134999999, 1.45187746999999, -0.4803584, 0.681643499999999, 0.37682458, 0.07648201, -0.05270971, -0.291863309999999, -0.570327359999999, -0.52805053, -0.278856209999999, -0.00355706999999999, 0.08835215, -0.232046439999999, -0.812577149999999, 0.00243426, 0.12064894, 0.327550049999999, -0.58553805, -0.01712549, -0.138711389999999, 0.92037943],
|
||||||
|
"IDENT_PARAMS_NF": [],
|
||||||
|
"PAYLOAD_PARAMS": [-0.0746499999999999, 0.0756249999999999, -0.0756249999999999, 0.275, 0.0790249999999999, 0.0777749999999999, 0.025, 0.28, 0.005329, 0.005329, 0.0729999999999999, 0.145999999999999, 0.145999999999999, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
"MODEL_BUILD_TYPE": 0,
|
||||||
|
"FRICTION_TYPE": 0,
|
||||||
|
"LINK_MASS": [4.542, 3.825, 2.207, 2.915, 1.585, 0.32],
|
||||||
|
"LINK_CENTROID": [-13.755, 16.08, 247.871, -8.709, 15.072, 135.405, 5.145, 6.671, -1.307, -122.719, 0.608, -0.188, 28.128, -1.014, 0.004, -9.557, 0.0, 0.051],
|
||||||
|
"LINK_MOMENT_OF_INERTIA_LOW": [26730.697, 23305.849, 18705.243, -389.139, 981.756, 1367.986, 55818.209, 49259.926, 13261.075, 71.676, -691.385, 1157.377, 4469.258, 4594.973, 5057.332, -88.824, 654.697, -69.477, 4638.362, 20273.735, 21764.076, 225.359, 17.193, 15.37, 1429.243, 2084.235, 2335.733, 45.188, 0.656, -0.408, 197.165, 118.444, 119.352, -0.0, 0.085, -0.0],
|
||||||
|
"MOTOR_INERTIA": [835553.702, 420546.841, 212626.306, 86013.415, 38263.971, 157525.725],
|
||||||
|
"CUBIC_FRICTION_PARAMS": [0.126, 1.447, 7.75, -5.222, 0.137, -1.59, 8.462, 4.614, 0.049, 0.477, 3.277, -5.465, 0.036, -0.431, 3.259, 6.058, 0.043, 0.54, 3.008, -4.789, 0.03, -0.414, 2.75, 4.184, 0.019, 0.367, 3.08, -4.867, 0.019, -0.372, 3.16, 4.732, 0.007, 0.137, 1.419, -2.47, 0.008, -0.149, 1.504, 2.418, 0.009, 0.163, 1.362, -1.95, 0.01, -0.171, 1.397, 1.942, 7.803, 5.538, 5.022, 9.391, 7.783, 10.495],
|
||||||
|
"PIECE_WISE_LINEAR_FRICTION_PARAMS": [-0.06535761799684625, 5.307688270951032, 1.7604060137212758, 6.068038154979308, 5.583910262589325, 2.6218551937934973, 6.732621808450132, 4.471944392836248, 7.806749671368908, 7.0602371104504185, 7.853981633974483, 5.331997878206609, 0.24831213946387853, 5.840754037739742, 0.7403630230897218, 2.968216798484358, 1.5824972029194462, 2.407956752510862, 2.589954407861573, 1.937742619236955, 5.573021764456917, 1.58751952063559, 5.8904862254808625, 4.357924135448341e-07, -0.30232711860210815, 4.529134308122705, 0.8817788776693095, 2.4193841686971425, 1.916911521752169, 1.7713111112576077, 3.095284385491982, 1.2439578089982188, 4.999009668864633, 0.889507380429942, 5.235987755982989, 1.6838803244759562e-05, 0.07276495199295319, 5.073757316934823, 2.954918730146166, 2.2231836749454685, 8.925123452528698, 0.8524820442812915, 9.39438330300407, 1.1316138156617148, 10.664561784960355, 4.4656417123822525e-07, 10.681415022205297, -1.1884619119438249e-05, -0.022751910304290357, 2.4695451161700452, 1.2278079266323212, 1.3395643105831287, 2.6707582902172615, 1.0161324308647695, 4.316481644896923, 0.7563247691632612, 7.79933238944163, 0.593519692288847, 9.666438934122441, -2.374687996390956e-07, 0.016116837609708723, 1.986467017026887, 1.6666214728424908, 1.1416576684507849, 3.461070297757759, 0.7112239873757976, 8.31710269092633, 0.457300468823857, 10.593335243447141, 0.8462317840546537, 16.226303519258618, -5.592302627025284e-08],
|
||||||
|
"IDENT_PARAMS_WF": [-0.3835157067, 5.035909, 9.38751, 0.1737, 0.9389008715, -0.0260568815, -0.0586179693999999, -0.0358425081999999, 0.0965298651999999, 3.1896350395, 0.0475487017, 5.403823, 5.012539, -2.883714, 0.3274178574, 0.0209162596999999, -0.0671335438, 0.761626541199999, 0.0442403211, 0.0940986696, 0.9138090424, 2.617634, 6.395417, 0.004183, 0.0771906938, -0.0003390905, 0.0237117726, 0.0798426609, -0.0119266748, 0.0108141559, 0.0497106805, 1.0543, 2.663184, 0.15474, -0.0370267432999999, -0.0054303809, -0.0239029530999999, 0.0071703301, 0.0127975931, 0.0017350899, -0.00237885969999999, 0.779036, 1.647843, 0.075562, 0.0053908232, -0.0112614849, 0.0124041744, -0.0061579121, 0.0070301924, 0.0023095324, 0.0040231572, 1.033086, 3.76907, 0.118944],
|
||||||
|
"LINK_MOMENT_OF_INERTIA": [26730.697, 23305.849, 854258.945, -389.139, 981.756, 1367.986, 55818.209, 469806.767, 13261.075, 71.676, -691.385, 1157.377, 4469.258, 217221.279, 5057.332, -88.824, 654.697, -69.477, 90651.777, 20273.735, 21764.076, 225.359, 17.193, 15.37, 1429.243, 40348.207, 2335.733, 45.188, 0.656, -0.408, 119.352, 118.444, 157722.891, -0.0, 0.085, -0.0],
|
||||||
|
"LINK_MASS_AID": [],
|
||||||
|
"LINK_CENTROID_AID": [],
|
||||||
|
"LINK_MOMENT_OF_INERTIA_AID": []
|
||||||
|
},
|
||||||
|
"MOTOR": {
|
||||||
|
"ENCODER_RESOLUTION": [131072, 131072, 131072, 131072, 131072, 131072],
|
||||||
|
"RATED_SPEED": [3000, 3000, 3000, 3000, 3000, 3000],
|
||||||
|
"MAX_SPEED": [6000, 6000, 6000, 6000, 6000, 6000],
|
||||||
|
"MAX_SPEED_CUSTOMIZE": [6000, 6000, 6000, 6000, 6000, 6000],
|
||||||
|
"RATED_TORQUE": [1.27, 0.64, 0.32, 0.32, 0.16, 0.32],
|
||||||
|
"TORQUE_OVERLOAD_FACTOR": [0.95, 1.5, 1.9, 1.45, 1.25, 1.55],
|
||||||
|
"PEAK_TORQUE": [4.46, 2.23, 1.11, 1.11, 0.56, 1.11],
|
||||||
|
"STALL_TORQUE": [1.27, 0.64, 0.32, 0.32, 0.16, 0.32],
|
||||||
|
"RATED_TORQUE_AT_MAX_SPEED": [0.64, 0.32, 0.159, 0.159, 0.08, 0.159],
|
||||||
|
"PEAK_TORQUE_AT_MAX_SPEED": [2, 1, 0.79, 0.79, 0.56, 0.79],
|
||||||
|
"SPEED_AT_PEAK_TORQUE_TURN_POINT": [3600, 3600, 4100, 4100, 6000, 4100],
|
||||||
|
"TORQUE_GRADIENT": [0.00021, 0.000107, 5.4e-05, 5.4e-05, 2.7e-05, 5.4e-05]
|
||||||
|
},
|
||||||
|
"TRANSMISSION": {
|
||||||
|
"REDUCTION_RATIO_NUMERATOR": [80, -106.66666666666666, -120, -58.82352941176471, -65, -38.72222222222222],
|
||||||
|
"REDUCTION_RATIO_DENOMINATOR": [1, 1, 1, 1, 1, 1],
|
||||||
|
"MAX_TORQUE_FOR_START_AND_STOP": [73, 73, 66.5, 33, 15, 22.5],
|
||||||
|
"OVERLOAD_FACTOR": [0.95, 1.45, 0.95, 0.95, 0.95, 0.95],
|
||||||
|
"COUPLING_FACTOR": [0, 0, -0.02582496413199426],
|
||||||
|
"MAX_AVERAGE_TORQUE": [46, 46, 48.5, 25.5, 6.2, 17.6],
|
||||||
|
"MAX_PEAK_TORQUE": [124, 124, 135.9, 69, 29, 47],
|
||||||
|
"MAX_INPUT_SPEED": [6500, 6500, 7300, 7200, 8200, 7200]
|
||||||
|
},
|
||||||
|
"MOTION": {
|
||||||
|
"MIN_SMOOTH_TIME": 1,
|
||||||
|
"MAX_SMOOTH_TIME": 1024,
|
||||||
|
"SMOOTH_TIME": 1,
|
||||||
|
"FILTER_ENABLE": false,
|
||||||
|
"VEL_SMOOTH_FACTOR": 1,
|
||||||
|
"JOINT_MAX_SPEED": [450.0, 318.0, 288.0, 550.0, 450.0, 612.0],
|
||||||
|
"JOINT_MAX_ACC": [10900, 8900, 5300, 8060, 4893, 10400],
|
||||||
|
"JOINT_MAX_JERK": [421000, 249000, 199000, 161200, 65244, 41800],
|
||||||
|
"TCP_MAX_SPEED": 7000,
|
||||||
|
"TCP_MAX_ACC": 5000,
|
||||||
|
"TCP_MAX_JERK": 100000,
|
||||||
|
"TCP_ROTATE_MAX_SPEED": 500,
|
||||||
|
"TCP_ROTATE_MAX_ACC": 600,
|
||||||
|
"TCP_ROTATE_MAX_JERK": 2000,
|
||||||
|
"JERK_LIMIT_CART": 1000,
|
||||||
|
"JERK_LIMIT_ROT": 1000,
|
||||||
|
"JERK_LIMIT_JOINT": 7000,
|
||||||
|
"MAX_ACC_PARAMS": [1, 0.5],
|
||||||
|
"MIN_ACC_PARAMS": [0.3, 0.02],
|
||||||
|
"DEFAULT_ACC_PARAMS": [1, 0.08],
|
||||||
|
"ACC_RAMPTIME_JOG": 0.06,
|
||||||
|
"ACC_RAMPTIME_STOP": 0.08
|
||||||
|
},
|
||||||
|
"SAFETY_CONTROL": {
|
||||||
|
"STOP_STO_TIME": [260, 760],
|
||||||
|
"BACK_DISTANCE": 3,
|
||||||
|
"STOP0_TYPE": 2,
|
||||||
|
"STOP0_TIME": 50,
|
||||||
|
"STOP0_LENGTH": 3,
|
||||||
|
"STOP0_DELAY": 240,
|
||||||
|
"STOP1_TYPE": 2,
|
||||||
|
"STOP1_TIME": 150,
|
||||||
|
"STOP1_LENGTH": 6,
|
||||||
|
"STOP1_DELAY": 700,
|
||||||
|
"STOP2_TYPE": 2,
|
||||||
|
"STOP2_TIME": 150,
|
||||||
|
"STOP2_LENGTH": 6,
|
||||||
|
"STOP2_DELAY": 700
|
||||||
|
},
|
||||||
|
"COLLISION": {
|
||||||
|
"ZERO_PROTECT_ENABLE": false,
|
||||||
|
"PATH_SPEED_MIN": [6, 6, 6, 2, 2, 2],
|
||||||
|
"PATH_SPEED_MAX": [25, 25, 15, 8, 5, 4],
|
||||||
|
"JOG_SPEED_MIN": [6, 6, 6, 2, 2, 2],
|
||||||
|
"JOG_SPEED_MAX": [25, 25, 15, 8, 5, 4],
|
||||||
|
"DELAY_PERIOD_RANGE": 50,
|
||||||
|
"SENSITIVITY": {
|
||||||
|
"LOW": [300, 300, 300, 50, 50, 50],
|
||||||
|
"MEDIUM": [30, 30, 30, 20, 20, 20],
|
||||||
|
"HIGH": [4, 4, 4, 2, 2, 2],
|
||||||
|
"ULTRA_LOW": [300, 300, 300, 50, 50, 50],
|
||||||
|
"ULTRA_MEDIUM": [30, 30, 30, 20, 20, 20],
|
||||||
|
"ULTRA_HIGH": [4, 4, 4, 2, 2, 2]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FORCE_CONTROL": {
|
||||||
|
"COMMON": {
|
||||||
|
"MAX_TRQ_CMD": [300, 300, 200, 80, 40, 40],
|
||||||
|
"PROTECT_FORCE_SWITCH": 1,
|
||||||
|
"COMPLIANCE_KD_IN_SLOWDOWN": [1, 1, 1, 1, 0.5, 0.5],
|
||||||
|
"COMPLIANCE_KI_IN_SLOWDOWN": [20, 20, 10, 5, 1, 1],
|
||||||
|
"PROTECT_FORCE_DAMP": [80, 80, 25, 10, 3, 3],
|
||||||
|
"PROTECT_FORCE_MAXTIME": 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RSC_PROTECT": {
|
||||||
|
"POS_FOLLOWING_ERROR_THRESHOLD": [262144, 262144, 262144, 262144, 262144, 262144],
|
||||||
|
"VEL_FOLLOWING_ERROR_THRESHOLD": [1200, 1000, 1000, 1000, 1000, 1000],
|
||||||
|
"CONTINUE_TIME": [1500, 1000, 0, 0],
|
||||||
|
"PROTECT_SUPPORT": false
|
||||||
|
},
|
||||||
|
"TEACHING": {
|
||||||
|
"FRICTION_FACTOR": [1, 1, 1, 1, 1, 1],
|
||||||
|
"INERTIAL_FACTOR": 0.3,
|
||||||
|
"MAX_CARTESIAN_SPEED": 0.25,
|
||||||
|
"MAX_JOINT_SPEED": 0.5,
|
||||||
|
"TORQUE_FACTOR": 1
|
||||||
|
}
|
||||||
|
}
|
BIN
assets/files/examples/自动测试/电机电流/NB4h_R580_3G/NB4h_R580_3G.zip
Normal file
BIN
assets/files/examples/自动测试/电机电流/NB4h_R580_3G/NB4h_R580_3G.zip
Normal file
Binary file not shown.
BIN
assets/files/examples/自动测试/电机电流/NB4h_R580_3G/T_电机电流.xlsx
Normal file
BIN
assets/files/examples/自动测试/电机电流/NB4h_R580_3G/T_电机电流.xlsx
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
assets/files/projects/NB4h_R580_3G.zip
Normal file
BIN
assets/files/projects/NB4h_R580_3G.zip
Normal file
Binary file not shown.
114
code/aio.py
114
code/aio.py
@ -27,7 +27,7 @@ class App:
|
|||||||
self.__set_root()
|
self.__set_root()
|
||||||
# ========================================================================
|
# ========================================================================
|
||||||
self.style = ttk.Style()
|
self.style = ttk.Style()
|
||||||
self.style.configure("tv.Treeview", font=self.f_treeview, rowheight=30)
|
self.style.configure("tv.Treeview", font=self.f_treeview, rowheight=25)
|
||||||
self.style.configure("Treeview.Heading", font=self.f_normal, rowheight=30)
|
self.style.configure("Treeview.Heading", font=self.f_normal, rowheight=30)
|
||||||
self.entry_path_dpv = ctk.StringVar()
|
self.entry_path_dpv = ctk.StringVar()
|
||||||
self.entry_path_dpv.set("数据文件夹路径")
|
self.entry_path_dpv.set("数据文件夹路径")
|
||||||
@ -82,8 +82,7 @@ class App:
|
|||||||
self.label_path_at = ctk.CTkLabel(self.tabview_top.tab("自动测试"), width=50, anchor="e", text="Path", font=self.f_common)
|
self.label_path_at = ctk.CTkLabel(self.tabview_top.tab("自动测试"), width=50, anchor="e", text="Path", font=self.f_common)
|
||||||
self.entry_path_at = ctk.CTkEntry(self.tabview_top.tab("自动测试"), width=80, state="disabled", textvariable=self.entry_path_atv, font=self.f_entry, text_color="#818181")
|
self.entry_path_at = ctk.CTkEntry(self.tabview_top.tab("自动测试"), width=80, state="disabled", textvariable=self.entry_path_atv, font=self.f_entry, text_color="#818181")
|
||||||
self.frame_top = ctk.CTkFrame(self.tabview_top.tab("自动测试"), width=120, height=10, fg_color="#E9E9E9")
|
self.frame_top = ctk.CTkFrame(self.tabview_top.tab("自动测试"), width=120, height=10, fg_color="#E9E9E9")
|
||||||
self.btn_robot_state = ctk.CTkButton(self.frame_top, width=100, text="机器信息", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__robot_info)
|
self.btn_robot_info = ctk.CTkButton(self.frame_top, width=100, text="机器信息", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__robot_info)
|
||||||
self.btn_robot_init = ctk.CTkButton(self.frame_top, width=100, text="初始操作", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__robot_init)
|
|
||||||
self.btn_trig_estop = ctk.CTkButton(self.frame_top, width=100, text="触发急停", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__trig_estop)
|
self.btn_trig_estop = ctk.CTkButton(self.frame_top, width=100, text="触发急停", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__trig_estop)
|
||||||
self.btn_reset_estop = ctk.CTkButton(self.frame_top, width=100, text="恢复急停", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__reset_estop)
|
self.btn_reset_estop = ctk.CTkButton(self.frame_top, width=100, text="恢复急停", font=self.f_segbtn, fg_color="#979DA2", corner_radius=0, command=self.__reset_estop)
|
||||||
self.popupmenu_ip = tk.Menu(self.entry_ip_at, tearoff=False)
|
self.popupmenu_ip = tk.Menu(self.entry_ip_at, tearoff=False)
|
||||||
@ -139,27 +138,113 @@ class App:
|
|||||||
...
|
...
|
||||||
|
|
||||||
def __detect_network(self):
|
def __detect_network(self):
|
||||||
|
def func_access(state):
|
||||||
|
self.btn_robot_info.configure(state=state)
|
||||||
|
self.btn_trig_estop.configure(state=state)
|
||||||
|
self.btn_reset_estop.configure(state=state)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
if clibs.c_hr.status:
|
if clibs.c_hr.status:
|
||||||
self.btn_conn.configure(fg_color="#2E8B57")
|
self.btn_conn.configure(fg_color="#2E8B57")
|
||||||
|
func_access("normal")
|
||||||
else:
|
else:
|
||||||
self.btn_conn.configure(fg_color="#979DA2")
|
self.btn_conn.configure(fg_color="#979DA2")
|
||||||
except Exception as Err:
|
func_access("disabled")
|
||||||
|
except Exception:
|
||||||
self.btn_conn.configure(fg_color="#979DA2")
|
self.btn_conn.configure(fg_color="#979DA2")
|
||||||
|
func_access("disabled")
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
def __robot_info(self):
|
def __robot_info(self):
|
||||||
...
|
def get_robot_info():
|
||||||
|
self.tabview_bottom.set("输出")
|
||||||
|
self.text_output.delete("1.0", "end")
|
||||||
|
self.__w2t("正在获取机器信息,请稍后...\n\n")
|
||||||
|
infos = {0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}, 8: {}, 9: {}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}, 15: {}, 16: {}, 17: {}, 18: {}, 19: {}, 20: {}}
|
||||||
|
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]:
|
||||||
|
data, activate = eval(record[0])["data"], []
|
||||||
|
infos[0]["robot_type"] = data["robot_type"]
|
||||||
|
infos[1]["controller_type"] = data["controller_type"]
|
||||||
|
infos[2]["disk_serial_number"] = data["disk_serial_number"]
|
||||||
|
infos[3]["mac_addr"] = data["mac_addr"]
|
||||||
|
infos[4]["security_type"] = data["security_type"]
|
||||||
|
infos[5]["xcore_version"] = data["version"]
|
||||||
|
auth_states = data["auth_state"]["function"]
|
||||||
|
for auth_state in auth_states:
|
||||||
|
if auth_state["auth"] == "activate":
|
||||||
|
activate.append(auth_state["name"])
|
||||||
|
infos[6]["activated"] = ", ".join(activate)
|
||||||
|
|
||||||
def __robot_init(self):
|
msg_id, state = clibs.c_hr.execution("device.get_params")
|
||||||
...
|
records = clibs.c_hr.get_from_id(msg_id, state)
|
||||||
|
for record in records:
|
||||||
|
if "请求发送成功" not in record[0]:
|
||||||
|
data = eval(record[0])["data"]["devices"]
|
||||||
|
for item in data:
|
||||||
|
if item["type"] == 2:
|
||||||
|
infos[7]["security_version"] = item["version"]
|
||||||
|
elif item["type"] == 4:
|
||||||
|
infos[8]["communication_version"] = item["version"]
|
||||||
|
elif item["type"] == 6:
|
||||||
|
infos[9]["motion_control_version"] = item["version"]
|
||||||
|
elif item["type"] == 9:
|
||||||
|
infos[10]["end_firmware_version"] = item["version"]
|
||||||
|
elif item["type"] == 10:
|
||||||
|
infos[11]["robot_cfg_version"] = item["version"]
|
||||||
|
elif item["type"] == 11:
|
||||||
|
infos[12]["env_package_version"] = item["version"]
|
||||||
|
|
||||||
|
msg_id, state = clibs.c_hr.execution("state.get_state")
|
||||||
|
records = clibs.c_hr.get_from_id(msg_id, state)
|
||||||
|
for record in records:
|
||||||
|
if "请求发送成功" not in record[0]:
|
||||||
|
data = eval(record[0])["data"]
|
||||||
|
infos[13]["rc_state"] = data["rc_state"]
|
||||||
|
infos[14]["engine"] = data["engine"]
|
||||||
|
infos[15]["servo_mode"] = data["servo_mode"]
|
||||||
|
infos[16]["operate"] = data["operate"]
|
||||||
|
infos[17]["task_space"] = data["task_space"]
|
||||||
|
infos[18]["robot_action"] = data["robot_action"]
|
||||||
|
infos[19]["safety_mode"] = data["safety_mode"]
|
||||||
|
|
||||||
|
msg_id, state = clibs.c_hr.execution("state.get_tp_mode")
|
||||||
|
records = clibs.c_hr.get_from_id(msg_id, state)
|
||||||
|
for record in records:
|
||||||
|
if "请求发送成功" not in record[0]:
|
||||||
|
data = eval(record[0])["data"]
|
||||||
|
infos[20]["tp_mode"] = data["tp_mode"]
|
||||||
|
|
||||||
|
for idx in sorted(infos.keys()):
|
||||||
|
for k, v in infos[idx].items():
|
||||||
|
self.__w2t(f"{k}: {v}\n")
|
||||||
|
t = threading.Thread(target=get_robot_info)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
def __trig_estop(self):
|
def __trig_estop(self):
|
||||||
...
|
def trig_estop():
|
||||||
|
self.tabview_bottom.set("输出")
|
||||||
|
self.text_output.delete("1.0", "end")
|
||||||
|
self.__w2t("触发软急停信号已发送...\n")
|
||||||
|
clibs.c_md.r_soft_estop(0)
|
||||||
|
t = threading.Thread(target=trig_estop)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
def __reset_estop(self):
|
def __reset_estop(self):
|
||||||
...
|
def reset_estop():
|
||||||
|
self.tabview_bottom.set("输出")
|
||||||
|
self.text_output.delete("1.0", "end")
|
||||||
|
self.__w2t("解除软急停信号已发送...\n")
|
||||||
|
clibs.c_md.r_soft_estop(1)
|
||||||
|
clibs.c_md.r_clear_alarm()
|
||||||
|
t = threading.Thread(target=reset_estop)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
def __thread_it(self, func, *args):
|
def __thread_it(self, func, *args):
|
||||||
""" 将函数打包进线程,必须使用 lambda """
|
""" 将函数打包进线程,必须使用 lambda """
|
||||||
@ -894,6 +979,10 @@ class App:
|
|||||||
clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
|
clibs.c_md = openapi.ModbusRequest(clibs.ip_addr, clibs.modbus_port)
|
||||||
clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port)
|
clibs.c_hr = openapi.HmiRequest(clibs.ip_addr, clibs.socket_port, clibs.xService_port)
|
||||||
clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
|
clibs.c_pd = openapi.PreDos(clibs.ip_addr, clibs.ssh_port, clibs.username, clibs.password)
|
||||||
|
# clibs.c_md.read_scenario_time()
|
||||||
|
# clibs.c_hr.execution('state.set_tp_mode', tp_mode='without')
|
||||||
|
# clibs.c_hr.execution("diagnosis.open", open=False, display_open=False, overrun=True, turn_area=True, delay_motion=False)
|
||||||
|
# clibs.c_hr.execution("diagnosis.set_params", display_pdo_params=[], frequency=50, version="1.4.1")
|
||||||
self.btn_conn.configure(state="normal", fg_color="#2E8B57")
|
self.btn_conn.configure(state="normal", fg_color="#2E8B57")
|
||||||
except Exception:
|
except Exception:
|
||||||
self.btn_conn.configure(state="normal", fg_color="#979DA2")
|
self.btn_conn.configure(state="normal", fg_color="#979DA2")
|
||||||
@ -960,10 +1049,9 @@ class App:
|
|||||||
self.label_path_at.grid(row=1, column=1, padx=(0, 10), pady=(0, 10), sticky="e")
|
self.label_path_at.grid(row=1, column=1, padx=(0, 10), pady=(0, 10), sticky="e")
|
||||||
self.entry_path_at.grid(row=1, column=2, columnspan=3, padx=(0, 10), pady=(0, 10), sticky="we")
|
self.entry_path_at.grid(row=1, column=2, columnspan=3, padx=(0, 10), pady=(0, 10), sticky="we")
|
||||||
self.frame_top.grid(row=2, column=0, columnspan=5, padx=0, pady=0, sticky="we")
|
self.frame_top.grid(row=2, column=0, columnspan=5, padx=0, pady=0, sticky="we")
|
||||||
self.btn_robot_state.grid(row=0, column=0, padx=10, pady=0)
|
self.btn_robot_info.grid(row=0, column=0, padx=10, pady=0)
|
||||||
self.btn_robot_init.grid(row=0, column=1, padx=(0, 10), pady=0)
|
self.btn_trig_estop.grid(row=0, column=1, padx=(0, 10), pady=0)
|
||||||
self.btn_trig_estop.grid(row=0, column=2, padx=(0, 10), pady=0)
|
self.btn_reset_estop.grid(row=0, column=2, padx=(0, 10), pady=0)
|
||||||
self.btn_reset_estop.grid(row=0, column=3, padx=(0, 10), pady=0)
|
|
||||||
|
|
||||||
# self.progressbar_at.start()
|
# self.progressbar_at.start()
|
||||||
# self.progressbar_at.configure(progress_color="red", fg_color="gray")
|
# self.progressbar_at.configure(progress_color="red", fg_color="gray")
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
from time import sleep, time, strftime, localtime
|
import time
|
||||||
from os import mkdir
|
import os
|
||||||
from paramiko import SSHClient, AutoAddPolicy
|
import paramiko
|
||||||
from openpyxl import load_workbook
|
import openpyxl
|
||||||
from pandas import DataFrame, concat
|
import pandas
|
||||||
import json
|
import json
|
||||||
from commons import clibs
|
from commons import clibs
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
|||||||
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!", "red")
|
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下五个文件,确认后重新运行!", "red")
|
||||||
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError")
|
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError")
|
||||||
|
|
||||||
config_file, reach33, reach66, reach100, prj_file = None, None, None, None, None
|
config_file, reach33, reach66, reach100, prj_file, result_dirs = None, None, None, None, None, []
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
filename = data_file.split("/")[-1]
|
filename = data_file.split("/")[-1]
|
||||||
if filename == "configs.xlsx":
|
if filename == "configs.xlsx":
|
||||||
@ -31,20 +31,19 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
|||||||
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError")
|
w2t("1. configs.xlsx\n2. reach33/reach66/reach100_xxxx.xlsx\n3. xxxx.zip\n", "red", "InitFileError")
|
||||||
|
|
||||||
if config_file and reach33 and reach66 and reach100 and prj_file:
|
if config_file and reach33 and reach66 and reach100 and prj_file:
|
||||||
result_dirs = []
|
os.mkdir(f"{path}/j1")
|
||||||
mkdir(f"{path}/j1")
|
os.mkdir(f"{path}/j2")
|
||||||
mkdir(f"{path}/j2")
|
os.mkdir(f"{path}/j3")
|
||||||
mkdir(f"{path}/j3")
|
|
||||||
|
|
||||||
load = f"load{sub.removeprefix("tool")}"
|
load = f"load{sub.removeprefix("tool")}"
|
||||||
for reach in ["reach33", "reach66", "reach100"]:
|
for reach in ["reach33", "reach66", "reach100"]:
|
||||||
for speed in ["speed33", "speed66", "speed100"]:
|
for speed in ["speed33", "speed66", "speed100"]:
|
||||||
dir_name = "_".join([reach, load, speed])
|
dir_name = "_".join([reach, load, speed])
|
||||||
result_dirs.append(dir_name)
|
result_dirs.append(dir_name)
|
||||||
mkdir(f"{path}/j1/{dir_name}")
|
os.mkdir(f"{path}/j1/{dir_name}")
|
||||||
mkdir(f"{path}/j2/{dir_name}")
|
os.mkdir(f"{path}/j2/{dir_name}")
|
||||||
if reach == "reach100":
|
if reach == "reach100":
|
||||||
mkdir(f"{path}/j3/{dir_name}")
|
os.mkdir(f"{path}/j3/{dir_name}")
|
||||||
|
|
||||||
w2t("数据目录合规性检查结束,未发现问题......\n", "blue")
|
w2t("数据目录合规性检查结束,未发现问题......\n", "blue")
|
||||||
return config_file, reach33, reach66, reach100, prj_file, result_dirs
|
return config_file, reach33, reach66, reach100, prj_file, result_dirs
|
||||||
@ -77,10 +76,10 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
|||||||
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}")
|
clibs.insert_logdb("INFO", "do_brake", f"get_configs: 各关节角速度 {avs}")
|
||||||
return avs
|
return avs
|
||||||
|
|
||||||
config_file, reach33, reach66, reach100, prj_file, result_dirs = check_files()
|
_config_file, _reach33, _reach66, _reach100, _prj_file, _result_dirs = check_files()
|
||||||
avs = get_configs()
|
_avs = get_configs()
|
||||||
|
|
||||||
return config_file, reach33, reach66, reach100, prj_file, result_dirs, avs
|
return _config_file, _reach33, _reach66, _reach100, _prj_file, _result_dirs, _avs
|
||||||
|
|
||||||
|
|
||||||
@clibs.db_lock
|
@clibs.db_lock
|
||||||
@ -101,10 +100,10 @@ def gen_result_file(path, axis, reach, load, speed, rounds):
|
|||||||
elif item.get("channel", None) == 0 and item.get("name", None) == "device_safety_estop":
|
elif item.get("channel", None) == 0 and item.get("name", None) == "device_safety_estop":
|
||||||
d_stop.extend(item["value"])
|
d_stop.extend(item["value"])
|
||||||
|
|
||||||
df1 = DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
||||||
df2 = DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
||||||
df3 = DataFrame.from_dict({"device_safety_estop": d_stop})
|
df3 = pandas.DataFrame.from_dict({"device_safety_estop": d_stop})
|
||||||
df = concat([df1, df2, df3], axis=1)
|
df = pandas.concat([df1, df2, df3], axis=1)
|
||||||
filename = f"{path}\\j{axis}\\reach{reach}_load{load}_speed{speed}\\reach{reach}_load{load}_speed{speed}_{rounds}.data"
|
filename = f"{path}\\j{axis}\\reach{reach}_load{load}_speed{speed}\\reach{reach}_load{load}_speed{speed}_{rounds}.data"
|
||||||
df.to_csv(filename, sep="\t", index=False)
|
df.to_csv(filename, sep="\t", index=False)
|
||||||
|
|
||||||
@ -114,7 +113,7 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
prj_name = prj_file.split("/")[-1].split(".")[0]
|
prj_name = prj_file.split("/")[-1].split(".")[0]
|
||||||
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback"] for chl in range(6)]
|
display_pdo_params = [{"name": name, "channel": chl} for name in ["hw_joint_vel_feedback", "device_servo_trq_feedback"] for chl in range(6)]
|
||||||
display_pdo_params.append({"name": "device_safety_estop", "channel": 0})
|
display_pdo_params.append({"name": "device_safety_estop", "channel": 0})
|
||||||
wb = load_workbook(config_file, read_only=True)
|
wb = openpyxl.load_workbook(config_file, read_only=True)
|
||||||
ws = wb["Target"]
|
ws = wb["Target"]
|
||||||
write_diagnosis = float(ws.cell(row=2, column=2).value)
|
write_diagnosis = float(ws.cell(row=2, column=2).value)
|
||||||
get_init_speed = float(ws.cell(row=3, column=2).value)
|
get_init_speed = float(ws.cell(row=3, column=2).value)
|
||||||
@ -150,11 +149,10 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
md.write_axis(axis)
|
md.write_axis(axis)
|
||||||
speed_max = 0
|
|
||||||
w2t(f"-"*90+"\n", "purple")
|
w2t(f"-"*90+"\n", "purple")
|
||||||
for rounds in range(1, 4):
|
for rounds in range(1, 4):
|
||||||
count += 1
|
count += 1
|
||||||
this_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()))
|
this_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
prj_path = f"{prj_name}/_build/{prj_name}.prj"
|
prj_path = f"{prj_name}/_build/{prj_name}.prj"
|
||||||
w2t(f"[{this_time} | {count}/{total}] 正在执行 {axis} 轴 {condition} 的第 {count} 次制动测试...\n")
|
w2t(f"[{this_time} | {count}/{total}] 正在执行 {axis} 轴 {condition} 的第 {count} 次制动测试...\n")
|
||||||
|
|
||||||
@ -163,13 +161,13 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
md.reset_estop()
|
md.reset_estop()
|
||||||
md.clear_alarm()
|
md.clear_alarm()
|
||||||
md.write_act(0)
|
md.write_act(0)
|
||||||
sleep(write_diagnosis) # 软急停超差后,等待写诊断时间,可通过configs.xlsx配置
|
time.sleep(write_diagnosis) # 软急停超差后,等待写诊断时间,可通过configs.xlsx配置
|
||||||
|
|
||||||
while count == 1:
|
while count == 1:
|
||||||
# 2. 修改要执行的场景
|
# 2. 修改要执行的场景
|
||||||
rl_cmd = ""
|
rl_cmd = ""
|
||||||
ssh = SSHClient()
|
ssh = paramiko.SSHClient()
|
||||||
ssh.set_missing_host_key_policy(AutoAddPolicy())
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
ssh.connect(hostname=clibs.ip_addr, port=clibs.ssh_port, username=clibs.username, password=clibs.password)
|
ssh.connect(hostname=clibs.ip_addr, port=clibs.ssh_port, username=clibs.username, password=clibs.password)
|
||||||
if pon == "positive":
|
if pon == "positive":
|
||||||
rl_cmd = f"brake_E(j{axis}_{reach}_p, j{axis}_{reach}_n, p_speed, p_tool)"
|
rl_cmd = f"brake_E(j{axis}_{reach}_p, j{axis}_{reach}_n, p_speed, p_tool)"
|
||||||
@ -196,23 +194,23 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
hr.execution("state.switch_motor_on")
|
hr.execution("state.switch_motor_on")
|
||||||
hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
|
hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
|
||||||
hr.execution("rl_task.run", tasks=["brake", "stop0_related"])
|
hr.execution("rl_task.run", tasks=["brake", "stop0_related"])
|
||||||
t_start = time()
|
t_start = time.time()
|
||||||
while True:
|
while True:
|
||||||
if md.read_ready_to_go() == 1:
|
if md.read_ready_to_go() == 1:
|
||||||
md.write_act(True)
|
md.write_act(True)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
sleep(1)
|
time.sleep(1)
|
||||||
if (time() - t_start) // 20 > 1:
|
if (time.time() - t_start) // 20 > 1:
|
||||||
w2t("20s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
w2t("20s 内未收到机器人的运行信号,需要确认 RL 程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
# 4. 找出最大速度,传递给RL程序,最后清除相关记录
|
||||||
sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度,可通过configs.xlsx配置
|
time.sleep(get_init_speed) # 指定时间后获取实际【正|负】方向的最大速度,可通过configs.xlsx配置
|
||||||
clibs.execution("rl_task.stop", tasks=["brake"])
|
clibs.execution("rl_task.stop", tasks=["brake"])
|
||||||
|
|
||||||
# 找出最大速度
|
# 找出最大速度
|
||||||
@clibs.db_lock
|
@clibs.db_lock
|
||||||
def get_speed_max(axis, pon):
|
def get_speed_max():
|
||||||
speed_max = 0
|
_speed_max = 0
|
||||||
len_records = int(get_init_speed * 20) + 1 # 1000 / 50 = 20
|
len_records = int(get_init_speed * 20) + 1 # 1000 / 50 = 20
|
||||||
clibs.cursor.execute(f"select content from logs where content like 'diagnosis.result' limit {len_records}")
|
clibs.cursor.execute(f"select content from logs where content like 'diagnosis.result' limit {len_records}")
|
||||||
records = clibs.cursor.fetchall()
|
records = clibs.cursor.fetchall()
|
||||||
@ -222,12 +220,12 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback":
|
if item.get("channel", None) == axis-1 and item.get("name", None) == "hw_joint_vel_feedback":
|
||||||
_ = clibs.RADIAN * sum(item["value"]) / len(item["value"])
|
_ = clibs.RADIAN * sum(item["value"]) / len(item["value"])
|
||||||
if pon == "positive":
|
if pon == "positive":
|
||||||
speed_max = max(_, speed_max)
|
_speed_max = max(_, _speed_max)
|
||||||
elif pon == "negative":
|
elif pon == "negative":
|
||||||
speed_max = min(_, speed_max)
|
_speed_max = min(_, _speed_max)
|
||||||
return speed_max
|
return _speed_max
|
||||||
|
|
||||||
speed_max = abs(get_speed_max(axis, pon))
|
speed_max = abs(get_speed_max())
|
||||||
speed_target = avs[axis-1] * float(speed) / 100
|
speed_target = avs[axis-1] * float(speed) / 100
|
||||||
clibs.insert_logdb("INFO", "do_brake", f"axis = {axis}, direction = {pon}, max speed = {speed_max}")
|
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:
|
if speed_max < speed_target*0.95 or speed_max > speed_target*1.05:
|
||||||
@ -255,21 +253,21 @@ def run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t):
|
|||||||
md.write_act(1)
|
md.write_act(1)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
sleep(1)
|
time.sleep(1)
|
||||||
else:
|
else:
|
||||||
w2t("3s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
|
w2t("3s 内未收到机器人的运行信号,需要确认 RL 程序配置正确并正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
|
|
||||||
sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
|
time.sleep(10) # 排除从其他位姿到零点位姿,再到轴极限位姿的时间
|
||||||
md.write_probe(1)
|
md.write_probe(1)
|
||||||
t_start = time()
|
t_start = time.time()
|
||||||
while True:
|
while True:
|
||||||
if md.read_brake_done() == 1:
|
if md.read_brake_done() == 1:
|
||||||
sleep(4) # 保证速度归零
|
time.sleep(4) # 保证速度归零
|
||||||
md.write_probe(0)
|
md.write_probe(0)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
sleep(1)
|
time.sleep(1)
|
||||||
if (time() - t_start) > 30:
|
if (time.time() - t_start) > 30:
|
||||||
md.write_probe(0)
|
md.write_probe(0)
|
||||||
w2t(f"30s 内未触发急停,该条数据无效,需要确认 RL/Python 程序配置正确并正常执行,或者判别是否是机器本体问题,比如正负方向速度是否一致...", "red", "NoEstopTriggeredError")
|
w2t(f"30s 内未触发急停,该条数据无效,需要确认 RL/Python 程序配置正确并正常执行,或者判别是否是机器本体问题,比如正负方向速度是否一致...", "red", "NoEstopTriggeredError")
|
||||||
|
|
||||||
@ -288,14 +286,13 @@ def main():
|
|||||||
w2t = clibs.w2t
|
w2t = clibs.w2t
|
||||||
hr = clibs.c_hr
|
hr = clibs.c_hr
|
||||||
md = clibs.c_md
|
md = clibs.c_md
|
||||||
insert_logdb = clibs.insert_logdb
|
|
||||||
|
|
||||||
s_time = time()
|
s_time = time.time()
|
||||||
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
||||||
config_file, reach33, reach66, reach100, prj_file, result_dirs, avs = initialization(path, sub, data_dirs, data_files, hr, w2t)
|
config_file, reach33, reach66, reach100, prj_file, result_dirs, avs = initialization(path, sub, data_dirs, data_files, hr, w2t)
|
||||||
clibs.c_pd.push_prj_to_server(prj_file)
|
clibs.c_pd.push_prj_to_server(prj_file)
|
||||||
run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t)
|
run_rl(path, sub, hr, md, config_file, prj_file, result_dirs, avs, w2t)
|
||||||
e_time = time()
|
e_time = time.time()
|
||||||
time_total = e_time - s_time
|
time_total = e_time - s_time
|
||||||
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", "green")
|
w2t(f"处理总时长:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s", "green")
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import multiprocessing
|
||||||
import time
|
import time
|
||||||
import paramiko
|
import paramiko
|
||||||
import pandas
|
import pandas
|
||||||
@ -7,9 +8,10 @@ from common import clibs
|
|||||||
|
|
||||||
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
||||||
def check_files():
|
def check_files():
|
||||||
|
msg = "初始路径下不允许有文件夹,且初始路径下只能存在如下两个文件,确认后重新运行!\n"
|
||||||
|
msg += "1. T_电机电流.xlsx\n2. xxxx.zip\n"
|
||||||
if len(data_dirs) != 0 or len(data_files) != 2:
|
if len(data_dirs) != 0 or len(data_files) != 2:
|
||||||
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下两个文件,确认后重新运行!\n", "red")
|
w2t(msg, "red", "InitFileError")
|
||||||
w2t("1. T_电机电流.xlsx\n2. xxxx.zip\n", "red", "ConfigFileError")
|
|
||||||
|
|
||||||
prj_file, count = None, 0
|
prj_file, count = None, 0
|
||||||
for data_file in data_files:
|
for data_file in data_files:
|
||||||
@ -20,12 +22,11 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
|||||||
count += 1
|
count += 1
|
||||||
prj_file = data_file
|
prj_file = data_file
|
||||||
else:
|
else:
|
||||||
w2t(f"{data_file} 不合规:初始路径下只能存在如下两个文件,确认后重新运行!\n", "red")
|
w2t(msg, "red", "InitFileError")
|
||||||
w2t("1. T_电机电流.xlsx\n2. xxxx.zip\n", "red", "ConfigFileError")
|
|
||||||
|
|
||||||
if count != 2:
|
if count != 2:
|
||||||
w2t("初始路径下不允许有文件夹,且初始路径下只能存在如下两个文件,确认后重新运行!\n", "red")
|
w2t(msg, "red", "InitFileError")
|
||||||
w2t("1. T_电机电流.xlsx\n2. xxxx.zip\n", "red", "ConfigFileError")
|
|
||||||
w2t("数据目录合规性检查结束,未发现问题......\n")
|
w2t("数据目录合规性检查结束,未发现问题......\n")
|
||||||
if sub == "tool100" or sub == "inertia":
|
if sub == "tool100" or sub == "inertia":
|
||||||
os.mkdir(f"{path}/single")
|
os.mkdir(f"{path}/single")
|
||||||
@ -50,10 +51,10 @@ def initialization(path, sub, data_dirs, data_files, hr, w2t):
|
|||||||
local_file = path + f"/{robot_type}.cfg"
|
local_file = path + f"/{robot_type}.cfg"
|
||||||
clibs.c_pd.pull_file_from_server(server_file, local_file)
|
clibs.c_pd.pull_file_from_server(server_file, local_file)
|
||||||
|
|
||||||
prj_file = check_files()
|
_prj_file = check_files()
|
||||||
get_configs()
|
get_configs()
|
||||||
|
|
||||||
return prj_file
|
return _prj_file
|
||||||
|
|
||||||
|
|
||||||
def single_axis_proc(path, records, number):
|
def single_axis_proc(path, records, number):
|
||||||
@ -61,15 +62,15 @@ def single_axis_proc(path, records, number):
|
|||||||
number = number if number < 6 else number - 6
|
number = number if number < 6 else number - 6
|
||||||
d_vel, d_trq, d_sensor = [], [], []
|
d_vel, d_trq, d_sensor = [], [], []
|
||||||
for record in records:
|
for record in records:
|
||||||
print(f"record = {record}")
|
data = eval(record[0])["data"]
|
||||||
data = eval(record)["data"]
|
|
||||||
for item in 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":
|
if item.get("channel", None) == number and item.get("name", None) == "hw_joint_vel_feedback":
|
||||||
d_vel.extend(item["value"])
|
d_vel.extend(d_item)
|
||||||
elif item.get("channel", None) == number and item.get("name", None) == "device_servo_trq_feedback":
|
elif item.get("channel", None) == number and item.get("name", None) == "device_servo_trq_feedback":
|
||||||
d_trq.extend(item["value"])
|
d_trq.extend(d_item)
|
||||||
elif item.get("channel", None) == number and item.get("name", None) == "hw_sensor_trq_feedback":
|
elif item.get("channel", None) == number and item.get("name", None) == "hw_sensor_trq_feedback":
|
||||||
d_sensor.extend(item["value"])
|
d_sensor.extend(d_item)
|
||||||
|
|
||||||
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
||||||
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
||||||
@ -80,39 +81,44 @@ def single_axis_proc(path, records, number):
|
|||||||
|
|
||||||
|
|
||||||
def scenario_proc(path, records, number, scenario_time):
|
def scenario_proc(path, records, number, scenario_time):
|
||||||
|
for axis in range(6):
|
||||||
d_vel, d_trq, d_sensor = [], [], []
|
d_vel, d_trq, d_sensor = [], [], []
|
||||||
for record in records:
|
for record in records:
|
||||||
print(f"record = {record}")
|
data = eval(record[0])["data"]
|
||||||
data = eval(record)["data"]
|
|
||||||
for axis in range(6):
|
|
||||||
for item in data:
|
for item in data:
|
||||||
|
d_item = reversed(item["value"])
|
||||||
if item.get("channel", None) == axis and item.get("name", None) == "hw_joint_vel_feedback":
|
if item.get("channel", None) == axis and item.get("name", None) == "hw_joint_vel_feedback":
|
||||||
d_vel.extend(item["value"])
|
d_vel.extend(d_item)
|
||||||
elif item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
|
elif item.get("channel", None) == axis and item.get("name", None) == "device_servo_trq_feedback":
|
||||||
d_trq.extend(item["value"])
|
d_trq.extend(d_item)
|
||||||
elif item.get("channel", None) == axis and item.get("name", None) == "hw_sensor_trq_feedback":
|
elif item.get("channel", None) == axis and item.get("name", None) == "hw_sensor_trq_feedback":
|
||||||
d_sensor.extend(item["value"])
|
d_sensor.extend(d_item)
|
||||||
|
|
||||||
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
df1 = pandas.DataFrame.from_dict({"hw_joint_vel_feedback": d_vel})
|
||||||
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
df2 = pandas.DataFrame.from_dict({"device_servo_trq_feedback": d_trq})
|
||||||
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
|
df3 = pandas.DataFrame.from_dict({"hw_sensor_trq_feedback": d_sensor})
|
||||||
df = pandas.concat([df1, df2, df3], axis=1)
|
df = pandas.concat([df1, df2, df3], axis=1)
|
||||||
filename = f"{path}/s_{number-11}/j{axis}_s_{number-11}_{scenario_time}_{time.time()}.data"
|
filename = f"{path}/s_{number-11}/j{axis+1}_s_{number-11}_{scenario_time}_{time.time()}.data"
|
||||||
df.to_csv(filename, sep="\t", index=False)
|
df.to_csv(filename, sep="\t", index=False)
|
||||||
|
|
||||||
|
|
||||||
@clibs.db_lock
|
def gen_result_file(path, number, start_time, end_time, scenario_time):
|
||||||
def gen_result_file(path, number, scenario_time):
|
@clibs.db_lock
|
||||||
if number < 12: # 35s/15s == 700/300
|
def get_records(s_time, e_time):
|
||||||
len_records = 700 if number < 6 else 300
|
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.execute(f"select content from logs where content like 'diagnosis.result' limit {len_records}")
|
_ = clibs.cursor.fetchall()
|
||||||
records = clibs.cursor.fetchall()
|
return _
|
||||||
single_axis_proc(path, records, number)
|
|
||||||
elif number < 15: # scenario time
|
if number < 12:
|
||||||
len_records = int(scenario_time * 20) + 1
|
records = get_records(start_time, end_time)
|
||||||
clibs.cursor.execute(f"select content from logs where content like 'diagnosis.result' limit {len_records}")
|
p = multiprocessing.Process(target=single_axis_proc, args=(path, records, number))
|
||||||
records = clibs.cursor.fetchall()
|
p.daemon = True
|
||||||
scenario_proc(path, records, number, scenario_time)
|
p.start()
|
||||||
|
elif number < 15:
|
||||||
|
records = get_records(start_time, end_time)
|
||||||
|
p = multiprocessing.Process(target=scenario_proc, args=(path, records, number, scenario_time))
|
||||||
|
p.daemon = True
|
||||||
|
p.start()
|
||||||
|
|
||||||
|
|
||||||
def run_rl(path, prj_file, hr, md, sub, w2t):
|
def run_rl(path, prj_file, hr, md, sub, w2t):
|
||||||
@ -151,8 +157,9 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
|
|||||||
# 打开诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来
|
# 打开诊断曲线,触发软急停,并解除,目的是让可能正在运行着的机器停下来
|
||||||
hr.execution("diagnosis.open", open=True, display_open=True, overrun=True, turn_area=True, delay_motion=False)
|
hr.execution("diagnosis.open", open=True, display_open=True, overrun=True, turn_area=True, delay_motion=False)
|
||||||
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
hr.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=50, version="1.4.1")
|
||||||
md.trigger_estop()
|
md.r_soft_estop(0)
|
||||||
md.reset_estop()
|
md.r_soft_estop(1)
|
||||||
|
md.r_clear_alarm()
|
||||||
|
|
||||||
for condition in conditions:
|
for condition in conditions:
|
||||||
number = conditions.index(condition)
|
number = conditions.index(condition)
|
||||||
@ -178,7 +185,7 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
|
|||||||
hr.execution("state.switch_auto")
|
hr.execution("state.switch_auto")
|
||||||
hr.execution("state.switch_motor_on")
|
hr.execution("state.switch_motor_on")
|
||||||
|
|
||||||
# 3. 开始运行程序,单轴运行35s
|
# 3. 开始运行程序
|
||||||
hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
|
hr.execution("rl_task.set_run_params", loop_mode=True, override=1.0)
|
||||||
hr.execution("rl_task.run", tasks=["current"])
|
hr.execution("rl_task.run", tasks=["current"])
|
||||||
t_start = time.time()
|
t_start = time.time()
|
||||||
@ -188,34 +195,35 @@ def run_rl(path, prj_file, hr, md, sub, w2t):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if (time.time() - t_start) // 20 > 1:
|
if (time.time() - t_start) > 20:
|
||||||
w2t("20s 内未收到机器人的运行信号,需要确认RL程序编写正确并正常执行...", "red", "ReadySignalTimeoutError")
|
w2t("20s 内未收到机器人的运行信号,需要确认RL程序和工具通信是否正常执行...", "red", "ReadySignalTimeoutError")
|
||||||
|
|
||||||
# 4. 打开诊断曲线,并执行采集
|
# 4. 执行采集
|
||||||
time.sleep(10) # 保证程序已经运行起来,其实主要是为了保持电流的采集而设定
|
time.sleep(10) # 消除前 10s 的不稳定数据
|
||||||
scenario_time = 0
|
start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
|
single_time, stall_time, scenario_time = 30, 10, 0
|
||||||
if number < 6: # 单轴
|
if number < 6: # 单轴
|
||||||
time.sleep(35)
|
time.sleep(single_time)
|
||||||
elif number < 12: # 堵转
|
elif number < 12: # 堵转
|
||||||
time.sleep(15)
|
time.sleep(stall_time)
|
||||||
else: # 场景
|
else: # 场景
|
||||||
t_start = time.time()
|
t_start = time.time()
|
||||||
while True:
|
while True:
|
||||||
scenario_time = md.read_scenario_time()
|
scenario_time = float(f"{float(md.read_scenario_time()):.2f}")
|
||||||
if float(scenario_time) > 1:
|
if float(scenario_time) != 0:
|
||||||
w2t(f"场景{number-5}的周期时间:{scenario_time}\n")
|
w2t(f"场景{number - 11}的周期时间:{scenario_time}\n")
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
time.sleep(5)
|
time.sleep(1)
|
||||||
if (time.time()-t_start)//60 > 3:
|
if (time.time()-t_start) > 180:
|
||||||
w2t(f"未收到场景{number-5}的周期时间,需要确认RL程序编写正确并正常执行...\n", "red", "GetScenarioTimeError")
|
w2t(f"180s 内未收到场景{number - 11}的周期时间,需要确认RL程序和工具通信交互是否正常执行...\n", "red", "GetScenarioTimeError")
|
||||||
time.sleep(1) # 一定要延迟一秒再读一次scenario time寄存器,因为一开始读取的数值不准确
|
time.sleep(20)
|
||||||
scenario_time = md.read_scenario_time()
|
|
||||||
time.sleep(float(scenario_time)*0.2) # 再运行周期的20%即可
|
|
||||||
|
|
||||||
# 5.停止程序运行,保留数据并处理输出
|
# 5.停止程序运行,保留数据并处理输出
|
||||||
clibs.execution("rl_task.stop", tasks=["current"])
|
end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
gen_result_file(path, number, scenario_time)
|
hr.execution("rl_task.stop", tasks=["current"])
|
||||||
|
time.sleep(5) # 确保数据都拿到
|
||||||
|
gen_result_file(path, number, start_time, end_time, scenario_time)
|
||||||
else:
|
else:
|
||||||
if sub == "tool100":
|
if sub == "tool100":
|
||||||
w2t("单轴和场景电机电流采集完毕,如需采集惯量负载,须切换负载类型,并更换惯量负载,重新执行。\n", "green")
|
w2t("单轴和场景电机电流采集完毕,如需采集惯量负载,须切换负载类型,并更换惯量负载,重新执行。\n", "green")
|
||||||
@ -231,7 +239,6 @@ def main():
|
|||||||
w2t = clibs.w2t
|
w2t = clibs.w2t
|
||||||
hr = clibs.c_hr
|
hr = clibs.c_hr
|
||||||
md = clibs.c_md
|
md = clibs.c_md
|
||||||
insert_logdb = clibs.insert_logdb
|
|
||||||
|
|
||||||
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
data_dirs, data_files = clibs.traversal_files(path, w2t)
|
||||||
prj_file = initialization(path, sub, data_dirs, data_files, hr, w2t)
|
prj_file = initialization(path, sub, data_dirs, data_files, hr, w2t)
|
||||||
|
@ -157,7 +157,7 @@ class ModbusRequest(object):
|
|||||||
clibs.insert_logdb("INFO", "openapi", f"modbus: 40101 将 {probe} 写入")
|
clibs.insert_logdb("INFO", "openapi", f"modbus: 40101 将 {probe} 写入")
|
||||||
|
|
||||||
def write_pon(self, pon):
|
def write_pon(self, pon):
|
||||||
self.__c.write_register(40101, pon)
|
self.__c.write_register(40102, pon)
|
||||||
clibs.insert_logdb("INFO", "openapi", f"modbus: 40102 将 {pon} 写入")
|
clibs.insert_logdb("INFO", "openapi", f"modbus: 40102 将 {pon} 写入")
|
||||||
|
|
||||||
def write_axis(self, axis):
|
def write_axis(self, axis):
|
||||||
@ -318,13 +318,12 @@ class ModbusRequest(object):
|
|||||||
return result.registers[0]
|
return result.registers[0]
|
||||||
|
|
||||||
def read_scenario_time(self):
|
def read_scenario_time(self):
|
||||||
results = self.__c.read_holding_registers(41002, count=2)
|
results = self.__c.read_holding_registers(40601, count=2)
|
||||||
result = BinaryPayloadDecoder.fromRegisters(results.registers, byteorder=Endian.BIG, wordorder=Endian.LITTLE)
|
result = self.__c.convert_from_registers(results.registers, data_type=self.__c.DATATYPE.FLOAT32, word_order="little")
|
||||||
result = f"{result.decode_32bit_float():.3f}"
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def read_brake_done(self):
|
def read_brake_done(self):
|
||||||
result = self.__c.read_holding_registers(41007, count=1)
|
result = self.__c.read_holding_registers(40603, count=1)
|
||||||
return result.registers[0]
|
return result.registers[0]
|
||||||
|
|
||||||
|
|
||||||
@ -721,7 +720,7 @@ class HmiRequest(object):
|
|||||||
self.close()
|
self.close()
|
||||||
clibs.w2t(f"请求 {msg_id} 发送失败......\n", "red", "ReqSendFailed")
|
clibs.w2t(f"请求 {msg_id} 发送失败......\n", "red", "ReqSendFailed")
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
time.sleep(clibs.interval * 2)
|
time.sleep(clibs.interval * 4)
|
||||||
try:
|
try:
|
||||||
clibs.lock.acquire(True)
|
clibs.lock.acquire(True)
|
||||||
clibs.cursor.execute(f"select content from logs where content like '{f_text}'")
|
clibs.cursor.execute(f"select content from logs where content like '{f_text}'")
|
||||||
|
@ -1,5 +1,275 @@
|
|||||||
|
import openpyxl
|
||||||
|
import os.path
|
||||||
|
import time
|
||||||
|
import pandas
|
||||||
|
import threading
|
||||||
|
import re
|
||||||
from common import clibs
|
from common import clibs
|
||||||
|
|
||||||
def main():
|
|
||||||
print("brake")
|
|
||||||
|
|
||||||
|
def check_files(path, rawdata_dirs, result_files, w2t):
|
||||||
|
msg_wrong = "需要有四个文件和若干个数据文件夹,可参考如下确认:\n"
|
||||||
|
msg_wrong += "1. reach33_XXXXXXX.xlsx\n2. reach66_XXXXXXX.xlsx\n3. reach100_XXXXXXX.xlsx\n4. *.cfg\n"
|
||||||
|
msg_wrong += "- reach33_load33_speed33\nreach33_load33_speed66\n......\nreach100_load100_speed66\nreach100_load100_speed100\n"
|
||||||
|
|
||||||
|
if len(result_files) != 4 or len(rawdata_dirs) == 0:
|
||||||
|
w2t(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):
|
||||||
|
w2t(msg_wrong, "red", "InitFileError")
|
||||||
|
|
||||||
|
reach_s = ['reach33', 'reach66', 'reach100']
|
||||||
|
load_s = ['load33', 'load66', 'load100']
|
||||||
|
speed_s = ['speed33', 'speed66', 'speed100']
|
||||||
|
for rawdata_dir in rawdata_dirs:
|
||||||
|
components = rawdata_dir.split("/")[-1].split('_') # reach_load_speed
|
||||||
|
if components[0] not in reach_s or components[1] not in load_s or components[2] not in speed_s:
|
||||||
|
msg = f"报错信息:数据目录 {rawdata_dir} 命名不合规,请参考如下形式\n"
|
||||||
|
msg += "命名规则:reachAA_loadBB_speedCC,AA/BB/CC 指的是臂展/负载/速度的比例\n"
|
||||||
|
msg += "规则解释:reach66_load100_speed33,表示 66% 臂展,100% 负载以及 33% 速度情况下的测试结果文件夹\n"
|
||||||
|
w2t(msg, "red", "WrongDataFolder")
|
||||||
|
|
||||||
|
_, rawdata_files = clibs.traversal_files(rawdata_dir, w2t)
|
||||||
|
if len(rawdata_files) != 3:
|
||||||
|
msg = f"数据目录 {rawdata_dir} 下数据文件个数错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件\n"
|
||||||
|
w2t(msg, "red", "WrongDataFile")
|
||||||
|
for rawdata_file in rawdata_files:
|
||||||
|
if not rawdata_file.endswith(".data"):
|
||||||
|
msg = f"数据文件 {rawdata_file} 后缀错误,每个数据目录下有且只能有三个以 .data 为后缀的数据文件"
|
||||||
|
w2t(msg, "red", "WrongDataFile")
|
||||||
|
|
||||||
|
w2t("数据目录合规性检查结束,未发现问题......")
|
||||||
|
|
||||||
|
|
||||||
|
def get_configs(configfile, w2t):
|
||||||
|
axis = configfile.split('\\')[-2][-1]
|
||||||
|
if axis not in ['1', '2', '3']:
|
||||||
|
w2t("被处理的根文件夹命名必须是 [Jj][123] 的格式", 0, 9, 'red')
|
||||||
|
else:
|
||||||
|
axis = int(axis)
|
||||||
|
|
||||||
|
_wb = load_workbook(configfile, read_only=True)
|
||||||
|
_ws = _wb['Target']
|
||||||
|
rr = float(_ws.cell(row=2, column=axis + 1).value)
|
||||||
|
av = float(_ws.cell(row=3, column=axis + 1).value)
|
||||||
|
|
||||||
|
return av, rr
|
||||||
|
|
||||||
|
|
||||||
|
def now_doing_msg(docs, flag, w2t):
|
||||||
|
# 功能:输出正在处理的文件或目录
|
||||||
|
# 参数:文件或目录,start 或 done 标识
|
||||||
|
# 返回值:-
|
||||||
|
now = strftime('%Y-%m-%d %H:%M:%S', localtime(time()))
|
||||||
|
file_type = 'file' if isfile(docs) else 'dir'
|
||||||
|
if flag == 'start' and file_type == 'dir':
|
||||||
|
w2t(f"[{now}] 正在处理目录 {docs} 中的数据......")
|
||||||
|
elif flag == 'start' and file_type == 'file':
|
||||||
|
w2t(f"[{now}] 正在处理文件 {docs} 中的数据......")
|
||||||
|
elif flag == 'done' and file_type == 'dir':
|
||||||
|
w2t(f"[{now}] 目录 {docs} 数据文件已处理完毕")
|
||||||
|
elif flag == 'done' and file_type == 'file':
|
||||||
|
w2t(f"[{now}] 文件 {docs} 数据已处理完毕")
|
||||||
|
|
||||||
|
|
||||||
|
def w2t_local(msg, wait, w2t):
|
||||||
|
while True:
|
||||||
|
global stop
|
||||||
|
if stop == 0 and wait != 0:
|
||||||
|
sleep(1)
|
||||||
|
w2t(msg, wait, 0, 'orange')
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, estop):
|
||||||
|
# 功能:将数据文件中有效数据拷贝至结果文件对应的 sheet
|
||||||
|
# 参数:如上
|
||||||
|
# 返回值:-
|
||||||
|
# 结果文件数据清零
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for _row in range(row_start, row_end + 1):
|
||||||
|
data.append(df.iloc[_row, vel - 1])
|
||||||
|
data.append(df.iloc[_row, trq - 1])
|
||||||
|
data.append(df.iloc[_row, estop - 1])
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
row_max = 2000 if row_end - row_start < 2000 else row_end - row_start + 20
|
||||||
|
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:
|
||||||
|
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 find_row_start(data_file, df, conditions, av, rr, vel, estop, w2t):
|
||||||
|
# 功能:查找数据文件中有效数据的行号,也即最后一个速度下降的点位
|
||||||
|
# 参数:如上
|
||||||
|
# 返回值:速度下降点位,最后的数据点位
|
||||||
|
ratio = float(conditions[2].removeprefix('speed')) / 100
|
||||||
|
av_max = av * ratio
|
||||||
|
row_max = df.index[-1]
|
||||||
|
threshold = 0.95
|
||||||
|
|
||||||
|
for _row in range(row_max, -1, -1):
|
||||||
|
if df.iloc[_row, estop - 1] != 0:
|
||||||
|
row_start = _row - 20 if _row - 20 > 0 else 0
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
w2t(f"数据文件 {data_file} 采集的数据中没有 ESTOP 为非 0 的情况,需要确认", 0, 9, 'red')
|
||||||
|
|
||||||
|
for _row in range(row_start, row_max):
|
||||||
|
speed_row = (df.iloc[_row, vel - 1] * 180) / 3.1415926 * rr * 60 / 360
|
||||||
|
if abs(speed_row) < 1:
|
||||||
|
row_end = _row + 100 if _row + 100 <= row_max else row_max
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
w2t(f"数据文件 {data_file} 最后的速度未降为零 ", 0, 10, 'red')
|
||||||
|
|
||||||
|
av_estop = abs((df.iloc[row_start - 10:row_start + 10, vel - 1].abs().mean() * 180) / 3.1415926)
|
||||||
|
if abs(av_estop / av_max) < threshold:
|
||||||
|
filename = data_file.split('\\')[-1]
|
||||||
|
w2t(f"[av_estop: {av_estop:.2f} | shouldbe: {av_max:.2f}] 数据文件 {filename} 触发 ESTOP 时未采集到指定百分比的最大速度,需要检查", 0, 0, '#8A2BE2')
|
||||||
|
|
||||||
|
return row_start, row_end
|
||||||
|
|
||||||
|
|
||||||
|
def find_result_sheet_name(conditions, count):
|
||||||
|
# 功能:获取结果文件准确的sheet页名称
|
||||||
|
# 参数:臂展和速度的列表
|
||||||
|
# 返回值:结果文件对应的sheet name
|
||||||
|
# 33%负载_33%速度_1 - ['loadxx', 'reachxx', 'speedxx']
|
||||||
|
load = conditions[0].removeprefix('load')
|
||||||
|
speed = conditions[2].removeprefix('speed')
|
||||||
|
result_sheet_name = f"{load}%负载_{speed}%速度_{count}"
|
||||||
|
|
||||||
|
return result_sheet_name
|
||||||
|
|
||||||
|
|
||||||
|
def single_file_process(data_file, wb_result, count, av, rr, vel, trq, estop, w2t):
|
||||||
|
# 功能:完成单个数据文件的处理
|
||||||
|
# 参数:如上
|
||||||
|
# 返回值:-
|
||||||
|
df = read_csv(data_file, sep='\t')
|
||||||
|
|
||||||
|
conditions = sorted(data_file.split('\\')[-2].split('_')) # ['loadxx', 'reachxx', 'speedxx']
|
||||||
|
result_sheet_name = find_result_sheet_name(conditions, count)
|
||||||
|
ws_result = wb_result[result_sheet_name]
|
||||||
|
|
||||||
|
row_start, row_end = find_row_start(data_file, df, conditions, av, rr, vel, estop, w2t)
|
||||||
|
copy_data_to_result(df, ws_result, row_start, row_end, vel, trq, estop)
|
||||||
|
|
||||||
|
|
||||||
|
def data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t):
|
||||||
|
# 功能:完成一个结果文件的数据处理
|
||||||
|
# 参数:结果文件,数据目录,以及预读取的参数
|
||||||
|
# 返回值:-
|
||||||
|
file_name = result_file.split('\\')[-1]
|
||||||
|
w2t(f"正在打开文件 {file_name} 需要 1min 左右", 1, 0, 'orange')
|
||||||
|
|
||||||
|
global stop
|
||||||
|
stop = 0
|
||||||
|
t_excel = clibs.GetThreadResult(load_workbook, args=(result_file,))
|
||||||
|
t_wait = Thread(target=w2t_local, args=('.', 1, w2t))
|
||||||
|
t_excel.start()
|
||||||
|
t_wait.start()
|
||||||
|
t_excel.join()
|
||||||
|
wb_result = t_excel.get_result()
|
||||||
|
stop = 1
|
||||||
|
sleep(1.1)
|
||||||
|
w2t('')
|
||||||
|
|
||||||
|
prefix = result_file.split('\\')[-1].split('_')[0]
|
||||||
|
for raw_data_dir in raw_data_dirs:
|
||||||
|
if raw_data_dir.split('\\')[-1].split('_')[0] == prefix:
|
||||||
|
now_doing_msg(raw_data_dir, 'start', w2t)
|
||||||
|
_, data_files = clibs.traversal_files(raw_data_dir, w2t)
|
||||||
|
# 数据文件串行处理模式---------------------------------
|
||||||
|
# count = 1
|
||||||
|
# for data_file in data_files:
|
||||||
|
# now_doing_msg(data_file, 'start', w2t)
|
||||||
|
# single_file_process(data_file, wb_result, count, av, rr, vel, trq, estop, w2t)
|
||||||
|
# count += 1
|
||||||
|
# now_doing_msg(data_file, 'done', w2t)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# 数据文件并行处理模式---------------------------------
|
||||||
|
threads = [
|
||||||
|
Thread(target=single_file_process, args=(data_files[0], wb_result, 1, av, rr, vel, trq, estop, w2t)),
|
||||||
|
Thread(target=single_file_process, args=(data_files[1], wb_result, 2, av, rr, vel, trq, estop, w2t)),
|
||||||
|
Thread(target=single_file_process, args=(data_files[2], wb_result, 3, av, rr, vel, trq, estop, w2t))
|
||||||
|
]
|
||||||
|
[t.start() for t in threads]
|
||||||
|
[t.join() for t in threads]
|
||||||
|
# ---------------------------------------------------
|
||||||
|
now_doing_msg(raw_data_dir, 'done', w2t)
|
||||||
|
|
||||||
|
now_doing_msg(result_file, 'done', w2t)
|
||||||
|
w2t(f"正在保存文件 {file_name} 需要 1min 左右", 1, 0, 'orange')
|
||||||
|
stop = 0
|
||||||
|
t_excel = Thread(target=wb_result.save, args=(result_file,))
|
||||||
|
t_wait = Thread(target=w2t_local, args=('.', 1, w2t))
|
||||||
|
t_excel.start()
|
||||||
|
t_wait.start()
|
||||||
|
t_excel.join()
|
||||||
|
stop = 1
|
||||||
|
sleep(1.1)
|
||||||
|
w2t('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# path, vel, trq, estop, w2t
|
||||||
|
path = clibs.data_dp["_path"]
|
||||||
|
vel = int(clibs.data_dp["_vel"])
|
||||||
|
trq = int(clibs.data_dp["_trq"])
|
||||||
|
estop = int(clibs.data_dp["_estop"])
|
||||||
|
w2t = clibs.w2t
|
||||||
|
insert_logdb = clibs.insert_logdb
|
||||||
|
time_start = time.time()
|
||||||
|
rawdata_dirs, result_files = clibs.traversal_files(path, w2t)
|
||||||
|
|
||||||
|
# threads = []
|
||||||
|
check_files(path, rawdata_dirs, result_files, w2t)
|
||||||
|
# av, rr = get_configs(path + '\\configs.xlsx', w2t)
|
||||||
|
#
|
||||||
|
# prefix = []
|
||||||
|
# for raw_data_dir in rawdata_dirs:
|
||||||
|
# prefix.append(raw_data_dir.split('\\')[-1].split("_")[0])
|
||||||
|
#
|
||||||
|
# for result_file in result_files:
|
||||||
|
# if result_file.split('\\')[-1].split('_')[0] not in set(prefix):
|
||||||
|
# continue
|
||||||
|
# else:
|
||||||
|
# now_doing_msg(result_file, 'start', w2t)
|
||||||
|
# data_process(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t)
|
||||||
|
# # threads.append(Thread(target=data_process, args=(result_file, raw_data_dirs, av, rr, vel, trq, estop, w2t)))
|
||||||
|
# # [t.start() for t in threads]
|
||||||
|
# # [t.join() for t in threads]
|
||||||
|
|
||||||
|
w2t("----------------------------------------------------------\n")
|
||||||
|
w2t("全部处理完毕\n")
|
||||||
|
time_end = time.time()
|
||||||
|
time_total = time_end - time_start
|
||||||
|
msg = f"数据处理时间:{time_total // 3600:02.0f} h {time_total % 3600 // 60:02.0f} m {time_total % 60:02.0f} s\n"
|
||||||
|
w2t(msg)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
Reference in New Issue
Block a user