Skip to content

Commit 1b84075

Browse files
committed
1.Add an interface for setting a new bio gripper;2.Added "get_tool_digital_input" interface;3."get_max_joint_velocity" interface adds parameter whether to return radian value;4."set_tgpio_digital_with_xyz" interface adds access TO3/4;5."set_collision_tool_model interface" adds setting model offset value;6.Blcockly added module for obtaining Euler angles/axis angles and joint angles;7.Blockly added a module to detect whether the bio gripper is grasping and the position of the position triggering IO
1 parent 849cb97 commit 1b84075

File tree

7 files changed

+310
-34
lines changed

7 files changed

+310
-34
lines changed

xarm/tools/blockly/_blockly_base.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,24 @@ def _get_condition_expression(self, value_block, arg_map=None):
224224
addr = int(fields[0].text.replace(' ', '').replace('0x', '').replace(',', '').replace('\xa0', ''), 16)
225225
return "list(map(lambda x: hex(x).split('0x')[1].upper().zfill(4)[:2] + ' ' + hex(x).split('0x')[1]." \
226226
"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.position_aa[{}], 2)'.format(direction-1)
234+
else:
235+
return 'round(self._arm.position[{}], 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)
227245

228246

229247
def __get_logic_compare(self, block, arg_map=None):

xarm/tools/blockly/_blockly_handler.py

Lines changed: 130 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import json
1010
import re
11+
import math
1112
from ._blockly_base import _BlocklyBase, OPS_MAP
1213
from ._blockly_highlight import HIGHLIGHT_BLOCKS
1314

@@ -417,8 +418,9 @@ def _handle_gpio_set_digital(self, block, indent=0, arg_map=None):
417418
fields = self._get_nodes('field', root=block)
418419
io = fields[0].text
419420
value = 0 if fields[1].text == 'LOW' else 1
420-
delay_sec = fields[2].text if len(fields) > 2 else 0
421-
self._append_main_code('code = self._arm.set_tgpio_digital({}, {}, delay_sec={})'.format(io, value, delay_sec), indent + 2)
421+
is_sync = fields[2].text if len(fields) > 2 else 'True'
422+
delay_sec = fields[3].text if len(fields) > 3 else 0
423+
self._append_main_code('code = self._arm.set_tgpio_digital({}, {}, delay_sec={}, sync={})'.format(io, value, delay_sec, is_sync), indent + 2)
422424
self._append_main_code('if not self._check_code(code, \'set_tgpio_digital\'):', indent + 2)
423425
self._append_main_code(' return', indent + 2)
424426

@@ -435,14 +437,36 @@ def _handle_gpio_set_digital_with_xyz(self, block, indent=0, arg_map=None):
435437
self._append_main_code('if not self._check_code(code, \'set_tgpio_digital_with_xyz\'):', indent + 2)
436438
self._append_main_code(' return', indent + 2)
437439

440+
def _handle_gpio_set_digital_with_xyz_var(self, block, indent=0, arg_map=None):
441+
value_nodes = self._get_nodes('value', root=block)
442+
x = self._get_block_val(value_nodes[0], arg_map)
443+
y = self._get_block_val(value_nodes[1], arg_map)
444+
z = self._get_block_val(value_nodes[2], arg_map)
445+
xyz_li = [x, y, z]
446+
xyz = []
447+
for i in range(3):
448+
if re.match('\d+(\.\d+)*$', xyz_li[i]) is not None:
449+
xyz.append(float(xyz_li[i]))
450+
else:
451+
xyz.append(math.log2(3) if i == 0 else math.log2(5) if i == 1 else math.log2(7))
452+
xyz = str(xyz).replace(str(math.log2(3)), xyz_li[0]).replace(str(math.log2(5)), xyz_li[1]).replace(
453+
str(math.log2(7)), xyz_li[2])
454+
tol_r = self._get_block_val(value_nodes[3], arg_map)
455+
io = self._get_block_val(value_nodes[4], arg_map)
456+
value = 0 if self._get_block_val(value_nodes[5], arg_map) == 'LOW' else 1
457+
self._append_main_code(
458+
'code = self._arm.set_tgpio_digital_with_xyz({}, {}, {}, {})'.format(io, value, xyz, tol_r), indent + 2)
459+
self._append_main_code('if not self._check_code(code, \'set_tgpio_digital_with_xyz\'):', indent + 2)
460+
self._append_main_code(' return', indent + 2)
461+
438462
def _handle_get_suction_cup(self, block, indent=0, arg_map=None):
439463
self._append_main_code('{}self._arm.get_suction_cup(hardware_version={})'.format('{}', self._vacuum_version), indent + 2)
440464

441465
def _handle_check_air_pump_state(self, block, indent=0, arg_map=None):
442466
fields = self._get_nodes('field', root=block)
443467
state = 1 if fields[0].text == 'ON' else 0
444468
timeout = float(fields[1].text)
445-
self._append_main_code('self._arm.arm.check_air_pump_state({}, timeout={})'.format(state, timeout), indent + 2)
469+
self._append_main_code('self._arm.arm.check_air_pump_state({}, timeout={}, hardware_version={})'.format(state, timeout, self._vacuum_version), indent + 2)
446470

447471
def _handle_check_bio_gripper_is_catch(self, block, indent=0, arg_map=None):
448472
fields = self._get_nodes('field', root=block)
@@ -464,7 +488,7 @@ def _handle_set_suction_cup(self, block, indent=0, arg_map=None):
464488
wait = False
465489
fields = self._get_nodes('field', root=block, name='delay')
466490
delay_sec = fields[0].text if len(fields) > 0 else 0
467-
self._append_main_code('code = self._arm.set_suction_cup({}, wait={}, delay_sec={}, hardware_version={})'.format( on, wait, delay_sec, self._vacuum_version), indent + 2)
491+
self._append_main_code('code = self._arm.set_suction_cup({}, wait={}, delay_sec={}, hardware_version={})'.format(on, wait, delay_sec, self._vacuum_version), indent + 2)
468492
self._append_main_code('if not self._check_code(code, \'set_suction_cup\'):', indent + 2)
469493
self._append_main_code(' return', indent + 2)
470494

@@ -511,8 +535,9 @@ def _handle_gpio_set_controller_digital(self, block, indent=0, arg_map=None):
511535
fields = self._get_nodes('field', root=block)
512536
io = fields[0].text
513537
value = 0 if fields[1].text == 'LOW' else 1
514-
delay_sec = fields[2].text if len(fields) > 2 else 0
515-
self._append_main_code('code = self._arm.set_cgpio_digital({}, {}, delay_sec={})'.format(io, value, delay_sec), indent + 2)
538+
is_sync = fields[2].text if len(fields) > 2 else 'True'
539+
delay_sec = fields[3].text if len(fields) > 3 else 0
540+
self._append_main_code('code = self._arm.set_cgpio_digital({}, {}, delay_sec={}, sync={})'.format(io, value, delay_sec, is_sync), indent + 2)
516541
self._append_main_code('if not self._check_code(code, \'set_cgpio_digital\'):', indent + 2)
517542
self._append_main_code(' return', indent + 2)
518543

@@ -525,6 +550,27 @@ def _handle_gpio_set_controller_digital_with_xyz(self, block, indent=0, arg_map=
525550
tol_r = fields[3].text
526551
io = fields[4].text
527552
value = 0 if fields[5].text == 'LOW' else 1
553+
self._append_main_code(
554+
'code = self._arm.set_cgpio_digital_with_xyz({}, {}, {}, {})'.format(io, value, xyz, tol_r), indent + 2)
555+
self._append_main_code('if not self._check_code(code, \'set_cgpio_digital_with_xyz\'):', indent + 2)
556+
self._append_main_code(' return', indent + 2)
557+
558+
def _handle_gpio_set_controller_digital_with_xyz_var(self, block, indent=0, arg_map=None):
559+
value_nodes = self._get_nodes('value', root=block)
560+
x = self._get_block_val(value_nodes[0], arg_map)
561+
y = self._get_block_val(value_nodes[1], arg_map)
562+
z = self._get_block_val(value_nodes[2], arg_map)
563+
xyz_li = [x, y, z]
564+
xyz = []
565+
for i in range(3):
566+
if re.match('\d+(\.\d+)*$', xyz_li[i]) is not None:
567+
xyz.append(float(xyz_li[i]))
568+
else:
569+
xyz.append(math.log2(3) if i == 0 else math.log2(5) if i == 1 else math.log2(7))
570+
xyz = str(xyz).replace(str(math.log2(3)), xyz_li[0]).replace(str(math.log2(5)), xyz_li[1]).replace(str(math.log2(7)), xyz_li[2])
571+
tol_r = self._get_block_val(value_nodes[3], arg_map)
572+
io = self._get_block_val(value_nodes[4], arg_map)
573+
value = 0 if self._get_block_val(value_nodes[5], arg_map) == 'LOW' else 1
528574
self._append_main_code('code = self._arm.set_cgpio_digital_with_xyz({}, {}, {}, {})'.format(io, value, xyz, tol_r), indent + 2)
529575
self._append_main_code('if not self._check_code(code, \'set_cgpio_digital_with_xyz\'):', indent + 2)
530576
self._append_main_code(' return', indent + 2)
@@ -533,20 +579,43 @@ def _handle_gpio_set_controller_digital_do(self, block, indent=0, arg_map=None):
533579
fields = self._get_nodes('field', root=block)
534580
io = fields[0].text
535581
value = 0 if fields[1].text == 'LOW' else 1
536-
delay_sec = fields[2].text if len(fields) > 2 else 0
537-
self._append_main_code('code = self._arm.set_cgpio_digital({}, {}, delay_sec={})'.format(io, value, delay_sec), indent + 2)
538-
self._append_main_code('if not self._check_code(code, \'set_suction_cup\'):', indent + 2)
582+
is_sync = fields[2].text if len(fields) > 2 else 'True'
583+
delay_sec = fields[3].text if len(fields) > 3 else 0
584+
self._append_main_code('code = self._arm.set_cgpio_digital({}, {}, delay_sec={}, sync={})'.format(io, value, delay_sec, is_sync), indent + 2)
585+
self._append_main_code('if not self._check_code(code, \'set_cgpio_digital\'):', indent + 2)
539586
self._append_main_code(' return', indent + 2)
540587

541588
def _handle_gpio_set_controller_digital_with_xyz_do(self, block, indent=0, arg_map=None):
542-
fields = self._get_nodes('field', root=block)
543-
x = fields[0].text
544-
y = fields[1].text
545-
z = fields[2].text
589+
value_nodes = self._get_nodes('value', root=block)
590+
x = self._get_block_val(value_nodes[0], arg_map)
591+
y = self._get_block_val(value_nodes[1], arg_map)
592+
z = self._get_block_val(value_nodes[2], arg_map)
546593
xyz = list(map(float, [x, y, z]))
547-
tol_r = fields[3].text
548-
io = fields[4].text
549-
value = 0 if fields[5].text == 'LOW' else 1
594+
tol_r = self._get_block_val(value_nodes[3], arg_map)
595+
io = self._get_block_val(value_nodes[4], arg_map)
596+
value = 0 if self._get_block_val(value_nodes[5], arg_map) == 'LOW' else 1
597+
self._append_main_code(
598+
'code = self._arm.set_cgpio_digital_with_xyz({}, {}, {}, {})'.format(io, value, xyz, tol_r), indent + 2)
599+
self._append_main_code('if not self._check_code(code, \'set_cgpio_digital_with_xyz\'):', indent + 2)
600+
self._append_main_code(' return', indent + 2)
601+
602+
def _handle_gpio_set_controller_digital_with_xyz_do_var(self, block, indent=0, arg_map=None):
603+
value_nodes = self._get_nodes('value', root=block)
604+
x = self._get_block_val(value_nodes[0], arg_map)
605+
y = self._get_block_val(value_nodes[1], arg_map)
606+
z = self._get_block_val(value_nodes[2], arg_map)
607+
tol_r = self._get_block_val(value_nodes[3], arg_map)
608+
io = self._get_block_val(value_nodes[4], arg_map)
609+
value = 0 if self._get_block_val(value_nodes[5], arg_map) == 'LOW' else 1
610+
xyz_li = [x, y, z]
611+
xyz = []
612+
for i in range(3):
613+
if re.match('\d+(\.\d+)*$', xyz_li[i]) is not None:
614+
xyz.append(float(xyz_li[i]))
615+
else:
616+
xyz.append(math.log2(3) if i == 0 else math.log2(5) if i == 1 else math.log2(7))
617+
xyz = str(xyz).replace(str(math.log2(3)), xyz_li[0]).replace(str(math.log2(5)), xyz_li[1]).replace(
618+
str(math.log2(7)), xyz_li[2])
550619
self._append_main_code('code = self._arm.set_cgpio_digital_with_xyz({}, {}, {}, {})'.format(io, value, xyz, tol_r), indent + 2)
551620
self._append_main_code('if not self._check_code(code, \'set_cgpio_digital_with_xyz\'):', indent + 2)
552621
self._append_main_code(' return', indent + 2)
@@ -564,11 +633,35 @@ def _handle_gpio_set_controller_analog_with_xyz(self, block, indent=0, arg_map=N
564633
self._append_main_code('if not self._check_code(code, \'set_cgpio_analog_with_xyz\'):', indent + 2)
565634
self._append_main_code(' return', indent + 2)
566635

636+
def _handle_gpio_set_controller_analog_with_xyz_var(self, block, indent=0, arg_map=None):
637+
value_nodes = self._get_nodes('value', root=block)
638+
x = self._get_block_val(value_nodes[0], arg_map)
639+
y = self._get_block_val(value_nodes[1], arg_map)
640+
z = self._get_block_val(value_nodes[2], arg_map)
641+
# xyz = list(map(lambda x: float(x) if re.match('\d+(\.\d+)*$', x) is not None else [x, y, z].index(x), [x, y, z]))
642+
xyz_li = [x, y, z]
643+
xyz = []
644+
for i in range(3):
645+
if re.match('\d+(\.\d+)*$', xyz_li[i]) is not None:
646+
xyz.append(float(xyz_li[i]))
647+
else:
648+
xyz.append(math.log2(3) if i == 0 else math.log2(5) if i == 1 else math.log2(7))
649+
xyz = str(xyz).replace(str(math.log2(3)), xyz_li[0]).replace(str(math.log2(5)), xyz_li[1]).replace(
650+
str(math.log2(7)), xyz_li[2])
651+
tol_r = self._get_block_val(value_nodes[3], arg_map)
652+
io = self._get_block_val(value_nodes[4], arg_map)
653+
value = self._get_block_val(value_nodes[5], arg_map)
654+
self._append_main_code('code = self._arm.set_cgpio_analog_with_xyz({}, {}, {}, {})'.format(io, value, xyz, tol_r), indent + 2)
655+
self._append_main_code('if not self._check_code(code, \'set_cgpio_analog_with_xyz\'):', indent + 2)
656+
self._append_main_code(' return', indent + 2)
657+
567658
def _handle_gpio_set_controller_analog(self, block, indent=0, arg_map=None):
568-
io = self._get_node('field', block).text
659+
fields = self._get_nodes('field', root=block)
660+
io = fields[0].text
661+
is_sync = fields[1].text
569662
value = self._get_node('value', root=block)
570663
value = self._get_block_val(value, arg_map=arg_map)
571-
self._append_main_code('code = self._arm.set_cgpio_analog({}, {})'.format(io, value), indent + 2)
664+
self._append_main_code('code = self._arm.set_cgpio_analog({}, {}, sync={})'.format(io, value, is_sync), indent + 2)
572665
self._append_main_code('if not self._check_code(code, \'set_cgpio_analog\'):', indent + 2)
573666
self._append_main_code(' return', indent + 2)
574667

@@ -654,15 +747,15 @@ def _handle_set_lite6_gripper(self, block, indent=0, arg_map=None):
654747

655748
def _handle_gripper_set(self, block, indent=0, arg_map=None):
656749
fields = self._get_nodes('field', root=block)
657-
if fields is not None and len(fields) >= 3:
750+
if fields is not None and len(fields) >= 4:
658751
pos = fields[0].text
659752
speed = fields[1].text
660-
wait = fields[2].text == 'TRUE'
753+
wait = fields[3].text == 'TRUE'
661754
else:
662755
values = self._get_nodes('value', root=block)
663756
pos = self._get_nodes('field', root=values[0], descendant=True)[0].text
664757
speed = self._get_nodes('field', root=values[1], descendant=True)[0].text
665-
wait = self._get_nodes('field', root=values[2], descendant=True)[0].text == 'TRUE'
758+
wait = self._get_nodes('field', root=values[3], descendant=True)[0].text == 'TRUE'
666759
self._append_main_code('code = self._arm.set_gripper_position({}, wait={}, speed={}, auto_enable=True)'.format(pos, wait, speed), indent + 2)
667760
self._append_main_code('if not self._check_code(code, \'set_gripper_position\'):', indent + 2)
668761
self._append_main_code(' return', indent + 2)
@@ -686,6 +779,11 @@ def _handle_gripper_set_status(self, block, indent=0, arg_map=None):
686779
self._append_main_code('if not self._check_code(code, \'set_gripper_status\'):', indent + 2)
687780
self._append_main_code(' return', indent + 2)
688781

782+
def _handle_set_bio_g2_gripper_init(self, block, indent=0, arg_map=None):
783+
self._append_main_code('code = self._arm.set_bio_gripper_enable(True)', indent + 2)
784+
self._append_main_code('if not self._check_code(code, \'set_bio_gripper_enable\'):', indent + 2)
785+
self._append_main_code(' return', indent + 2)
786+
689787
def _handle_set_bio_gripper_init(self, block, indent=0, arg_map=None):
690788
self._append_main_code('code = self._arm.set_bio_gripper_enable(True)', indent + 2)
691789
self._append_main_code('if not self._check_code(code, \'set_bio_gripper_enable\'):', indent + 2)
@@ -707,6 +805,16 @@ def _handle_set_bio_gripper(self, block, indent=0, arg_map=None):
707805
self._append_main_code('if not self._check_code(code, \'close_bio_gripper\'):', indent + 2)
708806
self._append_main_code(' return', indent + 2)
709807

808+
def _handle_set_bio_gripper_pos_force(self, block, indent=0, arg_map=None):
809+
fields = self._get_nodes('field', root=block)
810+
pos = fields[0].text
811+
speed = fields[1].text
812+
force = fields[2].text
813+
wait = fields[3].text == 'TRUE'
814+
self._append_main_code('code = self._arm.set_bio_gripper_position(pos={}, speed={}, force={}, wait={})'.format(pos, speed, force, wait), indent + 2)
815+
self._append_main_code('if not self._check_code(code, \'open_bio_gripper\'):', indent + 2)
816+
self._append_main_code(' return', indent + 2)
817+
710818
def _handle_set_robotiq_init(self, block, indent=0, arg_map=None):
711819
self._append_main_code('code, ret = self._arm.robotiq_reset()', indent + 2)
712820
self._append_main_code('if not self._check_code(code, \'robotiq_reset\'):', indent + 2)
@@ -1124,6 +1232,7 @@ def _handle_python_code(self, block, indent=0, arg_map=None, **kwargs):
11241232
if (self._is_exec or (not self._is_exec and not self._is_ide)) and code.strip() and code not in \
11251233
['finally:', 'else:'] and all([i not in code for i in ['elif', 'except', 'def', 'class']]) \
11261234
and not code.startswith('@'):
1235+
# 只有在studio执行blockly时或者SDK直接调用run_blockly_app时才会执行
11271236
code_indent = re.match('(\s*).*', code).group(1)
11281237
self._append_main_code(code_indent + 'if not self.is_alive:', indent + 2)
11291238
self._append_main_code(code_indent + 'return', indent + 3)

xarm/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.14.8'
1+
__version__ = '1.14.9'

xarm/wrapper/xarm_api.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2802,6 +2802,47 @@ def set_bio_gripper_speed(self, speed):
28022802
"""
28032803
return self._arm.set_bio_gripper_speed(speed)
28042804

2805+
def set_bio_gripper_control_mode(self, mode):
2806+
"""
2807+
Set the bio gripper control mode
2808+
2809+
:param mode: 0: bio gripper opening and closing mode
2810+
1: position loop mode
2811+
2812+
:return: code
2813+
code: See the [API Code Documentation](./xarm_api_code.md#api-code) for details.
2814+
"""
2815+
2816+
return self._arm.set_bio_gripper_control_mode(mode)
2817+
2818+
def set_bio_gripper_force(self, force):
2819+
"""
2820+
Set the bio gripper force
2821+
2822+
:param force: gripper force between 10 and 100
2823+
2824+
:return: code
2825+
code: See the [API Code Documentation](./xarm_api_code.md#api-code) for details.
2826+
"""
2827+
2828+
return self._arm.set_bio_gripper_force(force)
2829+
2830+
def set_bio_gripper_position(self, pos, speed=0, force=100, wait=True, timeout=5, **kwargs):
2831+
"""
2832+
Set the bio gripper position
2833+
2834+
:param pos: gripper pos between 71 and 150
2835+
:param speed: gripper speed between 0 and 4500
2836+
:param force: gripper force between 10 and 100
2837+
:param wait: whether to wait for the robotiq motion to complete, default is True
2838+
:param timeout: maximum waiting time(unit: second), default is 5, only available if wait=True
2839+
2840+
:return: tuple((code, robotiq_response))
2841+
code: See the [API Code Documentation](./xarm_api_code.md#api-code) for details.
2842+
robotiq_response: See the robotiq documentation
2843+
"""
2844+
return self._arm.set_bio_gripper_position(pos, speed=speed, force=force, wait=wait, timeout=timeout, **kwargs)
2845+
28052846
def open_bio_gripper(self, speed=0, wait=True, timeout=5, **kwargs):
28062847
"""
28072848
Open the bio gripper

0 commit comments

Comments
 (0)