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/gpio.py ADDED
@@ -0,0 +1,457 @@
1
+ #!/usr/bin/env python3
2
+ # Software License Agreement (BSD License)
3
+ #
4
+ # Copyright (c) 2019, UFACTORY, Inc.
5
+ # All rights reserved.
6
+ #
7
+ # Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
8
+
9
+ import time
10
+ from ..core.utils.log import logger
11
+ from ..core.config.x_config import XCONF
12
+ from .code import APIState
13
+ from .base import Base
14
+ from .decorator import xarm_is_connected, xarm_is_ready, xarm_wait_until_not_pause, xarm_is_not_simulation_mode, xarm_wait_until_cmdnum_lt_max
15
+
16
+
17
+ class GPIO(Base):
18
+ def __init__(self):
19
+ super(GPIO, self).__init__()
20
+ self.cgpio_state = {
21
+ 'digital': [-1] * 8,
22
+ 'analog': [9999] * 2
23
+ }
24
+ self.tgpio_state = {
25
+ 'digital': [-1] * 5,
26
+ 'analog': [9999] * 2
27
+ }
28
+
29
+ # @xarm_is_connected(_type='set')
30
+ # def set_tgpio_addr_16(self, addr, value):
31
+ # ret = self.arm_cmd.tgpio_addr_w16(addr, value)
32
+ # return ret[0]
33
+ #
34
+ # @xarm_is_connected(_type='get')
35
+ # def get_tgpio_addr_16(self, addr):
36
+ # ret = self.arm_cmd.tgpio_addr_r16(addr)
37
+ # return ret[0], ret[1]
38
+ #
39
+ # @xarm_is_connected(_type='set')
40
+ # def set_tgpio_addr_32(self, addr, value):
41
+ # ret = self.arm_cmd.tgpio_addr_w32(addr, value)
42
+ # return ret[0]
43
+ #
44
+ # @xarm_is_connected(_type='get')
45
+ # def get_tgpio_addr_32(self, addr):
46
+ # ret = self.arm_cmd.tgpio_addr_r32(addr)
47
+ # return ret[0], ret[1]
48
+
49
+ @xarm_is_connected(_type='get')
50
+ def get_tgpio_version(self):
51
+ versions = ['*', '*', '*']
52
+ ret1 = self.arm_cmd.tgpio_addr_r16(0x0801)
53
+ ret2 = self.arm_cmd.tgpio_addr_r16(0x0802)
54
+ ret3 = self.arm_cmd.tgpio_addr_r16(0x0803)
55
+
56
+ code = 0
57
+
58
+ if ret1[0] == 0 and len(ret1) == 2:
59
+ versions[0] = ret1[1]
60
+ else:
61
+ code = ret1[0]
62
+
63
+ if ret2[0] == 0 and len(ret2) == 2:
64
+ versions[1] = ret2[1]
65
+ else:
66
+ code = ret2[0]
67
+
68
+ if ret3[0] == 0 and len(ret3) == 2:
69
+ versions[2] = ret3[1]
70
+ else:
71
+ code = ret3[0]
72
+ # if code != 0:
73
+ # _, err_warn = self.get_err_warn_code()
74
+ # if _ in [0, 1, 2]:
75
+ # if err_warn[0] not in [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 28]:
76
+ # versions = [ret1[1], ret2[1], ret3[1]]
77
+
78
+ return code, '.'.join(map(str, versions))
79
+
80
+ @xarm_is_connected(_type='get')
81
+ def get_tgpio_digital(self, ionum=None):
82
+ assert ionum is None or ionum == 0 or ionum == 1 or ionum == 2 or ionum == 3 or ionum == 4, 'The value of parameter ionum can only be 0 or 1 or None.'
83
+ if self.check_is_simulation_robot():
84
+ return 0, [0, 0, 0, 0] if ionum is None else 0
85
+ if ionum == 2:
86
+ # Only available for Lite6 and 850
87
+ ret = self.arm_cmd.tgpio_addr_r16(0x0A12)
88
+ return ret[0], ret[1] & 0x0001
89
+ else:
90
+ ret = self.arm_cmd.tgpio_get_digital()
91
+ if ret[0] == 0:
92
+ self.tgpio_state['digital'] = ret[1:]
93
+ return ret[0], ret[1:] if ionum is None else ret[ionum + 1 if ionum < 3 else ionum]
94
+
95
+ @xarm_is_connected(_type='get')
96
+ def get_tool_digital_input(self, ionum=None):
97
+ assert ionum is None or ionum == 0 or ionum == 1 or ionum == 2 or ionum == 3 or ionum == 4, 'The value of parameter ionum can only be 0 or 1 or None.'
98
+ if self.check_is_simulation_robot():
99
+ return 0, [0, 0, 0, 0, 0] if ionum is None else 0
100
+ if ionum == 2:
101
+ # Only available for Lite6 and 850
102
+ ret = self.arm_cmd.tgpio_addr_r16(0x0A12)
103
+ return ret[0], ret[1] & 0x0001
104
+ elif isinstance(ionum, int):
105
+ ret = self.arm_cmd.tgpio_get_digital()
106
+ if ret[0] == 0:
107
+ self.tgpio_state['digital'] = ret[1:]
108
+ return ret[0], ret[ionum+1 if ionum < 3 else ionum]
109
+ else:
110
+ ret1 = self.arm_cmd.tgpio_get_digital()
111
+ if ret1[0] == 0:
112
+ self.tgpio_state['digital'] = ret1[1:]
113
+ ret2 = [0]
114
+ if self.is_lite6 or self.is_850:
115
+ ret2 = self.arm_cmd.tgpio_addr_r16(0x0A12)
116
+ ret1.insert(3, ret2[1])
117
+ return ret1[0] or ret2[0], ret1[1:4] if self.is_lite6 else ret1[1:] if self.is_850 or int(self.sn[2:6]) >= 1305 else ret1[1:3]
118
+
119
+ @xarm_is_connected(_type='get')
120
+ def get_tgpio_output_digital(self, ionum=None):
121
+ ret_li = [0, 0, 0, 0, 0]
122
+ assert ionum is None or ionum == 0 or ionum == 1 or ionum == 2 or ionum == 3 or ionum == 4, 'The value of parameter ionum can only be 0 or 1 or None.'
123
+ if self.check_is_simulation_robot():
124
+ return 0, [0, 0] if ionum is None else 0
125
+ code, ret = self.arm_cmd.tgpio_addr_r16(0x0A18)
126
+ ret_li[0] = ret & 0b01
127
+ ret_li[1] = ret >> 1 & 0b01
128
+ ret_li[2] = ret >> 4 & 0b01
129
+ ret_li[3] = ret >> 2 & 0b01
130
+ ret_li[4] = ret >> 3 & 0b01
131
+ return code, ret_li if ionum is None else ret_li[ionum]
132
+
133
+ @xarm_wait_until_not_pause
134
+ @xarm_wait_until_cmdnum_lt_max
135
+ @xarm_is_ready(_type='set')
136
+ @xarm_is_not_simulation_mode(ret=0)
137
+ def set_tgpio_digital(self, ionum, value, delay_sec=0, sync=True):
138
+ assert ionum == 0 or ionum == 1 or ionum == 2 or ionum == 3 or ionum == 4, 'The value of parameter ionum can only be 0 or 1.'
139
+ if delay_sec is not None and delay_sec > 0:
140
+ if not sync:
141
+ logger.warning('The sync parameter is ignored when delay_sec is non-zero')
142
+ ret = self.arm_cmd.tgpio_delay_set_digital(ionum if ionum < 2 else ionum-1, value, delay_sec)
143
+ self.log_api_info('API -> set_tgpio_digital(ionum={}, value={}, delay_sec={}) -> code={}'.format(ionum, value, delay_sec, ret[0]), code=ret[0])
144
+ else:
145
+ if not sync and not self.version_is_ge(2, 4, 101):
146
+ logger.warning('The current firmware does not support sync to False. If necessary, please upgrade the firmware to 2.4.101 or later.')
147
+ ret = self.arm_cmd.tgpio_set_digital(ionum+1, value, sync=sync if self.version_is_ge(2, 4, 101) else None)
148
+ self.log_api_info('API -> set_tgpio_digital(ionum={}, value={}) -> code={}'.format(ionum, value, ret[0]), code=ret[0])
149
+ return ret[0]
150
+
151
+ @xarm_is_connected(_type='get')
152
+ def get_tgpio_analog(self, ionum=None):
153
+ if self.check_is_simulation_robot():
154
+ return 0, [0, 0] if ionum is None else 0
155
+ if ionum is None:
156
+ ret1 = self.arm_cmd.tgpio_get_analog1()
157
+ ret2 = self.arm_cmd.tgpio_get_analog2()
158
+ if ret1[0] == 0:
159
+ code = ret2[0]
160
+ else:
161
+ code = ret1[0]
162
+ if ret1[0] == 0:
163
+ self.tgpio_state['analog'][0] = ret1[1]
164
+ if ret2[0] == 0:
165
+ self.tgpio_state['analog'][1] = ret2[1]
166
+ ret = [code, [ret1[1], ret2[1]]]
167
+ else:
168
+ assert ionum == 0 or ionum == 1, 'The value of parameter ionum can only be 0 or 1 or None.'
169
+ if ionum == 0:
170
+ ret = self.arm_cmd.tgpio_get_analog1()
171
+ if ret[0] == 0:
172
+ self.tgpio_state['analog'][0] = ret[1]
173
+ else:
174
+ ret = self.arm_cmd.tgpio_get_analog2()
175
+ if ret[0] == 0:
176
+ self.tgpio_state['analog'][1] = ret[1]
177
+ # if ret[0] != 0:
178
+ # self.get_err_warn_code()
179
+ # if self.error_code != 19:
180
+ # ret[0] = 0
181
+ return ret[0], ret[1]
182
+
183
+ @xarm_is_connected(_type='get')
184
+ def get_cgpio_digital(self, ionum=None):
185
+ assert ionum is None or (isinstance(ionum, int) and 15 >= ionum >= 0)
186
+ if self.check_is_simulation_robot():
187
+ return 0, [1] * (16 if self._control_box_type_is_1300 else 8) if ionum is None else 1
188
+ ret = self.arm_cmd.cgpio_get_auxdigit()
189
+ digitals = [ret[0]]
190
+ for i in range(16 if self._control_box_type_is_1300 else 8):
191
+ digitals.append(ret[1] >> i & 0x0001)
192
+ return digitals[0], digitals[1:] if ionum is None else digitals[ionum+1]
193
+
194
+ @xarm_is_connected(_type='get')
195
+ def get_cgpio_analog(self, ionum=None):
196
+ if self.check_is_simulation_robot():
197
+ return 0, [0, 0] if ionum is None else 0
198
+ if ionum is None:
199
+ ret1 = self.arm_cmd.cgpio_get_analog1()
200
+ ret2 = self.arm_cmd.cgpio_get_analog2()
201
+ if ret1[0] == 0:
202
+ code = ret2[0]
203
+ else:
204
+ code = ret1[0]
205
+ ret = [code, [ret1[1], ret2[1]]]
206
+ else:
207
+ assert ionum == 0 or ionum == 1, 'The value of parameter ionum can only be 0 or 1 or None.'
208
+ if ionum == 0:
209
+ ret = self.arm_cmd.cgpio_get_analog1()
210
+ else:
211
+ ret = self.arm_cmd.cgpio_get_analog2()
212
+ # if ret[0] != 0:
213
+ # self.get_err_warn_code()
214
+ # if self.error_code != 33:
215
+ # ret[0] = 0
216
+ return ret[0], ret[1]
217
+
218
+ @xarm_wait_until_not_pause
219
+ @xarm_wait_until_cmdnum_lt_max
220
+ @xarm_is_ready(_type='set')
221
+ @xarm_is_not_simulation_mode(ret=0)
222
+ def set_cgpio_digital(self, ionum, value, delay_sec=0, sync=True):
223
+ assert isinstance(ionum, int) and 15 >= ionum >= 0
224
+ if delay_sec is not None and delay_sec > 0:
225
+ if not sync:
226
+ logger.warning('The sync parameter is ignored when delay_sec is non-zero')
227
+ ret = self.arm_cmd.cgpio_delay_set_digital(ionum, value, delay_sec)
228
+ self.log_api_info('API -> set_cgpio_digital(ionum={}, value={}, delay_sec={}) -> code={}'.format(ionum, value, delay_sec, ret[0]), code=ret[0])
229
+ else:
230
+ if not sync and not self.version_is_ge(2, 4, 101):
231
+ logger.warning('The current firmware does not support sync to False. If necessary, please upgrade the firmware to 2.4.101 or later.')
232
+ ret = self.arm_cmd.cgpio_set_auxdigit(ionum, value, sync=sync if self.version_is_ge(2, 4, 101) else None)
233
+ self.log_api_info('API -> set_cgpio_digital(ionum={}, value={}) -> code={}'.format(ionum, value, ret[0]), code=ret[0])
234
+ return ret[0]
235
+
236
+ @xarm_wait_until_not_pause
237
+ @xarm_wait_until_cmdnum_lt_max
238
+ @xarm_is_ready(_type='set')
239
+ @xarm_is_not_simulation_mode(ret=0)
240
+ def set_cgpio_analog(self, ionum, value, sync=True):
241
+ assert ionum == 0 or ionum == 1, 'The value of parameter ionum can only be 0 or 1.'
242
+ if not sync and not self.version_is_ge(2, 4, 101):
243
+ logger.warning('The current firmware does not support sync to False. If necessary, please upgrade the firmware to 2.4.101 or later.')
244
+ if ionum == 0:
245
+ ret = self.arm_cmd.cgpio_set_analog1(value, sync=sync if self.version_is_ge(2, 4, 101) else None)
246
+ else:
247
+ ret = self.arm_cmd.cgpio_set_analog2(value, sync=sync if self.version_is_ge(2, 4, 101) else None)
248
+ self.log_api_info('API -> set_cgpio_analog(ionum={}, value={}) -> code={}'.format(ionum, value, ret[0]), code=ret[0])
249
+ return ret[0]
250
+
251
+ @xarm_is_connected(_type='set')
252
+ def set_cgpio_digital_input_function(self, ionum, fun):
253
+ assert isinstance(ionum, int) and 15 >= ionum >= 0
254
+ ret = self.arm_cmd.cgpio_set_infun(ionum, fun)
255
+ self.log_api_info('API -> set_cgpio_digital_input_function(ionum={}, fun={}) -> code={}'.format(ionum, fun, ret[0]), code=ret[0])
256
+ return ret[0]
257
+
258
+ @xarm_is_connected(_type='set')
259
+ def set_cgpio_digital_output_function(self, ionum, fun):
260
+ assert isinstance(ionum, int) and 15 >= ionum >= 0
261
+ ret = self.arm_cmd.cgpio_set_outfun(ionum, fun)
262
+ self.log_api_info('API -> set_cgpio_digital_output_function(ionum={}, fun={}) -> code={}'.format(ionum, fun, ret[0]), code=ret[0])
263
+ return ret[0]
264
+
265
+ @xarm_is_connected(_type='get')
266
+ def get_cgpio_state(self):
267
+ ret = self.arm_cmd.cgpio_get_state()
268
+ code, states = ret[0], ret[1:]
269
+ if not self._control_box_type_is_1300:
270
+ states[-1] = states[-1][:8]
271
+ states[-2] = states[-2][:8]
272
+ if code == 0 and states[0] == 0 and states[1] == 0:
273
+ self.cgpio_state['digital'] = [states[3] >> i & 0x0001 if states[10][i] in [0, 255] else 1 for i in range(len(states[10]))]
274
+ self.cgpio_state['analog'] = [states[6], states[7]]
275
+ # data = {
276
+ # 'state': ret[1],
277
+ # 'error_code': ret[2],
278
+ # 'digital': {
279
+ # 'functional': {
280
+ # 'input': [ret[3] >> i & 0x01 for i in range(8)],
281
+ # 'output': [ret[5] >> i & 0x01 for i in range(8)]
282
+ # },
283
+ # 'configuring': {
284
+ # 'input': [ret[4] >> i & 0x01 for i in range(8)],
285
+ # 'output': [ret[6] >> i & 0x01 for i in range(8)],
286
+ # }
287
+ # },
288
+ # 'analog': {
289
+ # 'input': [ret[7], ret[8]],
290
+ # 'output': [ret[9], ret[10]]
291
+ # },
292
+ # 'digital_fun': {
293
+ # 'input': ret[11],
294
+ # 'output': ret[12]
295
+ # }
296
+ # }
297
+ # import json
298
+ # # print(json.dumps(data, sort_keys=True, indent=4, skipkeys=True, separators=(',', ':'), ensure_ascii=False))
299
+ # print('cgpio_state:', ret[1])
300
+ # print('cgpio_err_code:', ret[2])
301
+ # print('cgpio_digital_input_fun_state:', bin(ret[3]))
302
+ # print('cgpio_digital_input_cfg_state:', bin(ret[4]))
303
+ # print('cgpio_digital_output_fun_state:', bin(ret[5]))
304
+ # print('cgpio_digital_output_cfg_state:', bin(ret[6]))
305
+ # print('cgpio_analog_1_input:', ret[7])
306
+ # print('cgpio_analog_2_input:', ret[8])
307
+ # print('cgpio_analog_1_output:', ret[9])
308
+ # print('cgpio_analog_2_output:', ret[10])
309
+ # print('cgpio_digital_input_fun:', ret[11])
310
+ # print('cgpio_digital_output_fun:', ret[12])
311
+ return code, states
312
+
313
+ @xarm_is_connected(_type='get')
314
+ def get_cgpio_li_state(self, Ci_Li, timeout=3, is_ci=True):
315
+ start_time = time.monotonic()
316
+ is_first = True
317
+ while is_first or time.monotonic() - start_time < timeout:
318
+ code = 0
319
+ is_first = False
320
+ if not self.connected or self.state == 4:
321
+ return False
322
+ codes, ret = self.get_cgpio_state()
323
+ digitals = [ret[3] >> i & 0x0001 if ret[10][i] in [0, 255] else 1 for i in
324
+ range(len(ret[10]))]
325
+ if codes == XCONF.UxbusState.ERR_CODE:
326
+ return False
327
+ if codes == 0:
328
+ for CI_num, CI in enumerate(Ci_Li):
329
+ if int(CI) != digitals[CI_num if is_ci else CI_num + 8]:
330
+ code = -1
331
+ break
332
+ if code == 0:
333
+ return True
334
+ time.sleep(0.1)
335
+ return False
336
+
337
+ @xarm_is_connected(_type='get')
338
+ def get_tgpio_li_state(self, Ti_Li, timeout=3):
339
+ start_time = time.monotonic()
340
+ is_first = True
341
+ while is_first or time.monotonic() - start_time < timeout:
342
+ code = 0
343
+ is_first = False
344
+ if not self.connected or self.state == 4:
345
+ return False
346
+ codes, ret = self.get_tgpio_digital()
347
+ if codes == XCONF.UxbusState.ERR_CODE:
348
+ return False
349
+ if codes == 0:
350
+ for TI_num, TI in enumerate(Ti_Li):
351
+ if int(TI) != ret[TI_num]:
352
+ code = -1
353
+ break
354
+ if code == 0:
355
+ return True
356
+ time.sleep(0.1)
357
+ return False
358
+
359
+ @xarm_wait_until_not_pause
360
+ @xarm_wait_until_cmdnum_lt_max
361
+ @xarm_is_ready(_type='set')
362
+ @xarm_is_not_simulation_mode(ret=0)
363
+ def set_suction_cup(self, on, wait=True, timeout=3, delay_sec=None, sync=True, hardware_version=1):
364
+ if on:
365
+ code1 = self.set_tgpio_digital(ionum=0 if hardware_version == 1 else 3, value=1, delay_sec=delay_sec, sync=sync)
366
+ code2 = self.set_tgpio_digital(ionum=1 if hardware_version == 1 else 4, value=0, delay_sec=delay_sec, sync=sync)
367
+ else:
368
+ code1 = self.set_tgpio_digital(ionum=0 if hardware_version == 1 else 3, value=0, delay_sec=delay_sec, sync=sync)
369
+ code2 = self.set_tgpio_digital(ionum=1 if hardware_version == 1 else 4, value=1, delay_sec=delay_sec, sync=sync)
370
+ code = code1 if code2 == 0 else code2
371
+ if code == 0 and wait:
372
+ start = time.monotonic()
373
+ code = APIState.SUCTION_CUP_TOUT
374
+ if delay_sec is not None and delay_sec > 0:
375
+ timeout += delay_sec
376
+ while time.monotonic() - start < timeout:
377
+ ret = self.get_suction_cup(hardware_version=hardware_version)
378
+ if ret[0] == XCONF.UxbusState.ERR_CODE:
379
+ code = XCONF.UxbusState.ERR_CODE
380
+ break
381
+ if ret[0] == 0:
382
+ if on and ret[1] == 1:
383
+ code = 0
384
+ break
385
+ if not on and ret[1] == 0:
386
+ code = 0
387
+ break
388
+ if not self.connected or self.state == 4:
389
+ code = APIState.EMERGENCY_STOP
390
+ break
391
+ time.sleep(0.1)
392
+ self.log_api_info('API -> set_suction_cup(on={}, wait={}, delay_sec={}) -> code={}'.format(on, wait, delay_sec, code), code=code)
393
+ return code
394
+
395
+ @xarm_is_connected(_type='get')
396
+ def get_suction_cup(self, hardware_version=1):
397
+ return self.get_tgpio_digital(ionum=0 if hardware_version == 1 else 3)
398
+
399
+ @xarm_wait_until_not_pause
400
+ @xarm_wait_until_cmdnum_lt_max
401
+ @xarm_is_ready(_type='set')
402
+ @xarm_is_not_simulation_mode(ret=0)
403
+ def set_tgpio_digital_with_xyz(self, ionum, value, xyz, fault_tolerance_radius):
404
+ assert isinstance(ionum, int) and (1 >= ionum >= 0 or 4 >= ionum >= 3)
405
+ assert fault_tolerance_radius >= 0, 'The value of parameter fault_tolerance_radius must be greater than or equal to 0.'
406
+ ret = self.arm_cmd.tgpio_position_set_digital(ionum - 1 if ionum >= 3 else ionum, value, xyz, fault_tolerance_radius)
407
+ self.log_api_info('API -> set_tgpio_digital_with_xyz(ionum={}, value={}, xyz={}, fault_tolerance_radius={}) -> code={}'.format(ionum, value, xyz, fault_tolerance_radius, ret[0]), code=ret[0])
408
+ return ret[0]
409
+
410
+ @xarm_wait_until_not_pause
411
+ @xarm_wait_until_cmdnum_lt_max
412
+ @xarm_is_ready(_type='set')
413
+ @xarm_is_not_simulation_mode(ret=0)
414
+ def set_cgpio_digital_with_xyz(self, ionum, value, xyz, fault_tolerance_radius):
415
+ assert isinstance(ionum, int) and 15 >= ionum >= 0
416
+ assert fault_tolerance_radius >= 0, 'The value of parameter fault_tolerance_radius must be greater than or equal to 0.'
417
+ ret = self.arm_cmd.cgpio_position_set_digital(ionum, value, xyz, fault_tolerance_radius)
418
+ self.log_api_info('API -> set_cgpio_digital_with_xyz(ionum={}, value={}, xyz={}, fault_tolerance_radius={}) -> code={}'.format(ionum, value, xyz, fault_tolerance_radius, ret[0]), code=ret[0])
419
+ return ret[0]
420
+
421
+ @xarm_wait_until_not_pause
422
+ @xarm_wait_until_cmdnum_lt_max
423
+ @xarm_is_ready(_type='set')
424
+ @xarm_is_not_simulation_mode(ret=0)
425
+ def set_cgpio_analog_with_xyz(self, ionum, value, xyz, fault_tolerance_radius):
426
+ assert ionum == 0 or ionum == 1, 'The value of parameter ionum can only be 0 or 1.'
427
+ assert fault_tolerance_radius >= 0, 'The value of parameter fault_tolerance_radius must be greater than or equal to 0.'
428
+ ret = self.arm_cmd.cgpio_position_set_analog(ionum, value, xyz, fault_tolerance_radius)
429
+ self.log_api_info('API -> set_cgpio_analog_with_xyz(ionum={}, value={}, xyz={}, fault_tolerance_radius={}) -> code={}'.format(ionum, value, xyz, fault_tolerance_radius, ret[0]), code=ret[0])
430
+ return ret[0]
431
+
432
+ @xarm_is_connected(_type='set')
433
+ def config_io_reset_when_stop(self, io_type, on_off):
434
+ ret = self.arm_cmd.config_io_stop_reset(io_type, int(on_off))
435
+ return ret[0]
436
+
437
+ @xarm_is_connected(_type='set')
438
+ @xarm_is_not_simulation_mode(ret=False)
439
+ def check_air_pump_state(self, state, timeout=3, hardware_version=1):
440
+ start_time = time.monotonic()
441
+ is_first = True
442
+ while is_first or time.monotonic() - start_time < timeout:
443
+ is_first = False
444
+ if not self.connected or self.state == 4:
445
+ return False
446
+ ret = self.get_suction_cup(hardware_version=hardware_version)
447
+ if ret[0] == XCONF.UxbusState.ERR_CODE:
448
+ return False
449
+ if ret[0] == 0:
450
+ if state and ret[1] == 1:
451
+ return True
452
+ if not state and ret[1] == 0:
453
+ return True
454
+ time.sleep(0.1)
455
+ return False
456
+
457
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env python3
2
+ # Software License Agreement (BSD License)
3
+ #
4
+ # Copyright (c) 2022, UFACTORY, Inc.
5
+ # All rights reserved.
6
+ #
7
+ # Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
8
+
9
+ import asyncio
10
+ from ..core.utils.log import logger
11
+
12
+ class AsyncObject(object):
13
+ async def _asyncio_loop_func(self):
14
+ logger.debug('asyncio thread start ...')
15
+ while self.connected:
16
+ await asyncio.sleep(0.001)
17
+ logger.debug('asyncio thread exit ...')
18
+
19
+ @staticmethod
20
+ async def _async_run_callback(callback, msg):
21
+ await callback(msg)
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env python3
2
+ # Software License Agreement (BSD License)
3
+ #
4
+ # Copyright (c) 2022, UFACTORY, Inc.
5
+ # All rights reserved.
6
+ #
7
+ # Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
8
+
9
+ import asyncio
10
+ from ..core.utils.log import logger
11
+
12
+
13
+ class CoroutineObject(object):
14
+ @asyncio.coroutine
15
+ def _asyncio_loop_func(self):
16
+ logger.debug('asyncio thread start ...')
17
+ while self.connected:
18
+ yield from asyncio.sleep(0.001)
19
+ logger.debug('asyncio thread exit ...')
20
+
21
+ @staticmethod
22
+ @asyncio.coroutine
23
+ def _async_run_callback(callback, msg):
24
+ yield from callback(msg)