DAM — Detachable Action Monitor
See where your policy breaks — before your hardware does.
Install · Quick Start · Isaac Sim · Architecture · Docs
https://github.com/user-attachments/assets/a10711ea-a419-4aee-ba06-de1e2d437d49
Install
pip install robot-dam # includes torch, lerobot, mcap, dam-rs (Rust extension)
pip install robot-dam[isaac] # + Isaac Sim 6.0 adapter
pip install robot-dam[full] # + ROS2, REST API, QP solver, everything
Or from source:
git clone https://github.com/ez945y/DAM.git && cd DAM
make setup
What It Does
ML policies always output the next action — they have no idea when something is unsafe. DAM intercepts every action and evaluates it through a layered guard pipeline before it reaches hardware. Each action is either passed, clamped (adjusted to stay safe), or rejected.
The goal isn't to hide failures. It's to make them visible and easier to understand.
Important: DAM is experimental research software, not a certified safety system.
Quick Start
git clone https://github.com/ez945y/DAM.git
cd DAM
make setup # Python venv + Rust extension + npm install (~3 min)
make run # Backend :8080 + Console :3000
Open http://localhost:3000 — the demo Stackfile replays a dataset through the full guard pipeline without hardware.
CLI
.venv/bin/dam doctor # check environment
.venv/bin/dam callbacks # list 18 built-in safety checks
.venv/bin/dam validate examples/stackfiles/*.yaml # schema-check Stackfiles
.venv/bin/dam run examples/stackfiles/demo.yaml --cycles 200 --task demo
Make Targets
| Command | What it does |
|---|---|
make setup |
First-time install (venv + Rust + npm) |
make run |
Backend + pre-built frontend |
make dev |
Backend + frontend with hot-reload |
make test |
Full test suite (688+ Python tests + 109 frontend tests) |
make record |
Safe IL recording with DAM guards |
make callbacks |
List all 18 built-in safety checks |
make validate |
Validate example Stackfiles |
Safe Recording for Imitation Learning
During data collection, DAM smooths motions and catches bad data before it enters your dataset. Integrates with LeRobot — one file configures hardware, safety boundaries, and recording.
make record # reads examples/stackfiles/safety.yaml
make record ARGS="--dataset.num_episodes=20" # CLI args override YAML
Python API (3 levels)
import dam
# One input dict per cycle: "action" is the command to validate, every other
# key is an observation group. Returns the safe command in the action's form.
# Level 1: one-liner (notebooks)
safe_action = dam.guardrail({"joints": obs, "action": action}, stackfile="safety.yaml")
# Level 2: stateful guard (recording loops + Isaac Sim)
guard = dam.Guardrail("safety.yaml", task="record") # prints the obs/action contract
safe_action = guard({"joints": obs, "action": action}) # mirrors the action's type
# Level 3: lerobot pipeline (one line addition)
from dam import GuardrailProcessorStep
robot_action_processor.steps.insert(0, GuardrailProcessorStep("safety.yaml"))
The recorded dataset contains only safe actions — your policy trains on data that already respects physical constraints. See Safe Recording Guide for full details.
Isaac Sim Integration
DAM works as a drop-in safety filter for Isaac Sim 6.0+ control loops. Accepts and returns torch.Tensor on any device — no CPU↔GPU copies needed.
import dam
from dam.adapter.isaac import IsaacSafetyFilter
# Single env — IsaacSafetyFilter accepts torch.Tensor directly
filt = IsaacSafetyFilter("franka_safety.yaml", task="manipulation")
safe_action = filt(action_tensor, obs_tensor) # same device/dtype
# Multi-env (Isaac Lab) — vectorized filter
filt = IsaacSafetyFilter("franka_safety.yaml", task="manipulation", num_envs=4096)
safe_actions = filt(actions_batch, obs_batch) # (N, J) → (N, J)
# Auto-detect from ArticulationView
filt = IsaacSafetyFilter.from_articulation(franka_view, "franka_safety.yaml")
Bundled presets: so101_follower, franka_emika_panda. See examples/isaac_franka_demo.py for the full demo.
Architecture
Guard Layers
| Layer | What it checks | Example checks |
|---|---|---|
| L0 OOD Detection | Is the observation in-distribution? | Real-NVP / Memory Bank anomaly scoring |
| L1 Physical Kinematics | Can this move physically happen? | Joint limits, workspace bounds, velocity caps |
| L2 Task Execution | Does this make sense for the task? | Gripper sequence, progress enforcement |
| L3 Hardware Monitoring | Is the hardware healthy? | Temperature, current, voltage, heartbeat |
L0 and L1 run in parallel. The final decision is the most restrictive outcome across all active layers.
Stackfile Configuration
Everything is configured in a YAML Stackfile:
boundaries:
joint_position_limits:
layer: L1
type: single
nodes:
- callback: joint_position_limits
params:
upper: [1.8243, 1.7691, 1.8326, 1.8067, 3.0741, 1.7453]
lower: [-1.8243, -1.7691, -1.8326, -1.8067, -3.0741, 0.0]
Start from examples/stackfiles/minimal.yaml or see the Stackfile Walkthrough.
18 Built-in Safety Checks
Run dam callbacks to list them all:
- L0: OOD detector (Real-NVP, Memory Bank, Welford)
- L1: Joint position/velocity limits, workspace bounds, keep-out zones, orientation, geofence, Cartesian velocity, smoothness
- L2: Task gripper sequence enforcement
- L3: Temperature, current, voltage, force/torque, hardware watchdog, host health
Documentation
| Goal | Start here |
|---|---|
| Learn DAM step by step | Learn DAM |
| Read a Stackfile | Stackfile Walkthrough |
| Common config edits | Common Stackfile Edits |
| Understand the console | Console Walkthrough |
| Prepare for hardware | Hardware Readiness |
| Troubleshooting | Troubleshooting |
Contributing
See Contributing. We welcome safety testing, hardware adapters, performance optimization, and example Stackfiles.
Metadata
Release files for robot-dam 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| robot_dam-0.7.0.tar.gz | 1.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| robot_dam-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.7 MB
Release files / robot_dam-0.7.0.tar.gz
| Download URL | robot_dam-0.7.0.tar.gz |
|---|---|
| Size | 1.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e40cc6e70269d5b04aaea06310d102175f4990292c80b4f22d468369c469e6ff
|
|
BLAKE2b-256 checksum How to use checksums |
6e986e5b1badd281a7034ae063739082372c2ebb261af409c64777960629f9fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.
Transparency logRelease files / robot_dam-0.7.0-py3-none-any.whl
| Download URL | robot_dam-0.7.0-py3-none-any.whl |
|---|---|
| Size | 338.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
954139edf0d1f4938a79d3e5a394ba512d602bf0f3fb9c19a6575598a838c307
|
|
BLAKE2b-256 checksum How to use checksums |
5b18e83d1e3806c8769aafe804b1325b519d50433829c3607b2bedd07c246eb1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.
Transparency log