Skip to main content
logo

CBFpy: Control Barrier Functions in Python and Jax

CBFpy is an easy-to-use and high-performance framework for constructing and solving Control Barrier Functions (CBFs) and Control Lyapunov Functions (CLFs), using Jax for:

  • Just-in-time compilation
  • Accelerated linear algebra operations with XLA
  • Automatic differentiation

For API reference, see the following documentation

If you use CBFpy in your research, please cite the following paper:

@inproceedings{morton2025oscbf,
  author={Morton, Daniel and Pavone, Marco},
  booktitle={2025 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)}, 
  title={Safe, Task-Consistent Manipulation with Operational Space Control Barrier Functions}, 
  year={2025},
  pages={187-194},
  doi={10.1109/IROS60139.2025.11246389}
}

Paper

Installation

From PyPI

pip install cbfpy

From source

A virtual environment is optional, but highly recommended. For pyenv installation instructions, see here.

git clone https://github.com/danielpmorton/cbfpy
cd cbfpy
pip install -e ".[examples]"

The [examples] tag installs all of the required packages for development and running the examples. The pure cbfpy functionality does not require these extra packages though. If you want to contribute to the repo, you can also include the [dev] dependencies.

If you are working on Apple silicon and have issues installing Jax, the following threads may be useful: [1], [2]

Performance tips

As with frax, I have a few tips for maximizing performance:

  • For best performance on a single, non-batched evaluation, use CPU rather than GPU/TPU. To do so, set JAX_PLATFORMS="cpu"
  • For best performance on CPU, use a version of JAX before 0.4.32. I recommend 0.4.30.
    • Note: This is mainly critical if using qpax as the solver backend. Setting ElastiQP as the backend significantly improves CPU solve times, but ElastiQP requires jax>=0.9.1. Essentially, if you choose ElastiQP, you will have much faster QP solves, at the cost of slightly more expensive Jacobian computations. Usually, the bottleneck is the QP solve, so this is probably a worthwhile tradeoff.
  • For accurate QP solutions, I recommend enabling double precision with JAX_ENABLE_X64=True. Note: Previous versions of CBFpy forced double precision globally; we now leave this choice up to the user
  • On CPU, it's probably faster to run on a single thread (these problems are small, and dispatching work to multiple threads introduces more overhead than it is worth). To do so, set XLA_FLAGS="--xla_cpu_multi_thread_eigen=false" and OPENBLAS_NUM_THREADS=1

On import, CBFpy will autodetect if you are running on CPU, and warn if some of these options are not configured.

Usage:

Example: A point-mass robot in 1D with an applied force and a positional barrier

For this problem, the state $z$ is defined as the position and velocity of the robot,

$$z = [x, \dot{x}]$$

So, the state derivative $\dot{z}$ is therefore

$$\dot{z} = [\dot{x}, \ddot{x}]$$

And the control input is the applied force in the $x$ direction:

$$u = F_{x}$$

The dynamics can be expressed as follows (with $m$ denoting the robot's mass):

$$\dot{z} = \begin{bmatrix}0 & 1 \ 0 & 0 \end{bmatrix}z + \begin{bmatrix}0 \ 1/m \end{bmatrix} u$$

This is a control affine system, since the dynamics can be expressed as

$$\dot{z} = f(z) + g(z) u$$

If the robot is controlled by some nominal (unsafe) controller, we may want to guarantee that it remains in some safe region. If we define $X_{safe} \in [x_{min}, \infty]$, we can construct a (relative-degree-2, zeroing) barrier $h$ where $h(z) \geq 0$ for any $z$ in the safe set:

$$h(z) = x - x_{min}$$

In Code

We'll first define our problem (dynamics, barrier, and any additional parameters) in a CBFConfig-derived class.

We use Jax for fast compilation of the problem. Jax can be tricky to learn at first, but luckily cbfpy just requires formulating your functions in jax.numpy which has the same familiar interface as numpy. These should be pure functions without side effects (for instance, modifying a class variable in self).

Additional tuning parameters/functions can be found in the CBFConfig documentation.

import jax.numpy as jnp
from cbfpy import CBF, CBFConfig


# Create a config class for your problem inheriting from the CBFConfig class
class MyCBFConfig(CBFConfig):
    def __init__(self):
        super().__init__(
            # Define the state and control dimensions
            n=2,  # [x, x_dot]
            m=1,  # [F_x]
            # Define control limits (if desired)
            u_min=None,
            u_max=None,
        )

    # Define the control-affine dynamics functions `f` and `g` for your system
    def f(self, z):
        A = jnp.array([[0.0, 1.0], [0.0, 0.0]])
        return A @ z

    def g(self, z):
        mass = 1.0
        B = jnp.array([[0.0], [1.0 / mass]])
        return B

    # Define the barrier function `h`
    # The *relative degree* of this system is 2, so, we'll use the h_2 method
    def h_2(self, z):
        x_min = 1.0
        x = z[0]
        return jnp.array([x - x_min])

We can then construct the CBF from our config and use it in our control loop as follows.

config = MyCBFConfig()
cbf = CBF.from_config(config)

# Pseudocode
while True:
    z = get_state()
    z_des = get_desired_state()
    u_nom = nominal_controller(z, z_des)
    u = cbf.safety_filter(z, u_nom)
    apply_control(u)
    step()

Examples

These can be found in the examples folder here

Adaptive Cruise Control

Use a CLF-CBF to maintain a safe follow distance to the vehicle in front, while tracking a desired velocity

  • State: z = [Follower velocity, Leader velocity, Follow distance] (n = 3)
  • Control: u = [Follower wheel force] (m = 1)
  • Relative degree: 1

Image: Adaptive cruise control

Point Robot Safe-Set Containment

Use a CBF to enforce that a point robot stays within a safe box, while a PD controller attempts to reduce the distance to a target position

  • State: z = [Position, Velocity] (n = 6)
  • Control: u = [Force] (m = 3)
  • Relative degree: 2

Image: Point robot in a safe set

Point Robot Obstacle Avoidance

Use a CBF to keep a point robot inside a safe box, while avoiding a moving obstacle. The nominal PD controller attempts to keep the robot at the origin.

  • State: z = [Position, Velocity] (n = 6)
  • Control: u = [Force] (m = 3)
  • Relative degree: 1 + 2 (1 for obstacle avoidance, 2 for safe set containment)
  • Additional data: The state of the obstacle (position and velocity)

Image: Point robot avoiding an obstacle

Manipulator Joint Limit Avoidance

Use a CBF to keep a manipulator operating within its joint limits, even if a nominal joint trajectory is unsafe.

  • State: z = [Joint angles] (n = 3)
  • Control: u = [Joint velocities] (m = 3)
  • Relative degree: 1

Image: 3-DOF manipulator avoiding joint limits

Drone Obstacle Avoidance

Use a CBF to keep a drone inside a safe box, while avoiding a moving obstacle. This is similar to the "point robot obstacle avoidance" demo, but with slightly different dynamics.

  • State: z = [Position, Velocity] (n = 6)
  • Control: u = [Velocity] (m = 3)
  • Relative degree: 1
  • Additional data: The state of the obstacle (position and velocity)

This is the same CBF which was used in the "Drone Fencing" demo at the Stanford Robotics center.

Image: Quadrotor avoiding an obstacle

Metadata

Release files for cbfpy 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cbfpy 0.1.0
File Size Uploaded
cbfpy-0.1.0.tar.gz 39.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cbfpy 0.1.0
File Interpreter ABI Platform
cbfpy-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 90.7 kB

Release files / cbfpy-0.1.0.tar.gz

Download URL cbfpy-0.1.0.tar.gz
Size 39.6 kB
Tags Source
SHA-256 checksum
How to use checksums
2f4163cbfb62d38b9870103b314f0994e0cbeee4a7df3c1c4437670fecfc904d
BLAKE2b-256 checksum
How to use checksums
5acc4dddd353c2d350b924a216bec87cb5bc1036a3337d9270d02777875a19d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / cbfpy-0.1.0-py3-none-any.whl

Download URL cbfpy-0.1.0-py3-none-any.whl
Size 51.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6c758b18a1259b662f6b1d35b4c59788278670ff909f6929f6db20e18abba9c
BLAKE2b-256 checksum
How to use checksums
13c2c1cd7db88d280bfd9ad74933c8c0302225650647da8d037a1c48a9340100
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page