xarm-python-sdk 1.15.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. xarm/__init__.py +2 -0
  2. xarm/build_backend.py +17 -0
  3. xarm/core/__init__.py +2 -0
  4. xarm/core/comm/__init__.py +5 -0
  5. xarm/core/comm/base.py +303 -0
  6. xarm/core/comm/serial_port.py +44 -0
  7. xarm/core/comm/socket_port.py +150 -0
  8. xarm/core/comm/uxbus_cmd_protocol.py +100 -0
  9. xarm/core/config/__init__.py +0 -0
  10. xarm/core/config/x_code.py +1427 -0
  11. xarm/core/config/x_config.py +553 -0
  12. xarm/core/utils/__init__.py +3 -0
  13. xarm/core/utils/convert.py +124 -0
  14. xarm/core/utils/crc16.py +76 -0
  15. xarm/core/utils/debug_print.py +21 -0
  16. xarm/core/utils/log.py +98 -0
  17. xarm/core/version.py +1 -0
  18. xarm/core/wrapper/__init__.py +11 -0
  19. xarm/core/wrapper/uxbus_cmd.py +1457 -0
  20. xarm/core/wrapper/uxbus_cmd_ser.py +94 -0
  21. xarm/core/wrapper/uxbus_cmd_tcp.py +305 -0
  22. xarm/tools/__init__.py +0 -0
  23. xarm/tools/blockly/__init__.py +1 -0
  24. xarm/tools/blockly/_blockly_base.py +416 -0
  25. xarm/tools/blockly/_blockly_handler.py +1338 -0
  26. xarm/tools/blockly/_blockly_highlight.py +94 -0
  27. xarm/tools/blockly/_blockly_node.py +61 -0
  28. xarm/tools/blockly/_blockly_tool.py +480 -0
  29. xarm/tools/blockly_tool.py +1864 -0
  30. xarm/tools/gcode.py +90 -0
  31. xarm/tools/list_ports.py +39 -0
  32. xarm/tools/modbus_tcp.py +205 -0
  33. xarm/tools/threads.py +30 -0
  34. xarm/tools/utils.py +36 -0
  35. xarm/version.py +1 -0
  36. xarm/wrapper/__init__.py +1 -0
  37. xarm/wrapper/studio_api.py +34 -0
  38. xarm/wrapper/xarm_api.py +4416 -0
  39. xarm/x3/__init__.py +2 -0
  40. xarm/x3/base.py +2638 -0
  41. xarm/x3/base_board.py +198 -0
  42. xarm/x3/code.py +62 -0
  43. xarm/x3/decorator.py +104 -0
  44. xarm/x3/events.py +166 -0
  45. xarm/x3/ft_sensor.py +264 -0
  46. xarm/x3/gpio.py +457 -0
  47. xarm/x3/grammar_async.py +21 -0
  48. xarm/x3/grammar_coroutine.py +24 -0
  49. xarm/x3/gripper.py +830 -0
  50. xarm/x3/modbus_tcp.py +84 -0
  51. xarm/x3/parse.py +110 -0
  52. xarm/x3/record.py +216 -0
  53. xarm/x3/report.py +204 -0
  54. xarm/x3/robotiq.py +220 -0
  55. xarm/x3/servo.py +485 -0
  56. xarm/x3/studio.py +138 -0
  57. xarm/x3/track.py +424 -0
  58. xarm/x3/utils.py +43 -0
  59. xarm/x3/xarm.py +1928 -0
  60. xarm_python_sdk-1.15.2.dist-info/METADATA +103 -0
  61. xarm_python_sdk-1.15.2.dist-info/RECORD +63 -0
  62. xarm_python_sdk-1.15.2.dist-info/WHEEL +4 -0
  63. xarm_python_sdk-1.15.2.dist-info/licenses/LICENSE +27 -0
xarm/x3/gripper.py ADDED
@@ -0,0 +1,830 @@
1
+ #!/usr/bin/env python3
2
+ # Software License Agreement (BSD License)
3
+ #
4
+ # Copyright (c) 2018, UFACTORY, Inc.
5
+ # All rights reserved.
6
+ #
7
+ # Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
8
+
9
+ import time
10
+ import struct
11
+ from ..core.config.x_config import XCONF
12
+ from ..core.utils.log import logger
13
+ from ..core.utils import convert
14
+ from .code import APIState
15
+ from .gpio import GPIO
16
+ from .decorator import xarm_is_connected, xarm_wait_until_not_pause, xarm_is_not_simulation_mode
17
+
18
+
19
+ class Gripper(GPIO):
20
+ def __init__(self):
21
+ super(Gripper, self).__init__()
22
+ self._gripper_error_code = 0
23
+ self._bio_gripper_version = 0 # 0表示未曾获取SN判别,1表示旧的(获取SN失败), 2表示新的(获取SN成功)
24
+
25
+ @property
26
+ def gripper_error_code(self):
27
+ return self._gripper_error_code
28
+
29
+ @gripper_error_code.setter
30
+ def gripper_error_code(self, val):
31
+ self._gripper_error_code = val
32
+
33
+ @property
34
+ def gripper_is_support_status(self):
35
+ if self.gripper_version_numbers[0] == -1 or self.gripper_version_numbers[1] == -1 or self.gripper_version_numbers[2] == -1:
36
+ self.get_gripper_version()
37
+ return self.gripper_version_numbers[0] > 3 \
38
+ or (self.gripper_version_numbers[0] == 3 and self.gripper_version_numbers[1] > 4) \
39
+ or (self.gripper_version_numbers[0] == 3 and self.gripper_version_numbers[1] == 4 and self.gripper_version_numbers[2] >= 3)
40
+
41
+ @xarm_is_connected(_type='get')
42
+ def get_gripper_status(self):
43
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
44
+ if code != 0:
45
+ return code, 0
46
+ ret = self.arm_cmd.gripper_modbus_r16s(0x0000, 1)
47
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
48
+ status = 0
49
+ if ret[0] == 0 and len(ret) == 7:
50
+ status = convert.bytes_to_u16(ret[5:7])
51
+ return ret[0], status
52
+
53
+ @xarm_is_connected(_type='get')
54
+ @xarm_is_not_simulation_mode(ret=(0, '*.*.*'))
55
+ def get_gripper_version(self):
56
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
57
+ if code != 0:
58
+ return code, '*.*.*'
59
+ versions = ['*', '*', '*']
60
+ ret1 = self.arm_cmd.gripper_modbus_r16s(0x0801, 1)
61
+ ret2 = self.arm_cmd.gripper_modbus_r16s(0x0802, 1)
62
+ ret3 = self.arm_cmd.gripper_modbus_r16s(0x0803, 1)
63
+ ret1[0] = self._check_modbus_code(ret1, only_check_code=True)
64
+ ret2[0] = self._check_modbus_code(ret2, only_check_code=True)
65
+ ret3[0] = self._check_modbus_code(ret3, only_check_code=True)
66
+
67
+ code = 0
68
+
69
+ if ret1[0] == 0 and len(ret1) == 7:
70
+ versions[0] = convert.bytes_to_u16(ret1[5:7])
71
+ self.gripper_version_numbers[0] = versions[0]
72
+ else:
73
+ code = ret1[0]
74
+
75
+ if ret2[0] == 0 and len(ret2) == 7:
76
+ versions[1] = convert.bytes_to_u16(ret2[5:7])
77
+ self.gripper_version_numbers[1] = versions[1]
78
+ else:
79
+ code = ret2[0]
80
+
81
+ if ret3[0] == 0 and len(ret3) == 7:
82
+ versions[2] = convert.bytes_to_u16(ret3[5:7])
83
+ self.gripper_version_numbers[2] = versions[2]
84
+ else:
85
+ code = ret3[0]
86
+
87
+ return code, '.'.join(map(str, versions))
88
+
89
+ @xarm_is_connected(_type='set')
90
+ @xarm_is_not_simulation_mode(ret=0)
91
+ def set_gripper_enable(self, enable, is_modbus=True):
92
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
93
+ if code != 0:
94
+ return code
95
+ if is_modbus:
96
+ return self._set_modbus_gripper_enable(enable)
97
+ else:
98
+ return self._set_gripper_enable(enable)
99
+
100
+ @xarm_is_connected(_type='set')
101
+ @xarm_is_not_simulation_mode(ret=0)
102
+ def set_gripper_mode(self, mode, is_modbus=True):
103
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
104
+ if code != 0:
105
+ return code
106
+ if is_modbus:
107
+ return self._set_modbus_gripper_mode(mode)
108
+ else:
109
+ return self._set_gripper_mode(mode)
110
+
111
+ @xarm_is_connected(_type='set')
112
+ @xarm_is_not_simulation_mode(ret=0)
113
+ def set_gripper_speed(self, speed, is_modbus=True):
114
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
115
+ if code != 0:
116
+ return code
117
+ if is_modbus:
118
+ return self._set_modbus_gripper_speed(speed)
119
+ else:
120
+ return self._set_gripper_speed(speed)
121
+
122
+ @xarm_is_connected(_type='get')
123
+ @xarm_is_not_simulation_mode(ret=(0, 0))
124
+ def get_gripper_position(self, is_modbus=True):
125
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
126
+ if code != 0:
127
+ return code, None
128
+ if is_modbus:
129
+ return self._get_modbus_gripper_position()
130
+ else:
131
+ return self._get_gripper_position()
132
+
133
+ @xarm_wait_until_not_pause
134
+ @xarm_is_connected(_type='set')
135
+ def set_gripper_position(self, pos, wait=False, speed=None, auto_enable=False, timeout=None, is_modbus=True, **kwargs):
136
+ if is_modbus:
137
+ return self._set_modbus_gripper_position(pos, wait=wait, speed=speed, auto_enable=auto_enable, timeout=timeout, **kwargs)
138
+ else:
139
+ return self._set_gripper_position(pos, wait=wait, speed=speed, auto_enable=auto_enable, timeout=timeout, **kwargs)
140
+
141
+ @xarm_is_connected(_type='get')
142
+ @xarm_is_not_simulation_mode(ret=(0, 0))
143
+ def get_gripper_err_code(self, is_modbus=True):
144
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
145
+ if code != 0:
146
+ return code, 0
147
+ if is_modbus:
148
+ return self._get_modbus_gripper_err_code()
149
+ else:
150
+ return self._get_gripper_position()
151
+
152
+ @xarm_is_connected(_type='set')
153
+ @xarm_is_not_simulation_mode(ret=0)
154
+ def clean_gripper_error(self, is_modbus=True):
155
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
156
+ if code != 0:
157
+ return code
158
+ if is_modbus:
159
+ return self._clean_modbus_gripper_error()
160
+ else:
161
+ return self._clean_gripper_error()
162
+
163
+ @xarm_is_connected(_type='set')
164
+ @xarm_is_not_simulation_mode(ret=0)
165
+ def set_gripper_zero(self, is_modbus=True):
166
+ """
167
+ Warnning, do not use, may cause the arm to be abnormal, just for debugging
168
+ :return:
169
+ """
170
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
171
+ if code != 0:
172
+ return code
173
+ if is_modbus:
174
+ return self._set_modbus_gripper_zero()
175
+ else:
176
+ return self._set_gripper_zero()
177
+
178
+ @xarm_is_connected(_type='set')
179
+ @xarm_is_not_simulation_mode(ret=0)
180
+ def set_gripper_status(self, status, delay_sec=0, sync=True):
181
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
182
+ if code != 0:
183
+ return code
184
+ if status:
185
+ code1 = self.set_tgpio_digital(ionum=0, value=1, delay_sec=delay_sec, sync=sync)
186
+ code2 = self.set_tgpio_digital(ionum=1, value=0, delay_sec=delay_sec, sync=sync)
187
+ else:
188
+ code1 = self.set_tgpio_digital(ionum=0, value=0, delay_sec=delay_sec, sync=sync)
189
+ code2 = self.set_tgpio_digital(ionum=1, value=1, delay_sec=delay_sec, sync=sync)
190
+ code = code1 if code2 == 0 else code2
191
+ self.log_api_info('API -> set_gripper_status(status={}, delay_sec={}) -> code={}'.format(status, delay_sec, code), code=code)
192
+ return code
193
+
194
+ ########################### Old Protocol #################################
195
+ @xarm_is_connected(_type='set')
196
+ def _set_gripper_enable(self, enable):
197
+ ret = self.arm_cmd.gripper_set_en(int(enable))
198
+ self.log_api_info('API -> set_gripper_enable(enable={}) -> code={}'.format(enable, ret[0]), code=ret[0])
199
+ return ret[0]
200
+
201
+ @xarm_is_connected(_type='set')
202
+ def _set_gripper_mode(self, mode):
203
+ ret = self.arm_cmd.gripper_set_mode(mode)
204
+ self.log_api_info('API -> set_gripper_mode(mode={}) -> code={}'.format(mode, ret[0]), code=ret[0])
205
+ return ret[0]
206
+
207
+ @xarm_is_connected(_type='set')
208
+ def _set_gripper_speed(self, speed):
209
+ ret = self.arm_cmd.gripper_set_posspd(speed)
210
+ self.log_api_info('API -> set_gripper_speed(speed={}) -> code={}'.format(speed, ret[0]), code=ret[0])
211
+ return ret[0]
212
+
213
+ @xarm_is_connected(_type='get')
214
+ def _get_gripper_position(self):
215
+ ret = self.arm_cmd.gripper_get_pos()
216
+ if self._check_code(ret[0]) != 0 or len(ret) <= 1:
217
+ return ret[0], None
218
+ elif ret[0] in [XCONF.UxbusState.ERR_CODE, XCONF.UxbusState.WAR_CODE]:
219
+ self.get_err_warn_code()
220
+ if self.error_code == 19 or self.error_code == 28:
221
+ return ret[0], None
222
+ ret[0] = 0
223
+ return ret[0], int(ret[1])
224
+
225
+ @xarm_is_connected(_type='set')
226
+ def _set_gripper_position(self, pos, wait=False, speed=None, auto_enable=False, timeout=None, **kwargs):
227
+ if kwargs.get('wait_motion', True):
228
+ has_error = self.error_code != 0
229
+ is_stop = self.is_stop
230
+ code = self.wait_move()
231
+ if not (code == 0 or (is_stop and code == APIState.EMERGENCY_STOP)
232
+ or (has_error and code == APIState.HAS_ERROR)):
233
+ return code
234
+ if self.check_is_simulation_robot():
235
+ return 0
236
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
237
+ if code != 0:
238
+ return code
239
+ if auto_enable:
240
+ self.arm_cmd.gripper_set_en(True)
241
+ if speed is not None:
242
+ self.arm_cmd.gripper_set_posspd(speed)
243
+ ret = self.arm_cmd.gripper_set_pos(pos)
244
+ self.log_api_info('API -> set_gripper_position(pos={}) -> code={}'.format(pos, ret[0]), code=ret[0])
245
+ if wait:
246
+ is_add = True
247
+ last_pos = 0
248
+ _, p = self._get_gripper_position()
249
+ if _ == 0 and p is not None:
250
+ last_pos = int(p)
251
+ if last_pos == pos:
252
+ return 0
253
+ is_add = True if pos > last_pos else False
254
+ count = 0
255
+ count2 = 0
256
+ if not timeout or not isinstance(timeout, (int, float)):
257
+ timeout = 10
258
+ expired = time.monotonic() + timeout
259
+ while time.monotonic() < expired:
260
+ _, p = self._get_gripper_position()
261
+ if _ == 0 and p is not None:
262
+ cur_pos = int(p)
263
+ if abs(pos - cur_pos) <= 1:
264
+ last_pos = cur_pos
265
+ break
266
+ if is_add:
267
+ if cur_pos <= last_pos:
268
+ count += 1
269
+ elif cur_pos <= pos:
270
+ last_pos = cur_pos
271
+ count = 0
272
+ count2 = 0
273
+ else:
274
+ count2 += 1
275
+ if count2 >= 10:
276
+ break
277
+ else:
278
+ if cur_pos >= last_pos:
279
+ count += 1
280
+ elif cur_pos >= pos:
281
+ last_pos = cur_pos
282
+ count = 0
283
+ count2 = 0
284
+ else:
285
+ count2 += 1
286
+ if count2 >= 10:
287
+ break
288
+ if count >= 7:
289
+ # print('gripper target: {}, current: {}'.format(pos, cur_pos))
290
+ break
291
+ time.sleep(0.2)
292
+ else:
293
+ return _
294
+ # print('gripper, pos: {}, last: {}'.format(pos, last_pos))
295
+ return ret[0]
296
+ else:
297
+ return ret[0]
298
+
299
+ @xarm_is_connected(_type='get')
300
+ def _get_gripper_err_code(self):
301
+ ret = self.arm_cmd.gripper_get_errcode()
302
+ if self._check_code(ret[0]) == 0:
303
+ self._gripper_error_code = ret[1]
304
+ if ret[0] == XCONF.UxbusState.ERR_CODE:
305
+ self.get_err_warn_code()
306
+ if self.error_code == 19 or self.error_code == 28:
307
+ print('gripper/tgpio error, code=C{}, G{}'.format(self.error_code, ret[1]))
308
+ return ret[0], ret[1]
309
+ ret[0] = 0
310
+ return ret[0], ret[1]
311
+ return ret[0], 0
312
+
313
+ @xarm_is_connected(_type='set')
314
+ def _clean_gripper_error(self):
315
+ ret = self.arm_cmd.gripper_clean_err()
316
+ self.log_api_info('API -> clean_gripper_error -> code={}'.format(ret[0]), code=ret[0])
317
+ return ret[0]
318
+
319
+ @xarm_is_connected(_type='set')
320
+ def _set_gripper_zero(self):
321
+ """
322
+ Warnning, do not use, may cause the arm to be abnormal, just for debugging
323
+ :return:
324
+ """
325
+ ret = self.arm_cmd.gripper_set_zero()
326
+ self.log_api_info('API -> set_gripper_zero -> code={}'.format(ret[0]), code=ret[0])
327
+ return ret[0]
328
+
329
+ ########################### Modbus Protocol #################################
330
+ @xarm_is_connected(_type='set')
331
+ def _set_modbus_gripper_enable(self, enable):
332
+ ret = self.arm_cmd.gripper_modbus_set_en(int(enable))
333
+ _, err = self._get_modbus_gripper_err_code()
334
+ self.log_api_info('API -> set_modbus_gripper_enable(enable={}) -> code={}, code2={}, err={}'.format(enable, ret[0], _, err), code=ret[0])
335
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
336
+ if ret[0] == 0 and self.gripper_error_code == 0:
337
+ self.gripper_is_enabled = True
338
+ return ret[0] if self._gripper_error_code == 0 else APIState.END_EFFECTOR_HAS_FAULT
339
+
340
+ @xarm_is_connected(_type='set')
341
+ def _set_modbus_gripper_mode(self, mode):
342
+ ret = self.arm_cmd.gripper_modbus_set_mode(mode)
343
+ _, err = self._get_modbus_gripper_err_code()
344
+ self.log_api_info('API -> set_modbus_gripper_mode(mode={}) -> code={}, code2={}, err={}'.format(mode, ret[0], _, err), code=ret[0])
345
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
346
+ return ret[0] if self._gripper_error_code == 0 else APIState.END_EFFECTOR_HAS_FAULT
347
+
348
+ @xarm_is_connected(_type='set')
349
+ def _set_modbus_gripper_speed(self, speed):
350
+ ret = self.arm_cmd.gripper_modbus_set_posspd(speed)
351
+ _, err = self._get_modbus_gripper_err_code()
352
+ self.log_api_info('API -> set_modbus_gripper_speed(speed={}) -> code={}, code2={}, err={}'.format(speed, ret[0], _, err), code=ret[0])
353
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
354
+ if ret[0] == 0 and self.gripper_error_code == 0:
355
+ self.gripper_speed = speed
356
+ return ret[0] if self._gripper_error_code == 0 else APIState.END_EFFECTOR_HAS_FAULT
357
+
358
+ @xarm_is_connected(_type='get')
359
+ def _get_modbus_gripper_position(self):
360
+ ret = self.arm_cmd.gripper_modbus_get_pos()
361
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
362
+ _, err = self._get_modbus_gripper_err_code()
363
+ if self._gripper_error_code != 0:
364
+ return APIState.END_EFFECTOR_HAS_FAULT
365
+ if ret[0] != 0 or len(ret) <= 1:
366
+ return ret[0], None
367
+ elif _ == 0 and err == 0:
368
+ return ret[0], int(ret[1])
369
+ else:
370
+ return ret[0], None
371
+ # return _ if err == 0 else XCONF.UxbusState.ERR_CODE, None
372
+
373
+ def __check_gripper_position(self, target_pos, timeout=None):
374
+ is_add = True
375
+ last_pos = 0
376
+ _, p = self._get_modbus_gripper_position()
377
+ if _ == 0 and p is not None:
378
+ last_pos = int(p)
379
+ if last_pos == target_pos:
380
+ return 0
381
+ is_add = True if target_pos > last_pos else False
382
+ count = 0
383
+ count2 = 0
384
+ if not timeout or not isinstance(timeout, (int, float)) or timeout <= 0:
385
+ timeout = 10
386
+ expired = time.monotonic() + timeout
387
+ failed_cnt = 0
388
+ code = APIState.WAIT_FINISH_TIMEOUT
389
+ while self.connected and time.monotonic() < expired:
390
+ _, p = self._get_modbus_gripper_position()
391
+ if self._gripper_error_code != 0:
392
+ print('xArm Gripper ErrorCode: {}'.format(self._gripper_error_code))
393
+ return APIState.END_EFFECTOR_HAS_FAULT
394
+ failed_cnt = 0 if _ == 0 and p is not None else failed_cnt + 1
395
+ if _ == 0 and p is not None:
396
+ cur_pos = int(p)
397
+ if abs(target_pos - cur_pos) <= 1:
398
+ return 0
399
+ if is_add:
400
+ if cur_pos <= last_pos:
401
+ count += 1
402
+ elif cur_pos <= target_pos:
403
+ last_pos = cur_pos
404
+ count = 0
405
+ count2 = 0
406
+ else:
407
+ count2 += 1
408
+ if count2 >= 10:
409
+ return 0
410
+ else:
411
+ if cur_pos >= last_pos:
412
+ count += 1
413
+ elif cur_pos >= target_pos:
414
+ last_pos = cur_pos
415
+ count = 0
416
+ count2 = 0
417
+ else:
418
+ count2 += 1
419
+ if count2 >= 10:
420
+ return 0
421
+ if count >= 8:
422
+ return 0
423
+ else:
424
+ if failed_cnt > 10:
425
+ return APIState.CHECK_FAILED
426
+ time.sleep(0.2)
427
+ return code
428
+
429
+ def __check_gripper_status(self, timeout=None):
430
+ start_move = False
431
+ not_start_move_cnt = 0
432
+ failed_cnt = 0
433
+ if not timeout or not isinstance(timeout, (int, float)) or timeout <= 0:
434
+ timeout = 10
435
+ expired = time.monotonic() + timeout
436
+ code = APIState.WAIT_FINISH_TIMEOUT
437
+ while self.connected and time.monotonic() < expired:
438
+ _, status = self.get_gripper_status()
439
+ failed_cnt = 0 if _ == 0 else failed_cnt + 1
440
+ if _ == 0:
441
+ if status & 0x03 == 0 or status & 0x03 == 2:
442
+ if start_move:
443
+ return 0
444
+ else:
445
+ not_start_move_cnt += 1
446
+ if not_start_move_cnt > 20:
447
+ return 0
448
+ elif not start_move:
449
+ not_start_move_cnt = 0
450
+ start_move = True
451
+ else:
452
+ if failed_cnt > 10:
453
+ return APIState.CHECK_FAILED
454
+ time.sleep(0.1)
455
+ return code
456
+
457
+ def check_catch_gripper_status(self, timeout=None):
458
+ start_move = False
459
+ not_start_move_cnt = 0
460
+ failed_cnt = 0
461
+ if not timeout or not isinstance(timeout, (int, float)) or timeout <= 0:
462
+ timeout = 10
463
+ expired = time.monotonic() + timeout
464
+ code = APIState.WAIT_FINISH_TIMEOUT
465
+ while self.connected and time.monotonic() < expired:
466
+ _, status = self.get_gripper_status()
467
+ failed_cnt = 0 if _ == 0 else failed_cnt + 1
468
+ if _ == 0:
469
+ if status & 0x03 == 2:
470
+ if start_move:
471
+ return 0
472
+ else:
473
+ not_start_move_cnt += 1
474
+ if not_start_move_cnt > 2:
475
+ return 0
476
+ elif not start_move:
477
+ not_start_move_cnt = 0
478
+ start_move = True
479
+ else:
480
+ if failed_cnt > 10:
481
+ return APIState.CHECK_FAILED
482
+ time.sleep(0.1)
483
+ return code
484
+
485
+ @xarm_is_connected(_type='set')
486
+ def _set_modbus_gripper_position(self, pos, wait=False, speed=None, auto_enable=False, timeout=None, **kwargs):
487
+ if kwargs.get('wait_motion', True):
488
+ has_error = self.error_code != 0
489
+ is_stop = self.is_stop
490
+ code = self.wait_move()
491
+ if not (code == 0 or (is_stop and code == APIState.EMERGENCY_STOP)
492
+ or (has_error and code == APIState.HAS_ERROR)):
493
+ return code
494
+ if self.check_is_simulation_robot():
495
+ return 0
496
+ code = self.checkset_modbus_baud(self._default_gripper_baud)
497
+ if code != 0:
498
+ return code
499
+ if auto_enable and not self.gripper_is_enabled:
500
+ ret = self.arm_cmd.gripper_modbus_set_en(True)
501
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
502
+ if ret[0] == 0:
503
+ self.gripper_is_enabled = True
504
+ if speed is not None and self.gripper_speed != speed:
505
+ ret = self.arm_cmd.gripper_modbus_set_posspd(speed)
506
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
507
+ if ret[0] == 0:
508
+ self.gripper_speed = speed
509
+ ret = self.arm_cmd.gripper_modbus_set_pos(pos)
510
+ self.log_api_info('API -> set_modbus_gripper_position(pos={}) -> code={}'.format(pos, ret[0]), code=ret[0])
511
+ _, err = self._get_modbus_gripper_err_code()
512
+ if self._gripper_error_code != 0:
513
+ print('xArm Gripper ErrorCode: {}'.format(self._gripper_error_code))
514
+ return APIState.END_EFFECTOR_HAS_FAULT
515
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
516
+ if wait and ret[0] == 0:
517
+ if self.gripper_is_support_status:
518
+ return self.__check_gripper_status(timeout=timeout)
519
+ else:
520
+ return self.__check_gripper_position(pos, timeout=timeout)
521
+ return ret[0]
522
+
523
+ @xarm_is_connected(_type='get')
524
+ def _get_modbus_gripper_err_code(self):
525
+ ret = self.arm_cmd.gripper_modbus_get_errcode()
526
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
527
+ if ret[0] == 0:
528
+ if ret[1] < 128:
529
+ self._gripper_error_code = ret[1]
530
+ if self._gripper_error_code != 0:
531
+ self.gripper_is_enabled = False
532
+ self.gripper_speed = 0
533
+ return ret[0], ret[1]
534
+ return ret[0], 0
535
+
536
+ @xarm_is_connected(_type='set')
537
+ def _clean_modbus_gripper_error(self):
538
+ ret = self.arm_cmd.gripper_modbus_clean_err()
539
+ self._gripper_error_code = 0
540
+ _, err = self._get_modbus_gripper_err_code()
541
+ self.log_api_info('API -> clean_modbus_gripper_error -> code={}, code2={}, err={}'.format(ret[0], _, err), code=ret[0])
542
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
543
+ return ret[0] if self._gripper_error_code == 0 else APIState.END_EFFECTOR_HAS_FAULT
544
+
545
+ @xarm_is_connected(_type='set')
546
+ def _set_modbus_gripper_zero(self):
547
+ """
548
+ Warnning, do not use, may cause the arm to be abnormal, just for debugging
549
+ :return:
550
+ """
551
+ ret = self.arm_cmd.gripper_modbus_set_zero()
552
+ _, err = self._get_modbus_gripper_err_code()
553
+ self.log_api_info('API -> set_modbus_gripper_zero -> code={}, code2={}, err={}'.format(ret[0], _, err), code=ret[0])
554
+ ret[0] = self._check_modbus_code(ret, only_check_code=True)
555
+ return ret[0] if self._gripper_error_code == 0 else APIState.END_EFFECTOR_HAS_FAULT
556
+
557
+ def __bio_gripper_send_modbus(self, data_frame, min_res_len=0):
558
+ code = self.checkset_modbus_baud(self._default_bio_baud)
559
+ if code != 0:
560
+ return code, []
561
+ return self.getset_tgpio_modbus_data(data_frame, min_res_len=min_res_len, ignore_log=True)
562
+
563
+ def __bio_gripper_wait_motion_completed(self, timeout=5, **kwargs):
564
+ failed_cnt = 0
565
+ expired = time.monotonic() + timeout
566
+ code = APIState.WAIT_FINISH_TIMEOUT
567
+ check_detected = kwargs.get('check_detected', False)
568
+ while time.monotonic() < expired:
569
+ _, status = self.get_bio_gripper_status()
570
+ failed_cnt = 0 if _ == 0 else failed_cnt + 1
571
+ if _ == 0:
572
+ code = code if (status & 0x03) == XCONF.BioGripperState.IS_MOTION \
573
+ else APIState.END_EFFECTOR_HAS_FAULT if (status & 0x03) == XCONF.BioGripperState.IS_FAULT \
574
+ else 0 if not check_detected or (status & 0x03) == XCONF.BioGripperState.IS_DETECTED else code
575
+ else:
576
+ code = APIState.NOT_CONNECTED if _ == APIState.NOT_CONNECTED else APIState.CHECK_FAILED if failed_cnt > 10 else code
577
+ if code != APIState.WAIT_FINISH_TIMEOUT:
578
+ break
579
+ time.sleep(0.1)
580
+ if self.bio_gripper_error_code != 0:
581
+ print('BIO Gripper ErrorCode: {}'.format(self.bio_gripper_error_code))
582
+ if code == 0 and not self.bio_gripper_is_enabled:
583
+ code = APIState.END_EFFECTOR_NOT_ENABLED
584
+ return code
585
+
586
+ def __bio_gripper_wait_enable_completed(self, timeout=3):
587
+ failed_cnt = 0
588
+ expired = time.monotonic() + timeout
589
+ code = APIState.WAIT_FINISH_TIMEOUT
590
+ while time.monotonic() < expired:
591
+ _, status = self.get_bio_gripper_status()
592
+ failed_cnt = 0 if _ == 0 else failed_cnt + 1
593
+ if _ == 0:
594
+ code = 0 if self.bio_gripper_is_enabled else code
595
+ else:
596
+ code = APIState.NOT_CONNECTED if _ == APIState.NOT_CONNECTED else APIState.CHECK_FAILED if failed_cnt > 10 else code
597
+ if code != APIState.WAIT_FINISH_TIMEOUT:
598
+ break
599
+ time.sleep(0.1)
600
+ return code
601
+
602
+ @xarm_is_connected(_type='set')
603
+ @xarm_is_not_simulation_mode(ret=False)
604
+ def check_bio_gripper_is_catch(self, timeout=3):
605
+ return self.__bio_gripper_wait_motion_completed(timeout=timeout, check_detected=True) == 0
606
+
607
+ @xarm_is_connected(_type='set')
608
+ @xarm_is_not_simulation_mode(ret=0)
609
+ def set_bio_gripper_enable(self, enable, wait=True, timeout=3):
610
+ data_frame = [0x08, 0x06, 0x01, 0x00, 0x00, int(enable)]
611
+ code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
612
+ if code == 0 and enable and wait:
613
+ code = self.__bio_gripper_wait_enable_completed(timeout=timeout)
614
+ self.log_api_info('API -> set_bio_gripper_enable(enable={}, wait={}, timeout={}) ->code={}'.format(enable, wait, timeout, code), code=code)
615
+ # self.bio_gripper_is_enabled = True if code == 0 else self.bio_gripper_is_enabled
616
+ self.get_bio_gripper_sn()
617
+ return code
618
+
619
+ @xarm_is_connected(_type='get')
620
+ @xarm_is_not_simulation_mode(ret=0)
621
+ def get_bio_gripper_sn(self):
622
+ code, ret = self.get_bio_gripper_register(address=0x0B10, number_of_registers=16)
623
+ if code == APIState.MODBUS_ERR_LENG:
624
+ self._bio_gripper_version = 1
625
+ return code, ret
626
+ elif code != 0:
627
+ self._bio_gripper_version = 0
628
+ return code, ''
629
+ else:
630
+ self._bio_gripper_version = 2
631
+ # return code, ''.join(list(map(chr, ret[5:])))
632
+ ret_list = [int(str(ret[i]) + str(ret[i+1])) for i in range(3, 31, 2)]
633
+ return code, ''.join(list(map(chr, ret_list)))
634
+
635
+ @xarm_is_connected(_type='set')
636
+ @xarm_is_not_simulation_mode(ret=0)
637
+ def set_bio_gripper_control_mode(self, mode):
638
+ data_frame = [0x08, 0x06, 0x11, 0x0A, 0x00, mode]
639
+ code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
640
+ # reset mcu
641
+ data_frame = [0x08, 0x06, 0x06, 0x07, 0x00, 0x01]
642
+ self.__bio_gripper_send_modbus(data_frame, 6)
643
+ # wait mcu reboot
644
+ time.sleep(0.6)
645
+ self.bio_gripper_speed = 0
646
+ return code
647
+
648
+ @xarm_is_connected(_type='get')
649
+ @xarm_is_not_simulation_mode(ret=0)
650
+ def get_bio_gripper_control_mode(self):
651
+ code, ret = self.get_bio_gripper_register(address=0x010A, number_of_registers=1)
652
+ mode = (ret[-2] * 256 + ret[-1]) if code == 0 else -1
653
+ return code, mode
654
+
655
+ # @xarm_is_connected(_type='set')
656
+ # @xarm_is_not_simulation_mode(ret=0)
657
+ # def set_bio_gripper_zero(self):
658
+ # data_frame = [0x08, 0x06, 0x08, 0x0C, 0x00, 0x01]
659
+ # code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
660
+ # return code
661
+
662
+ @xarm_is_connected(_type='set')
663
+ @xarm_is_not_simulation_mode(ret=0)
664
+ def set_bio_gripper_force(self, force):
665
+ force = 1 if force < 1 else 100 if force > 100 else force
666
+ data_frame = [0x08, 0x06, 0x05, 0x06, 0x00, force]
667
+ code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
668
+ return code
669
+
670
+ @xarm_is_connected(_type='set')
671
+ @xarm_is_not_simulation_mode(ret=0)
672
+ def set_bio_gripper_speed(self, speed):
673
+ data_frame = [0x08, 0x06, 0x03, 0x03, speed // 256 % 256, speed % 256]
674
+ code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
675
+ self.log_api_info('API -> set_bio_gripper_speed(speed={}) ->code={}'.format(speed, code), code=code)
676
+ self.bio_gripper_speed = speed if code == 0 else self.bio_gripper_speed
677
+ return code
678
+
679
+ @xarm_is_connected(_type='set')
680
+ def set_bio_gripper_position(self, pos, speed=0, force=100, wait=True, timeout=5, **kwargs):
681
+ if kwargs.get('wait_motion', True):
682
+ has_error = self.error_code != 0
683
+ is_stop = self.is_stop
684
+ code = self.wait_move()
685
+ if not (code == 0 or (is_stop and code == APIState.EMERGENCY_STOP)
686
+ or (has_error and code == APIState.HAS_ERROR)):
687
+ return code
688
+ if self.check_is_simulation_robot():
689
+ return 0
690
+ if kwargs.get('auto_enable', False) and not self.bio_gripper_is_enabled:
691
+ self.set_bio_gripper_enable(True)
692
+ if speed > 0 and speed != self.bio_gripper_speed:
693
+ self.set_bio_gripper_speed(speed)
694
+
695
+ if self._bio_gripper_version == 0:
696
+ self.get_bio_gripper_sn()
697
+ if self._bio_gripper_version == 2:
698
+ code, mode = self.get_bio_gripper_control_mode()
699
+ if mode == 1:
700
+ # pos = int(pos * 3.798 - 269.620)
701
+ pos = int(pos * 3.7342 - 265.13)
702
+ self.set_bio_gripper_force(force)
703
+
704
+ data_frame = [0x08, 0x10, 0x07, 0x00, 0x00, 0x02, 0x04]
705
+ data_frame.extend(list(struct.pack('>i', pos)))
706
+ code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
707
+ if code == 0 and wait:
708
+ code = self.__bio_gripper_wait_motion_completed(timeout=timeout)
709
+ self.log_api_info(
710
+ 'API -> set_bio_gripper_position(pos={}, wait={}, timeout={}) ->code={}'.format(pos, wait, timeout, code),
711
+ code=code)
712
+ return code
713
+
714
+ @xarm_is_connected(_type='set')
715
+ def open_bio_gripper(self, speed=0, wait=True, timeout=5, **kwargs):
716
+ return self.set_bio_gripper_position(130, speed=speed, wait=wait, timeout=timeout, **kwargs)
717
+ # if kwargs.get('auto_enable', False) and not self.bio_gripper_is_enabled:
718
+ # self.set_bio_gripper_enable(True)
719
+ # if speed > 0 and speed != self.bio_gripper_speed:
720
+ # self.set_bio_gripper_speed(speed)
721
+ # data_frame = [0x08, 0x10, 0x07, 0x00, 0x00, 0x02, 0x04, 0x80, 0x00, 0x00, 0x64]
722
+ # code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
723
+ # if code == 0 and wait:
724
+ # code = self.__bio_gripper_wait_motion_completed(timeout=timeout, **kwargs)
725
+ # self.log_api_info('API -> open_bio_gripper(wait={}, timeout={}) ->code={}'.format(wait, timeout, code), code=code)
726
+ # return code
727
+
728
+ @xarm_is_connected(_type='set')
729
+ def close_bio_gripper(self, speed=0, wait=True, timeout=5, **kwargs):
730
+ return self.set_bio_gripper_position(50, speed=speed, wait=wait, timeout=timeout, **kwargs)
731
+ # if kwargs.get('auto_enable', False):
732
+ # self.set_bio_gripper_enable(True)
733
+ # if speed > 0 and speed != self.bio_gripper_speed:
734
+ # self.set_bio_gripper_speed(speed)
735
+ # data_frame = [0x08, 0x10, 0x07, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x64]
736
+ # code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
737
+ # if code == 0 and wait:
738
+ # code = self.__bio_gripper_wait_motion_completed(timeout=timeout, **kwargs)
739
+ # self.log_api_info('API -> close_bio_gripper(wait={}, timeout={}) ->code={}'.format(wait, timeout, code), code=code)
740
+ # return code
741
+
742
+ @xarm_is_connected(_type='get')
743
+ def get_bio_gripper_register(self, address=0x00, number_of_registers=1):
744
+ data_frame = [0x08, 0x03]
745
+ data_frame.extend(list(struct.pack('>h', address)))
746
+ data_frame.extend(list(struct.pack('>h', number_of_registers)))
747
+ return self.__bio_gripper_send_modbus(data_frame, 3 + 2 * number_of_registers)
748
+
749
+ @xarm_is_connected(_type='get')
750
+ @xarm_is_not_simulation_mode(ret=(0, 0))
751
+ def get_bio_gripper_status(self):
752
+ code, ret = self.get_bio_gripper_register(address=0x00)
753
+ status = (ret[-2] * 256 + ret[-1]) if code == 0 else -1
754
+ if code == 0:
755
+ if (status & 0x03) == XCONF.BioGripperState.IS_FAULT:
756
+ self.get_bio_gripper_error()
757
+ else:
758
+ self.bio_gripper_error_code = 0
759
+ if ((status >> 2) & 0x03) == XCONF.BioGripperState.IS_ENABLED:
760
+ self.bio_gripper_is_enabled = True
761
+ else:
762
+ self.bio_gripper_is_enabled = False
763
+ return code, status
764
+
765
+ @xarm_is_connected(_type='get')
766
+ @xarm_is_not_simulation_mode(ret=(0, 0))
767
+ def get_bio_gripper_error(self):
768
+ code, ret = self.get_bio_gripper_register(address=0x0F)
769
+ error_code = (ret[-2] * 256 + ret[-1]) if code == 0 else -1
770
+ if code == 0:
771
+ self.bio_gripper_error_code = error_code
772
+ return code, error_code
773
+
774
+ @xarm_is_not_simulation_mode(ret=(0, '*.*.*'))
775
+ def get_bio_gripper_version(self):
776
+ code, ret = self.get_bio_gripper_register(address=0x0801, number_of_registers=0x03)
777
+ versions = ['*', '*', '*']
778
+ if code == 0:
779
+ versions[0] = convert.bytes_to_u16(ret[3:5])
780
+ versions[1] = convert.bytes_to_u16(ret[5:7])
781
+ versions[2] = convert.bytes_to_u16(ret[7:9])
782
+ return code, '.'.join(map(str, versions))
783
+
784
+ @xarm_is_connected(_type='get')
785
+ @xarm_is_not_simulation_mode(ret=(0, 0))
786
+ def get_bio_gripper_position(self):
787
+ code, ret = self.get_bio_gripper_register(address=0x0702, number_of_registers=2)
788
+ bio_position = (ret[-4] * 256**3 + ret[-3] * 256**2 + ret[-2] * 256 + ret[-1]) if code == 0 else -1
789
+ bio_position = round((bio_position + 265.13) / 3.7342, 0)
790
+ return code, bio_position
791
+
792
+ @xarm_is_connected(_type='get')
793
+ @xarm_is_not_simulation_mode(ret=(0, 0))
794
+ def get_bio_gripper_speed(self):
795
+ code, ret = self.get_bio_gripper_register(address=0x0303)
796
+ bio_speed = (ret[-2] * 256 + ret[-1]) if code == 0 else -1
797
+ return code, bio_speed
798
+
799
+ @xarm_is_connected(_type='get')
800
+ @xarm_is_not_simulation_mode(ret=(0, 0))
801
+ def get_bio_gripper_force(self):
802
+ code, ret = self.get_bio_gripper_register(address=0x0506)
803
+ bio_force = (ret[-2] * 256 + ret[-1]) if code == 0 else -1
804
+ return code, bio_force
805
+
806
+ @xarm_is_connected(_type='set')
807
+ def clean_bio_gripper_error(self):
808
+ data_frame = [0x08, 0x06, 0x00, 0x0F, 0x00, 0x00]
809
+ code, _ = self.__bio_gripper_send_modbus(data_frame, 6)
810
+ self.log_api_info('API -> clean_bio_gripper_error -> code={}'.format(code), code=code)
811
+ self.get_bio_gripper_status()
812
+ return code
813
+
814
+ @xarm_is_connected(_type='set')
815
+ def open_lite6_gripper(self, sync=True):
816
+ code1 = self.set_tgpio_digital(0, 1, sync=sync)
817
+ code2 = self.set_tgpio_digital(1, 0, sync=sync)
818
+ return code1 if code2 == 0 else code2
819
+
820
+ @xarm_is_connected(_type='set')
821
+ def close_lite6_gripper(self, sync=True):
822
+ code1 = self.set_tgpio_digital(0, 0, sync=sync)
823
+ code2 = self.set_tgpio_digital(1, 1, sync=sync)
824
+ return code1 if code2 == 0 else code2
825
+
826
+ @xarm_is_connected(_type='set')
827
+ def stop_lite6_gripper(self, sync=True):
828
+ code1 = self.set_tgpio_digital(0, 0, sync=sync)
829
+ code2 = self.set_tgpio_digital(1, 0, sync=sync)
830
+ return code1 if code2 == 0 else code2