Skip to content

docs(isaac): backend reference + Phase 1 status banner (5/5 of #31 split)#48

Merged
yinsong1986 merged 2 commits into
strands-labs:mainfrom
yinsong1986:pr5/isaac-docs
May 28, 2026
Merged

docs(isaac): backend reference + Phase 1 status banner (5/5 of #31 split)#48
yinsong1986 merged 2 commits into
strands-labs:mainfrom
yinsong1986:pr5/isaac-docs

Conversation

@yinsong1986
Copy link
Copy Markdown
Contributor

Summary

Part 5 / 5 of the split of #31 — tracked by #42.

Adds the user-facing reference doc for the Isaac backend plus the companion test file that pins R2's "Phase 1 status" disclosure banner. Branched off PR-1 (#44); rebases cleanly onto main once PR-1 merges. Parallel-mergeable with PR-4 (#47) — no code dependency on simulation.py.

What's in this slice

File Status LOC Purpose
docs/backends/isaac.md new 208 Install + Quick Start + API reference + R2's Phase 1 status banner
strands_robots_sim/isaac/tests/test_phase1_doc_banner.py new (~75 LOC, 3 tests) 75 Carved from cagataycali's test_phase1_doc_honesty.py::TestIsaacDocsPhase1Banner; pins the banner content + ordering

R2 review-fix carry-over

R2 (commit 85e180f on #31) added a "Phase 1 status" banner to docs/backends/isaac.md between Overview and Installation. The banner discloses that the Phase 1 skeleton silently no-ops the data plane:

  • add_robot (procedural branch)
  • _load_usd_robot / _load_urdf_robot
  • add_object
  • add_camera
  • replicate

…all return status: "success" without instantiating the underlying USD prim or articulation handle. The observable downstream effect: get_observation() returns {} and render() returns blank frames.

Reviewer asked for this explicitly so a user following the Quick Start sees the disclaimer before following the documented call sequence — the banner sits before the ## Installation heading.

Why split test_phase1_doc_honesty.py

The original test file mixed two concerns:

Source class New file Lands in
TestG1DOFCount (3 tests) tests/test_procedural_g1_dof.py PR-3 (#46)
TestIsaacDocsPhase1Banner (3 tests) tests/test_phase1_doc_banner.py This PR (5/5)

Splitting keeps each parallel-mergeable slice CI-green standalone. Shipping the original combined file in either PR would couple them (PR-3 would CI-red until PR-5 lands, or vice versa). Combined coverage equals the original file.

CI signal

  • hatch run lint (black --check / isort --check-only / flake8 over strands_robots_sim/ + examples/) — clean.
  • pytest strands_robots_sim/isaac/tests/test_phase1_doc_banner.py -v3 passed.
  • The 3 tests verify (a) the doc file exists at the expected path, (b) the "Phase 1 status" banner precedes the ## Installation heading, (c) the banner enumerates add_robot, replicate, get_observation by name.

Dependency chain

PR-1 (#44, foundation) → PR-5 (this), parallel with PR-4 (#47, simulation). This is the closing slice — when PR-5 lands and #31 is closed, the umbrella tracker #42 closes too.

Diff: 2 files, +288 / 0 LOC.

Original authorship

Original work by @cagataycali in #31 (413ff15..85e180f). This slice cherry-picks docs/backends/isaac.md plus the carved-out banner test file. R2's banner addition (commit 85e180f) is already baked into this doc.

cagataycali
cagataycali previously approved these changes May 26, 2026
Copy link
Copy Markdown
Member

@cagataycali cagataycali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local review on Thor — 3/3 pin tests pass ✅, docs are accurate

Verified locally:

  • pytest strands_robots_sim/isaac/tests/test_phase1_doc_banner.py -v → 3 passed
  • Banner sits between Overview and Installation ✅ (line 17, before ## Installation at line 21)
  • Banner enumerates the silent-success methods correctly: add_robot (procedural branch), _load_usd_robot, _load_urdf_robot, add_object, add_camera, replicate
  • Banner names downstream effects: get_observation() returns {}, render() returns blank frames ✅
  • render_mode enum in docs matches config.py: headless / rtx_realtime / rtx_pathtracing

What's good ✅

  • 3-test pin file is well-scoped (file existence, banner-precedes-installation ordering, method enumeration)
  • Quick Start sequence matches the actual IsaacSimulation API surface in #47
  • Phase 1 status disclosure is upfront and honest — exactly what R2's review feedback asked for
  • Install paths cover all three real install vectors (Launcher / Isaac Lab / Docker)

Minor nit

Line 73: render_mode="rtx_realtime" in the Quick Start. Combined with headless=True, this is valid but a bit confusing because "headless" is also a render_mode value. A headless=True, render_mode="rtx_realtime" combo means "run with no GUI but still rasterize for camera renders". Worth a one-liner clarifying that headless controls the viewer, render_mode controls camera-render quality. Not blocking.

Mergeability

✅ Mergeable as-is once #44 lands. No code dependency on #47, so this can land in parallel with PR-4 (as the PR description correctly states).

@yinsong1986
Copy link
Copy Markdown
Contributor Author

Rebased onto pr1/isaac-foundation at c7e2e5e (PR #44's R1 fix that ports the 10 surface tests + adds pytest>=7.0 to [isaac] extra + flips hatch run test to pytest). Pushed as a force-update with --force-with-lease.

SHA shift on this branch:

Before After
docs(isaac): backend reference + Phase 1 status banner … 9c18e83 e811fec

Same content; rebased commit object only. No parallel-session activity on this branch.

Local verification post-rebase:

$ pytest strands_robots_sim/isaac/tests/ -v
… 13 passed in 0.15s   # 10 surface tests from PR-1 + 3 doc-banner tests
$ black --check strands_robots_sim   # clean
$ isort --check-only --profile black --line-length 120 strands_robots_sim   # clean
$ flake8 --max-line-length=120 strands_robots_sim   # clean

PR is approved by @cagataycali and mergeable_state: clean against the new base. After PR-1 (#44) merges to main, this trivially fast-forwards. Awaiting #44's merge before this can land per the dependency chain in #42.

…s-labs#31 split)

Part 5 / 5 of the split of strands-labs#31 — tracked by strands-labs#42. Branched off PR-1
(`pr1/isaac-foundation` -> strands-labs#44); rebases cleanly onto `main` once
PR-1 merges. Parallel-mergeable with PR-4 (strands-labs#47, simulation) -- this
slice has no code dependency on simulation.py.

Adds the user-facing reference doc for the Isaac backend plus the
companion test file that pins R2's "Phase 1 status" disclosure
banner:

- `docs/backends/isaac.md` (208 LOC):
  Install + Quick Start + API reference + environment variables
  + R2's Phase 1 status banner before the Installation section.
  The banner discloses that the Phase 1 skeleton silently no-ops
  the data plane (`add_robot` procedural branch, `_load_usd_robot`,
  `_load_urdf_robot`, `add_object`, `add_camera`, `replicate` all
  return `status: "success"` without instantiating the underlying
  USD prim or articulation handle, with the observable downstream
  effect that `get_observation()` returns `{}` and `render()`
  returns blank frames). R2 reviewer asked for this explicitly so
  a user following the Quick Start sees the disclaimer before the
  silent path.

- `strands_robots_sim/isaac/tests/test_phase1_doc_banner.py`
  (~75 LOC, 3 tests):
  Carved out of cagataycali's original
  `test_phase1_doc_honesty.py` -- the `TestIsaacDocsPhase1Banner`
  class only. The companion `TestG1DOFCount` class lives in PR-3
  (strands-labs#46) alongside `procedural.py`. Pin tests:
  - `test_isaac_docs_file_exists`: truth-source pin for the doc
    file's location.
  - `test_phase1_banner_present_before_installation`: pins that
    "Phase 1 status" appears AND precedes the `## Installation`
    heading.
  - `test_phase1_banner_names_the_silent_methods`: pins that the
    banner enumerates `add_robot`, `replicate`, `get_observation`
    by name (so a future maintainer who reads only the banner
    knows which API surfaces are affected).

CI signal: lint clean (black / isort / flake8); the 3 doc-banner
pin tests pass standalone (`pytest test_phase1_doc_banner.py -v` ->
3 passed).

Why split `test_phase1_doc_honesty.py` into G1-DOF (PR-3) + doc-
banner (this PR): keeps each parallel-mergeable slice CI-green
standalone. Shipping the original combined file in either PR would
couple them (PR-3 would CI-red until PR-5 lands, or vice versa).
The combined coverage equals the original file.

Original work by @cagataycali in strands-labs#31 (`413ff15..85e180f`); this
slice cherry-picks `docs/backends/isaac.md` plus the carved-out
banner test file. R2's banner addition (commit `85e180f`) is
already baked into this doc.
…d to main

Updates docs/backends/isaac.md to reflect the actual state of
strands_robots_sim.isaac after PR strands-labs#44 / strands-labs#45 / strands-labs#46 / strands-labs#47 / strands-labs#51 all
landed. The Phase 1 status banner had become stale (claimed all data-
plane methods were silent no-op when in fact the procedural builders
work, the loaders module ships, and several SimEngine methods now
have concrete implementations).

Three substantive changes:

1. Phase 1 status banner — split into 'Working today' (config,
   is_available, lifecycle, procedural builders, loaders module) vs
   'Still no-op' (add_object, add_camera, replicate, the per-class
   _load_usd_robot / _load_urdf_robot stubs, articulation-touching
   paths under get_observation / send_action / render). The loaders
   module is the working URDF / MJCF / USD ingestion path today; the
   IsaacSimulation private no-op stubs remain Phase 2 work.

2. New 'Loading External Description Files (URDF / MJCF / USD)'
   section between Procedural Robots and Comparison with Newton.
   Documents the loaders module (PR strands-labs#51): three load_*() functions
   producing ProceduralRobot dataclass instances, shared failure
   semantics (FileNotFoundError / ValueError, never silent phantom
   robot), and the parity-test pin against the seven robosuite-
   bundled MJCFs the strands-robots LIBERO adapter consumes.

3. Procedural Robots — added the G1 intermediate-link-bodies
   explanation and the fail-first kinematic-tree guard contract
   (PR strands-labs#51's  commit). No env-var escape hatch.

Plus housekeeping in the Architecture file-list and Testing section:

- Architecture: added _install.py (PR strands-labs#47's commit  —
  centralised install hints), loaders.py (PR strands-labs#51), and the actual
  test files now in main (test_get_observation_diagnostic_logs.py,
  test_procedural_g1_dof.py, test_procedural_kinematic_guard.py,
  test_loaders.py) instead of the placeholder list.

- Testing: pytest invocations updated to cover the five no-GPU test
  files now shipped, plus a one-liner for running them all at once
  (the --ignore pattern that the hatch script uses).

The doc was already accurate about the *direction* of Phase 1 vs
Phase 2; the update just brings the surface lists in line with what
actually shipped.

Verification:
- pytest strands_robots_sim/isaac/tests/test_phase1_doc_banner.py
  → 3 passed (the banner-content pin still matches; the rewrite
    keeps 'Phase 1 status' + the same enumerated method names).
- diff stat: docs/backends/isaac.md, +51 / -7 LOC.

This change lands inside PR strands-labs#48 (5/5 of strands-labs#31 split) since it's the
canonical home for docs/backends/isaac.md updates. Top-level README
and examples/MIGRATION.md drift (Stage-3-no-longer-future framing)
is a separate doc-alignment concern and lands in a follow-up PR
rather than widening this slice.
@yinsong1986
Copy link
Copy Markdown
Contributor Author

Two-part update: conflict resolved + doc content aligned with what's now in main.

1. Conflict resolved

Rebased onto current main (06fce4d, now includes the squash-merges of #44 / #45 / #46 / #47 / #51) — pushed as --force-with-lease.

Before After
Branch HEAD e811fec 76c3b1f

The interactive rebase dropped 2 commits already in main via PR #44's squash:

The remaining 2 commits replayed cleanly with zero conflicts:

# SHA (new) Title
1 a94150b docs(isaac): backend reference + Phase 1 status banner (5/5 of #31 split)
2 76c3b1f docs(isaac): align with PR #47 + PR #51 merged to main

mergeable_state flipped from dirtyblocked (just reviews now).

2. Doc content updated for the post-#47 / #51 state

The Phase 1 status banner in the original e811fec was accurate for the day it was written — but IsaacSimulation (PR #47) and the loaders module (PR #51) merged in the meantime, so several "silent no-op" claims drifted. Commit 76c3b1f brings three sections in line with what actually shipped:

Phase 1 status banner — split into "Working today" (config, is_available, lifecycle, procedural builders, loaders module) vs "Still no-op" (add_object, add_camera, replicate, the per-IsaacSimulation _load_usd_robot / _load_urdf_robot stubs, articulation-touching paths under get_observation / send_action / render). The test_phase1_doc_banner.py pin still passes against the rewrite — the same enumerated method names anchor the contract test.

New "Loading External Description Files (URDF / MJCF / USD)" section — documents isaac.loaders.load_urdf / load_mjcf / load_usd (PR #51): three load_*() functions producing ProceduralRobot dataclass instances, shared failure semantics (FileNotFoundError / ValueError, never silent phantom robot), and the parity-test pin against the seven robosuite-bundled MJCFs the strands-robots LIBERO adapter consumes.

Procedural Robots + Architecture file-list — added the G1 intermediate-link-bodies explanation, the fail-first kinematic-tree guard contract (PR #51's 3eeab25 commit), _install.py (PR #47's centralised install hints), and the actual test files now in main (instead of the placeholder list).

Diff on this commit alone: docs/backends/isaac.md, +51 / -7 LOC.

3. Companion PR for top-level docs

The same drift exists on README.md and examples/MIGRATION.md (Stage 3 framed as "future", rtx_mode='path_traced' kwarg that would TypeError against IsaacConfig's actual render_mode field, R5/R6/R7 checkboxes still unchecked). Filed PR #54 as the top-level sibling — same kind of post-merge alignment as PR #36 did for examples/README.md after #26 merged.

This PR (#48, the canonical home for docs/backends/isaac.md) and PR #54 (top-level README + MIGRATION) together bring all three doc surfaces in sync. They can land independently in either order — no code dependency.

Verification post-rebase + doc update

$ pytest strands_robots_sim/isaac/tests/test_phase1_doc_banner.py -v
3 passed in 0.11s
$ black --check strands_robots_sim       # clean
$ isort --check-only --profile black --line-length 120 strands_robots_sim   # clean
$ flake8 --max-line-length=120 strands_robots_sim   # clean

@yinsong1986 yinsong1986 requested a review from cagataycali May 28, 2026 08:32
Copy link
Copy Markdown
Member

@cagataycali cagataycali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve — rebased cleanly + content rewrite verified against main

My earlier R1 approve (2026-05-26T01:40:34Z, dismissed by force-push) covered the original a94150b content. Re-reviewing the rebased branch (76c3b1f) which adds the post-#47 / #51 alignment commit.

Rebase is clean

Dropped 3a0a854 and c7e2e5e (foundation + R1 surface tests, both now in main via PR #44's squash). Two commits replayed with zero conflicts. Branch is now MERGEABLE.

76c3b1f content rewrite — verified accurate against main @ 06fce4d

Phase 1 status banner restructure (Working today vs Still no-op):

  • "Working today" enumeration matches code: IsaacConfig (config.py), is_available() (simulation.py), lifecycle methods (PR #47), procedural builders for so100 / panda / unitree_g1 (procedural.py), and the isaac.loaders module with load_urdf / load_mjcf / load_usd (loaders.py lines 157 / 367 / 576).
  • "Still no-op" enumeration matches simulation.py stubs: add_object, add_camera, replicate, the per-IsaacSimulation _load_usd_robot / _load_urdf_robot private methods, and articulation-touching paths under get_observation / send_action / render.
  • Identical to PR #54's framing — three doc surfaces stay in sync.

New "Loading External Description Files" section:

  • Documents the three loader functions accurately (ProceduralRobot return type, shared failure semantics: FileNotFoundError for missing files, ValueError for malformed input — never silent phantom robot).
  • Parity-test pin against the seven robosuite-bundled MJCFs is consistent with the LIBERO adapter's actual asset list.

Procedural Robots + Architecture file-list:

  • G1 intermediate-link-bodies explanation matches the actual G1 builder's body construction.
  • _install.py reference is accurate (PR #47 centralised the install hints there).
  • Test file list matches what's actually under strands_robots_sim/isaac/tests/ on main (no longer the placeholder list).

Banner contract test still passes against the rewrite

$ python -m pytest strands_robots_sim/isaac/tests/test_phase1_doc_banner.py -v
strands_robots_sim/isaac/tests/test_phase1_doc_banner.py::TestIsaacDocsPhase1Banner::test_isaac_docs_file_exists PASSED
strands_robots_sim/isaac/tests/test_phase1_doc_banner.py::TestIsaacDocsPhase1Banner::test_phase1_banner_present_before_installation PASSED
strands_robots_sim/isaac/tests/test_phase1_doc_banner.py::TestIsaacDocsPhase1Banner::test_phase1_banner_names_the_silent_methods PASSED
3 passed in 0.02s

The pin survives the rewrite because the same enumerated method names (add_robot, replicate, get_observation) anchor the contract test — the test asks for method-name presence, not exact wording. Good test design choice on the original split.

Render-mode field name now consistent

The rewritten Quick Start uses render_mode="rtx_pathtracing", matching IsaacConfig.render_mode (config.py:67) and the same fix landing in PR #54 for the top-level docs. No more rtx_mode drift anywhere.

headless vs render_mode clarification

The minor nit from my R1 review (overlap between headless=True and render_mode="rtx_realtime") didn't block then and doesn't block now — Phase 2 work is the right place to clean up the headless / render_mode interaction docs once the camera-render path is actually wired. Filing as a follow-up not blocking this docs PR.

Mergeability

MERGEABLE against current main. No code dependency on PR #54 — the two PRs land independently. Re-approving.

@cagataycali cagataycali added the docs Documentation label May 28, 2026
@yinsong1986 yinsong1986 merged commit 73ea431 into strands-labs:main May 28, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in Strands Labs - Robots May 28, 2026
yinsong1986 added a commit that referenced this pull request May 28, 2026
Top-level docs claimed Isaac would 'land in v0.3.0+' as future work,
but PR #44 / #45 / #46 / #47 / #51 (R6 + R7 Phase 1) all merged to
main on 2026-05-26. Updates the doc-side framing to reflect what's
actually shipped vs what's still pending.

README.md:

1. Status banner: 'Backend code lands in v0.3.0+ (Isaac)' →
   explicit Phase 1 / Phase 2 split. Names what works today (entry-
   point registration, IsaacConfig, lifecycle scaffolding,
   procedural builders, URDF / MJCF / USD loaders) vs what's still
   no-op (add_object, add_camera, replicate, per-IsaacSimulation
   _load_*_robot stubs).

2. Quick-start preamble: 'become copy-paste-runnable when R6/#13
   and R7/#14 ship' → 'Isaac Sim Phase 1 has shipped — the snippet
   below is copy-paste-runnable today on a host with Isaac Sim
   2024.x+ installed'. Newton snippets remain gated on R11/#18.

3. Isaac Sim quick-start snippet: fixed the kwarg name
   (rtx_mode='path_traced' → render_mode='rtx_pathtracing') so
   it matches the IsaacConfig field actually defined in
   strands_robots_sim/isaac/config.py. The previous spelling
   would TypeError at construction. Added a second snippet showing
   the loaders module (load_urdf / load_mjcf / load_usd) since
   that's the working URDF / MJCF / USD ingestion path today.

4. Status & roadmap section:
   - Stage 2 R5: [ ] → [x] (#26 merged).
   - Stage 3 R6: [ ] → [x] with link to #44.
   - Stage 3 R7: split into 'Phase 1 [x]' (linking #45 / #46 /
     #47 / #51) and 'Phase 2 [ ]' so the next-up scope is visible
     without dropping the historical #14 reference.

examples/MIGRATION.md:

1. [isaac] extras line: 'Heavy GPU-only backends ship in later 0.x
   releases' / commented-out pip install → uncommented; comment
   notes 'Phase 1 shipped; data-plane in Phase 2'. Newton stays
   commented (Stage 4 pending).

2. 'After — same task on Isaac Sim' heading: 'Stage 3, future' →
   'Stage 3, Phase 1 shipped'. Snippet kwarg fixed
   (rtx_mode → render_mode; same bug as the README). Added a
   2-line comment noting evaluate_benchmark on a real LIBERO
   scene needs Phase 2 data-plane wiring (matches the disclosure
   banner on docs/backends/isaac.md, so the three doc surfaces
   stay in sync).

examples/README.md is left as-is: its TBD rows reference the
example files (libero/run_isaac.py etc.), which haven't shipped
yet — those issue links (R8/#15, R23/#27) are still accurate
forward-pointers.

Verification:
- diff stat: 2 files, +28 / -14 LOC. No code touched.
- README + MIGRATION render cleanly under standard markdown
  parsers (verified by spot-checking the table / heading nesting).
- The doc-banner test (test_phase1_doc_banner.py) is on the
  parallel pr5/isaac-docs branch (PR #48); the docstring banner
  on docs/backends/isaac.md was already updated there to the same
  framing — this PR brings README + MIGRATION in line.

Cross-references: PR #36 (the previous examples/README.md drift
fix) lands the same kind of post-merge alignment for #26's R5
work; this is its R7 Phase 1 sibling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants