Skip to content

Sample the skill-factory parameters in Grow's and Coffee's NSRTs - #201

Merged
yichao-liang merged 3 commits into
masterfrom
fix-grow-oracle-samplers
Oct 3, 2026
Merged

yichao-liang merged 3 commits into
masterfrom
fix-grow-oracle-samplers

Conversation

@yichao-liang

Copy link
Copy Markdown
Collaborator

Summary

The bug.
--approach oracle on pybullet_grow raised IndexError: index 0 is out of bounds for axis 0 with size 0 in _descend_pose (skill_factories/pick.py).
Grow's NSRTs still sampled for the legacy options: no parameters for PickJug and a normalized (x, y) for Place.
The default skill-factory options take a grasp height for PickJug and a world (x, y, release_z, yaw) target for Place.
ParameterizedOption.ground let the empty grasp height through, because a wrong-shaped array passes its float-tolerance fallback, so the failure only surfaced inside the skill.

Coffee's NSRTs have the same mismatch for PickJug, PlaceJugInMachine and TurnMachineOn; its oracle reaches it once Coffee's planner can read its cups (#202).
Sampling every NSRT of the other RoboDisco environments the same way found no other mismatch (Bridge's and Domino's NSRTs need task-specific objects that this check does not build).

The fix.
With the skill-factory options, both factories now use the samplers their processes already use, as Bridge's NSRTs do; the legacy options and the 2D coffee env keep theirs.
tests/ground_truth_models/test_nsrt_samplers_fit_options.py grounds every NSRT of both environments and checks the sampled parameters against the option's parameter space.

Grow's oracle now runs but times out refining its plan, so Grow still solves only with oracle_process_planning and its README row is unchanged.
The module docstrings of Grow's ground-truth models no longer call it the coffee environment.
ParameterizedOption.ground accepting wrong-shaped parameters is left for a separate change.

Test plan

  • The README command on pybullet_grow: oracle runs to completion (0/1, timeout; it crashed before) and oracle_process_planning still solves (1/1).
  • The new test fails on the old code for both environments and passes here.
  • yapf 0.32.0, isort 5.10.1, docformatter 1.4, mypy 1.8.0 and pylint on the whole repo.
  • The full test suite on the top of this stack (Keep each PyBullet world's body ids on its own Objects #202).

Stacked on #200.

🤖 Generated with Claude Code

Circuit, Laser and Switch looked up their switch joints without
physicsClientId, so PyBullet answered from client 0, the first world
the process built. Built after any other env (through the RoboDisco
wrapper, in a test session, or in scripts/robodisco_getting_started.py)
they read the wrong world and failed with "getJointState failed;
invalid jointIndex" or "GetJointInfo failed.".

The same omission sat in calls that never crash. Laser created its beam
bodies in client 0, so the planner's world drew beams into the
executing env's world, and its bookkeeping then removed bodies from its
own. Coffee joined its cord segments and its plugged-in plug with
constraints in client 0, and the Domino fan component read its switch
joints from client 0.

Each of these calls now names the env's client, as do the few calls that
passed it positionally, so tests/test_pybullet_client_ids.py can require
physicsClientId= on every PyBullet call that reaches a physics server.
Regression tests build Circuit, Laser and Switch after Blocks in one
process and check that Laser's beams appear in its own world only.

The envs README and the smoke script no longer describe the failure, and
the smoke script numbers its seven steps out of seven.
Both oracle approaches crashed on Domino and Fan in the default
configuration, for unrelated reasons.

Domino's ground-truth processes were written for domino targets
(domino_use_domino_blocks_as_target=True, the benchmark setting). By
default the targets are hinged flaps and Toppled ranges over them, so
the process for a domino falling flat built Toppled(?d1) over a domino
and failed LiftedAtom's type check (structs.py:880). That process now
adds Toppled only when dominoes are the targets; with hinged targets a
fallen domino just stops tilting. No process models a hinged target
falling, so both oracles now run and report the goal unreachable.

Fan's default scene (the exposed deck since #196) attaches a
FanTransferEvaluator to each task. The process planner rewrites the
goal BallAtTarget into the grid goal BallAtLoc but kept the evaluator,
failing Task's check that an evaluator judges the task's own goal
(structs.py:1051). The rewritten task now drops it, as
replace_goal_with_alt_goal does; the planner never reads it.
oracle_process_planning then runs, but its grid processes cannot reach
the goal cell. The oracle approach already ran without crashing.

The envs README now lists Domino and Fan among the environments that
run but do not solve the test task.
Grow's NSRTs still sampled for the legacy options: no parameters for
PickJug and a normalized (x, y) for Place. The default skill-factory
options take a grasp height for PickJug and a world (x, y, release_z,
yaw) target for Place. Grounding let the empty grasp height through,
so Grow's oracle ran PickJug without one and raised "IndexError: index
0 is out of bounds" in pick.py's _descend_pose. Coffee's NSRTs have the
same mismatch for PickJug, PlaceJugInMachine and TurnMachineOn; its
oracle reaches it once Coffee's planner can read its cups.

With the skill-factory options both factories now use the samplers
their processes already use, as Bridge's NSRTs do; the legacy options
and the 2D coffee env keep theirs. A test grounds every NSRT of both
environments and checks the sampled parameters against the option's
parameter space.

Grow's oracle now runs but times out refining its plan, so Grow still
solves only with oracle_process_planning. The module docstrings of
Grow's ground-truth models no longer call it the coffee environment.
@yichao-liang
yichao-liang changed the base branch from fix-domino-fan-oracle-default to master October 3, 2026 07:59
@yichao-liang
yichao-liang merged commit 423cae0 into master Oct 3, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant