Skip to content

Commit 50c90d3

Browse files
authored
Release v0.3.0 — slim install, safe-RL Colab, GitHub Pages blog, and green CI (#362)
* feat: v0.3.0 — slim install, safe-RL Colab, GitHub Pages, and green CI Package CBFKit for distribution and first-time users: - Slim the core: move casadi/cvxopt/plotly/black from mandatory deps to extras (casadi, cvxopt, plotly, codegen); add all/solvers/vis umbrellas; dev pulls cbfkit[all]. `import cbfkit` now loads zero heavy deps, guarded by a new core-import CI job. - Bump VERSION to 0.3.0; enrich metadata (keywords, classifiers, URLs); absolutize README showcase image URLs so they render off-repo. - Add a Gymnasium safe-RL Colab quickstart (installs from GitHub). - README badges; GitHub Pages workflow to host the blog. - run_black degrades gracefully when black is absent so codegen works on a slim install; add a friendly ImportError for the CasADi controller path. Fix pre-existing CI failures (ruff was red on main, blocking all tests): - Remove unused locals (unicycle_sweep, monte_carlo_gpu, plot_mppi_ffmpeg). - Import Time in ros/_experiment.py (F821 undefined name). - Manim 2D backend raises NotImplementedError before requiring manim; guard the manim_3d_multi_robot import so the module loads without manim installed. Verified: 469 passed, ruff clean, python -m build + twine check pass. * fix(blog): carousel clicks, dark-section contrast, and README-style showcase gallery Browser-QA pass on the landing page (desktop 1440px + mobile 390px): - Carousel prev/next never fired: .bc-btn:active carried a stale translateY(-50%) that moved the button out from under the pointer between mousedown and mouseup. Scale-only :active now; buttons also re-center on resize/image load and get type="button". Script tag is versioned (?v=2) so cached copies pick up the fix. - Dark-section contrast: stat numbers, section labels, pipeline arrows, formulation equations, carousel bars/pills, pip-install code, and footer hovers used slate #3d4248 on #1a1a1a; recolored to light graphite tones. Secondary buttons on ink (CTA "Read the Paper") get light text/border. - New Showcase section: README-style 16-tile gallery, each tile backed by its runnable example path and linked to the source on GitHub; lazy-loaded GIFs; nav link added. Replaces the four GIF slides that were buried in the benchmark carousel. - Removed the "CBFKit vs. other toolboxes" comparison slide and all decorative emoji icons (architecture pipeline, MPPI cards, systems grid); tutorials use mono 01-06 labels instead. - Equation block restyled as a flat-ink card with clause-level wrapping. - Polish: dead particle-canvas JS and hero-gradient CSS removed, inline SVG favicon (fixes console 404), prefers-reduced-motion support, formulations grid balanced 2x2, gallery tiles locked to 4:3.
1 parent 6c537fd commit 50c90d3

17 files changed

Lines changed: 2689 additions & 81 deletions

File tree

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,31 @@ jobs:
6868
CBFKIT_TEST_MODE: "1"
6969
run: |
7070
pytest -m "slow" tests
71+
72+
core-import:
73+
name: Slim-core import (no extras)
74+
runs-on: ubuntu-latest
75+
env:
76+
JAX_PLATFORM_NAME: cpu
77+
steps:
78+
- uses: actions/checkout@v6
79+
- name: Set up Python
80+
uses: actions/setup-python@v6
81+
with:
82+
python-version: "3.11"
83+
- name: Install core only (no extras)
84+
run: pip install .
85+
- name: Assert the default import surface stays lean
86+
run: |
87+
python - <<'PY'
88+
import sys
89+
import cbfkit
90+
from cbfkit.controllers.cbf_clf import vanilla_cbf_clf_qp_controller
91+
from cbfkit.optimization.quadratic_program import get_solver
92+
get_solver("fast")
93+
get_solver("jaxopt")
94+
heavy = {"casadi", "cvxopt", "kvxopt", "plotly"}
95+
leaked = sorted(m for m in sys.modules if m.split(".")[0] in heavy)
96+
assert not leaked, f"Heavy optional deps leaked into the default import: {leaked}"
97+
print("OK: default import surface is lean (no casadi/cvxopt/plotly).")
98+
PY

.github/workflows/pages.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Deploy blog to GitHub Pages
2+
3+
# Serves blog/ (the "CBFKit Reborn" landing page) at the project's Pages URL.
4+
# One-time setup: repo Settings -> Pages -> Build and deployment -> Source: "GitHub Actions".
5+
# All media in blog/index.html is referenced by absolute raw.githubusercontent URLs,
6+
# so the deployed folder stays free of large binaries.
7+
8+
on:
9+
push:
10+
branches: [main]
11+
paths:
12+
- "blog/**"
13+
- ".github/workflows/pages.yml"
14+
workflow_dispatch:
15+
16+
permissions:
17+
contents: read
18+
pages: write
19+
id-token: write
20+
21+
concurrency:
22+
group: pages
23+
cancel-in-progress: false
24+
25+
jobs:
26+
deploy:
27+
environment:
28+
name: github-pages
29+
url: ${{ steps.deployment.outputs.page_url }}
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v6
33+
- name: Configure Pages
34+
uses: actions/configure-pages@v5
35+
- name: Upload blog as Pages artifact
36+
uses: actions/upload-pages-artifact@v3
37+
with:
38+
path: blog
39+
- name: Deploy to GitHub Pages
40+
id: deployment
41+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,6 @@ jax_cache/
228228

229229
# Generated results
230230
results/
231+
232+
# Local-only launch notes (not published to the repo)
233+
docs/launch/

README.md

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
# CBFKit: A Control Barrier Function Toolbox for Robotics Applications
22

3+
[![Python 3.10–3.12](https://img.shields.io/badge/python-3.10--3.12-blue.svg)](https://github.com/bardhh/cbfkit)
4+
[![CI](https://github.com/bardhh/cbfkit/actions/workflows/ci.yml/badge.svg)](https://github.com/bardhh/cbfkit/actions/workflows/ci.yml)
5+
[![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD--3--Clause-blue.svg)](https://github.com/bardhh/cbfkit/blob/main/LICENSE)
6+
[![arXiv](https://img.shields.io/badge/arXiv-2404.07158-b31b1b.svg)](https://arxiv.org/abs/2404.07158)
7+
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/bardhh/cbfkit/blob/main/examples/gymnasium/safe_single_integrator.ipynb)
8+
39
CBFKit is a Python/ROS2 toolbox for safe planning and control using Control Barrier Functions (CBFs). Built on JAX for automatic differentiation and JIT compilation, it provides formal safety guarantees for robotic systems operating in deterministic, disturbed, and stochastic environments. It also includes an efficient JAX implementation of Model Predictive Path Integral (MPPI) control with reach-avoid specifications.
410

511
<p align="center">
6-
<img src="media/showcase/ped_mppi.gif" width="48%" alt="MPPI navigation among pedestrians">
7-
<img src="media/showcase/pedestrian_head_on.gif" width="48%" alt="CBF safety with head-on encounter">
12+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/ped_mppi.gif" width="48%" alt="MPPI navigation among pedestrians">
13+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/pedestrian_head_on.gif" width="48%" alt="CBF safety with head-on encounter">
814
</p>
915
<p align="center">
10-
<img src="media/showcase/mppi_rollouts.gif" width="48%" alt="MPPI trajectory sampling">
11-
<img src="media/showcase/ekf_estimation.gif" width="48%" alt="EKF state estimation">
16+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/mppi_rollouts.gif" width="48%" alt="MPPI trajectory sampling">
17+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/ekf_estimation.gif" width="48%" alt="EKF state estimation">
1218
</p>
1319
<p align="center">
1420
<em>MPPI among pedestrians &nbsp;|&nbsp; CBF head-on safety</em><br>
@@ -19,11 +25,19 @@ Supported dynamics: $\dot{x} = f(x) + g(x)u$, $\dot{x} = f(x) + g(x)u + Mw$, $dx
1925

2026
## Quick Start
2127

22-
Requires **Python 3.10--3.12**.
28+
Requires **Python 3.10--3.12**. Install directly from GitHub:
29+
30+
```bash
31+
pip install "cbfkit @ git+https://github.com/bardhh/cbfkit.git"
32+
```
33+
34+
Need optional features? Add extras, e.g. `pip install "cbfkit[gymnasium] @ git+https://github.com/bardhh/cbfkit.git"` (also available: `neural`, `casadi`, `cvxopt`, `plotly`, `manim`, or `all`).
35+
36+
Or clone for development (editable install with all dev tools + extras):
2337

2438
```bash
2539
git clone https://github.com/bardhh/cbfkit.git && cd cbfkit
26-
pip install -e .
40+
pip install -e ".[dev]"
2741
python examples/unicycle/reach_goal/unicycle_reach_avoid_cbf.py
2842
```
2943

@@ -87,7 +101,7 @@ print(f"Final position: ({results.states[-1, 0]:.2f}, {results.states[-1, 1]:.2f
87101

88102
Drop-in CBF safety filter for any continuous Gymnasium environment. Wraps the env so every action from your RL policy gets safety-projected by a CBF-QP before reaching the simulator — works with PPO, SAC, or any off-the-shelf algorithm, no policy retraining required.
89103

90-
<p align="center"><img src="media/showcase/safe_rl_gymnasium.gif" width="85%" alt="Safe RL: naive vs CBF-filtered policy"></p>
104+
<p align="center"><img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/safe_rl_gymnasium.gif" width="85%" alt="Safe RL: naive vs CBF-filtered policy"></p>
91105

92106
```bash
93107
python examples/gymnasium/safe_single_integrator.py
@@ -97,7 +111,7 @@ python examples/gymnasium/safe_single_integrator.py
97111

98112
Skip the math: learn the barrier function from samples. A small neural network learns h(x) from labeled safe/unsafe states, then plugs straight into CBFKit's CBF-QP controller. Useful when obstacles are hard to describe analytically — point clouds, learned occupancy maps, scanned environments.
99113

100-
<p align="center"><img src="media/showcase/neural_cbf.gif" width="65%" alt="Neural CBF: agent avoiding a learned obstacle"></p>
114+
<p align="center"><img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/neural_cbf.gif" width="65%" alt="Neural CBF: agent avoiding a learned obstacle"></p>
101115

102116
```bash
103117
python examples/neural_cbf/neural_cbf_obstacle_avoidance.py
@@ -115,7 +129,7 @@ Measured on random PD QPs (50 reps after warmup) on the sizes typical of CBF-CLF
115129
| 4×10 | **785×** | 73× |
116130
| 8×20 | **696×** | 64× |
117131

118-
<p align="center"><img src="media/showcase/fast_qp_benchmark.png" width="75%" alt="QP solver wall-time comparison"></p>
132+
<p align="center"><img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/fast_qp_benchmark.png" width="75%" alt="QP solver wall-time comparison"></p>
119133

120134
```bash
121135
python benchmarks/qp_solver_comparison.py
@@ -125,7 +139,7 @@ python benchmarks/qp_solver_comparison.py
125139

126140
Cinematic 3D simulation rendering with Manim. Multi-robot reach-avoid in 3D, rendered via CBFKit's Manim backend. Shows the visualization stack scales from quick matplotlib plots to publication-quality 3D animations.
127141

128-
<p align="center"><img src="media/showcase/multi_robot_3d.gif" width="70%" alt="Manim 3D render of multi-robot reach-avoid"></p>
142+
<p align="center"><img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/multi_robot_3d.gif" width="70%" alt="Manim 3D render of multi-robot reach-avoid"></p>
129143

130144
```bash
131145
python tutorials/multi_robot_3d_reachavoid.py
@@ -136,64 +150,64 @@ python tutorials/multi_robot_3d_reachavoid.py
136150
<table>
137151
<tr>
138152
<td align="center" width="33%">
139-
<img src="media/showcase/risk_aware_cvar.gif" width="100%" alt="Ellipsoidal-obstacle CBF"><br>
140-
<sub><b>Ellipsoidal-obstacle CBF</b> <a href="examples/unicycle/reach_goal/ellipsoidal_obstacle_cbf.py" title="Source: examples/unicycle/reach_goal/ellipsoidal_obstacle_cbf.py">🔗</a><br>Unicycle reach-goal with linear class-K</sub>
153+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/risk_aware_cvar.gif" width="100%" alt="Ellipsoidal-obstacle CBF"><br>
154+
<sub><b>Ellipsoidal-obstacle CBF</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/unicycle/reach_goal/ellipsoidal_obstacle_cbf.py" title="Source: examples/unicycle/reach_goal/ellipsoidal_obstacle_cbf.py">🔗</a><br>Unicycle reach-goal with linear class-K</sub>
141155
</td>
142156
<td align="center" width="33%">
143-
<img src="media/showcase/stochastic_cbf.gif" width="100%" alt="Stochastic CBF"><br>
144-
<sub><b>Stochastic CBF (SDE)</b> <a href="examples/unicycle/reach_goal/stochastic_cbf.py" title="Source: examples/unicycle/reach_goal/stochastic_cbf.py">🔗</a><br>Safety under Brownian disturbance</sub>
157+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/stochastic_cbf.gif" width="100%" alt="Stochastic CBF"><br>
158+
<sub><b>Stochastic CBF (SDE)</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/unicycle/reach_goal/stochastic_cbf.py" title="Source: examples/unicycle/reach_goal/stochastic_cbf.py">🔗</a><br>Safety under Brownian disturbance</sub>
145159
</td>
146160
<td align="center" width="33%">
147-
<img src="media/showcase/robust_cbf.gif" width="100%" alt="Robust CBF"><br>
148-
<sub><b>Robust CBF</b> <a href="examples/unicycle/reach_goal/robust_cbf.py" title="Source: examples/unicycle/reach_goal/robust_cbf.py">🔗</a><br>Worst-case bounded disturbance</sub>
161+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/robust_cbf.gif" width="100%" alt="Robust CBF"><br>
162+
<sub><b>Robust CBF</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/unicycle/reach_goal/robust_cbf.py" title="Source: examples/unicycle/reach_goal/robust_cbf.py">🔗</a><br>Worst-case bounded disturbance</sub>
149163
</td>
150164
</tr>
151165
<tr>
152166
<td align="center">
153-
<img src="media/showcase/mppi_rollouts.gif" width="100%" alt="MPPI rollouts"><br>
154-
<sub><b>MPPI rollout sampling</b> <a href="examples/unicycle/reach_goal/mppi_cbf.py" title="Source: examples/unicycle/reach_goal/mppi_cbf.py">🔗</a><br>Sampling-based planning</sub>
167+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/mppi_rollouts.gif" width="100%" alt="MPPI rollouts"><br>
168+
<sub><b>MPPI rollout sampling</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/unicycle/reach_goal/mppi_cbf.py" title="Source: examples/unicycle/reach_goal/mppi_cbf.py">🔗</a><br>Sampling-based planning</sub>
155169
</td>
156170
<td align="center">
157-
<img src="media/showcase/mppi_stl.gif" width="100%" alt="MPPI reach-avoid"><br>
158-
<sub><b>MPPI reach-avoid</b> <a href="examples/single_integrator/mppi_reach_avoid.py" title="Source: examples/single_integrator/mppi_reach_avoid.py">🔗</a><br>Sampling-based planning with goal + obstacle cost</sub>
171+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/mppi_stl.gif" width="100%" alt="MPPI reach-avoid"><br>
172+
<sub><b>MPPI reach-avoid</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/single_integrator/mppi_reach_avoid.py" title="Source: examples/single_integrator/mppi_reach_avoid.py">🔗</a><br>Sampling-based planning with goal + obstacle cost</sub>
159173
</td>
160174
<td align="center">
161-
<img src="media/showcase/multi_robot_2d.gif" width="100%" alt="Multi-robot 2D coordination"><br>
162-
<sub><b>Multi-robot 2D</b> <a href="examples/single_integrator/multi_robot_coordination.py" title="Source: examples/single_integrator/multi_robot_coordination.py">🔗</a><br>Coordination via shared CBFs</sub>
175+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/multi_robot_2d.gif" width="100%" alt="Multi-robot 2D coordination"><br>
176+
<sub><b>Multi-robot 2D</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/single_integrator/multi_robot_coordination.py" title="Source: examples/single_integrator/multi_robot_coordination.py">🔗</a><br>Coordination via shared CBFs</sub>
163177
</td>
164178
</tr>
165179
<tr>
166180
<td align="center">
167-
<img src="media/showcase/fixed_wing_3d.gif" width="100%" alt="Fixed-wing aerial 3D"><br>
168-
<sub><b>Fixed-wing aerial 3D</b> <a href="examples/fixed_wing/reach_drop_point/ekf.py" title="Source: examples/fixed_wing/reach_drop_point/ekf.py">🔗</a><br>UAV reach-drop-point in 3D</sub>
181+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/fixed_wing_3d.gif" width="100%" alt="Fixed-wing aerial 3D"><br>
182+
<sub><b>Fixed-wing aerial 3D</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/fixed_wing/reach_drop_point/ekf.py" title="Source: examples/fixed_wing/reach_drop_point/ekf.py">🔗</a><br>UAV reach-drop-point in 3D</sub>
169183
</td>
170184
<td align="center">
171-
<img src="media/showcase/pedestrian_head_on.gif" width="100%" alt="Pedestrian head-on"><br>
172-
<sub><b>Pedestrian head-on</b> <a href="examples/pedestrian/navigate_among_pedestrians/head_on.py" title="Source: examples/pedestrian/navigate_among_pedestrians/head_on.py">🔗</a><br>Dynamic-agent avoidance</sub>
185+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/pedestrian_head_on.gif" width="100%" alt="Pedestrian head-on"><br>
186+
<sub><b>Pedestrian head-on</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/pedestrian/navigate_among_pedestrians/head_on.py" title="Source: examples/pedestrian/navigate_among_pedestrians/head_on.py">🔗</a><br>Dynamic-agent avoidance</sub>
173187
</td>
174188
<td align="center">
175-
<img src="media/showcase/ekf_estimation.gif" width="100%" alt="EKF state estimation"><br>
176-
<sub><b>EKF state estimation</b> <a href="examples/unicycle/reach_goal/ekf.py" title="Source: examples/unicycle/reach_goal/ekf.py">🔗</a><br>Unicycle reach-goal under measurement noise</sub>
189+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/ekf_estimation.gif" width="100%" alt="EKF state estimation"><br>
190+
<sub><b>EKF state estimation</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/unicycle/reach_goal/ekf.py" title="Source: examples/unicycle/reach_goal/ekf.py">🔗</a><br>Unicycle reach-goal under measurement noise</sub>
177191
</td>
178192
</tr>
179193
<tr>
180194
<td align="center" width="33%">
181-
<img src="media/showcase/van_der_pol_clf.gif" width="100%" alt="Van der Pol CLF"><br>
182-
<sub><b>Van der Pol (CLF)</b> <a href="examples/van_der_pol/regulation/perfect_sensing.py" title="Source: examples/van_der_pol/regulation/perfect_sensing.py">🔗</a><br>Nonlinear regulation to the origin</sub>
195+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/van_der_pol_clf.gif" width="100%" alt="Van der Pol CLF"><br>
196+
<sub><b>Van der Pol (CLF)</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/van_der_pol/regulation/perfect_sensing.py" title="Source: examples/van_der_pol/regulation/perfect_sensing.py">🔗</a><br>Nonlinear regulation to the origin</sub>
183197
</td>
184198
<td align="center" width="33%">
185-
<img src="media/showcase/mpc_double_integrator.gif" width="100%" alt="Model Predictive Control"><br>
186-
<sub><b>Model Predictive Control</b> <a href="examples/double_integrator/mpc_tracking.py" title="Source: examples/double_integrator/mpc_tracking.py">🔗</a><br>Receding-horizon LTI tracking</sub>
199+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/mpc_double_integrator.gif" width="100%" alt="Model Predictive Control"><br>
200+
<sub><b>Model Predictive Control</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/double_integrator/mpc_tracking.py" title="Source: examples/double_integrator/mpc_tracking.py">🔗</a><br>Receding-horizon LTI tracking</sub>
187201
</td>
188202
<td align="center" width="33%">
189-
<img src="media/showcase/quadrotor_6dof.gif" width="100%" alt="Quadrotor 6-DOF geometric tracking"><br>
190-
<sub><b>Quadrotor 6-DOF</b> <a href="examples/quadrotor_6dof/geometric_tracking.py" title="Source: examples/quadrotor_6dof/geometric_tracking.py">🔗</a><br>Geometric SE(3) tracking + altitude CBF</sub>
203+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/quadrotor_6dof.gif" width="100%" alt="Quadrotor 6-DOF geometric tracking"><br>
204+
<sub><b>Quadrotor 6-DOF</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/quadrotor_6dof/geometric_tracking.py" title="Source: examples/quadrotor_6dof/geometric_tracking.py">🔗</a><br>Geometric SE(3) tracking + altitude CBF</sub>
191205
</td>
192206
</tr>
193207
<tr>
194208
<td align="center" colspan="3">
195-
<img src="media/showcase/monte_carlo_safety.gif" width="45%" alt="Monte Carlo safety verification"><br>
196-
<sub><b>Monte Carlo safety verification</b> <a href="examples/single_integrator/monte_carlo_safety.py" title="Source: examples/single_integrator/monte_carlo_safety.py">🔗</a><br>200 stochastic CBF rollouts (<code>jax.vmap</code>), live empirical risk</sub>
209+
<img src="https://raw.githubusercontent.com/bardhh/cbfkit/main/media/showcase/monte_carlo_safety.gif" width="45%" alt="Monte Carlo safety verification"><br>
210+
<sub><b>Monte Carlo safety verification</b> <a href="https://github.com/bardhh/cbfkit/blob/main/examples/single_integrator/monte_carlo_safety.py" title="Source: examples/single_integrator/monte_carlo_safety.py">🔗</a><br>200 stochastic CBF rollouts (<code>jax.vmap</code>), live empirical risk</sub>
197211
</td>
198212
</tr>
199213
</table>

0 commit comments

Comments
 (0)