Add typed configurations to Arena environments - #858
Conversation
Move environment construction behind a typed dataclass while preserving the existing argparse frontend as a compatibility adapter. Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Keep the established environment argument names and avoid changing teleoperation behavior as part of the dataclass refactor. Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Keep provider identity on the registered factory and declare build inputs only on each concrete environment configuration. Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Greptile SummaryThis PR decouples all 19 first-party Arena environments from
Confidence Score: 5/5Safe to merge — all 19 environments apply the same adapter pattern consistently, the compatibility boundary is well-tested, and no existing behaviour changes. The change is a pure structural refactoring: runtime paths through get_env are identical to before (same assets, same conditions), mutable default fields use factory functions, the mimic/auto sentinel logic is semantically equivalent to the old hasattr checks, and a dedicated test suite validates every adapter without requiring Isaac Sim. No data loss, no broken contracts, no unguarded type changes. No files require special attention. The test file's use of object.new to skip init is intentional and safe since build is monkeypatched before any asset registry access. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant CLI as CLI / argparse
participant Adapter as get_env(args_cli)
participant Cfg as EnvironmentCfg (dataclass)
participant Build as build(cfg)
participant Env as IsaacLabArenaEnvironment
CLI->>Adapter: Namespace with raw strings/bools
Adapter->>Cfg: construct typed dataclass
Cfg-->>Adapter: validated, defaulted cfg
Adapter->>Build: build(cfg)
Build->>Env: assemble scene, embodiment, task
Env-->>CLI: IsaacLabArenaEnvironment
note over Adapter,Cfg: Legacy compatibility boundary (get_env stays abstract)
note over Build,Env: Typed Hydra-composable boundary (build raises NotImplementedError until migrated)
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant CLI as CLI / argparse
participant Adapter as get_env(args_cli)
participant Cfg as EnvironmentCfg (dataclass)
participant Build as build(cfg)
participant Env as IsaacLabArenaEnvironment
CLI->>Adapter: Namespace with raw strings/bools
Adapter->>Cfg: construct typed dataclass
Cfg-->>Adapter: validated, defaulted cfg
Adapter->>Build: build(cfg)
Build->>Env: assemble scene, embodiment, task
Env-->>CLI: IsaacLabArenaEnvironment
note over Adapter,Cfg: Legacy compatibility boundary (get_env stays abstract)
note over Build,Env: Typed Hydra-composable boundary (build raises NotImplementedError until migrated)
Reviews (2): Last reviewed commit: "Consolidate environment config tests" | Re-trigger Greptile |
🤖 Isaac Lab-Arena Review BotSummaryThis PR introduces a per-environment typed Design, Boundaries & ScopeThe one thing worth weighing: the ~20 Findings🟡 Warning: example_environment_base.py — ~20 duplicated Test Coverage
VerdictShip it — one optional design simplification worth considering. |
Move construction inputs out of argparse namespaces and into typed configuration objects. Keep get_env() as a compatibility adapter while build(cfg) becomes the frontend-independent boundary. Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Keep the legacy CLI option because teleop and demo-recording frontends consume it directly, while limiting the typed environment config to values used by build(cfg). Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Make the registry-wide test describe and verify the legacy CLI adapter boundary, while retaining the Maple teleop regression in the same file. Signed-off-by: Clemens Volk <cvolk@nvidia.com>
alexmillane
left a comment
There was a problem hiding this comment.
LGTM. Configuring this way makes a lot more sense.
My only substantial comment is whether we could generate the argparse from the config class difinition? That would eliminate one (loose) contract for during the transition.
Use each typed environment dataclass as the source of truth for legacy argparse flags and Namespace conversion. Remove the duplicated per-environment parser and adapter declarations. Signed-off-by: Clemens Volk <cvolk@nvidia.com>
Summary
Decouple environment construction from argparse
Detailed description
argparse.Namespacereads into environment-specific dataclass configs.build(cfg)the typed, frontend-independent construction boundary so Hydra and future dispatchers can compose environments without emulating CLI state.get_env(args_cli)as a temporary compatibility adapter, preserving existing command-line workflows and behavior.Follow up: Make
ExampleEnvironmentBase()a core base class