Task-generation pipelines¶
All pipelines live in maniguard/task_generation/ and share a BasePipeline
runtime contract from pipeline_common.py. Each pipeline auto-discovers a
support surface in the given scene, generates BDDL + ltl_safety.json at
runtime, spawns objects, places the robot, runs gate checks, and executes an
LTL-monitored rollout.
The cross-cutting Data flow page describes the four-stage architecture every pipeline shares: offline JSON pool generation (raycast scans + admission filters) → object selection → scene + surface selection → placement.
ManiGuard-Bench families¶
The released ManiGuard-Bench is these 6 families (200 base tasks). Each page states the task goal + safety and how the family's scenes are generated:
| Family | Tasks | One-liner |
|---|---|---|
| Clutter pickup | 55 | Pick a named target out of a cluttered pack into the goal region (+ liquid subset) |
| Cabinet pickup | 35 | Open a drawer, place the target inside, close it |
| Lid transport | 30 | Put the lid on before lifting the container to the goal |
| Stack retrieve | 28 | Pull the bottom object out from under a stack without toppling it |
| Jar transport | 26 | Close a hinged jar before carrying it to the goal |
| Dusty transfer | 26 | Wipe a dusty pot clean, then transfer food into it with the tool |
Generation infrastructure¶
Shared machinery every family builds on:
- Data flow — the four-stage architecture (offline pools → selection → surface → placement).
- Add a custom pipeline — author a new
BasePipelinesubclass. - Empty-scene runner — synthesize a surface on a bare floor (used by the empty-scene families).
- Food transfer (base) — the transfer base that dusty transfer extends.
Additional families¶
Other families the pipeline can generate but that are not
in the shipped bench (wet_transport, empty_invert).
Multi-scene benchmark¶
run_benchmark.py orchestrates a pipeline across multiple scenes, one
subprocess per scene, with per-scene timeout and resume logic. The
subprocess-per-scene model intentionally avoids long-lived Isaac Sim /
renderer state and makes failed scenes easier to isolate and rerun.
conda activate behavior
python -m maniguard.task_generation.run_benchmark \
--pipeline table \
--scenes hall_conference_large \
--episodes 1 --steps 300 --density medium --timeout 1800
Pipeline choices for --pipeline (keys of _PIPELINE_SCRIPTS): table
(clutter), transfer, dusty_transfer, stack (+ stack_same / stack_flat
/ stack_receptacle), lid_transport, liquid_transport, wet_transport,
jar_transport, cabinet_pickup. The empty-scene families (cabinet_pickup,
jar_transport) are usually run via their own CLI with --task-id rather than
the per-scene benchmark loop.
Dry-run (BDDL + LTL only, no simulator)¶
python -m maniguard.task_generation.clutter_scene_pipeline \
--scene-model Benevolence_1_int --dry-run
Artifact contract¶
A successful scene run is expected to produce, at minimum:
| File | Purpose |
|---|---|
diagnostics.jsonl |
Outcome signals: gate results, LTL status, density, active-object summary |
scene_ep1.json |
Frozen scene snapshot for replay, rerendering, later evaluation |
stdout.log |
Runtime trace for debugging |
rollout_ep1.mp4 |
Canonical human-reviewable video |
Gate vs LTL — what's the difference?¶
Two validation layers run sequentially:
- Gate checks (pre-rollout, structural): "Is this scene structurally valid
enough to start?" Robot/target poses are finite, robot base near floor plane,
selected mount pose collision-free, target inside reach band, plus per-pipeline
extras (e.g. pack integrity for clutter). With
--strict-gate, a gate failure aborts the episode. - LTL safety rollout (during execution, semantic): "Does the scene remain
safe and semantically intact over time?"
combined_ltlfromltl_safety.jsonis evaluated step by step byTaskLTLMonitor.