Skip to content

Commit 9f8d21d

Browse files
committed
Added group shape function and get visual objects of robot components.
1 parent 0c8c639 commit 9f8d21d

12 files changed

+57
-10
lines changed

pyrep/backend/vrep.py

+9
Original file line numberDiff line numberDiff line change
@@ -1013,3 +1013,12 @@ def simGetExplicitHandling(generalObjectHandle):
10131013
flag = lib.simGetExplicitHandling(generalObjectHandle)
10141014
_check_return(flag)
10151015
return flag
1016+
1017+
1018+
def simUngroupShape(shapeHandle):
1019+
count = ffi.new('int*')
1020+
shapes = lib.simUngroupShape(shapeHandle, count)
1021+
_check_null_return(shapes)
1022+
handles = [shapes[i] for i in range(count[0])]
1023+
# simReleaseBuffer(shapes)
1024+
return handles

pyrep/objects/cartesian_path.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def create(show_line: bool = True, show_orientation: bool = True,
5858
handle = vrep.simCreatePath(attributes)
5959
return CartesianPath(handle)
6060

61-
def get_type(self) -> ObjectType:
61+
def _get_requested_type(self) -> ObjectType:
6262
return ObjectType.PATH
6363

6464
def get_pose_on_path(self, relative_distance: float

pyrep/objects/dummy.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ def create(size=0.01) -> 'Dummy':
1919
handle = vrep.simCreateDummy(size, None)
2020
return Dummy(handle)
2121

22-
def get_type(self) -> ObjectType:
22+
def _get_requested_type(self) -> ObjectType:
2323
return ObjectType.DUMMY

pyrep/objects/force_sensor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class ForceSensor(Object):
88
"""An object able to measure forces and torques that are applied to it.
99
"""
1010

11-
def get_type(self) -> ObjectType:
11+
def _get_requested_type(self) -> ObjectType:
1212
return ObjectType.FORCE_SENSOR
1313

1414
def read(self) -> Tuple[List[float], List[float]]:

pyrep/objects/joint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Joint(Object):
1515
def __init__(self, name_or_handle: Union[str, int]):
1616
super().__init__(name_or_handle)
1717

18-
def get_type(self) -> ObjectType:
18+
def _get_requested_type(self) -> ObjectType:
1919
return ObjectType.JOINT
2020

2121
def get_joint_type(self) -> JointType:

pyrep/objects/object.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def __init__(self, name_or_handle: Union[str, int]):
1717
self._handle = name_or_handle
1818
else:
1919
self._handle = vrep.simGetObjectHandle(name_or_handle)
20-
assert_type = self.get_type()
20+
assert_type = self._get_requested_type()
2121
actual = ObjectType(vrep.simGetObjectType(self._handle))
2222
if actual != assert_type:
2323
raise WrongObjectTypeError(
@@ -50,12 +50,19 @@ def get_object_type(name: str) -> ObjectType:
5050
"""
5151
return ObjectType(vrep.simGetObjectType(vrep.simGetObjectHandle(name)))
5252

53+
def _get_requested_type(self) -> ObjectType:
54+
"""Used for internally checking assumptions user made about object type.
55+
56+
:return: Type of the object.
57+
"""
58+
raise NotImplementedError('Must be overridden.')
59+
5360
def get_type(self) -> ObjectType:
5461
"""Gets the type of the object.
5562
5663
:return: Type of the object.
5764
"""
58-
raise NotImplementedError('Must be overridden.')
65+
return ObjectType(vrep.simGetObjectType(self._handle))
5966

6067
def get_handle(self) -> int:
6168
"""Gets the internal handle of this object.

pyrep/objects/proximity_sensor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class ProximitySensor(Object):
1010
sensors.
1111
"""
1212

13-
def get_type(self) -> ObjectType:
13+
def _get_requested_type(self) -> ObjectType:
1414
return ObjectType.PROXIMITY_SENSOR
1515

1616
def is_detected(self, obj: Object) -> bool:

pyrep/objects/shape.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def create_mesh(vertices: List[float], indices: List[int],
120120
options, shading_angle, vertices, indices)
121121
return Shape(handle)
122122

123-
def get_type(self) -> ObjectType:
123+
def _get_requested_type(self) -> ObjectType:
124124
return ObjectType.SHAPE
125125

126126
def is_respondable(self) -> bool:
@@ -348,3 +348,11 @@ def set_texture(self, texture: Texture, mapping_mode: TextureMappingMode,
348348
vrep.simSetShapeTexture(
349349
self.get_handle(), texture.get_texture_id(), mapping_mode.value,
350350
options, list(uv_scaling), position, orientation)
351+
352+
def ungroup(self) -> List['Shape']:
353+
"""Ungroups a compound shape into several simple shapes.
354+
355+
:return: A list of shapes.
356+
"""
357+
handles = vrep.simUngroupShape(self.get_handle())
358+
return [Shape(handle) for handle in handles]

pyrep/objects/vision_sensor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def create(resolution: List[int], explicit_handling=False,
104104
vs.set_orientation(orientation)
105105
return vs
106106

107-
def get_type(self) -> ObjectType:
107+
def _get_requested_type(self) -> ObjectType:
108108
return ObjectType.VISION_SENSOR
109109

110110
def capture_rgb(self) -> np.ndarray:

pyrep/robots/robot_component.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
from typing import List, Tuple
2+
3+
from pyrep.objects.shape import Shape
4+
25
from pyrep.backend import vrep
36
from pyrep.const import JointType
47
from pyrep.objects.object import Object
@@ -40,7 +43,7 @@ def copy(self) -> 'RobotComponent':
4043
num = 0
4144
return self.__class__(num)
4245

43-
def get_type(self) -> ObjectType:
46+
def _get_requested_type(self) -> ObjectType:
4447
"""Gets the type of the object.
4548
4649
:return: Type of the object.
@@ -236,6 +239,17 @@ def set_joint_mode(self, value: JointMode) -> None:
236239
"""
237240
[j.set_joint_mode(value) for j in self.joints]
238241

242+
def get_visuals(self) -> List[Object]:
243+
"""Gets a list of the visual elements of this component.
244+
245+
Can be useful for methods such as domain randomization.
246+
Should ideally be overridden for each robot.
247+
248+
:return: A list of visual shapes.
249+
"""
250+
tree = self.get_objects_in_tree(ObjectType.SHAPE, exclude_base=False)
251+
return [obj for obj in tree if 'visual' in obj.get_name()]
252+
239253
def _assert_len(self, inputs: list) -> None:
240254
if len(self.joints) != len(inputs):
241255
raise RuntimeError(

tests/test_joint_groups.py

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ def test_get_joint_upper_velocity_limits(self):
5353
self.assertEqual(
5454
len(self.robot.get_joint_upper_velocity_limits()), self.num_joints)
5555

56+
def test_get_visuals(self):
57+
self.assertEqual(len(self.robot.get_visuals()), 10)
58+
5659

5760
if __name__ == '__main__':
5861
unittest.main()

tests/test_objects.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import unittest
2+
3+
from pyrep.const import ObjectType
4+
25
from tests.core import TestCore
36
from pyrep.objects.shape import Shape
47
from pyrep.objects.dummy import Dummy
@@ -23,6 +26,9 @@ def test_equality(self):
2326
def test_get_handle(self):
2427
self.assertGreater(self.dynamic_cube.get_handle(), 0)
2528

29+
def test_get_type(self):
30+
self.assertEqual(self.dynamic_cube.get_type(), ObjectType.SHAPE)
31+
2632
def test_still_exists(self):
2733
self.assertTrue(self.dynamic_cube.still_exists())
2834
self.assertFalse(Shape(-1).still_exists())

0 commit comments

Comments
 (0)