Robotics Lab

Control barrier functions explained with a mobile robot

A robot has a controller that works. Now it has to be safe as well, without rewriting that controller. Control barrier functions are the standard way to do that. This guide builds one step by step for a differential-drive robot.

The problem: a good controller that ignores obstacles

Take a differential-drive robot with pose (x, y, θ) and commands u = (v, ω): forward speed and turn rate. Its motion is the unicycle model:

ẋ = v cos θ ẏ = v sin θ θ̇ = ω

A go-to-goal controller steers it toward a target. It is fast, smooth and easy to tune, and it drives straight through anything in the way, because nothing in it knows obstacles exist.

You could redesign the controller to handle obstacles. But real systems stack many objectives: tracking, comfort, energy, and safety. Mixing them into one controller makes each harder to reason about. A safety filter keeps them apart: the nominal controller proposes a command, and the filter passes it through unchanged unless it is unsafe, in which case it changes it as little as possible.

Step 1: describe safety as a set

Pick a function h(x) that is positive when the robot is safe, zero on the boundary and negative when it is not. For a circular obstacle with centre o and radius r, and a robot of radius ρ, a natural choice is

h(x) = |p − o|² − (r + ρ)²

where p is the robot's position. The safe set is C = { x : h(x) ≥ 0 }. Safety now has a precise meaning: the state never leaves C. In control language, C must be forward invariant.

Step 2: the CBF condition

Staying in C is a statement about all future time, which is hard to enforce directly. The CBF condition turns it into a condition on the current command only:

ḣ(x, u) ≥ −α · h(x), α > 0

Read it as a speed limit on approaching danger. Far from the obstacle, h is large and h may decrease quickly. As the robot gets closer, the allowed rate of decrease shrinks. On the boundary, where h = 0, h may not decrease at all. The robot can approach the obstacle, but it cannot cross the boundary.

Why this guarantees safety: if ḣ ≥ −αh holds along the whole trajectory, the comparison lemma gives h(t) ≥ h(0)·e^(−αt). Starting safe, h(0) ≥ 0, means h(t) ≥ 0 forever. More generally αh can be replaced by any extended class-K function of h; the linear version is the common default.

h = 0 around the obstacle q ν_nom points into danger ν after the filter ν_nom ν* allowed: a·ν ≥ b
Left: the nominal velocity would carry the look-ahead point q into the keep-out circle. Right: the CBF condition is a half-plane of allowed velocities; the filter picks the closest allowed one.

Step 3: the unicycle catch, and the look-ahead point

Differentiate h for the robot centre: ḣ = 2(p − o)·(v cos θ, v sin θ). The turn rate ω does not appear. A filter built on this h can brake, but it can never steer. Facing an obstacle, the best it can do is stop, and the robot freezes in front of it. In control terms, h has relative degree 2 with respect to ω.

The standard fix for differential-drive robots is to put the barrier on a point a small distance l in front of the centre:

q = p + l·(cos θ, sin θ) q̇ = J(θ)·u, J(θ) = [ cos θ −l sin θ ; sin θ l cos θ ]

det J = l, so for l > 0 every velocity of q can be produced by some (v, ω). The point q behaves like a fully actuated particle. With the keep-out radius inflated to D = r + ρ + l, the triangle inequality |p − o| ≥ |q − o| − l means that keeping q safe keeps the body safe too. The price is conservatism: the robot never gets closer than about l to what it could have reached.

Step 4: the safety filter

With h(q) = |q − o|² − D², the condition becomes linear in the velocity ν = q̇:

2(q − o)·ν ≥ −α·h a·ν ≥ b, a = 2(q − o), b = −α·h

The filter solves a tiny optimisation problem at every control step:

ν* = argmin |ν − ν_nom|² subject to a·ν ≥ b u* = J(θ)⁻¹·ν*

With one obstacle this has a closed form. If ν_nom already satisfies the constraint, keep it. Otherwise move it onto the boundary line along a:

ν* = ν_nom + max(0, b − a·ν_nom) · a / |a|²

Because the correction is applied to q, it becomes a mix of braking and turning in (v, ω), and the robot slides around the obstacle instead of stopping. With several obstacles each one adds a half-plane, and the filter becomes a small quadratic program, the "CBF-QP" of the literature. In two dimensions it can be solved exactly by checking a handful of candidate points.

Build this filter yourself. The free lab gives you the robot, the simulator and 20 hidden test scenarios. You write cbf_filter in Python, in your browser.

Open the CBF lab

Tradeoffs you will run into

Where to go from here

The formal theory, including higher-order CBFs for relative degree above one and combinations with control Lyapunov functions, is covered in A. D. Ames et al., "Control Barrier Function Based Quadratic Programs for Safety Critical Systems" (IEEE Transactions on Automatic Control, 2017) and the survey "Control Barrier Functions: Theory and Applications" (European Control Conference, 2019). For the practical question of when to use a CBF instead of a classic repulsive field, read CBF vs potential fields for robot obstacle avoidance.

Get notified when new robotics labs are released.

One email per new lab.