Skip to content

Commit 93635f5

Browse files
add contact info solve #218 (#220)
* add contact info * remove all zero value * put a wrapper for get contact points in object.py and add test * add doc string for get_contact * fix get_contact function bug that return all contacts * fix unit test Co-authored-by: Stephen James <[email protected]>
1 parent e8a05ca commit 93635f5

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

pyrep/backend/sim.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,32 @@ def simCheckOctreePointOccupancy(octreeHandle, options, points):
13811381
return False
13821382

13831383

1384+
def simGetContactInfo(contact_obj_handle, get_contact_normal):
1385+
index = 0
1386+
contact_list = []
1387+
result = 1
1388+
1389+
while result > 0:
1390+
if get_contact_normal:
1391+
contact = ffi.new('float[9]')
1392+
ext = sim_handleflag_extended
1393+
else:
1394+
contact = ffi.new('float[6]')
1395+
ext = 0
1396+
1397+
object_handles = ffi.new('int[2]')
1398+
result = lib.simGetContactInfo(sim_handle_all, contact_obj_handle, index + ext, object_handles,
1399+
contact)
1400+
contact_info = {
1401+
"contact": list(contact),
1402+
"contact_handles": list(object_handles)
1403+
}
1404+
contact_list.append(contact_info)
1405+
index += 1
1406+
contact_list.pop(-1) # remove the all zero value
1407+
return contact_list
1408+
1409+
13841410
def simGetConfigForTipPose(ikGroupHandle, jointHandles, thresholdDist, maxTimeInMs, metric, collisionPairs, jointOptions, lowLimits, ranges):
13851411
jointCnt = len(jointHandles)
13861412
collisionPairCnt = len(collisionPairs) // 2

pyrep/objects/object.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,24 @@ def set_collidable(self, value: bool) -> None:
330330
"""
331331
self._set_property(sim.sim_objectspecialproperty_collidable, value)
332332

333+
def get_contact(self, contact_obj=None, get_contact_normal: bool = True) -> List:
334+
"""Get the contact point and force with other object
335+
336+
:param contact_obj: The object want to check contact info with, set to None to get contact with all objects
337+
:param get_contact_normal: Weather get the force and direction
338+
:return: a list of all the contact info
339+
"""
340+
contact_info = sim.simGetContactInfo(self.get_handle(), get_contact_normal)
341+
if contact_obj is None:
342+
return contact_info
343+
else:
344+
result = []
345+
check_handle = contact_obj.get_handle()
346+
for contact in contact_info:
347+
if check_handle in contact['contact_handles']:
348+
result.append(contact)
349+
return result
350+
333351
def is_measurable(self) -> bool:
334352
"""Whether the object is measurable or not.
335353

tests/test_objects.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,18 @@ def test_get_set_collidable(self):
143143
self.dynamic_cube.set_collidable(True)
144144
self.assertTrue(self.dynamic_cube.is_collidable())
145145

146+
def test_get_contact(self):
147+
contact = self.dynamic_cube.get_contact(self.simple_model, get_contact_normal=True)
148+
self.assertTrue(len(contact) == 0)
149+
for _ in range(20):
150+
self.pyrep.step()
151+
c1 = Shape('colliding_cube1')
152+
c0 = Shape('colliding_cube0')
153+
contact = c1.get_contact(None, True)
154+
self.assertTrue(len(contact) > 0)
155+
contact = c0.get_contact(None, True)
156+
self.assertTrue(len(contact) > 0)
157+
146158
def test_get_set_measurable(self):
147159
self.dynamic_cube.set_measurable(False)
148160
self.assertFalse(self.dynamic_cube.is_measurable())

0 commit comments

Comments
 (0)