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
@@ -0,0 +1,94 @@
1
+
2
+ HIGHLIGHT_BLOCKS = [
3
+ 'studio_play_recording',
4
+ 'studio_run_python',
5
+ 'studio_run_traj',
6
+ 'studio_run_file',
7
+ 'app_studio_traj',
8
+
9
+ 'wait_until',
10
+ 'wait',
11
+ 'loop_break',
12
+
13
+ 'set_acceleration',
14
+ 'set_speed',
15
+ 'set_angle_speed',
16
+ 'set_angle_acceleration',
17
+
18
+ 'set_gripper',
19
+ 'gripper_mode',
20
+ 'gripper_enable',
21
+ 'gripper_position',
22
+ 'gripper_speed',
23
+ 'gripper_set',
24
+ 'gripper_set_status',
25
+ 'set_suction_cup',
26
+ 'get_suction_cup',
27
+ 'check_air_pump_state',
28
+ 'set_lite6_gripper',
29
+
30
+ 'gpio_get_analog',
31
+ 'gpio_get_digital',
32
+ 'gpio_set_digital',
33
+ 'gpio_get_controller_analog',
34
+ 'gpio_get_controller_digital',
35
+ 'gpio_set_controller_digital',
36
+ 'gpio_set_controller_analog',
37
+ 'gpio_set_digital_with_xyz',
38
+ 'gpio_set_controller_digital_with_xyz',
39
+ 'gpio_set_controller_analog_with_xyz',
40
+
41
+ 'move_7',
42
+ 'move_to',
43
+ 'move_arc_to',
44
+ 'move_circle',
45
+ 'move',
46
+ 'reset',
47
+ 'sleep',
48
+ 'motion_stop',
49
+ 'motion_set_state',
50
+ 'move_joints',
51
+ 'move_joints_var',
52
+ 'move_cartesian',
53
+ 'move_cartesian_var',
54
+ 'move_tool_line',
55
+
56
+ 'set_tcp_load',
57
+ 'set_tcp_offset',
58
+ 'set_world_offset',
59
+ 'set_counter_reset',
60
+ 'set_counter_increase',
61
+ 'set_collision_sensitivity',
62
+
63
+ 'set_bio_gripper_init',
64
+ 'set_bio_gripper',
65
+ 'check_bio_gripper_is_catch',
66
+ 'set_robotiq_init',
67
+ 'set_robotiq_gripper',
68
+ 'check_robotiq_is_catch',
69
+
70
+ 'tool_message',
71
+ 'tool_console',
72
+ 'tool_console_with_variable',
73
+
74
+ 'event_gpio_digital',
75
+ 'event_gpio_analog',
76
+ 'event_gpio_controller_digital',
77
+ 'event_gpio_controller_analog',
78
+
79
+ 'procedures_callnoreturn',
80
+ 'procedures_callreturn',
81
+
82
+ 'variables_set',
83
+ 'math_change',
84
+ 'loop_run_forever',
85
+ 'controls_whileUntil',
86
+ 'controls_repeat_ext',
87
+ 'loop_break',
88
+
89
+ 'python_code',
90
+ 'python_expression',
91
+ 'gpio_get_controller_ci_li',
92
+ 'gpio_get_controller_di_li',
93
+ 'gpio_get_tgpio_li'
94
+ ]
@@ -0,0 +1,61 @@
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
+ try:
10
+ import xml.etree.cElementTree as ET
11
+ except ImportError:
12
+ import xml.etree.ElementTree as ET
13
+ import re
14
+
15
+
16
+ class _BlocklyNode(object):
17
+ def __init__(self, xml_path):
18
+ self._root = ET.parse(xml_path).getroot()
19
+ self._ns = self.__get_ns()
20
+
21
+ def __get_ns(self):
22
+ try:
23
+ r = re.compile('({.+})')
24
+ if r.search(self._root.tag) is not None:
25
+ ns = r.search(self._root.tag).group(1)
26
+ else:
27
+ ns = ''
28
+ except Exception as e:
29
+ print('get namespace exception: {}'.format(e))
30
+ ns = ''
31
+ return ns
32
+
33
+ def _get_node(self, tag, root=None):
34
+ root = self._root if root is None else root
35
+ return root.find(self._ns + tag)
36
+
37
+ def _get_nodes(self, tag, root=None, descendant=False, **kwargs):
38
+ root = self._root if root is None else root
39
+ nodes = []
40
+ func = root.iter if descendant else root.findall
41
+ for node in func(self._ns + tag):
42
+ flag = True
43
+ for k, v in kwargs.items():
44
+ if node.attrib[k] != v:
45
+ flag = False
46
+ if flag:
47
+ nodes.append(node)
48
+ return nodes
49
+
50
+ def get_node(self, tag, root=None):
51
+ """
52
+ Only call in studio
53
+ """
54
+ return self._get_node(tag, root=root)
55
+
56
+ def get_nodes(self, tag, root=None, descendant=False, **kwargs):
57
+ """
58
+ Only call in studio
59
+ """
60
+ return self._get_nodes(tag, root=root, descendant=descendant, **kwargs)
61
+
@@ -0,0 +1,480 @@
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 json
10
+ from ._blockly_handler import _BlocklyHandler
11
+
12
+
13
+ class BlocklyTool(_BlocklyHandler):
14
+ def __init__(self, xml_path):
15
+ super(BlocklyTool, self).__init__(xml_path)
16
+ self._is_converted = False
17
+ self._codes = []
18
+
19
+ @property
20
+ def codes(self):
21
+ return '\n'.join(self._codes)
22
+
23
+ def to_python(self, path=None, arm=None, init=True, wait_seconds=1, mode=0, state=0, error_exit=True, stop_exit=True, **kwargs):
24
+ if not self._is_converted:
25
+ self._is_exec = kwargs.get('is_exec', False)
26
+ self._is_ide = kwargs.get('is_ide', False)
27
+ self._vacuum_version = kwargs.get('vacuum_version', '1')
28
+ # highlight_callback: only use pack to run blockly in studio
29
+ self._highlight_callback = kwargs.get('highlight_callback', None)
30
+ # axis_type: Obtain the type of mechanical arm axis for end leveling use
31
+ if 'axis_type' in kwargs:
32
+ self.axis_type = kwargs.get('axis_type', [])
33
+ else:
34
+ self.axis_type = []
35
+ # loop_max_frequency: limit frequency in loop, only use pack to run blockly in studio
36
+ if 'loop_max_frequency' in kwargs:
37
+ loop_max_freq = kwargs.get('loop_max_frequency', -1)
38
+ if loop_max_freq < 0 or loop_max_freq > 10000:
39
+ self._loop_interval_sec = 0
40
+ else:
41
+ self._loop_interval_sec = 1 / loop_max_freq
42
+ elif self._highlight_callback:
43
+ self._loop_interval_sec = 0.001
44
+ self._init_header_codes()
45
+ self._init_robot_main_run_codes()
46
+ self._parse_block()
47
+ self._finish_robot_main_run_codes(error_exit, stop_exit)
48
+ self._init_robot_main_class_codes(init=init, wait_seconds=wait_seconds, mode=mode, state=state, error_exit=error_exit, stop_exit=stop_exit)
49
+ self._init_main_codes(arm=arm)
50
+ self._codes.extend(self._init_code_list)
51
+ self._codes.extend(self._main_init_code_list)
52
+ self._codes.extend(self._main_func_code_list)
53
+ self._codes.extend(self._main_run_code_list)
54
+ self._is_converted = True
55
+ if path is not None:
56
+ with open(path, 'w', encoding='utf-8') as f:
57
+ f.write('{}\n'.format(self.codes))
58
+ return self._succeed
59
+
60
+ def _init_header_codes(self):
61
+ self._append_init_code('#!/usr/bin/env python3')
62
+ self._append_init_code('# Software License Agreement (BSD License)')
63
+ self._append_init_code('#')
64
+ self._append_init_code('# Copyright (c) 2022, UFACTORY, Inc.')
65
+ self._append_init_code('# All rights reserved.')
66
+ self._append_init_code('#')
67
+ self._append_init_code('# Author: Vinman <vinman.wen@ufactory.cc> <vinman.cub@gmail.com>\n')
68
+ self._append_init_code('"""')
69
+ self._append_init_code('# Notice')
70
+ self._append_init_code('# 1. Changes to this file on Studio will not be preserved')
71
+ self._append_init_code('# 2. The next conversion will overwrite the file with the same name')
72
+ self._append_init_code('# ')
73
+ self._append_init_code('# xArm-Python-SDK: https://github.com/xArm-Developer/xArm-Python-SDK')
74
+ self._append_init_code('# 1. git clone git@github.com:xArm-Developer/xArm-Python-SDK.git')
75
+ self._append_init_code('# 2. cd xArm-Python-SDK')
76
+ self._append_init_code('# 3. python setup.py install')
77
+ self._append_init_code('"""')
78
+ self._append_init_code('import sys')
79
+ self._append_init_code('import math')
80
+ self._append_init_code('import time')
81
+ self._append_init_code('import queue')
82
+ self._append_init_code('import datetime')
83
+ self._append_init_code('import random')
84
+ self._append_init_code('import traceback')
85
+ self._append_init_code('import threading')
86
+ self._append_init_code('from xarm import version')
87
+ self._append_init_code('from xarm.wrapper import XArmAPI\n\n')
88
+
89
+ def _init_robot_main_run_codes(self):
90
+ self._append_main_code(' # Robot Main Run', indent=-1)
91
+ self._append_main_code(' def run(self):', indent=-1)
92
+ self._append_main_code(' try:', indent=-1)
93
+
94
+ def _finish_robot_main_run_codes(self, error_exit=True, stop_exit=True):
95
+ if self._listen_tgpio_digital or self._listen_tgpio_analog or self._listen_cgpio_state \
96
+ or len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks) or len(self._count_callbacks) or len(self._holding_callbacks):
97
+ self._append_main_code(' # Event Loop', indent=-1)
98
+ self._append_main_code(' while self.is_alive:', indent=-1)
99
+ self._append_main_code(' time.sleep(0.5)', indent=-1)
100
+
101
+ if self._is_main_run_code and (self._main_run_code_list[-1] == ' try:' or ' # ' in self._main_run_code_list[-1]):
102
+ self._append_main_code(' pass', indent=-1)
103
+ # catch exception and release callback
104
+ self._append_main_code(' except Exception as e:', indent=-1)
105
+ self._append_main_code(' self.pprint(\'MainException: {}\'.format(e))', indent=-1)
106
+ self._append_main_code(' finally:', indent=-1)
107
+ self._append_main_code(' self.alive = False', indent=-1)
108
+ if stop_exit or error_exit:
109
+ if error_exit:
110
+ self._append_main_code(' self._arm.release_error_warn_changed_callback(self._error_warn_changed_callback)', indent=-1)
111
+ if stop_exit:
112
+ self._append_main_code(' self._arm.release_state_changed_callback(self._state_changed_callback)', indent=-1)
113
+ if self._listen_counter:
114
+ self._append_main_code(' if hasattr(self._arm, \'release_count_changed_callback\'):', indent=-1)
115
+ self._append_main_code(' self._arm.release_count_changed_callback(self._count_changed_callback)', indent=-1)
116
+
117
+ # if self._listen_tgpio_digital or self._listen_tgpio_analog or self._listen_cgpio_state \
118
+ # or len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks):
119
+ # self._append_main_code(' # Event Loop', indent=-1)
120
+ # self._append_main_code(' while self.is_alive:', indent=-1)
121
+ # self._append_main_code(' time.sleep(0.5)', indent=-1)
122
+ # self._append_main_code(' self.alive = False', indent=-1)
123
+ # if stop_exit or error_exit:
124
+ # if error_exit:
125
+ # self._append_main_code(' self._arm.release_error_warn_changed_callback(self._error_warn_changed_callback)', indent=-1)
126
+ # if stop_exit:
127
+ # self._append_main_code(' self._arm.release_state_changed_callback(self._state_changed_callback)', indent=-1)
128
+ # self._append_main_code(' if hasattr(self._arm, \'release_count_changed_callback\'):', indent=-1)
129
+ # self._append_main_code(' self._arm.release_count_changed_callback(self._count_changed_callback)', indent=-1)
130
+
131
+ def _init_robot_main_class_codes(self, init=True, wait_seconds=1, mode=0, state=0, error_exit=True, stop_exit=True):
132
+ self._append_main_init_code('class RobotMain(object):')
133
+ self._append_main_init_code(' """Robot Main Class"""')
134
+ self._append_main_init_code(' def __init__(self, robot, **kwargs):')
135
+ self._append_main_init_code(' self.alive = True')
136
+ self._append_main_init_code(' self._arm = robot')
137
+ self._append_main_init_code(' self._ignore_exit_state = False')
138
+ self._append_main_init_code(' self._tcp_speed = 100')
139
+ self._append_main_init_code(' self._tcp_acc = 2000')
140
+ self._append_main_init_code(' self._angle_speed = 20')
141
+ self._append_main_init_code(' self._angle_acc = 500')
142
+ self._append_main_init_code(' self._vars = {}'.format({var: 0 for var in self._parse_variables()}))
143
+ if len(self._funcs):
144
+ self._append_main_init_code(' self._funcs = {')
145
+ for key, val in self._funcs.items():
146
+ self._append_main_init_code(' {}: self.{},'.format(json.dumps(key, ensure_ascii=False), val))
147
+ self._append_main_init_code(' }')
148
+ else:
149
+ self._append_main_init_code(' self._funcs = {}')
150
+ self._append_main_init_code(' self._robot_init()')
151
+ if len(self._tgpio_digital_callbacks):
152
+ self._append_main_init_code(' self._tgpio_digital_callbacks = []')
153
+ if len(self._tgpio_analog_callbacks):
154
+ self._append_main_init_code(' self._tgpio_analog_callbacks = []')
155
+ if len(self._cgpio_digital_callbacks):
156
+ self._append_main_init_code(' self._cgpio_digital_callbacks = []')
157
+ if len(self._cgpio_analog_callbacks):
158
+ self._append_main_init_code(' self._cgpio_analog_callbacks = []')
159
+ if len(self._count_callbacks):
160
+ self._append_main_init_code(' self._count_callbacks = []')
161
+ if len(self._holding_callbacks):
162
+ self._append_main_init_code(' self._holding_callbacks = []')
163
+ if self._listen_cgpio_state or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks):
164
+ self._append_main_init_code(' self._cgpio_state = None')
165
+
166
+ if self._listen_count or len(self._count_callbacks):
167
+ self._append_main_init_code(' self._counter_val = None')
168
+ if self._listen_holding or len(self._holding_callbacks):
169
+ self._append_main_init_code(' self._holding_dict = {}')
170
+
171
+ if len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks)\
172
+ or len(self._count_callbacks) or len(self._holding_callbacks):
173
+ self._append_main_init_code(' self._callback_in_thread = kwargs.get(\'callback_in_thread\', True)')
174
+ self._append_main_init_code(' self._callback_que = queue.Queue()')
175
+
176
+ if self._listen_tgpio_digital or self._listen_tgpio_analog or self._listen_cgpio_state \
177
+ or len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks):
178
+ self._append_main_init_code(' gpio_t = threading.Thread(target=self._listen_gpio_thread, daemon=True)')
179
+ self._append_main_init_code(' gpio_t.start()')
180
+
181
+ if len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks)\
182
+ or len(self._count_callbacks) or len(self._holding_callbacks):
183
+ self._append_main_init_code(' callback_t = threading.Thread(target=self._event_callback_handle_thread, daemon=True)')
184
+ self._append_main_init_code(' callback_t.start()')
185
+
186
+ if self._listen_count or len(self._count_callbacks):
187
+ self._append_main_init_code(
188
+ ' count_t = threading.Thread(target=self._listen_count_thread, daemon=True)')
189
+ self._append_main_init_code(' count_t.start()')
190
+
191
+ if self._holding_callbacks or len(self._holding_callbacks):
192
+ self._append_main_init_code(
193
+ ' holding_t = threading.Thread(target=self._listen_holding_thread, daemon=True)')
194
+ self._append_main_init_code(' holding_t.start()')
195
+
196
+ self._append_main_init_code('')
197
+
198
+ self.__define_callback_thread_func()
199
+ self.__define_listen_gpio_thread_func()
200
+ self.__define_listen_count_thread_func()
201
+ self.__define_listen_holding_registers_thread_func()
202
+ self.__define_run_blockly_func()
203
+ self.__define_robot_init_func(init=init, wait_seconds=wait_seconds, mode=mode, state=state, error_exit=error_exit, stop_exit=stop_exit)
204
+ self.__define_error_warn_changed_callback_func(error_exit=error_exit)
205
+ self.__define_state_changed_callback_func(stop_exit=stop_exit)
206
+ self.__define_count_changed_callback_func()
207
+ self.__define_cgpio_digitals_is_matchs_bin_func()
208
+ self.__define_check_code_func()
209
+ self.__define_is_prime_func()
210
+ self.__define_pprint_func()
211
+ self.__define_property()
212
+ self.__define_is_alive_property()
213
+
214
+ def __define_is_prime_func(self):
215
+ # Define Function: is_prime
216
+ if self._define_is_prime_func:
217
+ self._append_main_init_code(' @staticmethod')
218
+ self._append_main_init_code(' def is_prime(n):')
219
+ self._append_main_init_code(' def _is_prime()')
220
+ self._append_main_init_code(' for i in range(6, int(math.sqrt(n) + 1), 6):')
221
+ self._append_main_init_code(' if n % (i - 1) == 0 or n % (i + 1) == 0:')
222
+ self._append_main_init_code(' return False')
223
+ self._append_main_init_code(' return True')
224
+ self._append_main_init_code(' return n == 2 or n == 3 or (n > 1 and n % 2 != 0 and n % 3 != 0 and _is_prime())\n')
225
+
226
+ def __define_cgpio_digitals_is_matchs_bin_func(self):
227
+ # Define Funciton: cgpio_digitals_is_matchs_bin
228
+ if self._define_bin_matchs_func:
229
+ self._append_main_init_code(' def _cgpio_digitals_is_matchs_bin(self, bin_val):')
230
+ self._append_main_init_code(' if self._cgpio_state is None:')
231
+ self._append_main_init_code(' return True')
232
+ self._append_main_init_code(' digitals_bin = \'\'.join(map(str, [self._cgpio_state[3] >> i & 0x0001 if self._cgpio_state[10][i] in [0, 255] else 1 for i in range(len(self._cgpio_state[10]))]))')
233
+ self._append_main_init_code(' length = min(len(digitals_bin), len(bin_val))')
234
+ self._append_main_init_code(' bin_val_ = bin_val[::-1]')
235
+ self._append_main_init_code(' for i in range(length):')
236
+ self._append_main_init_code(' if bin_val_[i] != digitals_bin[i]:')
237
+ self._append_main_init_code(' return False')
238
+ self._append_main_init_code(' return True\n')
239
+
240
+ def __define_property(self):
241
+ # define property: self.arm -> self._arm
242
+ self._append_main_init_code(' @property')
243
+ self._append_main_init_code(' def arm(self):')
244
+ self._append_main_init_code(' return self._arm\n')
245
+ # define property: self.VARS -> self._vars
246
+ self._append_main_init_code(' @property')
247
+ self._append_main_init_code(' def VARS(self):')
248
+ self._append_main_init_code(' return self._vars\n')
249
+ # define property: self.FUNCS -> self._funcs
250
+ self._append_main_init_code(' @property')
251
+ self._append_main_init_code(' def FUNCS(self):')
252
+ self._append_main_init_code(' return self._funcs\n')
253
+
254
+ def __define_callback_thread_func(self):
255
+ # Define callback thread function
256
+ if len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks) or len(self._count_callbacks) or len(self._holding_callbacks):
257
+ self._append_main_init_code(' def _event_callback_handle_thread(self):')
258
+ self._append_main_init_code(' while self.alive:')
259
+ self._append_main_init_code(' try:')
260
+ self._append_main_init_code(' callback = self._callback_que.get(timeout=1)')
261
+ self._append_main_init_code(' callback() if not self._callback_in_thread else threading.Thread(target=callback, daemon=True).start()')
262
+ self._append_main_init_code(' except queue.Empty:')
263
+ self._append_main_init_code(' pass')
264
+ self._append_main_init_code(' except Exception as e:')
265
+ self._append_main_init_code(' self.pprint(e)\n')
266
+
267
+ def __define_listen_gpio_thread_func(self):
268
+ # Define listen gpio thread function
269
+ if self._listen_tgpio_digital or self._listen_tgpio_analog or self._listen_cgpio_state \
270
+ or len(self._tgpio_digital_callbacks) or len(self._tgpio_analog_callbacks) or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks):
271
+
272
+ self._append_main_init_code(' def _listen_gpio_thread(self):')
273
+ if self._listen_tgpio_digital or len(self._tgpio_digital_callbacks):
274
+ self._append_main_init_code(' _, values2 = self._arm.get_tgpio_digital(2)')
275
+ self._append_main_init_code(' _, values = self._arm.get_tgpio_digital()')
276
+ self._append_main_init_code(' values.insert(2, values2)')
277
+ self._append_main_init_code(' tgpio_digitals = values if _ == 0 else [0] * 5')
278
+ if self._listen_tgpio_analog or len(self._tgpio_analog_callbacks):
279
+ self._append_main_init_code(' _, values = self._arm.get_tgpio_analog()')
280
+ self._append_main_init_code(' tgpio_analogs = values if _ == 0 else [0] * 2')
281
+ if self._listen_cgpio_state or len(self._cgpio_digital_callbacks) or len(self._cgpio_analog_callbacks):
282
+ self._append_main_init_code(' _, values = self._arm.get_cgpio_state()')
283
+ if self._listen_cgpio_state or len(self._cgpio_digital_callbacks):
284
+ self._append_main_init_code(' cgpio_digitals = [values[3] >> i & 0x0001 if values[10][i] in [0, 255] else 1 for i in range(len(values[10]))] if _ == 0 else [0] * 16')
285
+ if self._listen_cgpio_state or len(self._cgpio_analog_callbacks):
286
+ self._append_main_init_code(' cgpio_analogs = [values[6], values[7]] if _ == 0 else [0] * 2')
287
+
288
+ self._append_main_init_code(' while self.alive:')
289
+ if self._listen_tgpio_digital or len(self._tgpio_digital_callbacks):
290
+ self._append_main_init_code(' _, values2 = self._arm.get_tgpio_digital(2)')
291
+ self._append_main_init_code(' _, values = self._arm.get_tgpio_digital()')
292
+ self._append_main_init_code(' values.insert(2, values2)')
293
+ self._append_main_init_code(' if _ == 0 and tgpio_digitals is not None:')
294
+ self._append_main_init_code(' for item in self._tgpio_digital_callbacks:')
295
+ self._append_main_init_code(' for io in range(5):')
296
+ self._append_main_init_code(' if item[\'io\'] == io and eval(\'{} {} {}\'.format(values[io], item[\'op\'], item[\'trigger\'])) and not eval(\'{} {} {}\'.format(tgpio_digitals[io], item[\'op\'], item[\'trigger\'])):')
297
+ self._append_main_init_code(' self._callback_que.put(item[\'callback\'])')
298
+ self._append_main_init_code(' tgpio_digitals = values if _ == 0 else tgpio_digitals')
299
+ if self._listen_tgpio_digital or len(self._tgpio_analog_callbacks):
300
+ self._append_main_init_code(' _, values = self._arm.get_tgpio_analog()')
301
+ self._append_main_init_code(' if _ == 0 and tgpio_analogs is not None:')
302
+ self._append_main_init_code(' for item in self._tgpio_analog_callbacks:')
303
+ self._append_main_init_code(' for io in range(2):')
304
+ self._append_main_init_code(' if item[\'io\'] == io and eval(\'{} {} {}\'.format(values[io], item[\'op\'], item[\'trigger\'])) and not eval(\'{} {} {}\'.format(tgpio_analogs[io], item[\'op\'], item[\'trigger\'])):')
305
+ self._append_main_init_code(' self._callback_que.put(item[\'callback\'])')
306
+ self._append_main_init_code(' tgpio_analogs = values if _ == 0 else tgpio_analogs')
307
+
308
+ if not self._listen_cgpio_state and len(self._cgpio_digital_callbacks) == 0 and len(self._cgpio_analog_callbacks) == 0:
309
+ self._append_main_init_code(' time.sleep(0.01)\n')
310
+ return
311
+
312
+ self._append_main_init_code(' _, values = self._arm.get_cgpio_state()')
313
+ self._append_main_init_code(' if _ == 0 and self._cgpio_state is not None and self._cgpio_state != values:')
314
+ if self._listen_cgpio_state or len(self._cgpio_digital_callbacks):
315
+ self._append_main_init_code(' digitals = [values[3] >> i & 0x0001 if values[10][i] in [0, 255] else 1 for i in range(len(values[10]))]')
316
+ self._append_main_init_code(' for item in self._cgpio_digital_callbacks:')
317
+ self._append_main_init_code(' for io in range(len(digitals)):')
318
+ self._append_main_init_code(' if item[\'io\'] == io and eval(\'{} {} {}\'.format(digitals[io], item[\'op\'], item[\'trigger\'])) and not eval(\'{} {} {}\'.format(cgpio_digitals[io], item[\'op\'], item[\'trigger\'])):')
319
+ self._append_main_init_code(' self._callback_que.put(item[\'callback\'])')
320
+ self._append_main_init_code(' cgpio_digitals = digitals')
321
+ if self._listen_cgpio_state or len(self._cgpio_analog_callbacks):
322
+ self._append_main_init_code(' analogs = [values[6], values[7]]')
323
+ self._append_main_init_code(' for item in self._cgpio_analog_callbacks:')
324
+ self._append_main_init_code(' for io in range(len(analogs)):')
325
+ self._append_main_init_code(' if item[\'io\'] == io and eval(\'{} {} {}\'.format(analogs[io], item[\'op\'], item[\'trigger\'])) and not eval(\'{} {} {}\'.format(cgpio_analogs[io], item[\'op\'], item[\'trigger\'])):')
326
+ self._append_main_init_code(' self._callback_que.put(item[\'callback\'])')
327
+ self._append_main_init_code(' cgpio_analogs = analogs')
328
+ self._append_main_init_code(' self._cgpio_state = values if _ == 0 else self._cgpio_state')
329
+ self._append_main_init_code(' time.sleep(0.01)\n')
330
+
331
+ def __define_listen_count_thread_func(self):
332
+ # Define listen counter value thread function
333
+ if self._listen_count or len(self._count_callbacks):
334
+ self._append_main_init_code(' def _listen_count_thread(self):')
335
+ if self._listen_count or len(self._count_callbacks):
336
+ self._append_main_init_code(' values = self._arm.count')
337
+
338
+ self._append_main_init_code(' while self.alive:')
339
+
340
+ self._append_main_init_code(' values = self._arm.count')
341
+ self._append_main_init_code(
342
+ ' if self._counter_val is not None and self._counter_val != values:')
343
+ if self._listen_count or len(self._count_callbacks):
344
+ self._append_main_init_code(' for item in self._count_callbacks:')
345
+ self._append_main_init_code(
346
+ ' if eval(\'{} {} {}\'.format(values, item[\'op\'], item[\'trigger\'])) and not eval(\'{} {} {}\'.format(self._counter_val, item[\'op\'], item[\'trigger\'])):')
347
+ self._append_main_init_code(' self._callback_que.put(item[\'callback\'])')
348
+ self._append_main_init_code(' self._counter_val = values')
349
+ self._append_main_init_code(' time.sleep(0.01)\n')
350
+
351
+ def __define_listen_holding_registers_thread_func(self):
352
+ # Define listen holding registers value thread function
353
+ if self._listen_holding or len(self._holding_callbacks):
354
+ self._append_main_init_code(' def _listen_holding_thread(self):')
355
+
356
+ self._append_main_init_code(' while self.alive:')
357
+ self._append_main_init_code(' for index, item in enumerate(self._holding_callbacks):')
358
+ self._append_main_init_code(' for i in range(2):')
359
+ self._append_main_init_code(' _, values = self._arm.read_holding_registers(int(item[\'addr\']), 1)')
360
+ self._append_main_init_code(
361
+ ' if _ == 0 and self._holding_dict.get(index, None) is not None:')
362
+ self._append_main_init_code(
363
+ ' if eval(\'{} == {}\'.format(values[0], item[\'trigger\'])) and not eval(\'{} == {}\'.format(self._holding_dict[index], item[\'trigger\'])):')
364
+ self._append_main_init_code(' self._callback_que.put(item[\'callback\'])')
365
+ self._append_main_init_code(' self._holding_dict[index] = values[0] if _ == 0 else self._holding_dict.get(index, None)')
366
+ self._append_main_init_code(' time.sleep(0.01)\n')
367
+
368
+ def __define_run_blockly_func(self):
369
+ if self._is_run_blockly and not self._is_exec:
370
+ self._append_main_init_code(' def _start_run_blockly(self, fileName, times):')
371
+ self._append_main_init_code(' for i in range(times):')
372
+ self._append_main_init_code(' code = self._arm.run_blockly_app(fileName, init=False, is_exec=True, axis_type=[self._arm.axis, self._arm.device_type])\n')
373
+
374
+ def __define_robot_init_func(self, init=True, wait_seconds=1, mode=0, state=0, error_exit=True, stop_exit=True):
375
+ # Define XArm Init Function:
376
+ self._append_main_init_code(' # Robot init')
377
+ self._append_main_init_code(' def _robot_init(self):')
378
+ if init:
379
+ self._append_main_init_code(' self._arm.clean_warn()')
380
+ self._append_main_init_code(' self._arm.clean_error()')
381
+ self._append_main_init_code(' self._arm.motion_enable(True)')
382
+ self._append_main_init_code(' self._arm.set_mode({})'.format(mode))
383
+ self._append_main_init_code(' self._arm.set_state({})'.format(state))
384
+ if wait_seconds > 0:
385
+ self._append_main_init_code(' time.sleep({})'.format(wait_seconds))
386
+ if error_exit:
387
+ self._append_main_init_code(' self._arm.register_error_warn_changed_callback(self._error_warn_changed_callback)')
388
+ if stop_exit:
389
+ self._append_main_init_code(' self._arm.register_state_changed_callback(self._state_changed_callback)')
390
+ if self._listen_counter:
391
+ self._append_main_init_code(' if hasattr(self._arm, \'register_count_changed_callback\'):')
392
+ self._append_main_init_code(' self._arm.register_count_changed_callback(self._count_changed_callback)')
393
+ self._append_main_init_code('')
394
+
395
+ def __define_error_warn_changed_callback_func(self, error_exit=True):
396
+ # Define error/warn changed callback
397
+ if error_exit:
398
+ self._append_main_init_code(' # Register error/warn changed callback')
399
+ self._append_main_init_code(' def _error_warn_changed_callback(self, data):')
400
+ self._append_main_init_code(' if data and data[\'error_code\'] != 0:')
401
+ self._append_main_init_code(' self.alive = False')
402
+ self._append_main_init_code(' self.pprint(\'err={}, quit\'.format(data[\'error_code\']))')
403
+ if self.is_run_linear_track:
404
+ self._append_main_init_code(' self._arm.set_linear_track_stop()')
405
+ self._append_main_init_code(' self._arm.release_error_warn_changed_callback(self._error_warn_changed_callback)\n')
406
+
407
+ def __define_state_changed_callback_func(self, stop_exit=True):
408
+ # Define state changed callback
409
+ if stop_exit:
410
+ self._append_main_init_code(' # Register state changed callback')
411
+ self._append_main_init_code(' def _state_changed_callback(self, data):')
412
+ self._append_main_init_code(' if not self._ignore_exit_state and data and data[\'state\'] == 4:')
413
+ self._append_main_init_code(' self.alive = False')
414
+ self._append_main_init_code(' self.pprint(\'state=4, quit\')')
415
+ self._append_main_init_code(' self._arm.release_state_changed_callback(self._state_changed_callback)\n')
416
+
417
+ def __define_count_changed_callback_func(self):
418
+ # Define count changed callback
419
+ if self._listen_counter:
420
+ self._append_main_init_code(' # Register count changed callback')
421
+ self._append_main_init_code(' def _count_changed_callback(self, data):')
422
+ self._append_main_init_code(' if self.is_alive:')
423
+ self._append_main_init_code(' self.pprint(\'counter val: {}\'.format(data[\'count\']))\n')
424
+
425
+ def __define_pprint_func(self):
426
+ self._append_main_init_code(' @staticmethod')
427
+ self._append_main_init_code(' def pprint(*args, **kwargs):')
428
+ self._append_main_init_code(' try:')
429
+ self._append_main_init_code(' stack_tuple = traceback.extract_stack(limit=2)[0]')
430
+ self._append_main_init_code(' print(\'[{}][{}] {}\'.format('
431
+ 'time.strftime(\'%Y-%m-%d %H:%M:%S\', time.localtime(time.time())), '
432
+ 'stack_tuple[1], \' \'.join(map(str, args))))')
433
+ self._append_main_init_code(' except:')
434
+ self._append_main_init_code(' print(*args, **kwargs)\n')
435
+
436
+ def __define_is_alive_property(self):
437
+ self._append_main_init_code(' @property')
438
+ self._append_main_init_code(' def is_alive(self):')
439
+ self._append_main_init_code(' if self.alive and self._arm.connected and self._arm.error_code == 0:')
440
+ self._append_main_init_code(' if self._ignore_exit_state:')
441
+ self._append_main_init_code(' return True')
442
+ self._append_main_init_code(' if self._arm.state == 5:')
443
+ self._append_main_init_code(' cnt = 0')
444
+ self._append_main_init_code(' while self._arm.state == 5 and cnt < 5:')
445
+ self._append_main_init_code(' cnt += 1')
446
+ self._append_main_init_code(' time.sleep(0.1)')
447
+ self._append_main_init_code(' return self._arm.state < 4')
448
+ self._append_main_init_code(' else:')
449
+ self._append_main_init_code(' return False\n')
450
+ # self._append_main_init_code(' return self.alive and self._arm.connected and self._arm.error_code == 0 and self._arm.state < 4\n')
451
+
452
+ def __define_check_code_func(self):
453
+ self._append_main_init_code(' def _check_code(self, code, label):')
454
+ self._append_main_init_code(' if not self.is_alive or code != 0:')
455
+ self._append_main_init_code(' self.alive = False')
456
+ # self._append_main_init_code(' self.pprint(\'{{}}, code={{}}, connected={{}}, state={{}}, error={{}}\'.format(label, code, self._arm.connected, self._arm.state, self._arm.error_code))')
457
+ self._append_main_init_code(' ret1 = self._arm.get_state()')
458
+ self._append_main_init_code(' ret2 = self._arm.get_err_warn_code()')
459
+ self._append_main_init_code(' self.pprint(\'{}, code={}, connected={}, state={}, error={}, ret1={}. ret2={}\'.format(label, code, self._arm.connected, self._arm.state, self._arm.error_code, ret1, ret2))')
460
+ self._append_main_init_code(' return self.is_alive\n')
461
+
462
+ def _init_main_codes(self, arm=None):
463
+ # exec can not run main function, if run in exec(), the parameter is_ide must set False
464
+ self._append_main_code('\n', indent=-1)
465
+ if self._is_ide:
466
+ self._append_main_code('if __name__ == \'__main__\':', indent=-1)
467
+ indent = 0
468
+ else:
469
+ indent = -1
470
+ self._append_main_code('RobotMain.pprint(\'xArm-Python-SDK Version:{}\'.format(version.__version__))', indent=indent)
471
+ if arm is None:
472
+ self._append_main_code('arm = XArmAPI(sys.argv[1], baud_checkset=False)', indent=indent)
473
+ self._append_main_code('time.sleep(0.5)', indent=indent)
474
+ elif isinstance(arm, str):
475
+ self._append_main_code('arm = XArmAPI(\'{}\', baud_checkset=False)'.format(arm), indent=indent)
476
+ self._append_main_code('time.sleep(0.5)', indent=indent)
477
+
478
+ self._append_main_code('robot_main = RobotMain(arm)', indent=indent)
479
+ self._append_main_code('robot_main.run()', indent=indent)
480
+ self._append_main_code('', indent=-1)