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/robotiq.py ADDED
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env python3
2
+ # Software License Agreement (BSD License)
3
+ #
4
+ # Copyright (c) 2020, 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 .code import APIState
12
+ from .base import Base
13
+ from .decorator import xarm_is_connected, xarm_is_not_simulation_mode
14
+
15
+
16
+ class RobotIQ(Base):
17
+ def __init__(self):
18
+ super(RobotIQ, self).__init__()
19
+ self.__robotiq_openmm = None
20
+ self.__robotiq_closemm = None
21
+ self.__robotiq_aCoef = None
22
+ self.__robotiq_bCoef = None
23
+ self._robotiq_status = {
24
+ 'gOBJ': 0, # 1和2表示停止并抓取到物体,3表示停止但没有抓取到物体,0表示正在动也没有抓取到物体
25
+ 'gSTA': 0, # 3表示激活完成
26
+ 'gGTO': 0,
27
+ 'gACT': 0,
28
+ 'kFLT': 0,
29
+ 'gFLT': 0, # 错误码
30
+ 'gPR': 0, # 抓取器的目标位置
31
+ 'gPO': 0, # 通过编码器获取抓取器的实际位置, 值介于0x00和0xFF之间, 0xFF为全闭合, 0x00为全张开
32
+ 'gCU': 0, # 从电机驱动器上瞬时读电流, 值介于0x00和0xFF之间, 等效电流大约为=10 * value mA
33
+ }
34
+
35
+ @property
36
+ def robotiq_error_code(self):
37
+ return self.robotiq_status['gFLT']
38
+
39
+ @property
40
+ def robotiq_status(self):
41
+ return self._robotiq_status
42
+
43
+ def __robotiq_send_modbus(self, data_frame, min_res_len=0):
44
+ code = self.checkset_modbus_baud(self._default_robotiq_baud)
45
+ if code != 0:
46
+ return code, []
47
+ return self.getset_tgpio_modbus_data(data_frame, min_res_len=min_res_len, ignore_log=True)
48
+
49
+ @xarm_is_connected(_type='get')
50
+ def __robotiq_set(self, params):
51
+ data_frame = [0x09, 0x10, 0x03, 0xE8, 0x00, 0x03, len(params)]
52
+ data_frame.extend(params)
53
+ return self.__robotiq_send_modbus(data_frame, 6)
54
+
55
+ @xarm_is_connected(_type='get')
56
+ def __robotiq_get(self, params):
57
+ data_frame = [0x09, 0x03]
58
+ data_frame.extend(params)
59
+ code, ret = self.__robotiq_send_modbus(data_frame, 3 + 2 * params[-1])
60
+ if code == 0 and len(ret) >= 5:
61
+ gripper_status_reg = ret[3]
62
+ self._robotiq_status['gOBJ'] = (gripper_status_reg & 0xC0) >> 6
63
+ self._robotiq_status['gSTA'] = (gripper_status_reg & 0x30) >> 4
64
+ self._robotiq_status['gGTO'] = (gripper_status_reg & 0x08) >> 3
65
+ self._robotiq_status['gACT'] = gripper_status_reg & 0x01
66
+ if len(ret) >= 7:
67
+ fault_status_reg = ret[5]
68
+ self._robotiq_status['kFLT'] = (fault_status_reg & 0xF0) >> 4
69
+ self._robotiq_status['gFLT'] = fault_status_reg & 0x0F
70
+ self._robotiq_status['gPR'] = ret[6]
71
+ if len(ret) >= 9:
72
+ self._robotiq_status['gPO'] = ret[7]
73
+ self._robotiq_status['gCU'] = ret[8]
74
+ if self._robotiq_status['gSTA'] == 3 and (self._robotiq_status['gFLT'] == 0 or self._robotiq_status['gFLT'] == 9):
75
+ self.robotiq_is_activated = True
76
+ else:
77
+ self.robotiq_is_activated = False
78
+ return code, ret
79
+
80
+ @xarm_is_connected(_type='get')
81
+ @xarm_is_not_simulation_mode(ret=(0, 0))
82
+ def robotiq_reset(self):
83
+ params = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
84
+ code, ret = self.__robotiq_set(params)
85
+ self.log_api_info('API -> robotiq_reset -> code={}, response={}'.format(code, ret), code=code)
86
+ return code, ret
87
+
88
+ @xarm_is_connected(_type='get')
89
+ @xarm_is_not_simulation_mode(ret=(0, 0))
90
+ def robotiq_set_activate(self, wait=True, timeout=3):
91
+ params = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
92
+ code, ret = self.__robotiq_set(params)
93
+ if wait and code == 0:
94
+ code = self.robotiq_wait_activation_completed(timeout)
95
+ self.log_api_info('API -> robotiq_set_activate ->code={}, response={}'.format(code, ret), code=code)
96
+ if code == 0:
97
+ self.robotiq_is_activated = True
98
+ return code, ret
99
+
100
+ @xarm_is_connected(_type='get')
101
+ def robotiq_set_position(self, pos, speed=0xFF, force=0xFF, wait=True, timeout=5, **kwargs):
102
+ if kwargs.get('wait_motion', True):
103
+ has_error = self.error_code != 0
104
+ is_stop = self.is_stop
105
+ code = self.wait_move()
106
+ if not (code == 0 or (is_stop and code == APIState.EMERGENCY_STOP)
107
+ or (has_error and code == APIState.HAS_ERROR)):
108
+ return code, 0
109
+ if self.check_is_simulation_robot():
110
+ return 0, 0
111
+ if kwargs.get('auto_enable') and not self.robotiq_is_activated:
112
+ self.robotiq_reset()
113
+ self.robotiq_set_activate(wait=True)
114
+ params = [0x09, 0x00, 0x00, pos, speed, force]
115
+ code, ret = self.__robotiq_set(params)
116
+ if wait and code == 0:
117
+ code = self.robotiq_wait_motion_completed(timeout, **kwargs)
118
+ self.log_api_info('API -> robotiq_set_position ->code={}, response={}'.format(code, ret), code=code)
119
+ return code, ret
120
+
121
+ def robotiq_open(self, speed=0xFF, force=0xFF, wait=True, timeout=5, **kwargs):
122
+ return self.robotiq_set_position(0x00, speed=speed, force=force, wait=wait, timeout=timeout, **kwargs)
123
+
124
+ def robotiq_close(self, speed=0xFF, force=0xFF, wait=True, timeout=5, **kwargs):
125
+ return self.robotiq_set_position(0xFF, speed=speed, force=force, wait=wait, timeout=timeout, **kwargs)
126
+
127
+ @xarm_is_connected(_type='get')
128
+ @xarm_is_not_simulation_mode(ret=(0, 0))
129
+ def robotiq_get_status(self, number_of_registers=3):
130
+ number_of_registers = 3 if number_of_registers not in [1, 2, 3] else number_of_registers
131
+ params = [0x07, 0xD0, 0x00, number_of_registers]
132
+ # params = [0x07, 0xD0, 0x00, 0x01]
133
+ # params = [0x07, 0xD0, 0x00, 0x03]
134
+ return self.__robotiq_get(params)
135
+
136
+ def robotiq_wait_activation_completed(self, timeout=3):
137
+ failed_cnt = 0
138
+ expired = time.monotonic() + timeout if timeout is not None and timeout > 0 else 0
139
+ code = APIState.WAIT_FINISH_TIMEOUT
140
+ while expired == 0 or time.monotonic() < expired:
141
+ _, ret = self.robotiq_get_status(number_of_registers=3)
142
+ failed_cnt = 0 if _ == 0 else failed_cnt + 1
143
+ if _ == 0:
144
+ gFLT = self._robotiq_status['gFLT']
145
+ gSTA = self._robotiq_status['gSTA']
146
+ code = APIState.END_EFFECTOR_HAS_FAULT if gFLT != 0 and not (gFLT == 5 and gSTA == 1) \
147
+ else 0 if gSTA == 3 else code
148
+ else:
149
+ code = APIState.NOT_CONNECTED if _ == APIState.NOT_CONNECTED else APIState.CHECK_FAILED if failed_cnt > 10 else code
150
+ if code != APIState.WAIT_FINISH_TIMEOUT:
151
+ break
152
+ time.sleep(0.05)
153
+ return code
154
+
155
+ def robotiq_wait_motion_completed(self, timeout=5, **kwargs):
156
+ failed_cnt = 0
157
+ expired = time.monotonic() + timeout if timeout is not None and timeout > 0 else 0
158
+ code = APIState.WAIT_FINISH_TIMEOUT
159
+ check_detected = kwargs.get('check_detected', False)
160
+ while expired == 0 or time.monotonic() < expired:
161
+ _, ret = self.robotiq_get_status(number_of_registers=3)
162
+ failed_cnt = 0 if _ == 0 else failed_cnt + 1
163
+ if _ == 0:
164
+ gFLT = self._robotiq_status['gFLT']
165
+ gSTA = self._robotiq_status['gSTA']
166
+ gOBJ = self._robotiq_status['gOBJ']
167
+ code = APIState.END_EFFECTOR_HAS_FAULT if gFLT != 0 and not (gFLT == 5 and gSTA == 1) \
168
+ else 0 if (check_detected and (gOBJ == 1 or gOBJ == 2)) or (gOBJ == 1 or gOBJ == 2 or gOBJ == 3) \
169
+ else code
170
+ else:
171
+ code = APIState.NOT_CONNECTED if _ == APIState.NOT_CONNECTED else APIState.CHECK_FAILED if failed_cnt > 10 else code
172
+ if code != APIState.WAIT_FINISH_TIMEOUT:
173
+ break
174
+ time.sleep(0.05)
175
+ if self.robotiq_error_code != 0:
176
+ print('ROBOTIQ Gripper ErrorCode: {}'.format(self.robotiq_error_code))
177
+ if code == 0 and not self.robotiq_is_activated:
178
+ code = APIState.END_EFFECTOR_NOT_ENABLED
179
+ return code
180
+
181
+ @xarm_is_connected(_type='set')
182
+ @xarm_is_not_simulation_mode(ret=False)
183
+ def check_robotiq_is_catch(self, timeout=5):
184
+ return self.robotiq_wait_motion_completed(timeout=timeout, check_detected=True) == 0
185
+
186
+ def robotiq_calibrate_mm(self, closemm, openmm):
187
+ ret = self.robotiq_open(wait=True)
188
+ if ret[0] == 0:
189
+ open_bit = self._robotiq_status['gPO']
190
+ ret = self.robotiq_close(wait=True)
191
+ if ret[0] == 0:
192
+ close_bit = self._robotiq_status['gPO']
193
+ self.__robotiq_aCoef = (closemm - openmm) / (close_bit - open_bit)
194
+ self.__robotiq_bCoef = (openmm * close_bit - closemm * open_bit) / (close_bit - open_bit)
195
+ self.__robotiq_closemm = closemm
196
+ self.__robotiq_openmm = openmm
197
+ return 0
198
+ return ret[0]
199
+
200
+ def robotiq_set_position_mm(self, pos_mm, speed=0xFF, force=0xFF, wait=False, timeout=5, check_detected=False):
201
+ if self.__robotiq_openmm is None or self.__robotiq_closemm is None:
202
+ print('You have to calibrate the gripper before using the function robotiq_set_position_mm()')
203
+ elif pos_mm > self.__robotiq_openmm:
204
+ print("The maximum opening is {}".format(self.__robotiq_openmm))
205
+ else:
206
+ pos = int(self.__robotiq_mm_to_bit(pos_mm))
207
+ return self.robotiq_set_position(pos, speed=speed, force=force, wait=wait, timeout=timeout, check_detected=check_detected)
208
+
209
+ def __robotiq_mm_to_bit(self, mm):
210
+ if self.__robotiq_aCoef is None or self.__robotiq_bCoef is None:
211
+ print('You have to calibrate the gripper before using the function robotiq_mm_to_bit()')
212
+ else:
213
+ return (mm - self.__robotiq_bCoef) / self.__robotiq_aCoef
214
+
215
+ def __robotiq_bit_to_mm(self, bit):
216
+ if self.__robotiq_aCoef is None or self.__robotiq_bCoef is None:
217
+ print('You have to calibrate the gripper before using the function robotiq_bit_to_mm()')
218
+ else:
219
+ return self.__robotiq_aCoef * bit + self.__robotiq_bCoef
220
+