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/servo.py ADDED
@@ -0,0 +1,485 @@
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
+ from ..core.config.x_config import XCONF
10
+ from ..core.config.x_code import ServoError
11
+ from ..core.utils.log import logger, pretty_print
12
+ from .base import Base
13
+ from .decorator import xarm_is_connected
14
+
15
+
16
+ class Servo(Base):
17
+ def __init__(self):
18
+ super(Servo, self).__init__()
19
+
20
+ @xarm_is_connected(_type='get')
21
+ def get_servo_debug_msg(self, show=False, lang='en'):
22
+ ret = self.arm_cmd.servo_get_dbmsg()
23
+ dbmsg = []
24
+ lang = lang if lang == 'cn' else 'en'
25
+ if self._check_code(ret[0]) == 0:
26
+ for i in range(1, 9):
27
+ servo_error = ServoError(ret[i * 2], status=ret[i * 2 - 1])
28
+ name = ('伺服-{}'.format(i) if lang == 'cn' else 'Servo-{}'.format(i)) if i < 8 else ('机械爪' if lang == 'cn' else 'Gripper')
29
+ dbmsg.append({
30
+ 'name': name,
31
+ 'servo_id': i,
32
+ 'status': servo_error.status,
33
+ 'code': servo_error.code,
34
+ 'title': servo_error.title[lang],
35
+ 'desc': servo_error.description[lang]
36
+ })
37
+ if show:
38
+ pretty_print('************* {}, {}: {} **************'.format(
39
+ '获取伺服信息' if lang == 'cn' else 'GetServoDebugMsg',
40
+ '状态' if lang == 'cn' else 'Status',
41
+ ret[0]), color='light_blue')
42
+ for servo_info in dbmsg:
43
+ color = 'red' if servo_info['code'] != 0 or servo_info['status'] != 0 else 'white'
44
+ pretty_print('* {}, {}: {}, {}: {}, {}: {}'.format(
45
+ servo_info['name'],
46
+ '状态' if lang == 'cn' else 'Status',
47
+ servo_info['status'],
48
+ '错误码' if lang == 'cn' else 'Code',
49
+ servo_info['code'],
50
+ '信息' if lang == 'cn' else 'Info',
51
+ servo_info['title']), color=color)
52
+ pretty_print('*' * 50, color='light_blue')
53
+ return ret[0], dbmsg
54
+
55
+ @xarm_is_connected(_type='set')
56
+ def set_servo_zero(self, servo_id=None):
57
+ """
58
+ Danger, do not use, may cause the arm to be abnormal, just for debugging
59
+ :param servo_id:
60
+ :return:
61
+ """
62
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 8, 'The value of parameter servo_id can only be 1-8.'
63
+ ret = self.arm_cmd.servo_set_zero(servo_id)
64
+ self.log_api_info('API -> set_servo_zero(servo_id={}) -> code={}'.format(servo_id, ret[0]), code=ret[0])
65
+ return ret[0]
66
+
67
+ @xarm_is_connected(_type='set')
68
+ def set_servo_addr_16(self, servo_id=None, addr=None, value=None, id_check=True):
69
+ """
70
+ Danger, do not use, may cause the arm to be abnormal, just for debugging
71
+ :param servo_id:
72
+ :param addr:
73
+ :param value:
74
+ :param id_check:
75
+ :return:
76
+ """
77
+ if id_check:
78
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 7, 'The value of parameter servo_id can only be 1-7.'
79
+ assert addr is not None, 'The value of parameter addr cannot be None.'
80
+ assert value is not None, 'The value of parameter value cannot be None.'
81
+ ret = self.arm_cmd.servo_addr_w16(servo_id, addr, value)
82
+ self.log_api_info('API -> set_servo_addr_16(servo_id={}, addr={}, value={}) -> code={}'.format(servo_id, addr, value, ret[0]), code=ret[0])
83
+ return ret[0]
84
+
85
+ @xarm_is_connected(_type='get')
86
+ def get_servo_addr_16(self, servo_id=None, addr=None, id_check=True):
87
+ """
88
+ Danger, do not use, may cause the arm to be abnormal, just for debugging
89
+ :param servo_id:
90
+ :param addr:
91
+ :return:
92
+ """
93
+ if id_check:
94
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 7, 'The value of parameter servo_id can only be 1-7.'
95
+ assert addr is not None, 'The value of parameter addr cannot be None.'
96
+ ret = self.arm_cmd.servo_addr_r16(servo_id, addr)
97
+ return ret[0], ret[1]
98
+
99
+ @xarm_is_connected(_type='set')
100
+ def set_servo_addr_32(self, servo_id=None, addr=None, value=None, id_check=True):
101
+ """
102
+ Danger, do not use, may cause the arm to be abnormal, just for debugging
103
+ :param servo_id:
104
+ :param addr:
105
+ :param value:
106
+ :return:
107
+ """
108
+ if id_check:
109
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 7, 'The value of parameter servo_id can only be 1-7.'
110
+ assert addr is not None, 'The value of parameter addr cannot be None.'
111
+ assert value is not None, 'The value of parameter value cannot be None.'
112
+ ret = self.arm_cmd.servo_addr_w32(servo_id, addr, value)
113
+ self.log_api_info('API -> set_servo_addr_32(servo_id={}, addr={}, value={}) -> code={}'.format(servo_id, addr, value, ret[0]), code=ret[0])
114
+ return ret[0]
115
+
116
+ @xarm_is_connected(_type='get')
117
+ def get_servo_addr_32(self, servo_id=None, addr=None, id_check=True):
118
+ """
119
+ Danger, do not use, may cause the arm to be abnormal, just for debugging
120
+ :param servo_id:
121
+ :param addr:
122
+ :return:
123
+ """
124
+ if id_check:
125
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 7, 'The value of parameter servo_id can only be 1-7.'
126
+ assert addr is not None, 'The value of parameter addr cannot be None.'
127
+ ret = self.arm_cmd.servo_addr_r32(servo_id, addr)
128
+ return ret[0], ret[1]
129
+
130
+ @xarm_is_connected(_type='set')
131
+ def clean_servo_error(self, servo_id=None):
132
+ """
133
+ Danger, do not use, may cause the arm to be abnormal, just for debugging
134
+ :param servo_id:
135
+ :return:
136
+ """
137
+ return self.set_servo_addr_16(servo_id, 0x0109, 1)
138
+
139
+ @xarm_is_connected(_type='get')
140
+ def get_servo_state(self, servo_id):
141
+ """
142
+ 获取运行状态
143
+ :param servo_id:
144
+ :return:
145
+ """
146
+ ret = self.get_servo_addr_16(servo_id, 0x0000)
147
+ return ret
148
+
149
+ @xarm_is_connected(_type='get')
150
+ def get_servo_rotate_speed(self, servo_id):
151
+ """
152
+ 获取转速
153
+ :param servo_id:
154
+ :return:
155
+ """
156
+ ret = self.get_servo_addr_16(servo_id, 0x0001)
157
+ return ret
158
+
159
+ @xarm_is_connected(_type='get')
160
+ def get_servo_current_percentage(self, servo_id):
161
+ """
162
+ 获取电流百分比
163
+ :param servo_id:
164
+ :return:
165
+ """
166
+ ret = self.get_servo_addr_16(servo_id, 0x0002)
167
+ return ret
168
+
169
+ @xarm_is_connected(_type='get')
170
+ def get_servo_current(self, servo_id):
171
+ """
172
+ 获取电流
173
+ :param servo_id:
174
+ :return:
175
+ """
176
+ ret = self.get_servo_addr_16(servo_id, 0x0003)
177
+ return ret[0], ret[1] / 100
178
+
179
+ @xarm_is_connected(_type='get')
180
+ def get_servo_command_position(self, servo_id):
181
+ """
182
+ 获取指令位置
183
+ :param servo_id:
184
+ :return:
185
+ """
186
+ ret = self.get_servo_addr_32(servo_id, 0x0004)
187
+ return ret
188
+
189
+ @xarm_is_connected(_type='get')
190
+ def get_servo_position(self, servo_id):
191
+ """
192
+ 获取电机位置
193
+ :param servo_id:
194
+ :return:
195
+ """
196
+ ret = self.get_servo_addr_32(servo_id, 0x0006)
197
+ return ret
198
+
199
+ @xarm_is_connected(_type='get')
200
+ def get_servo_position_deviation(self, servo_id):
201
+ """
202
+ 获取位置误差
203
+ :param servo_id:
204
+ :return:
205
+ """
206
+ ret = self.get_servo_addr_32(servo_id, 0x0008)
207
+ return ret
208
+
209
+ @xarm_is_connected(_type='get')
210
+ def get_servo_electrical_angle(self, servo_id):
211
+ """
212
+ 获取电角度
213
+ :param servo_id:
214
+ :return:
215
+ """
216
+ ret = self.get_servo_addr_16(servo_id, 0x000B)
217
+ return ret
218
+
219
+ @xarm_is_connected(_type='get')
220
+ def get_servo_drv8323_sr0_register(self, servo_id):
221
+ """
222
+ 获取DRV8323_SR0状态寄存器
223
+ :param servo_id:
224
+ :return:
225
+ """
226
+ ret = self.get_servo_addr_16(servo_id, 0x000C)
227
+ return ret
228
+
229
+ @xarm_is_connected(_type='get')
230
+ def get_servo_drv8323_sr1_register(self, servo_id):
231
+ """
232
+ 获取DRV8323_SR1状态寄存器
233
+ :param servo_id:
234
+ :return:
235
+ """
236
+ ret = self.get_servo_addr_16(servo_id, 0x000D)
237
+ return ret
238
+
239
+ @xarm_is_connected(_type='get')
240
+ def get_servo_temperature(self, servo_id):
241
+ """
242
+ 获取当前温度
243
+ :param servo_id:
244
+ :return:
245
+ """
246
+ ret = self.get_servo_addr_16(servo_id, 0x000E)
247
+ return ret
248
+
249
+ @xarm_is_connected(_type='get')
250
+ def get_servo_alarm_code(self, servo_id):
251
+ """
252
+ 获取当前报警代码
253
+ :param servo_id:
254
+ :return:
255
+ """
256
+ ret = self.get_servo_addr_16(servo_id, 0x000F)
257
+ return ret
258
+
259
+ @xarm_is_connected(_type='get')
260
+ def get_servo_alarm_current(self, servo_id):
261
+ """
262
+ 获取报警发生时的电流值
263
+ :param servo_id:
264
+ :return:
265
+ """
266
+ ret = self.get_servo_addr_16(servo_id, 0x0010)
267
+ return ret
268
+
269
+ @xarm_is_connected(_type='get')
270
+ def get_servo_alarm_speed(self, servo_id):
271
+ """
272
+ 获取报警发生时的速度值
273
+ :param servo_id:
274
+ :return:
275
+ """
276
+ ret = self.get_servo_addr_16(servo_id, 0x0011)
277
+ return ret
278
+
279
+ @xarm_is_connected(_type='get')
280
+ def get_servo_alarm_voltage(self, servo_id):
281
+ """
282
+ 获取报警发生时的输入电压值
283
+ :param servo_id:
284
+ :return:
285
+ """
286
+ ret = self.get_servo_addr_16(servo_id, 0x0012)
287
+ return ret
288
+
289
+ @xarm_is_connected(_type='get')
290
+ def get_servo_bus_voltage(self, servo_id):
291
+ """
292
+ 获取母线电压
293
+ :param servo_id:
294
+ :return:
295
+ """
296
+ ret = self.get_servo_addr_16(servo_id, 0x0018)
297
+ return ret[0], ret[1] / 100
298
+
299
+ @xarm_is_connected(_type='get')
300
+ def get_servo_mu_state(self, servo_id):
301
+ """
302
+ 获取MU当前状态
303
+ :param servo_id:
304
+ :return:
305
+ """
306
+ ret = self.get_servo_addr_16(servo_id, 0x001E)
307
+ return ret
308
+
309
+ @xarm_is_connected(_type='get')
310
+ def get_servo_mu_alarm_count(self, servo_id):
311
+ """
312
+ 获取MU上电后报警次数
313
+ :param servo_id:
314
+ :return:
315
+ """
316
+ ret = self.get_servo_addr_16(servo_id, 0x001F)
317
+ return ret
318
+
319
+ @xarm_is_connected(_type='get')
320
+ def get_servo_feedback_position(self, servo_id):
321
+ """
322
+ 获取关节反馈位置
323
+ :param servo_id:
324
+ :return:
325
+ """
326
+ ret = self.get_servo_addr_32(servo_id, 0x0040)
327
+ return ret
328
+
329
+ # @xarm_is_connected(_type='get')
330
+ # def get_servo_current(self, servo_id):
331
+ # """
332
+ # 获取电流
333
+ # :param servo_id:
334
+ # :return:
335
+ # """
336
+ # ret = self.get_servo_addr_16(servo_id, 0x0042)
337
+ # return ret
338
+
339
+ @xarm_is_connected(_type='get')
340
+ def get_servo_version(self, servo_id=1):
341
+ """
342
+ 获取关节版本
343
+ :param servo_id:
344
+ :return:
345
+ """
346
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 8, 'The value of parameter servo_id can only be 1-8.'
347
+
348
+ def _get_servo_version(id_num):
349
+ versions = ['*', '*', '*']
350
+ ret1 = self.get_servo_addr_16(id_num, 0x0801)
351
+ ret2 = self.get_servo_addr_16(id_num, 0x0802)
352
+ ret3 = self.get_servo_addr_16(id_num, 0x0803)
353
+ code = 0
354
+ if ret1[0] == 0:
355
+ versions[0] = ret1[1]
356
+ else:
357
+ code = ret1[0]
358
+ if ret2[0] == 0:
359
+ versions[1] = ret2[1]
360
+ else:
361
+ code = ret2[0]
362
+ if ret3[0] == 0:
363
+ versions[2] = ret3[1]
364
+ else:
365
+ code = ret3[0]
366
+ # if code != 0:
367
+ # _, err_warn = self.get_err_warn_code()
368
+ # if _ in [0, 1, 2]:
369
+ # if err_warn[0] not in [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 28]:
370
+ # versions = [ret1[1], ret2[1], ret3[1]]
371
+ return code, '.'.join(map(str, versions))
372
+
373
+ if servo_id > self.axis:
374
+ code = 0
375
+ versions = []
376
+ for i in range(1, self.axis + 1):
377
+ ret = _get_servo_version(i)
378
+ if ret[0] != 0:
379
+ code = ret[0]
380
+ versions.append(ret[1])
381
+ return code, versions
382
+ else:
383
+ return _get_servo_version(servo_id)
384
+
385
+ @xarm_is_connected(_type='get')
386
+ def get_harmonic_type(self, servo_id=1):
387
+ """
388
+ 获取关节版本
389
+ :param servo_id:
390
+ :return:
391
+ """
392
+ assert isinstance(servo_id, int) and 1 <= servo_id <= 8, 'The value of parameter servo_id can only be 1-8.'
393
+
394
+ if servo_id > self.axis:
395
+ code = 0
396
+ types = []
397
+ for i in range(1, self.axis + 1):
398
+ ret = self.get_servo_addr_16(i, 0x081F)
399
+ if ret[0] != 0:
400
+ code = ret[0]
401
+ types.append(ret[1])
402
+ return code, types
403
+ else:
404
+ return self.get_servo_addr_16(servo_id, 0x081F)
405
+
406
+ @xarm_is_connected(_type='get')
407
+ def get_servo_error_code(self, servo_id=None):
408
+ assert servo_id is None or (isinstance(servo_id, int) and servo_id >= 1), \
409
+ 'The value of parameter servo_id must be greater than 1 or None.'
410
+ code = 0
411
+ if servo_id is None or servo_id > self.axis:
412
+ count = 7 if servo_id == 8 else self.axis
413
+ errcodes = [0] * count
414
+ for i in range(count):
415
+ ret = self.get_servo_addr_32(i + 1, XCONF.ServoConf.CURR_POS)
416
+ if ret[0] == XCONF.UxbusState.ERR_CODE:
417
+ _, err_warn = self.get_err_warn_code()
418
+ if _ == 0:
419
+ if i + 11 == err_warn[0]:
420
+ errcodes[i] = ret[1]
421
+ else:
422
+ errcodes[i] = 0
423
+ else:
424
+ code = _
425
+ logger.error('Get controller errwarn: ret={}, errwarn={}'.format(code, err_warn))
426
+ errcodes[i] = ret[1]
427
+ else:
428
+ errcodes = 0
429
+ ret = self.get_servo_addr_32(servo_id, XCONF.ServoConf.CURR_POS)
430
+ if ret[0] == XCONF.UxbusState.ERR_CODE:
431
+ _, err_warn = self.get_err_warn_code()
432
+ if _ == 0:
433
+ if servo_id + 10 == err_warn[0]:
434
+ errcodes = ret[1]
435
+ else:
436
+ errcodes = 0
437
+ else:
438
+ code = _
439
+ logger.error('Get controller errwarn: ret={}, errwarn={}'.format(code, err_warn))
440
+ errcodes = ret[1]
441
+ return code, errcodes
442
+
443
+ @xarm_is_connected(_type='set')
444
+ def clean_servo_pvl_err(self, servo_id=None):
445
+ assert servo_id is None or (isinstance(servo_id, int) and servo_id >= 1), \
446
+ 'The value of parameter servo_id must be greater than 1 or None.'
447
+ if servo_id is None or servo_id > self.axis:
448
+ count = 7 if servo_id == 8 else self.axis
449
+ ids = range(count)
450
+ else:
451
+ ids = [servo_id - 1]
452
+ _, errcode = self.get_servo_error_code()
453
+ for i in ids:
454
+ if errcode[i] == 0x12:
455
+ self.set_servo_addr_16(i + 1, XCONF.ServoConf.RESET_PVL, 0x0002)
456
+ self.set_servo_addr_16(i + 1, XCONF.ServoConf.RESET_ERR, 1)
457
+ return 0
458
+
459
+ @xarm_is_connected(_type='get')
460
+ def get_servo_all_pids(self, servo_id=None):
461
+ assert servo_id is None or (isinstance(servo_id, int) and servo_id >= 1), \
462
+ 'The value of parameter servo_id must be greater than 1 or None.'
463
+ self.clean_error()
464
+ self.clean_warn()
465
+ addrs = [
466
+ XCONF.ServoConf.POS_KP, XCONF.ServoConf.POS_FWDKP, XCONF.ServoConf.POS_PWDTC,
467
+ XCONF.ServoConf.SPD_KP, XCONF.ServoConf.SPD_KI, XCONF.ServoConf.CURR_KP,
468
+ XCONF.ServoConf.CURR_KI, XCONF.ServoConf.SPD_IFILT, XCONF.ServoConf.SPD_OFILT,
469
+ XCONF.ServoConf.CURR_IFILT, XCONF.ServoConf.POS_KD, XCONF.ServoConf.POS_CMDILT,
470
+ XCONF.ServoConf.GET_TEMP, XCONF.ServoConf.OVER_TEMP
471
+ ]
472
+ if servo_id is None or servo_id > self.axis:
473
+ count = 7 if servo_id == 8 else self.axis
474
+ pids = [[9999] * len(addrs) for _ in range(count)]
475
+ for i in range(count):
476
+ for j, addr in enumerate(addrs):
477
+ _, data = self.get_servo_addr_16(i + 1, addr)
478
+ if _ == 0:
479
+ pids[i][j] = data
480
+ else:
481
+ pids = [9999] * len(addrs)
482
+ for j, addr in enumerate(addrs):
483
+ _, data = self.get_servo_addr_16(servo_id, addr)
484
+ pids[j] = data
485
+ return 0, pids
xarm/x3/studio.py ADDED
@@ -0,0 +1,138 @@
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
+ import json
10
+ import warnings
11
+ from ..core.utils.log import logger
12
+ from .code import APIState
13
+
14
+ try:
15
+ from requests import Session
16
+ except:
17
+ import urllib.request
18
+
19
+ class Session(object):
20
+ class Request:
21
+ def __init__(self, url, data, **kwargs):
22
+ req = urllib.request.Request(url, data.encode('utf-8'))
23
+ self.r = urllib.request.urlopen(req)
24
+ self._data = self.r.read()
25
+
26
+ @property
27
+ def status_code(self):
28
+ return self.r.code
29
+
30
+ def json(self):
31
+ return json.loads(self._data.decode('utf-8'))
32
+
33
+ def post(self, url, data=None, **kwargs):
34
+ return self.Request(url, data)
35
+
36
+ def close(self):
37
+ pass
38
+
39
+
40
+ class Studio(object):
41
+ def __init__(self, ip, ignore_warnning=False):
42
+ super(Studio, self).__init__()
43
+ if not ignore_warnning:
44
+ warnings.warn("don't use it for now, just for debugging")
45
+ self.__ip = ip
46
+ self.__session = Session()
47
+
48
+ def __del__(self):
49
+ self.__session.close()
50
+
51
+ def run_blockly_app(self, name, **kwargs):
52
+ try:
53
+ self.call_studio_api({}, api_name='Core.command.xarm_set_blockly_init', show_fail_log=False)
54
+ except:
55
+ pass
56
+ kwargs['appName'] = name
57
+ ret = self.call_studio_api(kwargs, api_name='Core.command.run_blockly')
58
+ if ret:
59
+ return ret['code']
60
+ return APIState.API_EXCEPTION
61
+
62
+ def delete_blockly_app(self, name):
63
+ ret = self.call_studio_api({
64
+ 'parentPath': name,
65
+ 'selectNode': {
66
+ 'type': 'file'
67
+ }
68
+ }, api_name='Core.command.app_delete_item')
69
+ if ret:
70
+ return ret['code']
71
+ return APIState.API_EXCEPTION
72
+
73
+ def playback_trajectory(self, filename, times=1, wait=False, double_speed=1):
74
+ ret = self.call_studio_api({
75
+ 'filename': filename,
76
+ 'times': times,
77
+ 'speed': double_speed,
78
+ 'wait': wait,
79
+ }, api_name='Core.command.xarm_playback_traj')
80
+ if ret:
81
+ return ret['code']
82
+ return APIState.API_EXCEPTION
83
+
84
+ def delete_trajectory(self, filename):
85
+ ret = self.call_studio_api({
86
+ 'filename': filename,
87
+ }, api_name='Core.command.xarm_delete_traj')
88
+ if ret:
89
+ return ret['code']
90
+ return APIState.API_EXCEPTION
91
+
92
+ def set_initial_point(self, point):
93
+ ret = self.call_studio_api({'point': point}, api_name='Core.command.xarm_set_initial_point')
94
+ if ret:
95
+ return ret['code']
96
+ return APIState.API_EXCEPTION
97
+
98
+ def get_initial_point(self):
99
+ ret = self.call_studio_api(api_name='XArm.xarm_initial_point')
100
+ if ret:
101
+ return ret['code'], ret['data']
102
+ return APIState.API_EXCEPTION, [0] * 7
103
+
104
+ def call_sdk_api(self, *args, **kwargs):
105
+ kwargs['api_name'] = 'XArm.xarm.{}'.format(kwargs['api_name'])
106
+ return self.call_studio_api(*args, **kwargs)
107
+
108
+ def call_studio_api(self, *args, **kwargs):
109
+ kwargs['path'] = 'v2/api'
110
+ return self.__call_remote_api(*args, **kwargs)
111
+
112
+ def __call_remote_api(self, *args, **kwargs):
113
+ api_name = kwargs.pop('api_name', None)
114
+ show_fail_log = kwargs.pop('show_fail_log', True)
115
+ path = kwargs.pop('path')
116
+ if self.__ip and api_name:
117
+ r = self.__session.post('http://{}:18333/{}'.format(self.__ip, path), data=json.dumps({
118
+ 'cmd': api_name, 'args': args, 'kwargs': kwargs
119
+ }), timeout=(5, None))
120
+ if r.status_code == 200:
121
+ res = r.json()
122
+ if res['code'] != 0:
123
+ if show_fail_log:
124
+ logger.error(res['data'])
125
+ return res
126
+ else:
127
+ if show_fail_log:
128
+ logger.error('request failed, http_status_code={}'.format(r.status_code))
129
+ else:
130
+ if show_fail_log:
131
+ logger.error('ip or api_name is empty, ip={}, api_name={}'.format(self.__ip, api_name))
132
+
133
+ def get_mount_direction(self):
134
+
135
+ ret = self.call_studio_api(api_name='XArm.xarm_mount_degrees')
136
+ if ret:
137
+ return ret['code'], ret['data']
138
+ return APIState.API_EXCEPTION, [0, 0]