PX4 + ROS 2: CBF Safety Filter
Control Barrier Function (CBF) safety filter demo for UAV obstacle avoidance using PX4 SITL, ROS 2 Humble, and gz-sim Harmonic.
| No CBF (Collision) | CBF Only (Zigzag) | CBF + Sliding (Smooth) |
|---|---|---|
![]() |
![]() |
![]() |
| Crashes at obstacle 1 | Safe but slow (87s) | Safe and fast (64s) |
Problem
Autonomous drones often follow a nominal controller (e.g., trajectory tracking), but that controller may violate safety constraints such as minimum distance to obstacles.
The goal is to enforce safety without redesigning the full controller.
System Architecture
(ROS2 node) → PX4 SITL / Vehicle
Features
- QP-based CBF implementation with formal safety guarantees
- 12-obstacle course (30m) with varying radii
- Tangential sliding to avoid local minima
- Toggle CBF on/off to compare safe vs unsafe behavior
- Logs barrier function (h(x)) to verify safety constraint satisfaction
CBF Mathematical Formulation
Single-integrator dynamics (position-controlled UAV):
Barrier function for a circular obstacle:
- $h>0$: safe region
- $h=0$: safety boundary
- $h<0$: unsafe (collision imminent)
CBF constraint (forward invariance of safe set):
QP-CBF formulation:
Where $\delta$ is a relaxation variable to ensure feasibility. The QP solver (OSQP via cvxpy) finds the closest safe velocity to the nominal command.
Results
We evaluate the safety filter by monitoring the barrier function (h(x)) during simulation.

Barrier function evolution under different controllers. Safety is guaranteed when \(h(x) \ge 0\).
The figure above shows the evolution of the barrier function (h(x)) over time for three cases:
- No CBF (red): the nominal controller violates the safety constraint, causing the barrier function to become negative. This corresponds to the system entering an unsafe region.
- CBF only (orange): the control barrier function modifies the nominal input to maintain (h(x) \ge 0), enforcing safety.
- CBF + sliding controller (blue): combining the safety filter with a sliding-mode controller improves robustness and keeps the system further away from the safety boundary.
The dashed line represents the safety boundary (h(x)=0).
Maintaining (h(x) \ge 0) guarantees forward invariance of the safe set.
These results demonstrate that the safety filter successfully enforces safety constraints while minimally modifying the nominal control input.

Comparison of trajectory for different scenario.
Comparison Summary
| Metric | CBF OFF | CBF Only | CBF + Sliding |
|---|---|---|---|
| Min barrier h(x) | -0.975 | 0.036 | 0.491 |
| Min distance (m) | 1.505 | 1.810 | 1.932 |
| Safety violated | YES | NO | NO |
| Collision | YES | NO | NO |
| Reached target | NO (crash) | YES | YES |
| Flight time (s) | 7.5 | 87.4 | 64.2 |
Key observations:
- CBF Only: Safe but inefficient (zigzags around obstacles, 36% slower)
- CBF + Sliding: Safe and efficient (smooth curves, better safety margin)
Prerequisites
- Ubuntu 22.04 + ROS 2 Humble
- gz-sim Harmonic (v8)
- PX4 SITL built at
~/ros2_ws/src/PX4-Autopilot - MicroXRCE-DDS-Agent
- Python:
pip install cvxpy osqp matplotlib numpy
How to Run
Terminal 1: Agent
./tools/start_agent.sh
Terminal 2: PX4 + gz-sim with obstacles
./tools/spawn_drone.sh
Terminal 3: Controller
source /opt/ros/humble/setup.bash
source install/setup.bash
WITH CBF (safe):
ros2 launch cbf_demo_bringup cbf_demo.launch.py use_cbf:=true
WITHOUT CBF (collision):
ros2 launch cbf_demo_bringup cbf_demo.launch.py use_cbf:=false
Terminal 4: RViz2
rviz2 -d $(ros2 pkg prefix cbf_demo_bringup)/share/cbf_demo_bringup/config/cbf_viz.rviz
Tech Stack
- ROS2
- PX4 SITL
- Python / C++
- Control Barrier Functions (CBFs)
- Quadratic Programming (QP)
Links
- Code: px4-ros2-cbf-safety-filter
- README: Documentation
References
- Ames et al., “Control Barrier Functions: Theory and Applications”, 2019
- Federica Ferraguti et al. “Safety and Efficiency in Robotics: the Control Barrier Functions Approach”, 2022
- CBF Tutorial Repo


