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
|
@@ -0,0 +1,416 @@
|
|
|
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 re
|
|
10
|
+
from ._blockly_node import _BlocklyNode
|
|
11
|
+
|
|
12
|
+
OPS_MAP = {
|
|
13
|
+
'EQ': '==',
|
|
14
|
+
'NEQ': '!=',
|
|
15
|
+
'LT': '<',
|
|
16
|
+
'LTE': '<=',
|
|
17
|
+
'GT': '>',
|
|
18
|
+
'GTE': '>=',
|
|
19
|
+
'===': '==',
|
|
20
|
+
'!==': '!=',
|
|
21
|
+
'>=': '>=',
|
|
22
|
+
'>': '>',
|
|
23
|
+
'<=': '<=',
|
|
24
|
+
'<': '<',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class _BlocklyBase(_BlocklyNode):
|
|
29
|
+
def __init__(self, xml_path):
|
|
30
|
+
super(_BlocklyBase, self).__init__(xml_path)
|
|
31
|
+
self._funcs = {}
|
|
32
|
+
self._define_is_prime_func = False
|
|
33
|
+
self._define_bin_matchs_func = False
|
|
34
|
+
self._vacuum_version = '1'
|
|
35
|
+
|
|
36
|
+
def _get_field_value(self, block):
|
|
37
|
+
field = self._get_node('field', root=block)
|
|
38
|
+
if field is not None:
|
|
39
|
+
return field.text
|
|
40
|
+
else:
|
|
41
|
+
return self._get_nodes('field', root=self._get_node('value', root=block), descendant=True)[0].text
|
|
42
|
+
|
|
43
|
+
def _get_block_val(self, block, arg_map=None):
|
|
44
|
+
block_v = self._get_node('block', root=block)
|
|
45
|
+
if block_v is not None:
|
|
46
|
+
val = self._get_condition_expression(block, arg_map=arg_map)
|
|
47
|
+
else:
|
|
48
|
+
shadow = self._get_node('shadow', root=block)
|
|
49
|
+
val = self._get_node('field', root=shadow).text
|
|
50
|
+
return val
|
|
51
|
+
|
|
52
|
+
def _get_condition_expression(self, value_block, arg_map=None):
|
|
53
|
+
block = self._get_node('block', value_block)
|
|
54
|
+
if block is None:
|
|
55
|
+
shadow = self._get_node('shadow', root=value_block)
|
|
56
|
+
return self._get_node('field', root=shadow).text
|
|
57
|
+
if block.attrib['type'] == 'logic_boolean':
|
|
58
|
+
return str(self._get_node('field', block).text == 'TRUE')
|
|
59
|
+
elif block.attrib['type'] == 'logic_compare':
|
|
60
|
+
return self.__get_logic_compare(block, arg_map=arg_map)
|
|
61
|
+
elif block.attrib['type'] == 'logic_operation':
|
|
62
|
+
return self.__get_logic_operation(block, arg_map=arg_map)
|
|
63
|
+
elif block.attrib['type'] == 'logic_negate':
|
|
64
|
+
value = self._get_node('value', root=block)
|
|
65
|
+
return 'not ({})'.format(self._get_condition_expression(value, arg_map=arg_map))
|
|
66
|
+
elif block.attrib['type'] == 'gpio_get_digital':
|
|
67
|
+
io = self._get_node('field', block).text
|
|
68
|
+
return 'self._arm.get_tgpio_digital({})[{}]'.format(io, 1)
|
|
69
|
+
elif block.attrib['type'] == 'gpio_get_analog':
|
|
70
|
+
io = self._get_node('field', block).text
|
|
71
|
+
return 'self._arm.get_tgpio_analog({})[{}]'.format(io, 1)
|
|
72
|
+
elif block.attrib['type'] == 'gpio_get_controller_digital':
|
|
73
|
+
io = self._get_node('field', block).text
|
|
74
|
+
return 'self._arm.get_cgpio_digital({})[{}]'.format(io, 1)
|
|
75
|
+
elif block.attrib['type'] == 'gpio_get_controller_digital_di':
|
|
76
|
+
io = self._get_node('field', block).text
|
|
77
|
+
return 'self._arm.get_cgpio_digital({})[{}]'.format(io, 1)
|
|
78
|
+
elif block.attrib['type'] == 'gpio_get_controller_analog':
|
|
79
|
+
io = self._get_node('field', block).text
|
|
80
|
+
return 'self._arm.get_cgpio_analog({})[{}]'.format(io, 1)
|
|
81
|
+
elif block.attrib['type'] == 'gpio_get_ci':
|
|
82
|
+
io = self._get_node('field', block).text
|
|
83
|
+
return '1 if self._cgpio_state is None else self._cgpio_state[3] >> {} & 0x0001'.format(io)
|
|
84
|
+
elif block.attrib['type'] == 'gpio_get_co':
|
|
85
|
+
io = self._get_node('field', block).text
|
|
86
|
+
return '0 if self._cgpio_state is None else self._cgpio_state[5] >> {} & 0x0001'.format(io)
|
|
87
|
+
elif block.attrib['type'] == 'gpio_get_ai':
|
|
88
|
+
io = self._get_node('field', block).text
|
|
89
|
+
return '0 if self._cgpio_state is None else self._cgpio_state[6 + {}]'.format(io)
|
|
90
|
+
elif block.attrib['type'] == 'gpio_get_ao':
|
|
91
|
+
io = self._get_node('field', block).text
|
|
92
|
+
return '0 if self._cgpio_state is None else self._cgpio_state[8 + {}]'.format(io)
|
|
93
|
+
elif block.attrib['type'] == 'gpio_match_controller_digitals_bin':
|
|
94
|
+
bin_val = self._get_node('field', block).text
|
|
95
|
+
self._define_bin_matchs_func = True
|
|
96
|
+
return 'self._cgpio_digitals_is_matchs_bin(\'{}\')'.format(bin_val)
|
|
97
|
+
elif block.attrib['type'] == 'get_suction_cup':
|
|
98
|
+
return 'self._arm.get_suction_cup(hardware_version={})[{}]'.format(self._vacuum_version, 1)
|
|
99
|
+
elif block.attrib['type'] == 'check_air_pump_state':
|
|
100
|
+
fields = self._get_nodes('field', root=block)
|
|
101
|
+
state = 1 if fields[0].text == 'ON' else 0
|
|
102
|
+
timeout = float(fields[1].text)
|
|
103
|
+
return 'self._arm.arm.check_air_pump_state({}, timeout={}, hardware_version={})'.format(state, timeout,
|
|
104
|
+
self._vacuum_version)
|
|
105
|
+
elif block.attrib['type'] == 'check_bio_gripper_is_catch':
|
|
106
|
+
fields = self._get_nodes('field', root=block)
|
|
107
|
+
timeout = float(fields[0].text)
|
|
108
|
+
return 'self._arm.arm.check_bio_gripper_is_catch(timeout={})'.format(timeout)
|
|
109
|
+
elif block.attrib['type'] == 'check_robotiq_is_catch':
|
|
110
|
+
fields = self._get_nodes('field', root=block)
|
|
111
|
+
timeout = float(fields[0].text)
|
|
112
|
+
return 'self._arm.arm.check_robotiq_is_catch(timeout={})'.format(timeout)
|
|
113
|
+
elif block.attrib['type'] == 'math_number':
|
|
114
|
+
val = self._get_node('field', block).text
|
|
115
|
+
return val
|
|
116
|
+
elif block.attrib['type'] == 'math_arithmetic':
|
|
117
|
+
return self.__get_math_arithmetic(block, arg_map=arg_map)
|
|
118
|
+
elif block.attrib['type'] == 'math_number_property':
|
|
119
|
+
return self.__get_math_number_property(block, arg_map=arg_map)
|
|
120
|
+
elif block.attrib['type'] == 'math_random_int':
|
|
121
|
+
return self.__get_math_random_int(block, arg_map=arg_map)
|
|
122
|
+
elif block.attrib['type'] == 'math_round':
|
|
123
|
+
return self.__get_math_round(block, arg_map=arg_map)
|
|
124
|
+
elif block.attrib['type'] == 'math_single':
|
|
125
|
+
# 算术函数
|
|
126
|
+
return self.__get_math_single(block, arg_map=arg_map)
|
|
127
|
+
elif block.attrib['type'] == 'math_trig':
|
|
128
|
+
# 三角函数
|
|
129
|
+
return self.__get_math_trig(block, arg_map=arg_map)
|
|
130
|
+
elif block.attrib['type'] == 'math_constant':
|
|
131
|
+
# 常量
|
|
132
|
+
return self.__get_math_constant(block, arg_map=arg_map)
|
|
133
|
+
elif block.attrib['type'] == 'math_modulo':
|
|
134
|
+
return self.__get_math_modulo(block, arg_map=arg_map)
|
|
135
|
+
elif block.attrib['type'] == 'math_constrain':
|
|
136
|
+
return self.__get_math_constrain(block, arg_map=arg_map)
|
|
137
|
+
elif block.attrib['type'] == 'variables_get':
|
|
138
|
+
field = self._get_node('field', block).text
|
|
139
|
+
if arg_map and field in arg_map:
|
|
140
|
+
return '{}'.format(arg_map[field])
|
|
141
|
+
else:
|
|
142
|
+
return 'self._vars.get(\'{}\', 0)'.format(field)
|
|
143
|
+
elif block.attrib['type'] == 'move_var':
|
|
144
|
+
val = self._get_node('field', block).text
|
|
145
|
+
return val
|
|
146
|
+
elif block.attrib['type'] == 'tool_get_date':
|
|
147
|
+
return 'datetime.datetime.now()'
|
|
148
|
+
elif block.attrib['type'] == 'tool_combination':
|
|
149
|
+
field = self._get_node('field', block).text
|
|
150
|
+
values = self._get_nodes('value', block)
|
|
151
|
+
var1 = self._get_condition_expression(values[0], arg_map=arg_map)
|
|
152
|
+
var2 = self._get_condition_expression(values[1], arg_map=arg_map)
|
|
153
|
+
return '\'{{}}{{}}{{}}\'.format({}, \'{}\', {})'.format(var1, field, var2)
|
|
154
|
+
elif block.attrib['type'] == 'procedures_callreturn':
|
|
155
|
+
mutation = self._get_node('mutation', block).attrib['name']
|
|
156
|
+
if not mutation:
|
|
157
|
+
mutation = '1'
|
|
158
|
+
if mutation in self._funcs:
|
|
159
|
+
name = self._funcs[mutation]
|
|
160
|
+
else:
|
|
161
|
+
name = 'function_{}'.format(len(self._funcs) + 1)
|
|
162
|
+
|
|
163
|
+
args = self._get_nodes('arg', root=self._get_node('mutation', block))
|
|
164
|
+
values = self._get_nodes('value', root=block)
|
|
165
|
+
if args and values and len(args) == len(values):
|
|
166
|
+
return 'self.{}({})'.format(name, ','.join(
|
|
167
|
+
[self._get_condition_expression(val, arg_map=arg_map) for val in values]))
|
|
168
|
+
else:
|
|
169
|
+
return 'self.{}()'.format(name)
|
|
170
|
+
elif block.attrib['type'] == 'python_expression':
|
|
171
|
+
ret = self._get_node('field', block).text
|
|
172
|
+
return ret
|
|
173
|
+
elif block.attrib['type'] == 'gpio_get_controller_ci_li':
|
|
174
|
+
fields = self._get_nodes('field', root=block)
|
|
175
|
+
values = []
|
|
176
|
+
for field in fields[:-1]:
|
|
177
|
+
values.append(int(field.text))
|
|
178
|
+
timeout = float(fields[-1].text)
|
|
179
|
+
return 'self._arm.arm.get_cgpio_li_state({}, timeout={}, is_ci=True)'.format(values, timeout)
|
|
180
|
+
elif block.attrib['type'] == 'gpio_get_controller_di_li':
|
|
181
|
+
fields = self._get_nodes('field', root=block)
|
|
182
|
+
values = []
|
|
183
|
+
for field in fields[:-1]:
|
|
184
|
+
values.append(int(field.text))
|
|
185
|
+
timeout = float(fields[-1].text)
|
|
186
|
+
return 'self._arm.arm.get_cgpio_li_state({}, timeout={}, is_ci=False)'.format(values, timeout)
|
|
187
|
+
elif block.attrib['type'] == 'gpio_get_tgpio_li':
|
|
188
|
+
fields = self._get_nodes('field', root=block)
|
|
189
|
+
values = []
|
|
190
|
+
for field in fields[:-1]:
|
|
191
|
+
values.append(int(field.text))
|
|
192
|
+
timeout = float(fields[-1].text)
|
|
193
|
+
return 'self._arm.arm.get_tgpio_li_state({}, timeout={})'.format(values, timeout)
|
|
194
|
+
elif block.attrib['type'] == 'get_modbus_rtu':
|
|
195
|
+
fields = self._get_nodes('field', root=block)
|
|
196
|
+
host_id = fields[0].text
|
|
197
|
+
cmd = fields[1].text
|
|
198
|
+
cmd_li = re.sub(',', ' ', cmd)
|
|
199
|
+
is_run_cmd = ''.join(cmd_li.split()).isalnum()
|
|
200
|
+
if not is_run_cmd:
|
|
201
|
+
self._append_main_code('-1', indent + 2)
|
|
202
|
+
cmd_li = re.sub(' +', ' ', cmd_li)
|
|
203
|
+
cmd_li = re.sub('\xa0', ' ', cmd_li)
|
|
204
|
+
cmd_li = re.sub('\s+', ' ', cmd_li)
|
|
205
|
+
cmd_li = cmd_li.strip().split(' ')
|
|
206
|
+
int_li = [int(da, 16) for da in cmd_li]
|
|
207
|
+
return '[" ".join([hex(da).split("0x")[1].upper().zfill(2) for da in data]) if isinstance(data, list) else data for ' \
|
|
208
|
+
'data in self._arm.getset_tgpio_modbus_data({}, host_id={})][-1]'.format(int_li, host_id)
|
|
209
|
+
elif block.attrib['type'] == 'get_gripper_status':
|
|
210
|
+
fields = self._get_nodes('field', root=block)
|
|
211
|
+
timeout = fields[0].text
|
|
212
|
+
return '0 == self._arm.arm.check_catch_gripper_status({})'.format(timeout)
|
|
213
|
+
elif block.attrib['type'] == 'get_ft_sensor':
|
|
214
|
+
direction_li = ['Fx', 'Fy', 'Fz', 'Tx', 'Ty', 'Tz']
|
|
215
|
+
fields = self._get_nodes('field', root=block)
|
|
216
|
+
direction = fields[0].text
|
|
217
|
+
return '[self._arm.ft_sensor_enable(1), self._arm.set_state(0), self._arm.get_ft_sensor_data()[1][{}]][2] if' \
|
|
218
|
+
' self._arm.get_ft_sensor_config()[1][1] == 0 else self._arm.get_ft_sensor_data()[1][{}]'.\
|
|
219
|
+
format(direction_li.index(direction), direction_li.index(direction))
|
|
220
|
+
elif block.attrib['type'] == 'get_counter':
|
|
221
|
+
return 'self._arm.count'
|
|
222
|
+
elif block.attrib['type'] == 'get_single_holding_register':
|
|
223
|
+
fields = self._get_nodes('field', root=block)
|
|
224
|
+
addr = int(fields[0].text.replace(' ', '').replace('0x', '').replace(',', '').replace('\xa0', ''), 16)
|
|
225
|
+
return "list(map(lambda x: hex(x).split('0x')[1].upper().zfill(4)[:2] + ' ' + hex(x).split('0x')[1]." \
|
|
226
|
+
"upper().zfill(4)[2:], self._arm.read_holding_registers({}, 1)[1]))[0]".format(str(addr))
|
|
227
|
+
elif block.attrib['type'] == 'get_position':
|
|
228
|
+
direction_li = ['X', 'Y', 'Z', 'R', 'P', 'Y']
|
|
229
|
+
fields = self._get_nodes('field', root=block)
|
|
230
|
+
is_axis = True if fields[0].text == 'axis' else False
|
|
231
|
+
direction = int(fields[1].text)
|
|
232
|
+
if is_axis:
|
|
233
|
+
return 'round(self._arm.get_position_aa()[1][{}], 2)'.format(direction-1)
|
|
234
|
+
else:
|
|
235
|
+
return 'round(self._arm.get_position()[1][{}], 2)'.format(direction-1)
|
|
236
|
+
elif block.attrib['type'] == 'get_joint_angle':
|
|
237
|
+
angle_li = ['J1', 'J2', 'J3', 'J4', 'J5', 'J6']
|
|
238
|
+
fields = self._get_nodes('field', root=block)
|
|
239
|
+
servo_angle = fields[0].text
|
|
240
|
+
return 'round(self._arm.get_servo_angle(servo_id={})[1], 2)'.format(servo_angle)
|
|
241
|
+
elif block.attrib['type'] == 'check_bio_g2_gripper_is_catch':
|
|
242
|
+
fields = self._get_nodes('field', root=block)
|
|
243
|
+
timeout = float(fields[0].text)
|
|
244
|
+
return 'self._arm.arm.check_bio_gripper_is_catch(timeout={})'.format(timeout)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def __get_logic_compare(self, block, arg_map=None):
|
|
248
|
+
op = OPS_MAP.get(self._get_node('field', block).text)
|
|
249
|
+
cond_a = 0
|
|
250
|
+
cond_b = 0
|
|
251
|
+
values = self._get_nodes('value', block)
|
|
252
|
+
if len(values) > 0:
|
|
253
|
+
cond_a = self._get_condition_expression(values[0], arg_map=arg_map)
|
|
254
|
+
if len(values) > 1:
|
|
255
|
+
cond_b = self._get_condition_expression(values[1], arg_map=arg_map)
|
|
256
|
+
return '({}) {} ({})'.format(cond_a, op, cond_b)
|
|
257
|
+
|
|
258
|
+
def __get_logic_operation(self, block, arg_map=None):
|
|
259
|
+
op = self._get_node('field', block).text.lower()
|
|
260
|
+
cond_a = False
|
|
261
|
+
cond_b = False
|
|
262
|
+
values = self._get_nodes('value', block)
|
|
263
|
+
if len(values) > 0:
|
|
264
|
+
cond_a = self._get_condition_expression(values[0], arg_map=arg_map)
|
|
265
|
+
if len(values) > 1:
|
|
266
|
+
cond_b = self._get_condition_expression(values[1], arg_map=arg_map)
|
|
267
|
+
return '({}) {} ({})'.format(cond_a, op, cond_b)
|
|
268
|
+
|
|
269
|
+
def __get_math_arithmetic(self, block, arg_map=None):
|
|
270
|
+
field = self._get_node('field', block).text
|
|
271
|
+
values = self._get_nodes('value', block)
|
|
272
|
+
if len(values) > 1:
|
|
273
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
274
|
+
val_b = self._get_block_val(values[1], arg_map=arg_map)
|
|
275
|
+
if field == 'ADD':
|
|
276
|
+
return '({} + {})'.format(val_a, val_b)
|
|
277
|
+
elif field == 'MINUS':
|
|
278
|
+
return '({} - {})'.format(val_a, val_b)
|
|
279
|
+
elif field == 'MULTIPLY':
|
|
280
|
+
return '({} * {})'.format(val_a, val_b)
|
|
281
|
+
elif field == 'DIVIDE':
|
|
282
|
+
return '({} / {})'.format(val_a, val_b)
|
|
283
|
+
elif field == 'POWER':
|
|
284
|
+
return 'pow({}, {})'.format(val_a, val_b)
|
|
285
|
+
|
|
286
|
+
def __get_math_number_property(self, block, arg_map=None):
|
|
287
|
+
field = self._get_node('field', block).text
|
|
288
|
+
values = self._get_nodes('value', block)
|
|
289
|
+
if len(values) >= 1:
|
|
290
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
291
|
+
|
|
292
|
+
if field == 'EVEN':
|
|
293
|
+
# 偶数
|
|
294
|
+
return '{} % 2 == 0'.format(val_a)
|
|
295
|
+
elif field == 'ODD':
|
|
296
|
+
# 奇数
|
|
297
|
+
return '{} % 2 == 1'.format(val_a)
|
|
298
|
+
elif field == 'PRIME':
|
|
299
|
+
# 质数
|
|
300
|
+
self._define_is_prime_func = True
|
|
301
|
+
return 'self.is_prime({})'.format(val_a)
|
|
302
|
+
elif field == 'WHOLE':
|
|
303
|
+
# 整数
|
|
304
|
+
return '{} % 1 == 0'.format(val_a)
|
|
305
|
+
elif field == 'POSITIVE':
|
|
306
|
+
# 正数
|
|
307
|
+
return '{} > 0'.format(val_a)
|
|
308
|
+
elif field == 'NEGATIVE':
|
|
309
|
+
# 负数
|
|
310
|
+
return '{} < 0'.format(val_a)
|
|
311
|
+
elif field == 'DIVISIBLE_BY':
|
|
312
|
+
# 可被整除
|
|
313
|
+
if len(values) > 1:
|
|
314
|
+
val_b = self._get_block_val(values[1], arg_map=arg_map)
|
|
315
|
+
else:
|
|
316
|
+
val_b = 0
|
|
317
|
+
return '{} % {} == 0'.format(val_a, val_b)
|
|
318
|
+
|
|
319
|
+
def __get_math_random_int(self, block, arg_map=None):
|
|
320
|
+
values = self._get_nodes('value', block)
|
|
321
|
+
if len(values) > 1:
|
|
322
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
323
|
+
val_b = self._get_block_val(values[1], arg_map=arg_map)
|
|
324
|
+
return 'random.randint({}, {})'.format(val_a, val_b)
|
|
325
|
+
|
|
326
|
+
def __get_math_round(self, block, arg_map=None):
|
|
327
|
+
field = self._get_node('field', block).text
|
|
328
|
+
values = self._get_nodes('value', block)
|
|
329
|
+
if len(values) >= 1:
|
|
330
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
331
|
+
if field == 'ROUND':
|
|
332
|
+
# 四舍五入
|
|
333
|
+
return 'round({})'.format(val_a)
|
|
334
|
+
elif field == 'ROUNDUP':
|
|
335
|
+
# 上舍入
|
|
336
|
+
return 'math.ceil({})'.format(val_a)
|
|
337
|
+
elif field == 'ROUNDDOWN':
|
|
338
|
+
# 下舍入
|
|
339
|
+
return 'math.floor({})'.format(val_a)
|
|
340
|
+
|
|
341
|
+
def __get_math_single(self, block, arg_map=None):
|
|
342
|
+
# 算术函数
|
|
343
|
+
field = self._get_node('field', block).text
|
|
344
|
+
values = self._get_nodes('value', block)
|
|
345
|
+
if len(values) >= 1:
|
|
346
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
347
|
+
if field == 'ROOT':
|
|
348
|
+
# 平方根
|
|
349
|
+
return 'math.sqrt({})'.format(val_a)
|
|
350
|
+
elif field == 'ABS':
|
|
351
|
+
# 绝对值
|
|
352
|
+
return 'abs({})'.format(val_a)
|
|
353
|
+
elif field == 'NEG':
|
|
354
|
+
# 相反数
|
|
355
|
+
return '-{}'.format(val_a)
|
|
356
|
+
elif field == 'LN':
|
|
357
|
+
# ln
|
|
358
|
+
return 'math.log({})'.format(val_a)
|
|
359
|
+
elif field == 'LOG10':
|
|
360
|
+
# log10
|
|
361
|
+
return '(math.log({}) / math.log(10))'.format(val_a)
|
|
362
|
+
elif field == 'EXP':
|
|
363
|
+
# exp
|
|
364
|
+
return 'math.exp({})'.format(val_a)
|
|
365
|
+
elif field == 'POW10':
|
|
366
|
+
# 10的多少次方
|
|
367
|
+
return 'math.pow(10, {})'.format(val_a)
|
|
368
|
+
|
|
369
|
+
def __get_math_trig(self, block, arg_map=None):
|
|
370
|
+
# 三角函数
|
|
371
|
+
field = self._get_node('field', block).text
|
|
372
|
+
values = self._get_nodes('value', block)
|
|
373
|
+
if len(values) >= 1:
|
|
374
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
375
|
+
if field == 'SIN':
|
|
376
|
+
return 'math.sin({})'.format(val_a)
|
|
377
|
+
elif field == 'COS':
|
|
378
|
+
return 'math.cos({})'.format(val_a)
|
|
379
|
+
elif field == 'TAN':
|
|
380
|
+
return 'math.tan({})'.format(val_a)
|
|
381
|
+
elif field == 'ASIN':
|
|
382
|
+
return 'math.asin({})'.format(val_a)
|
|
383
|
+
elif field == 'ACOS':
|
|
384
|
+
return 'math.acos({})'.format(val_a)
|
|
385
|
+
elif field == 'ATAN':
|
|
386
|
+
return 'math.atan({})'.format(val_a)
|
|
387
|
+
|
|
388
|
+
def __get_math_constant(self, block, arg_map=None):
|
|
389
|
+
field = self._get_node('field', block).text
|
|
390
|
+
if field == 'PI':
|
|
391
|
+
return 'math.pi'
|
|
392
|
+
elif field == 'E':
|
|
393
|
+
return 'math.e'
|
|
394
|
+
elif field == 'GOLDEN_RATIO':
|
|
395
|
+
return '(1 + math.sqrt(5)) / 2'
|
|
396
|
+
elif field == 'SQRT2':
|
|
397
|
+
return 'math.sqrt(2)'
|
|
398
|
+
elif field == 'SQRT1_2':
|
|
399
|
+
return 'math.sqrt(0.5)'
|
|
400
|
+
elif field == 'INFINITY':
|
|
401
|
+
return 'math.inf'
|
|
402
|
+
|
|
403
|
+
def __get_math_modulo(self, block, arg_map=None):
|
|
404
|
+
values = self._get_nodes('value', block)
|
|
405
|
+
if len(values) > 1:
|
|
406
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
407
|
+
val_b = self._get_block_val(values[1], arg_map=arg_map)
|
|
408
|
+
return '{} % {}'.format(val_a, val_b)
|
|
409
|
+
|
|
410
|
+
def __get_math_constrain(self, block, arg_map=None):
|
|
411
|
+
values = self._get_nodes('value', block)
|
|
412
|
+
if len(values) > 2:
|
|
413
|
+
val_a = self._get_block_val(values[0], arg_map=arg_map)
|
|
414
|
+
val_b = self._get_block_val(values[1], arg_map=arg_map)
|
|
415
|
+
val_c = self._get_block_val(values[2], arg_map=arg_map)
|
|
416
|
+
return 'min(max({}, {}), {})'.format(val_a, val_b, val_c)
|