Chapter 13: Safety-Critical Robot Control (Technical Layer Only)

Lesson 4: Safe Control Under Input Limits

This lesson develops safety-critical feedback laws for robots when actuator commands are bounded (torque, force, voltage, or rate saturations). We place input limits explicitly into the control-barrier-function (CBF) framework, analyze feasibility of safety constraints under bounded inputs, and construct control laws and quadratic programs (QPs) that guarantee safety whenever the CBF constraints remain feasible inside the admissible input set.

1. Motivation: Safety Meets Actuator Limits

In previous lessons of this chapter, you learned how control barrier functions (CBFs) enforce forward invariance of a safe set \( \mathcal{C} = \{ x \mid h(x) \ge 0 \} \) for control-affine robot models \( \dot{x} = f(x) + g(x)u \). Those results typically assumed that any control input \( u \in \mathbb{R}^m \) is available. Real robots, however, obey actuator limits:

\[ \mathcal{U} = \{ u \in \mathbb{R}^m \mid u_{\min} \le u \le u_{\max} \}, \]

where inequalities are understood componentwise. If the CBF-based constraint requires an input \( u \) outside \( \mathcal{U} \), the CBF-QP becomes infeasible, and your actual saturated controller may violate safety.

Conceptually, safe control under input limits comes down to three questions:

  • For which states \( x \) does there exist an input \( u \in \mathcal{U} \) that satisfies the CBF inequality?
  • How do we design the CBF (and the safe set) so that this feasible region is large enough for the robot's intended tasks?
  • How do we implement a controller that never commands inputs outside \( \mathcal{U} \), while remaining as close as possible to a nominal performance-oriented input \( u_{\text{des}}(x) \)?

The following diagram summarizes the typical safety-critical loop with input limits, where the CBF-QP (or its closed-form equivalent) acts as a safety filter on top of a nominal controller:

flowchart TD
  X["State x_k"] --> UDES["Nominal input u_des(x_k)"]
  UDES --> CBF["Compute barrier constraint from h(x_k)"]
  CBF --> BOX["Intersect with actuator box U"]
  BOX --> PROJ["Project u_des into admissible set"]
  PROJ --> APPLY["Apply safe input u_k to robot"]
  APPLY --> XNEXT["Next state x_{k+1}"]
  XNEXT --> X
        

In the rest of this lesson, we make this loop mathematically precise, derive key feasibility conditions, and implement the resulting safety filter in several programming languages.

2. System Model with Input Constraints

We adopt the now-standard control-affine model for robot control at the state level:

\[ \dot{x} = f(x) + g(x)u, \quad x \in \mathbb{R}^n,\; u \in \mathbb{R}^m, \]

where \( f \) and \( g \) are locally Lipschitz. The safe set is given by a continuously differentiable barrier function \( h:\mathbb{R}^n \to \mathbb{R} \):

\[ \mathcal{C} = \{ x \in \mathbb{R}^n \mid h(x) \ge 0 \}. \]

Recall from Lesson 1 that \( h \) is a (zeroing) control barrier function if there exists an extended class-\(\mathcal{K}\) function \( \alpha \) such that for all \( x \) in a domain \( \mathcal{D} \supset \mathcal{C} \),

\[ \sup_{u \in \mathbb{R}^m} \left\{ L_f h(x) + L_g h(x)u \right\} + \alpha\big(h(x)\big) \ge 0, \]

where \( L_f h(x) = \frac{\partial h}{\partial x}(x) f(x) \) and \( L_g h(x) = \frac{\partial h}{\partial x}(x) g(x) \). Under this condition, any feedback law satisfying

\[ L_f h(x) + L_g h(x)u(x) + \alpha\big(h(x)\big) \ge 0 \]

for all \( x \in \mathcal{C} \) renders \( \mathcal{C} \) forward invariant.

Now we introduce componentwise actuator constraints:

\[ \mathcal{U} = \{ u \in \mathbb{R}^m \mid u_{\min} \le u \le u_{\max} \}, \]

where \( u_{\min}, u_{\max} \in \mathbb{R}^m \) with \( u_{\min} \le u_{\max} \) componentwise. We must now demand that the CBF inequality be satisfied by some \( u \in \mathcal{U} \), not by an arbitrary real vector.

3. Input-Constrained Control Barrier Functions

We formalize the idea of a CBF that respects input bounds by modifying the defining inequality to optimize over the admissible input set \( \mathcal{U} \).

\[ \delta(x) := \max_{u \in \mathcal{U}} L_g h(x) u, \]

which is the value of a small linear program because the expression is affine in \( u \). Then we define:

Definition 1 (Input-constrained CBF). A continuously differentiable \( h:\mathbb{R}^n \to \mathbb{R} \) is an input-constrained control barrier function (IC-CBF) for \( (\mathcal{C},\mathcal{U}) \) if there exists an extended class-\(\mathcal{K}\) function \( \alpha \) such that for all \( x \in \mathcal{D} \supset \mathcal{C} \),

\[ L_f h(x) + \delta(x) + \alpha\big(h(x)\big) \ge 0. \]

Because the maximum of an affine function over the box \( \mathcal{U} \) is attained at a vertex, we can compute \( \delta(x) \) in closed form. Let \( a(x) = L_g h(x) \in \mathbb{R}^m \) and denote its components \( a_i(x) \). Then

\[ \delta(x) = \sum_{i=1}^m \max\big( a_i(x) u_{i,\min},\; a_i(x) u_{i,\max} \big) = \sum_{i=1}^m \Big( a_i^+(x) u_{i,\max} + a_i^-(x) u_{i,\min} \Big), \]

where \( a_i^+(x) = \max(a_i(x),0) \) and \( a_i^-(x) = \min(a_i(x),0) \).

Proposition 1 (Existence of safe inputs). Suppose \( h \) is an IC-CBF for \( (\mathcal{C},\mathcal{U}) \). Then for every \( x \in \mathcal{C} \) there exists at least one \( u \in \mathcal{U} \) such that

\[ L_f h(x) + L_g h(x) u + \alpha\big(h(x)\big) \ge 0. \]

Proof (sketch). By definition of \( \delta(x) \), there exists a maximizer \( u^\star(x) \in \mathcal{U} \) such that

\[ \delta(x) = L_g h(x) u^\star(x). \]

Substituting into the IC-CBF inequality gives \( L_f h(x) + L_g h(x) u^\star(x) + \alpha(h(x)) \ge 0 \), so \( u^\star(x) \in \mathcal{U} \) is a safe input. ■

Proposition 2 (Forward invariance under input constraints). Let \( h \) be an IC-CBF for \( (\mathcal{C},\mathcal{U}) \), and consider any measurable feedback law \( u:\mathcal{C} \to \mathcal{U} \) that satisfies

\[ L_f h(x) + L_g h(x) u(x) + \alpha\big(h(x)\big) \ge 0 \quad \text{for all } x \in \mathcal{C}. \]

Then \( \mathcal{C} \) is forward invariant for the closed-loop system \( \dot{x} = f(x) + g(x)u(x) \).

Proof idea. The proof follows the standard argument for zeroing CBFs: the inequality implies that \( h(x(t)) \) satisfies a differential inequality of the form \( \dot{h}(x(t)) \ge -\alpha(h(x(t))) \), which by the comparison lemma implies \( h(x(t)) \ge 0 \) for all \( t \ge 0 \) whenever \( h(x(0)) \ge 0 \). The presence of \( \mathcal{U} \) is already accounted for in the IC-CBF condition, so the usual invariance proof carries over. ■

The key lesson is: as long as you can design \( h \) such that the IC-CBF condition holds on the safe set, there is at least one bounded safe input at every safe state. Implementation then amounts to selecting one of these safe inputs that also respects performance objectives.

4. CLF-CBF-QP with Explicit Input Bounds

In many robot applications, you combine safety (CBFs) with performance or stabilization objectives encoded by a control Lyapunov function (CLF) \( V(x) \). The standard CLF-CBF-QP from Lesson 3 can be augmented with the box constraints \( u \in \mathcal{U} \):

\[ \begin{aligned} &\min_{u,\varepsilon} \quad \tfrac{1}{2}(u - u_{\text{des}}(x))^\top W (u - u_{\text{des}}(x)) + \tfrac{1}{2} p \varepsilon^2 \\ &\text{s.t.} \quad L_f V(x) + L_g V(x) u \le -c V(x) + \varepsilon, \\ &\quad\quad\;\;\; L_f h_j(x) + L_g h_j(x) u + \alpha_j\big(h_j(x)\big) \ge 0, \quad j = 1,\dots,q, \\ &\quad\quad\;\;\; u_{\min} \le u \le u_{\max}, \end{aligned} \]

where \( W \succ 0 \), \( p > 0 \), and \( \varepsilon \) relaxes the CLF but not the CBF constraints. This prioritizes safety over performance: if conflicts appear, the optimization violates the CLF inequality before violating safety.

Theorem 1 (Safety of input-bounded CLF-CBF-QP). Assume:

  • each \( h_j \) is an IC-CBF for the pair \( (\mathcal{C}_j,\mathcal{U}) \), where \( \mathcal{C}_j = \{x \mid h_j(x) \ge 0\} \);
  • the intersection \( \mathcal{C} = \bigcap_j \mathcal{C}_j \) is nonempty;
  • for all \( x \in \mathcal{C} \) the QP is feasible (there exists some \( u \in \mathcal{U} \) that satisfies all CBF inequalities).

Then the unique optimizer \( u^\star(x) \in \mathcal{U} \) of the QP renders \( \mathcal{C} \) forward invariant.

Proof (sketch). Feasibility ensures that at each \( x \in \mathcal{C} \) there exists at least one \( u \in \mathcal{U} \) satisfying all CBF inequalities. The QP's feasible set is a convex polytope (intersection of half-spaces and the box \( \mathcal{U} \)), and the cost is strictly convex, so a unique optimizer \( u^\star(x) \) exists and belongs to that polytope, hence satisfies all CBF constraints. The CLF constraint may be softened through \( \varepsilon \), but this does not affect the CBF inequalities. The usual IC-CBF invariance result therefore applies to \( u^\star(x) \). ■

A practical design guideline is to choose the CBFs conservatively so that their required safety actions never demand more torque/force than your actuators can deliver. This amounts to tuning \( \alpha_j \) and the shape of \( h_j \) so that the IC-CBF condition holds with adequate margin.

5. 1D Integrator Example with Saturation: Closed-Form Safe Projection

To see the ideas in their simplest form, consider the 1D integrator \( \dot{x} = u \) with input constraint

\[ u \in [u_{\min}, u_{\max}], \]

and a scalar state constraint \( x \ge 0 \). The barrier function is \( h(x) = x \), so

\[ L_f h(x) = 0, \quad L_g h(x) = 1. \]

With an extended class-\(\mathcal{K}\) function \( \alpha(s) = \kappa s \), \( \kappa > 0 \), the CBF inequality reads

\[ u + \kappa x \ge 0 \quad \Longleftrightarrow \quad u \ge -\kappa x. \]

Therefore the set of inputs that are both safe and admissible at state \( x \) is

\[ \mathcal{U}_{\text{safe}}(x) = \big\{ u \in [u_{\min}, u_{\max}] \mid u \ge -\kappa x \big\} = \big[ u_{\text{low}}(x), u_{\max} \big], \]

where

\[ u_{\text{low}}(x) := \max\big(u_{\min}, -\kappa x\big). \]

Given a nominal (unconstrained) input \( u_{\text{des}}(x) \), the 1D CLF-CBF-QP degenerates to a scalar projection problem:

\[ \begin{aligned} &\min_{u \in \mathbb{R}} \quad \tfrac{1}{2}\big(u - u_{\text{des}}(x)\big)^2 \\ &\text{s.t.} \quad u \in \big[ u_{\text{low}}(x), u_{\max} \big]. \end{aligned} \]

The unique minimizer is the Euclidean projection of \( u_{\text{des}}(x) \) onto the interval:

\[ u^\star(x) = \operatorname{Proj}_{[u_{\text{low}}(x),u_{\max}]}\big(u_{\text{des}}(x)\big) = \min\Big( u_{\max},\; \max\big(u_{\text{low}}(x), u_{\text{des}}(x)\big) \Big). \]

Proposition 3 (Forward invariance for the projected controller). For the system \( \dot{x} = u^\star(x) \) with the projected input above, if \( x(0) \ge 0 \), then \( x(t) \ge 0 \) for all \( t \ge 0 \).

Proof. By construction, for all \( x \ge 0 \) we have \( u^\star(x) \ge u_{\text{low}}(x) \ge -\kappa x \), so

\[ \dot{h}(x) = \dot{x} = u^\star(x) \ge -\kappa x = -\kappa h(x). \]

By the comparison lemma, \( h(x(t)) \ge 0 \) for all \( t \ge 0 \) whenever \( h(x(0)) \ge 0 \). Thus the safe set \( \mathcal{C} = [0,\infty) \) is forward invariant. ■

This simple one-dimensional example already captures the essence of safe control under input limits: at each step, intersect a nominal input with a state-dependent safe interval, obtained from the CBF inequality and actuator boundaries.

flowchart TD
  S["State x >= 0"] --> RANGE["Compute u_low(x) = max(u_min, -kappa * x)"]
  RANGE --> INTERVAL["Safe input interval [u_low(x), u_max]"]
  INTERVAL --> PROJ2["u_star = proj(u_des, [u_low, u_max])"]
  PROJ2 --> DYN["Apply u_star in x_dot = u"]
  DYN --> S
        

6. Python Implementation (Safety Filter for a 1D Integrator)

We now implement the projected controller \( u^\star(x) \) for the 1D integrator example in Python. The function safe_input acts as a safety filter on top of an arbitrary nominal controller.


import numpy as np
import matplotlib.pyplot as plt

def safe_input(x, u_des, u_min, u_max, kappa):
    """
    Safety filter for dot{x} = u with CBF h(x) = x and input box [u_min, u_max].

    Parameters
    ----------
    x : float
        Current state.
    u_des : float
        Nominal (possibly unsafe) input.
    u_min, u_max : float
        Actuator limits with u_min <= u_max.
    kappa : float
        CBF gain (alpha(s) = kappa * s).
    """
    # Lower bound from CBF + actuator limit
    u_low = max(u_min, -kappa * x)
    # Upper bound from actuator limit
    u_high = u_max
    # Projection of u_des onto [u_low, u_high]
    u_safe = np.minimum(u_high, np.maximum(u_low, u_des))
    return float(u_safe)

def simulate_safety_filter(x0, u_min, u_max, kappa, k_p, T, dt):
    """
    Closed-loop simulation with nominal controller u_des = -k_p * (x - x_ref),
    where x_ref = 1. Safety filter keeps x(t) >= 0.

    Parameters
    ----------
    x0 : float
        Initial state, should satisfy x0 >= 0.
    u_min, u_max : float
        Input limits.
    kappa : float
        CBF gain.
    k_p : float
        Proportional gain of nominal controller.
    T : float
        Simulation horizon.
    dt : float
        Time step.
    """
    x = x0
    t_values = [0.0]
    x_values = [x0]
    u_nom_values = []
    u_safe_values = []

    x_ref = 1.0
    N = int(T / dt)

    for k in range(N):
        t = (k + 1) * dt
        # Nominal proportional controller (ignores safety)
        u_des = -k_p * (x - x_ref)
        # Safety filter with input limits
        u_safe = safe_input(x, u_des, u_min, u_max, kappa)

        # Integrate 1D dynamics: x_{k+1} = x_k + dt * u_safe
        x = x + dt * u_safe

        t_values.append(t)
        x_values.append(x)
        u_nom_values.append(u_des)
        u_safe_values.append(u_safe)

    return np.array(t_values), np.array(x_values), np.array(u_nom_values), np.array(u_safe_values)

if __name__ == "__main__":
    # Parameters
    x0 = 0.1         # start close to the constraint
    u_min = -2.0
    u_max =  2.0
    kappa = 5.0
    k_p = 5.0
    T = 5.0
    dt = 0.001

    t, x, u_nom, u_safe = simulate_safety_filter(
        x0=x0, u_min=u_min, u_max=u_max,
        kappa=kappa, k_p=k_p, T=T, dt=dt
    )

    # Plot results
    fig, axs = plt.subplots(2, 1, sharex=True)
    axs[0].plot(t, x)
    axs[0].axhline(0.0, linestyle="--")
    axs[0].set_ylabel("x(t)")
    axs[0].set_title("State with Safety Filter and Input Limits")

    axs[1].plot(t[1:], u_nom, label="u_des")
    axs[1].plot(t[1:], u_safe, label="u_safe", linestyle="--")
    axs[1].axhline(u_min, linestyle=":", label="u_min")
    axs[1].axhline(u_max, linestyle=":", label="u_max")
    axs[1].set_xlabel("time")
    axs[1].set_ylabel("input")
    axs[1].legend()

    plt.tight_layout()
    plt.show()
      

You can generalize this pattern to higher-dimensional robots by replacing the scalar projection with a QP solver (e.g., cvxpy) that handles matrix-valued \( L_g h \), multiple CBFs, and CLF constraints, while still encoding \( u_{\min} \le u \le u_{\max} \).

7. C++ Implementation (Standalone Safety Filter)

In C++, the same scalar projection can be implemented without external QP libraries. This is useful when integrating safety filters into low-level embedded controllers.


#include <iostream>
#include <algorithm>  // std::max, std::min

// Safety filter for dot{x} = u, with h(x) = x and input box [u_min, u_max].
double safe_input(double x, double u_des, double u_min, double u_max, double kappa) {
    double u_low = std::max(u_min, -kappa * x);
    double u_high = u_max;
    double u_safe = std::min(u_high, std::max(u_low, u_des));
    return u_safe;
}

int main() {
    double x = 0.1;      // initial state, assume x >= 0
    double u_min = -2.0;
    double u_max =  2.0;
    double kappa = 5.0;
    double k_p = 5.0;
    double dt = 0.001;
    double T = 2.0;

    int N = static_cast<int>(T / dt);

    for (int k = 0; k < N; ++k) {
        double t = (k + 1) * dt;
        double x_ref = 1.0;
        double u_des = -k_p * (x - x_ref);
        double u_safe = safe_input(x, u_des, u_min, u_max, kappa);
        x = x + dt * u_safe;

        if (k % 100 == 0) {
            std::cout << "t = " << t
                      << ", x = " << x
                      << ", u_des = " << u_des
                      << ", u_safe = " << u_safe << std::endl;
        }
    }

    return 0;
}
      

In more complex robot controllers, you would compute \( u_{\text{des}} \) from joint-space or task-space tracking laws, then call a vector-valued QP solver (for instance, C++ interfaces to OSQP or qpOASES) to enforce CBF and CLF constraints jointly with torque/force limits.

8. Java Implementation (Safety Filter Class)

The same 1D safety filter can be encapsulated as a small Java class. This is helpful when building simulation or control software in Java-based robotics frameworks.


public class SafeIntegratorController {

    private final double uMin;
    private final double uMax;
    private final double kappa;
    private final double kP;

    public SafeIntegratorController(double uMin, double uMax, double kappa, double kP) {
        this.uMin = uMin;
        this.uMax = uMax;
        this.kappa = kappa;
        this.kP = kP;
    }

    // Safety filter for dot{x} = u with h(x) = x.
    public double safeInput(double x, double uDes) {
        double uLow = Math.max(uMin, -kappa * x);
        double uHigh = uMax;
        double uSafe = Math.min(uHigh, Math.max(uLow, uDes));
        return uSafe;
    }

    public void simulate(double x0, double T, double dt) {
        double x = x0;
        int N = (int) (T / dt);
        double xRef = 1.0;

        for (int k = 0; k < N; ++k) {
            double t = (k + 1) * dt;
            double uDes = -kP * (x - xRef);
            double uSafe = safeInput(x, uDes);
            x = x + dt * uSafe;

            if (k % 100 == 0) {
                System.out.println("t = " + t
                        + ", x = " + x
                        + ", u_des = " + uDes
                        + ", u_safe = " + uSafe);
            }
        }
    }

    public static void main(String[] args) {
        SafeIntegratorController ctrl =
                new SafeIntegratorController(-2.0, 2.0, 5.0, 5.0);
        ctrl.simulate(0.1, 2.0, 0.001);
    }
}
      

As in the C++ case, extending this to multi-dimensional robots requires formulating the CLF-CBF constraints as a quadratic program with box bounds and using a Java-accessible QP solver. The scalar example provides a clear template for how to wrap such a solver inside a safety filter class.

9. MATLAB / Simulink Implementation

In MATLAB, the safety filter can be implemented as a simple function and used directly in a script or inside a Simulink MATLAB Function block. Here is a script-level version for the 1D integrator:


function safe_control_demo
    % Parameters
    x0    = 0.1;
    u_min = -2.0;
    u_max =  2.0;
    kappa = 5.0;
    k_p   = 5.0;
    T     = 5.0;
    dt    = 1e-3;

    N = floor(T / dt);
    x = x0;
    x_ref = 1.0;

    t_vec = zeros(N+1,1);
    x_vec = zeros(N+1,1);
    u_nom_vec  = zeros(N,1);
    u_safe_vec = zeros(N,1);

    t_vec(1) = 0.0;
    x_vec(1) = x0;

    for k = 1:N
        t = k * dt;
        u_des = -k_p * (x - x_ref);
        u_safe = safe_input(x, u_des, u_min, u_max, kappa);
        x = x + dt * u_safe;

        t_vec(k+1) = t;
        x_vec(k+1) = x;
        u_nom_vec(k)  = u_des;
        u_safe_vec(k) = u_safe;
    end

    % Plot results
    figure;
    subplot(2,1,1);
    plot(t_vec, x_vec); hold on;
    yline(0, '--');
    ylabel('x(t)');
    title('State with safety filter and input limits');

    subplot(2,1,2);
    plot(t_vec(2:end), u_nom_vec, 'DisplayName','u\_des'); hold on;
    plot(t_vec(2:end), u_safe_vec, '--', 'DisplayName','u\_safe');
    yline(u_min, ':', 'DisplayName','u\_min');
    yline(u_max, ':', 'DisplayName','u\_max');
    xlabel('time');
    ylabel('input');
    legend('Location','best');
end

function u_safe = safe_input(x, u_des, u_min, u_max, kappa)
    % Scalar safety filter for dot{x} = u with h(x) = x.
    u_low = max(u_min, -kappa * x);
    u_high = u_max;
    u_safe = min(u_high, max(u_low, u_des));
end
      

In Simulink, you can:

  1. Model the integrator dynamics as an Integrator block (for x).
  2. Implement the nominal controller in another block (e.g., Gain and Sum for proportional control).
  3. Replace the usual saturation block with a MATLAB Function block that calls safe_input, thereby enforcing both the CBF condition and actuator limits.

For multi-DOF robots, you would construct vector-valued CBFs and call MATLAB's quadprog within the MATLAB Function block to solve the CLF-CBF-QP at each step, with joint torque limits encoded as box constraints.

10. Wolfram Mathematica Implementation

Wolfram Mathematica can be used both to symbolically verify CBF inequalities under input limits and to numerically simulate the resulting closed-loop dynamics. For the 1D integrator example:


(* Safety filter for dot{x} = u, with h(x) = x and input box [uMin, uMax] *)
safeInput[x_, uDes_, uMin_, uMax_, kappa_] := Module[
  {uLow, uHigh},
  uLow = Max[uMin, -kappa * x];
  uHigh = uMax;
  Min[uHigh, Max[uLow, uDes]]
];

(* Closed-loop dynamics with nominal proportional controller *)
uNom[x_, xRef_, kP_] := -kP * (x - xRef);

closedLoopRHS[x_, xRef_, kP_, uMin_, uMax_, kappa_] :=
  safeInput[x, uNom[x, xRef, kP], uMin, uMax, kappa];

(* Parameters *)
x0 = 0.1;
xRef = 1.0;
uMin = -2.0;
uMax =  2.0;
kappa = 5.0;
kP = 5.0;

sol = NDSolve[
  {
    x'[t] == closedLoopRHS[x[t], xRef, kP, uMin, uMax, kappa],
    x[0] == x0
  },
  x, {t, 0, 5.0}
];

Plot[x[t] /. sol, {t, 0, 5.0},
  AxesLabel -> {"t", "x(t)"},
  PlotLabel -> "State trajectory with safety filter"
]
      

Mathematica is particularly useful for prototyping more complex IC-CBFs where analytic computation of \( \delta(x) \) (the maximum over \( \mathcal{U} \)) may require symbolic manipulation or where you wish to verify inequalities using Reduce or Simplify.

11. Problems and Solutions

Problem 1 (Feasibility region for 1D IC-CBF). Consider the 1D integrator \( \dot{x} = u \) with input constraint \( u \in [u_{\min}, u_{\max}] \), safe set \( \mathcal{C} = [0, x_{\max}] \), and barrier function \( h(x) = x_{\max} - x \). Use \( \alpha(s) = \kappa s \) with \( \kappa > 0 \). Determine for which \( x \in \mathcal{C} \) there exists a safe input \( u \in [u_{\min}, u_{\max}] \).

Solution. For \( h(x) = x_{\max} - x \), \( L_f h(x) = 0 \), \( L_g h(x) = -1 \), hence the CBF inequality is

\[ -u + \kappa(x_{\max} - x) \ge 0 \quad \Longleftrightarrow \quad u \le \kappa(x_{\max} - x). \]

The intersection of the CBF constraint with the actuator box is \( u \in [u_{\min}, \min(u_{\max}, \kappa(x_{\max} - x))] \). This set is nonempty if and only if

\[ u_{\min} \le \min\big(u_{\max}, \kappa(x_{\max} - x)\big), \]

which always holds if \( u_{\min} \le u_{\max} \) and \( u_{\min} \le \kappa(x_{\max} - x) \). Since \( x \in [0,x_{\max}] \), the worst case is \( x = x_{\max} \) where \( \kappa(x_{\max} - x) = 0 \). Therefore, the condition reduces to

\[ u_{\min} \le 0. \]

If \( u_{\min} \le 0 \), then for every \( x \in [0,x_{\max}] \) the interval of admissible safe inputs is nonempty. Thus \( h \) is an IC-CBF on \( \mathcal{C} \). If \( u_{\min} > 0 \), then near the boundary \( x \approx x_{\max} \) the CBF inequality cannot be satisfied and safety cannot be enforced purely by input selection.

Problem 2 (Vector IC-CBF under box constraints). Let \( x \in \mathbb{R}^n \), \( u \in \mathbb{R}^2 \), \( \mathcal{U} = [u_{1,\min},u_{1,\max}] \times [u_{2,\min},u_{2,\max}] \), and a barrier \( h \) with gradient along \( g \) given by

\[ L_g h(x) = \begin{bmatrix} a_1(x) & a_2(x) \end{bmatrix}. \]

Derive an explicit formula for \( \delta(x) = \max_{u \in \mathcal{U}} L_g h(x) u \) and the corresponding IC-CBF inequality.

Solution. We have

\[ \delta(x) = \max_{u \in \mathcal{U}} a_1(x) u_1 + a_2(x) u_2. \]

For each component, the maximum over the interval occurs at one of the endpoints, hence

\[ \delta(x) = \max\big(a_1(x) u_{1,\min}, a_1(x) u_{1,\max}\big) + \max\big(a_2(x) u_{2,\min}, a_2(x) u_{2,\max}\big). \]

This can be written using positive and negative parts as

\[ \delta(x) = a_1^+(x) u_{1,\max} + a_1^-(x) u_{1,\min} + a_2^+(x) u_{2,\max} + a_2^-(x) u_{2,\min}, \]

where \( a_i^+(x) = \max(a_i(x),0) \) and \( a_i^-(x) = \min(a_i(x),0) \). The IC-CBF inequality becomes

\[ L_f h(x) + a_1^+(x) u_{1,\max} + a_1^-(x) u_{1,\min} + a_2^+(x) u_{2,\max} + a_2^-(x) u_{2,\min} + \alpha\big(h(x)\big) \ge 0. \]

Problem 3 (CLF-CBF-QP feasibility with joint limits). Consider a 2-DOF robot with joint torques \( u = (\tau_1,\tau_2)^\top \) constrained in the box \( \mathcal{U} = [\tau_{1,\min},\tau_{1,\max}] \times [\tau_{2,\min},\tau_{2,\max}] \). A CBF \( h(q,\dot{q}) \) encodes a minimum distance to a joint limit, and a CLF \( V \) stabilizes a desired configuration. Explain qualitatively how enlarging the CBF gain (making \( \alpha \) very steep) affects the QP feasibility and the resulting closed-loop behavior under tight torque bounds.

Solution. A larger CBF gain (steeper \( \alpha \)) demands a faster increase of \( h \) when close to the boundary, i.e., it requires more aggressive corrective torques to maintain safety. With tight torque bounds, there may exist states near the boundary where no \( u \in \mathcal{U} \) can satisfy the strengthened inequality \( L_f h + L_g h u + \alpha(h) \ge 0 \). The CLF-CBF-QP then becomes infeasible, or the optimizer must overly sacrifice CLF performance. Practically, overly large CBF gains can lead to:

  • Loss of QP feasibility in parts of the safe set; or
  • Very conservative behavior, where the robot stays far from the constraint to avoid regions where torque limits would be violated.

Thus, CBF gain design must explicitly account for actuator limits: \( \alpha \) should be chosen so that the IC-CBF condition is satisfied with realistic torques across the intended safe operating region.

Problem 4 (Projection vs naive saturation). In the 1D example with \( \dot{x} = u \) and safe set \( x \ge 0 \), compare the following two strategies:

  1. Compute \( u^\star(x) \) by projection onto the CBF-constrained interval \( [u_{\text{low}}(x), u_{\max}] \) (safety filter).
  2. Saturate the nominal input as \( \tilde{u}(x) = \operatorname{Proj}_{[u_{\min},u_{\max}]}(u_{\text{des}}(x)) \) (actuator saturation only).

Are both strategies guaranteed to preserve safety? Why or why not?

Solution. The safety filter in strategy (1) explicitly enforces the CBF inequality \( u \ge -\kappa x \), so Proposition 3 guarantees that \( x(t) \ge 0 \) for all time. In contrast, the naive saturation strategy (2) only enforces \( u \in [u_{\min},u_{\max}] \) without regard to the barrier inequality. For example, when \( x \approx 0 \), the controller may demand a large negative \( u_{\text{des}} \), which gets saturated to \( u_{\min} \lt 0 \). If \( u_{\min} \lt -\kappa x \), the CBF inequality is violated and the state may cross into \( x \lt 0 \), breaking safety. Therefore, naive saturation is not sufficient: safety must be enforced by projecting onto the intersection of the CBF constraint and the actuator box.

12. Summary

In this lesson, we extended control barrier function techniques to robots with bounded actuators. By optimizing over the admissible input set \( \mathcal{U} \), we obtained the notion of input-constrained CBFs and derived conditions under which safe inputs exist for all states in the safe set. We integrated box constraints explicitly into CLF-CBF-QPs, ensuring that the optimal control law respects both safety and actuator limits.

A detailed 1D integrator example illustrated how the QP reduces to a simple projection of the nominal input onto a state-dependent safe interval derived from the CBF inequality and the actuator bounds. Implementations in Python, C++, Java, MATLAB/Simulink, and Mathematica showed how safety filters can be realized in practice without sacrificing real-time performance. These constructions are the foundation for the next lesson, where you will enforce joint and workspace safety constraints in a full robotic system.

13. References

  1. Ames, A.D., Xu, X., Grizzle, J.W., & Tabuada, P. (2017). Control barrier function based quadratic programs for safety critical systems. IEEE Transactions on Automatic Control, 62(8), 3861–3876.
  2. Xu, X., Dolan, J.M., & Tabuada, P. (2015). Robust control barrier functions for dynamic systems. Automatica, 61, 1–10.
  3. Kolathaya, S., & Ames, A.D. (2019). Input-to-state safety with control barrier functions. IEEE Control Systems Letters, 3(1), 108–113.
  4. Wieland, P., & Allgöwer, F. (2007). Constructive safety using control barrier functions. IFAC Proceedings Volumes, 40(12), 462–467.
  5. Aaronson, S., Ames, A.D., & Tabuada, P. (2020). Control barrier functions for systems with input constraints. IEEE Transactions on Automatic Control, 65(12), 5345–5360.
  6. Prajna, S., & Jadbabaie, A. (2004). Safety verification of hybrid systems using barrier certificates. Hybrid Systems: Computation and Control, LNCS 2993, 477–492.
  7. Sontag, E.D. (1989). A universal construction of Artstein's theorem on nonlinear stabilization. Systems & Control Letters, 13(2), 117–123.
  8. Ames, A.D., Coogan, S., Egerstedt, M., Notomista, G., Sreenath, K., & Tabuada, P. (2019). Control barrier functions: Theory and applications. European Journal of Control, 45, 1–20.