Φferromotion · textbook · chapter 3 rust → wasm · on-device

The command it will not obey

A safety layer that sits between any controller and the robot, and changes the command only when it must — so the robot physically cannot be driven into a hazard, whatever it is told. Everything below runs on your device, on the same Rust safety filter the native tools use.

01 — the problemA command you can't fully trust

Whatever is driving a robot — a hand controller, a planner, a learned policy — will occasionally command something unsafe. The usual fix is to make the controller more careful, and hope. But hope does not compose: a policy that is safe in training can be commanded into a wall the first time the world differs. We want a guarantee that does not depend on trusting the thing giving the orders.

The idea is a filter. Let the controller ask for whatever it wants; between it and the motors, a thin layer corrects the command to the nearest one that keeps the robot safe — and, when the command is already safe, does nothing at all.

02 — the barrierOne function that means "safe"

Pick a function h(x) that is positive where the robot is safe and zero at the edge of danger — here, distance to a hazard minus its radius. The filter enforces one inequality, ḣ + α·h ≥ 0: near the boundary (small h) the robot's approach speed must shrink to zero, so it can never cross. That single condition is linear in the command, so enforcing it is cheap.

Drive the robot below — move your cursor and it follows. The gold arrow is the command you gave; the green arrow is what the filter allows. Steer straight at a hazard.

safety margin h
command changed by
filter

the safety margin bar never reaches zero — press Aim into the hazard and watch the robot refuse

It slides along the edge. The gold arrow keeps pointing into the hazard — you are still commanding it inward — but the green arrow bends to run along the boundary. The robot obeys you exactly as far as it safely can, and no further.

03 — minimal interventionAs much of your command as it safely can

The filter solves min ½‖u − unom‖² subject to the barrier — the closest safe command to the one you asked for. Away from every hazard the two arrows are identical: the filter is invisible. Only when your command has an inward component does it remove exactly that component and nothing else, which is why the robot slides rather than stops.

This is what makes a safety filter composable: it does not replace your controller, it defers to it. Any policy at all can drive — a hand controller, a planner, a black-box neural policy — and the guarantee holds regardless, because it is enforced on the command that actually reaches the motors, not on the thing that produced it. Turn berth α down for a wider, more cautious margin; up to let it commit later and graze closer.

04 — the guaranteeNot "usually." Never.

On load, this page took a robot, aimed it dead-centre at a hazard, and integrated twenty thousand steps of a command pointing straight in — then recorded the smallest safety margin over the whole run:

smallest safety margin h over 20,000 steps
margin where it came to rest (on the boundary)
did it ever enter the hazard?

The margin never goes negative — not as an average, not with high probability, but on every single step. Because the barrier condition is convex here, each discrete step lands on the safe side of its own linear prediction, so the discrete robot is at least as safe as the continuous guarantee promises.

05 — the pointSafety as a filter, not a hope

The guarantee lives on the command, not the controller.

Whatever asks for the motion — teleop, a planner, a learned policy you did not write and cannot fully trust — the last thing it passes through is one small convex program that will not sign off on a command that crosses the barrier.

For physical AI this is the shape of the safety story worth betting on. You are not going to verify a large neural policy line by line, and you do not have to. You wrap it in a certified filter whose only job is to keep one inequality true, and you get a guarantee that holds no matter how the policy behaves. The controller can be as clever, as learned, as opaque as you like; the barrier is simple enough to prove correct, and it has the last word.

What you just drove: the CbfFilter and CbfConstraint from ferromotion-control, compiled to WebAssembly — the same code the native tools link against, not a reimplementation. Each hazard becomes a relative-degree-1 barrier; the filter is a small quadratic program (closed-form for a single active hazard, clarabel otherwise). Nothing is precomputed — the correction is solved every frame, and the guarantee above was integrated live on load.

Verified in the library: the robot cannot be driven into a hazard over 20,000 steps aimed straight in (min h ≥ 0) · a safe command passes through bit-for-bit unchanged · the correction is the exact orthogonal projection — only the inward component is removed, so tangential motion is untouched · a whole field of hazards is respected at once · larger α rides provably closer. Each is a test in cargo test, not a claim in prose. See also chapter 1 and chapter 2.

Institute for Physical AI · the Rust library · crates.io