Giter VIP home page Giter VIP logo

python-fcl's Introduction

python-fcl

Python Interface for the Flexible Collision Library

Python-FCL is an (unofficial) Python interface for the Flexible Collision Library (FCL), an excellent C++ library for performing proximity and collision queries on pairs of geometric models. Currently, this package is targeted for FCL 0.7.0.

This package supports three types of proximity queries for pairs of geometric models:

  • Collision Detection: Detecting whether two models overlap (and optionally where).
  • Distance Computation: Computing the minimum distance between a pair of models.
  • Continuous Collision Detection: Detecting whether two models overlap during motion (and optionally the time of contact).

This package also supports most of FCL's object shapes, including:

  • TriangleP
  • Box
  • Sphere
  • Ellipsoid
  • Capsule
  • Cone
  • Convex
  • Cylinder
  • Half-Space
  • Plane
  • Mesh
  • OcTree

Installation

First, install octomap, which is necessary to use OcTree. For Ubuntu, use sudo apt-get install liboctomap-dev. Second, install FCL using the instructions provided here. If you're on Ubuntu 17.04 or newer, you can install FCL using sudo apt-get install libfcl-dev. Otherwise, just compile FCL from source -- it's quick and easy, and its dependencies are all easily installed via apt or brew. Note: the provided install scripts (under build_dependencies) can automate this process as well.

In order to install the Python wrappers for FCL, simply run

pip install python-fcl

Objects

Collision Objects

The primary construct in FCL is the CollisionObject, which forms the backbone of all collision and distance computations. A CollisionObject consists of two components -- its geometry, defined by a CollisionGeometry object, and its pose, defined by a Transform object.

Collision Geometries

There are two main types of CollisionGeometry objects -- geometric primitives, such as boxes and spheres, and arbitrary triangular meshes. Here's some examples of how to instantiate geometric primitives. Note that the box, sphere, ellipsoid, capsule, cone, and cylinder are all centered at the origin.

import numpy as np
import fcl

v1 = np.array([1.0, 2.0, 3.0])
v2 = np.array([2.0, 1.0, 3.0])
v3 = np.array([3.0, 2.0, 1.0])
x, y, z = 1, 2, 3
rad, lz = 1.0, 3.0
n = np.array([1.0, 0.0, 0.0])
d = 5.0

t = fcl.TriangleP(v1, v2, v3) # Triangle defined by three points
b = fcl.Box(x, y, z)          # Axis-aligned box with given side lengths
s = fcl.Sphere(rad)           # Sphere with given radius
e = fcl.Ellipsoid(x, y, z)    # Axis-aligned ellipsoid with given radii
c = fcl.Capsule(rad, lz)      # Capsule with given radius and height along z-axis
c = fcl.Cone(rad, lz)         # Cone with given radius and cylinder height along z-axis
c = fcl.Cylinder(rad, lz)     # Cylinder with given radius and height along z-axis
h = fcl.Halfspace(n, d)       # Half-space defined by {x : <n, x> < d}
p = fcl.Plane(n, d)           # Plane defined by {x : <n, x> = d}

Triangular meshes are wrapped by the BVHModel class, and they are instantiated a bit differently.

verts = np.array([[1.0, 1.0, 1.0],
                  [2.0, 1.0, 1.0],
                  [1.0, 2.0, 1.0],
                  [1.0, 1.0, 2.0]])
tris  = np.array([[0,2,1],
                  [0,3,2],
                  [0,1,3],
                  [1,2,3]])

m = fcl.BVHModel()
m.beginModel(len(verts), len(tris))
m.addSubModel(verts, tris)
m.endModel()

If the mesh is convex, such as the example above, you can also wrap it in the Convex class. Note that the instantiation is a bit different because the Convex class supports arbitrary polygons for each face of the convex object.

verts = np.array([[1.0, 1.0, 1.0],
                  [2.0, 1.0, 1.0],
                  [1.0, 2.0, 1.0],
                  [1.0, 1.0, 2.0]])
tris  = np.array([[0,2,1],
                  [0,3,2],
                  [0,1,3],
                  [1,2,3]])
faces = np.concatenate((3 * np.ones((len(tris), 1), dtype=np.int64), tris), axis=1).flatten()
c = fcl.Convex(verts, len(tris), faces)

Transforms

In addition to a CollisionGeometry, a CollisionObject requires a Transform, which tells FCL where the CollisionGeometry is actually located in the world. All Transform objects specify a rigid transformation (i.e. a rotation and a translation). The translation is always a 3-entry vector, while the rotation can be specified by a 3x3 rotation matrix or a 4-entry quaternion.

Here are some examples of possible ways to instantiate and manipulate a Transform.

R = np.array([[0.0, -1.0, 0.0],
              [1.0,  0.0, 0.0],
              [0.0,  0.0, 1.0]])
T = np.array([1.0, 2.0, 3.0])
q = np.array([0.707, 0.0, 0.0, 0.707])

tf = fcl.Transform()     # Default gives identity transform
tf = fcl.Transform(q)    # Quaternion rotation, zero translation
tf = fcl.Transform(R)    # Matrix rotation, zero translation
tf = fcl.Transform(T)    # Translation, identity rotation
tf = fcl.Transform(q, T) # Quaternion rotation and translation
tf = fcl.Transform(R, T) # Matrix rotation and translation
tf1 = fcl.Transform(tf)  # Can also initialize with another Transform

Now, given a CollisionGeometry and a Transform, we can create a CollisionObject:

t = fcl.Transform(R, T)
b = fcl.Box(x, y, z)
obj = fcl.CollisionObject(b, t)

The transform of a collision object can be modified in-place:

t1 = fcl.Transform(R1, T1)
obj.setTransform(t1)   # Using a transform
obj.setRotation(R2)    # Specifying components individually
obj.setTranslation(T2)
obj.setQuatRotation(q2)

Commands

Pairwise Operations

Given a pair of collision objects, this library supports three types of queries:

  • Collision Detection
  • Distance Computation
  • Continuous Collision Detection

The interfaces for each of these operations follow a common pipeline. First, a query request data structure is initialized and populated with parameters. Then, an empty query response structure is initialized. Finally, the query function is called with the two CollisionObject items, the request structure, and the response structure as arguments. The query function returns a scalar result, and any additional information is stored in the query result data structure. Examples of all three operations are shown below.

Collision Checking

g1 = fcl.Box(1,2,3)
t1 = fcl.Transform()
o1 = fcl.CollisionObject(g1, t1)

g2 = fcl.Cone(1,3)
t2 = fcl.Transform()
o2 = fcl.CollisionObject(g2, t2)

request = fcl.CollisionRequest()
result = fcl.CollisionResult()

ret = fcl.collide(o1, o2, request, result)

After calling fcl.collide(), ret contains the number of contacts generated between the two objects, and result contains information about the collision and contacts. For more information about available parameters for collision requests and results, see fcl/collision_data.py.

Distance Checking

g1 = fcl.Box(1,2,3)
t1 = fcl.Transform()
o1 = fcl.CollisionObject(g1, t1)

g2 = fcl.Cone(1,3)
t2 = fcl.Transform()
o2 = fcl.CollisionObject(g2, t2)

request = fcl.DistanceRequest()
result = fcl.DistanceResult()

ret = fcl.distance(o1, o2, request, result)

After calling fcl.distance(), ret contains the minimum distance between the two objects and result contains information about the closest points on the objects. If ret is negative, the objects are in collision. For more information about available parameters for distance requests and results, see fcl/collision_data.py.

Continuous Collision Checking

g1 = fcl.Box(1,2,3)
t1 = fcl.Transform()
o1 = fcl.CollisionObject(g1, t1)
t1_final = fcl.Transform(np.array([1.0, 0.0, 0.0]))

g2 = fcl.Cone(1,3)
t2 = fcl.Transform()
o2 = fcl.CollisionObject(g2, t2)
t2_final = fcl.Transform(np.array([-1.0, 0.0, 0.0]))

request = fcl.ContinuousCollisionRequest()
result = fcl.ContinuousCollisionResult()

ret = fcl.continuousCollide(o1, t1_final, o2, t2_final, request, result)

After calling fcl.continuousCollide(), ret contains the time of contact in (0,1), or 1.0 if the objects did not collide during movement from their initial poses to their final poses. Additionally, result contains information about the collision time and status. For more information about available parameters for continuous collision requests and results, see fcl/collision_data.py.

Broadphase Checking

In addition to pairwise checks, FCL supports broadphase collision/distance queries between groups of objects and can avoid n-squared complexity. Specifically, CollisionObject items are registered with a DynamicAABBTreeCollisionManager before collision or distance checking is performed.

Three types of checks are possible:

  • One-to-many: Collision/distance checking between a stand-alone CollisionObject and all objects managed by a manager.
  • Internal many-to-many: Pairwise collision/distance checking between all pairs of objects managed by a manager.
  • Group many-to-many: Pairwise collision/distance checking between items from two managers.

In general, the collision methods can return all contact pairs, while the distance methods will just return the single closest distance between any pair of objects. Here are some examples of managed collision checking. The methods take a callback function -- use the defaults from python-fcl unless you have a special use case -- and a wrapper object, either CollisionData or DistanceData, that wraps a request-response pair. This object also has a field, done, that tells the recursive collision checker when to quit. Be sure to use a new Data object for each request or set the done attribute to False before reusing one.

objs1 = [fcl.CollisionObject(box), fcl.CollisionObject(sphere)]
objs2 = [fcl.CollisionObject(cone), fcl.CollisionObject(mesh)]

manager1 = fcl.DynamicAABBTreeCollisionManager()
manager2 = fcl.DynamicAABBTreeCollisionManager()

manager1.registerObjects(objs1)
manager2.registerObjects(objs2)

manager1.setup()
manager2.setup()

#=====================================================================
# Managed internal (sub-n^2) collision checking
#=====================================================================
cdata = fcl.CollisionData()
manager1.collide(cdata, fcl.defaultCollisionCallback)
print 'Collision within manager 1?: {}'.format(cdata.result.is_collision)

##=====================================================================
## Managed internal (sub-n^2) distance checking
##=====================================================================
ddata = fcl.DistanceData()
manager1.distance(ddata, fcl.defaultDistanceCallback)
print 'Closest distance within manager 1?: {}'.format(ddata.result.min_distance)

#=====================================================================
# Managed one to many collision checking
#=====================================================================
req = fcl.CollisionRequest(num_max_contacts=100, enable_contact=True)
rdata = fcl.CollisionData(request = req)

manager1.collide(fcl.CollisionObject(mesh), rdata, fcl.defaultCollisionCallback)
print 'Collision between manager 1 and Mesh?: {}'.format(rdata.result.is_collision)
print 'Contacts:'
for c in rdata.result.contacts:
    print '\tO1: {}, O2: {}'.format(c.o1, c.o2)

#=====================================================================
# Managed many to many collision checking
#=====================================================================
rdata = fcl.CollisionData(request = req)
manager1.collide(manager2, rdata, fcl.defaultCollisionCallback)
print 'Collision between manager 1 and manager 2?: {}'.format(rdata.result.is_collision)
print 'Contacts:'
for c in rdata.result.contacts:
    print '\tO1: {}, O2: {}'.format(c.o1, c.o2)

Extracting Which Objects Are In Collision

To determine which objects are actually in collision, you'll need parse the collision data's contacts and use an additional external data structure.

Specifically, the fcl.CollisionData object that is passed into any collide() call has an internal set of contacts, stored in cdata.result.contacts. This object is a simple list of Contact objects, each of which represents a contact point between two objects. 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. This is a bit wonky, but it's part of the FCL API.

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. 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.

Here's an example.

import fcl
import numpy as np

# Create collision geometry and objects
geom1 = fcl.Cylinder(1.0, 1.0)
obj1 = fcl.CollisionObject(geom1)

geom2 = fcl.Cylinder(1.0, 1.0)
obj2 = fcl.CollisionObject(geom2, fcl.Transform(np.array([0.0, 0.0, 0.3])))

geom3 = fcl.Cylinder(1.0, 1.0)
obj3 = fcl.CollisionObject(geom3, fcl.Transform(np.array([0.0, 0.0, 3.0])))

geoms = [geom1, geom2, geom3]
objs = [obj1, obj2, obj3]
names = ['obj1', 'obj2', 'obj3']

# Create map from geometry IDs to objects
geom_id_to_obj = { id(geom) : obj for geom, obj in zip(geoms, objs) }

# Create map from geometry IDs to string names
geom_id_to_name = { id(geom) : name for geom, name in zip(geoms, names) }

# Create manager
manager = fcl.DynamicAABBTreeCollisionManager()
manager.registerObjects(objs)
manager.setup()

# Create collision request structure
crequest = fcl.CollisionRequest(num_max_contacts=100, enable_contact=True)
cdata = fcl.CollisionData(crequest, fcl.CollisionResult())

# Run collision request
manager.collide(cdata, fcl.defaultCollisionCallback)

# Extract collision data from contacts and use that to infer set of
# objects that are in collision
objs_in_collision = set()

for contact in cdata.result.contacts:
    # Extract collision geometries that are in contact
    coll_geom_0 = contact.o1
    coll_geom_1 = contact.o2

    # Get their names
    coll_names = [geom_id_to_name[id(coll_geom_0)], geom_id_to_name[id(coll_geom_1)]]
    coll_names = tuple(sorted(coll_names))
    objs_in_collision.add(coll_names)

for coll_pair in objs_in_collision:
    print('Object {} in collision with object {}!'.format(coll_pair[0], coll_pair[1]))
>>> Object obj1 in collision with object obj2!

For more examples, see examples/example.py.

python-fcl's People

Contributors

cyrilwaechter avatar dmitryneverov avatar eric-vin avatar iceflame89 avatar jackbow avatar jf--- avatar kjyv avatar mikedh avatar mjd3 avatar mmatl avatar neka-nat avatar rmumi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-fcl's Issues

Error during installation via pip

Hello,

I am quite new to python. I use Python 3.6, Windows 10 and want to install fcl via pip 'pip install python-fcl'. Do I need octomap before installing fcl? I can not install octomap aswell.

Terminal respond:
Collecting python-fcl
Using cached https://files.pythonhosted.org/packages/b4/c9/522b42c9e6842125686deac3a87b64739dac8ad8f313d02288cbe255efe2/python-fcl-0.0.11.tar.gz
ERROR: Complete output from command python setup.py egg_info:
ERROR: Traceback (most recent call last):
File "", line 1, in
File "C:\Users\roehr\AppData\Local\Temp\pip-install-z66h54fz\python-fcl\setup.py", line 45, in
raise NotImplementedError(sys.platform)
NotImplementedError: win32
----------------------------------------
ERROR: Command "python setup.py egg_info" failed with error code 1 in C:\Users\roehr\AppData\Local\Temp\pip-install-z66h54fz\python-fcl\

Can you help me out?

Thank you!

Accessing BVH Structure

Is there a way to access the underlying bounding boxes created by the BVHModel? I've seen in the C++ version that you can call getBV(int id) to access individual boxes.

Clarification about broadphase checking

In the readme, the broadphase checker is said to be able to "avoid n-squared complexity" (as is the purpose of the broad-phase, obviously). Then, one of the examples is Managed internal (n^2) collision checking. Does this mean that internal collision checking within a manager is n^2? If so, which operations are sub-n^2? I would be happy to update the readme with a bit clearer wording around this topic if someone can help me understand how exactly it works!

Accessing Collision Object Vertices

I have created a sphere as a collision object. Is there a way I can get the vertices of the sphere/collision object so that I can visualize them?

Segfault with continuous collision checking if collision object is BVHModel

As the title says it: I get a segmentation fault if I try to do a continuous collision check with a collision object that is created with a fcl.BVHModel. Is this expected behavior?

The bug can be reproduced by replacing cyl with mesh in line 111 of example.py:

dist = fcl.continuousCollide(fcl.CollisionObject(box, fcl.Transform()),
                             fcl.Transform(np.array([5.0, 0.0, 0.0])),
                             fcl.CollisionObject(mesh, fcl.Transform(np.array([5.0,0.0,0.0]))),
                             fcl.Transform(np.array([0.0, 0.0, 0.0])), 
                             req, res)

the time to create BVHModel

For large amounts of data, Why does it take more than ten times longer to create BVHModels based on Python than C++?

e.g.
the number of points is 176223, the number of triangles is 343688,

Python

m = fcl.BVHModel()
m.beginModel(len(points), len(triangles))
m.addSubModel(points, triangles)
m.endModel()

C++

std::shared_ptr<BVHModel<AABBd>> mesh_model;
mesh_model = std::make_shared<BVHModel<AABBd>>();
mesh_model->beginModel();
mesh_model->addSubModel(points, triangles);
mesh_model->endModel();

Collision check of parts that are partially inside

Hey, I'm trying to built an Assembly Sequence Planning tool. I'm trying to use python-fcl for assemblies of multiple parts, which are imported via pythonocc. For the situation shown below I get a collision returned, even though no surfaces are in contact.

I'm not sure, whether the shown meshes are exactly the same as the BVHModels. I struggled using trimesh to visualize the BVHModels, so I displayed the triangles directly within pythonocc.

Can anyone provide a code snippet to visualy check the BVHModels?
Are there any options / workarounds to check collision for parts that are positioned inside other parts with fcl ?

grafik

Sphere to Mesh nearest point results in nonsense when intersecting

Using fcl.distance on a small sphere intersecting the face of the mesh and a BVH representation of that mesh results in nearest points that are not on the mesh OR the sphere. Reproducer below (includes trimesh for visualization; you will need to install pyglet <2.0).

Seems likely this is an FCL, not python-fcl, issue, but thought I should report here first since that's where I encountered it.

import numpy as np
import fcl
import trimesh
#Use Trimesh to visualize the problematic scenario; requires pyglet<2.0
verts = np.array([[1.0, 1.0, 1.0],
                  [2.0, 1.0, 1.0],
                  [1.0, 2.0, 1.0],
                  [1.0, 1.0, 2.0]])
tris  = np.array([[0,2,1],
                  [0,3,2],
                  [0,1,3],
                  [1,2,3]])
query=np.array([1.5,1.25,1.0])
test_rad=0.0001
plot_rad=0.01
mesh=trimesh.Trimesh(vertices=verts,faces=tris)
mesh.visual.face_colors[:,-1]=100
edges=trimesh.load_path(mesh.vertices[mesh.edges_unique])
green_sphere=trimesh.primitives.Sphere(radius=plot_rad,center=query)
green_sphere.visual.face_colors=np.array([0,255,0,255])

bvhmesh=fcl.BVHModel()
bvhmesh.beginModel(len(verts),len(tris))
bvhmesh.addSubModel(verts,tris)
bvhmesh.endModel()
collision_mesh=fcl.CollisionObject(bvhmesh,fcl.Transform())

t=fcl.Transform(np.eye(3),query)
sphere=fcl.Sphere(test_rad)
collision_sphere=fcl.CollisionObject(sphere,t)

request=fcl.DistanceRequest(enable_nearest_points=True,enable_signed_distance=True)
result=fcl.DistanceResult()

ret=fcl.distance(collision_mesh,collision_sphere,request,result)

red_sphere=trimesh.primitives.Sphere(radius=plot_rad,center=result.nearest_points[0])
red_sphere.visual.face_colors=np.array([255,0,0,255])

blue_sphere=trimesh.primitives.Sphere(radius=plot_rad,center=result.nearest_points[1])
blue_sphere.visual.face_colors=np.array([0,0,255,255])

scene=trimesh.Scene([mesh,edges,green_sphere,red_sphere,blue_sphere])
scene.show()

EDIT: Screenshot of result of script. Green is the query point, blue and red are the "nearest points."
FCL Sphere to mesh failure

BVHModel.begin_update() not found

Thank you for your software, it has come in handy many times. I am right now facing a performance problem. I want to check the collision between 2 meshes (BVHModel) but the one changes its vertices dynamically. I have seen in the c++ documentation that there is a function begin_update() which updates the vertices of the mesh immediately without having to regenerate the whole mesh (which is slow) but I can't find it at the python binding. Do you have any further info or another solution to my problem?

Support the latest version of FCL (v0.6.1)?

Hi, thank you for this excellent project.

I'm wondering if there is a plan to support FCL v0.6.X. The current README says

Currently, this package is targeted for FCL 0.5.0.

but the latest FCL version available in Homebrew ( https://github.com/Homebrew/homebrew-core/blob/master/Formula/fcl.rb ) is v0.6.1.

This means that macOS users cannot simply install python-fcl through brew and pip:

brew install fcl # This installs FCL v0.6.1
pip install python-fcl # This generates errors because of the version mismatch!

but need to install FCL 0.5.0 manually (e.g., by writing a custom brew file to install FCL v0.5.0).

Source distribution is not available on pypi after 0.6.1

According to https://pypi.org/project/python-fcl/0.0.12/#files, after 0.6.1, no source distribution is released on pypi. This results in failure in pip installing from any ARM machine because wheel distribution is not released in the first place.

Could you release the source distribution when you have time? @mjd3 @mmatl

In fact, On x86 marchine latest version is available

h-ishida@stonep:~$ pip3 install python-fcl==whatever-version
ERROR: Could not find a version that satisfies the requirement python-fcl==whatever-version (from versions: 0.0.4, 0.0.6, 0.0.7, 0.0.9, 0.0.10, 0.0.11, 0.0.12, 0.6.1, 0.6.11, 0.7.0, 0.7.0.1)
ERROR: No matching distribution found for python-fcl==whatever-version

While, on ARM machine available latest version is 0.0.12 and newer versions are not available

h-ishida@a5e40f79ba8e:~/python-fcl$ pip3 install python-fcl==whatever-version
ERROR: Could not find a version that satisfies the requirement python-fcl==whatever-version (from versions: 0.0.4, 0.0.6, 0.0.7, 0.0.9, 0.0.10, 0.0.11, 0.0.12)

Quaternion

Hi!

Does the first digit of q that passed to tf = fcl.Transform(q, T) represent x or w?

Thanks!

Mac ARM version

Has anyone built MacOS ARM versions for Python 3.9 or 3.10? When I try to compile from source I get a lot of C++ errors that I am not equipped to try to fix.

I'd really appreciate any help!

Incorrect project links on PyPI?

The PyPI project links to the fork https://github.com/CyrilWaechter/python-fcl as the project homepage; links in the “GitHub Statistics” section also go to that project.

Based on the version numbers in https://pypi.org/project/python-fcl/#files, it looks like releases to PyPI are not built from that fork, which has not been updated in some time, but from this repository (https://github.com/BerkeleyAutomation/python-fcl/).

Could the PyPI metadata be updated to link to the correct project?

Incorrect collision contact point on BVHModel

I am new to these concepts so please excuse this beginner query. I have two BVHModels that represent the two below shapes. The CollisionObjects contain the BVHModel with the correct vertices, faces, and transformations. I have checked this manually to confirm.

However, collide() results tell me there is a collision, located at the crosshair in the image below.

I do not understand why this is the case. Is BVHModel the wrong type to use, due to the concave nature of the shape?

image

Issues with Dockerfile

I am having issues building an image from the Dockerfile. Specifically, build.bash fails with these error messages:

Step 8/12 : RUN bash build.bash
 ---> Running in cad4162835d3
build.bash: /usr/bin/cmake: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
make: *** No targets specified and no makefile found.  Stop.
make: *** No rule to make target `install'.  Stop.
build.bash: /usr/bin/cmake: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
make: *** No targets specified and no makefile found.  Stop.
make: *** No rule to make target `install'.  Stop.
build.bash: /usr/bin/cmake: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
make: *** No targets specified and no makefile found.  Stop.
make: *** No rule to make target `install'.  Stop.

There are some other fixes I want to propose to the Dockerfile, but I am stuck on this error and have no more extra time to spend on this. This error occurs for me on Ubuntu 18.04 as well as Docker for Mac. Could you confirm?

Wheels for Python 3.12

Now that 3.12.0rc1 has been released, would it be possible to create wheels for Python 3.12 and post them to PyPi?

Identifying the CollisionObjects that overlap using collide()

As per my email, I have a question about identifying the objects that collide using python-fcl:

In my use case, I have many cylinder CollisionObjects in one manager. When I call manager.collide(), I get back the number of contact points and their locations and the distance between the objects that collide.

However, I'd like to know which objects are actually colliding. For example, if I have 4 CollisionObjects named obj1, ..., obj4 in my manager and only 2 of them collide, it appears that the collide() method only returns objects named o1 and o2. Do o1 and o2 contain identifiers that map them back to one of the original obj ``CollisionObjects?

Thanks in advance,
Lee

Can't install Python-FCL, please help

PS C:\Users...\Desktop\Python\venv> pip install python-fcl
Collecting python-fcl
Using cached python-fcl-0.0.12.tar.gz (17 kB)
ERROR: Command errored out with exit status 1:
command: 'c:\users...\appdata\local\programs\python\python39\python.exe' -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\...\AppData\Local\Temp\pip-install-cds4ao_r\python-fcl_94f219e272744b3d9053c1de3b1b1da8\setup.py'"'"'; file='"'"'C:\Users\...\AppData\Local\Temp\pip-install-cds4ao_r\python-fcl_94f219e272744b3d9053c1de3b1b1da8\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users...\AppData\Local\Temp\pip-pip-egg-info-yld_5lnw'
cwd: C:\Users...\AppData\Local\Temp\pip-install-cds4ao_r\python-fcl_94f219e272744b3d9053c1de3b1b1da8
Complete output (5 lines):
Traceback (most recent call last):
File "", line 1, in
File "C:\Users...\AppData\Local\Temp\pip-install-cds4ao_r\python-fcl_94f219e272744b3d9053c1de3b1b1da8\setup.py", line 45, in
raise NotImplementedError(sys.platform)
NotImplementedError: win32
----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/d6/1a/51e9a3cf8473f297226396ad508702483f4fe3df9bb60676b35d2aca340d/python-fcl-0.0.12.tar.gz#sha256=f5e60c4f2f43f72f0029435dd4bac61a7e5867c53cf14adc54afe67dc8ad3510 (from https://pypi.org/simple/python-fcl/). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Example usages for fcl.OcTree

Would it be possible to add tests and examples using fcl.OcTree. Could you give an instantiation example? I assume it should be read from bytes representing an octree. If I give:

fcl_tree =fcl.OcTree(0.1, data)

It gives the following error:
Traceback (most recent call last): File "example1.py", line 20, in <module> fcl_tree =fcl.OcTree(0.1, data) File "fcl/fcl.pyx", line 403, in fcl.fcl.OcTree.__cinit__ File "stringsource", line 48, in vector.from_py.__pyx_convert_vector_from_py_char TypeError: an integer is required

Wrong result on collision check

Hello, I am testing python-fcl for using in collision detection.
I 'm getting wrong results from library using this code example:

import numpy as np
import fcl

# Cylinder geometry displaced
geom1 = fcl.Cylinder(1.0, 4.0)
obj1 = fcl.CollisionObject(geom1)
obj1.setTranslation(np.array([0.5, 2, 1.0]))

# Same cylinder geometry rotated around x axis 90 degrees and displaced
geom2 = fcl.Cylinder(1.0, 4)
obj2 = fcl.CollisionObject(geom2)
obj2.setRotation(np.array([[ 1.,0. ,0.],[ 0., 0., 1.],[ 0., -1., 0.]]))
obj2.setTranslation(np.array([0.5, -1.1, 2]))

# Check collision
request = fcl.CollisionRequest(num_max_contacts=1, enable_contact=True)
result = fcl.CollisionResult()
cdata = fcl.CollisionData(request, result)
ret = fcl.collide(obj1, obj2, request, result)

# Print results
print('Collision?: ','No' if ret==0 else 'Yes')
print([x.pos for x in cdata.result.contacts])

Here I show the objects drawn in FreeCAD:
2023-08-12-20h56-32

However python-fcl indicates that there is no collision. ¿could it my mistake with code values?

Thank you for your awesome piece of code,
Dani.

How to use fcl.OcTree in python-fcl.

Hey everyone!

I am wondering is it possible to create an octree from point cloud using fcl.OcTree, then do the collision detection using fcl.OcTree. Issue #7 mentioned the similar question, but I can't find answers there. Could you guys offer some examples on how to use this.

Thanks a lot!

Cannot install python-fcl on pop os

I am facing this issue while installing the python-fcl package
(I have octomap installed ) i followed the steps and always get this error message :
Collecting python-fcl
Using cached python-fcl-0.0.12.tar.gz (17 kB)
Requirement already satisfied: numpy in /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages (from python-fcl) (1.20.1)
Requirement already satisfied: cython in /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages (from python-fcl) (0.29.23)
Building wheels for collected packages: python-fcl
Building wheel for python-fcl (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: /home/hamdiharaketi/anaconda3/envs/downgrade/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/setup.py'"'"'; file='"'"'/tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-w9m44af_
cwd: /tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/
Complete output (28 lines):
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.8
creating build/lib.linux-x86_64-3.8/fcl
copying fcl/collision_data.py -> build/lib.linux-x86_64-3.8/fcl
copying fcl/version.py -> build/lib.linux-x86_64-3.8/fcl
copying fcl/init.py -> build/lib.linux-x86_64-3.8/fcl
running build_ext
cythoning fcl/fcl.pyx to fcl/fcl.cpp
building 'fcl.fcl' extension
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/fcl
gcc -pthread -B /home/hamdiharaketi/anaconda3/envs/downgrade/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/include -I/usr/local/include -I/usr/include/eigen3 -I/home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include -I/home/hamdiharaketi/anaconda3/envs/downgrade/include/python3.8 -c fcl/fcl.cpp -o build/temp.linux-x86_64-3.8/fcl/fcl.o -std=c++11
cc1plus: attention: l'option de la ligne de commande « -Wstrict-prototypes » est valable pour C/ObjC mais pas pour C++
Dans le fichier inclus depuis /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/ndarraytypes.h:1944,
depuis /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
depuis /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/arrayobject.h:4,
depuis fcl/fcl.cpp:633:
/home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: attention: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
17 | #warning "Using deprecated NumPy API, disable it with "
| ^~~~~~~
fcl/fcl.cpp:656:10: erreur fatale: octomap/OccupancyOcTreeBase.h : Aucun fichier ou dossier de ce type
656 | #include "octomap/OccupancyOcTreeBase.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminée.
error: command 'gcc' failed with exit status 1

ERROR: Failed building wheel for python-fcl
Running setup.py clean for python-fcl
Failed to build python-fcl
Installing collected packages: python-fcl
Running setup.py install for python-fcl ... error
ERROR: Command errored out with exit status 1:
command: /home/hamdiharaketi/anaconda3/envs/downgrade/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/setup.py'"'"'; file='"'"'/tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /tmp/pip-record-p3qgen2b/install-record.txt --single-version-externally-managed --compile --install-headers /home/hamdiharaketi/anaconda3/envs/downgrade/include/python3.8/python-fcl
cwd: /tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/
Complete output (28 lines):
running install
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.8
creating build/lib.linux-x86_64-3.8/fcl
copying fcl/collision_data.py -> build/lib.linux-x86_64-3.8/fcl
copying fcl/version.py -> build/lib.linux-x86_64-3.8/fcl
copying fcl/init.py -> build/lib.linux-x86_64-3.8/fcl
running build_ext
skipping 'fcl/fcl.cpp' Cython extension (up-to-date)
building 'fcl.fcl' extension
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/fcl
gcc -pthread -B /home/hamdiharaketi/anaconda3/envs/downgrade/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/include -I/usr/local/include -I/usr/include/eigen3 -I/home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include -I/home/hamdiharaketi/anaconda3/envs/downgrade/include/python3.8 -c fcl/fcl.cpp -o build/temp.linux-x86_64-3.8/fcl/fcl.o -std=c++11
cc1plus: attention: l'option de la ligne de commande « -Wstrict-prototypes » est valable pour C/ObjC mais pas pour C++
Dans le fichier inclus depuis /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/ndarraytypes.h:1944,
depuis /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
depuis /home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/arrayobject.h:4,
depuis fcl/fcl.cpp:633:
/home/hamdiharaketi/anaconda3/envs/downgrade/lib/python3.8/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: attention: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
17 | #warning "Using deprecated NumPy API, disable it with "
| ^~~~~~~
fcl/fcl.cpp:656:10: erreur fatale: octomap/OccupancyOcTreeBase.h : Aucun fichier ou dossier de ce type
656 | #include "octomap/OccupancyOcTreeBase.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminée.
error: command 'gcc' failed with exit status 1
----------------------------------------
ERROR: Command errored out with exit status 1: /home/hamdiharaketi/anaconda3/envs/downgrade/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/setup.py'"'"'; file='"'"'/tmp/pip-install-0kgk9pn3/python-fcl_c4c6e2e8fc484e71b7203662422d1846/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /tmp/pip-record-p3qgen2b/install-record.txt --single-version-externally-managed --compile --install-headers /home/hamdiharaketi/anaconda3/envs/downgrade/include/python3.8/python-fcl Check the logs for full command output.

nearest points inconsistent

Hello,

I was using this library to do simple 2d collision detection. However, when using the collision managers to get nearest points (witness points), I am seeing some inconsistencies - basically the distance between the nearest points does NOT equal to min_distance. A supposedly reproducible code is here:

import fcl
from scipy.spatial.transform import Rotation
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import matplotlib.patheffects as path_effects
from matplotlib.cm import get_cmap
import seaborn as sns
sns.set()

box1, box1_t = (20., 5.), (-2.0,0.0)
box2, box2_t = (5,5), (-5., 10.)
box3, box3_t = (5, 5), (-15., 15.)
theta1, theta2 = np.pi/3, 0
theta3 = 0


h = 1000
box1_bottom_left, box2_bottom_left, box3_bottom_left = (-box1[0]/2, -box1[1]/2), (-box2[0]/2, -box2[1]/2), (-box3[0]/2, -box3[0]/2)
g1 = fcl.Box(*box1, h)
t1 = fcl.Transform(Rotation.from_rotvec([0., 0., theta1]).as_quat()[[3,0,1,2]], [*box1_t,0])
o1 = fcl.CollisionObject(g1, t1)
g2 = fcl.Box(*box2, h)
t2 = fcl.Transform(Rotation.from_rotvec([0., 0., theta2]).as_quat()[[3,0,1,2]], [*box2_t,0])
o2 = fcl.CollisionObject(g2, t2)
g3 = fcl.Box(*box3, h)
t3 = fcl.Transform(Rotation.from_rotvec([0., 0., theta3]).as_quat()[[3,0,1,2]], [*box3_t,0])
o3 = fcl.CollisionObject(g3, t3)

robot_manager = fcl.DynamicAABBTreeCollisionManager()
robot_manager.registerObjects([o1])
robot_manager.setup()
obs_manager = fcl.DynamicAABBTreeCollisionManager()
obs_manager.registerObjects([o2, o3])
# obs_manager.registerObjects([o3, o2])

obs_manager.setup()
ddata = fcl.DistanceData(request=fcl.DistanceRequest(enable_nearest_points=True))
robot_manager.distance(obs_manager, ddata, fcl.defaultDistanceCallback)
assert ddata.result.min_distance == np.linalg.norm(ddata.result.nearest_points[1][:2]-ddata.result.nearest_points[0][:2]), \
    (ddata.result.min_distance, np.linalg.norm(ddata.result.nearest_points[1][:2]-ddata.result.nearest_points[0][:2]))

## below are just visualization
box1_bottom_left = (Rotation.from_rotvec([0., 0., theta1]).as_matrix() @ np.array([*box1_bottom_left, 0]))[:2]+box1_t
box2_bottom_left = (Rotation.from_rotvec([0., 0., theta2]).as_matrix() @ np.array([*box2_bottom_left, 0]))[:2]+box2_t
box3_bottom_left = (Rotation.from_rotvec([0., 0., theta3]).as_matrix() @ np.array([*box3_bottom_left, 0]))[:2]+box3_t

p_o1 = ddata.result.nearest_points[0][:2]
p_o2 = ddata.result.nearest_points[1][:2]
fig, ax = plt.subplots(1,1)
ax.set_xlim(-30, 30)
ax.set_ylim(-30, 30)
ax.set_aspect('equal', adjustable='box')

cmaps = [get_cmap('Reds'), get_cmap('Blues')]
with sns.axes_style('ticks'):
    ax.add_patch(Rectangle(tuple(box1_bottom_left), *box1, angle=np.degrees(theta1), path_effects=[path_effects.withSimplePatchShadow()], color=cmaps[1](0.5), alpha=0.5))
    ax.add_patch(Rectangle(tuple(box2_bottom_left), *box2, angle=np.degrees(theta2), path_effects=[path_effects.withSimplePatchShadow()], color=cmaps[0](0.5), alpha=0.5))
    ax.add_patch(Rectangle(tuple(box3_bottom_left), *box3, angle=np.degrees(theta3), path_effects=[path_effects.withSimplePatchShadow()], color=cmaps[0](0.5), alpha=0.5))
ax.plot(*p_o1, 'o', color=cmaps[1](0.5), markersize=4)
ax.plot(*p_o2, 'o', color=cmaps[0](0.5), markersize=4)
plt.show(block=True)

You can uncomment one of these two lines and you should be able to see the nearest points are not consistent in two runs:

obs_manager.registerObjects([o2, o3])
# obs_manager.registerObjects([o3, o2])

Interestingly, I tried using raw FCL and it does not have the problem. Code also here:

#include <Eigen/Dense>
#include <unsupported/Eigen/MatrixFunctions>
#include "math.h"

using namespace fcl;
int main(int argc, char** argv)
{
  DistanceResultd result;
  DistanceRequestd request;

  std::shared_ptr<CollisionGeometryd> box_geometry_1(
    new Boxd(20, 5, 1000));
  std::shared_ptr<CollisionGeometryd> box_geometry_2(
    new Boxd(5, 5, 1000));
  std::shared_ptr<CollisionGeometryd> box_geometry_3(
    new Boxd(5, 5, 1000));
  CollisionObjectd box_object_1(
    box_geometry_1, Eigen:: Quaterniond(std::cos(M_PI/6), 0, 0, std::sin(M_PI/6)).matrix(),
    Eigen::Vector3d(-2, 0.000000, 0.00000));
  CollisionObjectd box_object_2(
    box_geometry_2, Eigen:: Quaterniond(1, 0, 0, 0).matrix(),
    Eigen::Vector3d(-5, 10, 0.00000));
  CollisionObjectd box_object_3(
    box_geometry_3, Eigen:: Quaterniond(1, 0, 0, 0).matrix(),
    Eigen::Vector3d(-5, 15, 0.00000));
  
  auto manager1 = new DynamicAABBTreeCollisionManagerd();
  auto manager2 = new DynamicAABBTreeCollisionManagerd();
  std::vector<CollisionObjectd*> robot;
  robot.push_back(&box_object_1);
  std::vector<CollisionObjectd*> obs;
  obs.push_back(&box_object_3);
  obs.push_back(&box_object_2);
  manager1->registerObjects(robot);
  manager2->registerObjects(obs);
  
  DefaultDistanceData<double> ddata;
  manager1->distance(manager2, &ddata, DefaultDistanceFunction<double>);
  std::cout << ddata.result.nearest_points[0] << std::endl << ddata.result.nearest_points[1] << std::endl;
  std::cout << sqrt((ddata.result.nearest_points[1]-ddata.result.nearest_points[0]).squaredNorm()) << std::endl;
  std::cout << ddata.result.min_distance << std::endl;
  return 0;
}

Building on OSX Catalina - Resolving math.h errors

FWIW, I had a lot of trouble building on OSX 10.15. The problem ended up being the include paths to the SDK included by setuptools in the CFLAGS variable. Here are my changes to setup.py to fix the issue:

import os
import sys

from setuptools.command.build_ext import build_ext
from setuptools import Extension, setup
from Cython.Build import cythonize

INSTALL_PREFIX_WIN = "deps\\install"


def is_nix_platform(platform):
    for prefix in ["darwin", "linux", "bsd"]:
        if prefix in sys.platform:
            return True
    return False


def get_include_dirs():
    if is_nix_platform(sys.platform):
        include_dirs = [
            "/usr/include",
            "/usr/local/include",
            "/usr/include/eigen3",
            "/usr/local/include/eigen3",
        ]

        if "CPATH" in os.environ:
            include_dirs += os.environ["CPATH"].split(":")

    elif sys.platform == "win32":
        include_dirs = [
            f"{INSTALL_PREFIX_WIN}\\include",
            f"{INSTALL_PREFIX_WIN}\\include\\eigen3",
        ]
    else:
        raise NotImplementedError(sys.platform)

    # get the numpy include path from numpy
    import numpy

    include_dirs.append(numpy.get_include())
    return include_dirs


def get_libraries_dir():
    if is_nix_platform(sys.platform):
        lib_dirs = ["/usr/lib", "/usr/local/lib"]

        if "LD_LIBRARY_PATH" in os.environ:
            lib_dirs += os.environ["LD_LIBRARY_PATH"].split(":")
        return lib_dirs
    if sys.platform == "win32":
        return [f"{INSTALL_PREFIX_WIN}\\lib"]

    raise NotImplementedError(sys.platform)


def get_libraries():
    libraries = ["fcl", "octomap"]
    if sys.platform == "win32":
        libraries.extend(["octomath", "ccd", "vcruntime"])
    return libraries


class custom_build_ext(build_ext):
    def build_extensions(self):
        compiler_so_new = []
        for v in self.compiler.compiler_so:
            if "MacOSX10.15" in v:
                pass
            else:
                compiler_so_new.append(v)

        self.compiler.compiler_so = compiler_so_new
        build_ext.build_extensions(self)


setup(
    ext_modules=cythonize(
        [
            Extension(
                "fcl.fcl",
                ["src/fcl/fcl.pyx"],
                include_dirs=get_include_dirs(),
                library_dirs=get_libraries_dir(),
                libraries=get_libraries(),
                language="c++",
                extra_compile_args=["-std=c++11"],
            )
        ],
    ),
    cmdclass={"build_ext": custom_build_ext}
)

Macos with m1 chip support

On macos with m1 chip, pip could not find the latest version 0.6.1.

$ pip install python-fcl==0.6.1                                                 
ERROR: Could not find a version that satisfies the requirement python-fcl==0.6.1 (from versions: 0.0.4, 0.0.6, 0.0.7, 0.0.9, 0.0.10, 0.0.11, 0.0.12)
ERROR: No matching distribution found for python-fcl==0.6.1

Windows Support

Is there any way this library can be compiled to work on Windows?

Is it technically feasible or possible?

Does collision-checking use an approximate or exact algorithm to check collision between two shapes?

I tried your library to check the collision between two ellipsoids. It works well in cases where both ellipsoids have a large overlap but it fails to detect a collision when both barely overlap. I confirmed this by plotting the ellipsoids in 3D and noticing that they overlap a bit. It is small but not negligible.

However, fcl seems to not detect the collision. So, I can only assume that you guys are using an approximate algorithm. Is there a way to force your library to use an exact algorithm? Or maybe I can change some parameters in your collision check algorithm to make it work for my case?

python-fcl Import Error

I'm getting the following error when importing python-fcl:

>>> import fcl
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ericvin/.cache/pypoetry/virtualenvs/scenic-Ux1uqsAP-py3.9/lib/python3.9/site-packages/fcl/__init__.py", line 2, in <module>
    from .fcl import (
ImportError: /home/ericvin/.cache/pypoetry/virtualenvs/scenic-Ux1uqsAP-py3.9/lib/python3.9/site-packages/fcl/fcl.cpython-39-x86_64-linux-gnu.so: undefined symbol: _ZTIN3fcl17CollisionGeometryIdEE

I've installed python-fcl using Poetry and revision f0836e2 (Not using the PyPi package since it hasn't been updated since 2019), which I think is the most up to date. I also have fcl (0.6.1) installed.

From quickly googling it looks like @CyrilWaechter had the same issue in pypa/cibuildwheel#775 (comment) .

macOS arm wheel ImportError symbol not found

ImportError: dlopen(.venv/lib/python3.9/site-packages/fcl/fcl.cpython-39-darwin.so, 0x0002): symbol not found in flat namespace '__ZNK3fcl17CollisionGeometryIdE34computeMomentofInertiaRelatedToCOMEv'

I'm getting the above error after installing python-fcl v0.7.0.4 and I think it's because the following env vars aren't being set. The following code produces a working wheel for me (which I've just committed to my own repo for convenience).

CPATH=$(brew --prefix)/include:$(brew --prefix)/include/eigen3 LD_LIBRARY_PATH=$(brew --prefix)/lib python setup.py bdist_wheel --universal

I'm not sure if that code will work with the github action runner since its running on intel building for arm, and I'm not sure if it's using brew, but it could be worth a shot by using env.CIBW_ENVIRONMENT_MACOS in the pypa/cibuildwheel step.
https://cibuildwheel.readthedocs.io/en/stable/options/#environment

I may get around to doing this but I'm writing this here in case I don't.

fcl/fcl_defs.pxd is missing in sdist generated tarballs

Hi,
the uploaded pypi tarball for python-fcl doesn't contain the file
fcl/fcl_defs.pxd and therefore on all non linux machines pip install python-fcl is failing.
I triggered the issue down to a missing line in MANIFEST.in:

include fcl/fcl_defs.pxd

will fix this problem!

Please add this asap and redistribute the pypi tar balls.

Cheers,
Oliver

meet TypeError when running example.py

hi, i'm using ubunu22.04 and i install python-fcl by pip. when i copy example.py to my project and run it, i got
Traceback (most recent call last): File "/home/letitia/test_ws/src/pytest/test/fcltest.py", line 89, in <module> req = fcl.DistanceRequest(enable_nearest_points=True, enable_signed_distance=True) TypeError: DistanceRequest.__init__() got an unexpected keyword argument 'enable_signed_distance'

could somebody help me to solve this problem?

how to compile python-fcl wheel from source?

@mikedh
Hi, I want to compile python-fcl on windows, but failed. I do not know how to compile this wheel successfully? Thanks!
and It also failed by using the dockerfile or compiling on linux
step as blew:

  1. powershell .\build_dependencies\install_windows.ps1
  2. cd python-fcl
  3. pip wheel ./ --no-deps -w wheelhouse/

get the errro

Processing d:\works\basic_lib\python-fcl
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error

  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [105 lines of output]

      Error compiling Cython file:
      ------------------------------------------------------------
      ...
              return list(self.objs)

          def collide(self, *args):
              if len(args) == 2 and inspect.isroutine(args[1]):
                  fn = CollisionFunction(args[1], args[0])
                  self.thisptr.collide(<void*> fn, CollisionCallBack)
                                                   ^
      ------------------------------------------------------------

      src\fcl\fcl.pyx:529:45: Cannot assign type 'bool (CollisionObjectd *, CollisionObjectd *, void *) except? -1' to 'CollisionCallBack'

      Error compiling Cython file:
      ------------------------------------------------------------
      ...
              if len(args) == 2 and inspect.isroutine(args[1]):
                  fn = CollisionFunction(args[1], args[0])
                  self.thisptr.collide(<void*> fn, CollisionCallBack)
              elif len(args) == 3 and isinstance(args[0], DynamicAABBTreeCollisionManager):
                  fn = CollisionFunction(args[2], args[1])
                  self.thisptr.collide((<DynamicAABBTreeCollisionManager?> args[0]).thisptr, <void*> fn, CollisionCallBack)
                                      ^
      ------------------------------------------------------------

      src\fcl\fcl.pyx:532:32: no suitable method found

      Error compiling Cython file:
      ------------------------------------------------------------
      ...
              elif len(args) == 3 and isinstance(args[0], DynamicAABBTreeCollisionManager):
                  fn = CollisionFunction(args[2], args[1])
                  self.thisptr.collide((<DynamicAABBTreeCollisionManager?> args[0]).thisptr, <void*> fn, CollisionCallBack)
              elif len(args) == 3 and inspect.isroutine(args[2]):
                  fn = CollisionFunction(args[2], args[1])
                  self.thisptr.collide((<CollisionObject?> args[0]).thisptr, <void*> fn, CollisionCallBack)
                                      ^
      ------------------------------------------------------------

      src\fcl\fcl.pyx:535:32: no suitable method found

      Error compiling Cython file:
      ------------------------------------------------------------
      ...
                  raise ValueError

          def distance(self, *args):
              if len(args) == 2 and inspect.isroutine(args[1]):
                  fn = DistanceFunction(args[1], args[0])
                  self.thisptr.distance(<void*> fn, DistanceCallBack)
                                                    ^
      ------------------------------------------------------------

      src\fcl\fcl.pyx:542:46: Cannot assign type 'bool (CollisionObjectd *, CollisionObjectd *, void *, double &) except? -1' to 'DistanceCallBack'

      Error compiling Cython file:
      ------------------------------------------------------------
      ...
              if len(args) == 2 and inspect.isroutine(args[1]):
                  fn = DistanceFunction(args[1], args[0])
                  self.thisptr.distance(<void*> fn, DistanceCallBack)
              elif len(args) == 3 and isinstance(args[0], DynamicAABBTreeCollisionManager):
                  fn = DistanceFunction(args[2], args[1])
                  self.thisptr.distance((<DynamicAABBTreeCollisionManager?> args[0]).thisptr, <void*> fn, DistanceCallBack)
                                       ^
      ------------------------------------------------------------

      src\fcl\fcl.pyx:545:33: no suitable method found

      Error compiling Cython file:
      ------------------------------------------------------------
      ...
              elif len(args) == 3 and isinstance(args[0], DynamicAABBTreeCollisionManager):
                  fn = DistanceFunction(args[2], args[1])
                  self.thisptr.distance((<DynamicAABBTreeCollisionManager?> args[0]).thisptr, <void*> fn, DistanceCallBack)
              elif len(args) == 3 and inspect.isroutine(args[2]):
                  fn = DistanceFunction(args[2], args[1])
                  self.thisptr.distance((<CollisionObject?> args[0]).thisptr, <void*> fn, DistanceCallBack)
                                       ^
      ------------------------------------------------------------

      src\fcl\fcl.pyx:548:33: no suitable method found

'Symbol not found in flat namespace' and 'fatal error: 'octomap/OccupancyOcTreeBase.h' file not found` on OSX Sonoma 14.1

Hello,

I encountered various issues trying to install python-fcl on an M3 Max OSX Sonoma 14.1 machine:

In a fresh python3.11 environment (or at least, my (base) conda environment), and also in my python3.10 environment with various other packages installed, i observed the following:

pip install python fcl
python
>>> import fcl

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/araistrick/miniconda3/lib/python3.11/site-packages/fcl/__init__.py", line 2, in <module>
    from .fcl import (
ImportError: dlopen(/Users/araistrick/miniconda3/lib/python3.11/site-packages/fcl/fcl.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '__ZNK3fcl17CollisionGeometryIdE34computeMomentofInertiaRelatedToCOMEv'

Note: pip chose to install python-fcl==0.7.0.5

Directly installing from github I get the following:

pip install 'python-fcl @ git+https://github.com/BerkeleyAutomation/python-fcl.git'

#warning "Using deprecated NumPy API, disable it with " \
       ^
      src/fcl/fcl.cpp:820:10: fatal error: 'octomap/OccupancyOcTreeBase.h' file not found
      #include "octomap/OccupancyOcTreeBase.h"
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      1 warning and 1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for python-fcl
Failed to build python-fcl

I then tried to get octomap from homebrew:

brew install octomap
export CPATH="/opt/homebrew/include:$CPATH"
pip install 'python-fcl @ git+https://github.com/BerkeleyAutomation/python-fcl.git'

src/fcl/fcl.cpp:813:10: fatal error: 'numpy/arrayobject.h' file not found
      #include "numpy/arrayobject.h"
               ^~~~~~~~~~~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1

I then tried manually adding my numpy.get_include() path to my CPATH:

export CPATH="/Users/araistrick/miniconda3/envs/infinigen/lib/python3.10/site-packages/numpy/core/include:$CPATH"
pip install 'python-fcl @ git+https://github.com/BerkeleyAutomation/python-fcl.git'  

 src/fcl/fcl.cpp:840:10: fatal error: 'fcl/common/types.h' file not found
      #include "fcl/common/types.h"
               ^~~~~~~~~~~~~~~~~~~~
      1 warning and 1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1

At which point it feels something deeper is going wrong and im not sure how to proceed, or perhaps im wrong in assuming that install from github would work.

Would appreciate any help, I recognize my environment is quite new. My numpy version is also very old (1.26.2) so I will update and retry also.

Penetration depth between mesh and mesh

Hello,this problem has bothered me for a long time,I wonder if the penetration depth is expressed by the minimum distance when two convex meshes collide? Can only return 0 in collision?

Why the collision result remain the same, no matter how I change the box scale and position when I run the example.py file

Why is the collision result always True? And why is the distance between the two objects always -1.0. Actually I have changed the sizes and postions of the test objects for multiple times, sometimes, it is obviouly that the two objects will no collide with each other(for example, I set the two objects very far from each other), but the result remain the unchanged of being Collided. No error was raised.
And my python-fcl version is python-fcl-win32-nr.
What is wrong with my scripts? or Is there any dependency which I need to install?
Thanks a lot for help.
image

python 3.10 support?

I was able to use the library just fine up till python 3.9. With python 3.10, when I run pip install python-fcl, I get the following error:

Collecting python-fcl
  Using cached python-fcl-0.0.12.tar.gz (17 kB)
Requirement already satisfied: numpy in /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages (from python-fcl) (1.22.3)
Requirement already satisfied: cython in /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages (from python-fcl) (0.29.28)
Building wheels for collected packages: python-fcl
  Building wheel for python-fcl (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/muhammadmehdi/anaconda3/envs/memex/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/setup.py'"'"'; __file__='"'"'/tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-fk87rphu
       cwd: /tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/
  Complete output (27 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-3.10
  creating build/lib.linux-x86_64-3.10/fcl
  copying fcl/__init__.py -> build/lib.linux-x86_64-3.10/fcl
  copying fcl/collision_data.py -> build/lib.linux-x86_64-3.10/fcl
  copying fcl/version.py -> build/lib.linux-x86_64-3.10/fcl
  running build_ext
  cythoning fcl/fcl.pyx to fcl/fcl.cpp
  building 'fcl.fcl' extension
  creating build/temp.linux-x86_64-3.10
  creating build/temp.linux-x86_64-3.10/fcl
  gcc -pthread -B /home/muhammadmehdi/anaconda3/envs/memex/compiler_compat -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/muhammadmehdi/anaconda3/envs/memex/include -fPIC -O2 -isystem /home/muhammadmehdi/anaconda3/envs/memex/include -fPIC -I/usr/include -I/usr/local/include -I/usr/include/eigen3 -I/home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include -I/home/muhammadmehdi/anaconda3/envs/memex/include/python3.10 -c fcl/fcl.cpp -o build/temp.linux-x86_64-3.10/fcl/fcl.o -std=c++11
  In file included from /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/ndarraytypes.h:1960,
                   from /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                   from /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/arrayobject.h:5,
                   from fcl/fcl.cpp:708:
  /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
     17 | #warning "Using deprecated NumPy API, disable it with " \
        |  ^~~~~~~
  fcl/fcl.cpp:732:10: fatal error: octomap/OccupancyOcTreeBase.h: No such file or directory
    732 | #include "octomap/OccupancyOcTreeBase.h"
        |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  compilation terminated.
  error: command '/usr/bin/gcc' failed with exit code 1
  ----------------------------------------
  ERROR: Failed building wheel for python-fcl
  Running setup.py clean for python-fcl
Failed to build python-fcl
Installing collected packages: python-fcl
    Running setup.py install for python-fcl ... error
    ERROR: Command errored out with exit status 1:
     command: /home/muhammadmehdi/anaconda3/envs/memex/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/setup.py'"'"'; __file__='"'"'/tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-owwnkyzy/install-record.txt --single-version-externally-managed --compile --install-headers /home/muhammadmehdi/anaconda3/envs/memex/include/python3.10/python-fcl
         cwd: /tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/
    Complete output (27 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.10
    creating build/lib.linux-x86_64-3.10/fcl
    copying fcl/__init__.py -> build/lib.linux-x86_64-3.10/fcl
    copying fcl/collision_data.py -> build/lib.linux-x86_64-3.10/fcl
    copying fcl/version.py -> build/lib.linux-x86_64-3.10/fcl
    running build_ext
    skipping 'fcl/fcl.cpp' Cython extension (up-to-date)
    building 'fcl.fcl' extension
    creating build/temp.linux-x86_64-3.10
    creating build/temp.linux-x86_64-3.10/fcl
    gcc -pthread -B /home/muhammadmehdi/anaconda3/envs/memex/compiler_compat -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/muhammadmehdi/anaconda3/envs/memex/include -fPIC -O2 -isystem /home/muhammadmehdi/anaconda3/envs/memex/include -fPIC -I/usr/include -I/usr/local/include -I/usr/include/eigen3 -I/home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include -I/home/muhammadmehdi/anaconda3/envs/memex/include/python3.10 -c fcl/fcl.cpp -o build/temp.linux-x86_64-3.10/fcl/fcl.o -std=c++11
    In file included from /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/ndarraytypes.h:1960,
                     from /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                     from /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/arrayobject.h:5,
                     from fcl/fcl.cpp:708:
    /home/muhammadmehdi/anaconda3/envs/memex/lib/python3.10/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
       17 | #warning "Using deprecated NumPy API, disable it with " \
          |  ^~~~~~~
    fcl/fcl.cpp:732:10: fatal error: octomap/OccupancyOcTreeBase.h: No such file or directory
      732 | #include "octomap/OccupancyOcTreeBase.h"
          |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    compilation terminated.
    error: command '/usr/bin/gcc' failed with exit code 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /home/muhammadmehdi/anaconda3/envs/memex/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/setup.py'"'"'; __file__='"'"'/tmp/pip-install-9sm4enj6/python-fcl_05eeff91d7a8401fb2470b7f0faf0317/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-owwnkyzy/install-record.txt --single-version-externally-managed --compile --install-headers /home/muhammadmehdi/anaconda3/envs/memex/include/python3.10/python-fcl Check the logs for full command output.

Update PyPi Repo

Would it be possible to update the PyPi repo with the new wheels? It looks like it hasn't been updated since 2019.

Erratic multiple Halfspace objects

Hi
I would like to combine multiple Halfspace objects to form a work space, but seems that there is some problem (at least the way I do it).

Here is a minimum working example:

import numpy as np
import fcl
obstacles = [
    fcl.CollisionObject(fcl.Halfspace(np.array([ 1.0, 0.0, 0.0]), -5.0)),
    fcl.CollisionObject(fcl.Halfspace(np.array([-1.0, 0.0, 0.0]), -5.0)),
]
# Collision checking.
collision_manager = fcl.DynamicAABBTreeCollisionManager()
collision_manager.registerObjects(obstacles)
collision_manager.setup()
# Robots collision objects.
ball0 = fcl.Sphere(0.01)
pos0 = fcl.Transform(np.array([0.0, 0.0, 0.0], dtype=float))
robo0 = fcl.CollisionObject(ball0, pos0)
#
req = fcl.CollisionRequest(num_max_contacts=10, enable_contact=True)
cdata = fcl.CollisionData(request=req)
collision_manager.collide(robo0, cdata, fcl.defaultCollisionCallback)
print(cdata.result.is_collision)

The goal is to check whether the point robo0 is between planes X< 5 and X>-5.

But The program runs without output. If I runf the code in Jupyter, the kernel stops and I will receive the following message:

Canceled future for execute_request message before replies were done

Am I doing this wrong or this is a bug?

Best
Farshid

Cannot install under OSX Mojave (10.14) using pip and python 3.7

I have installed octomap before but once I type
$ pip3 install python-fcl

It fails with this output:

Collecting python-fcl
Using cached https://files.pythonhosted.org/packages/d6/1a/51e9a3cf8473f297226396ad508702483f4fe3df9bb60676b35d2aca340d/python-fcl-0.0.12.tar.gz
Requirement already satisfied: numpy in /Users/misan/Library/Python/3.7/lib/python/site-packages (from python-fcl) (1.16.4)
Requirement already satisfied: cython in /Users/misan/Library/Python/3.7/lib/python/site-packages (from python-fcl) (0.29.10)
Building wheels for collected packages: python-fcl
Building wheel for python-fcl (setup.py) ... error
ERROR: Complete output from command /usr/local/opt/python/bin/python3.7 -u -c 'import setuptools, tokenize;file='"'"'/private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-install-zz_36jyd/python-fcl/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-wheel-w3h9lffv --python-tag cp37:
ERROR: running bdist_wheel
running build
running build_py
creating build
creating build/lib.macosx-10.14-x86_64-3.7
creating build/lib.macosx-10.14-x86_64-3.7/fcl
copying fcl/collision_data.py -> build/lib.macosx-10.14-x86_64-3.7/fcl
copying fcl/version.py -> build/lib.macosx-10.14-x86_64-3.7/fcl
copying fcl/init.py -> build/lib.macosx-10.14-x86_64-3.7/fcl
running build_ext
cythoning fcl/fcl.pyx to fcl/fcl.cpp
building 'fcl.fcl' extension
creating build/temp.macosx-10.14-x86_64-3.7
creating build/temp.macosx-10.14-x86_64-3.7/fcl
clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers -I/usr/include -I/usr/local/include -I/usr/include/eigen3 -I/Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include -I/usr/local/include -I/usr/local/opt/openssl/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c fcl/fcl.cpp -o build/temp.macosx-10.14-x86_64-3.7/fcl/fcl.o -std=c++11
In file included from fcl/fcl.cpp:619:
In file included from /Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/arrayobject.h:4:
In file included from /Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/ndarrayobject.h:12:
In file included from /Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822:
/Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
#warning "Using deprecated NumPy API, disable it with "
^
fcl/fcl.cpp:627:10: fatal error: 'fcl/data_types.h' file not found
#include "fcl/data_types.h"
^~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
error: command 'clang' failed with exit status 1

ERROR: Failed building wheel for python-fcl
Running setup.py clean for python-fcl
Failed to build python-fcl
Installing collected packages: python-fcl
Running setup.py install for python-fcl ... error
ERROR: Complete output from command /usr/local/opt/python/bin/python3.7 -u -c 'import setuptools, tokenize;file='"'"'/private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-install-zz_36jyd/python-fcl/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-record-oh_p8l97/install-record.txt --single-version-externally-managed --compile:
ERROR: running install
running build
running build_py
creating build
creating build/lib.macosx-10.14-x86_64-3.7
creating build/lib.macosx-10.14-x86_64-3.7/fcl
copying fcl/collision_data.py -> build/lib.macosx-10.14-x86_64-3.7/fcl
copying fcl/version.py -> build/lib.macosx-10.14-x86_64-3.7/fcl
copying fcl/init.py -> build/lib.macosx-10.14-x86_64-3.7/fcl
running build_ext
skipping 'fcl/fcl.cpp' Cython extension (up-to-date)
building 'fcl.fcl' extension
creating build/temp.macosx-10.14-x86_64-3.7
creating build/temp.macosx-10.14-x86_64-3.7/fcl
clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers -I/usr/include -I/usr/local/include -I/usr/include/eigen3 -I/Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include -I/usr/local/include -I/usr/local/opt/openssl/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c fcl/fcl.cpp -o build/temp.macosx-10.14-x86_64-3.7/fcl/fcl.o -std=c++11
In file included from fcl/fcl.cpp:619:
In file included from /Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/arrayobject.h:4:
In file included from /Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/ndarrayobject.h:12:
In file included from /Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822:
/Users/misan/Library/Python/3.7/lib/python/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
#warning "Using deprecated NumPy API, disable it with "
^
fcl/fcl.cpp:627:10: fatal error: 'fcl/data_types.h' file not found
#include "fcl/data_types.h"
^~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
error: command 'clang' failed with exit status 1
----------------------------------------
ERROR: Command "/usr/local/opt/python/bin/python3.7 -u -c 'import setuptools, tokenize;file='"'"'/private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-install-zz_36jyd/python-fcl/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-record-oh_p8l97/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /private/var/folders/rz/kw6z5q015bx5_zhls77kznz00000gn/T/pip-install-zz_36jyd/python-fcl/

Failure to install python-fcl for python 3.7 on Ubuntu 16.04

Here are first few errors:

Error compiling Cython file:
------------------------------------------------------------
...
from cython.operator cimport dereference as deref, preincrement as inc, address
cimport numpy as np
import numpy
ctypedef np.float64_t DOUBLE_t

cimport fcl_defs as defs
       ^
------------------------------------------------------------

fcl/fcl.pyx:13:8: 'fcl_defs.pxd' not found

Error compiling Cython file:
------------------------------------------------------------
...

###############################################################################
# Transforms
###############################################################################
cdef class Transform:
    cdef defs.Transform3f *thisptr
        ^
------------------------------------------------------------

fcl/fcl.pyx:20:9: 'Transform3f' is not a type identifier

Error compiling Cython file:
------------------------------------------------------------
...
###############################################################################
# Collision objects and geometries
###############################################################################

cdef class CollisionObject:
    cdef defs.CollisionObject *thisptr
        ^
------------------------------------------------------------

Continuous Collision With Simple Mesh Example Fails

import numpy as np
import fcl
from trimesh import Trimesh


def print_collision_result(o1_name, o2_name, result):
    print('Collision between {} and {}:'.format(o1_name, o2_name))
    print('-'*30)
    print('Collision?: {}'.format(result.is_collision))
    print('Number of contacts: {}'.format(len(result.contacts)))
    print('')


def print_continuous_collision_result(o1_name, o2_name, result):
    print('Continuous collision between {} and {}:'.format(o1_name, o2_name))
    print('-'*30)
    print('Collision?: {}'.format(result.is_collide))
    print('Time of collision: {}'.format(result.time_of_contact))
    print('')


def print_distance_result(o1_name, o2_name, result):
    print('Distance between {} and {}:'.format(o1_name, o2_name))
    print('-'*30)
    print('Distance: {}'.format(result.min_distance))
    print('Closest Points:')
    print(result.nearest_points[0])
    print(result.nearest_points[1])
    print('')


def create_fcl_bvh(mesh: Trimesh) -> fcl.BVHModel:
    bvh = fcl.BVHModel()
    err = bvh.beginModel(len(mesh.vertices), len(mesh.faces))
    err = bvh.addSubModel(mesh.vertices, mesh.faces)
    err = bvh.endModel()
    return bvh


def create_fcl_transform(homog) -> fcl.Transform:
    res = fcl.Transform(homog[:3, :3], homog[:3, 3])
    return res


def print_continuous_collision_result(o1_name, o2_name, result):
    print('Continuous collision between {} and {}:'.format(o1_name, o2_name))
    print('-' * 30)
    print('Collision?: {}'.format(result.is_collide))
    print('Time of collision: {}'.format(result.time_of_contact))
    print('')


def print_collision_result(o1_name, o2_name, result):
    print('Collision between {} and {}:'.format(o1_name, o2_name))
    print('-'*30)
    print('Collision?: {}'.format(result.is_collision))
    print('Number of contacts: {}'.format(len(result.contacts)))
    print('')


def check_collision(obj1, obj2):
    request = fcl.CollisionRequest()
    result = fcl.CollisionResult()
    ret = fcl.collide(obj1, obj2, request, result)
    print_collision_result("obj1", "obj2", result)


vertices = np.array([
    [-1.0, -1.0, 0.0],
    [1.0, -1.0, 0.0],
    [-1.0, 1.0, 0.0],
    [1.0, 1.0, 0.0],
    [-1.0, -1.0, 1.0],
    [1.0, -1.0, 1.0],
    [-1.0, 1.0, 1.0],
    [1.0, 1.0, 1.0]
])
faces = np.array([
    [3, 1, 0],
    [3, 0, 2],
    [0, 1, 5],
    [0, 5, 4],
    [1, 3, 7],
    [1, 7, 5],
    [3, 2, 6],
    [3, 6, 7],
    [2, 0, 4],
    [2, 4, 6],
    [4, 5, 7],
    [4, 7, 6],
])


mesh1 = Trimesh(vertices=vertices, faces=faces)
mesh2 = mesh1.copy()

mesh1.apply_translation((0., 0., 3.))
mesh2.apply_scale((2., 2., 0.5))

homog1_start = np.array([
    [1., 0., 0., 1.],
    [0., 1., 0., 0.],
    [0., 0., 1., -1.],
    [0., 0., 0., 1.],
])
homog1_end = np.array([
    [1., 0., 0., 1.],
    [0., 1., 0., 0.],
    [0., 0., 1., -2.],
    [0., 0., 0., 1.],
])

homog2_start = np.array([
    [1., 0., 0., -2.],
    [0., 1., 0., 0.],
    [0., 0., 1., 0.],
    [0., 0., 0., 1.],
])
homog2_end = np.array([
    [1., 0., 0., 2.],
    [0., 1., 0., 0.],
    [0., 0., 1., 1.5],
    [0., 0., 0., 1.],
])

bvh1 = create_fcl_bvh(mesh1)
bvh2 = create_fcl_bvh(mesh2)

obj1_start = fcl.CollisionObject(bvh1, create_fcl_transform(homog1_start))
obj1_end = fcl.CollisionObject(bvh1, create_fcl_transform(homog1_end))
obj2_start = fcl.CollisionObject(bvh2, create_fcl_transform(homog2_start))
obj2_end = fcl.CollisionObject(bvh2, create_fcl_transform(homog2_end))

check_collision(obj1_start, obj2_start)
check_collision(obj2_end, obj2_end)

request = fcl.ContinuousCollisionRequest(
    num_max_iterations=100, gjk_solver_type=fcl.GJKSolverType.GST_INDEP)
result = fcl.ContinuousCollisionResult()
ret = fcl.continuousCollide(obj1_start, create_fcl_transform(homog1_end), obj2_start,
                            create_fcl_transform(homog2_end), request, result)
print_continuous_collision_result("obj1", "obj2", result)

Output:

Collision between obj1 and obj2:
------------------------------
Collision?: False
Number of contacts: 0

Collision between obj1 and obj2:
------------------------------
Collision?: True
Number of contacts: 1

Continuous collision between obj1 and obj2:
------------------------------
Collision?: False
Time of collision: 1.0

I would expect that if collision is True for any of the fcl.collide calls, that fcl.continuousCollide would detect a collision. This doesn't seem to be true.

Inconsistent results for continuous collision checking

This program gives different results if run repeatedly:

from __future__ import print_function

import numpy as np
import fcl

def main():
    g1 = fcl.Box(1,2,3)
    t1 = fcl.Transform([-10.0, 0, 0])
    o1 = fcl.CollisionObject(g1, t1)
    t1_final = fcl.Transform(np.array([10.0, 0.0, 0.0]))

    g2 = fcl.Cone(1,3)
    t2 = fcl.Transform([0, 0, 0])
    o2 = fcl.CollisionObject(g2, t2)
    t2_final = fcl.Transform(np.array([0.0, 0.0, 0.0]))

    request = fcl.ContinuousCollisionRequest()
    result = fcl.ContinuousCollisionResult()

    ret = fcl.continuousCollide(o1, t1_final, o2, t2_final, request, result)

    return result
    
if __name__ == "__main__":
    print("FCL version: ", fcl.__version__)

    result = main()

    print("Time of contact: ", result.time_of_contact)
    print("Is colliding: ", result.is_collide)

Why?

No default __reduce__ due to non-trivial __cinit__

Hi, thank you for providing this amazing project for us. It works well for most of the scenarios that I tested.

Recently I encountered a problem when I tried to use the python multiprocessing toolbox (passed in a fcl collision object as input). It throws me an error: no default __reduce__ due to non-trivial __cinit__. Do you know to add the additional __reduce__ method to the cython class? Thank you very much for your help.

Collision checking with Python-fcl

Hi,

I was able to successfully install python-fcl. I used a couple of different ways to do this and was able to install the library. But I am not able to detect collisions. This leads me to believe that maybe the way I set things up are broken. Here are the following things I did:

  • brew installed libccd, octomap, fcl then cloned the python-fcl repo and checkout out the pull-request for the fcl version 0.6.1
  • brew installed libccd, octomap, cloned fcl, checked out version 0.5.0 and built it using cmake -> make -> make install and pip installed python-fcl
  • brew installed libccd cloned octomap and built it using cmake -> make -> make install, cloned fcl and built it the same way then pip installed python-fcl

All threw methods allowed me import fcl into my python script. Here is the test script I wrote:
`import numpy as np
import fcl

b = fcl.Box(15,15,15)
v1 = np.array([1.0, 1.0, 1.0])
v2 = np.array([1.0, 1.0, 2.0])
v3 = np.array([1.0, 2.0, 1.0])
t = fcl.TriangleP(v1, v2, v3)

obj1 = fcl.CollisionObject(b)
obj2 = fcl.CollisionObject(t)

objs = [obj1, obj2]

manager = fcl.DynamicAABBTreeCollisionManager()
manager.registerObjects(objs)
manager.setup()

crequest = fcl.CollisionRequest(num_max_contacts=100, enable_contact=True)
cdata = fcl.CollisionData(crequest, fcl.CollisionResult())

manager.collide(cdata, fcl.defaultCollisionCallback)

print('Collision within manager 1?: {}'.format(cdata.result.is_collision))`

Here is the output that I get when I run this:

Warning: collision function between node type 9 and node type 18 is not supported Collision within manager 1?: False

I am currently trying to force the script to detect a collision. I am not sure what I am doing wrong. I believe that the installation was not successful and as a result the collision detection is not working properly. I am extremely new to all of this and any advice would be really helpful.

Some additional information:
I am currently on macOS Big Sur (11.3) on a MacBook Pro 2015
Homebrew version 3.1.6
boost 1.75.0_3
Cython 0.29.23
eigen 3.3.9
fcl 0.5.0 when cloning and 0.6.1 when brew installing
icu4c 69.1
libccd 2.1_1
octomap 1.9.7

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.