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:
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
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:
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.
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:
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̇:
The filter solves a tiny optimisation problem at every control step:
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:
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.
Tradeoffs you will run into
- α sets how aggressive the robot is. Large α lets it approach obstacles quickly and cut close; small α makes it slow down early.
- Safety, not progress. A CBF keeps the robot in the safe set. It does not promise the robot reaches the goal: some obstacle layouts create points where the filtered system simply stops (deadlocks).
- Sampling. The guarantee is for continuous time. A digital controller holds each command for one period, so fast approaches can slightly overshoot the boundary. Run the filter fast enough, or add margin.
- Input limits. Motors saturate. If the filter ignores limits, the command actually applied may no longer satisfy the condition. Put the limits into the QP.
- Model errors. The guarantee holds for the model. Real robots need margins for localisation error, delays and slip.
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.