Coal: a fast collision detection library for robotics
An extension of the Flexible Collision Library
At a glance
- What is it?
- Coal is the renamed successor to HPP-FCL, itself a 2015 fork of the Flexible Collision Library, and it is a C++ library with Python bindings that implements GJK and EPA directly rather than depending on libccd. It is used by Pinocchio, Crocoddyl, HPP and several other robotics stacks, and it is distributed through conda-forge and PyPI.
- Who is it for?
- Adopt Coal if you are doing collision detection or distance queries on articulated robots and want GJK and EPA implemented directly in the library, with Python bindings for prototyping, rather than a dependency on libccd. Do not adopt it if you need the broad phase that HPP-FCL once carried, since the README says the broad phase was reintroduced in 2022 based on FCL 0.7.0.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
From FCL to HPP-FCL to Coal, and why the name changed
The project history explains the design. FCL was forked in 2015, creating a new project called HPP-FCL. Since then a large part of the code has been rewritten or removed, described as unused and untested code, and new features have been introduced. Because of those major changes, it was decided in 2024 to rename the HPP-FCL project to Coal. The rename is therefore a signal of a substantial divergence from the upstream FCL codebase rather than a cosmetic rebrand, and for anyone porting an existing FCL dependency that distinction matters. The README also asks users to cite the project if they use it in projects and research papers, and the repository carries both a CITATION.bib and a CITATION.cff, along with a CHANGELOG.md and a CODE_OF_CONDUCT.md. The default branch is devel, and the recent release tags are v3.0.4 from 2026-06-29, v3.0.3 from 2026-05-05 and v3.0.2 from 2025-09-29, with the last push on 2026-10-19.
What Coal does that FCL did not
The new features list is the substance of the project. Coal has dedicated and efficient implementations of the GJK and the EPA algorithms and does not rely on libccd. It supports safety margins for collision detection. It has an accelerated version of collision detection in the style of Nesterov, which the README says leads to increased performance, up to a factor of 2, with a paper linked for detail. It computes a lower bound of the distance between two objects when a collision check finds no collision, which matters when a robot planner wants to know how far it can move before it collides. It provides Python bindings for quick prototyping, supports new geometries such as height fields, capsules and ellipsoids, and it computes contact points and contact patches between objects efficiently. Object serialization is fully supported through Boost.Serialization, and the README mentions a large number of bug fixes as a reliability improvement.
GJK implemented directly, and why not a generic QP solver
The performance argument is the interesting part of the README. Coal implements the well-established GJK algorithm and its variants for collision detection and distance computation, and the README says these implementations lead to state of the art performance. The benchmarks are against the Bullet simulator, the original FCL library as used in the Drake framework, and the libccd library as used in MuJoCo, and the README notes that the accelerated variants of GJK largely outperform by a large margin, from 5x up to 15x times faster, on a log scale y axis. Then there is a second, more interesting argument, about why you should not simply formulate collision detection as a quadratic problem and call an off the shelf optimization solver such as ProxQP. The README's answer is empirical: GJK based approaches largely outperform solutions based on classic optimization solvers, notably for large geometries composed of tens or hundreds of vertices. That is a narrow claim about a specific problem shape, but it is a claim about the narrow phase, which is where collision detection costs actually sit in a robotics stack.
The projects that depend on it, and what that tells you
The README lists the open source projects relying on Coal, and the list is more informative than a customer list would be. Pinocchio is a fast and flexible implementation of rigid body dynamics algorithms and their analytical derivatives. IfcOpenShell is an open source IFC library and geometry engine. Crocoddyl realises model predictive control for complex robotics platforms. TSID implements a task space inverse dynamics QP. HPP is an SDK implementing motion planners for humanoids and other robots. Jiminy is a simulator based on Pinocchio, and ocs2 is a toolbox for optimal control for switched systems. The pattern is telling. These are libraries where collision queries sit in the inner loop of a planner or a controller, so the difference between 5x and 15x on the narrow phase is not a micro-optimisation. The README also notes that Coal has been used to develop Simple, a new differentiable simulator for robotics, which tells you the Python bindings and the API shape are being treated as a real interface rather than an afterthought.
Installing from conda-forge, and the broad phase question
The installation section of the README covers conda and Docker, and the badges at the top of the page point at the conda-forge package named coal and at a PyPI package of the same name, so the project is distributed both as a binary conda package and as a Python wheel. The same section documents a C++ example and a Python example, and points to the online doxygen documentation, the pipeline status badge on the GitLab instance, and a coverage report. The one item in the feature list that deserves a second look is the broad phase note, which says the broad phase was reintroduced by Justin Carpentier in 2022, based on the FCL version 0.7.0. A broad phase, as opposed to the narrow phase the rest of the library is about, is the part that cheaply rejects pairs of objects that cannot possibly be touching. If your workload is dominated by many objects in a large scene, that is the layer you will notice first, and it is the layer that arrives by backport from an older FCL rather than as a Coal original.
Practical limits, and the trade against libccd
Three limits are worth naming. The first is that the accelerated GJK variants are described against a log scale benchmark, which means the headline multipliers apply to specific geometry and query shapes rather than uniformly, so a project with a different mix of shapes and query types will not see 15x across the board. The second is the Boost.Serialization dependency for object serialization, which is a real constraint on a library that otherwise tries to keep its dependency footprint narrow. The third is the licence, which the repository listing classifies as a custom one that GitHub cannot categorise, so the terms have to be read in the LICENSE file rather than inferred from the badge in the README. The alternative to weigh is libccd, the library Coal was written specifically to stop depending on, and the original FCL. libccd is a smaller, more focused library with its own performance profile, and it is the right choice if you want collision detection without the robotics stack around it. Coal earns its extra weight when you also want safety margins, contact patches, distance lower bounds, serialization, and the same code path from C++ and from Python.
Editorial conclusion
Adopt Coal if you are doing collision detection or distance queries on articulated robots and want GJK and EPA implemented directly in the library, with Python bindings for prototyping, rather than a dependency on libccd. Do not adopt it if you need the broad phase that HPP-FCL once carried, since the README says the broad phase was reintroduced in 2022 based on FCL 0.7.0. Before you port an existing HPP-FCL codebase, read the rename and feature notes, check the licence file, since the repository is classified under a custom licence, and plan for the fact that the 3.0 series is the current line and the default branch is devel.
Frequently asked questions
What is Coal and how does it relate to HPP-FCL and FCL?
Coal is an extension of the Flexible Collision Library. FCL was forked in 2015 to create HPP-FCL, a large part of the code was rewritten or removed, new features were introduced, and it was decided in 2024 to rename the HPP-FCL project to Coal.
Does Coal depend on libccd?
No. Coal has dedicated and efficient implementations of the GJK and the EPA algorithms and does not rely on libccd. The README benchmarks against libccd, the original FCL library and the Bullet simulator, reporting that the accelerated GJK variants are from 5x up to 15x times faster.
Which robotics projects use Coal?
The README lists Pinocchio, IfcOpenShell, Crocoddyl, TSID, HPP, Jiminy and ocs2, and says Coal has recently also been used to develop Simple, a new differentiable simulator for robotics.
How do I install Coal?
The README's installation section covers conda and Docker, and the badges point at the conda-forge package named coal and a PyPI package of the same name. The repository is also laid out for a CMake based build, with a CMakeLists.txt at the root, a cmake/ directory, a flake.nix and a pixi.toml, and a colcon.pkg file for ROS packaging.
What does the broad phase note in Coal mean?
The README states that the broad phase was reintroduced by Justin Carpentier in 2022, based on the FCL version 0.7.0. The rest of the library focuses on the narrow phase, where the dedicated GJK and EPA implementations apply.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/coal-library-coal)