Skip to content

Fix graph camera setup for DROID scenes#910

Open
lgulich wants to merge 1 commit into
rcathomen/cap-distance-gap-probefrom
lgulich/fix/graph-camera-setup
Open

Fix graph camera setup for DROID scenes#910
lgulich wants to merge 1 commit into
rcathomen/cap-distance-gap-probefrom
lgulich/fix/graph-camera-setup

Conversation

@lgulich

@lgulich lgulich commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fix graph camera setup for DROID graph specs

Detailed description

  • Generated graph YAMLs could not request the reviewed DROID exterior RGB-D camera profile, so camera setup depended on non-graph Maple environment wiring.
  • Adds registered camera profiles, routes the DROID exterior RGB-D profile through agentic generation and graph-spec builds, and fails closed when a profile is selected without cameras enabled.
  • Shares CAP Maple/DROID staging and local asset routing with graph-YAML builds so generated DROID scenes can run directly without mutating shared registered asset classes.
  • Validated with pre-commit run --all-files and focused graph/camera/asset tests: 53 passed, 3 skipped.

Add reviewed camera profiles to environment graph specs so agentic
DROID scenes can request the exterior RGB-D camera explicitly. Route
that profile through graph generation, YAML loading, and direct graph
builds, and fail closed when cameras are disabled.

Share CAP Maple/DROID staging and local asset routing between the
registered Maple environment and graph-YAML builds so generated graph
specs can run directly without mutating shared registered asset classes.

Signed-off-by: Lionel Gulich <lgulich@nvidia.com>
@greptile-apps

greptile-apps Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds graph-driven camera setup for DROID scenes. The main changes are:

  • Registered camera profiles for compatible embodiments.
  • Optional embodiment.camera_profile support in graph specs.
  • DROID exterior RGB-D profile routing through graph and agentic builds.
  • Shared CAP Maple/DROID staging and local asset override helpers.
  • CLI and test updates for graph camera and asset routing.

Confidence Score: 4/5

The changed graph local-asset path needs a fix before merging.

  • Camera profile validation and application are covered by the changed graph flow.
  • The local asset mirror path can route unrelated graph objects into the CAP-only baked asset tree.
  • That can break valid DROID graph builds when normal USD-backed objects are present.

isaaclab_arena_environments/cap_asset_overrides.py

Important Files Changed

Filename Overview
isaaclab_arena_environments/cap_asset_overrides.py Adds shared CAP staging/local routing, with one issue where local graph routing applies too broadly.
isaaclab_arena/environment_spec/arena_env_graph_conversion_utils.py Applies selected camera profiles during graph asset instantiation and moves pxr-dependent imports behind lazy paths.
isaaclab_arena/environment_spec/arena_env_graph_types.py Adds EmbodimentSpec with optional camera-profile validation.
isaaclab_arena/embodiments/droid/camera_profile_library.py Registers the DROID exterior RGB-D camera profile.
isaaclab_arena_environments/cli.py Routes graph-spec CLI builds through CAP asset overrides and forwards camera enablement.
isaaclab_arena_examples/agentic_environment_generation/environment_generation_runner.py Updates agentic graph preview builds to use CAP routing and camera enablement.

Reviews (1): Last reviewed commit: "Fix graph camera setup for DROID scenes" | Re-trigger Greptile

Comment on lines +119 to +122
if local_asset_root is not None:
source_url = getattr(routed_cls, "usd_path", None)
if source_url:
routed_cls, _, _ = local_asset_subclass(routed_cls, local_asset_root)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Local Mirror Overroutes Assets

When CAP_LOCAL_ASSET_ROOT is set, this branch localizes every graph asset class with a usd_path, while the guard only checks that the embodiment is DROID. A DROID graph that includes normal robolab or YCB objects can then look for those object USDs inside the CAP baked mirror and fail with FileNotFoundError, even though the local closure is documented for the Maple table and DROID scene assets.

@classmethod
def apply(cls, embodiment):
from isaaclab_arena.variations.camera_extrinsics_variation import CameraExtrinsicsVariation
from isaaclab_arena_environments.maple_cameras import MapleDroidPerceptionCameraCfg

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Core embodiment depends on an extension package

This profile lives in core (isaaclab_arena/embodiments/droid/) but pulls MapleDroidPerceptionCameraCfg from the isaaclab_arena_environments extension, and it's really Maple/GaP-specific (see the name and docstring). Deferring the import keeps import-time clean, but conceptually core now depends on an extension. Could the concrete profile live in isaaclab_arena_environments next to maple_cameras, leaving only the generic CameraProfileBase/registry in core?

**embodiment_params
)
embodiment = asset_registry.get_asset_by_name(embodiment_spec.registry_name)(**embodiment_params)
camera_profile = getattr(embodiment_spec, "camera_profile", None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 getattr for a declared field

graph_spec.embodiment is now typed EmbodimentSpec, which always declares camera_profile (default None), so the name is known and the fallback can't fire — direct access is clearer.

Suggested change
camera_profile = getattr(embodiment_spec, "camera_profile", None)
camera_profile = embodiment_spec.camera_profile

return f"{{ENV_REGEX_NS}}/{registry_name}/{prim_path.lstrip('/')}"


def _object_reference_classes() -> tuple[Any, Any]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Simpler deferred import

The module-level ObjectReference = None globals plus _object_reference_classes() re-implement caching that Python's import system already does, and the inner if ... is None checks are redundant right after the import. A plain deferred from ... import ... inside _instantiate_assets_from_spec (hoisted above the for ref loop) would keep the sim-deferred behavior with less machinery. Is the global caching needed for anything?

@arena-review-bot

Copy link
Copy Markdown
Contributor

🤖 Isaac Lab-Arena Review Bot

Summary

This PR gives graph/DROID scenes an explicit, reviewed camera setup by adding a CameraProfileBase + CameraProfileRegistry mechanism, an EmbodimentSpec.camera_profile field validated against compatibility, and routing through agentic generation, YAML loading, and direct graph builds (failing closed when a profile is selected without cameras). It also factors the CAP Maple/DROID staging & local-asset routing out of pick_and_place_maple_table_environment.py into a shared cap_asset_overrides.py and reuses it for graph-YAML builds. The extraction and dedup are good, and the mechanism is well-tested; one boundary concern and two small cleanups below.

Design, Boundaries & Scope

The generic camera-profile mechanism (base class + registry) sitting in core is fine — that's a reusable primitive. But the one concrete profile, DroidWorkspaceExteriorRgbdProfile, lives in core (isaaclab_arena/embodiments/droid/) while depending on MapleDroidPerceptionCameraCfg from the isaaclab_arena_environments extension, and it's Maple/GaP-specific by name and intent. That makes core conceptually depend on an extension (the deferred import hides it at import-time but not in responsibility). Suggest moving the concrete profile into the extension next to maple_cameras.

Findings

🟡 Warning: camera_profile_library.py:23 — Core DROID embodiment references a Maple/GaP-specific camera cfg from the isaaclab_arena_environments extension; the concrete profile likely belongs in the extension.
🔵 Improvement: arena_env_graph_conversion_utils.py:117getattr(embodiment_spec, "camera_profile", None) on a now-typed EmbodimentSpec; use direct access.
🔵 Improvement: arena_env_graph_conversion_utils.py:92_object_reference_classes() + module-global None caching duplicates Python's import cache; a plain deferred local import would be simpler.

Test Coverage

Good coverage: registry apply/compat, spec validation (accept/reject/unknown profile), catalogue rendering, system-prompt guidance, CLI flag parsing, the shared CAP override routing (staging/local, non-DROID rejection, temporary registry restoration), and a sim test asserting the installed exterior RGB-D camera dimensions/data types. Sim tests follow the inner/outer run_simulation_app_function pattern.

Verdict

Minor fixes needed

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