{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# When a Barrier Filter’s Assumptions Break\n",
        "\n",
        "A scalar control barrier filter makes its assumptions visible: continuous feedback, sampled commands, model bias, and actuator feasibility.\n",
        "\n",
        "Scalar first-order margin dynamics and an analytic projection, entirely in arithmetic simulation. Diagnostic continuation after infeasibility is not a valid CBF solution or a real-system safety guarantee.\n",
        "\n",
        "The code uses Python 3 and the standard library. Saved output is from the checked CPU run.\n"
      ],
      "id": "control-barrier-filter-assumpt-0"
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "source": [
        "def simulate(dt, bias, filtered=True):\n",
        "    h, minimum = 1.0, 1.0\n",
        "    violations, infeasible = 0, 0\n",
        "    alpha, lower_limit, upper_limit = 2.0, -1.0, 1.0\n",
        "    for _ in range(round(6.0/dt)):\n",
        "        nominal = -1.0\n",
        "        if filtered:\n",
        "            lower = max(lower_limit, -alpha*h)\n",
        "            if lower > upper_limit:\n",
        "                infeasible += 1\n",
        "                u = upper_limit  # diagnostic continuation, not a feasible solution\n",
        "            else:\n",
        "                u = max(lower, min(upper_limit, nominal))\n",
        "        else:\n",
        "            u = nominal\n",
        "        h += dt*(u-bias)\n",
        "        minimum = min(minimum, h)\n",
        "        violations += int(h < -1e-12)\n",
        "    return minimum, violations, infeasible\n",
        "\n",
        "cases = ((0.1, 0.0, False), (0.1, 0.0, True), (0.75, 0.0, True),\n",
        "         (0.1, 0.2, True), (0.1, 2.0, True))\n",
        "for dt, bias, filtered in cases:\n",
        "    minimum, violations, infeasible = simulate(dt, bias, filtered)\n",
        "    print(f'dt={dt:.2f} bias={bias:.1f} filter={filtered} min_h={minimum:.4f} negative_samples={violations} infeasible={infeasible}')\n",
        "assert simulate(0.1, 0.0)[0] >= 0\n",
        "assert simulate(0.75, 0.0)[0] < 0\n",
        "assert simulate(0.1, 2.0)[2] > 0\n"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "dt=0.10 bias=0.0 filter=False min_h=-5.0000 negative_samples=50 infeasible=0\n",
            "dt=0.10 bias=0.0 filter=True min_h=0.0000 negative_samples=0 infeasible=0\n",
            "dt=0.75 bias=0.0 filter=True min_h=-0.1250 negative_samples=4 infeasible=0\n",
            "dt=0.10 bias=0.2 filter=True min_h=-0.1000 negative_samples=48 infeasible=0\n",
            "dt=0.10 bias=2.0 filter=True min_h=-5.8412 negative_samples=57 infeasible=53\n"
          ]
        }
      ],
      "id": "control-barrier-filter-assumpt-1"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Sources\n",
        "\n",
        "- Control Barrier Function Based Quadratic Programs for Safety Critical Systems: https://arxiv.org/abs/1609.06408\n"
      ],
      "id": "control-barrier-filter-assumpt-2"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.12.14"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
