Skip to content

Commit 70bc53a

Browse files
authored
Update readme with info on how to extract objects
1 parent 5235349 commit 70bc53a

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,75 @@ for c in rdata.result.contacts:
278278
print '\tO1: {}, O2: {}'.format(c.o1, c.o2)
279279
```
280280

281+
### Extracting Which Objects Are In Collision
282+
283+
To determine which objects are actually in collision, you'll need parse the collision data's contacts and use an additional external data structure.
284+
285+
Specifically, the `fcl.CollisionData` object that is passed into any `collide()` call has an internal set of contacts, stored in `cdata.result.contacts`.
286+
This object is a simple list of `Contact` objects, each of which represents a contact point between two objects.
287+
Each contact object has two attributes, `o1` and `o2`, that store references to the original `fcl.CollisionGeometry` objects were created for the two `fcl.CollisionObject` objects that are in collision.
288+
This is a bit wonky, but it's part of the FCL API.
289+
290+
Therefore, all you have to do is make a map from the `id` of each `fcl.CollisionGeometry` object to either the actual `fcl.CollisionObject` it corresponds to or to some string identifier for each object.
291+
Then, you can iterate over `cdata.result.contacts`, extract `o1` and `o2`, apply the built-in `id()` function to each, and find the corresponding data you want in your map.
292+
293+
Here's an example.
294+
295+
```python
296+
import fcl
297+
import numpy as np
298+
299+
# Create collision geometry and objects
300+
geom1 = fcl.Cylinder(1.0, 1.0)
301+
obj1 = fcl.CollisionObject(geom1)
302+
303+
geom2 = fcl.Cylinder(1.0, 1.0)
304+
obj2 = fcl.CollisionObject(geom2, fcl.Transform(np.array([0.0, 0.0, 0.3])))
305+
306+
geom3 = fcl.Cylinder(1.0, 1.0)
307+
obj3 = fcl.CollisionObject(geom3, fcl.Transform(np.array([0.0, 0.0, 3.0])))
308+
309+
geoms = [geom1, geom2, geom3]
310+
objs = [obj1, obj2, obj3]
311+
names = ['obj1', 'obj2', 'obj3']
312+
313+
# Create map from geometry IDs to objects
314+
geom_id_to_obj = { id(geom) : obj for geom, obj in zip(geoms, objs) }
315+
316+
# Create map from geometry IDs to string names
317+
geom_id_to_name = { id(geom) : name for geom, name in zip(geoms, names) }
318+
319+
# Create manager
320+
manager = fcl.DynamicAABBTreeCollisionManager()
321+
manager.registerObjects(objs)
322+
manager.setup()
323+
324+
# Create collision request structure
325+
crequest = fcl.CollisionRequest(num_max_contacts=100, enable_contact=True)
326+
cdata = fcl.CollisionData(crequest, fcl.CollisionResult())
327+
328+
# Run collision request
329+
manager.collide(cdata, fcl.defaultCollisionCallback)
330+
331+
# Extract collision data from contacts and use that to infer set of
332+
# objects that are in collision
333+
objs_in_collision = set()
334+
335+
for contact in cdata.result.contacts:
336+
# Extract collision geometries that are in contact
337+
coll_geom_0 = contact.o1
338+
coll_geom_1 = contact.o2
339+
340+
# Get their names
341+
coll_names = [geom_id_to_name[id(coll_geom_0)], geom_id_to_name[id(coll_geom_1)]]
342+
coll_names = tuple(sorted(coll_names))
343+
objs_in_collision.add(coll_names)
344+
345+
for coll_pair in objs_in_collision:
346+
print('Object {} in collision with object {}!'.format(coll_pair[0], coll_pair[1]))
347+
```
348+
349+
```
350+
>>> Object obj1 in collision with object obj2!
351+
```
281352
For more examples, see `example/example.py`.

0 commit comments

Comments
 (0)