FCL: The Flexible Collision Library

FCL: The Flexible Collision Library

Posted by YuCong on July 15, 2022

FCL: The Flexible Collision Library 碰撞检测算法库简单笔记


Created 2022.07.15 by Cong Yu; Last modified: 2022.07.19-V1.8.2

Contact: windmillyucong@163.com

Copyleft! 2022 Cong Yu. Some rights reserved.


FCL: The Flexible Collision Library

  • github https://github.com/flexible-collision-library/fcl
  • homepage https://flexible-collision-library.github.io/index.html

库的编译与安装

依赖

  • ccd
  • octomap
ccd
1
2
3
4
5
6
7
8
git clone https://github.com/danfis/libccd.git

cd libccd
mkdir build
cd build
cmake ..
make -j4
sudo make install

如果需要添加ccd的编译选项,可在cmakefile中添加

1
2
3
4
# Use "-fPIC" / "-fPIE" for all targets by default, including static libs
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# CMake doesn't add "-pie" by default for executables (CMake issue #14983)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
octomap
1
2
3
4
5
6
7
8
9
git clone https://github.com/Octomap/octomap.git

cd octomap
git checkout v1.9.0
mkdir build
cd build
camke ..
make -j4
sudo make install
FCL
1
2
3
4
5
6
7
8
9
git clone https://github.com/flexible-collision-library/fcl.git

cd fcl
git checkout 0.7.0
mkdir build
cd build
cmake ..
make -j4
sudo make install

API 简单笔记

AABB

  • the AABB collision structure, which is a box in 3D space determined by two diagonal points. 由两个对角点表达的三维空间
  • 一个基本的数据结构

1. 几何体相关

1.0 CollisionGeometry

  • The geometry for the object for collision or distance computation.
  • 碰撞几何的虚基类

img

CollisionGeometryf, CollisionGeometryd
1
2
using CollisionGeometryf = CollisionGeometry<float>;
using CollisionGeometryd = CollisionGeometry<double>;
OBJECT_TYPE
1
2
/// @brief object type: BVH (mesh, points), basic geometry, octree
enum OBJECT_TYPE {OT_UNKNOWN, OT_BVH, OT_GEOM, OT_OCTREE, OT_COUNT};
NODE_TYPE
1
2
3
/// @brief traversal node type: bounding volume (AABB, OBB, RSS, kIOS, OBBRSS, KDOP16, KDOP18, kDOP24), basic shape (box, sphere, ellipsoid, capsule, cone, cylinder, convex, plane, halfspace, triangle), and octree
enum NODE_TYPE {BV_UNKNOWN, BV_AABB, BV_OBB, BV_RSS, BV_kIOS, BV_OBBRSS, BV_KDOP16, BV_KDOP18, BV_KDOP24,
                GEOM_BOX, GEOM_SPHERE, GEOM_ELLIPSOID, GEOM_CAPSULE, GEOM_CONE, GEOM_CYLINDER, GEOM_CONVEX, GEOM_PLANE, GEOM_HALFSPACE, GEOM_TRIANGLE, GEOM_OCTREE, NODE_COUNT};
computeLocalAABB()
  • 计算AABB
computeCOM()
  • 计算中心点
computeMomentofInertia()
  • compute the inertia matrix, related to the origin. 计算关于原点的惯性矩阵
computeVolume()
  • 计算体积
computeMomentofInertiaRelatedToCOM()
  • 计算关于中心的惯性矩阵

1.1 Box

  • 立方体

img

Boxf, Boxd
1
2
using Boxf = Box<float>;
using Boxd = Box<double>;
Box()
1
2
3
4
5
/// @brief Constructor
Box(S x, S y, S z);

/// @brief Constructor
Box(const Vector3<S>& side);
  • 构造参数:xyz 或者 vector3S
getBoundVertices()
  • get the vertices of some convex shape which can bound this shape in a specific configuration 计算一组包裹该形状的顶点
  • 返回的是立方体的12个顶点

1.2 Sphere

// todo(congyu)

1.3 ellipsoid

// todo(congyu)

1.4 Capsule

  • 胶囊体
Capsule()
1
2
  /// @brief Constructor
  Capsule(S radius, S lz);
  • 构造参数
    • radius: 半径
    • lz: z方向的长度
getBoundVertices()
  • 返回包裹它的36个点

1.5 Cone

  • 椎体
Cone()
1
Cone(S radius, S lz);
  • 构造参数
    • radius: 底圆半径
    • lz: z反向长度

1.6 cylinder

// todo(congyu)

1.7 convex

// todo(congyu)

1.8 plane

// todo(congyu)

1.9 half-space

// todo(congyu)

1.10 mesh

// todo(congyu)

1.11 octree

// todo(congyu)

2 CollisionObject

  • the object for collision or distance computation, contains the geometry and the transform information

img

  • CollisionObject 可由 CollisionGeometry对象+Transform对象 构造出

    1
    2
    3
    4
    5
    
    //geom and tf are the geometry and the transform of the object
    std::shared_ptr<BVHModel<OBBRSSf>> geom = ...
    Transform3f tf = ...
    //Combine them together
    CollisionObjectf* obj = new CollisionObjectf(geom, tf);
    

3 Transform3

  • 一个Transform对象由R和t构成
1
2
3
4
5
6
7
8
9
// R and T are the rotation matrix and translation vector
Matrix3f R;
Vector3f T;
// code for setting R and T
...
// transform is configured according to R and T
Transform3f pose = Transform3f::Identity();
pose.linear() = R;
pose.translation() = T;
linear()
translation()

4 碰撞检测相关

4.1 CollisionRequest

CollisionRequest()
1
CollisionRequest (size_t num_max_contacts_=1, bool enable_contact_=false, size_t num_max_cost_sources_=1, bool enable_cost_=false, bool use_approximate_cost_=true, GJKSolverType gjk_solver_type_=GST_LIBCCD)
  • 参数说明

    • num_max_contacts_: The maximum number of contacts will return.
    • enable_contact_: whether the contact information (normal, penetration depth and contact position) will return
  • 通常设置

    1
    2
    
    int num_max_contacts = std::numeric_limits<int>::max();
    bool enable_contact = true;
    

4.1.1 GJKSolverType

  • Type of narrow phase GJK solver.
1
enum  	GJKSolverType { GST_LIBCCD, GST_INDEP }
  • GST_LIBCCD
  • GST_INDEP

4.2 CollisionResult

// todo(congyu)

4.3 ContinuousCollisionRequest

基本同CollisionRequest

// todo(congyu)

4.4 ContinuousCollisionResult

基本同CollisionResult

// todo(congyu)

4.5 collide()

1
2
3
4
5
6
7
8
9
// Given two objects o1 and o2
CollisionObjectf* o1 = ...
CollisionObjectf* o2 = ...
// set the collision request structure, here we just use the default setting
CollisionRequest request;
// result will be returned via the collision result structure
CollisionResult result;
// perform collision test
collide(o1, o2, request, result);

4.6 distance()

1
2
3
4
5
6
7
8
9
// Given two objects o1 and o2
CollisionObjectf* o1 = ...
CollisionObjectf* o2 = ...
// set the distance request structure, here we just use the default setting
DistanceRequest request;
// result will be returned via the collision result structure
DistanceResult result;
// perform distance test
distance(o1, o2, request, result);

4.7 continuousCollide()

1
2
3
4
5
6
7
8
9
10
11
12
13
// Given two objects o1 and o2
CollisionObjectf* o1 = ...
CollisionObjectf* o2 = ...
// The goal transforms for o1 and o2
Transform3f tf_goal_o1 = ...
Transform3f tf_goal_o2 = ...
// set the continuous collision request structure, here we just use the default
// settin
ContinuousCollisionRequest request;
// result will be returned via the continuous collision result structure
ContinuousCollisionResult result;
// perform continuous collision test
continuousCollide(o1, tf_goal_o1, o2, tf_goal_o2, request, result);

4.8 BroadPhaseCollisionManager

1
2
3
4
5
6
7
// Initialize the collision manager for the first group of objects. 
// FCL provides various different implementations of CollisionManager.
// Generally, the DynamicAABBTreeCollisionManager would provide the best
// performance.
BroadPhaseCollisionManagerf* manager1 = new DynamicAABBTreeCollisionManagerf(); 
// Initialize the collision manager for the second group of objects.
BroadPhaseCollisionManagerf* manager2 = new DynamicAABBTreeCollisionManagerf();
registerObject()
1
2
3
4
5
6
7
8
9
// To add objects into the collision manager, using
// BroadPhaseCollisionManager::registerObject() function to add one object
std::vector<CollisionObjectf*> objects1 = ...
for(std::size_t i = 0; i < objects1.size(); ++i)
manager1->registerObject(objects1[i]);
// Another choose is to use BroadPhaseCollisionManager::registerObjects()
// function to add a set of objects
std::vector<CollisionObjectf*> objects2 = ...
manager2->registerObjects(objects2);
setup()
collide()
distance()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// In order to collect the information during broadphase, CollisionManager
// requires two settings:
// a) a callback to collision or distance; 
// b) an intermediate data to store the information generated during the
//    broadphase computation.
// For convenience, FCL provides default callbacks to satisfy a) and a
// corresponding call back data to satisfy b) for both collision and distance
// queries. For collision use DefaultCollisionCallback and DefaultCollisionData
// and for distance use DefaultDistanceCallback and DefaultDistanceData.
// The default collision/distance data structs are simply containers which
// include the request and distance structures for each query type as mentioned
// above.
DefaultCollisionData collision_data;
DefaultDistanceData distance_data;
// Setup the managers, which is related with initializing the broadphase
// acceleration structure according to objects input
manager1->setup();
manager2->setup();

// Examples for various queries
// 1. Collision query between two object groups and get collision numbers
manager2->collide(manager1, &collision_data, DefaultCollisionFunction);
int n_contact_num = collision_data.result.numContacts(); 
// 2. Distance query between two object groups and get the minimum distance
manager2->distance(manager1, &distance_data, DefaultDistanceFunction);
double min_distance = distance_data.result.min_distance;
// 3. Self collision query for group 1
manager1->collide(&collision_data, DefaultCollisionFunction);
// 4. Self distance query for group 1
manager1->distance(&distance_data, DefaultDistanceFunction);
// 5. Collision query between one object in group 1 and the entire group 2
manager2->collide(objects1[0], &collision_data, DefaultCollisionFunction);
// 6. Distance query between one object in group 1 and the entire group 2
manager2->distance(objects1[0], &distance_data, DefaultDistanceFunction);

Examples and Tests

  • examples
    • test_fcl_collision.cpp: provide examples for collision test
    • test_fcl_distance.cpp: provide examples for distance test
    • test_fcl_broadphase.cpp: provide examples for broadphase collision/distance test
    • test_fcl_frontlist.cpp: provide examples for frontlist collision acceleration
    • test_fcl_octomap.cpp: provide examples for collision/distance computation between octomap data and other data types.
  • unit-tests
    • https://github.com/flexible-collision-library/fcl/tree/master/test

Bullet

  • github https://github.com/bulletphysics/bullet3
  • homepage https://pybullet.org/wordpress/