From f85759621d59d864eda50aa71779ae9a6b91fa23 Mon Sep 17 00:00:00 2001 From: Yichao Liang Date: Thu, 1 Oct 2026 06:17:09 -0400 Subject: [PATCH 1/2] Show solve GIFs from the RoboDisco site in the envs README The Environments table previewed each environment with a random-action GIF. Each preview is now the solve GIF the RoboDisco site shows, linked to that environment's page there, and the legend says what it shows. --- predicators/envs/README.md | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/predicators/envs/README.md b/predicators/envs/README.md index d461aec15f..e2840bd283 100644 --- a/predicators/envs/README.md +++ b/predicators/envs/README.md @@ -71,27 +71,28 @@ The Gymnasium wrapper exposes: ## Environments Status legend: -- **Tasks** — the env's task generator produces multiple init states and goals (✅) versus only a single fixed configuration (❌). -- **Skills** — `predicators/ground_truth_models//options.py` exposes a non-empty set of primitive options (✅) versus an empty set or no factory (❌). -- **Demos** — `python predicators/main.py --env --approach oracle --seed 0 --num_train_tasks 1 --num_test_tasks 1 --timeout 60` solves the test task end-to-end (✅) versus failing during planning, execution, or sampler grounding (❌). +- **Preview** - one task being solved, by planning with ground-truth models or by a scripted skill sequence, from the [RoboDisco site](https://yichao-liang.github.io/robodisco-site/); click it for the environment's page. +- **Tasks** - the env's task generator produces multiple init states and goals (✅) versus only a single fixed configuration (❌). +- **Skills** - `predicators/ground_truth_models//options.py` exposes a non-empty set of primitive options (✅) versus an empty set or no factory (❌). +- **Demos** - `python predicators/main.py --env --approach oracle --seed 0 --num_train_tasks 1 --num_test_tasks 1 --timeout 60` solves the test task end-to-end (✅) versus failing during planning, execution, or sampler grounding (❌). | Environment | Preview | Description | Tasks | Skills | Demos | |---|---|---|:---:|:---:|:---:| -| `robodisco/Ants-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_ants.gif) | Place food items near ants on a tabletop | ❌ | ✅ | ❌ | -| `robodisco/Balance-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_balance.gif) | Balance blocks on a beam by pressing buttons | ✅ | ✅ | ❌ | -| `robodisco/Barrier-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_barrier.gif) | Move blocks past barriers to target locations | ❌ | ❌ | ❌ | -| `robodisco/Blocks-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_blocks.gif) | Stack and arrange blocks on a table | ✅ | ✅ | ✅ | -| `robodisco/Boil-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_boil.gif) | Fill and boil water using a jug, faucet, and burner | ✅ | ✅ | ✅ | -| `robodisco/Circuit-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_circuit.gif) | Assemble circuit components (batteries, wires, switch) | ❌ | ✅ | ✅ | -| `robodisco/Coffee-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_coffee.gif) | Operate a coffee machine: plug in, brew, pour, serve | ✅ | ✅ | ❌ | -| `robodisco/Cover-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_cover.gif) | Place blocks to cover target regions | ✅ | ✅ | ✅ | -| `robodisco/Domino-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_domino.gif) | Set up domino chains with fans, balls, and ramps | ✅ | ✅ | ✅ | -| `robodisco/Fan-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_fan.gif) | Use fans to blow lightweight objects to goals | ✅ | ✅ | ✅ | -| `robodisco/Float-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_float.gif) | Float light blocks by filling a container with water | ❌ | ✅ | ✅ | -| `robodisco/Grow-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_grow.gif) | Grow plants by watering them | ✅ | ✅ | ✅ | -| `robodisco/Laser-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_laser.gif) | Align lasers and mirrors to hit targets | ❌ | ✅ | ❌ | -| `robodisco/MagicBin-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_magic_bin.gif) | Sort objects into magic bins that transform them | ❌ | ❌ | ❌ | -| `robodisco/Switch-v0` | ![](../../docs/envs/assets/random_action_gifs/pybullet_switch.gif) | Toggle switches to open doors and move objects | ❌ | ❌ | ❌ | +| `robodisco/Ants-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/ants.gif)](https://yichao-liang.github.io/robodisco-site/envs/ants.html) | Place food items near ants on a tabletop | ❌ | ✅ | ❌ | +| `robodisco/Balance-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/balance.gif)](https://yichao-liang.github.io/robodisco-site/envs/balance.html) | Balance blocks on a beam by pressing buttons | ✅ | ✅ | ❌ | +| `robodisco/Barrier-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/barrier.gif)](https://yichao-liang.github.io/robodisco-site/envs/barrier.html) | Move blocks past barriers to target locations | ❌ | ❌ | ❌ | +| `robodisco/Blocks-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/blocks.gif)](https://yichao-liang.github.io/robodisco-site/envs/blocks.html) | Stack and arrange blocks on a table | ✅ | ✅ | ✅ | +| `robodisco/Boil-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/boil.gif)](https://yichao-liang.github.io/robodisco-site/envs/boil.html) | Fill and boil water using a jug, faucet, and burner | ✅ | ✅ | ✅ | +| `robodisco/Circuit-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/circuit.gif)](https://yichao-liang.github.io/robodisco-site/envs/circuit.html) | Assemble circuit components (batteries, wires, switch) | ❌ | ✅ | ✅ | +| `robodisco/Coffee-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/coffee.gif)](https://yichao-liang.github.io/robodisco-site/envs/coffee.html) | Operate a coffee machine: plug in, brew, pour, serve | ✅ | ✅ | ❌ | +| `robodisco/Cover-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/cover.gif)](https://yichao-liang.github.io/robodisco-site/envs/cover.html) | Place blocks to cover target regions | ✅ | ✅ | ✅ | +| `robodisco/Domino-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/domino.gif)](https://yichao-liang.github.io/robodisco-site/envs/domino.html) | Set up domino chains with fans, balls, and ramps | ✅ | ✅ | ✅ | +| `robodisco/Fan-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/fan.gif)](https://yichao-liang.github.io/robodisco-site/envs/fan.html) | Use fans to blow lightweight objects to goals | ✅ | ✅ | ✅ | +| `robodisco/Float-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/float.gif)](https://yichao-liang.github.io/robodisco-site/envs/float.html) | Float light blocks by filling a container with water | ❌ | ✅ | ✅ | +| `robodisco/Grow-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/grow.gif)](https://yichao-liang.github.io/robodisco-site/envs/grow.html) | Grow plants by watering them | ✅ | ✅ | ✅ | +| `robodisco/Laser-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/laser.gif)](https://yichao-liang.github.io/robodisco-site/envs/laser.html) | Align lasers and mirrors to hit targets | ❌ | ✅ | ❌ | +| `robodisco/MagicBin-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/magic-bin.gif)](https://yichao-liang.github.io/robodisco-site/envs/magic-bin.html) | Sort objects into magic bins that transform them | ❌ | ❌ | ❌ | +| `robodisco/Switch-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/switch.gif)](https://yichao-liang.github.io/robodisco-site/envs/switch.html) | Toggle switches to open doors and move objects | ❌ | ❌ | ❌ | The Demos column was verified by running the oracle command above on every env. Failing envs typically need additional `CFG` overrides or From 381e831c567511da77f4550980ff4472961e6e4b Mon Sep 17 00:00:00 2001 From: Yichao Liang Date: Thu, 1 Oct 2026 06:54:39 -0400 Subject: [PATCH 2/2] Bring the envs README up to date and register all 22 environments Re-measured every claim in predicators/envs/README.md on October 1: - The Gymnasium registry gains the seven RoboDisco environments it lacked (Balloons, Bridge, BusyBoard, Crane, IceRink, Launcher, Magnets); all 22 build, reset, step and render through the wrapper. - The table lists all 22 with the site's descriptions; Tasks and Skills follow the measured task variation and skill libraries, and the Oracle column (was Demos) names the approach that solves the test task in the default configuration, with the reasons for the rest. - The stale note that Circuit, Cover, Laser and Switch fail to build is replaced by the actual failure: Circuit, Laser and Switch fail when another env was built earlier in the same process. - The Standalone API example wraps its actions in Action, so it runs. - New: task selection and seeding through reset(), the observation layout, the five benchmark domains, and the two skill libraries. The smoke script and the notebook count 22 environments, and the smoke script no longer blames missing CFG for the same-process failures. --- notebooks/getting_started.ipynb | 2 +- predicators/envs/README.md | 129 ++++++++++++++------------ predicators/envs/gymnasium_wrapper.py | 15 ++- scripts/robodisco_getting_started.py | 6 +- tests/envs/test_robodisco.py | 12 +-- 5 files changed, 96 insertions(+), 68 deletions(-) diff --git a/notebooks/getting_started.ipynb b/notebooks/getting_started.ipynb index 46139eef4a..52042db59b 100644 --- a/notebooks/getting_started.ipynb +++ b/notebooks/getting_started.ipynb @@ -58,7 +58,7 @@ "source": [ "## Discovering Available Environments\n", "\n", - "RoboDisco provides 15 PyBullet-based robotic manipulation environments.\n", + "RoboDisco provides 22 PyBullet-based robotic manipulation environments.\n", "Let's register them all and see what's available." ] }, diff --git a/predicators/envs/README.md b/predicators/envs/README.md index e2840bd283..c9ded6402e 100644 --- a/predicators/envs/README.md +++ b/predicators/envs/README.md @@ -1,15 +1,13 @@ # PyBullet Environments -**RoboDisco** (Robot Model Discovery Benchmark) — a robotic -world-model learning and causal-discovery suite. The envs ship as part -of the [predicators](../../README.md) repository and are exposed -through a standard [Gymnasium](https://gymnasium.farama.org/) API. +**RoboDisco** (Robot Model Discovery Benchmark) is a suite of 22 environments for robotic world-model learning and causal discovery. +The envs ship as part of the [predicators](../../README.md) repository and are exposed through a standard [Gymnasium](https://gymnasium.farama.org/) API. 🌐 **Project page:** -Each environment features a Fetch or Panda robot interacting with objects -on a tabletop. The same envs are used by predicators' planning research -code and can be consumed independently of the planner. +Each environment features a Fetch or Panda robot interacting with objects on a tabletop. +Five of them (Balloons, Boil, Bridge, Domino and Fan) are the benchmark domains of the EMPIRIC experiments; their benchmark settings live in [`scripts/configs/empiric/envs.yaml`](../../scripts/configs/empiric/envs.yaml). +The same envs are used by predicators' planning research code and can be consumed independently of the planner. ## Installation @@ -19,9 +17,8 @@ From the repo root: pip install -e . ``` -This installs the agent solvers and the RoboDisco envs together. The -package is slightly heavy because it bundles both — a lighter -envs-only install is future work. +This installs the agent solvers and the RoboDisco envs together. +The package is slightly heavy because it bundles both; a lighter envs-only install is future work. ## Quick Start (Gymnasium API) @@ -49,65 +46,83 @@ env.close() The Gymnasium wrapper exposes: -- `obs`: a 1-D `float32` numpy array of object features (PyBullet body ids - and other `sim_features` are excluded). -- `action_space`: the underlying robot's joint action space, as a - `gymnasium.spaces.Box`. +- `obs`: a 1-D `float32` numpy array of object features (PyBullet body ids and other `sim_features` are excluded). + Its layout comes from the objects of the first training task, so objects that only appear in other tasks (the BusyBoard and Laser test tasks add some) are missing from `obs`; read them from `info["state"]`. +- `action_space`: the underlying robot's joint action space, as a `gymnasium.spaces.Box`. - `reward`: `1.0` when all goal predicates are satisfied, `0.0` otherwise. - `terminated`: `True` when the goal is reached. - `truncated`: `True` when the episode hits the 500-step limit. -- `info["state"]`: the full object-centric `predicators.structs.State` - for the current step (predicates, types, sim state). +- `info["state"]`: the full object-centric `predicators.structs.State` for the current step (predicates, types, sim state). - `info["goal_reached"]`: shortcut for `env.goal_reached()`. +- `env.reset(options={"train_or_test": "test", "task_idx": 0})` selects the task to play (training task 0 by default), and `env.reset(seed=s)` reseeds the environment. ## Walkthroughs -- **Notebook:** [`notebooks/getting_started.ipynb`](../../notebooks/getting_started.ipynb) - — interactive walkthrough with rendering. -- **Smoke script:** [`scripts/robodisco_getting_started.py`](../../scripts/robodisco_getting_started.py) - — non-interactive smoke test that mirrors the notebook and resets every - env to verify installation health. +- **Notebook:** [`notebooks/getting_started.ipynb`](../../notebooks/getting_started.ipynb), an interactive walkthrough with rendering. +- **Smoke script:** [`scripts/robodisco_getting_started.py`](../../scripts/robodisco_getting_started.py), a non-interactive smoke test that mirrors the notebook and resets every env to verify installation health. ## Environments Status legend: - **Preview** - one task being solved, by planning with ground-truth models or by a scripted skill sequence, from the [RoboDisco site](https://yichao-liang.github.io/robodisco-site/); click it for the environment's page. -- **Tasks** - the env's task generator produces multiple init states and goals (✅) versus only a single fixed configuration (❌). -- **Skills** - `predicators/ground_truth_models//options.py` exposes a non-empty set of primitive options (✅) versus an empty set or no factory (❌). -- **Demos** - `python predicators/main.py --env --approach oracle --seed 0 --num_train_tasks 1 --num_test_tasks 1 --timeout 60` solves the test task end-to-end (✅) versus failing during planning, execution, or sampler grounding (❌). +- **Tasks** - the task generator varies the initial state across tasks (✅) or starts every task from one layout (❌). +- **Skills** - `predicators/ground_truth_models//options.py` builds a non-empty skill library (✅) or none (❌); see [Skill libraries](#skill-libraries). +- **Oracle** - the approach that solves the test task with `python predicators/main.py --env --approach --seed 0 --num_train_tasks 1 --num_test_tasks 1 --timeout 60` in the default configuration: `oracle` (bilevel planning with ground-truth operators and samplers) or `oracle_process_planning` (planning with ground-truth process models); ❌ when neither does. +- Names in **bold** are the five benchmark domains. -| Environment | Preview | Description | Tasks | Skills | Demos | +| Environment | Preview | Description | Tasks | Skills | Oracle | |---|---|---|:---:|:---:|:---:| -| `robodisco/Ants-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/ants.gif)](https://yichao-liang.github.io/robodisco-site/envs/ants.html) | Place food items near ants on a tabletop | ❌ | ✅ | ❌ | -| `robodisco/Balance-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/balance.gif)](https://yichao-liang.github.io/robodisco-site/envs/balance.html) | Balance blocks on a beam by pressing buttons | ✅ | ✅ | ❌ | -| `robodisco/Barrier-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/barrier.gif)](https://yichao-liang.github.io/robodisco-site/envs/barrier.html) | Move blocks past barriers to target locations | ❌ | ❌ | ❌ | -| `robodisco/Blocks-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/blocks.gif)](https://yichao-liang.github.io/robodisco-site/envs/blocks.html) | Stack and arrange blocks on a table | ✅ | ✅ | ✅ | -| `robodisco/Boil-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/boil.gif)](https://yichao-liang.github.io/robodisco-site/envs/boil.html) | Fill and boil water using a jug, faucet, and burner | ✅ | ✅ | ✅ | -| `robodisco/Circuit-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/circuit.gif)](https://yichao-liang.github.io/robodisco-site/envs/circuit.html) | Assemble circuit components (batteries, wires, switch) | ❌ | ✅ | ✅ | -| `robodisco/Coffee-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/coffee.gif)](https://yichao-liang.github.io/robodisco-site/envs/coffee.html) | Operate a coffee machine: plug in, brew, pour, serve | ✅ | ✅ | ❌ | -| `robodisco/Cover-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/cover.gif)](https://yichao-liang.github.io/robodisco-site/envs/cover.html) | Place blocks to cover target regions | ✅ | ✅ | ✅ | -| `robodisco/Domino-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/domino.gif)](https://yichao-liang.github.io/robodisco-site/envs/domino.html) | Set up domino chains with fans, balls, and ramps | ✅ | ✅ | ✅ | -| `robodisco/Fan-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/fan.gif)](https://yichao-liang.github.io/robodisco-site/envs/fan.html) | Use fans to blow lightweight objects to goals | ✅ | ✅ | ✅ | -| `robodisco/Float-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/float.gif)](https://yichao-liang.github.io/robodisco-site/envs/float.html) | Float light blocks by filling a container with water | ❌ | ✅ | ✅ | -| `robodisco/Grow-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/grow.gif)](https://yichao-liang.github.io/robodisco-site/envs/grow.html) | Grow plants by watering them | ✅ | ✅ | ✅ | -| `robodisco/Laser-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/laser.gif)](https://yichao-liang.github.io/robodisco-site/envs/laser.html) | Align lasers and mirrors to hit targets | ❌ | ✅ | ❌ | -| `robodisco/MagicBin-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/magic-bin.gif)](https://yichao-liang.github.io/robodisco-site/envs/magic-bin.html) | Sort objects into magic bins that transform them | ❌ | ❌ | ❌ | -| `robodisco/Switch-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/switch.gif)](https://yichao-liang.github.io/robodisco-site/envs/switch.html) | Toggle switches to open doors and move objects | ❌ | ❌ | ❌ | - -The Demos column was verified by running the oracle command above on -every env. Failing envs typically need additional `CFG` overrides or -hit known issues (missing NSRTs, sampler-grounding errors, or -execution drift); they may still be useful as targets for skill or -NSRT learning research. A handful of envs (`Circuit`, `Cover`, `Laser`, -`Switch`) also currently fail to instantiate through the Gymnasium -wrapper with parser defaults — pass `cfg_overrides={...}` to -`robodisco.make(...)` or call `utils.update_config({...})` before -`make()` to supply the missing fields. +| `robodisco/Ants-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/ants.gif)](https://yichao-liang.github.io/robodisco-site/envs/ants.html) | Sort food by whether it attracts ants, stacking same-coloured items | ✅ | ✅ | `oracle` | +| `robodisco/Balance-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/balance.gif)](https://yichao-liang.github.io/robodisco-site/envs/balance.html) | Equalise two plates on a beam, then press the button | ✅ | ✅ | `oracle` | +| **`robodisco/Balloons-v0`** | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/balloons.gif)](https://yichao-liang.github.io/robodisco-site/envs/balloons.html) | Free clipped balloons so they lift a box to hang inside a target band | ✅ | ✅ | ❌ | +| `robodisco/Barrier-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/barrier.gif)](https://yichao-liang.github.io/robodisco-site/envs/barrier.html) | Raise and lower barriers with the switches that control them | ✅ | ❌ | ❌ | +| `robodisco/Blocks-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/blocks.gif)](https://yichao-liang.github.io/robodisco-site/envs/blocks.html) | Rearrange blocks into the requested towers | ✅ | ✅ | `oracle` | +| **`robodisco/Boil-v0`** | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/boil.gif)](https://yichao-liang.github.io/robodisco-site/envs/boil.html) | Fill jugs at a faucet and boil them on a burner without spilling | ✅ | ✅ | `oracle_process_planning`\* | +| **`robodisco/Bridge-v0`** | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/bridge.gif)](https://yichao-liang.github.io/robodisco-site/envs/bridge.html) | Glue identical blocks into an n-shaped bridge whose joints cure over time | ✅ | ✅ | `oracle_process_planning`\* | +| `robodisco/BusyBoard-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/busyboard.gif)](https://yichao-liang.github.io/robodisco-site/envs/busyboard.html) | Light the right lamps on a board of switches with hidden wiring | ✅ | ✅ | ❌ | +| `robodisco/Circuit-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/circuit.gif)](https://yichao-liang.github.io/robodisco-site/envs/circuit.html) | Wire a battery to a bulb and switch it on | ✅ | ✅ | `oracle` | +| `robodisco/Coffee-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/coffee.gif)](https://yichao-liang.github.io/robodisco-site/envs/coffee.html) | Brew a jug of coffee and pour it into every cup | ✅ | ✅ | ❌ | +| `robodisco/Cover-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/cover.gif)](https://yichao-liang.github.io/robodisco-site/envs/cover.html) | Place blocks so they cover target regions | ✅ | ✅ | `oracle` | +| `robodisco/Crane-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/crane.gif)](https://yichao-liang.github.io/robodisco-site/envs/crane.html) | Swing a hinged ram to knock a crate onto a landing pad | ✅ | ✅ | `oracle` | +| **`robodisco/Domino-v0`** | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/domino.gif)](https://yichao-liang.github.io/robodisco-site/envs/domino.html) | Place as few dominoes as possible so a pushed chain topples the target | ✅ | ✅ | ❌ | +| **`robodisco/Fan-v0`** | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/fan.gif)](https://yichao-liang.github.io/robodisco-site/envs/fan.html) | Switch banks of fans to blow a ball through a walled grid to a target | ✅ | ✅ | ❌ | +| `robodisco/Float-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/float.gif)](https://yichao-liang.github.io/robodisco-site/envs/float.html) | Raise the water level to lift a floating block within reach | ✅ | ✅ | ❌ | +| `robodisco/Grow-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/grow.gif)](https://yichao-liang.github.io/robodisco-site/envs/grow.html) | Grow plants by pouring from the jug of matching colour | ✅ | ✅ | `oracle_process_planning` | +| `robodisco/IceRink-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/icerink.gif)](https://yichao-liang.github.io/robodisco-site/envs/icerink.html) | Push sliding tiles onto matching targets across a low-friction rink | ✅ | ✅ | ❌ | +| `robodisco/Laser-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/laser.gif)](https://yichao-liang.github.io/robodisco-site/envs/laser.html) | Place mirrors to route a laser beam onto the targets | ✅ | ✅ | ❌ | +| `robodisco/Launcher-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/launcher.gif)](https://yichao-liang.github.io/robodisco-site/envs/launcher.html) | Cock a spring launcher to knock only the top block off a tower | ✅ | ✅ | `oracle` | +| `robodisco/MagicBin-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/magic-bin.gif)](https://yichao-liang.github.io/robodisco-site/envs/magic-bin.html) | Make blocks vanish by dropping them in a bin that a switch activates | ❌ | ❌ | ❌ | +| `robodisco/Magnets-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/magnets.gif)](https://yichao-liang.github.io/robodisco-site/envs/magnets.html) | Steer coloured pieces into slots with a magnetic wand | ✅ | ✅ | `oracle` | +| `robodisco/Switch-v0` | [![](https://yichao-liang.github.io/robodisco-site/assets/gifs/switch.gif)](https://yichao-liang.github.io/robodisco-site/envs/switch.html) | Set a light's colour with a power switch and a colour switch | ✅ | ❌ | ❌ | + +All columns were checked on October 1, 2026. +Every environment builds, resets, steps and renders through the Gymnasium wrapper with the Quick Start configuration. +Circuit, Laser and Switch fail with a PyBullet joint error when another environment was built earlier in the same process, so build them in a fresh process. + +\* Boil and Bridge solve with `oracle_process_planning` under the settings of their oracle tests ([`test_oracle_process_planning_boil.py`](../../tests/approaches/test_oracle_process_planning_boil.py), [`test_oracle_process_planning_bridge.py`](../../tests/approaches/test_oracle_process_planning_bridge.py)); they do not solve in the default configuration. + +Laser and BusyBoard start every training task from one layout and use a different one for testing; MagicBin keeps one layout and varies only the goal. + +The other ❌ entries in the Oracle column, in the default configuration: +Barrier, MagicBin and Switch have no ground-truth operators or processes; +Domino and Fan fail an assertion while building their ground-truth processes; +Coffee fails to read a cup's pose; +Balloons, BusyBoard, Float, IceRink and Laser run but do not solve the test task. +The clips on the project page come from the benchmark settings or from scripted skill sequences, as each environment's page says. + +## Skill libraries + +`CFG.skill_library` selects the skills that `get_gt_options` builds: + +- `"composite"` (the default) is each environment's own skills, such as `PickJug`, `SwitchFaucetOn` or `Push`, with task knowledge built in. + These are the skills of the Skills column. +- `"primitive"` is one domain-general library, identical in every environment that supports it: `MoveTo[x, y, z, yaw, tilt]`, `MoveLinear[dx, dy, dz, step]`, `MoveUntilContact[dx, dy, dz, step]`, `Gripper[width, force]` and `Wait[steps]` (see [`skill_factories/primitives.py`](../ground_truth_models/skill_factories/primitives.py)). + The agent supplies the grasp points, push strokes and release moments itself. + Balloons, Boil, Bridge, Domino and Fan support it. ## Per-environment configuration -The RoboDisco envs read from predicators' global `CFG` object, which -normally gets populated by `predicators/main.py`'s command-line parser. +The RoboDisco envs read from predicators' global `CFG` object, which normally gets populated by `predicators/main.py`'s command-line parser. For library use, set it explicitly: ```python @@ -139,23 +154,21 @@ Each env can be used directly via predicators' `BaseEnv` interface: ```python from predicators import utils from predicators.envs.pybullet_blocks import PyBulletBlocksEnv +from predicators.structs import Action utils.reset_config({"num_train_tasks": 5, "num_test_tasks": 5}) env = PyBulletBlocksEnv(use_gui=False) state = env.reset("train", 0) for _ in range(50): - action = env.action_space.sample() + action = Action(env.action_space.sample()) state = env.step(action) ``` -This gives you direct access to `env.predicates`, `env.types`, -`env.goal_predicates`, `env.get_train_tasks()`, etc., without flattening -the state into a `Box` observation. +This gives you direct access to `env.predicates`, `env.types`, `env.goal_predicates`, `env.get_train_tasks()`, etc., without flattening the state into a `Box` observation. ## Developing new envs -For a guide on writing new PyBullet environments, see -[`docs/envs/pybullet-guide.md`](../../docs/envs/pybullet-guide.md). +For a guide on writing new PyBullet environments, see [`docs/envs/pybullet-guide.md`](../../docs/envs/pybullet-guide.md). ## Predicators planning framework diff --git a/predicators/envs/gymnasium_wrapper.py b/predicators/envs/gymnasium_wrapper.py index 98a65cb797..6f57f5edf4 100644 --- a/predicators/envs/gymnasium_wrapper.py +++ b/predicators/envs/gymnasium_wrapper.py @@ -1,6 +1,6 @@ """RoboDisco: a Gymnasium-API wrapper for predicators' PyBullet envs. -RoboDisco (Robot Model Discovery Benchmark) exposes the 15 native +RoboDisco (Robot Model Discovery Benchmark) exposes the 22 native ``predicators.envs.pybullet_*`` environments through a standard ``gymnasium.Env`` interface so the suite can be used as a robot model-discovery benchmark independent of the predicators planning @@ -200,24 +200,37 @@ def close(self) -> None: ("robodisco/Ants-v0", "predicators.envs.pybullet_ants:PyBulletAntsEnv"), ("robodisco/Balance-v0", "predicators.envs.pybullet_balance:PyBulletBalanceEnv"), + ("robodisco/Balloons-v0", + "predicators.envs.pybullet_balloons:PyBulletBalloonsEnv"), ("robodisco/Barrier-v0", "predicators.envs.pybullet_barrier:PyBulletBarrierEnv"), ("robodisco/Blocks-v0", "predicators.envs.pybullet_blocks:PyBulletBlocksEnv"), ("robodisco/Boil-v0", "predicators.envs.pybullet_boil:PyBulletBoilEnv"), + ("robodisco/Bridge-v0", + "predicators.envs.pybullet_bridge:PyBulletBridgeEnv"), + ("robodisco/BusyBoard-v0", + "predicators.envs.pybullet_busyboard:PyBulletBusyBoardEnv"), ("robodisco/Circuit-v0", "predicators.envs.pybullet_circuit:PyBulletCircuitEnv"), ("robodisco/Coffee-v0", "predicators.envs.pybullet_coffee:PyBulletCoffeeEnv"), ("robodisco/Cover-v0", "predicators.envs.pybullet_cover:PyBulletCoverEnv"), + ("robodisco/Crane-v0", "predicators.envs.pybullet_crane:PyBulletCraneEnv"), ("robodisco/Domino-v0", "predicators.envs.pybullet_domino.env:PyBulletDominoEnv"), ("robodisco/Fan-v0", "predicators.envs.pybullet_fan:PyBulletFanEnv"), ("robodisco/Float-v0", "predicators.envs.pybullet_float:PyBulletFloatEnv"), ("robodisco/Grow-v0", "predicators.envs.pybullet_grow:PyBulletGrowEnv"), + ("robodisco/IceRink-v0", + "predicators.envs.pybullet_icerink:PyBulletIceRinkEnv"), ("robodisco/Laser-v0", "predicators.envs.pybullet_laser:PyBulletLaserEnv"), + ("robodisco/Launcher-v0", + "predicators.envs.pybullet_launcher:PyBulletLauncherEnv"), ("robodisco/MagicBin-v0", "predicators.envs.pybullet_magic_bin:PyBulletMagicBinEnv"), + ("robodisco/Magnets-v0", + "predicators.envs.pybullet_magnets:PyBulletMagnetsEnv"), ("robodisco/Switch-v0", "predicators.envs.pybullet_switch:PyBulletSwitchEnv"), ] diff --git a/scripts/robodisco_getting_started.py b/scripts/robodisco_getting_started.py index 353415e617..35469780a8 100644 --- a/scripts/robodisco_getting_started.py +++ b/scripts/robodisco_getting_started.py @@ -27,7 +27,7 @@ robodisco.register_all_environments() env_ids = sorted(robodisco.get_all_env_ids()) print(f"[1/6] Found {len(env_ids)} environments") -assert len(env_ids) == 15, f"Expected 15 environments, got {len(env_ids)}" +assert len(env_ids) == 22, f"Expected 22 environments, got {len(env_ids)}" for eid in env_ids: print(f" {eid}") @@ -132,7 +132,9 @@ print(f"\nSummary: {len(ok)}/{len(env_ids)} envs reset cleanly.") if fail: - print("Failing envs (require additional CFG to instantiate):") + print("Failing envs (Circuit, Laser and Switch fail when another env " + "was built earlier in the same process; see " + "predicators/envs/README.md):") for eid, kind, msg in fail: print(f" {eid}: {kind}: {msg}") diff --git a/tests/envs/test_robodisco.py b/tests/envs/test_robodisco.py index 5bc7a4bbb7..f08e66220c 100644 --- a/tests/envs/test_robodisco.py +++ b/tests/envs/test_robodisco.py @@ -35,18 +35,18 @@ def rgb_env(): def test_register_all_environments_count(): - """register_all_environments() registers all 15 envs.""" + """register_all_environments() registers all 22 envs.""" register_all_environments() rd_ids = { eid for eid in gymnasium.registry if eid.startswith("robodisco/") } - assert len(rd_ids) == 15 + assert len(rd_ids) == 22 -def test_get_all_env_ids_returns_15(): - """get_all_env_ids() returns exactly 15 ids.""" - assert len(get_all_env_ids()) == 15 +def test_get_all_env_ids_returns_22(): + """get_all_env_ids() returns exactly 22 ids.""" + assert len(get_all_env_ids()) == 22 def test_get_all_env_ids_prefix(): @@ -60,7 +60,7 @@ def test_register_is_idempotent(): """register_all_environments() is safe to call multiple times.""" register_all_environments() register_all_environments() - assert len(get_all_env_ids()) == 15 + assert len(get_all_env_ids()) == 22 # ---------------------------------------------------------------------------