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.
- xarm/__init__.py +2 -0
- xarm/build_backend.py +17 -0
- xarm/core/__init__.py +2 -0
- xarm/core/comm/__init__.py +5 -0
- xarm/core/comm/base.py +303 -0
- xarm/core/comm/serial_port.py +44 -0
- xarm/core/comm/socket_port.py +150 -0
- xarm/core/comm/uxbus_cmd_protocol.py +100 -0
- xarm/core/config/__init__.py +0 -0
- xarm/core/config/x_code.py +1427 -0
- xarm/core/config/x_config.py +553 -0
- xarm/core/utils/__init__.py +3 -0
- xarm/core/utils/convert.py +124 -0
- xarm/core/utils/crc16.py +76 -0
- xarm/core/utils/debug_print.py +21 -0
- xarm/core/utils/log.py +98 -0
- xarm/core/version.py +1 -0
- xarm/core/wrapper/__init__.py +11 -0
- xarm/core/wrapper/uxbus_cmd.py +1457 -0
- xarm/core/wrapper/uxbus_cmd_ser.py +94 -0
- xarm/core/wrapper/uxbus_cmd_tcp.py +305 -0
- xarm/tools/__init__.py +0 -0
- xarm/tools/blockly/__init__.py +1 -0
- xarm/tools/blockly/_blockly_base.py +416 -0
- xarm/tools/blockly/_blockly_handler.py +1338 -0
- xarm/tools/blockly/_blockly_highlight.py +94 -0
- xarm/tools/blockly/_blockly_node.py +61 -0
- xarm/tools/blockly/_blockly_tool.py +480 -0
- xarm/tools/blockly_tool.py +1864 -0
- xarm/tools/gcode.py +90 -0
- xarm/tools/list_ports.py +39 -0
- xarm/tools/modbus_tcp.py +205 -0
- xarm/tools/threads.py +30 -0
- xarm/tools/utils.py +36 -0
- xarm/version.py +1 -0
- xarm/wrapper/__init__.py +1 -0
- xarm/wrapper/studio_api.py +34 -0
- xarm/wrapper/xarm_api.py +4416 -0
- xarm/x3/__init__.py +2 -0
- xarm/x3/base.py +2638 -0
- xarm/x3/base_board.py +198 -0
- xarm/x3/code.py +62 -0
- xarm/x3/decorator.py +104 -0
- xarm/x3/events.py +166 -0
- xarm/x3/ft_sensor.py +264 -0
- xarm/x3/gpio.py +457 -0
- xarm/x3/grammar_async.py +21 -0
- xarm/x3/grammar_coroutine.py +24 -0
- xarm/x3/gripper.py +830 -0
- xarm/x3/modbus_tcp.py +84 -0
- xarm/x3/parse.py +110 -0
- xarm/x3/record.py +216 -0
- xarm/x3/report.py +204 -0
- xarm/x3/robotiq.py +220 -0
- xarm/x3/servo.py +485 -0
- xarm/x3/studio.py +138 -0
- xarm/x3/track.py +424 -0
- xarm/x3/utils.py +43 -0
- xarm/x3/xarm.py +1928 -0
- xarm_python_sdk-1.15.2.dist-info/METADATA +103 -0
- xarm_python_sdk-1.15.2.dist-info/RECORD +63 -0
- xarm_python_sdk-1.15.2.dist-info/WHEEL +4 -0
- xarm_python_sdk-1.15.2.dist-info/licenses/LICENSE +27 -0
xarm/x3/base_board.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# __author: rock
|
|
3
|
+
# @time: 2021-04-02
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
import time
|
|
7
|
+
from ..core.utils.log import logger
|
|
8
|
+
from .base import Base
|
|
9
|
+
from .decorator import xarm_is_connected
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseBoard(Base):
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
super(BaseBoard, self).__init__()
|
|
16
|
+
|
|
17
|
+
@xarm_is_connected(_type='get')
|
|
18
|
+
def get_base_board_version(self, board_id=10):
|
|
19
|
+
versions = ['*', '*', '*']
|
|
20
|
+
|
|
21
|
+
ret1 = self.arm_cmd.tgpio_addr_r16(0x0801, bid=board_id)
|
|
22
|
+
ret2 = self.arm_cmd.tgpio_addr_r16(0x0802, bid=board_id)
|
|
23
|
+
ret3 = self.arm_cmd.tgpio_addr_r16(0x0803, bid=board_id)
|
|
24
|
+
|
|
25
|
+
code = 0
|
|
26
|
+
if ret1[0] == 0 and len(ret1) == 2:
|
|
27
|
+
versions[0] = ret1[1]
|
|
28
|
+
else:
|
|
29
|
+
code = ret1[0]
|
|
30
|
+
if ret2[0] == 0 and len(ret2) == 2:
|
|
31
|
+
versions[1] = ret2[1]
|
|
32
|
+
else:
|
|
33
|
+
code = ret2[0]
|
|
34
|
+
if ret3[0] == 0 and len(ret3) == 2:
|
|
35
|
+
versions[2] = ret3[1]
|
|
36
|
+
else:
|
|
37
|
+
code = ret3[0]
|
|
38
|
+
|
|
39
|
+
return code, '.'.join(map(str, versions))
|
|
40
|
+
|
|
41
|
+
@xarm_is_connected(_type='get')
|
|
42
|
+
def get_current_angle(self, board_id=10):
|
|
43
|
+
code, acc_xyz = self.get_imu_data(board_id)
|
|
44
|
+
self.arm_cmd.tgpio_addr_w16(addr=0x0606, value=1, bid=board_id)
|
|
45
|
+
if code == 0 and acc_xyz[0] != 0 and acc_xyz[1] != 0 and acc_xyz[2] != 0:
|
|
46
|
+
angle = self.__get_z_axios_offset_angle(acc_xyz[0], acc_xyz[1], acc_xyz[2])
|
|
47
|
+
return code, angle
|
|
48
|
+
else:
|
|
49
|
+
return code, 0
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def __get_z_axios_offset_angle(x=1, y=1, z=1):
|
|
53
|
+
angle = math.degrees(math.atan(z / (math.sqrt(abs((x ** 2) + (y ** 2))))))
|
|
54
|
+
angle = 90 - angle
|
|
55
|
+
return angle
|
|
56
|
+
|
|
57
|
+
@xarm_is_connected(_type='set')
|
|
58
|
+
def write_sn(self, sn='', servo_id=10):
|
|
59
|
+
code = 0
|
|
60
|
+
if len(sn) == 14:
|
|
61
|
+
for i in range(0, 14, 2):
|
|
62
|
+
ret = self.arm_cmd.tgpio_addr_w16(addr=0x1900 + (int(i / 2)), value=ord(sn[i]) | ord(sn[i + 1]) << 8, bid=servo_id)
|
|
63
|
+
code = self._check_code(ret[0])
|
|
64
|
+
time.sleep(0.1)
|
|
65
|
+
if code != 0:
|
|
66
|
+
self.log_api_info('API -> write_sn -> code={}, sn={}'.format(code, sn), code=code)
|
|
67
|
+
return code
|
|
68
|
+
self.log_api_info('API -> write_sn -> code={}, sn={}'.format(code, sn), code=code)
|
|
69
|
+
return code
|
|
70
|
+
|
|
71
|
+
@xarm_is_connected(_type='get')
|
|
72
|
+
def get_sn(self, servo_id=10):
|
|
73
|
+
rd_sn = ''
|
|
74
|
+
ret = [0, '']
|
|
75
|
+
for i in range(0, 14, 2):
|
|
76
|
+
ret = self.arm_cmd.tgpio_addr_r16(addr=0x0900 + (int(i / 2)), bid=servo_id)
|
|
77
|
+
time.sleep(0.1)
|
|
78
|
+
rd_sn = ''.join([rd_sn, chr(ret[1] & 0x00FF)])
|
|
79
|
+
rd_sn = ''.join([rd_sn, chr((ret[1] >> 8) & 0x00FF)])
|
|
80
|
+
ret[0] = self._check_code(ret[0])
|
|
81
|
+
if ret[0] != 0:
|
|
82
|
+
self.log_api_info('API -> get_sn -> code={}, sn={}'.format(ret[0], rd_sn), code=ret[0])
|
|
83
|
+
return ret[0], ''
|
|
84
|
+
self.log_api_info('API -> get_sn -> code={}, sn={}'.format(ret[0], rd_sn), code=ret[0])
|
|
85
|
+
return ret[0], rd_sn
|
|
86
|
+
|
|
87
|
+
@xarm_is_connected(_type='set')
|
|
88
|
+
def write_iden_to_base(self, idens, servo_id=10):
|
|
89
|
+
cmds = [0x0D00, 0x0D0C, 0x0D18, 0x0D24, 0x0D30, 0x0D3C, 0x0D48]
|
|
90
|
+
code = 0
|
|
91
|
+
if idens:
|
|
92
|
+
for i, data in enumerate(idens):
|
|
93
|
+
# print(i, data)
|
|
94
|
+
for j, d in enumerate(data):
|
|
95
|
+
ret = self.arm_cmd.tgpio_addr_w32(addr=(cmds[i] + (2 * j)) | 0x1000, value=d, bid=servo_id)
|
|
96
|
+
# print("%x, %f, ret:%d" % (cmds[i] + (2 * j), d, ret[0]))
|
|
97
|
+
|
|
98
|
+
time.sleep(0.1)
|
|
99
|
+
code = ret[0]
|
|
100
|
+
if code != 0:
|
|
101
|
+
return code
|
|
102
|
+
return code
|
|
103
|
+
else:
|
|
104
|
+
return 1
|
|
105
|
+
|
|
106
|
+
@xarm_is_connected(_type='get')
|
|
107
|
+
def get_imu_data(self, board_id=10):
|
|
108
|
+
code = 0
|
|
109
|
+
if board_id == 9:
|
|
110
|
+
self.arm_cmd.tgpio_addr_w16(addr=0x0606, value=1, bid=board_id)
|
|
111
|
+
|
|
112
|
+
ret1 = self.arm_cmd.tgpio_addr_r32(addr=0x0C00, bid=board_id, fmt='>f')
|
|
113
|
+
ret2 = self.arm_cmd.tgpio_addr_r32(addr=0x0C02, bid=board_id, fmt='>f')
|
|
114
|
+
ret3 = self.arm_cmd.tgpio_addr_r32(addr=0x0C04, bid=board_id, fmt='>f')
|
|
115
|
+
code = 0 if ret1[0] == 0 else ret1[0]
|
|
116
|
+
code = code if ret2[0] == 0 else ret2[0]
|
|
117
|
+
code = code if ret3[0] == 0 else ret3[0]
|
|
118
|
+
|
|
119
|
+
if board_id == 9:
|
|
120
|
+
self.arm_cmd.tgpio_addr_w16(addr=0x0606, value=0, bid=board_id)
|
|
121
|
+
if code != 0:
|
|
122
|
+
return code, [1, 1, 1]
|
|
123
|
+
else:
|
|
124
|
+
return code, [ret1[1], ret2[1], ret3[1]]
|
|
125
|
+
|
|
126
|
+
@xarm_is_connected(_type='get')
|
|
127
|
+
def read_iden_from_base(self, servo_id=10):
|
|
128
|
+
cmds = [0x0D00, 0x0D0C, 0x0D18, 0x0D24, 0x0D30, 0x0D3C, 0x0D48]
|
|
129
|
+
code = 0
|
|
130
|
+
conf = []
|
|
131
|
+
for i in range(7):
|
|
132
|
+
vl = []
|
|
133
|
+
for j in range(6):
|
|
134
|
+
ret = self.arm_cmd.tgpio_addr_r32((cmds[i] + (2 * j)), servo_id, fmt='>f')
|
|
135
|
+
time.sleep(0.01)
|
|
136
|
+
# print("%x, %f, ret:%d" % (cmds[i] + (2 * j), ret[1], ret[0]))
|
|
137
|
+
vl.append(ret[1])
|
|
138
|
+
code = ret[0]
|
|
139
|
+
if code != 0:
|
|
140
|
+
return code, None
|
|
141
|
+
conf.append(vl)
|
|
142
|
+
return code, conf
|
|
143
|
+
|
|
144
|
+
@xarm_is_connected(_type='set')
|
|
145
|
+
def write_poe_to_end(self, datas, servo_id=9):
|
|
146
|
+
cmds1 = [0x0E00, 0x0E0C, 0x0E18, 0x0E24, 0x0E30, 0x0E3C, 0x0E48]
|
|
147
|
+
cmds2 = 0x0F00
|
|
148
|
+
code = 0
|
|
149
|
+
if datas:
|
|
150
|
+
joints, homes = datas
|
|
151
|
+
for i, data in enumerate(joints):
|
|
152
|
+
for j, d in enumerate(data):
|
|
153
|
+
ret = self.arm_cmd.tgpio_addr_w32(addr=(cmds1[i] + (2 * j)) | 0x1000, value=d, bid=servo_id)
|
|
154
|
+
time.sleep(0.1)
|
|
155
|
+
code = ret[0]
|
|
156
|
+
if code != 0:
|
|
157
|
+
return code
|
|
158
|
+
for i, data in enumerate(homes):
|
|
159
|
+
for j, d in enumerate(data):
|
|
160
|
+
ret = self.arm_cmd.tgpio_addr_w32(addr=(cmds2 + (2 * (i * len(data) + j))) | 0x1000, value=d, bid=servo_id)
|
|
161
|
+
time.sleep(0.1)
|
|
162
|
+
code = ret[0]
|
|
163
|
+
if code != 0:
|
|
164
|
+
return code
|
|
165
|
+
return code
|
|
166
|
+
else:
|
|
167
|
+
return 1
|
|
168
|
+
|
|
169
|
+
@xarm_is_connected(_type='get')
|
|
170
|
+
def read_poe_from_end(self, servo_id=9):
|
|
171
|
+
cmds = [0x0E00, 0x0E0C, 0x0E18, 0x0E24, 0x0E30, 0x0E3C, 0x0E48]
|
|
172
|
+
cmds2 = 0x0F00
|
|
173
|
+
code = 0
|
|
174
|
+
conf = []
|
|
175
|
+
joints_conf = []
|
|
176
|
+
homes_conf = []
|
|
177
|
+
for i in range(7):
|
|
178
|
+
vl = []
|
|
179
|
+
for j in range(6):
|
|
180
|
+
ret = self.arm_cmd.tgpio_addr_r32(cmds[i] + (2 * j), servo_id, fmt='>f')
|
|
181
|
+
time.sleep(0.01)
|
|
182
|
+
vl.append(ret[1])
|
|
183
|
+
code = ret[0]
|
|
184
|
+
if code != 0:
|
|
185
|
+
return code, None
|
|
186
|
+
joints_conf.append(vl)
|
|
187
|
+
for i in range(4):
|
|
188
|
+
vl = []
|
|
189
|
+
for j in range(4):
|
|
190
|
+
ret = self.arm_cmd.tgpio_addr_r32(cmds2 + 2 * (i * 4 + j), servo_id, fmt='>f')
|
|
191
|
+
time.sleep(0.01)
|
|
192
|
+
vl.append(ret[1])
|
|
193
|
+
code = ret[0]
|
|
194
|
+
if code != 0:
|
|
195
|
+
return code, None
|
|
196
|
+
homes_conf.append(vl)
|
|
197
|
+
conf = [joints_conf, homes_conf]
|
|
198
|
+
return code, conf
|
xarm/x3/code.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
|
|
10
|
+
from ..core.config.x_config import XCONF
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class APIState(object):
|
|
14
|
+
NOT_CONNECTED = -1 # 已断开或未连接
|
|
15
|
+
NOT_READY = -2 # 未使能或者设置状态
|
|
16
|
+
API_EXCEPTION = -3 # 接口异常,可能是参数错误
|
|
17
|
+
CMD_NOT_EXIST = -4 # 命令不存在
|
|
18
|
+
TCP_LIMIT = -6 # 笛卡尔限位
|
|
19
|
+
JOINT_LIMIT = -7 # 关节角度限位
|
|
20
|
+
OUT_OF_RANGE = -8 # 超出范围
|
|
21
|
+
EMERGENCY_STOP = -9 # 紧急停止
|
|
22
|
+
SERVO_NOT_EXIST = -10 # 不存在此ID的关节
|
|
23
|
+
CONVERT_FAILED = -11 # 转换Blockly失败
|
|
24
|
+
RUN_BLOCKLY_EXCEPTION = -12 # 运行blockly app异常
|
|
25
|
+
NORMAL = 0 # 正常
|
|
26
|
+
HAS_ERROR = XCONF.UxbusState.ERR_CODE # 有尚未清除的错误
|
|
27
|
+
HAS_WARN = XCONF.UxbusState.WAR_CODE # 有尚未清除的警告
|
|
28
|
+
RES_TIMEOUT = XCONF.UxbusState.ERR_TOUT # 命令回复超时
|
|
29
|
+
RES_LENGTH_ERROR = XCONF.UxbusState.ERR_LENG # TCP长度错误
|
|
30
|
+
CMD_NUM_ERROR = XCONF.UxbusState.ERR_NUM # TCP序号错误
|
|
31
|
+
CMD_PROT_ERROR = XCONF.UxbusState.ERR_PROT # TCP协议标志错误
|
|
32
|
+
FUN_ERROR = XCONF.UxbusState.ERR_FUN # TCP回复指令和发送指令不匹配
|
|
33
|
+
NO_TCP = XCONF.UxbusState.ERR_NOTTCP # 写数据异常
|
|
34
|
+
STATE_NOT_READY = XCONF.UxbusState.STATE_NOT_READY # 参数错误
|
|
35
|
+
RET_IS_INVALID = XCONF.UxbusState.INVALID # 结果无效
|
|
36
|
+
OTHER = XCONF.UxbusState.ERR_OTHER # 其它错误
|
|
37
|
+
PARAM_ERROR = XCONF.UxbusState.ERR_PARAM # 参数错误
|
|
38
|
+
|
|
39
|
+
HOST_ID_ERR = 20 # 主机ID错误, 看使用的接口,可能是末端IO也可能是滑轨
|
|
40
|
+
MODBUS_BAUD_NOT_SUPPORT = 21 # modbus不支持此波特率
|
|
41
|
+
MODBUS_BAUD_NOT_CORRECT = 22 # 末端modbus波特率不正确
|
|
42
|
+
MODBUS_ERR_LENG = 23 # modbus回复数据长度错误
|
|
43
|
+
|
|
44
|
+
TRAJ_RW_FAILED = 31 # 读写轨迹失败(加载轨迹或保存轨迹)
|
|
45
|
+
TRAJ_RW_TOUT = 32 # 读写轨迹等待超时(加载轨迹或保存轨迹)
|
|
46
|
+
TRAJ_PLAYBACK_TOUT = 33 # 回放轨迹超时(多种情况)
|
|
47
|
+
TRAJ_PLAYBACK_FAILED = 34 # 回放轨迹失败(多种情况)
|
|
48
|
+
SUCTION_CUP_TOUT = 41 # 等待吸泵设置超时
|
|
49
|
+
|
|
50
|
+
MODE_IS_NOT_CORRECT = 51 # 模式不正确
|
|
51
|
+
|
|
52
|
+
LINEAR_TRACK_HAS_FAULT = 80 # 滑轨有错误
|
|
53
|
+
LINEAR_TRACK_SCI_IS_LOW = 81 # 滑轨的SCI被置低了
|
|
54
|
+
LINEAR_TRACK_NOT_INIT = 82 # 直线滑轨未初始化
|
|
55
|
+
|
|
56
|
+
WAIT_FINISH_TIMEOUT = 100 # 等待操作完成超时
|
|
57
|
+
CHECK_FAILED = 101 # 等待操作完成过程检测状态连续失败次数过多
|
|
58
|
+
END_EFFECTOR_HAS_FAULT = 102 # 末端配件有错误
|
|
59
|
+
END_EFFECTOR_NOT_ENABLED = 103 # 末端配件未使能
|
|
60
|
+
|
|
61
|
+
# 129 ~ 144: 标准modbus tcp的异常码,实际异常码(api_code - 0x80)
|
|
62
|
+
|
xarm/x3/decorator.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# !/usr/bin/env python3
|
|
2
|
+
# Software License Agreement (BSD License)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2021, UFACTORY, Inc.
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
import time
|
|
11
|
+
import math
|
|
12
|
+
import functools
|
|
13
|
+
from ..core.utils.log import logger
|
|
14
|
+
from .code import APIState
|
|
15
|
+
from ..core.config.x_config import XCONF
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def check_modbus_baud(baud=2000000, _type='set', default=None, host_id=XCONF.TGPIO_HOST_ID):
|
|
19
|
+
def _check_modbus_baud(func):
|
|
20
|
+
@functools.wraps(func)
|
|
21
|
+
def decorator(self, *args, **kwargs):
|
|
22
|
+
code = self.checkset_modbus_baud(baud, host_id=host_id)
|
|
23
|
+
if code != 0:
|
|
24
|
+
logger.error('check modbus baud is failed, code={}'.format(code))
|
|
25
|
+
return code if _type == 'set' else (code, default if default != -99 else [])
|
|
26
|
+
else:
|
|
27
|
+
return func(self, *args, **kwargs)
|
|
28
|
+
return decorator
|
|
29
|
+
return _check_modbus_baud
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def xarm_is_connected(_type='set'):
|
|
33
|
+
def _xarm_is_connected(func):
|
|
34
|
+
@functools.wraps(func)
|
|
35
|
+
def decorator(self, *args, **kwargs):
|
|
36
|
+
if self.connected:
|
|
37
|
+
return func(self, *args, **kwargs)
|
|
38
|
+
else:
|
|
39
|
+
logger.error('xArm is not connected')
|
|
40
|
+
return APIState.NOT_CONNECTED if _type == 'set' else (APIState.NOT_CONNECTED, 'xArm is not connect')
|
|
41
|
+
return decorator
|
|
42
|
+
return _xarm_is_connected
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def xarm_is_ready(_type='set'):
|
|
46
|
+
def _xarm_is_ready(func):
|
|
47
|
+
@functools.wraps(func)
|
|
48
|
+
def decorator(self, *args, **kwargs):
|
|
49
|
+
if self.connected and kwargs.get('auto_enable', False):
|
|
50
|
+
if not self.ready:
|
|
51
|
+
self.motion_enable(enable=True)
|
|
52
|
+
self.set_mode(0)
|
|
53
|
+
self.set_state(0)
|
|
54
|
+
if self.connected:
|
|
55
|
+
if self.check_xarm_is_ready:
|
|
56
|
+
return func(self, *args, **kwargs)
|
|
57
|
+
else:
|
|
58
|
+
logger.error('xArm is not ready')
|
|
59
|
+
logger.info('Please check the arm for errors. If so, please clear the error first. '
|
|
60
|
+
'Then enable the motor, set the mode and set the state')
|
|
61
|
+
return APIState.NOT_READY if _type == 'set' else (APIState.NOT_READY, 'xArm is not ready')
|
|
62
|
+
else:
|
|
63
|
+
logger.error('xArm is not connected')
|
|
64
|
+
return APIState.NOT_CONNECTED if _type == 'set' else (APIState.NOT_CONNECTED, 'xArm is not connect')
|
|
65
|
+
return decorator
|
|
66
|
+
return _xarm_is_ready
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def xarm_wait_until_not_pause(func):
|
|
70
|
+
@functools.wraps(func)
|
|
71
|
+
def decorator(self, *args, **kwargs):
|
|
72
|
+
self.wait_until_not_pause()
|
|
73
|
+
return func(self, *args, **kwargs)
|
|
74
|
+
return decorator
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def xarm_wait_until_cmdnum_lt_max(func):
|
|
78
|
+
@functools.wraps(func)
|
|
79
|
+
def decorator(self, *args, **kwargs):
|
|
80
|
+
self.wait_until_cmdnum_lt_max()
|
|
81
|
+
return func(self, *args, **kwargs)
|
|
82
|
+
return decorator
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def xarm_is_not_simulation_mode(ret=0):
|
|
86
|
+
def _xarm_is_not_simulation_mode(func):
|
|
87
|
+
@functools.wraps(func)
|
|
88
|
+
def decorator(self, *args, **kwargs):
|
|
89
|
+
if not self.check_is_simulation_robot():
|
|
90
|
+
return func(self, *args, **kwargs)
|
|
91
|
+
else:
|
|
92
|
+
return ret
|
|
93
|
+
return decorator
|
|
94
|
+
return _xarm_is_not_simulation_mode
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def api_log(func):
|
|
98
|
+
@functools.wraps(func)
|
|
99
|
+
def decorator(self, *args, **kwargs):
|
|
100
|
+
ret = func(self, *args, **kwargs)
|
|
101
|
+
logger.info('{}, ret={}, args={}, kwargs={}'.format(func.__name__, ret, args[1:], kwargs))
|
|
102
|
+
return ret
|
|
103
|
+
return decorator
|
|
104
|
+
|
xarm/x3/events.py
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
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
|
+
REPORT_ID = 'REPORT'
|
|
10
|
+
REPORT_LOCATION_ID = 'LOCATION'
|
|
11
|
+
REPORT_CONNECT_CHANGED_ID = 'REPORT_CONNECT_CHANGED'
|
|
12
|
+
REPORT_STATE_CHANGED_ID = 'REPORT_STATE_CHANGED'
|
|
13
|
+
REPORT_MODE_CHANGED_ID = 'REPORT_MODE_CHANGED'
|
|
14
|
+
REPORT_MTABLE_MTBRAKE_CHANGED_ID = 'REPORT_MTABLE_MTBRAKE_CHANGED'
|
|
15
|
+
REPORT_ERROR_WARN_CHANGED_ID = 'REPORT_ERROR_WARN_CHANGED'
|
|
16
|
+
REPORT_CMDNUM_CHANGED_ID = 'REPORT_CMDNUM_CHANGED'
|
|
17
|
+
REPORT_TEMPERATURE_CHANGED_ID = 'REPORT_TEMPERATURE_CHANGED'
|
|
18
|
+
REPORT_COUNT_CHANGED_ID = 'REPORT_COUNT_CHANGED'
|
|
19
|
+
REPORT_IDEN_PROGRESS_CHANGED_ID = 'REPORT_IDEN_PROGRESS_CHANGED_ID'
|
|
20
|
+
FEEDBACK_ID = 'FEEDBACK_ID'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Events(object):
|
|
24
|
+
REPORT_ID = REPORT_ID
|
|
25
|
+
REPORT_LOCATION_ID = REPORT_LOCATION_ID
|
|
26
|
+
REPORT_CONNECT_CHANGED_ID = REPORT_CONNECT_CHANGED_ID
|
|
27
|
+
REPORT_STATE_CHANGED_ID = REPORT_STATE_CHANGED_ID
|
|
28
|
+
REPORT_MODE_CHANGED_ID = REPORT_MODE_CHANGED_ID
|
|
29
|
+
REPORT_MTABLE_MTBRAKE_CHANGED_ID = REPORT_MTABLE_MTBRAKE_CHANGED_ID
|
|
30
|
+
REPORT_ERROR_WARN_CHANGED_ID = REPORT_ERROR_WARN_CHANGED_ID
|
|
31
|
+
REPORT_CMDNUM_CHANGED_ID = REPORT_CMDNUM_CHANGED_ID
|
|
32
|
+
REPORT_TEMPERATURE_CHANGED_ID = REPORT_TEMPERATURE_CHANGED_ID
|
|
33
|
+
REPORT_COUNT_CHANGED_ID = REPORT_COUNT_CHANGED_ID
|
|
34
|
+
REPORT_IDEN_PROGRESS_CHANGED_ID = REPORT_IDEN_PROGRESS_CHANGED_ID
|
|
35
|
+
FEEDBACK_ID = FEEDBACK_ID
|
|
36
|
+
|
|
37
|
+
def __init__(self):
|
|
38
|
+
self._report_callbacks = {
|
|
39
|
+
REPORT_ID: [],
|
|
40
|
+
REPORT_LOCATION_ID: [],
|
|
41
|
+
REPORT_CONNECT_CHANGED_ID: [],
|
|
42
|
+
REPORT_ERROR_WARN_CHANGED_ID: [],
|
|
43
|
+
REPORT_STATE_CHANGED_ID: [],
|
|
44
|
+
REPORT_MODE_CHANGED_ID: [],
|
|
45
|
+
REPORT_MTABLE_MTBRAKE_CHANGED_ID: [],
|
|
46
|
+
REPORT_CMDNUM_CHANGED_ID: [],
|
|
47
|
+
REPORT_COUNT_CHANGED_ID: [],
|
|
48
|
+
REPORT_IDEN_PROGRESS_CHANGED_ID: [],
|
|
49
|
+
FEEDBACK_ID: []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
def _register_report_callback(self, report_id, callback):
|
|
53
|
+
if report_id not in self._report_callbacks.keys():
|
|
54
|
+
self._report_callbacks[report_id] = []
|
|
55
|
+
if (callable(callback) or isinstance(callback, dict)) and callback not in self._report_callbacks[report_id]:
|
|
56
|
+
self._report_callbacks[report_id].append(callback)
|
|
57
|
+
return True
|
|
58
|
+
elif not (callable(callback) or isinstance(callback, dict)):
|
|
59
|
+
return False
|
|
60
|
+
else:
|
|
61
|
+
return True
|
|
62
|
+
|
|
63
|
+
def _release_report_callback(self, report_id, callback):
|
|
64
|
+
if report_id in self._report_callbacks.keys():
|
|
65
|
+
if callback is None:
|
|
66
|
+
self._report_callbacks[report_id].clear()
|
|
67
|
+
return True
|
|
68
|
+
elif callback:
|
|
69
|
+
for cb in self._report_callbacks[report_id]:
|
|
70
|
+
if callback == cb:
|
|
71
|
+
self._report_callbacks[report_id].remove(callback)
|
|
72
|
+
return True
|
|
73
|
+
elif isinstance(cb, dict):
|
|
74
|
+
if cb['callback'] == callback:
|
|
75
|
+
self._report_callbacks[report_id].remove(cb)
|
|
76
|
+
return True
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
def register_report_callback(self, callback=None, report_cartesian=True, report_joints=True,
|
|
80
|
+
report_state=True, report_error_code=True, report_warn_code=True,
|
|
81
|
+
report_mtable=True, report_mtbrake=True, report_cmd_num=True):
|
|
82
|
+
return self._register_report_callback(REPORT_ID, {
|
|
83
|
+
'callback': callback,
|
|
84
|
+
'cartesian': report_cartesian,
|
|
85
|
+
'joints': report_joints,
|
|
86
|
+
'error_code': report_error_code,
|
|
87
|
+
'warn_code': report_warn_code,
|
|
88
|
+
'state': report_state,
|
|
89
|
+
'mtable': report_mtable,
|
|
90
|
+
'mtbrake': report_mtbrake,
|
|
91
|
+
'cmdnum': report_cmd_num
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
def register_report_location_callback(self, callback=None, report_cartesian=True, report_joints=False):
|
|
95
|
+
ret = self._register_report_callback(REPORT_LOCATION_ID, {
|
|
96
|
+
'callback': callback,
|
|
97
|
+
'cartesian': report_cartesian,
|
|
98
|
+
'joints': report_joints,
|
|
99
|
+
})
|
|
100
|
+
return ret
|
|
101
|
+
|
|
102
|
+
def register_connect_changed_callback(self, callback=None):
|
|
103
|
+
return self._register_report_callback(REPORT_CONNECT_CHANGED_ID, callback)
|
|
104
|
+
|
|
105
|
+
def register_state_changed_callback(self, callback=None):
|
|
106
|
+
return self._register_report_callback(REPORT_STATE_CHANGED_ID, callback)
|
|
107
|
+
|
|
108
|
+
def register_mode_changed_callback(self, callback=None):
|
|
109
|
+
return self._register_report_callback(REPORT_MODE_CHANGED_ID, callback)
|
|
110
|
+
|
|
111
|
+
def register_mtable_mtbrake_changed_callback(self, callback=None):
|
|
112
|
+
return self._register_report_callback(REPORT_MTABLE_MTBRAKE_CHANGED_ID, callback)
|
|
113
|
+
|
|
114
|
+
def register_error_warn_changed_callback(self, callback=None):
|
|
115
|
+
return self._register_report_callback(REPORT_ERROR_WARN_CHANGED_ID, callback)
|
|
116
|
+
|
|
117
|
+
def register_cmdnum_changed_callback(self, callback=None):
|
|
118
|
+
return self._register_report_callback(REPORT_CMDNUM_CHANGED_ID, callback)
|
|
119
|
+
|
|
120
|
+
def register_temperature_changed_callback(self, callback=None):
|
|
121
|
+
return self._register_report_callback(REPORT_TEMPERATURE_CHANGED_ID, callback)
|
|
122
|
+
|
|
123
|
+
def register_count_changed_callback(self, callback=None):
|
|
124
|
+
return self._register_report_callback(REPORT_COUNT_CHANGED_ID, callback)
|
|
125
|
+
|
|
126
|
+
def register_iden_progress_changed_callback(self, callback=None):
|
|
127
|
+
return self._register_report_callback(REPORT_IDEN_PROGRESS_CHANGED_ID, callback)
|
|
128
|
+
|
|
129
|
+
def register_feedback_callback(self, callback=None):
|
|
130
|
+
return self._register_report_callback(FEEDBACK_ID, callback)
|
|
131
|
+
|
|
132
|
+
def release_report_callback(self, callback=None):
|
|
133
|
+
return self._release_report_callback(REPORT_ID, callback)
|
|
134
|
+
|
|
135
|
+
def release_report_location_callback(self, callback=None):
|
|
136
|
+
return self._release_report_callback(REPORT_LOCATION_ID, callback)
|
|
137
|
+
|
|
138
|
+
def release_connect_changed_callback(self, callback=None):
|
|
139
|
+
return self._release_report_callback(REPORT_CONNECT_CHANGED_ID, callback)
|
|
140
|
+
|
|
141
|
+
def release_state_changed_callback(self, callback=None):
|
|
142
|
+
return self._release_report_callback(REPORT_STATE_CHANGED_ID, callback)
|
|
143
|
+
|
|
144
|
+
def release_mode_changed_callback(self, callback=None):
|
|
145
|
+
return self._release_report_callback(REPORT_MODE_CHANGED_ID, callback)
|
|
146
|
+
|
|
147
|
+
def release_mtable_mtbrake_changed_callback(self, callback=None):
|
|
148
|
+
return self._release_report_callback(REPORT_MTABLE_MTBRAKE_CHANGED_ID, callback)
|
|
149
|
+
|
|
150
|
+
def release_error_warn_changed_callback(self, callback=None):
|
|
151
|
+
return self._release_report_callback(REPORT_ERROR_WARN_CHANGED_ID, callback)
|
|
152
|
+
|
|
153
|
+
def release_cmdnum_changed_callback(self, callback=None):
|
|
154
|
+
return self._release_report_callback(REPORT_CMDNUM_CHANGED_ID, callback)
|
|
155
|
+
|
|
156
|
+
def release_temperature_changed_callback(self, callback=None):
|
|
157
|
+
return self._release_report_callback(REPORT_TEMPERATURE_CHANGED_ID, callback)
|
|
158
|
+
|
|
159
|
+
def release_count_changed_callback(self, callback=None):
|
|
160
|
+
return self._release_report_callback(REPORT_COUNT_CHANGED_ID, callback)
|
|
161
|
+
|
|
162
|
+
def release_iden_progress_changed_callback(self, callback=None):
|
|
163
|
+
return self._release_report_callback(REPORT_IDEN_PROGRESS_CHANGED_ID, callback)
|
|
164
|
+
|
|
165
|
+
def release_feedback_callback(self, callback=None):
|
|
166
|
+
return self._release_report_callback(FEEDBACK_ID, callback)
|