diff --git a/docs/conf.py b/docs/conf.py index 590e47e13..585a6e5b0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -107,7 +107,7 @@ "pygments_dark_style": "monokai", "footer_links": {}, "github_url": "https://github.com/isaac-sim/IsaacLab-Arena", - "show_nav_level": 2, + "show_nav_level": 1, # TODO(alexmillane, 2025-04-24): Try re-enabling this once we have a pypi page. # "icon_links": [ # { diff --git a/docs/images/affordances_objects.png b/docs/images/affordances_objects.png new file mode 100644 index 000000000..92857a8e0 --- /dev/null +++ b/docs/images/affordances_objects.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b696e78676531f1d001db4b31b5a7a2d3d91127c6256c981538b9741c6e9326 +size 209475 diff --git a/docs/images/arena_env_builder.png b/docs/images/arena_env_builder.png new file mode 100644 index 000000000..73d94b180 --- /dev/null +++ b/docs/images/arena_env_builder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21c5315ac061d0bc1c7fa8514526bd4714bd9c00989e3ff210a870abe8285858 +size 211821 diff --git a/docs/images/open_door_task.png b/docs/images/open_door_task.png new file mode 100644 index 000000000..7bbf003bf --- /dev/null +++ b/docs/images/open_door_task.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5092ed237d280a6ccac0e275cf2097e68170701fee798408c2baeda6d138ae51 +size 167761 diff --git a/docs/index.rst b/docs/index.rst index 9aab40eb9..b76120867 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -211,40 +211,26 @@ TABLE OF CONTENTS pages/example_workflows/imitation_learning/index pages/example_workflows/reinforcement_learning_workflows/index -.. toctree:: - :maxdepth: 1 - :caption: Advanced - - pages/advanced/private_omniverse - pages/advanced/assets_management - pages/advanced/gr00t_server_client - pages/quickstart/jupyter_notebooks - -.. toctree:: - :maxdepth: 1 - :caption: Policy Evaluation - - pages/policy_evaluation/index - .. toctree:: :maxdepth: 1 :caption: Concepts pages/concepts/concept_overview - pages/concepts/concept_environment_design - pages/concepts/concept_embodiment_design - pages/concepts/concept_tasks_design - pages/concepts/concept_sequential_tasks_design - pages/concepts/concept_scene_design - pages/concepts/concept_metrics_design - pages/concepts/concept_teleop_devices_design pages/concepts/concept_environment_compilation - pages/concepts/concept_assets_design - pages/concepts/concept_affordances_design + pages/concepts/scene/index + pages/concepts/task/index + pages/concepts/embodiment/index pages/concepts/concept_object_placement - pages/concepts/concept_policy_design - pages/concepts/concept_remote_policies_design + pages/concepts/policy/index + +.. toctree:: + :maxdepth: 1 + :caption: Advanced + pages/advanced/private_omniverse + pages/advanced/assets_management + pages/advanced/gr00t_server_client + pages/quickstart/jupyter_notebooks .. toctree:: :maxdepth: 1 diff --git a/docs/pages/advanced/gr00t_server_client.rst b/docs/pages/advanced/gr00t_server_client.rst index ddeb605a9..fef0ecfbe 100644 --- a/docs/pages/advanced/gr00t_server_client.rst +++ b/docs/pages/advanced/gr00t_server_client.rst @@ -3,7 +3,7 @@ Server-Client Mode With GR00T Arena supports running the simulation and the policy model in separate containers connected via a lightweight RPC protocol. This is useful when the policy environment has different dependencies or -needs to run on a different machine. You can see more details in the :doc:`../concepts/concept_remote_policies_design` page. +needs to run on a different machine. You can see more details in the :doc:`../concepts/policy/concept_remote_policies_design` page. It requires two containers to run: @@ -59,4 +59,4 @@ The simulation environment and the policy model communicate via the remote polic If you want to host other policy models as remote servers, you can follow the same pattern: create a dedicated server Dockerfile and launcher script (similar to ``docker/Dockerfile.gr00t_server`` and ``docker/run_gr00t_server.sh``), and point it to a custom ``ServerSidePolicy`` -implementation as described in :doc:`../concepts/concept_remote_policies_design`. +implementation as described in :doc:`../concepts/policy/concept_remote_policies_design`. diff --git a/docs/pages/concepts/concept_affordances_design.rst b/docs/pages/concepts/concept_affordances_design.rst deleted file mode 100644 index dac04ce9d..000000000 --- a/docs/pages/concepts/concept_affordances_design.rst +++ /dev/null @@ -1,108 +0,0 @@ -Affordances Design -=================== - -Affordances define what interactions objects can perform - opening doors, pressing buttons, manipulating objects. -They provide standardized interfaces that integrate with assets and tasks. - -Core Architecture ------------------ - -Affordances use the ``AffordanceBase`` abstract class and mixin pattern: - -.. code-block:: python - - class AffordanceBase(ABC): - @property - @abstractmethod - def name(self) -> str: - pass - - class Openable(AffordanceBase): - def open(self, env, env_ids, percentage=1.0): - """Set opening percentage via joint control.""" - - def is_open(self, env, threshold=None): - """Query current open state.""" - -Affordances are mixin classes that combine with objects through multiple inheritance, operating on articulated objects via joint control. - -Affordances in Detail ---------------------- - -**Openable Affordance** - Provides opening and closing functionality for articulated objects: - - - **State Methods**: ``is_open()``, ``get_openness()`` for querying current state - - **Control Methods**: ``open()``, ``close()`` for direct state manipulation - - **Parameters**: ``openable_joint_name``, ``openable_open_threshold`` - - **Implementation**: Normalized joint position control (0.0-1.0 range) - -**Pressable Affordance** - Enables pressing and releasing functionality for button-like objects: - - - **State Methods**: ``is_pressed()`` for current button state - - **Control Methods**: ``press()``, ``unpress()`` for state changes - - **Parameters**: ``pressable_joint_name``, ``pressable_pressed_threshold`` - - **Implementation**: Threshold-based binary state determination - -**Object Integration Pattern** - Affordances combine with assets through multiple inheritance: - - .. code-block:: python - - @register_asset - class Microwave(LibraryObject, Openable): - name = "microwave" - object_type = ObjectType.ARTICULATION - openable_joint_name = "microjoint" - openable_open_threshold = 0.5 - -**Task Integration** - Affordances provide termination conditions and event handling for tasks: - - - **Termination**: Use ``is_open()`` for success criteria in ``OpenDoorTask`` - - **Events**: Reset object states with affordance methods during episode resets - - **Metrics**: Track interaction progress through state queries - -Environment Integration ------------------------ - -.. code-block:: python - - # Create affordance-enabled object - microwave = asset_registry.get_asset_by_name("microwave")() - - # Use in task definition - task = OpenDoorTask( - openable_object=microwave, - openness_threshold=0.8, - reset_openness=0.2 - ) - - # Environment composition - environment = IsaacLabArenaEnvironment( - name="microwave_opening", - embodiment=embodiment, - scene=scene, - task=task - ) - -Usage Examples --------------- - -**Microwave Opening Task** - -.. code-block:: python - - microwave = asset_registry.get_asset_by_name("microwave")() - task = OpenDoorTask(microwave, openness_threshold=0.8) - -**Runtime State Querying** - -.. code-block:: python - - # Check object state during simulation - if microwave.is_open(env, threshold=0.7): - print("Microwave is open enough") - - current_openness = microwave.get_openness(env) diff --git a/docs/pages/concepts/concept_assets_design.rst b/docs/pages/concepts/concept_assets_design.rst deleted file mode 100644 index 78b1c7a57..000000000 --- a/docs/pages/concepts/concept_assets_design.rst +++ /dev/null @@ -1,121 +0,0 @@ -Assets Design -============= - -Assets are the building blocks of simulation environments - robots, objects, backgrounds, and scene elements. -The asset system provides a registry system for managing these components. - -Core Architecture ------------------ - -The asset system uses a hierarchical class structure: - -.. code-block:: python - - class Asset: - """Base class for all assets.""" - def __init__(self, name: str, tags: list[str] | None = None, **kwargs): - self._name = name - self.tags = tags - - class ObjectBase(Asset): - """Physical objects that can be spawned.""" - def __init__(self, object_type: ObjectType, prim_path: str, **kwargs): - self.object_type = object_type - self.prim_path = prim_path - self.object_cfg = self.get_cfg() - - def get_cfg(self) -> dict[str, Any]: - """Generate Isaac Lab configurations.""" - -The system supports complex compositions through mixins like affordances while automatically generating Isaac Lab-compatible configurations. - -Assets in Detail ----------------- - -**Asset Hierarchy** - Three-tier architecture from generic to specialized: - - - **Asset**: Base class providing name, tags, and identification - - **ObjectBase**: Adds physics types, pose management, and configuration generation - - **Specialized Classes**: Object, Background, ObjectReference, EmbodimentBase for specific use cases - -**Physics Types** - Support for different simulation behaviors: - - - **BASE**: Static objects without physics (backgrounds, markers) - - **RIGID**: Single rigid body physics (boxes, tools, furniture) - - **ARTICULATION**: Multi-body with joints (robots, doors, appliances) - -**Registration System** - Automatic asset discovery through decorators: - - .. code-block:: python - - @register_asset - class CrackerBox(LibraryObject): - name = "cracker_box" - tags = ["object"] - usd_path = "path/to/cracker_box.usd" - object_type = ObjectType.RIGID - -**Discovery Mechanisms** - Multiple ways to find and instantiate assets: - - - **By Name**: ``asset_registry.get_asset_by_name("cracker_box")()`` - - **By Tags**: ``asset_registry.get_assets_by_tag("object")`` - - **Random Selection**: ``asset_registry.get_random_asset_by_tag("object")()`` - -**Configuration Generation** - Automatic Isaac Lab configuration creation based on object type and properties, handling physics setup, contact sensors, and collision detection internally. - -Environment Integration ------------------------ - -.. code-block:: python - - # Asset creation and positioning - background = asset_registry.get_asset_by_name("kitchen")() - pick_object = asset_registry.get_asset_by_name("cracker_box")() - pick_object.set_initial_pose(Pose(position_xyz=(0.4, 0.0, 0.1))) - - # Scene composition - scene = Scene(assets=[background, pick_object]) - - # Environment integration - environment = IsaacLabArenaEnvironment( - name="manipulation_task", - embodiment=embodiment, - scene=scene, - task=task - ) - -Usage Examples --------------- - -**Asset Discovery** - -.. code-block:: python - - # Direct asset creation - kitchen = asset_registry.get_asset_by_name("kitchen")() - objects = asset_registry.get_assets_by_tag("object") - -**Affordance Integration** - -.. code-block:: python - - # Objects with interaction capabilities - microwave = asset_registry.get_asset_by_name("microwave")() # Has Openable mixin - task = OpenDoorTask(microwave, openness_threshold=0.8) - -**Object References** - -.. code-block:: python - - # Reference existing scene elements - destination = ObjectReference( - name="kitchen_drawer", - prim_path="{ENV_REGEX_NS}/kitchen/Cabinet_B_02", - parent_asset=kitchen_background, - object_type=ObjectType.RIGID - ) diff --git a/docs/pages/concepts/concept_embodiment_design.rst b/docs/pages/concepts/concept_embodiment_design.rst deleted file mode 100644 index b8ee49954..000000000 --- a/docs/pages/concepts/concept_embodiment_design.rst +++ /dev/null @@ -1,172 +0,0 @@ -Embodiment Design -================== - -Embodiments define robot-specific configurations and behaviors. They provide a modular way to integrate different robots into environments, encapsulating kinematics, control actions, observations, and camera systems. - -Core Architecture ------------------ - -Embodiments use the ``EmbodimentBase`` abstract class that extends the asset system: - -.. code-block:: python - - class EmbodimentBase(Asset): - name: str | None = None - tags: list[str] = ["embodiment"] - arm_mode: ArmMode | None = None - - def __init__(self, enable_cameras: bool = False, initial_pose: Pose | None = None, arm_mode: ArmMode | None = None): - self.scene_config: Any | None = None - self.action_config: Any | None = None - self.observation_config: Any | None = None - # ... other configs - - @abstractmethod - def get_scene_cfg(self) -> Any: - """Robot physical configuration and actuators.""" - - @abstractmethod - def get_action_cfg(self) -> Any: - """Control interface definition.""" - -Embodiments in Detail ---------------------- - -**Configuration Components** - Embodiments contribute multiple configuration aspects to environments: - - - **Scene Configuration**: Robot physical properties, actuators, initial pose, mounting stands - - **Action Configuration**: Control interface (joint positions, end-effector poses, WBC) - - **Observation Configuration**: Sensor data, joint states, end-effector poses, camera feeds - - **Event Configuration**: Robot initialization, resets, randomization - - **Camera Configuration**: Onboard cameras with positions and sensor properties (optional) - - **XR Configuration**: XR device locations for teleop integration (optional) - - **Mimic Configuration**: Mimic environment support for demonstration (optional) - - -**Available Embodiments** - Robot assets with different capabilities and control modes: - - - **Franka Panda**: 7-DOF manipulator with differential IK control - - **Unitree G1**: Humanoid with WBC, dual-arm manipulation, locomotion - - **GR1T2**: Humanoid optimized for manipulation with dual end-effector control - - **Control Variants**: Joint space vs. inverse kinematics control modes - -**Camera Integration** - Optional camera systems that add observation terms when enabled, supporting both manipulation and perception tasks with head-mounted or external cameras. - - -**Arm Mode** - Embodiments expose an ``arm_mode`` attribute that declares which arms are - movable for demonstration playback. This attribute uses the - ``ArmMode`` enum from ``isaaclab_arena.embodiments.common.arm_mode``: - - - **SINGLE_ARM** – the robot has only one arm. - - **DUAL_ARM** – bimanual robot, task is performed with both arms in the demonstration. - - **LEFT** – bimanual robot, task is performed with the left arm and right arm is idle. - - **RIGHT** – bimanual robot, task is performed with the right arm and left arm is idle. - - Tasks and mimic environment builders can consult this property to request the correct - subtask configurations, ensuring that mimic environments match the - capabilities of the selected embodiment. - - .. code-block:: python - - class PickAndPlaceTask(TaskBase): - """ Task class """ - - def get_mimic_env_cfg(self, arm_mode: ArmMode): - # gets the mimic environment configuration based on embodiment's arm mode. - return PickPlaceMimicEnvCfg( - arm_mode=arm_mode, - pick_up_object_name=self.pick_up_object.name, - destination_location_name=self.destination_location.name, - ) - - @configclass - class PickPlaceMimicEnvCfg(MimicEnvCfg): - """Mimic environment configuration class""" - - arm_mode: ArmMode = ArmMode.SINGLE_ARM - - def __post_init__(self): - super().__post_init__() - - # defines the subtask configurations based on the arm mode. - if self.arm_mode == ArmMode.SINGLE_ARM: - # single arm subtask configuration - elif self.arm_mode in [ArmMode.LEFT, ArmMode.RIGHT]: - # bimanual robot with one arm idle subtask configuration - elif self.arm_mode == ArmMode.DUAL_ARM: - # dual arm subtask configuration - else: - # raise error for unsupported arm mode - - class ArenaEnvBuilder: - """ ArenaEnvBuilder class """ - - def compose_manager_cfg(self): - # composes the mimic environment configuration based on embodiment's mimic arm mode. - task_mimic_env_cfg = self.arena_env.task.get_mimic_env_cfg( - arm_mode=self.arena_env.embodiment.arm_mode - ) - return task_mimic_env_cfg - - -Environment Integration ------------------------ - -.. code-block:: python - - # Embodiment creation with camera support - embodiment = asset_registry.get_asset_by_name("franka_ik")( - enable_cameras=True - ) - - # Set robot initial pose - embodiment.set_initial_pose( - Pose(position_xyz=(0.0, 0.0, 0.0), rotation_xyzw=(0.0, 0.0, 0.0, 1.0)) - ) - - # Environment composition - environment = IsaacLabArenaEnvironment( - name="manipulation_task", - embodiment=embodiment, # Robot configuration - scene=scene, - task=task, - teleop_device=teleop_device - ) - -Usage Examples --------------- - -**Manipulation Robot** - -.. code-block:: python - - franka = asset_registry.get_asset_by_name("franka_ik")(enable_cameras=True) - task = PickAndPlaceTask(pick_object, destination, background) - -**Humanoid Control Modes** - -.. code-block:: python - - # Joint space control - g1_joint = asset_registry.get_asset_by_name("g1_wbc_joint")() - - # Inverse kinematics control - g1_ik = asset_registry.get_asset_by_name("g1_wbc_pink")() - -**Teleop Integration** - -.. code-block:: python - - embodiment = asset_registry.get_asset_by_name("gr1_pink")() - teleop_device = device_registry.get_device_by_name("avp_handtracking")() - - environment = IsaacLabArenaEnvironment( - embodiment=embodiment, - teleop_device=teleop_device, - scene=scene, - task=task - ) diff --git a/docs/pages/concepts/concept_environment_compilation.rst b/docs/pages/concepts/concept_environment_compilation.rst index fc5ed0820..40a8433e7 100644 --- a/docs/pages/concepts/concept_environment_compilation.rst +++ b/docs/pages/concepts/concept_environment_compilation.rst @@ -1,131 +1,79 @@ -Environment Compilation Design -================================ +Environment Compilation +======================= -Environment compilation transforms modular IsaacLab Arena Environment components into complete Isaac Lab Arena environment configurations. -The system handles configuration merging, environment registration, and integration with Isaac Lab's architecture. +Environment compilation is the step that turns the three independent components — +scene, embodiment, and task — into a runnable Isaac Lab environment. +``ArenaEnvBuilder`` does this by collecting the partial configuration each +component contributes and merging them into a single +``ManagerBasedRLEnvCfg``. -Core Architecture ------------------ +.. figure:: ../../images/arena_env_builder.png + :width: 100% + :alt: ArenaEnvBuilder merges Scene, Embodiment, and Task into a ManagerBasedRLEnv + :align: center -Compilation uses the ``ArenaEnvBuilder`` class: + ``ArenaEnvBuilder`` merges the Scene, Embodiment, and Task into a runnable ``ManagerBasedRLEnv``. .. code-block:: python - class ArenaEnvBuilder: - """Compose IsaacLab Arena → Isaac Lab configs""" - - def __init__(self, arena_env: IsaacLabArenaEnvironment, args: argparse.Namespace): - self.arena_env = arena_env - self.args = args - - def compose_manager_cfg(self) -> IsaacLabArenaManagerBasedRLEnvCfg: - """Combine configurations from all components.""" - scene_cfg = combine_configclass_instances( - "SceneCfg", - self.DEFAULT_SCENE_CFG, - self.arena_env.scene.get_scene_cfg(), - self.arena_env.embodiment.get_scene_cfg(), - self.arena_env.task.get_scene_cfg() - ) - -The builder transforms IsaacLab Arena environment definitions into Isaac Lab's configuration format through systematic component integration. - -Compilation in Detail ---------------------- - -**Configuration Merging** - Systematic combination of component configurations: - - - **Scene Configuration**: Merges default settings, scene assets, embodiment physics, and task-specific elements - - **Observation Configuration**: Extracts sensor data and state information from embodiment - - **Action Configuration**: Defines control interfaces from embodiment specifications - - **Event Configuration**: Combines reset and randomization logic from embodiment, scene, and task - - **Termination Configuration**: Merges success/failure conditions from task and scene components - - **Metrics Configuration**: Automatic recorder manager setup for performance evaluation - - **XR Configuration**: XR device locations for teleop integration (optional) - - **Teleop Device Configuration**: Teleop device configuration from embodiment - - **Recorder Manager Configuration**: Recorder manager configuration for performance evaluation - -**Environment Modes** - Support for different Isaac Lab environment types: - - - **Standard Mode**: Full environment with observations, actions, events, terminations, and metrics - - **Mimic Mode**: Mimic environment with subtask definitions - -Environment Integration ------------------------ - -.. code-block:: python - - # Create IsaacLab Arena environment definition environment = IsaacLabArenaEnvironment( - name="kitchen_manipulation", - embodiment=franka_embodiment, - scene=kitchen_scene, - task=pick_and_place_task, - teleop_device=keyboard_device + name="manipulation_task", + embodiment=embodiment, + scene=scene, + task=task, ) - # Compile to Isaac Lab environment - env_builder = ArenaEnvBuilder(environment, args) - - # Register and create executable environment - env = env_builder.make_registered() - - # Alternative: get both environment and configuration - env, cfg = env_builder.make_registered_and_return_cfg() - -Usage Examples --------------- - -**Standard Environment Compilation** - -.. code-block:: python - - # Build standard RL environment - args.mimic = False - env_builder = ArenaEnvBuilder(arena_environment, args) + env_builder = ArenaEnvBuilder(environment, args_cli) env = env_builder.make_registered() - # Environment ready for training/evaluation - obs, _ = env.reset() - actions = policy.get_action(env, obs) - obs, rewards, terminated, truncated, info = env.step(actions) - -**Mimic Environment Compilation** - -.. code-block:: python - - # Build demonstration generation environment - args.mimic = True - env_builder = ArenaEnvBuilder(arena_environment, args) - env = env_builder.make_registered() - - # Environment configured for mimic data generation - mimic_env.generate_demonstrations() - -**Configuration Inspection** - -.. code-block:: python - - # Examine compiled configuration before registration - env_builder = ArenaEnvBuilder(arena_environment, args) - cfg = env_builder.compose_manager_cfg() - - print(f"Scene objects: {list(cfg.scene.keys())}") - print(f"Action space: {cfg.actions}") - print(f"Observation space: {cfg.observations}") - -**Runtime Parameter Override** - -.. code-block:: python - - # Apply runtime configuration changes - name, cfg = env_builder.build_registered() - cfg = parse_env_cfg( - name, - device="cuda:0", - num_envs=1024, - use_fabric=True - ) - env = gym.make(name, cfg=cfg) +How it works +------------ + +Each component (Scene, Embodiment, Task) exposes a set of ``get_*_cfg()`` methods that return its +contribution to each Isaac Lab manager. The typical contributions of each component +to each manager are tabulated below: + ++-------------+------------------------------------------------------------------------+ +| Isaac Lab | Isaac Lab - Arena Component | ++ Manager +-----------------------+-------------------------+----------------------+ +| | Scene | Embodiment | Task | ++=============+=======================+=========================+======================+ +| Scene | assets, lights | robot, sensors | task-specific assets | ++-------------+-----------------------+-------------------------+----------------------+ +| Observations| | proprioception, cameras | goal observations | ++-------------+-----------------------+-------------------------+----------------------+ +| Actions | | control interface | | ++-------------+-----------------------+-------------------------+----------------------+ +| Events | object placement | robot reset | task reset | +| (resets) | | | | ++-------------+-----------------------+-------------------------+----------------------+ +| Terminations| | | success, failure | ++-------------+-----------------------+-------------------------+----------------------+ +| Rewards | | | dense rewards (RL) | ++-------------+-----------------------+-------------------------+----------------------+ +| Recorder | | | metrics-required data| ++-------------+-----------------------+-------------------------+----------------------+ + + +``ArenaEnvBuilder.compose_manager_cfg()`` first assembles the partial manager contributions +from each component into a set of complete managers. Then it merges these complete managers +into a single ``ManagerBasedRLEnvCfg``. +The Arena Environment Builder also optionally solves spatial relations between +objects (``--solve_relations``). See :doc:`./concept_object_placement` for more details. + + +The compiled config is then registered with the gym registry under the +environment's name, and ``gym.make()`` returns the gym environment. + +Mimic mode +---------- + +Passing ``--mimic`` at the command line compiles a +``ManagerBasedRLMimicEnv`` instead of a standard ``ManagerBasedRLEnv``. +The mimic environment is used for demonstration generation and includes +subtask configurations from the task. Metrics and recorders are excluded +in mimic mode. + +.. code-block:: bash + + python isaaclab_arena/scripts/imitation_learning/generate_dataset.py --mimic ... diff --git a/docs/pages/concepts/concept_environment_design.rst b/docs/pages/concepts/concept_environment_design.rst deleted file mode 100644 index eab079313..000000000 --- a/docs/pages/concepts/concept_environment_design.rst +++ /dev/null @@ -1,57 +0,0 @@ -Environment Design -================== - -IsaacLab Arena environment contains the main components used to create a manager-based RL environment. -This includes the embodiment, scene, task and teleop device. - -Core Architecture ------------------ - -.. code-block:: python - - @configclass - class IsaacLabArenaEnvironment: - name: str = MISSING - embodiment: EmbodimentBase = MISSING - scene: Scene = MISSING - task: TaskBase = MISSING - teleop_device: TeleopDeviceBase | None = None - - class ArenaEnvBuilder: - """Compose IsaacLab Arena → Isaac Lab configs.""" - def compose_manager_cfg(self) -> IsaacLabArenaManagerBasedRLEnvCfg: - # Combine configurations from all components - scene_cfg = combine_configclass_instances(...) - observation_cfg = self.arena_env.embodiment.get_observation_cfg() - actions_cfg = self.arena_env.embodiment.get_action_cfg() - -Each component contributes to the final environment configuration, with automatic integration handled by the environment builder. - -Creating an Environment Example --------------------------------- - -.. code-block:: python - - # Component creation - embodiment = asset_registry.get_asset_by_name("franka_ik")() - background = asset_registry.get_asset_by_name("kitchen")() - pick_object = asset_registry.get_asset_by_name("cracker_box")() - pick_object.set_initial_pose(Pose(position_xyz=(0.4, 0.0, 0.1))) - - # Environment composition - scene = Scene(assets=[background, pick_object]) - task = PickAndPlaceTask(pick_object, destination, background) - - arena_environment = IsaacLabArenaEnvironment( - name="manipulation_task", - embodiment=embodiment, - scene=scene, - task=task, - teleop_device=None - ) - - # Build and execute - env_builder = ArenaEnvBuilder(arena_environment, args) - env = env_builder.make_registered() - -To see how the manager-based RL environment configuration is compiled, please refer to the :doc:`./concept_environment_compilation` page. diff --git a/docs/pages/concepts/concept_metrics_design.rst b/docs/pages/concepts/concept_metrics_design.rst deleted file mode 100644 index b02b86a46..000000000 --- a/docs/pages/concepts/concept_metrics_design.rst +++ /dev/null @@ -1,108 +0,0 @@ -Metrics Design -============== - -Metrics evaluate robot performance and task completion. The system integrates with Isaac Lab's recorder manager to capture simulation data and compute performance indicators. - -Core Architecture ------------------ - -Metrics use two-component architecture separating data collection from metric computation: - -.. code-block:: python - - class MetricBase(ABC): - name: str - recorder_term_name: str - - @abstractmethod - def get_recorder_term_cfg(self) -> RecorderTermCfg: - """Define what data to record.""" - - @abstractmethod - def compute_metric_from_recording(self, recorded_metric_data: list[np.ndarray]) -> float: - """Compute final metric from recorded data.""" - -Each metric has a **RecorderTerm** that collects data and a **MetricBase** implementation that processes recorded data into performance indicators. - -Metrics in Detail ------------------ - -**Data Collection Pipeline** - Two-phase approach to performance evaluation: - - - **RecorderTerm Components**: Real-time data collection during simulation with configurable triggers - - **Recording Modes**: Pre-reset, post-step, event-triggered, and continuous monitoring patterns - - **Storage Format**: HDF5 format with episode organization and parallel environment support - - **Data Extraction**: Access simulation state and extract relevant measurements - -**Available Metrics** - Built-in metrics for common evaluation scenarios: - - - **Success Rate Metric**: Binary task completion tracking across episodes - - **Door Moved Rate Metric**: Interaction progress with openable objects via joint positions - - **Object Moved Rate Metric**: Manipulation assessment through object velocity tracking - - **Custom Metrics**: Extensible framework for task-specific performance indicators - -**Integration Pattern** - Metrics integrate through task definitions: - - .. code-block:: python - - class OpenDoorTask(TaskBase): - def get_metrics(self) -> list[MetricBase]: - return [ - SuccessRateMetric(), - DoorMovedRateMetric(self.openable_object, reset_openness=self.reset_openness) - ] - -**Computation Workflow** - Standardized evaluation process: - - - **Data Recording**: Capture relevant simulation data throughout execution - - **Episode Completion**: Organize and store data when episodes terminate - - **Metric Computation**: Post-simulation processing of recorded data - - **Result Aggregation**: Combine multiple metrics into evaluation reports - -Environment Integration ------------------------ - -.. code-block:: python - - # Metric collection during environment execution - env_builder = ArenaEnvBuilder(arena_environment, args) - env = env_builder.make_registered() # Metrics auto-configured from task - - # Execute episodes with automatic recording - for episode in range(100): - obs, _ = env.reset() - done = False - while not done: - actions = policy(obs) - obs, _, terminated, truncated, _ = env.step(actions) - done = terminated or truncated - - # Compute final performance indicators - metrics_results = compute_metrics(env) - -Usage Examples --------------- - -**Task-Specific Metrics** - -.. code-block:: python - - # Pick and place evaluation - task = PickAndPlaceTask(pick_object, destination, background) - metrics = task.get_metrics() # [SuccessRateMetric(), ObjectMovedRateMetric()] - - # Door opening evaluation - task = OpenDoorTask(microwave, openness_threshold=0.8) - metrics = task.get_metrics() # [SuccessRateMetric(), DoorMovedRateMetric()] - -**Results Analysis** - -.. code-block:: python - - # Performance evaluation across environments - print(f"Success Rate: {metrics_results['success_rate']:.2%}") - print(f"Object Moved Rate: {metrics_results['object_moved_rate']:.2%}") diff --git a/docs/pages/concepts/concept_overview.rst b/docs/pages/concepts/concept_overview.rst index 3f1c3e203..32af3448d 100644 --- a/docs/pages/concepts/concept_overview.rst +++ b/docs/pages/concepts/concept_overview.rst @@ -1,49 +1,46 @@ Concept Overview ================ -This section provides an overview of the core concepts in Isaac Lab Arena. +Isaac Lab Arena aims to simplify the creation of task/environment libraries. +The key to achieving that goal is the use of *composition*. +Arena environments are composed of three independent sub-pieces: -.. figure:: ../../images/isaaclab_arena_core_framework.png - :width: 100% +* **Scene**: The scene is a collection of objects, backgrounds, lights, etc. +* **Embodiment**: The robot embodiment, its physical description, observations, actions, sensors etc. +* **Task**: A definition of what is to be accomplished in the environment. + +.. figure:: ../../images/isaac_lab_arena_arch_overview.png + :width: 90% :alt: Isaac Lab Arena Workflow :align: center - IsaacLab Arena Workflow Overview - -In the core of the workflow, we have three main components, **Scene**, **Embodiment**, and **Task**. We compile most of the managers of the -manager-based RL environment from these three components. We strongly incline towards keeping these components as independent as possible. This -allows us to reuse the components in different environments and tasks, thus making the framework more modular and easier to extend. - -**Embodiment** - -Embodiments define robot-specific configurations and behaviors. They provide a modular way to integrate different robots into environments, -encapsulating kinematics, control actions, observations, terminations and camera systems. See :doc:`./concept_embodiment_design` for more details. - -**Task** - -Tasks define objectives, success criteria, and behavior logic for environments. They provide configurations for termination conditions, event handling, -metrics collection, and mimic components. See :doc:`./concept_tasks_design` for more details. - -**Scene** - -Scenes manage collections of assets that define the physical environment for simulation. They provide a unified interface for composing backgrounds, -objects, and interactive elements. See :doc:`./concept_scene_design` for more details. + The architecture of Isaac Lab Arena. Evaluation environments are composed of + three independent sub-pieces: Scene, Embodiment, and Task. These sub-pieces + are passed to the Environment Compiler to produce an Isaac Lab manager-based + environment. -When combining these three components we create the observation, action, event, termination, metrics, mimic components of the manager-based RL environment. -For more details on how to combine these components, see :doc:`./concept_environment_compilation`. +In code, this looks like: -Other components of interest are the **Affordances** and the **Metrics**. +.. code-block:: python -**Affordances** + scene = Scene(assets=[background, pick_up_object]) -Affordances define what interactions objects can perform - opening doors, pressing buttons, manipulating objects. -They provide standardized interfaces that integrate with tasks and embodiments. See :doc:`./concept_affordances_design` for more details. + environment = IsaacLabArenaEnvironment( + name="manipulation_task", + embodiment=embodiment, + scene=scene, + task=task, + teleop_device=teleop_device, # optional + ) -**Metrics** + env = ArenaEnvBuilder(environment, args_cli).make_registered() -Metrics define the performance evaluation metrics for the environment. -Some metrics are independent of the task and the embodiment, such as the success rate metric, -while others are task-specific, such as open door rate metric. See :doc:`./concept_metrics_design` for more details. +``ArenaEnvBuilder`` compiles the scene, embodiment, and task configurations into +a single Isaac Lab ``ManagerBasedRLEnv``. The ``make_registered()`` call registers +the environment with the gym registry and returns it ready to run. -These components together with teleoperation devices form the manager-based RL environment. -See :doc:`./concept_environment_design` for more details on how these components are easily combined to create our environments. +Because these pieces are independent, they can be reused and combined freely. +The same pick-and-place task works with any robot on any scene: swap the Franka +for a G1, or the kitchen for a warehouse, with no changes to the task. +This moves us from a library of monolithic environment descriptions to a library +of environment *parts*. diff --git a/docs/pages/concepts/concept_policy_design.rst b/docs/pages/concepts/concept_policy_design.rst deleted file mode 100644 index cd0532fbf..000000000 --- a/docs/pages/concepts/concept_policy_design.rst +++ /dev/null @@ -1,138 +0,0 @@ -Policy Design -============= - -Policies define how agents generate actions from observations. -The policy system provides a registry system for managing different policies. - -For how to run policies in practice (single job, sequential batch, or -server–client), see :doc:`Evaluation Types <../policy_evaluation/evaluation_types>`. - -Core Architecture ------------------ - -Policies use the ``PolicyBase`` abstract class: - -.. code-block:: python - - class PolicyBase(ABC): - @abstractmethod - def get_action(self, env: gym.Env, observation: GymSpacesDict) -> torch.Tensor: - """Compute an action given the environment and observation. - - Args: - env: The environment instance - observation: Observation dictionary from the environment - - Returns: - torch.Tensor: The action to take - """ - -This enables seamless swapping between different policy implementations while maintaining consistent integration with IsaacLab Arena environments. - -Policies in Detail ------------------- - -**Policy Categories** - Three main types addressing different use cases: - - - **Zero Action Policy**: Baseline that returns zero actions for environment testing and physics validation - - **Replay Action Policy**: Replays pre-recorded demonstrations from HDF5 datasets for analysis and evaluation - - **GR00T Neural Policies**: Advanced foundation models for visuomotor control with multi-modal inputs - -**Implementation Patterns** - Common policy implementation approaches: - - - **Stateless Policies**: Pure functions from observations to actions (ZeroActionPolicy) - - **Dataset-Driven**: Load and replay recorded trajectories (ReplayActionPolicy) - - **Neural Networks**: Process visual and proprioceptive inputs for learned behaviors (GR00T policies) - -Environment Integration ------------------------ - -.. code-block:: python - - # Policy creation from CLI arguments - arena_builder = get_arena_builder_from_cli(args) - env = arena_builder.make_registered() - policy, num_steps = create_policy(args) - - # Standard execution loop - obs, _ = env.reset() - for step in range(num_steps): - with torch.inference_mode(): - actions = policy.get_action(env, obs) - obs, rewards, terminated, truncated, info = env.step(actions) - if terminated.any() or truncated.any(): - obs, _ = env.reset() - -Usage Examples --------------- - -**Baseline Testing** - -.. tab-set:: - - .. tab-item:: Single GPU - - .. code-block:: bash - - # Zero action policy for environment validation - python isaaclab_arena/evaluation/policy_runner.py --policy_type zero_action --num_steps 1000 kitchen_pick_and_place --object cracker_box - - .. tab-item:: Distribute Multi-GPU - - .. code-block:: bash - - # Zero action policy for environment validation - # --nproc_per_node represents the number of available GPUs - python -m torch.distributed.run --nnode=1 --nproc_per_node=2 isaaclab_arena/evaluation/policy_runner.py --distributed --headless --policy_type zero_action --num_steps 1000 kitchen_pick_and_place --object cracker_box - -**Demonstration Replay** - -.. tab-set:: - - .. tab-item:: Single GPU - - .. code-block:: bash - - # Replay recorded demonstrations - python isaaclab_arena/evaluation/policy_runner.py --policy_type replay --replay_file_path demos.h5 kitchen_pick_and_place --object cracker_box - - .. tab-item:: Distribute Multi-GPU - - .. code-block:: bash - - # Replay recorded demonstrations - # --nproc_per_node represents the number of available GPUs - python -m torch.distributed.run --nnode=1 --nproc_per_node=2 isaaclab_arena/evaluation/policy_runner.py --distributed --headless --policy_type replay --replay_file_path demos.h5 kitchen_pick_and_place --object cracker_box - -**Neural Policy Execution** - -.. tab-set:: - - .. tab-item:: Single GPU - - .. code-block:: bash - - # GR00T foundation model deployment - python isaaclab_arena/evaluation/policy_runner.py --policy_type isaaclab_arena_gr00t.policy.gr00t_closedloop_policy.Gr00tClosedloopPolicy --policy_config_yaml_path config.yaml - - .. tab-item:: Distribute Multi-GPU - - .. code-block:: bash - - # GR00T foundation model deployment - # --nproc_per_node represents the number of available GPUs - python -m torch.distributed.run --nnode=1 --nproc_per_node=2 isaaclab_arena/evaluation/policy_runner.py --distributed --headless --policy_type isaaclab_arena_gr00t.policy.gr00t_closedloop_policy.Gr00tClosedloopPolicy --policy_config_yaml_path config.yaml - -**Custom Policy Integration** - -.. code-block:: python - - class CustomPolicy(PolicyBase): - def get_action(self, env, observation): - # Custom control logic - return torch.zeros(env.action_space.shape) - - policy = CustomPolicy() - actions = policy.get_action(environment, observations) diff --git a/docs/pages/concepts/concept_scene_design.rst b/docs/pages/concepts/concept_scene_design.rst deleted file mode 100644 index 27b6b8e8b..000000000 --- a/docs/pages/concepts/concept_scene_design.rst +++ /dev/null @@ -1,103 +0,0 @@ -Scene Design -============ - -Scenes manage collections of assets that define the physical environment for simulation. They provide a unified interface for composing backgrounds, objects, and interactive elements. - -Core Architecture ------------------ - -Scenes use the ``Scene`` class that manages asset collections: - -.. code-block:: python - - class Scene: - def __init__(self, assets: list[Asset] | None = None): - self.assets: dict[str, Asset] = {} - - def add_asset(self, asset: Asset): - """Add single asset to scene.""" - self.assets[asset.name] = asset - - def get_scene_cfg(self) -> Any: - """Generate Isaac Lab scene configuration from assets.""" - -Scenes automatically aggregate asset configurations into Isaac Lab-compatible scene configurations while maintaining asset relationships and spatial organization. - -Scenes in Detail ----------------- - -The main method in the scene class is ``get_scene_cfg`` which returns a configclass containing all the scene elements. - -It reads all the registered assets and their cfgs and combines them into a configclass. - -.. code-block:: python - - def get_scene_cfg(self) -> Any: - """Returns a configclass containing all the scene elements.""" - # Combine the configs into a configclass. - fields: list[tuple[str, type, AssetCfg]] = [] - for asset in self.assets.values(): - fields.append((asset.name, type(asset.object_cfg), asset.object_cfg)) - NewConfigClass = make_configclass("SceneCfg", fields) - new_config_class = NewConfigClass() - return new_config_class - - -Environment Integration ------------------------ - -.. code-block:: python - - # Asset creation and positioning - background = asset_registry.get_asset_by_name("kitchen")() - pick_object = asset_registry.get_asset_by_name("cracker_box")() - pick_object.set_initial_pose(Pose(position_xyz=(0.4, 0.0, 0.1))) - - # Scene composition - scene = Scene(assets=[background, pick_object]) - - # Environment integration - environment = IsaacLabArenaEnvironment( - name="manipulation_task", - embodiment=embodiment, - scene=scene, # Physical environment layout - task=task, - teleop_device=teleop_device - ) - -Usage Examples --------------- - -**Kitchen Pick and Place** - -.. code-block:: python - - background = asset_registry.get_asset_by_name("kitchen")() - mustard_bottle = asset_registry.get_asset_by_name("mustard_bottle")() - mustard_bottle.set_initial_pose(Pose(position_xyz=(0.4, 0.0, 0.1))) - - scene = Scene(assets=[background, mustard_bottle]) - -**Microwave Interaction** - -.. code-block:: python - - kitchen = asset_registry.get_asset_by_name("kitchen")() - microwave = asset_registry.get_asset_by_name("microwave")() - microwave.set_initial_pose(Pose(position_xyz=(0.8, 0.0, 0.23))) - - scene = Scene(assets=[kitchen, microwave]) - -**Object References** - -.. code-block:: python - - # Reference elements within larger scene assets - destination = ObjectReference( - name="kitchen_drawer", - prim_path="{ENV_REGEX_NS}/kitchen/Cabinet_B_02", - parent_asset=kitchen, - object_type=ObjectType.RIGID - ) - - scene = Scene(assets=[kitchen, destination]) diff --git a/docs/pages/concepts/concept_tasks_design.rst b/docs/pages/concepts/concept_tasks_design.rst deleted file mode 100644 index a0cfbd60f..000000000 --- a/docs/pages/concepts/concept_tasks_design.rst +++ /dev/null @@ -1,115 +0,0 @@ -Tasks Design -============ - -Tasks define objectives, success criteria, and behavior logic for environments. They provide configurations for termination conditions, event handling, metrics collection, and demonstration generation. - -Core Architecture ------------------ - -Tasks use the ``TaskBase`` abstract class: - -.. code-block:: python - - class TaskBase(ABC): - @abstractmethod - def get_scene_cfg(self) -> Any: - """Additional scene configurations.""" - - @abstractmethod - def get_termination_cfg(self) -> Any: - """Success and failure conditions.""" - - @abstractmethod - def get_events_cfg(self) -> Any: - """Reset and randomization handling.""" - - @abstractmethod - def get_metrics(self) -> list[MetricBase]: - """Performance evaluation metrics.""" - - @abstractmethod - def get_mimic_env_cfg(self, arm_mode: ArmMode) -> Any: - """Demonstration generation configuration.""" - -Tasks in Detail ---------------- - -**Configuration Components** - Tasks contribute to multiple Isaac Lab manager configurations: - - - **Scene Configuration**: Additional sensors and physics components (contact sensors, object interactions) - - **Termination Configuration**: Success and failure conditions defining episode completion - - **Event Configuration**: Reset and randomization logic for consistent episode initialization - - **Metrics Integration**: Performance evaluation and data collection systems - - **Mimic Configuration**: Demonstration generation with subtask decomposition - -**Available Tasks** - Built-in task implementations for common scenarios: - - - **PickAndPlaceTask**: Move objects between locations with contact-based success detection - - **OpenDoorTask**: Affordance-based interaction with openable objects and thresholds - - **G1LocomanipPickAndPlaceTask**: Combined locomotion and manipulation for humanoid robots - -**RL Task Design** - RL tasks extend their IL counterparts by adding reinforcement learning components: - - - **Inheritance**: RL tasks inherit from IL task base classes (e.g., ``LiftObjectTaskRL`` extends ``LiftObjectTask``) - - **Commands**: Introduce command managers that sample random target goals each episode - - **Rewards**: Define dense reward functions for desired behaviors (reaching, grasping, lifting, target achievement) - - **Observations**: Configure state observations to include object state, and goal commands - - **Success Function**: Override the success function to use the command manager goals for success detection. We just return false during training. - - -Environment Integration ------------------------ - -.. code-block:: python - - # Task construction with scene assets - pick_object = asset_registry.get_asset_by_name("cracker_box")() - destination = ObjectReference("kitchen_drawer", parent_asset=kitchen) - - task = PickAndPlaceTask( - pick_up_object=pick_object, - destination_location=destination, - background_scene=kitchen - ) - - # Environment composition - environment = IsaacLabArenaEnvironment( - name="kitchen_manipulation", - embodiment=embodiment, - scene=scene, - task=task, # Defines objectives and success criteria - teleop_device=teleop_device - ) - - # Automatic configuration integration - env = env_builder.make_registered() # Task configs merged automatically - -Usage Examples --------------- - -**Pick and Place Task** - -.. code-block:: python - - pick_object = asset_registry.get_asset_by_name("mustard_bottle")() - destination = ObjectReference("kitchen_drawer", parent_asset=kitchen) - - task = PickAndPlaceTask(pick_object, destination, kitchen) - -**Humanoid Locomotion** - -.. code-block:: python - - pick_object = asset_registry.get_asset_by_name("cracker_box")() - destination_bin = asset_registry.get_asset_by_name("sorting_bin")() - - task = G1LocomanipPickAndPlaceTask(pick_object, destination_bin, galileo_scene) - -Sequential Tasks ----------------- - -Tasks can be composed sequentially to form longer horizon, more complex tasks. -See :doc:`./concept_sequential_tasks_design` for more details. diff --git a/docs/pages/concepts/concept_teleop_devices_design.rst b/docs/pages/concepts/concept_teleop_devices_design.rst deleted file mode 100644 index f3f668d85..000000000 --- a/docs/pages/concepts/concept_teleop_devices_design.rst +++ /dev/null @@ -1,113 +0,0 @@ -Teleop Devices Design -====================== - -Teleop devices defined in Arena are a thin wrapper around the Isaac Lab teleop devices. -We define this wrapper to allow for easy registration and discovery of teleop devices. - -Core Architecture ------------------ - -Teleop devices use the ``TeleopDeviceBase`` abstract class with automatic registration: - -.. code-block:: python - - class TeleopDeviceBase(ABC): - name: str | None = None - - @abstractmethod - def get_device_cfg(self, pipeline_builder=None, embodiment=None): - """Return an Isaac Lab device config for the specific device.""" - - @register_device - class KeyboardCfg(TeleopDeviceBase): - name = "keyboard" - - def get_device_cfg(self, pipeline_builder=None, embodiment=None): - return Se3KeyboardCfg(pos_sensitivity=0.05, rot_sensitivity=0.05) - -Devices are automatically discovered through decorator-based registration and provide Isaac Lab-compatible configurations. - -For XR teleoperation, the ``OpenXRCfg`` device produces an ``IsaacTeleopCfg`` that -references a **pipeline builder** -- a callable that constructs an ``isaacteleop`` -retargeting pipeline graph. This pipeline converts XR tracking data (hand poses, -controller inputs) into robot action tensors. ``OpenXRCfg.get_device_cfg`` raises -``ValueError`` if no pipeline builder is provided. - -.. code-block:: python - - @register_device - class OpenXRCfg(TeleopDeviceBase): - name = "openxr" - - def get_device_cfg(self, pipeline_builder=None, embodiment=None) -> IsaacTeleopCfg: - return IsaacTeleopCfg( - pipeline_builder=pipeline_builder, - xr_cfg=embodiment.get_xr_cfg(), - ) - -Teleop Devices in Detail -------------------------- - -**Available Devices** - Three primary input modalities for different use cases: - - - **Keyboard**: WASD-style SE3 manipulation with configurable sensitivity parameters - - **SpaceMouse**: 6DOF precise spatial control for manipulation tasks - - **XR Hand Tracking**: Isaac Teleop pipeline-based hand tracking for humanoid control, - using ``isaacteleop`` retargeters (Se3AbsRetargeter, DexHandRetargeter, etc.) to map - XR hand poses to robot joint commands - -**Registration and Discovery** - Decorator-based system for automatic device management: - - - **@register_device**: Automatic registration during module import - - **Device Registry**: Central discovery mechanism for available devices - - **@register_retargeter**: Associates a pipeline builder with a (device, embodiment) pair - -Environment Integration ------------------------ - -.. code-block:: python - - # Device selection during environment creation - teleop_device = device_registry.get_device_by_name(args_cli.teleop_device)() - - # Environment composition with teleop support - environment = IsaacLabArenaEnvironment( - name="manipulation_task", - embodiment=embodiment, - scene=scene, - task=task, - teleop_device=teleop_device, # Optional human control interface - ) - - # Automatic device configuration and integration - env = env_builder.make_registered() # Handles device setup internally - -For XR devices, the environment builder sets ``isaac_teleop`` on the env config -(an ``IsaacTeleopCfg``). For keyboard/spacemouse devices, standard Isaac Lab -device configs are used. - -Usage Examples --------------- - -**Keyboard Teleoperation** - -.. code-block:: bash - - # Basic keyboard control - python isaaclab_arena/scripts/imitation_learning/teleop.py --viz kit --teleop_device keyboard kitchen_pick_and_place - -**SpaceMouse Control** - -.. code-block:: bash - - # Precise manipulation with SpaceMouse - python isaaclab_arena/scripts/imitation_learning/teleop.py --viz kit--teleop_device spacemouse kitchen_pick_and_place --sensitivity 2.0 - -**Hand Tracking** - -.. code-block:: bash - - # XR hand tracking for humanoid control (requires CloudXR runtime via Isaac Teleop) - python isaaclab_arena/scripts/imitation_learning/teleop.py --viz kit --teleop_device openxr gr1_open_microwave diff --git a/docs/pages/concepts/embodiment/concept_teleop_devices_design.rst b/docs/pages/concepts/embodiment/concept_teleop_devices_design.rst new file mode 100644 index 000000000..4d3d23132 --- /dev/null +++ b/docs/pages/concepts/embodiment/concept_teleop_devices_design.rst @@ -0,0 +1,63 @@ +Teleop Devices +============== + +A teleop device is the human input interface for teleoperation — it translates +operator input (keyboard, SpaceMouse, or XR hand tracking) into robot commands +during demonstration collection. + +Arena's teleop devices are a thin wrapper around Isaac Lab's built-in devices, +added so they can be registered by name and discovered from the device registry, +the same way assets and embodiments are. + +.. code-block:: python + + from isaaclab_arena.assets.register import register_device + + @register_device + class KeyboardCfg(TeleopDeviceBase): + name = "keyboard" + + def get_device_cfg(self, pipeline_builder=None, embodiment=None) -> Se3KeyboardCfg: + return Se3KeyboardCfg(pos_sensitivity=0.05, rot_sensitivity=0.05) + +The ``@register_device`` decorator makes the device available by name. The wrapper +implements a single method, ``get_device_cfg()``, that returns the underlying +Isaac Lab device configuration. + +To add teleoperation to an environment, pick a device by name and pass it in: + +.. code-block:: python + + teleop_device = device_registry.get_device_by_name("keyboard")() + + environment = IsaacLabArenaEnvironment( + name="kitchen_pick_and_place", + embodiment=embodiment, + scene=scene, + task=task, + teleop_device=teleop_device, + ) + + env = ArenaEnvBuilder(environment, args_cli).make_registered() + +``teleop_device`` is optional — omit it for policy evaluation and include it +when collecting demonstrations. + +Available devices +----------------- + +**keyboard** + WASD-style SE3 control with configurable sensitivity. Good for quick setup + and simple manipulation tasks. + +**spacemouse** + 6-DOF spatial control. More precise than the keyboard; suitable for + fine manipulation. + +**openxr** + XR hand tracking via the ``isaacteleop`` retargeting pipeline. Maps hand + poses and controller input to robot joint commands. + + For a full walkthrough — collecting demonstrations on a static manipulation + task using an Apple Vision Pro or Meta Quest — see + :doc:`../../example_workflows/static_manipulation/step_2_teleoperation`. diff --git a/docs/pages/concepts/embodiment/index.rst b/docs/pages/concepts/embodiment/index.rst new file mode 100644 index 000000000..f8a702f9a --- /dev/null +++ b/docs/pages/concepts/embodiment/index.rst @@ -0,0 +1,50 @@ +Embodiment +========== + +An embodiment is the robot: its physical description, control interface, sensors, and cameras. +Because the embodiment is independent of the scene and task, you can swap the robot +without touching anything else. The same pick-and-place task works with a Franka or a G1. + +.. code-block:: python + + embodiment = asset_registry.get_asset_by_name("franka_ik")(enable_cameras=True) + + environment = IsaacLabArenaEnvironment( + name="kitchen_pick_and_place", + embodiment=embodiment, + scene=scene, + task=task, + ) + +Walkthrough +----------- + +We load the embodiment from the registry, passing any options to its constructor: + +.. code-block:: python + + embodiment = asset_registry.get_asset_by_name("franka_ik")(enable_cameras=True) + embodiment.set_initial_pose(Pose(position_xyz=(0.5, 0.0, 0.0), rotation_xyzw=(0.0, 0.0, 0.0, 1.0))) + +The initial pose places the robot in world frame — relative to the scene origin. +This is usually set to position the robot in front of the workspace. + +Available embodiments include the Franka Panda, Unitree G1, GR1T2, DROID, and others. +Each has one or more control variants registered separately. +For example, ``franka_ik`` uses differential IK control, +while ``franka_joint_pos`` uses direct joint position control. + +**Cameras** + +Passing ``enable_cameras=True`` adds the robot's onboard cameras to the observation space. +This is required for any policy that takes image observations, such as GR00T. + +More details +------------ + +The rest of this section covers further details of the embodiment component. + +.. toctree:: + :maxdepth: 1 + + concept_teleop_devices_design diff --git a/docs/pages/policy_evaluation/evaluation_types.rst b/docs/pages/concepts/policy/concept_evaluation_types.rst similarity index 94% rename from docs/pages/policy_evaluation/evaluation_types.rst rename to docs/pages/concepts/policy/concept_evaluation_types.rst index 9608e6b99..e59b2f73a 100644 --- a/docs/pages/policy_evaluation/evaluation_types.rst +++ b/docs/pages/concepts/policy/concept_evaluation_types.rst @@ -5,10 +5,10 @@ Isaac Lab Arena supports three main ways to run policy evaluation: a single-job **policy runner** (single or multi-GPU), a **sequential batch eval runner** for multiple jobs in one process, and a **server–client** setup for remote policies. This section summarizes when to use each and how they work. Each section below links -to the relevant concept docs: :doc:`Policy Design <../concepts/concept_policy_design>`, -:doc:`Environment Design <../concepts/concept_environment_design>`, -:doc:`Metrics Design <../concepts/concept_metrics_design>`, and -:doc:`Remote Policies Design <../concepts/concept_remote_policies_design>`. +to the relevant concept docs: :doc:`Policy Design `, +:doc:`Environment Design <../concept_overview>`, +:doc:`Metrics Design <../task/concept_metrics_design>`, and +:doc:`Remote Policies Design `. Summary ------- @@ -43,7 +43,7 @@ choice for ad-hoc runs, debugging, or when you want to drive one scenario with full control over CLI arguments. **Design context:** For how policies are defined and integrated with environments, -see :doc:`Policy Design <../concepts/concept_policy_design>`. +see :doc:`Policy Design `. **Features:** @@ -139,9 +139,9 @@ configurations (e.g. many objects or tasks) without launching multiple processes by hand. Persistence of the simulation application is maintained between jobs. **Design context:** For how environments are composed and how metrics are -defined and computed, see :doc:`Environment Design <../concepts/concept_environment_design>` -and :doc:`Metrics Design <../concepts/concept_metrics_design>`. Policies used per job -follow :doc:`Policy Design <../concepts/concept_policy_design>`. +defined and computed, see :doc:`Environment Design <../concept_overview>` +and :doc:`Metrics Design <../task/concept_metrics_design>`. Policies used per job +follow :doc:`Policy Design `. **Features:** @@ -235,7 +235,7 @@ side, but the policy is a **client-side remote policy** that talks to a **Design context:** For the full remote policy design, protocol, and how to implement custom server-side and client-side policies, see -:doc:`Remote Policies Design <../concepts/concept_remote_policies_design>`. +:doc:`Remote Policies Design `. **Features:** diff --git a/docs/pages/concepts/concept_remote_policies_design.rst b/docs/pages/concepts/policy/concept_remote_policies_design.rst similarity index 98% rename from docs/pages/concepts/concept_remote_policies_design.rst rename to docs/pages/concepts/policy/concept_remote_policies_design.rst index f64208022..cc56e5d86 100644 --- a/docs/pages/concepts/concept_remote_policies_design.rst +++ b/docs/pages/concepts/policy/concept_remote_policies_design.rst @@ -1,12 +1,12 @@ -Remote Policies Design -====================== +Remote Policies +=============== This section describes the generic remote policy interface in Isaac Lab Arena, how it is structured around server-side and client-side policies, and how to plug in your own remote policies. For running evaluation with a remote policy (server–client), see -:doc:`Evaluation Types <../policy_evaluation/evaluation_types>`. +:doc:`Evaluation Types `. Overview -------- @@ -45,7 +45,7 @@ policy follows a different pattern, you can implement your own ``ClientSidePolicy`` subclass to adapt the raw actions from the remote model to the environment. -.. figure:: ../../images/remote_policy_design.png +.. figure:: ../../../images/remote_policy_design.png :align: center :width: 100% diff --git a/docs/pages/concepts/policy/index.rst b/docs/pages/concepts/policy/index.rst new file mode 100644 index 000000000..1f074bfc0 --- /dev/null +++ b/docs/pages/concepts/policy/index.rst @@ -0,0 +1,94 @@ +Policy +====== + +A policy in Arena is a standard interface between your model and the evaluation +pipeline. You implement one method — ``get_action(env, obs)`` — and the policy +plugs into both the single-job runner and the batch eval runner without any +changes to either. In bare IsaacLab you would write an ad-hoc inference loop +for each model; Arena's ``PolicyBase`` gives a consistent contract that all +runners depend on. + +.. code-block:: python + + policy = ZeroActionPolicy(config=ZeroActionPolicyArgs()) + obs, _ = env.reset() + action = policy.get_action(env, obs) + +Built-in policies +----------------- + +Arena ships with four policies: + +**ZeroActionPolicy** (``"zero_action"``) + Returns a zero-filled action tensor. Useful for validating an environment + without a trained model. + +**ReplayActionPolicy** (``"replay"``) + Replays actions from a recorded episode stored in an HDF5 file. + +**RslRlActionPolicy** (``"rsl_rl"``) + Runs inference with a trained RSL-RL checkpoint. Loads the checkpoint and + its accompanying ``params/agent.yaml`` automatically. + + +Writing a custom policy +----------------------- + +Subclass ``PolicyBase``, set a ``name``, decorate with ``@register_policy``, +and implement ``get_action``: + +.. code-block:: python + + import gymnasium as gym + import torch + from gymnasium.spaces.dict import Dict as GymSpacesDict + + from isaaclab_arena.assets.register import register_policy + from isaaclab_arena.policy.policy_base import PolicyBase + + + @register_policy + class MyPolicy(PolicyBase): + name = "my_policy" + + def __init__(self, config): + super().__init__(config) + + def get_action(self, env: gym.Env, observation: GymSpacesDict) -> torch.Tensor: + # Your model inference here + return torch.zeros(env.action_space.shape, device=torch.device(env.unwrapped.device)) + + @staticmethod + def add_args_to_parser(parser): + # Add any CLI arguments your policy needs, then return the parser + return parser + + @staticmethod + def from_args(args): + return MyPolicy(config=None) + +Once registered, select the policy by name on the command line: + +.. code-block:: bash + + python isaaclab_arena/evaluation/policy_runner.py \ + --policy_type my_policy \ + ... + +For policies not registered by name, pass a dotted Python path instead +(e.g. ``--policy_type mypackage.mypolicy.MyPolicy``). The runner will +import and instantiate the class directly. + +To use a custom policy in the batch eval runner's JSON config, define a +``config_class`` dataclass on the policy and implement ``from_dict()``. +This lets the runner instantiate the policy from a plain dict without +going through argparse. See :doc:`concept_evaluation_types` for details. + +More details +------------ + +.. toctree:: + :maxdepth: 1 + + concept_evaluation_types + concept_remote_policies_design diff --git a/docs/pages/concepts/scene/concept_affordances_design.rst b/docs/pages/concepts/scene/concept_affordances_design.rst new file mode 100644 index 000000000..8268ce34f --- /dev/null +++ b/docs/pages/concepts/scene/concept_affordances_design.rst @@ -0,0 +1,46 @@ +Affordances +=========== + +An affordance is an interaction that an object makes available to the robot — +opening a door, pressing a button, turning a knob. +By attaching affordances to objects, Arena gives tasks a standard interface +to interact with them, regardless of the specific object. + +.. figure:: ../../../images/affordances_objects.png + :width: 100% + :alt: Examples of Pressable and Openable objects + :align: center + + Two examples of affordances. A drill and coffee machine are **Pressable** + (``is_pressed()``, ``press()``); a microwave and cardboard box are **Openable** + (``is_open()``, ``close()``). + +How an object gets an affordance +--------------------------------- + +Affordances are added to an object through multiple inheritance. +The microwave inherits from both ``LibraryObject`` and ``Openable``, +and declares the joint name that the affordance controls: + +.. code-block:: python + + @register_asset + class Microwave(LibraryObject, Openable): + name = "microwave" + tags = ["object", "openable"] + object_type = ObjectType.ARTICULATION + + # Openable affordance parameters + openable_joint_name = "microjoint" + openable_threshold = 0.5 # open if joint > threshold, closed otherwise + +The ``Openable`` mixin implements ``is_open()`` and ``close()`` using the joint +name provided — no further setup needed. + +Why this matters +---------------- + +Because tasks are written against the affordance interface rather than a specific object, +the same task works with any object that has the right affordance. +``OpenDoorTask`` works with the microwave, a fridge, a cabinet — any ``Openable``. +This is what makes tasks modular and reusable across different scenes. diff --git a/docs/pages/concepts/scene/concept_assets_design.rst b/docs/pages/concepts/scene/concept_assets_design.rst new file mode 100644 index 000000000..9e780a6d3 --- /dev/null +++ b/docs/pages/concepts/scene/concept_assets_design.rst @@ -0,0 +1,81 @@ +Assets +====== + +Assets are the objects and backgrounds that make up a scene. +Arena ships with a set of assets ready to use by name, +and new assets can be added by registering them in the asset library. + +.. code-block:: python + + background = asset_registry.get_asset_by_name("kitchen")() + cracker_box = asset_registry.get_asset_by_name("cracker_box")() + +Registering a new asset +----------------------- + +To add a new object, subclass ``LibraryObject``, provide the USD path and object type, +and decorate it with ``@register_asset``: + +.. code-block:: python + + @register_asset + class MyObject(LibraryObject): + name = "my_object" + tags = ["object", "graspable"] + usd_path = "path/to/my_object.usd" + object_type = ObjectType.RIGID + +Once registered, the object is available in the registry like any other asset: + +.. code-block:: python + + obj = asset_registry.get_asset_by_name("my_object")() + +Assets can also be tagged to make them discoverable by category: + +.. code-block:: python + + # All graspable objects + objects = asset_registry.get_assets_by_tag("graspable") + + # A random graspable object + obj = asset_registry.get_random_asset_by_tag("graspable")() + +Useful tags include ``"graspable"``, ``"openable"``, ``"pressable"``, and ``"background"``. +Assets can have multiple tags — for example, a fruit is tagged both ``"graspable"`` and ``"food"``. + +Object types +------------ + +Every asset has an object type that determines how it is simulated: + +- **RIGID** — a single rigid body (boxes, bottles, tools, furniture). +- **ARTICULATION** — a multi-body object with joints (robots, doors, drawers, appliances). +- **BASE** — no physics; used for static backgrounds and markers. + +Object references +----------------- + +A background asset like a kitchen is a single USD file containing many prims: +countertops, shelves, drawers, and so on. To use one of these internal prims +as a destination or interaction target (e.g. "place the object on the counter"), +you use an ``ObjectReference``. + +.. code-block:: python + + kitchen = asset_registry.get_asset_by_name("kitchen")() + + counter = ObjectReference( + name="kitchen_counter", + prim_path="{ENV_REGEX_NS}/kitchen/counter_right_main_group/top_geometry", + parent_asset=kitchen, + ) + + task = PickAndPlaceTask( + pick_up_object=cracker_box, + destination_location=counter, + background_scene=kitchen, + ) + +The ``parent_asset`` tells the environment which spawned USD the prim path belongs to. +The prim path uses ``{ENV_REGEX_NS}`` so it resolves correctly across parallel environments. diff --git a/docs/pages/concepts/scene/index.rst b/docs/pages/concepts/scene/index.rst new file mode 100644 index 000000000..39a688095 --- /dev/null +++ b/docs/pages/concepts/scene/index.rst @@ -0,0 +1,36 @@ +Scene +===== + +A scene is a collection of assets. +It defines the physical environment the robot operates in, and because it +is independent of the robot and task, you can swap objects or backgrounds +without touching the task or embodiment. + +.. code-block:: python + + background = asset_registry.get_asset_by_name("kitchen")() + pick_object = asset_registry.get_asset_by_name("cracker_box")() + + pick_object.set_initial_pose(Pose(position_xyz=(0.4, 0.0, 0.1))) + + scene = Scene(assets=[background, pick_object]) + + environment = IsaacLabArenaEnvironment( + name="my_scene", + scene=scene, + ) + +Assets are loaded from the asset registry by name. An asset can be a +background, a rigid object, or a set of objects (``RigidObjectSet``). +Assets can also carry affordances (e.g. ``Openable``, ``Placeable``) that +describe how they can be interacted with, which is what allows tasks to +work with any compatible object. + +More details +------------ + +.. toctree:: + :maxdepth: 1 + + concept_assets_design + concept_affordances_design diff --git a/docs/pages/concepts/task/concept_metrics_design.rst b/docs/pages/concepts/task/concept_metrics_design.rst new file mode 100644 index 000000000..32281b713 --- /dev/null +++ b/docs/pages/concepts/task/concept_metrics_design.rst @@ -0,0 +1,41 @@ +Metrics +======= + +A metric is a quantity that is reported at the end of an evaluation, that quantifies +some aspect of a policy's performance on the task. +In Isaac Lab Arena, metrics are task-specific. A task defines the metrics that should +be calculated during the evaluation of that task. +This design means that metrics can be defined once in the task and +they are automatically applied to every environment that uses that task. + +Under the hood, a metric does two things: + +* **Recording** — The metric records the quantity during each episode of policy execution. +* **Computing** The metric computes the final value from the recorded data, typically by reducing the recordings to a scalar. + +In the code below we show how to inspect the metrics defined by the ``PickAndPlaceTask``. + +.. code-block:: python + + task = PickAndPlaceTask(pick_object, destination, kitchen) + task.get_metrics() + # → [SuccessRateMetric(), ObjectMovedRateMetric(pick_object)] + +Example: ObjectMovedRateMetric +------------------------------ + +Here we provide an example of how the ``ObjectMovedRateMetric`` is implemented. +The ``ObjectMovedRateMetric`` implements the recording and computing steps described above +in the following way: + +* **Recording** During simulation ``ObjectMovedRateMetric`` records the + object's velocity vector (a 3D vector) at every simulation step. +* **Computing** After the rollout completes, the ``ObjectMovedRateMetric`` process + the velocity history for each episode. It first computes the magnitude of the velocity + vector for each step in an episode. + Then it checks if the magnitude is greater than a threshold. If it is, the object is + considered moved in this episode. + Finally, it computes the fraction of episodes in which the object was moved. + +You do not need to manage any of this manually — it is all wired up automatically +in the Arena Environment Builder when the environment is compiled from the task. diff --git a/docs/pages/concepts/task/concept_rl_tasks_design.rst b/docs/pages/concepts/task/concept_rl_tasks_design.rst new file mode 100644 index 000000000..42dccd668 --- /dev/null +++ b/docs/pages/concepts/task/concept_rl_tasks_design.rst @@ -0,0 +1,65 @@ +RL Tasks +======== + +RL tasks extend their imitation learning counterparts with the components +needed for reinforcement learning training: a command manager that samples +a new goal each episode, reward terms, and goal-conditioned observations. + +The pattern is straightforward — an RL task subclasses the corresponding IL task, +and implements the RL-specific parts: + +.. code-block:: python + + class LiftObjectTaskRL(LiftObjectTask): + + def __init__(self): + super().__init__() + + def get_rewards_cfg(self): + pass + + def get_commands_cfg(self): + pass + +This means the RL task inherits everything from the IL task (scene config, +termination conditions, metrics) and adds the RL-specific parts on top. +Note the the RL task is also likely to *modify* the IL task's configuration. +For example, adding privileged information to the observations. + +Usage +----- + +.. code-block:: python + + lift_object = asset_registry.get_asset_by_name("cracker_box")() + + task = LiftObjectTaskRL( + lift_object=lift_object, + background_scene=table, + embodiment=embodiment, + ) + +``LiftObjectTaskRL`` adds a command manager that samples a random target +position each episode, reward terms for reaching the object, lifting it, +and tracking the goal, and goal-conditioned observations that tell the +policy where the target is. + +See :doc:`../../example_workflows/reinforcement_learning/index` for a complete example +for how to use an RL task. + +Training vs. evaluation mode +----------------------------- + +RL tasks have an ``rl_training_mode`` flag (default ``True``). +During training, success does not terminate the episode — the robot +keeps acting until the time limit. This is standard practice to avoid +sparse termination signals early in training. +For evaluation, set ``rl_training_mode=False`` so episodes end on success: + +.. code-block:: python + + # Training + task = LiftObjectTaskRL(lift_object, table, embodiment, rl_training_mode=True) + + # Evaluation + task = LiftObjectTaskRL(lift_object, table, embodiment, rl_training_mode=False) diff --git a/docs/pages/concepts/concept_sequential_tasks_design.rst b/docs/pages/concepts/task/concept_sequential_tasks_design.rst similarity index 66% rename from docs/pages/concepts/concept_sequential_tasks_design.rst rename to docs/pages/concepts/task/concept_sequential_tasks_design.rst index a889e3b3b..9821128b1 100644 --- a/docs/pages/concepts/concept_sequential_tasks_design.rst +++ b/docs/pages/concepts/task/concept_sequential_tasks_design.rst @@ -1,9 +1,12 @@ -Sequential Tasks Design -======================= +Sequential Tasks +================ Tasks can be composed sequentially to form longer horizon, more complex tasks using the ``SequentialTaskBase`` class. ``SequentialTaskBase`` takes a list of ``TaskBase`` instances and automatically composes them into a single task. The order of the tasks in the list determines the order in which subtasks must be completed. +Internally, the Arena Environment Builder will automatically track that each sub-task is +completed successfully in turn. +It will also automatically compose the sub-task metrics, resets etc. **Usage Example (Pick and Place Task and Close Door Task Composition)** @@ -18,6 +21,7 @@ The order of the tasks in the list determines the order in which subtasks must b sequential_task = SequentialTaskBase(subtasks=[pick_and_place_task, close_door_task]) -**Available Examples** - -- **PutAndCloseDoorTask**: Pick up and move an object to a destination location and then close a door (within **GR1PutAndCloseDoorEnvironment**). +We demonstrate the use of a sequential task in one of our workflows. +See :doc:`../../example_workflows/sequential_static_manipulation/index` to see a +sequential task is use - picking up an object and placing it in a refrigerator and then +closing the door. diff --git a/docs/pages/concepts/task/index.rst b/docs/pages/concepts/task/index.rst new file mode 100644 index 000000000..1db4cfe3b --- /dev/null +++ b/docs/pages/concepts/task/index.rst @@ -0,0 +1,55 @@ +Task +==== + +A task defines what the robot is supposed to do in the environment. +Concretely, a task specifies four things: + +- **Success condition** — when has the robot completed the task? (e.g. is the door open?) +- **Failure condition** — when should the episode end early? (e.g. has the object fallen off the table?) +- **Reset action** — how should the scene be restored at the start of each episode? (e.g. close the door) +- **Metrics** — what should be measured? (e.g. how far open did the microwave get?) + +.. code-block:: python + + microwave = asset_registry.get_asset_by_name("microwave")() + + task = OpenDoorTask(openable_object=microwave) + + environment = IsaacLabArenaEnvironment( + name="open_microwave", + embodiment=embodiment, + scene=scene, + task=task, + ) + +Tasks and affordances +--------------------- + +Tasks are defined in terms of object **affordances**, not specific objects. +``OpenDoorTask`` takes any ``Openable`` — a microwave, a fridge, a cabinet. +Its success condition calls ``openable.is_open()``, its reset calls ``openable.close()``, +and its metric tracks ``openable.get_openness()``. + +.. figure:: ../../../images/open_door_task.png + :width: 100% + :alt: OpenDoorTask defined in terms of the Openable affordance + :align: center + + ``OpenDoorTask`` is defined entirely in terms of the ``Openable`` affordance interface, + making it reusable with any openable object. + +This is what makes tasks modular — the same task works across different objects +and scenes without any changes. + +Available tasks include (but are not limited to) ``PickAndPlaceTask``, ``LiftObjectTask``, +``OpenDoorTask``, ``CloseDoorTask``, and ``PressButtonTask``. + +More details +------------ + +.. toctree:: + :maxdepth: 1 + + concept_sequential_tasks_design + concept_rl_tasks_design + concept_metrics_design diff --git a/docs/pages/example_workflows/locomanipulation/step_1_environment_setup.rst b/docs/pages/example_workflows/locomanipulation/step_1_environment_setup.rst index 3b84de78f..e350a0828 100644 --- a/docs/pages/example_workflows/locomanipulation/step_1_environment_setup.rst +++ b/docs/pages/example_workflows/locomanipulation/step_1_environment_setup.rst @@ -82,7 +82,7 @@ Step-by-Step Breakdown Here, we're selecting the specific pieces we need for our locomanipulation task: the Galileo arena as our background environment, an object to pick up, a blue sorting bin as our goal location, and the G1 embodiment. The ``AssetRegistry`` and ``DeviceRegistry`` have been initialized in the ``ExampleEnvironmentBase`` class. -See :doc:`../../concepts/concept_assets_design` for details on asset architecture. +See :doc:`../../concepts/scene/concept_assets_design` for details on asset architecture. **2. Position the Objects** @@ -116,7 +116,7 @@ currently set manually to create an achievable task. scene = Scene(assets=[background, pick_up_object, blue_sorting_bin]) Now we bring everything together into a IsaacLab-Arena scene. -See :doc:`../../concepts/concept_scene_design` for scene composition details. +See :doc:`../../concepts/scene/index` for scene composition details. **4. Create the Locomanip Pick and Place Task** @@ -129,7 +129,7 @@ environment: pick up the specified object and place it in the blue sorting bin. The task knows about the key objects involved (what to pick, where to place it, and the environment context) and will provide rewards, compute observations, and determine when the episode should end. -See :doc:`../../concepts/concept_tasks_design` for task creation details. +See :doc:`../../concepts/task/index` for task creation details. **5. Create the IsaacLab Arena Environment** @@ -145,7 +145,7 @@ See :doc:`../../concepts/concept_tasks_design` for task creation details. Finally, we assemble all the pieces into a complete, runnable environment. The ``IsaacLabArenaEnvironment`` is the top-level container that connects your embodiment (the robot), the scene (the world) and the task (the objective). -See :doc:`../../concepts/concept_environment_design` for environment composition details. +See :doc:`../../concepts/concept_overview` for environment composition details. Step 1: Download a test dataset diff --git a/docs/pages/example_workflows/reinforcement_learning/step_1_environment_setup.rst b/docs/pages/example_workflows/reinforcement_learning/step_1_environment_setup.rst index b4055b442..9e13b4097 100644 --- a/docs/pages/example_workflows/reinforcement_learning/step_1_environment_setup.rst +++ b/docs/pages/example_workflows/reinforcement_learning/step_1_environment_setup.rst @@ -109,7 +109,7 @@ is positioned below to provide physical support. scene = Scene(assets=assets) Now we bring everything together into an IsaacLab-Arena scene. -See :doc:`../../concepts/concept_scene_design` for scene composition details. +See :doc:`../../concepts/scene/index` for scene composition details. **4. Create the Lift Object RL Task** @@ -133,7 +133,7 @@ The task includes: - **Termination Conditions**: Object dropped or timeout - **Success Condition**: Object reaches target position (disabled by the ``--rl_training_mode`` flag for training) -See :doc:`../../concepts/concept_tasks_design` for task creation details. +See :doc:`../../concepts/task/index` for task creation details. **5. Create the IsaacLab Arena Environment** @@ -149,7 +149,7 @@ See :doc:`../../concepts/concept_tasks_design` for task creation details. Finally, we assemble all the pieces into a complete, runnable RL environment. The ``IsaacLabArenaEnvironment`` connects the embodiment (the robot), the scene (the world), and the task (the objective and rewards). -See :doc:`../../concepts/concept_environment_design` for environment composition details. +See :doc:`../../concepts/concept_overview` for environment composition details. Validation: Run Random Policy diff --git a/docs/pages/example_workflows/sequential_static_manipulation/step_1_environment_setup.rst b/docs/pages/example_workflows/sequential_static_manipulation/step_1_environment_setup.rst index 3d2333272..536787b76 100644 --- a/docs/pages/example_workflows/sequential_static_manipulation/step_1_environment_setup.rst +++ b/docs/pages/example_workflows/sequential_static_manipulation/step_1_environment_setup.rst @@ -245,7 +245,7 @@ Here, we're selecting the components needed for our sequential static manipulati The GR1 embodiment, the kitchen environment as our background, the object to pick and place, and a light to illuminate the scene. The ``AssetRegistry`` and ``DeviceRegistry`` have been initialized in the ``ExampleEnvironmentBase`` class. -See :doc:`../../concepts/concept_assets_design` for details on asset architecture. +See :doc:`../../concepts/scene/concept_assets_design` for details on asset architecture. **2. Position the Embodiment and Objects** @@ -321,7 +321,7 @@ the relational object placement APIs. The object is placed within a randomzation sequential_task = PutAndCloseDoorTask(subtasks=[pick_and_place_task, close_door_task]) The sequential task is composed of two atomic subtasks: the pick and place task and the close door task. -See :doc:`../../concepts/concept_tasks_design` for task creation details. +See :doc:`../../concepts/task/index` for task creation details. **4. Compose the Scene** @@ -331,7 +331,7 @@ See :doc:`../../concepts/concept_tasks_design` for task creation details. scene = Scene(assets=[kitchen_background, pickup_object, light, refrigerator, refrigerator_shelf]) Now we bring everything together into an IsaacLab-Arena scene. -See :doc:`../../concepts/concept_scene_design` for scene composition details. +See :doc:`../../concepts/scene/index` for scene composition details. **5. Create the IsaacLab Arena Environment** @@ -348,7 +348,7 @@ See :doc:`../../concepts/concept_scene_design` for scene composition details. Finally, we assemble all the pieces into a complete, runnable environment. The ``IsaacLabArenaEnvironment`` is the top-level container that connects the embodiment (the robot), the scene (the world), and the task (the objective). -See :doc:`../../concepts/concept_environment_design` for environment composition details. +See :doc:`../../concepts/concept_overview` for environment composition details. Step 1: Download a Test Dataset diff --git a/docs/pages/example_workflows/static_manipulation/step_1_environment_setup.rst b/docs/pages/example_workflows/static_manipulation/step_1_environment_setup.rst index 7fab1f29b..738adbbfc 100644 --- a/docs/pages/example_workflows/static_manipulation/step_1_environment_setup.rst +++ b/docs/pages/example_workflows/static_manipulation/step_1_environment_setup.rst @@ -77,7 +77,7 @@ Step-by-Step Breakdown Here, we're selecting the components needed for our static manipulation task: the kitchen environment as our background, a microwave with an openable door, and the GR1 embodiment (our robot). The ``AssetRegistry`` and ``DeviceRegistry`` have been initialized in the ``ExampleEnvironmentBase`` class. -See :doc:`../../concepts/concept_assets_design` for details on asset architecture. +See :doc:`../../concepts/scene/concept_assets_design` for details on asset architecture. **2. Position the Objects** @@ -100,7 +100,7 @@ currently set manually to create an achievable task. In this case, we place the scene = Scene(assets=assets) Now we bring everything together into an IsaacLab-Arena scene. -See :doc:`../../concepts/concept_scene_design` for scene composition details. +See :doc:`../../concepts/scene/index` for scene composition details. **4. Create the Open Door Task** @@ -109,7 +109,7 @@ See :doc:`../../concepts/concept_scene_design` for scene composition details. task = OpenDoorTask(microwave, openness_threshold=0.8, reset_openness=0.2) The ``OpenDoorTask`` encapsulates the goal of this environment: open the microwave door. -See :doc:`../../concepts/concept_tasks_design` for task creation details. +See :doc:`../../concepts/task/index` for task creation details. **5. Create the IsaacLab Arena Environment** @@ -125,7 +125,7 @@ See :doc:`../../concepts/concept_tasks_design` for task creation details. Finally, we assemble all the pieces into a complete, runnable environment. The ``IsaacLabArenaEnvironment`` is the top-level container that connects the embodiment (the robot), the scene (the world), and the task (the objective). -See :doc:`../../concepts/concept_environment_design` for environment composition details. +See :doc:`../../concepts/concept_overview` for environment composition details. Step 1: Download a Test Dataset diff --git a/docs/pages/policy_evaluation/index.rst b/docs/pages/policy_evaluation/index.rst deleted file mode 100644 index f3faf5bbc..000000000 --- a/docs/pages/policy_evaluation/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Policy Evaluation -================= - -This section describes how to run policy evaluation in Isaac Lab Arena: single-job -and sequential batch evaluation, plus server–client setups for remote policies. - -.. toctree:: - :maxdepth: 1 - - evaluation_types diff --git a/docs/pages/quickstart/first_arena_env.rst b/docs/pages/quickstart/first_arena_env.rst index 98b907c52..ea2c6d850 100644 --- a/docs/pages/quickstart/first_arena_env.rst +++ b/docs/pages/quickstart/first_arena_env.rst @@ -113,7 +113,7 @@ Notice that ``pick_up_object`` and ``destination_location`` come from ``args_cli being hardcoded. This is the variation axis: swapping ``--pick_up_object`` on the command line changes which asset is fetched here, resulting in a new environment, with zero code changes. -See :doc:`../concepts/concept_assets_design` for details on the asset registry and how to register +See :doc:`../concepts/scene/concept_assets_design` for details on the asset registry and how to register custom assets. @@ -176,7 +176,7 @@ space, observation space, and cameras. ``droid_abs_joint_pos`` is the DROID setu Robotiq 2F-85 gripper) with absolute joint-position control. Swapping ``--embodiment`` replaces the robot entirely — observations, actions, and sensors update -automatically. See :doc:`../concepts/concept_embodiment_design` for details. +automatically. See :doc:`../concepts/embodiment/index` for details. Step 5: Compose the Scene @@ -190,7 +190,7 @@ The ``Scene`` collects all physical assets. The embodiment is kept separate — to ``IsaacLabArenaEnvironment`` rather than added to the scene — because the robot interacts with the scene rather than being part of it. -See :doc:`../concepts/concept_scene_design` for scene composition details. +See :doc:`../concepts/scene/index` for scene composition details. Step 6: Define the Task @@ -214,7 +214,7 @@ It also attaches metrics (``SuccessRateMetric``, ``ObjectMovedRateMetric``) that collects at the end of each episode. These metrics will report the proportion of successful episodes, as well as the proportion of episodes in which the object was moved. -See :doc:`../concepts/concept_tasks_design` for creating custom tasks. +See :doc:`../concepts/task/index` for creating custom tasks. Step 7: Assemble the Environment