From 3dfaf3050b04c85c1bc8406c9fb70b1cf3ac883c Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Mon, 11 May 2026 22:30:41 -0700 Subject: [PATCH 1/6] Updates ecosystem docs --- docs/source/_static/setup/ecosystem-dark.svg | 93 ++++++ docs/source/_static/setup/ecosystem-light.svg | 94 ++++++ docs/source/setup/ecosystem.rst | 275 ++++++++++-------- 3 files changed, 348 insertions(+), 114 deletions(-) create mode 100644 docs/source/_static/setup/ecosystem-dark.svg create mode 100644 docs/source/_static/setup/ecosystem-light.svg diff --git a/docs/source/_static/setup/ecosystem-dark.svg b/docs/source/_static/setup/ecosystem-dark.svg new file mode 100644 index 000000000000..ca86201590a7 --- /dev/null +++ b/docs/source/_static/setup/ecosystem-dark.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + Learning Libraries + RSL-RL · skrl · Stable Baselines 3 · RL Games + + + + Isaac Lab Extensions + + isaaclab_tasks + pre-built environments + + isaaclab_assets + robot & sensor configs + + isaaclab_rl + RL library wrappers + + isaaclab_mimic + imitation learning + + isaaclab_teleop + teleoperation & XR + + + + Isaac Lab Core (isaaclab) + sim · scene · assets · sensors · envs · managers · actuators + controllers · terrains · devices · mdp · utils · markers · renderers + ManagerBasedRLEnv · DirectRLEnv · DirectMARLEnv · InteractiveScene + factory pattern: uniform API dispatches to the active physics backend at runtime + + + + + + isaaclab_physx · isaaclab_ovphysx · isaaclab_ov + Articulation · Rigid Body · Rigid Object Collection · Deformable + Fabric Views · Camera · USD spawners + Isaac RTX Renderer · OvRTX Renderer + + + + isaaclab_newton + Articulation · Rigid Body · Rigid Object Collection + Camera · USD spawners · Warp Renderer + MJWarp Solver · VBD Solver + + + + + + Isaac Sim (optional) + PhysX · RTX Rendering · USD / Omniverse + ROS / ROS 2 · URDF & MJCF importers + required for the PhysX backend + + + + Newton Physics + Warp + GPU-parallel simulation · Warp kernels + MJWarp (MuJoCo-Warp) solver + kit-less · no Isaac Sim required + + + + NVIDIA GPU Platform + CUDA · Warp (required by all backends) + diff --git a/docs/source/_static/setup/ecosystem-light.svg b/docs/source/_static/setup/ecosystem-light.svg new file mode 100644 index 000000000000..52b5f54c5941 --- /dev/null +++ b/docs/source/_static/setup/ecosystem-light.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + Learning Libraries + RSL-RL · skrl · Stable Baselines 3 · RL Games + + + + Isaac Lab Extensions + + isaaclab_tasks + pre-built environments + + isaaclab_assets + robot & sensor configs + + isaaclab_rl + RL library wrappers + + isaaclab_mimic + imitation learning + + isaaclab_teleop + teleoperation & XR + + + + Isaac Lab Core (isaaclab) + sim · scene · assets · sensors · envs · managers · actuators + controllers · terrains · devices · mdp · utils · markers · renderers + ManagerBasedRLEnv · DirectRLEnv · DirectMARLEnv · InteractiveScene + factory pattern: uniform API dispatches to the active physics backend at runtime + + + + + + isaaclab_physx · isaaclab_ovphysx · isaaclab_ov + Articulation · Rigid Body · Rigid Object Collection · Deformable + Fabric Views · Camera · USD spawners + Isaac RTX Renderer · OvRTX Renderer + + + + isaaclab_newton + Articulation · Rigid Body · Rigid Object Collection + Camera · USD spawners · Warp Renderer + MJWarp Solver · VBD Solver + + + + + + Isaac Sim (optional) + PhysX · RTX Rendering · USD / Omniverse + ROS / ROS 2 · URDF & MJCF importers + required for the PhysX backend + + + + Newton Physics + Warp + GPU-parallel simulation · Warp kernels + MJWarp (MuJoCo-Warp) solver + kit-less · no Isaac Sim required + + + + NVIDIA GPU Platform + CUDA · Warp (required by all backends) + diff --git a/docs/source/setup/ecosystem.rst b/docs/source/setup/ecosystem.rst index 75c22b24313e..31bf64b8ca8c 100644 --- a/docs/source/setup/ecosystem.rst +++ b/docs/source/setup/ecosystem.rst @@ -3,156 +3,203 @@ Isaac Lab Ecosystem =================== -Isaac Lab is built on top of Isaac Sim and Newton to provide a unified and flexible framework -for robot learning that exploits the latest simulation technologies. It is designed to be modular and extensible, -and aims to simplify common workflows in robotics research (such as RL, learning from demonstrations, and -motion planning). While it includes some pre-built environments, sensors, and tasks, its main goal is to -provide an open-sourced, unified, and easy-to-use interface for developing and testing custom environments -and robot learning algorithms. - -Working with Isaac Lab requires the installation of Isaac Sim for full functionality, which is packaged with -core robotics tools including URDF and MJCF importers, and ROS features. Isaac Sim also builds on top of the NVIDIA -Omniverse platform, leveraging advanced physics simulation from **PhysX**, photorealistic **RTX** rendering -technologies, and Universal Scene Description (USD) for scene creation. Without Isaac Sim, users can still use -the **Newton** physics backend as well as the new **OVRTX** renderers. +Isaac Lab is a modular, extensible framework for robot learning built on top of `Isaac Sim`_ and +`Newton`_. It provides a unified interface for the most common workflows in robotics research — +reinforcement learning, learning from demonstrations, and motion planning — while staying easy to +use and easy to extend. + +Isaac Lab supports two physics backends: + +* **PhysX** (via `Isaac Sim`_) — the default backend, with access to GPU-accelerated rigid-body + simulation, deformable objects, Fabric views, tiled RTX rendering, ROS/ROS2, URDF/MJCF + importers, and the full Omniverse toolchain. +* **Newton** — a Warp-native backend that can run **without Isaac Sim** installed, enabling + lightweight kit-less deployments and GPU-parallel simulation using `Warp`_. .. note:: - Isaac Lab 3.0 supports a **kit-less installation** mode: you can install Isaac Lab and use the Newton - physics backend without installing Isaac Sim at all. See :ref:`isaaclab-installation-root` for details. + Isaac Lab 3.0 supports a **kit-less installation** mode: you can install Isaac Lab and use the + Newton physics backend without installing Isaac Sim at all. + See :ref:`isaaclab-installation-root` for details. -Isaac Lab not only inherits the capabilities of Isaac Sim, but also adds a number -of new features that pertain to robot learning research. For example, including actuator dynamics in the -simulation, procedural terrain generation, and support to collect data from human demonstrations. +A factory pattern dispatches every asset and sensor instantiation to the correct backend at +runtime, so user code stays unchanged regardless of which backend is active. See +:doc:`/source/overview/core-concepts/multi_backend_architecture` for details. -.. image:: ../_static/setup/ecosystem-light.jpg +.. image:: ../_static/setup/ecosystem-light.svg :class: only-light :align: center - :alt: The Isaac Lab, Isaac Sim, and NVIDIA Omniverse ecosystem + :alt: The Isaac Lab package ecosystem layered on the NVIDIA GPU platform -.. image:: ../_static/setup/ecosystem-dark.jpg +.. image:: ../_static/setup/ecosystem-dark.svg :class: only-dark :align: center - :alt: The Isaac Lab, Isaac Sim, and NVIDIA Omniverse ecosystem + :alt: The Isaac Lab package ecosystem layered on the NVIDIA GPU platform + + +Package structure +----------------- + +Isaac Lab is organized into a set of focused packages that can be used independently or together. + +**Core** + +* ``isaaclab`` — the core library. Contains simulation context and configuration + (:mod:`~isaaclab.sim`), the :class:`~isaaclab.scene.InteractiveScene` that aggregates all + assets, sensors, and terrain for a vectorized set of environments, asset interfaces + (:mod:`~isaaclab.assets`), sensor interfaces (:mod:`~isaaclab.sensors`), environment base + classes (:mod:`~isaaclab.envs`), the manager system (:mod:`~isaaclab.managers`), + composable MDP term functions (:mod:`~isaaclab.envs.mdp`), actuator models + (:mod:`~isaaclab.actuators`), low-level controllers (:mod:`~isaaclab.controllers`), + procedural terrain generation (:mod:`~isaaclab.terrains`), and human-input device support + (:mod:`~isaaclab.devices`). + +**Physics backends** + +* ``isaaclab_physx`` / ``isaaclab_ovphysx`` — PhysX-backed implementations of articulations, + rigid bodies, deformable objects, Fabric views, the Isaac RTX renderer, and USD spawners. + Requires Isaac Sim. +* ``isaaclab_newton`` — Newton-backed implementations of articulations, rigid bodies, and the + Warp renderer. Supports a kit-less installation without Isaac Sim. + +**Extensions** + +* ``isaaclab_assets`` — pre-configured robot and sensor :class:`~isaaclab.utils.configclass` + dataclasses for a wide range of robots (Franka, Unitree, ANYmal, Spot, Allegro, humanoids, + quadcopters, and more) and sensors (Velodyne, GelSight). +* ``isaaclab_tasks`` — registered `gymnasium`_ environments organized into two authoring patterns: + + * *Manager-based* — behavior is fully specified through composable manager configurations + (observations, rewards, terminations, events, commands, actions). Well-suited for research + that requires clean separation between task specification and environment logic. + * *Direct* — a single Python class implements the full step/reset/obs/reward loop, similar + in style to Isaac Gym. Convenient for rapid prototyping and tasks with complex custom logic. + +* ``isaaclab_rl`` — thin wrappers that adapt Isaac Lab environments to the vectorized + environment interfaces expected by `RSL-RL`_, `skrl`_, `Stable Baselines 3`_, and + `RL Games`_. +* ``isaaclab_mimic`` — APIs and pre-configured environments for data generation and imitation + learning, including cuRobo-based motion planners and a full dataset-generation pipeline. +* ``isaaclab_teleop`` — teleoperation session orchestration with XR (OpenXR / CloudXR) support, + device retargeters for manipulators and humanoids, and gamepad/spacemouse/keyboard input. +* ``isaaclab_visualizers`` — supplementary visualizer backends (Isaac Kit, Rerun, Viser) that + work with any physics backend. +* ``isaaclab_contrib`` — community-contributed features: multirotor assets, TacSL visuo-tactile + sensors, drone thrust controllers, and more. +* ``isaaclab_experimental`` — pre-production experiments, including Warp-accelerated manager and + environment variants. Where does Isaac Lab fit in the Isaac ecosystem? ------------------------------------------------ Over the years, NVIDIA has developed a number of tools for robotics and AI. These tools leverage -the power of GPUs to accelerate the simulation both in terms of speed and realism. They show great -promise in the field of simulation technology and are being used by many researchers and companies -worldwide. - -`Isaac Gym`_ :cite:`makoviychuk2021isaac` provides a high performance GPU-based physics simulation -for robot learning. It is built on top of `PhysX`_ which supports GPU-accelerated simulation of rigid bodies -and a Python API to directly access physics simulation data. Isaac Lab extends this foundation with -additional support for the **Newton** physics backend, enabling broader simulation options. Through an end-to-end GPU pipeline, it is possible -to achieve high frame rates compared to CPU-based physics engines. The tool has been used successfully in a -number of research projects, including legged locomotion :cite:`rudin2022learning` :cite:`rudin2022advanced`, -in-hand manipulation :cite:`handa2022dextreme` :cite:`allshire2022transferring`, and industrial assembly -:cite:`narang2022factory`. - -Despite the success of Isaac Gym, it is not designed to be a general purpose simulator for -robotics. For example, it does not include interaction between deformable and rigid objects, high-fidelity -rendering, and support for ROS. The tool has been primarily designed as a preview release to showcase the -capabilities of the underlying physics engine. With the release of `Isaac Sim`_, NVIDIA is building -a general purpose simulator for robotics and has integrated the functionalities of Isaac Gym into -Isaac Sim. - -`Isaac Sim`_ is a robot simulation toolkit built on top of Omniverse, which is a general purpose platform -that aims to unite complex 3D workflows. Isaac Sim leverages the latest advances in graphics and -physics simulation to provide a high-fidelity simulation environment for robotics. It supports -ROS/ROS2, various sensor simulation, tools for domain randomization and synthetic data creation. -Tiled rendering support in Isaac Sim allows for vectorized rendering across environments, along with -support for running in the cloud using `Isaac Automator`_. -Overall, it is a powerful tool for roboticists and is a huge step forward in the field of robotics -simulation. - -With the release of above two tools, NVIDIA also released an open-sourced set of environments called -`IsaacGymEnvs`_ and `OmniIsaacGymEnvs`_, that have been built on top of Isaac Gym and Isaac Sim respectively. -These environments have been designed to display the capabilities of the underlying simulators and provide -a starting point to understand what is possible with the simulators for robot learning. These environments -can be used for benchmarking but are not designed for developing and testing custom environments and algorithms. -This is where Isaac Lab comes in. - -Isaac Lab is built on top of Isaac Sim to provide a unified and flexible framework -for robot learning that exploits latest simulation technologies. It is designed to be modular and extensible, -and aims to simplify common workflows in robotics research (such as RL, learning from demonstrations, and -motion planning). While it includes some pre-built environments, sensors, and tasks, its main goal is to -provide an open-sourced, unified, and easy-to-use interface for developing and testing custom environments -and robot learning algorithms. It not only inherits the capabilities of Isaac Sim, but also adds a number -of new features that pertain to robot learning research. For example, including actuator dynamics in the -simulation, procedural terrain generation, and support to collect data from human demonstrations. - -Isaac Lab replaces the previous `IsaacGymEnvs`_, `OmniIsaacGymEnvs`_ and `Orbit`_ frameworks and will -be the single robot learning framework for Isaac Sim. Previously released frameworks are deprecated -and we encourage users to follow our migration guides to transition over to Isaac Lab. +the power of GPUs to accelerate simulation both in terms of speed and realism. + +`Isaac Gym`_ :cite:`makoviychuk2021isaac` provided a high-performance GPU-based physics simulation +for robot learning built on top of `PhysX`_. Its end-to-end GPU pipeline enabled frame rates +far beyond what CPU-based physics engines could achieve. The tool proved successful across a +number of research projects, including legged locomotion :cite:`rudin2022learning` +:cite:`rudin2022advanced`, in-hand manipulation :cite:`handa2022dextreme` +:cite:`allshire2022transferring`, and industrial assembly :cite:`narang2022factory`. + +`Isaac Sim`_ is a general-purpose robot simulation toolkit built on top of `Omniverse`_. It +integrates the capabilities of Isaac Gym while adding high-fidelity rendering, ROS/ROS2, +deformable-object simulation, synthetic data generation, domain randomization, tiled rendering +for vectorized observations, and cloud support via `Isaac Automator`_. With the Isaac Gym legacy +API absorbed into Isaac Sim, NVIDIA also released open-sourced environment collections +`IsaacGymEnvs`_ and `OmniIsaacGymEnvs`_ to showcase the capabilities of these simulators. +Those environment collections are now deprecated in favor of Isaac Lab. + +Isaac Lab supersedes `IsaacGymEnvs`_, `OmniIsaacGymEnvs`_, and `Orbit`_ as the single robot +learning framework for Isaac Sim. It retains full access to the PhysX/Isaac Sim stack while +adding the Newton physics backend for kit-less deployments, an expanded sensor suite, imitation +learning tooling, XR teleoperation, and a rich set of pre-built tasks. Is Isaac Lab a simulator? ------------------------- -Often, when people think of simulators, they think of various commonly available engines, such as -`MuJoCo`_, `Bullet`_, and `Flex`_. These engines are powerful and have been used in a number of -research projects. However, they are not designed to be a general purpose simulator for robotics. -Rather they are primarily physics engines that are used to simulate the dynamics of rigid and -deformable bodies. They are shipped with some basic rendering capabilities to visualize the -simulation and provide parsing capabilities of different scene description formats. - -Various recent works combine these physics engines with different rendering engines to provide -a more complete simulation environment. They include APIs that allow reading and writing to the -physics and rendering engines. In some cases, they support ROS and hardware-in-the-loop simulation -for more robotic-specific applications. An example of these include `AirSim`_, `DoorGym`_, `ManiSkill`_, -`ThreeDWorld`_ and lastly, `Isaac Sim`_. - -At its core, Isaac Lab is **not** a robotics simulator, but a framework for building robot learning -applications on top of `Isaac Sim`_ and `Newton`_. An equivalent example of such a framework is `RoboSuite`_, which -is built on top of `MuJoCo`_ and is specific to fixed-base robots. Other examples include -`MuJoCo Playground`_ and `Isaac Gym`_ which use `MJX`_ and `PhysX`_ respectively. Isaac Lab supports -both `PhysX`_ and `Newton`_ as physics backends. They -include a number of pre-built tasks with separated out stand-alone implementations for individual -tasks. While this is a good starting point (and often convenient), a lot of code -repetition occurs across different task implementations, which can reduce code-reuse for larger -projects and teams. - -The main goal of Isaac Lab is to provide a unified framework for robot learning that includes -a variety of tooling and features that are required for robot learning, while being easy to -use and extend. It includes design patterns that simplify many of the common requirements for -robotics research. These include simulating sensors at different frequencies, connecting to different -teleoperation interfaces for data collection, switching action spaces for policy learning, -using Hydra for configuration management, supporting different learning libraries and more. -Isaac Lab supports designing tasks using *manager-based (modularized)* and *direct (single-script -similar to Isaac Gym)* patterns, leaving it up to the user to choose the best approach for their -use-case. For each of these patterns, Isaac Lab includes a number of pre-built tasks that can be -used for benchmarking and research. +At its core, Isaac Lab is **not** a robotics simulator; it is a framework for building robot +learning applications on top of a simulator. An analogous example is `RoboSuite`_, which is +built on top of `MuJoCo`_ for fixed-base manipulation. Other examples include +`MuJoCo Playground`_ (built on `MJX`_) and Isaac Gym (built on `PhysX`_). + +Isaac Lab supports both `PhysX`_ and `Newton`_ as physics backends and is deliberately +agnostic to the underlying engine — user environments and tasks do not import backend-specific +modules directly. + +The framework addresses a recurring problem with standalone task implementations: because each +task reimplements the observation, reward, termination, and randomization logic from scratch, +large projects accumulate significant code duplication. Isaac Lab solves this with two +complementary patterns: + +* **Manager-based** environments defer every behavioral concern to typed, composable + *manager* objects (``ObservationManager``, ``RewardManager``, ``TerminationManager``, + ``EventManager``, ``CurriculumManager``, ``CommandManager``, ``ActionManager``, + ``RecorderManager``). Each manager is driven by small, reusable MDP term functions that live + in :mod:`isaaclab.envs.mdp`. This makes it easy to mix and match terms across tasks and to + test individual components in isolation. + +* **Direct** environments implement ``_get_observations``, ``_get_rewards``, + ``_get_dones``, and ``_reset_idx`` directly in a subclass, similar to the Isaac Gym style. + They sacrifice some modularity for simplicity and are a natural starting point for rapid + prototyping. + +Both patterns expose a standard `gymnasium`_ ``Env`` interface with vectorized semantics, +so the same environment works unmodified with any of the supported RL libraries. +Configuration management uses `Hydra`_ with a preset system that allows selecting physics +backends and hyperparameter sweeps from the command line. Why should I use Isaac Lab? --------------------------- -Isaac Lab provides an open-sourced platform for the community to drive progress with consolidated efforts -toward designing benchmarks and robot learning systems as a joint initiative. This allows us to reuse -existing components and algorithms, and to build on top of each other's work. Doing so not only saves -time and effort, but also allows us to focus on the more important aspects of research. Our hope with -Isaac Lab is that it becomes the de-facto platform for robot learning research and an environment *zoo* -that leverages Isaac Sim. As the framework matures, we foresee it benefitting hugely from the latest -simulation developments (as part of internal developments at NVIDIA and collaborating partners) -and research in robotics. - -We are already working with labs in universities and research institutions to integrate their work into Isaac Lab -and hope that others in the community will join us too in this effort. If you are interested in contributing -to Isaac Lab, please reach out to us. +Isaac Lab provides an open-sourced platform for the community to build benchmarks and robot +learning systems together. Sharing a common infrastructure lets teams reuse existing components, +compare results on the same tasks, and focus on the research problems that matter rather than +rebuilding simulation scaffolding from scratch. + +Concretely, Isaac Lab offers: + +* **Two authoring patterns** — manager-based for modular research and direct for rapid + prototyping — with a shared :class:`~isaaclab.scene.InteractiveScene` and sensor stack. +* **Multi-backend simulation** — switch between PhysX and Newton from the command line; the + same environment code runs on both. +* **Rich sensor suite** — cameras (tiled and standard), ray-casters, contact sensors, IMU, + frame transformers, joint-wrench sensors, and visuo-tactile sensors. +* **Imitation learning tooling** — ``isaaclab_mimic`` provides cuRobo-based planners and a + full dataset-generation pipeline for human demonstration collection. +* **Teleoperation and XR** — ``isaaclab_teleop`` supports OpenXR, CloudXR, gamepads, + spacemouses, and Haply devices with retargeters for manipulators and humanoids. +* **Hydra configuration management** — hierarchical configs with command-line overrides and a + preset system for multi-backend environment variants. +* **RL library integrations** — wrappers for RSL-RL, skrl, Stable Baselines 3, and RL Games + ship in ``isaaclab_rl``. +* **Kit-less deployment** — run policies and simulations using the Newton backend without a + full Isaac Sim installation. + +We are working with labs in universities and research institutions to integrate their work into +Isaac Lab and hope that others in the community will join us. If you are interested in +contributing, please reach out to us. .. _PhysX: https://developer.nvidia.com/physx-sdk .. _Newton: https://github.com/newton-physics/newton +.. _Warp: https://github.com/NVIDIA/warp .. _Isaac Sim: https://developer.nvidia.com/isaac-sim +.. _Omniverse: https://www.nvidia.com/en-us/omniverse/ .. _Isaac Gym: https://developer.nvidia.com/isaac-gym .. _IsaacGymEnvs: https://github.com/isaac-sim/IsaacGymEnvs .. _OmniIsaacGymEnvs: https://github.com/isaac-sim/OmniIsaacGymEnvs .. _Orbit: https://isaac-orbit.github.io/ .. _Isaac Automator: https://github.com/isaac-sim/IsaacAutomator +.. _gymnasium: https://gymnasium.farama.org/ +.. _Hydra: https://hydra.cc/ +.. _RSL-RL: https://github.com/leggedrobotics/rsl_rl +.. _skrl: https://skrl.readthedocs.io/ +.. _Stable Baselines 3: https://stable-baselines3.readthedocs.io/ +.. _RL Games: https://github.com/Denys88/rl_games .. _AirSim: https://microsoft.github.io/AirSim/ .. _DoorGym: https://github.com/PSVL/DoorGym/ .. _ManiSkill: https://github.com/haosulab/ManiSkill From 595e9b5d43d040549cef013c91d7b90f13a543a6 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Mon, 11 May 2026 22:44:07 -0700 Subject: [PATCH 2/6] more doc updates --- docs/index.rst | 1 + .../overview/core-concepts/sensors/index.rst | 1 - .../sensors/visuo_tactile_sensor.rst | 205 ------------------ .../developer-guide/repo_structure.rst | 129 +++++++---- 4 files changed, 93 insertions(+), 243 deletions(-) delete mode 100644 docs/source/overview/core-concepts/sensors/visuo_tactile_sensor.rst diff --git a/docs/index.rst b/docs/index.rst index 6c8e6ba9ac41..d3218514afb7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -143,6 +143,7 @@ Table of Contents source/experimental-features/bleeding-edge source/experimental-features/newton-physics-integration/index + source/experimental-features/visuo_tactile_sensor .. toctree:: :maxdepth: 1 diff --git a/docs/source/overview/core-concepts/sensors/index.rst b/docs/source/overview/core-concepts/sensors/index.rst index f32923ab9c30..1ecae8e3ccdf 100644 --- a/docs/source/overview/core-concepts/sensors/index.rst +++ b/docs/source/overview/core-concepts/sensors/index.rst @@ -21,4 +21,3 @@ The following pages describe the available sensors in more detail: pva joint_wrench_sensor ray_caster - visuo_tactile_sensor diff --git a/docs/source/overview/core-concepts/sensors/visuo_tactile_sensor.rst b/docs/source/overview/core-concepts/sensors/visuo_tactile_sensor.rst deleted file mode 100644 index e1b389e45c1c..000000000000 --- a/docs/source/overview/core-concepts/sensors/visuo_tactile_sensor.rst +++ /dev/null @@ -1,205 +0,0 @@ -.. _overview_sensors_tactile: - -.. currentmodule:: isaaclab - -Visuo-Tactile Sensor -==================== - - -The visuo-tactile sensor in Isaac Lab provides realistic tactile feedback through integration with TacSL (Tactile Sensor Learning) [Akinola2025]_. It is designed to simulate high-fidelity tactile interactions, generating both visual and force-based data that mirror real-world tactile sensors like GelSight devices. The sensor can provide tactile RGB images, force field distributions, and other intermediate tactile measurements essential for robotic manipulation tasks requiring fine tactile feedback. - - -.. figure:: ../../../_static/overview/sensors/tacsl_diagram.jpg - :align: center - :figwidth: 100% - :alt: Tactile sensor with RGB visualization and force fields - - -Configuration -~~~~~~~~~~~~~ - -Tactile sensors require specific configuration parameters to define their behavior and data collection properties. The sensor can be configured with various parameters including sensor resolution, force sensitivity, and output data types. - -.. code-block:: python - - from isaaclab.sensors import CameraCfg - from isaaclab_assets.sensors import GELSIGHT_R15_CFG - import isaaclab.sim as sim_utils - - from isaaclab_contrib.sensors.tacsl_sensor import VisuoTactileSensorCfg - - # Tactile sensor configuration - tactile_sensor = VisuoTactileSensorCfg( - prim_path="{ENV_REGEX_NS}/Robot/elastomer/tactile_sensor", - ## Sensor configuration - render_cfg=GELSIGHT_R15_CFG, - enable_camera_tactile=True, - enable_force_field=True, - ## Elastomer configuration - tactile_array_size=(20, 25), - tactile_margin=0.003, - ## Contact object configuration - contact_object_prim_path_expr="{ENV_REGEX_NS}/contact_object", - ## Force field physics parameters - normal_contact_stiffness=1.0, - friction_coefficient=2.0, - tangential_stiffness=0.1, - ## Camera configuration - camera_cfg=CameraCfg( - prim_path="{ENV_REGEX_NS}/Robot/elastomer_tip/cam", - update_period=1 / 60, # 60 Hz - height=320, - width=240, - data_types=["distance_to_image_plane"], - spawn=None, # camera already spawned in USD file - ), - ) - -The configuration supports customization of: - -* **Render Configuration**: Specify the GelSight sensor rendering parameters using predefined configs - (e.g., ``GELSIGHT_R15_CFG``, ``GELSIGHT_MINI_CFG`` from ``isaaclab_assets.sensors``) -* **Tactile Modalities**: - * ``enable_camera_tactile`` - Enable tactile RGB imaging through camera sensors - * ``enable_force_field`` - Enable force field computation and visualization -* **Force Field Grid**: Set tactile grid dimensions (``tactile_array_size``) and margins, which directly affects the spatial resolution of the computed force field -* **Contact Object Configuration**: Define properties of interacting objects using prim path expressions to locate objects with SDF collision meshes -* **Physics Parameters**: Control the sensor's force field computation: - * ``normal_contact_stiffness``, ``friction_coefficient``, ``tangential_stiffness`` - Normal stiffness, friction coefficient, and tangential stiffness -* **Camera Settings**: Configure resolution, update rates, and data types using :class:`~sensors.CameraCfg`. Currently only ``distance_to_image_plane`` (alias for ``depth``) is supported. - ``spawn`` is set to ``None`` by default, which means that the camera is already spawned in the USD file. - If you want to spawn the camera yourself and set focal length, etc., you can set the spawn configuration to a valid spawn configuration. - -Configuration Requirements -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. important:: - The following requirements must be satisfied for proper sensor operation: - - **Camera Tactile Imaging** - If ``enable_camera_tactile=True``, a valid ``camera_cfg`` (CameraCfg) must be provided with appropriate camera parameters. - - **Force Field Computation** - If ``enable_force_field=True``, the following parameters are required: - - * ``contact_object_prim_path_expr`` - Prim path expression to locate contact objects with SDF collision meshes - - **SDF Computation** - When force field computation is enabled, penalty-based normal and shear forces are computed using Signed Distance Field (SDF) queries. To achieve GPU acceleration: - - * Interacting objects should have SDF collision meshes - * An SDFView must be defined during initialization, therefore interacting objects should be specified before simulation. - - **Elastomer Configuration** - The sensor's ``prim_path`` must be configured as a child of the elastomer prim in the USD hierarchy. - The query points for the force field computation is computed from the surface of the elastomer mesh, which is searched for under the prim path of the elastomer. - - **Physics Materials** - The sensor uses physics materials to configure the compliant contact properties of the elastomer. - By default, physics material properties are pre-configured in the USD asset. However, you can override - these properties by specifying the following parameters in ``UsdFileWithCompliantContactCfg`` when - spawning the robot: - - * ``compliant_contact_stiffness`` - Contact stiffness for the elastomer surface - * ``compliant_contact_damping`` - Contact damping for the elastomer surface - * ``physics_material_prim_path`` - Prim path where physics material is applied (typically ``"elastomer"``) - - If any parameter is set to ``None``, the corresponding property from the USD asset will be retained. - - -Usage Example -~~~~~~~~~~~~~ - -To use the tactile sensor in a simulation environment, run the demo: - -.. code-block:: bash - - cd scripts/demos/sensors - python tacsl_sensor.py --use_tactile_rgb --use_tactile_ff --tactile_compliance_stiffness 100.0 --tactile_compliant_damping 1.0 --contact_object_type nut --num_envs 16 --save_viz --enable_cameras - -Available command-line options include: - -* ``--use_tactile_rgb``: Enable camera-based tactile sensing -* ``--use_tactile_ff``: Enable force field tactile sensing -* ``--contact_object_type``: Specify the type of contact object (nut, cube, etc.) -* ``--num_envs``: Number of parallel environments -* ``--save_viz``: Save visualization outputs for analysis -* ``--tactile_compliance_stiffness``: Override compliant contact stiffness (default: use USD asset values) -* ``--tactile_compliant_damping``: Override compliant contact damping (default: use USD asset values) -* ``--normal_contact_stiffness``: Normal contact stiffness for force field computation -* ``--tangential_stiffness``: Tangential stiffness for shear forces -* ``--friction_coefficient``: Friction coefficient for shear forces -* ``--debug_sdf_closest_pts``: Visualize closest SDF points for debugging -* ``--debug_tactile_sensor_pts``: Visualize tactile sensor points for debugging -* ``--trimesh_vis_tactile_points``: Enable trimesh-based visualization of tactile points - -For a complete list of available options: - -.. code-block:: bash - - python tacsl_sensor.py -h - -.. note:: - The demo examples are based on the Gelsight R1.5, which is a prototype sensor that is now discontinued. The same procedure can be adapted for other visuotactile sensors. - -.. figure:: ../../../_static/overview/sensors/tacsl_demo.jpg - :align: center - :figwidth: 100% - :alt: TacSL tactile sensor demo showing RGB tactile images and force field visualizations - -The tactile sensor supports multiple data modalities that provide comprehensive information about contact interactions: - - -Output Tactile Data -~~~~~~~~~~~~~~~~~~~ -**RGB Tactile Images** - Real-time generation of tactile RGB images as objects make contact with the sensor surface. These images show deformation patterns and contact geometry similar to gel-based tactile sensors [Si2022]_ - - -**Force Fields** - Detailed contact force field and pressure distributions across the sensor surface, including normal and shear components. - -.. list-table:: - :widths: 50 50 - :class: borderless - - * - .. figure:: ../../../_static/overview/sensors/tacsl_taxim_example.jpg - :align: center - :figwidth: 80% - :alt: Tactile output with RGB visualization - - - .. figure:: ../../../_static/overview/sensors/tacsl_force_field_example.jpg - :align: center - :figwidth: 80% - :alt: Tactile output with force field visualization - -Integration with Learning Frameworks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The tactile sensor is designed to integrate seamlessly with reinforcement learning and imitation learning frameworks. The structured tensor outputs can be directly used as observations in learning algorithms: - -.. code-block:: python - - def get_tactile_observations(self): - """Extract tactile observations for learning.""" - tactile_data = self.scene["tactile_sensor"].data - - # tactile RGB image - tactile_rgb = tactile_data.tactile_rgb_image - - # tactile depth image - tactile_depth = tactile_data.tactile_depth_image - - # force field - tactile_normal_force = tactile_data.tactile_normal_force - tactile_shear_force = tactile_data.tactile_shear_force - - return [tactile_rgb, tactile_depth, tactile_normal_force, tactile_shear_force] - - - -References -~~~~~~~~~~ - -.. [Akinola2025] Akinola, I., Xu, J., Carius, J., Fox, D., & Narang, Y. (2025). TacSL: A library for visuotactile sensor simulation and learning. *IEEE Transactions on Robotics*. -.. [Si2022] Si, Z., & Yuan, W. (2022). Taxim: An example-based simulation model for GelSight tactile sensors. *IEEE Robotics and Automation Letters*, 7(2), 2361-2368. diff --git a/docs/source/overview/developer-guide/repo_structure.rst b/docs/source/overview/developer-guide/repo_structure.rst index d8a5a1b200a5..ecc56f9b9608 100644 --- a/docs/source/overview/developer-guide/repo_structure.rst +++ b/docs/source/overview/developer-guide/repo_structure.rst @@ -15,56 +15,111 @@ Repository organization ├── docs ├── docker ├── source - │   ├── isaaclab - │   ├── isaaclab_assets - │   ├── isaaclab_mimic - │   ├── isaaclab_rl - │   └── isaaclab_tasks + │ ├── isaaclab # core framework + │ ├── isaaclab_physx # PhysX backend (requires Isaac Sim) + │ ├── isaaclab_ovphysx # Standalone PhysX backend (does not require Isaac Sim) + │ ├── isaaclab_ov # Standalone RTX renderer (does not require Isaac Sim) + │ ├── isaaclab_newton # Newton backend (kit-less) + │ ├── isaaclab_assets # pre-configured robot & sensor assets + │ ├── isaaclab_tasks # pre-built RL/IL environments + │ ├── isaaclab_tasks_experimental # Warp-accelerated environments + │ ├── isaaclab_rl # RL library wrappers + │ ├── isaaclab_mimic # imitation learning & data generation + │ ├── isaaclab_teleop # teleoperation & XR + │ ├── isaaclab_visualizers # external visualizer backends + │ ├── isaaclab_contrib # community-contributed extensions + │ ├── isaaclab_experimental # Warp-accelerated manager and environment variants + │ ├── extensions # legacy Omniverse extension wrappers + │ └── standalone # standalone tutorials & workflows ├── scripts - │   ├── benchmarks - │   ├── demos - │   ├── environments - │   ├── imitation_learning - │   ├── reinforcement_learning - │   ├── tools - │   ├── tutorials + │ ├── benchmarks + │ ├── demos + │ ├── environments + │ ├── imitation_learning + │ ├── reinforcement_learning + │ ├── sim2sim_transfer + │ ├── tools + │ └── tutorials ├── tools └── VERSION -Isaac Lab is built on the same back end as Isaac Sim. As such, it exists as a collection of **extensions** that can be assembled into **applications**. -The ``source`` directory contains the majority of the code in the repository and the specific extensions that compose Isaac lab, while ``scripts`` containing python scripts for launching customized standalone apps (Like our workflows). -These are the two primary ways of interacting with the simulation and Isaac lab supports both! -Checkout this `Isaac Sim introduction to workflows `__ for more details. +Isaac Lab supports two physics backends — **PhysX** (via Isaac Sim) and **Newton** (a Warp-native +kit-less backend) — through a factory pattern that dispatches to the active backend at runtime. +The ``source`` directory contains all packages that compose Isaac Lab, while ``scripts`` contains +standalone Python applications for training, evaluation, and tooling. +See :doc:`/source/overview/core-concepts/multi_backend_architecture` for details on the backend +system, and :doc:`/source/setup/ecosystem` for a full package-layer overview. -Extensions +Submodules ~~~~~~~~~~ -The extensions that compose Isaac Lab are kept in the ``source`` directory. To simplify the build process, Isaac Lab directly use `setuptools `__. It is strongly recommend that you adhere to this process if you create your own extensions using Isaac Lab. +The packages under ``source/`` are installed as Python packages using +`setuptools `__. They are organized into three +groups: -The extensions are organized as follows: +**Core and physics backends** -* **isaaclab**: Contains the core interface extension for Isaac Lab. This provides the main modules for actuators, - objects, robots and sensors. -* **isaaclab_assets**: Contains the extension with pre-configured assets for Isaac Lab. -* **isaaclab_tasks**: Contains the extension with pre-configured environments for Isaac Lab. -* **isaaclab_mimic**: Contains APIs and pre-configured environments for data generation for imitation learning. -* **isaaclab_rl**: Contains wrappers for using the above environments with different reinforcement learning agents. +* **isaaclab**: The core framework. Provides :mod:`~isaaclab.sim` (simulation context and + configuration), :class:`~isaaclab.scene.InteractiveScene`, asset and sensor base classes and + factory interfaces (:mod:`~isaaclab.assets`, :mod:`~isaaclab.sensors`), environment base + classes (:mod:`~isaaclab.envs`), the manager system (:mod:`~isaaclab.managers`), composable + MDP term library (:mod:`~isaaclab.envs.mdp`), actuator models (:mod:`~isaaclab.actuators`), + low-level controllers (:mod:`~isaaclab.controllers`), procedural terrain generation + (:mod:`~isaaclab.terrains`), and human-input device support (:mod:`~isaaclab.devices`). +* **isaaclab_physx**: PhysX-backed implementations of articulations, rigid bodies, deformable + objects, Fabric views, the Isaac RTX renderer, and USD spawners. Requires Isaac Sim. +* **isaaclab_ovphysx**: OmniVerse PhysX backend variant with an OmniVerse-managed physics + context. Requires Isaac Sim. +* **isaaclab_ov**: OvRTX renderer backend. Requires Isaac Sim. +* **isaaclab_newton**: Newton-backed implementations of articulations, rigid bodies, rigid + object collections, cameras, USD spawners, and the Warp renderer. Supports + :ref:`kit-less installation ` without Isaac Sim. + +**Tasks and assets** + +* **isaaclab_assets**: Pre-configured :class:`~isaaclab.utils.configclass` dataclasses for a + wide range of robots (Franka, Unitree, ANYmal, Spot, Allegro, humanoids, quadcopters, and + more) and sensors (Velodyne, GelSight). +* **isaaclab_tasks**: Registered `gymnasium `__ environments for + reinforcement and imitation learning, organized as *manager-based* and *direct* tasks across + locomotion, manipulation, navigation, and classic control domains. +* **isaaclab_tasks_experimental**: Experimental task implementations under active development, + not yet part of the stable task suite. + +**Optional Additions** + +* **isaaclab_rl**: Thin wrappers that adapt Isaac Lab environments to the interfaces expected + by `RSL-RL `__, + `skrl `__, + `Stable Baselines 3 `__, and + `RL Games `__. +* **isaaclab_mimic**: APIs and pre-configured environments for data generation and imitation + learning, including cuRobo-based motion planners and a dataset-generation pipeline. +* **isaaclab_teleop**: Teleoperation session orchestration with OpenXR / CloudXR support, + device retargeters for manipulators and humanoids, and gamepad / spacemouse / keyboard input. +* **isaaclab_visualizers**: Supplementary visualizer backends (Isaac Sim Kit, Newton, Rerun, Viser) that + work with any physics backend. +* **isaaclab_contrib**: Community-contributed features: multirotor assets, TacSL + visuo-tactile sensors, drone thrust controllers, and more. +* **isaaclab_experimental**: Pre-production core experiments including Warp-accelerated manager + and environment variants. Standalone ~~~~~~~~~~ -The ``scripts`` directory contains various standalone applications written in python. +The ``scripts`` directory contains standalone Python applications. They are structured as follows: -* **benchmarks**: Contains scripts for benchmarking different framework components. -* **demos**: Contains various demo applications that showcase the core framework :mod:`isaaclab`. -* **environments**: Contains applications for running environments defined in :mod:`isaaclab_tasks` with - different agents. These include a random policy, zero-action policy, teleoperation or scripted state machines. -* **imitation_learning**: Contains applications for training and evaluating policies with various - imitation learning libraries (e.g. robomimic). -* **reinforcement_learning**: Contains applications for training and evaluating policies with various - reinforcement learning libraries (e.g. rsl_rl, rl_games, sb3, skrl). -* **tools**: Contains applications for using the tools provided by the framework. These include converting assets, - generating datasets, etc. -* **tutorials**: Contains step-by-step tutorials for using the APIs provided by the framework. +* **benchmarks**: Scripts for benchmarking different framework components. +* **demos**: Demo applications that showcase the core framework :mod:`isaaclab`. +* **environments**: Scripts for running environments defined in :mod:`isaaclab_tasks` with + different agents (random policy, zero-action policy, teleoperation, scripted state machines). +* **imitation_learning**: Applications for training and evaluating policies with imitation + learning libraries (e.g. robomimic). +* **reinforcement_learning**: Applications for training and evaluating policies with RL + libraries (e.g. rsl_rl, rl_games, sb3, skrl). +* **sim2sim_transfer**: Scripts for transferring policies trained in one simulator to another. +* **tools**: Applications for using framework tools such as converting assets and generating + datasets. +* **tutorials**: Step-by-step tutorials for using the APIs provided by the framework. From c1e4b79ba1bf28383d6530bdb07a1c81e40cd123 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Mon, 11 May 2026 22:45:24 -0700 Subject: [PATCH 3/6] update --- .../visuo_tactile_sensor.rst | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 docs/source/experimental-features/visuo_tactile_sensor.rst diff --git a/docs/source/experimental-features/visuo_tactile_sensor.rst b/docs/source/experimental-features/visuo_tactile_sensor.rst new file mode 100644 index 000000000000..e1b389e45c1c --- /dev/null +++ b/docs/source/experimental-features/visuo_tactile_sensor.rst @@ -0,0 +1,205 @@ +.. _overview_sensors_tactile: + +.. currentmodule:: isaaclab + +Visuo-Tactile Sensor +==================== + + +The visuo-tactile sensor in Isaac Lab provides realistic tactile feedback through integration with TacSL (Tactile Sensor Learning) [Akinola2025]_. It is designed to simulate high-fidelity tactile interactions, generating both visual and force-based data that mirror real-world tactile sensors like GelSight devices. The sensor can provide tactile RGB images, force field distributions, and other intermediate tactile measurements essential for robotic manipulation tasks requiring fine tactile feedback. + + +.. figure:: ../../../_static/overview/sensors/tacsl_diagram.jpg + :align: center + :figwidth: 100% + :alt: Tactile sensor with RGB visualization and force fields + + +Configuration +~~~~~~~~~~~~~ + +Tactile sensors require specific configuration parameters to define their behavior and data collection properties. The sensor can be configured with various parameters including sensor resolution, force sensitivity, and output data types. + +.. code-block:: python + + from isaaclab.sensors import CameraCfg + from isaaclab_assets.sensors import GELSIGHT_R15_CFG + import isaaclab.sim as sim_utils + + from isaaclab_contrib.sensors.tacsl_sensor import VisuoTactileSensorCfg + + # Tactile sensor configuration + tactile_sensor = VisuoTactileSensorCfg( + prim_path="{ENV_REGEX_NS}/Robot/elastomer/tactile_sensor", + ## Sensor configuration + render_cfg=GELSIGHT_R15_CFG, + enable_camera_tactile=True, + enable_force_field=True, + ## Elastomer configuration + tactile_array_size=(20, 25), + tactile_margin=0.003, + ## Contact object configuration + contact_object_prim_path_expr="{ENV_REGEX_NS}/contact_object", + ## Force field physics parameters + normal_contact_stiffness=1.0, + friction_coefficient=2.0, + tangential_stiffness=0.1, + ## Camera configuration + camera_cfg=CameraCfg( + prim_path="{ENV_REGEX_NS}/Robot/elastomer_tip/cam", + update_period=1 / 60, # 60 Hz + height=320, + width=240, + data_types=["distance_to_image_plane"], + spawn=None, # camera already spawned in USD file + ), + ) + +The configuration supports customization of: + +* **Render Configuration**: Specify the GelSight sensor rendering parameters using predefined configs + (e.g., ``GELSIGHT_R15_CFG``, ``GELSIGHT_MINI_CFG`` from ``isaaclab_assets.sensors``) +* **Tactile Modalities**: + * ``enable_camera_tactile`` - Enable tactile RGB imaging through camera sensors + * ``enable_force_field`` - Enable force field computation and visualization +* **Force Field Grid**: Set tactile grid dimensions (``tactile_array_size``) and margins, which directly affects the spatial resolution of the computed force field +* **Contact Object Configuration**: Define properties of interacting objects using prim path expressions to locate objects with SDF collision meshes +* **Physics Parameters**: Control the sensor's force field computation: + * ``normal_contact_stiffness``, ``friction_coefficient``, ``tangential_stiffness`` - Normal stiffness, friction coefficient, and tangential stiffness +* **Camera Settings**: Configure resolution, update rates, and data types using :class:`~sensors.CameraCfg`. Currently only ``distance_to_image_plane`` (alias for ``depth``) is supported. + ``spawn`` is set to ``None`` by default, which means that the camera is already spawned in the USD file. + If you want to spawn the camera yourself and set focal length, etc., you can set the spawn configuration to a valid spawn configuration. + +Configuration Requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. important:: + The following requirements must be satisfied for proper sensor operation: + + **Camera Tactile Imaging** + If ``enable_camera_tactile=True``, a valid ``camera_cfg`` (CameraCfg) must be provided with appropriate camera parameters. + + **Force Field Computation** + If ``enable_force_field=True``, the following parameters are required: + + * ``contact_object_prim_path_expr`` - Prim path expression to locate contact objects with SDF collision meshes + + **SDF Computation** + When force field computation is enabled, penalty-based normal and shear forces are computed using Signed Distance Field (SDF) queries. To achieve GPU acceleration: + + * Interacting objects should have SDF collision meshes + * An SDFView must be defined during initialization, therefore interacting objects should be specified before simulation. + + **Elastomer Configuration** + The sensor's ``prim_path`` must be configured as a child of the elastomer prim in the USD hierarchy. + The query points for the force field computation is computed from the surface of the elastomer mesh, which is searched for under the prim path of the elastomer. + + **Physics Materials** + The sensor uses physics materials to configure the compliant contact properties of the elastomer. + By default, physics material properties are pre-configured in the USD asset. However, you can override + these properties by specifying the following parameters in ``UsdFileWithCompliantContactCfg`` when + spawning the robot: + + * ``compliant_contact_stiffness`` - Contact stiffness for the elastomer surface + * ``compliant_contact_damping`` - Contact damping for the elastomer surface + * ``physics_material_prim_path`` - Prim path where physics material is applied (typically ``"elastomer"``) + + If any parameter is set to ``None``, the corresponding property from the USD asset will be retained. + + +Usage Example +~~~~~~~~~~~~~ + +To use the tactile sensor in a simulation environment, run the demo: + +.. code-block:: bash + + cd scripts/demos/sensors + python tacsl_sensor.py --use_tactile_rgb --use_tactile_ff --tactile_compliance_stiffness 100.0 --tactile_compliant_damping 1.0 --contact_object_type nut --num_envs 16 --save_viz --enable_cameras + +Available command-line options include: + +* ``--use_tactile_rgb``: Enable camera-based tactile sensing +* ``--use_tactile_ff``: Enable force field tactile sensing +* ``--contact_object_type``: Specify the type of contact object (nut, cube, etc.) +* ``--num_envs``: Number of parallel environments +* ``--save_viz``: Save visualization outputs for analysis +* ``--tactile_compliance_stiffness``: Override compliant contact stiffness (default: use USD asset values) +* ``--tactile_compliant_damping``: Override compliant contact damping (default: use USD asset values) +* ``--normal_contact_stiffness``: Normal contact stiffness for force field computation +* ``--tangential_stiffness``: Tangential stiffness for shear forces +* ``--friction_coefficient``: Friction coefficient for shear forces +* ``--debug_sdf_closest_pts``: Visualize closest SDF points for debugging +* ``--debug_tactile_sensor_pts``: Visualize tactile sensor points for debugging +* ``--trimesh_vis_tactile_points``: Enable trimesh-based visualization of tactile points + +For a complete list of available options: + +.. code-block:: bash + + python tacsl_sensor.py -h + +.. note:: + The demo examples are based on the Gelsight R1.5, which is a prototype sensor that is now discontinued. The same procedure can be adapted for other visuotactile sensors. + +.. figure:: ../../../_static/overview/sensors/tacsl_demo.jpg + :align: center + :figwidth: 100% + :alt: TacSL tactile sensor demo showing RGB tactile images and force field visualizations + +The tactile sensor supports multiple data modalities that provide comprehensive information about contact interactions: + + +Output Tactile Data +~~~~~~~~~~~~~~~~~~~ +**RGB Tactile Images** + Real-time generation of tactile RGB images as objects make contact with the sensor surface. These images show deformation patterns and contact geometry similar to gel-based tactile sensors [Si2022]_ + + +**Force Fields** + Detailed contact force field and pressure distributions across the sensor surface, including normal and shear components. + +.. list-table:: + :widths: 50 50 + :class: borderless + + * - .. figure:: ../../../_static/overview/sensors/tacsl_taxim_example.jpg + :align: center + :figwidth: 80% + :alt: Tactile output with RGB visualization + + - .. figure:: ../../../_static/overview/sensors/tacsl_force_field_example.jpg + :align: center + :figwidth: 80% + :alt: Tactile output with force field visualization + +Integration with Learning Frameworks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The tactile sensor is designed to integrate seamlessly with reinforcement learning and imitation learning frameworks. The structured tensor outputs can be directly used as observations in learning algorithms: + +.. code-block:: python + + def get_tactile_observations(self): + """Extract tactile observations for learning.""" + tactile_data = self.scene["tactile_sensor"].data + + # tactile RGB image + tactile_rgb = tactile_data.tactile_rgb_image + + # tactile depth image + tactile_depth = tactile_data.tactile_depth_image + + # force field + tactile_normal_force = tactile_data.tactile_normal_force + tactile_shear_force = tactile_data.tactile_shear_force + + return [tactile_rgb, tactile_depth, tactile_normal_force, tactile_shear_force] + + + +References +~~~~~~~~~~ + +.. [Akinola2025] Akinola, I., Xu, J., Carius, J., Fox, D., & Narang, Y. (2025). TacSL: A library for visuotactile sensor simulation and learning. *IEEE Transactions on Robotics*. +.. [Si2022] Si, Z., & Yuan, W. (2022). Taxim: An example-based simulation model for GelSight tactile sensors. *IEEE Robotics and Automation Letters*, 7(2), 2361-2368. From d2b225330450cafa161878ee44a54bf375aa1895 Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Sat, 16 May 2026 20:55:58 -0700 Subject: [PATCH 4/6] address review --- docs/source/_static/setup/ecosystem-dark.jpg | Bin 182687 -> 0 bytes docs/source/_static/setup/ecosystem-dark.svg | 6 ++--- docs/source/_static/setup/ecosystem-light.jpg | Bin 176206 -> 0 bytes docs/source/_static/setup/ecosystem-light.svg | 4 +-- .../developer-guide/repo_structure.rst | 22 ++++++++-------- docs/source/setup/ecosystem.rst | 24 +++++++++++------- 6 files changed, 32 insertions(+), 24 deletions(-) delete mode 100644 docs/source/_static/setup/ecosystem-dark.jpg delete mode 100644 docs/source/_static/setup/ecosystem-light.jpg diff --git a/docs/source/_static/setup/ecosystem-dark.jpg b/docs/source/_static/setup/ecosystem-dark.jpg deleted file mode 100644 index 9057aeb48b298936775fa6e6e3b38412ce871aa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182687 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

-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 Q_AmdV^bM(@CHVg)0A2d>p8x;= diff --git a/docs/source/_static/setup/ecosystem-dark.svg b/docs/source/_static/setup/ecosystem-dark.svg index ca86201590a7..a09f1d0c5036 100644 --- a/docs/source/_static/setup/ecosystem-dark.svg +++ b/docs/source/_static/setup/ecosystem-dark.svg @@ -1,4 +1,4 @@ - + xO7zjY*pqqb$T7Um(XV1! zGwdydi4fGvwMutp=o*5l@Bp?cO1s0%z%7YSEEGDhc48mfv5O2E_F4Hf8cEnreZAy< zL}q*=>U*8Np|M`V>_vd>1JFV`lfDPr=28aijtlk)9m$7Xl7$o2qOk(GxN*{=0TbPK8cgVHE^8ujijxu7ZUJr!y zU$^xBB2D?N`G8oQ%sMMba%ToAAy&^15-jC@)z7D14A?pw6mg&+ddn|b-JiJzcFTX_ zqi66Z=f3<)ZMh=66~zZsu?C$PWD zZQOcAdi$OyCnowzEVdzoFr1l;W0a2CNK%cc35A7os#>H;xW2ld_}0z7qfE2zQu{7* zPTBagJpocaSb)CfP4Y-_8onDWEsa)_I>U2-Tur#rA|nV?jrFrac9?UXz1$(h772PQ zj7w1m@?H_q54J@X*v)Fd(Y?wl1@;w5<|(-Glbx?x82r!g_y{F0H=_7_a+eUUe!pZ|%YKyampfHolw|z>k%LVTC&dN$f z`*tzctqj-c)J+ln2a($^5mBSjMB?tmrBRfqSPE0N?}c5VS(Zf_3m75poOiF3p#DU*sc8-O3X*5K~EuW)HQr9T6%orrF4X&VJpejONi|=LlZPISq?6Xw}Ffr0>mi=q8#E5 z-K!Oc&Y#qF6Ho|-`nyCJYLsQ%vT9YdU*o27sYm7*&zQOmU91R&tdQFOs4{+cF#C=Q z87cIw2$*6h)oHPjGT2(HB)w-)PufS)dhp?8i3C3JIFFoMyg zFq5LDsIuD9IR3{sOKiB*PQ8nEzfpGK!}Viq)h&`w9xZXcuxtbQbIW?O^H}I0a!Jd7 z61AO3c!as+lGW(qkvHddZ_M`m4&%o?DoKYgG{Vev28V;A%k< zoU6@e%cy#E*2q`YiFmW(t`hYLMqAfqfI>NV(K#`N2kM~l(6{4i`P0=Dd&ySTis@6cpL(CI|+FD8WEPU zzH0t_E3~CVdDF;;#nlh4d&8F|d@hMcE%qoL*xRD6m{!dVTl-h%`>&6y_#t_g>FcDQ zu&XnGaBOCWwo9PP0zCKLFDCPgpRmn?x$KL7>$m^$Rx%3#UL#HwW%`z{7By4=pcqI+ z8)ASnZ|4e-=}GOs@$~=tWjT{@zB!ii7rZLSFLhn)RokA-lW$sa*;(1)dZ>}%Rx9I) zpzUgRBVbu19M4=D7loM?|8j0X+b|)gY0p2lRCr%X46zfX8b#eB2;2&g{GtZm>3lsj zHE+y?YUZ00+DY2+Ih))GLdF-##Fv3GAIf5A!+$g>ir$Zkv%?l$LlGLqZji_TcWgW2S2)B4C`tkz_(BOA5-)EK8bnBEE~X1Q>aZbd~Mj7zoW>_unvKF zPy`J)gNg{Nrh^S$>rQ_rmH#E;;#UQh&%H39g}5DKQe^Vx7J|E0k~n_>@my}KEA)1D z>PXS#lDNHp8~$YP>Vp5i7D*dZA6Hk`FGfN~_861T)p2J9a%SY^X7Gmws5DP5LkF?I zlZWh3AuLUbQ3D}tbD8$NCeNqb%vR6#<|J=Bhe&s#JyqRAnUA};a}-9r`)1K1D?>~O zm=gJ5mIUNUni_tZ2B)yXGusNr)My#Q{!y0;{qGPTxSTogL-zR4J7l3sI7<@LHB@%S z=Pqb(iv-E*9WCUul{Li?ldjqqqS|;W<0W_VT@0=(d~;w6FVeJhV0CVBS!trWq|!j> zi4hpSI_@GNRS23>#ffF<8W&uA z!o@+}^T5*eG|b)yLBfaWNt@-FfE*qFZ1V2p{$3Pl=lZqz*5DxT`s=4JaYqftQe-!K z0Dw~-hH)*J(~c?4aIP%N%=qkfuRVW6tZ094w&v$2Re49s*{9F*Zz;>o;11YB`JO&G zCP6mqzkPe{xE^(f=kQp=dxN8CZ$8%L^V=&XKwfk;h8Bd#H_7!et&`@W)U4)xtLco* z9RB)wf!Rad7kB)o^i88G%; z+ca|n_A=xt_~xa(fYB%7wf+68kfS`u3E*6mw|`%q%j96ga#?$ z5+WDmu1~3b(Rl-HE02u$B;wE?aq7*7^=9|()37@LQXt$!fn0!?S5v>PEoHrqb+9k% zv3}Bn+7PtAwjtME_D@muCuGT*Q~fB;fR99OJ!$mY`7}7>Kv_5FTk5p0>Sbs-p>>^@ zNyd%*b%UAUxcAUI&P=Y|&A3G6cu*dp2Z!XFk_!|>bUH2=lvY>hYr#zR9fRq3g27@7 zhc_a58z=LRd+8!xDwpRBOX&?-h#cX`N88`MW^#Y|%F3~~J3lO4#-JuT;FJ7e-&Irn zOnSXK6lPu1+AT^=Q+&g+3@7pf_Lbyj@L7`5>+l>H;g}^1Xhh5nnRsn^J$KJ_|9IWi zgw8S6dF90$WUUr6CxAk~TW>rr57HZycx#3ZMF}6S+l!!;So6L?`G)0hG#sbniac%m zh1g0!Aywpp5itn^aqjwE&8V`O^&28epZkr&)mN3z^#Tm<|DprE$ zn;pI!oL$c<>M}2h85l>rG~9x#yJ)8ZmKyP~hQ#gR^{`djyS5_V-0!XT9kTy`7H>7N zSI%koco=$BV8Q011=|&A5ePJGWk+w86~6Rw*Y934dvHQM$JZgJ+1(?zLiYRfZUf^X z`@2nP$U^sSeQ8u4s|m4nt!x`|@p4U%_;FMW{}s-=ib#LJ{J! z=MP_cI1!||XRUz9;lpD9Igviz!}88nBEwcA&x1UtdZ&)5bL5emBfGC1_>0GD-Dk0l zznK?d(_brz9;lT}{KUW0*5yaz>vo^TMCw)5+cHiH1@#6y&4tpmC4RVn<)oo1nNP5e zUHm?Z=PQb91`2gYQq8Bk$4F_@RuV=BI^Q&(xV_~QA8f+%eYd_?ts>+~B1)s?ysf7n zzFe@hmTDbd9l`?-IUf199n%AUlBjc=!_ zXG=V?DYQ9RT9bP59@~`RZT_=^Hd)SP0lRw&7w^$^YxUW->ww+6r$1h4}Rq zz%Jm+er>a$jTuNvq>NdQ?v1%}GsN&p*ZY8A;iINaO)u*M4vp`oJ-&gZr z2+yUKlEMxxeV1|juuJy(!}V=7d=aqQ#fPY>cNMDLxZl0~ch#0#`u3M~`(Q?nj(G>xP# zsn1ah?mTBMy6%3GFwxDJsu2evtwIf+3lzqD4gc;b-QRWJu&9yto>_4nR2RCC z2po`K{pMhkd$_c6jL9mV-{oC)#o^Y}UgVvPD-ILUP4G(3z+)(B)~EE6SjZD(Qe6k- z+}S~&bAg5A{ex{NqHtFOvt03ZwtoVbtWq-7XD zFXBPPbghUHnWw+^p8w?$>oTfHx?H={?F%MuS#394#W{83LpWkmXgR+m3`nOj$ZkC; z$fyqdN5t^7JteLu2T%5Xmw6vL-hU-8d2;&fs{_W@xGsF05f@)UN(BspSl4~g){n%r zAv=YzL?B$9_UoK&@!t79M<-WwYLup3^A5$1QWgduotvw;;Z(`YM>t@`eFkZf-2p0? zz0`qt65?_4&4^*OjAkRtojx3Ku>DnF1<)ozEba)}!o6&L zxuB;?B}U0PtHO88&Pse|Cgs1EmU--bmrrZY&H|&T1<-m)euE zh2C2RpOBadDpJ{Ht2}Lg%2m}{xAFzN^37p>t%mY+R!=d*JcY$$Wgj434!|?W?WrPjgT2WU4QB!2Ce>HKF(xIJd6p%SLMBgj)?Iy^*!2DyE^gX(tpk zh|vNqimBS<4bvCfUmNVx zsp%596d3`xzT$qF?Sznx?I|K|MIMfI*DA|1|lxQ@VsFsWt9q5_f7k4P4yX5ga z-_-5|U8jYM*olI1-iqFUEdd>XtHo|JZ+V%e`=w;b2i@SQ@?=}=NS1)fIy1~soG$FxpQTlbusL!`g5F`=#v0%3!xxm;hH=! zU&f`x2+xl{VQc{c3kV6-lRGkR{?X6{eJV1 z8SH*~F?K2YWx!AXZ~ym#)l|zy>3x(MYR?*z{Q}I^#Zu-?oZiar!@Pm!0~}kn<72Ql zyN2&COkkHf=oZcayD4@xRKZqh8LGX>Yv%_Ja+S|s?%IeSz1l|4_qkZ9Olvzd57Ux; zkh8ewWSk_2}9p z%6PRRY2E=9v<$xGIymLL650Uj%JdN>TQ=CbPfQn1&S9dr(ah|L);*TLBqv>u0(O<0w9aFbi-tu9gI5?0aeV^bbGY z*WP!V>pBCFqOF``AR67ue6sGpyi{X~Kq+v;)>TH>X@ivY#jtGWC$=t?tr5CblkM@2 zAa3QIrG~4NT7@19^tsaa?mOW2ig8fwEWN=8DNtMMQl?3V1DtC5lgNf+FB9w{r5xOPq zy1TlEUe|lpkIt1YF*0nX)C*gpQb!z7q$NNqll)ttAmq?}DR@&N(eXoKM`?4#W49d= zN9X6oggJJBOx6;p9S~hAy-pVbF%mw!X!V&_p-Pk8-jeQ{&*tHdF)iW=Lq+A=r^W>= zQY*yaO$xY0D*Y-(pP3o3XSj{OUdgYKz_TXyD!IKmxux9I-Rn-KNpwsK?)YVc=mMMX zPsS8y5Rd|@(PnuotAY4_`H`-fQc)fj^n7dFG|!PW?>TXA&RzDr>!CNzHk@%8PabeH zxr5|_grbEn37iD55^VMW+rRP}|AXA%HiqZ>lyi^~zTSODe1}rLf{{d`lh$sS*8WNm zm;;RN&+Zw5WCg{uLYTm!z#IYh0KLrp`*px={XH)K8|#3y%+1iE@)9Cchh)Ea<&tCO z_uoVxJekXP)MNy8C+6wDrObb&%>fYd=iK4HFG%s1dLA|uFXLptt{FH_q?o0;*C~~) z&D!ga0(LSKjWehM-O9X$GvO*zoa!Bizg@q2^j%C9^8BX@-_JlvEUt^xIYJ3x>C)@Y z+RNE+oZVb^;P~|??cdU`-f5*~@OB9T1_5j5thH40Ors_PNoj5QVu(Ugx8WugX%!LI z^lTRnbrw8geq%G?n217?eUe`@=oR=qphg>)IC!Wkvl=cn*HrKj>J0 zEz9{fIfhe_ZUP@xWbIl&Ko@x^mUPa=tRAC?U z0eVmyos)s0mWLNsAIpKN>fWKPG4ckXK8uWYQ~ysBW-=diR_+>qWPjKJdw^_(Lk9=z zutTjacYVBprz}uXgRm~wae7}?_MuO<)ct!q&3Q_ooURhQWS2$3l2MOX2pA6Z*{39=4 zRVn0>$e_T-r0zhw?c^iNsexLb706Nx1~hkORqd{TK~eAfM1G9xYbc1;jA<+Qe9UT0 z;SSGZr&F;{c5R!;J^{470IfUdDrOgDJsf+RIBe8Xnea#=wDcu3{k`?9-{Ypp9M0Hb zt9_i`foHKVQB22T2U)EKEG{uhDX!6dgg|qmPDi@)rB5n3G{revhkV{H<43o=GI-;a zKZ9%cjv2|C5SV{3)pBw@gtZM)o@uf>JXq4jH=F3Q%a&-q59cwPrTc#Oo&3b(5Am{) z3ixCrh?9Q8XB^H8Sxy=z`4-x$xBJ=T+Y}xzvdJ*+XgXIA<);vb%*J&6GMP{`S_RPd zN##V<-4VU;*XLssWQB5B68)MQ`EJc_t~F#M8N3zWQ|t9LS%I% z-^BTnd2Q&@BX<3Jx^Kf5-(U4z_jGE<3CIYK1^-YNa)?ump@2K$oB)u2%sULg3}aN8 z=$3QgrdC!XSItDf*So+ft}ucwvOkgSG}NY|dy9QkVnG@*P1n;rNH1VE-5`VZ^h<(uTz+MSH zEr*x_q#RB*&SZa}?hjf7nB8E8Br|^P<2?f0XZh@xHIt`6-id43Ef%>qP0?rS-i5Dk zVYH$!nh&#}b~me^C7lj9A(I^%O=SZGBBZ@U;pSqk*5^AS-o3ta$I9@INAkv-L0U1m z1w1VVdI(4bVH1N*{NXI!+P)nD`v);PuO;(UtJt@Vn+{Di>ATV&bNIH2YvFYv9uVCL z-$GHWQZ+6P)B?adV5XVH^8r1kIX^JiRe0#Gqw?#Wuw7?!ud3Tjb^2y($GQ?B1$^MW zI9(`GYKiF%8j+L^ps?W2r39)^gr)qy#`J#3O+o{02epAe73J>iIWJA9J zIW%4H;cV(b4@excS32X^>$arVDQhSrjWMZMx{NrW*?Ro6j|M}?iG^IC0Y~pGD+|QQ znfPLiEm-KUfkSN<_Y*d|El?N9;wmQLLiGfgi6wNEM|S%LFc&6D3DwRjYsSesVb3~S zF73^HL_+NeSiGa1Rtj%HK?Ggpkpp|xMA?o#{wc(-5CBF+N^D%0zgSzAHk zQ)3Z1VWpa?+^M)M(YHJWi-d#F@gxc++4I;I<`|~oTL2LU3 zHey@!E{*cU2kNcAEr5S*p8!I4d$ILa2QaBIf)6~z~j9wY7*`3f_gagahcp&DjV;mGnHwbn$PUAI*vrm+f!(Iblu zf|~mC?bR9QjW`CAesTN0Nwfo;aw&!n@?T$-RTNhw7|FII3AFUE zjb>;rM{J-;NsAvyXdI+e-o$gW*VX1k&#DbdsQJ}xAS5sGG*W^mU0!lWWbNf0h9{oH zc6bpemT-P6$Y`>4ahaT|J}!w6vW93~CZf~>RyRtYF{sD>nAFuB|4-f(|B&*xbLwRudZL5dM<8MWYAPg z16I$EYTS{+?}_c+O#f#gwM1HVN9`IJ4(=dy*tT!KS-^zBGApSxOood74E(diN!qgI$6qO$kyrk^ebXzVpZju>T+7bnRU z@19}{JPZTm1=NlJMIU!EGT0SkKsxSumMRkYfGc#R#VdKgOwdv7!@9zndno#9(|XEa z$>K1A6u@rMS#oNv3`pS&QS<&%y7zeYr%y?_Y(5UScA}QWiT!e3ur>S+W*kPxiLMLo z$C7mzgp<_=Uqc9+F9nPq8O{3M<#R~?H8^oLjpwHuC)RCmZJu$#Q+d@*se0tf8}a)81YNKWB;+ku(Z z2oI3C^`Nzx_oUdO^4^->HO2Onl(M@pzr>K(@Q)i&j~*m%y3_hV?TkK@2{`>l*+3Jd z$CBq4w-J;i_%Oiseya^EhMB%}7L`bgrKl{nkpzl-el%^OLhlXQ#~$xZKS~OdvyVOz zXUP6yUwi}^;e>|{oNvqPfZA{{&ru*8u zv1Dd4Bq<0R%0T*Lp^It?LCj7HVPaXHeEP#PShMNAqb;yK-=Dmp56V-VXd93L-2ii` z4wEXmzEdCT#m|58`+@R+H0mpnjmtZ%oQI`T9be5^V@!EVvtKFh zIGiEIc1eFrpz7?)zcB88b#VDl(lGi6AAZj=ADP55!vufAjFZX-;+W0SzcE4H<<5q?>#$5;3ix)@h`Ib{8JxZo)OdHaGT}6hh zE=ih|o7(D_l*M!o2#H;J8GZ5%E(3NsM2L+8WJ3;VuUuinWjJT>$AYtFBAKNPwNIMy)~aJL11xzTbmKa8{{AL! zPUvk00`2J`{z)>J{YV1mx-n;b&{1?bGaGv?1jvQl>Y7A8WOz;ThhTRtE{4AFN>vy8 zzJy3L0p>O|Q^)}6UwE!jzDu$a zAxue?2WTyRGSRNBP&~BibpS;Xz+~aJwzxyjs z%5mZYErE(ek?)V9R*teC)*Cww!=!LB1m91JHi6`>^9&ij#5IX}Jihx2Af#RERweQe zLvE5OkDsaDBrQFwepA54Q_rzQOk&l2#DE6ayP?&+40bo&(;yO=r63|)b~>X#k!@6ntuXFIpZU>2V2Zg4M%;4d0!+SuZ_%}TcKdcXr80h8G#0lzU+J79+`!g z7%ln(&AVk<7-U2yLdJx5Skfip)p2InqBNG4^CGtj({%(>SamEF|6)~m>7oT^6l;)B zY#vOv9-7s7H$U9^h~Y?*4E6@T#ID(u?aTMt_%!%@d`8&s?snQO(1|HqW^r{>6(`3! zV$y-&PZU)Hhk-kI3XeD^JB2CfYSD)F-Icc8%*Hhj^64E|lrQi4MW z6VDJJ@e1n#-){S`53(sSV2_nvBdx0>^3H?-?uh#LvGtX&tp;|(nt$VRZhc_67!Sl- zdO?g*pjH$ic=5holO5M9D_(!{)z$!Q|ParW_Mk?_LJ#A+f`rw4%X%bl&vE#>`pExajb_ zd6YnbTfsH=Y>GVX7S$-2;hPK0Sthx|@F(p2zy;HoQ}2V9 zB1DYsUG(l-91GoxJg(WcsSVI|>_mDfz&n9p2f*x#7zj%HY3SQTp@Iv71n<8_y;K(L z=XAUCiox9^ZiAz79`6G++sM)z^!+EO`R75kP_QjT&*dbyIg1uG&^PsQ#ToypZhJ1Qk-p_BUrlW(fW!A;6 z@9Z_~pMTuAs_1ut;0_8^$SnxTfMXc8{^}#(N4u{I4b?dW$qRJyw=KgxVz~TMiqHLSreUDF?a%J%k z6Q`oM>#Ctb`c=m5v{r*&mLTLbk*wB)^q;gvHme8h8{)1|eq!A~@DG%kA#+53y3@Fj ze1QEMh`!;A3uNT5B1xl>snVd0qR}!lpnTae_6t>10$@qxcJ*1dA?5->GIpnN7l!gb!Cy4LiK};2QF`% zW9hTmZxeel1@j{Y5`}6NG1tE6nz~c@C)ODX8`sOYavYlPKOoXlv@5RDLr{utqRU>y zMf4CbMIak6k%lcUE1e)f@?J9y=@Al&E*jQ-$=Nk)$zzRo+P8jwCwyI2c`mg;?Anxc zX*));l$nRPzRY36(CQ5kh5X3gq4(6(H@8)xCsX{nCwVN8Ny48kVTm`y;PNn-#*yjT zF|huxGb2IqJV2g({K%-t+G7mc>h5n)I9bwp6;kbxOEy*Ezp|fuB)?pFDrD5q&@$+* znFdXtnaXgWl+(U4Gj(n8&Y+zfWj#iXM|{=XLS z8ojVQG}3}9F$&WY8G&?+SYJ~b19W;zQ%?sBZY2yY?NgdId2Z|NAoJ~N@glGPaj_8z z+zIo4s~7x(Mf?w1v=~K{7X}2kahFI0`ZgP&>X^Y7@mF_a_o(}hY`)0)DjJFh>(}$~o2m#^bF8-@$LGcy{(V~r@ zAs*Kb=9$uvrS%>w?T4bpiGuI$iot7Ie49Za6okaUsNRd+^gS*t5o%dHGZJr*N4$C* zKb-ktWOowZtaror7kQlGAD1IGF9T-)Uk8U_Y+qvQEg1e(kp+_#hGe17`F68+eR};o zzJmf!$I~pZY97Ju2RL_20HAiO%CF(4pHOLlL#OUxm)xP#3~z^mdF02}-)f7Vjs9q* ze|^^MK5?g>Lcmu$O-eQ~Xq6bO$4eQ<`wJAuw}4aT`3aBLC&gU-9v9G<**>zl*P6|b zN(wKemtcQcLf)-FnF}?1t_bQ4Rxd?Y=_5Qdd>hyeCB_TTXey!&h%Tf!@ zE&?ZEB0WtS@}_gOQH(6AlFq;DSKR=D82$IF*N?@mm}jguh20H)vDL!U?gAz0JTo8b z@DsMhig7%Qga~CFbFtoWvglmat6LW5D>!d%+oo}312+N|T?bHc zSxg}FhhcZ=qN%9K*IBQK7*i<7KE}^h#q-K+qQ?#+S3!+KMv^$>)4N{}fl5LI!3itI z5CHDn!bPefj+x{@Mv9xgneAZ~an%mp9x2{0bN^r;rbxIZ|JTr_LIlbtA`%5)f0FNO zv@_#$_UK&U(WqySx>fy(iIVRlHWX<`l4wtuPphR!?jhQQdMWv4X~{2cp=r9P9H^&r zK=z#rayj}{#Lc^pn_^cITlLXP4-T+T0XNEs<_tZj5NY{1a(aD=tz?sSS>|iy*hzQp zTbA~1Ue7K_UwvX8aPjGNqppV`U0VAJeUKn+Tx!(H|Cj}jp_A4_K?>aRY_(15O?1bD z!KS3j&oWx&A=fQpL%(-~?%rw6UET-I&d-2Og8aiAuoM~F`l?lcIkP9(W-W>xN z+ZWEjZaXH3WMlviZy-ltv8A(=anN;1!lt+q*k(I^!l?JyCR8m6*v9Q+pmeqk80d+>r=y=51K067l-oKmJdqhs)!71WG#`Q`DUJYbc+c?Ia zHN9<7Hl;Y|F_#RZMf^JjB!8{6`9J)-7FcV4Qd{yTQIB@I8j%Q(m6phHE;GGu4l$~> z9Wr9iV4Qc6V)$qT$;_vU6_V-))*WytxM9<|MM*57!AQca708%vLsGK-?pX%kt%y17 zpWgKQLw=9RKdzI1z)4V2*oI`PHLz_${{VO4;qJx%a&KT-1s3U5U5VB@xe2W z%tRAr1{#6?F%YO*7O|!RIdn;4y9&ctTMOZo)-?5>uyh-K29GstWmvI~K*H$)u?M{} zI3!YnZIt#IVfo)iP?Vh6+nwU zKU#=C7Owwf{<{bc^q_vK$`HoyP=FO63IFOLW638K`A zky;K?sB}JgR_uu7!rDKm0sN)$K>u#d<&X#I8E}dzZsRaAgg}Fp{3^_{W7@F;*anoy z#&bZxO}oZ}1oAk`{cR{HZq4Zu{NaN=FC!FX^#7(<>#yAT-`De}hSF`inY2nz6f9Wdmw_2FL zfB(1MegCavVL8RW1n6t>u2cl8F&yBr_xm@Q|9C)TCNbQ5*NlMbhF#9ffF^jEcPl&$ z@eUEFnu;J18(kI)SJ575x%KenJ!x0UU@;#P-QHN~Ywqw!UONGjJKG^9Zeu@z3qipH z{@xV#3UR2HWkw)%F(W0sS@GHTg&FHjc5>6u*@9SZU>YF*ykPuLEO z8@>;*vE{??fuFF)g{k**es$er86(P%q<26vFF|QnFaro|zXb0GsVkR9LEBsGFm47FE`Rxk-SGmF#K#vF+?Kne^# z@~mr`A<)ea9r%;i``Z`&?f?Idd;ZJgJ)_o9Y?~Tn1h{VjnLlA4g*&^A7^iP9lp+{g zfjH_3=7%Vjd%YCMhXy^u_&1PA_y+ThpRfp^%Y$P)`JMauo$LCY+xwS%DRA}y5VG+H z5OQpUrSK~uld#r#?w{=^QHCy@ybi>qA7LTOd0-e(TUmXCoh)S+qBQ12{w=%hlvhd8 z2NKjQ$|OctPV9O%z?+#icI5}#d{&`B^T`a<1N_1pi{jGnneV6NsZo*0@ zMMkWi__cWYUhmUYKBkIpSqRY-ZbyX;r!sH~TivL@3VuYId?T17Fl3;kjz? zAtNnm`>3zqCL2D_dj0Z{^?4%|LVJ8*hXmPu|A~)9x+2_V%GGxupC9HnN}_4s+g!$; z_hf6wTLe`(eR*oxi7HQDTGLq6AmL%-qdq{?+=FaurTYAut<7S7PO*h4=L+g`y=IH3 z=DcD*)&&toq;#R)18!Zl7c+%f3<`6K64Y~O@Dl&@B|GcyL({IVAJ&FFX3?m{YNXP^ zmAOl$QkM%=({0tze!^=H5+lo-U;dc&7P6dC2}Vo+I;n`B40LPInzFnYOck{2UOs{L zThiWKnIFExb^g5ZYENO%_KCG^<+@s6KaG`9EF%uBE=R*TSo;|8uyc3H){~x?dhV1O z8!+Az@4Wo&RoHON2a27iB>qNMt zmz;%U=}eb==gk5hPZwYGo;b$g#ODX+F40lckri=7O1)spE};lz|bHDg(>UB|9(Sh70H;06`Hn?w?s=#NM0xsuR0{?%&>tKU|DOt4BRL&MDcUmBnO8GuL-#dwG zKs`QoD_K7zoPKW$IxG=Z!;_l%)M2`DF9~8^U_Qj&?ts%KnQ5wBqF1&rc{vlltkr0$ z+nCo_Xyg>Nd~}q5^LF`(9x$&#`><^nm^p++Owv!7;g}_Yeg+Dlv$&+_XdA{&N=IQM zMgmH`S7vvtS1C(LI_X~1+ltdtM@@}uS+_iD^qH2Am69D4zIn0^3E9dMM%L=o{>anlqQGBGz(hma=N{t3!%H=^Hr;k7*J1`|KajB9^KOoSu0x>rll4~;SOsW2DaOH}WRDNRYe z6-;u&A|^JiVoymht8!5Hj*9%1;hu3sW$&iYXfV2T zKs)J&V1HbM0J`n)5<9DiG6(RR3E>+Y)EXcbFINN3n_;c}|I*7|AjXcSQ^5{2Ka~qo zzWktpmg-$N#n64ju&WWVx%L4xUChfLuRVg123;`-VG{U949o1{1qtb5u24VUFY3p- z0dIvT4+vZ5!6GOqNJfK^)j9Y$II1}Hmtm{c z-kJi}L+`X2S|W~`=ml;;uMj8F7eT!O|5-}w(m|@{mG?iCbzNnX;ScQs0@|h02E%*5 z9BbWjL~7vN=wLUIVnZ1AW{Ho`qy`FZ&#aVoNh4@m(*}m;1oJfbbf`NWyBzinb^>Yo zbcX0L8kU)ab;5E%{74}8Zz4lk3bJWG>hi!x^jLbb3zobNO*y%@RF6xxAJg`|LEZ4u zP>7FSmHKAt6f2I#kF+vR=C6m_|tzKHs7m%CA zIby4i^1S1|C3@!m<0o#GM5cI}pfLMQjb3Aqe8;zPf zJT(8M*Zi}U@hQB#V6r;hkAGTJYozQH zb}zr?P1I+VDEahB!OcLRJ*y1@VPjlss!fp8uub&-qWPj$AIv_Ucmv1b|Vz&c) zOpa^Jr>m%k@Z$Bb>T@*Bo7Au-#Y+QTw&thDJQYlTH1qxFY(AMIUT@#gH$Y^FcsGbj z9|Je*#xM#U(1Bkn(&N@@`@-EA?n*k#e<}$!9o1n2tfMdS}GgC-W^iZXjTc*J{vFpkZ~@DU%*A( zF;XdIDY{SDf0v0&*ZF;CR}@zt5Oj18dc&LHkfx_iWv|VW2#bpnTUHaRbup>!lmar> zg^IhR_q5{X`82rXNo?c2?ERIVr&|*?iKpkqwv8&(FMT3*s5ule3jhzL5QwEF(B0<8 zVSOc1h%1y)J&6dqX=!m;YH761#peloOO5y(xSP^9Zd`$R#0UBy9;Z{zBSv^8q(P-A z*I*0~u_NsG%Fu`&uz3V}jrA#AyQ{uYlyp?=@yD&N$}PC+xqb5Oj!|rJ;3S?r&Wq2C z@#<#CRz`6zRB)Z=yy*UB`Q!1&!ZhO2IiMAfdN1E(YLgp>_N`XS&ClAA&;Q=UuIAPU zH=g;YX(FKO)E&>ecWW#C%5HV#yD@d7b|rAzb?SBK-N5^;EzL}Wb+Qa8dV?Et)`?a* z%}lD5On*GQI($PrtBxXjn@^o(YEfbZTO3I=|JR?Fx?W?S z7vbJ~i~Br3Wzkr4sWZXw+mcq6$g7Jd_T>!K8Z9mV^u+$RZ#-rUByDXlkAeehoy?83EQpY1mbonoh!$-dj zh^ZvYSW-j`H%TH(_9Bf!k!2!F*0Br8nh9lQ>}zH$(=bcVr}O=t^R2$;oYy(e>-jzB z`+FXLcyZtE^>bgJ>vLW2>$={T)+1Me=h*b#qiAOybm6Y>&3iJ${8w3_F?oF6;88Q|aP==oD&u)p8tTZ*{se0_>*MTp>hgNR>o)}UIXG(Pe z_Z;3vZo4P=+A!nOr|JXNHBDnSO}24Hx?c#h;vUH0yY#tr3rPCGq#8v#5zC@X5)GYy zKe7Pv`ctlD_n;Dj!fSy76z9*gXtscP$CofynmZPEF+DPDqU)r<-nq<{o87ie@<}~S zSy_oJ>zM4si0Ht$GIit!v0|znt(WRqtw`Su4`2(SOQB#hGO^A;^LimG@}g;#0u&Z4(|3RW$BCjjs|zO^S0C)qKY&Q#B)kPHzXd)} zbwGiYAjjU}Hp#+))*Y#{kS-Nv#Y7CyTN&>mqoDY$nVGCa{r4bYZ`L$y;@}pDO z?c%T63%rafFB1YzwanZZxI>eZZHhQ+h|uTK*l%>*U+WgHWmF_ijLiUQ69YtgRHHXvJh$C2yae8P&6>;rSAOc@F<@r1CJY znOrc(1Fmpj_fd>z`(kKWjN^C;oTL!xK{`L`;XZXMafa-vH||S*9U&&eHzH@>sv?ZhvGkqP1ll46s&3oh z;3q(bQA>MkwNZN_ zU}1Pk>Fw6!#5VJg>*gf+$2Oe)Vmh|QM;~wA163c!lhTWcuZT19l%b=Qg&mev>|I^6 zu8U=lazePln5G+U<_g5?J7N%Rq`h)bTT zePS=J!h0o<8Y1S zgF-cBX_l;Pyd$oUYe*{~V+yfG3BHyo+H)mZPf^hYIq2rh6+bGq=c~-{>pKYQOvmf6 z8^Gjr01e?@)cFwmR4wSb3{A|w;6b7L8VW)Tv~joX+(Q5Qbxrr!bCN>`Kg~k^`}kjJD(51KR28<3XCH(O3N0b7xfAvFiII8GCrkl?X^#GQ1#1Y zRVZBO!jm$v1zdoc!Fdyb_JA&KmqK@~OUV0ZIiT@oUUk95WSFKL}$SPrXKp4O&&j>8~dpWFlQ8J5&JlV;#nr z&X+ae#%_mRzt1CEtwk5yb=^EMA#2fh;>KMQ5BKYPPYe3?Ywu7!3JjYypQzS3gV-&8 ztrKKXD`Z`G)>JfV;->0pt=gBLTnZU#Z}p!|`_d12Y`yVz$~r86>)>lSWx3;GN~v1t z=Et+^Gjg4`k2FtbFHZT0yJo(On`pRZbo#5qXLa=RT;i>=H1;QAF<0G;3R1w!kamNT zQye(Uf5FnyF~P?}IvA&09?&HIRB-4JCkN`dUlqQXoy0)XA&b}L?XKklLv8Ec%Y&Bk zn^1gX=KCaMGi^;}PQI#@v9;Y15mbpm^@+2&r9cDp4HPWwB2-rcXIpkb7ZLv0g7aV; zLg`t9#Cp)MsFJ&YY8c!aH%2@D)Il=4>uE8s--N=81h?}a<0Znzq8`Y+yUr9iwcXC> z(!?9t>aMI-sV?j3n3&Ph%1mjGQGtxkxZQ`Y>!iPs%Vmk>j*Xk}8=;b(Z2ceLEyMl@ z9E@`VWRq46co!KU2K4F(G@(=Pmq#KpBf*kkJ@O5ferzEhKZrN{04nCypr&FbfaUUR zfcwSzZmTgTK>q?bw4y{OkF6UR)o(u8E#%3&XE-M?^v! z3fs8oiA{7sySwR0VVlQv zFvnh+(8@HCoPI!2Rqq3=B)AY%zAjTh+9HoC1-x|Kno?x&muV&3mWs!%&p%rx1f}Ra zj+D1_xgj{6X}Yzl)i29P#}#WA_xi#yH|0)aBcq#BE|q4o!uR8MIo=rPK}sV@Pm!-Y z>srs!s2`LRVdJF?(5P)uB?%ca>*T&9ncp=aT>a>I-0`=s&b7?*mc83yHi-?=IABM@ z^EmWrC3E*rESnVEjPFo9G4xk*GXe8l2!#kv4SpGYE-tq?Cg02tlc{*jR9slCJxr1Y zi6uZ1Q54{+iIRoxYsq`rk(ho06#Tt%1F1)YBPHcl(gukOeL98EtsUW(!0j&hD6jyQ zuMM>#3BdQf1mcTorz2kw9s6>hlFQ!6J7tp`z9?L=f4eR!L++j7;Z;%<5uriJ2FA6< zBd9kq==XERgfG%lhVhS`DJm?NFMj9P4N!4$qhhZp&56=hOQc@`Xy^{WPIPnkE_ORZ z>!|}Re6IY_9OxTHbWt6e6?;U>1wFnCU1x$AZuVwka0;TTRhQIyH~TKZn4qDfk!R@4 zM``72cn~RrbEU%Zv4(EQJZ60aC>s!8^h`(ge z+I=oT<*RdrucA#obkX%=@o`oV(yj%ucA^;3XK^Q5`3o*{E3>Fu;S=mV7bS)JWlHps zj3#Lb=2w#I9WA-<+M7ZzZs7Am)fsu69IMfH-c+>g)bc`KF~(7&@J;_neDkY5QRMCg z<*yzB!yRpTyjk~fX2dxA=KZdWR&}NNUGsZ6d@?f&>ZN||#R4Uf+m zqg04l&P6(oU!H{)#+u+s%(hU7R0zF}3}H)RBmvVWJb3wZW|kL&e79`V(@Sd~p(R^~ z+skq(Q4JeZdbddLfS2Z=EHJyMIgNF$K?4W^PANzKX!(ciouzNO7B|=xmF7o15DGo< zX|1X0+Z_R&rF-_|2|v!dn0awbfKe=kwLIC{*tv`|Jv6v2^LPwu<21`#n7xNm5gg9k zmoeU#lkEu_K|4z(e=ZM{RWjafc6Rz4XuVS@N>^p*LDk|KwmIg^eUvh$JzX}_s&KI~ zIy%0)Aiwd;%UoOYgRp#EIVT~vbC=Nz&7p)n?_XX_Roj2Z(Kxx}scdim)$A?ojFraN?n)Qn|614&skYO- zhsdg-p!>^fA>ba8g{fT3T{hK_tr~&mPVB95emKYOC~hIL-%k^IPz8cXH*zp*s1?b{ zm6QYnDHj2nN^5I#O2)9!)WIJJ3FEwIVvrMbS{4Uxi@{FrT_*{e7=pBNSy z0v=H=ay`a`Dm@fA-S0^z^3VfOh3(}Ri`8QLT#}W$y)o9lne$Ti-S-IGjW;e{GJJ}A zlaX7B(KZ&&o;O+3DlP5uWDZR!Npp)nAAGMUci9{J-Cep-$p;qqu`1VKnjimnjcs_# zZb%lLbx$c-4c)ur&e6U5)f%!*R_zefxGp;ru6gqOk!9SNaC)yqsK0u`%DHs2`F~t4*JD#D8hS*$BjL33+VW1or$a^C| zsX1L-`Z}e~L#*)Y8i5JjkUb6VV{a>(PbXNNH8xxP8s4L(_rf`~Woe2Yi!mg(Ah&wC zp6T>hXF6DWt|+>5R0<%jyG_q7a)vTnSb>nuY)B6X2?zx&}t*%-=YV7ShBz#jZPtWaDa@k>A_a4~T zJD7fQ%N;)gxpQi`Pos@i3us6IvCkCEjjCJAI_a7(Rpxx(C%LS$=~|e?-BX_2lW7q{ z;uRQm%6(cP>m_s%;ye%N`aP$qgNXZrY|(q>4r*h;SKmZQ6&l8C&Tg!za*~0$oG03g zCLEGpC=KnBf8Qe(SaaFFAxCPd)VrfTCa@4tfCpXh>gvPr1sE;!fLEp>} zwgjMqDo|`}X%oR5p^RW_W`l?qReJmc%Kh~+F0?+*PAlp)3RZtqvs?6V*xV2oZIW&< zh!cXUjX;Z?%??_^)U}x@;|6Z5^h^tfE(5z4BM}-CCMR{Vw0pQWGA|>1o9=tPJZH0} zNk*n&LSk^pXR^QNtIM=o!}V@jRH%ir?P$*YCDbbBC3*tGf?ba+fbJ_#AvX{)est8J zCAQ$Bx%ujZ(miv6>xP1ahx+zzy_crjmlJo>kueuK)I2XkmQ-{&sVpveHLZL$)zr<; z;nAh3m(KG#dYWC|V459Eu8fmR7gpMLr(lyP`E(LPb&AMSkbL>efWcWas>JKGYxUbg zNm&N2E^CFgcbXpGu~|r}@&T(1B0c^}L?Evi0s{0JHP9q=ifm!=$?N*E-CU2u#gH?p zs_LH8rW@PUa=lu8-E_R;4n9kh)SXmHJ+72C99^E5_>8eocORsY0Q0XS7wa(pVYiFT5e?F|r(n4o%)PD9%-h zz#ak9QS&M*g{hn7l~jk_E_$L9BJU`(4Ckwjr${G1s|^!y;Eil1D)6?v*%5#7bjO0P zKwHH7S06H(<9H-?msreQXdR#ZGOzNiLd_vB+3B35(AKj?uAW(p+=V4T+=S9{3;L1z z@z44<2GrhP1o>2~)NinlJCO^|1}pt>SU^FHSV9y)3{Giw>;CPB4WhM>|cOZw!rY$PigIo!|Q2CkI%0-8`WyM*HVDNSRz9ul$6 z2FV#qUH{RF^JhQz+*^5;U&iAP0?;ln4}y4sz+s|+60VD&Cam**D9ffAza-Yeu4n#V3)Td|CfDPD+jVz)J2bv8 z8yZHkrCviMu!7B9gf>9atI(iIEWTnHk7}g2=%e_IE1cA>$0oU2S$ewOn0gvVwi7s{ zZS_PNFuSOO^!auh;4i<0m<9++Z7H0!RymRx{0&w|C^EW$om4mqxcWPo&^!F}W5k?d z9TiEx^qGqtDALFV{}}|}*^f_Akspfez7Wg~NTq*+J%p~1fTQUr4OYk6P2DcBvc%!5WO!NF3Eb9xrJCAAtQ2Fr?w3hr>AZ!;MUat8!L-xxC80qt>@P2%1pV}W zfNmJ^`@kXduR(9|e1M(frxyS;X+OUoty$(9%;-8|d2Qqn`w}ZAkgY@i7rv41@_jHo z?Me`09=`I4RzA_nELxdG1}ln=Ew!>1eP3%=)}j@2;YX8h#avji=vIvGzd02vM)!Be zZ^c|#F&BPw%~#BY6?0+5Tv!2sRxrBnAmjfgMu!28*BTi*;4HG% zEI~A4;;PN#iyq3$C8&oeiWz)KT>xa^NaEN*@;(@3?V+n20y7l%bCOqcaYc!a%rG>` z-Y8O2rWXs)-fDSJ(on?~1Yv>Ipw2-@-e=JZ&fG#|pMsNJS^o0Sf-wPamh%_J-WR%b zw*_q-e$(RtE3C}_8CK?hW!(QD1b$Blqe4u9TK4IBXnH+>@t^8jJwyy*A~ZZHY&-DP zDf-aTUgUS)W{?>7H{RxAP}s}y8*ek}FTBk`(4hW@WPT_ZaSYUUU9ta8DZldb=Ntop zr68a#u7OXOhhnU@08Lno2@^AZm!Rqk$l+--c2zunnZK|%fGz!Ys1bsX`a&R|Tbl|=DR}N{AW+sH2Zblqh1s)`2xYXQPRsW59;075Q2Vt zA+kdL=0)iK+(9a_b_sjwUtARaktBdFr~yO1mQ~Aw_f=vtE=Yu zG?X607U62ZF6^5`ef#fftSALVnqq`tvC;hRe!j{yJd) zPmE0x(iRG>+(pIKE9Olm){iV^ypA_i&|UJ}n1bjgbh`h{er|2TxIk|?M=`8rX-(-> zKB*Zr(7tSUkCgv#_#m^2nKg!`+apAv_Qp(zXv37@m?@PVH2i57h|LC2U$A(*6Ie84 zjlWj^vr37d_eK76{K_T%{KF|*#!6%>(39%%LJR%d^(`vP3!ia4y6^B78mW;k+b6oTQ_`$3ly(|Lh6kiLx#&+7Zn-P zP!NLBuB8Nwr%2Grrm~TKhO6HlWL^He)9B|@V7|pGm-*{}{Xa1_4O$}f*`W=9ynljX zFt}ZBFmY7LV_s`69u~?t=>ErEI-#;4$;t^Sh8A0!*N!^Tt>8|3bF1#TR0D<6tF23V zJ_T;SqI>@T)Wh|78zPX4Lj?qsS+|SF+G4L`S54nn9UVhh&=UX1l7z!TXnctG*V`Hn z&#TiWi*IgjwH;ME_K|16CX9X9EC#AQOz&df)zoJ*5ah!M=ML1CpLXdomEhsXahq=Z zY#y6`745SCRr;r0KOMbtfj{XWTDLL8FvkcQH!{#IS(9cKxBGQh-8;FwE+ zyZ@R$iF>C=mknknhXROa3vl+2#N!Ro^BdUQWYE#&GM>f>eE#sYJV-qU!U<=$Ep+q zt=D78v%m)s=)vd>$!_Nc_nl_=%shA>!@(%&h$Y`H-ilP%zu!?7+p9~$)wlk!dpnXq;wsgm#NdEg;cz!p`A08m5MppEvH1y zAnLozITJ)L-S3$BOS1ulTXB`3ioX&l?^=;8V0Ft zTMECVs>`kuk=na&)%nbW@mj%m#}8{B`GZ;Vn|T5^XN5t-`B48IVyopz{40D^O#V2UX|{J(-M;uoh@PX^=Z1G$2?^VGXOKf3ViSCI9g5rN_xjuq!i8 zmn*C3CRD^}dNrt`V#{_4_v=%|uxryDFI>8FJ;j65+y9zxJQ|U&0^w%5Y4T{~O6VB3f8V-*xxeWm3`g!o*1ZWX&3h18c?iH+5gDknR3sn=RZ)Rx~tR z>Hsaihgkd{MhhoU`G(8{14VWTAZ&S-=&x1ttNi97hX7wq6qXkvBthSktwEwHAf~me zLoJRHJN>o9e?8&%Z7Se*i>$|O#&EMj**oZEHKoBc)IB9lO}qTEIdN>$4JCAPw5<5G zx=XPU_8fgOxzaQ=_2yG>zuvK`zR?^vTE*G(?M^sX>A4=Hn!^s=n|&!VEnBXotoq1J zMbUSoX848_{e|#rx@y!KX(#Eg8++6gUTQV1Y3$39cu&WBhrdP+7-XyS9!8uoLV=dw zpeoZIC+ycIf~dJwj>v{=ng(6PCi)c8{Jx*#Ectmh`2evED&LxPtT{`|gs@Vj$cw1(Q= zw?=$SfoIr1zi>$ZmazBBXxR}QT?#p)Kj<2c%ufi_u%*H+**$OC3ujIXl`!_P~N?iFW<*$|T3>1WIr;5@*t>Nu3ugk6oFWo`uU^W*MSz7jFBX=KSqc(2R z`;O6xjzovCr5@u_E0Zlh!D&ar3%aYDT0>MVpmMr``Z@|T=Gmk zm5Q98=sq--BCWmPJ(Lb&5Frs~KhI z=lr_I=f=)p!xPrxWyM0fk%IosH5^6X*-EOr)x^uDWnYs|C@oc@CnR6sx zGLd+8=keK!2>Vt4K!Uwlp%7Y;m)-FV#_zX(JaHucJ{nD#tp|UiKi0}!H{>4MxbN1s z1Jn;kA{}ANfvNf7#)$74f^$`EAnu53me4z_`*C1}e~G zSAP`GqW+R!o6U2kPM1QiWS?bA_?DYjYi^(B=ks5$O!x#pVbSe8}yur+@kHWx<1HT!OjjLpcHBb;mI9%2r?RB;n=>>(SJ6_;g%bCqcV1Y?aHhyi?L zMFAV?+8g#6vvjE17|=gq+*uEl8#@HG2iw-PAVS^O@4C>OaMSMHDrDc4fz;1Iuv=h3 z_2Wg*Jm&zGqL?CfLk#y0LmCnj>kkW>|n1pU^l;{%l5@p(x(= zQ}zlpr?ge6w{2{?!K3n(uXm#KeMWxV-p~4*L>+Zs`JW70x@9${>B`)KuQMYS3Du(z zejUp_SouiWg5VPY3Uf<9657(fBR4dvflwkH^?BVQ?g%RnLbocCkahRm5urpL7Z1Zg z?;QWQa?>JE;$Bp`F>vGOjF7OCT*sGMu3Yq;N!g}4O<+i2c-yrO*sFb={!Ddj)DAus z+cJpQXkRJG9>^!;+-vB48cpt#=Gq#QoOpLFH*C9oCeqr(DFPdOaivWX{^1#?6)N1 zf4$aWex$v=rX_6_e6$cE23|=OECI58R|`g2upr!%D@ZCTNUHPXi|ysiSJXOTF0@Be zw8YeUwgyi*39V@?|i`?Wv_0yi!N(bIw8+-Ovbht@f zuX>weBcs)fwi(>#K8oqm?YrCG6g)Vzrn=(#Oa>3$TbC;K7;8E>E2OOLha_CCcL3wc_?D=R_+erOCQd_u@APY zv{#8~1L=~YY6ax72dud$b`3;cw6!RGBSda;c@`@AXnJ7=ZL;OTrP6prlH>E*rZX>G z#c#DaFqGL%SWb6%Sl^}!hAPG)ul-V&(k-XUE8?^i)%%b&yohRE=sxzQhu{v2-FO)~{Jh07W-kfCTym97P)MYA9>nw@II9HpJ5M+v|eP^EREWvTbWE z^hcf>|HZOc#C~jK>r1oV7%)34U*lqsHi#uTERC!>e{%V~|BoaR8YtQzFwbqCLm!Qh z3+D>wKKtr1+@Pj?UC3z}?D8IqC70iiXMWCSrQ^wocoL3?P=v@R<|!&z`<}$4X%BlH zILiL;q|3QnzS4FeiGP9XaUyFME)=rGEuCtc+4)^KMS*bY9NvbUK`=bLl4u}gy9o5z zS8`+xew!D%en33Wq-T`ceP%rTnZx^uN=W?OEeW1%F4#7$!!B`sfV0PM=OpnJYI-+? zNG1j{br8Xe@{UudDaZUI-?(v4>|K|qOuo9~_>rgT`6_EAHXq&vgu{&7kOwOBtv9jK znS4&2UiZmPEt~MpLR_XDSDa3UPrdfphAox2%H{>&X!QxUm;u9?-8itC9zdDZFQRr^ zi+;#1w{d>fwB=pt;=`k({aZh7erNK^W=Bk60w-xRT%nW|iMLTlaOt@{$GA~uuytv7 zT7)9_25&=X(RX$;JX#+{t`wiyyzSaL4T3pkj272}bVSj2q3Yy4>&%QMwRUte)w9P- zgBHB{A<1%=EF_Gl+;(eJwFE&0a&r9`ih|!dgV|20Z;S}@5vsmVDS?VM_8^A{Y)woK zIBlm*da!A{| z`1@Tc6z3&D5m=hE1Jpd=e-Il;T;l{5xooIF zx*pnsG3i#$IZGb%$LOgBm1~md%ImYIj{*gkU7FNndo?P5-HyQd&3b22+>pgzr#)>M zl1wAklbLefEVK%KlL!1>qP>_%B|d(6oM!8mMqp7OP&>~e$jgCvh@(lHhbXYYq|UWFc>yAdUc$16srPq zWI%n4MnJ3SVaVZNQPEaw#W$!Bhp#K{+48aWsV9B(gn^4>^Uf2!g>O&K`iWq}I*BQ>P;i6am9K({e`Po;`mfU!9y85l8PcjkAo@JQ+|n}IK&kM3~v2e71vA$LLaKmr2I{fZHQ-*LyAwZ`LQ>$d1q`NUORq{ z0T`!_l04qh8!0b__@8h@4njeg4U(>#76?11!w`Vs>0-S7~A4=KiN|(Vk zl;G`A^qtFIqh7`XQ*}4hG#BemY8`v{`RM2>_It`l8qNezRFWPK@D*Weko-(YDsRZ} zeh81+(;h`-%cxC{WE<8M7ZvLX3f$gXZ(?p4@Ob$;mU14y=_B2cz5dXkJkp>&8?(>O zQK>Le?{(-wQrBzG_4{@;tcImU&4qcJ5fD5e`RB10#I7#-23y{3&oS)U>&ia6j{)rW zj~k8y#j?*V2E)fn9A&-4lTx9AwqTD|AM;mqPurY6E40Yz1TWfk^nAgo2enFhQPRC1 zj%B}1_uO~d&teh#>xGPfqyP$l*ib(Lf+pGpbmYRSF(M$XntcX7?Vd^`20=}z?k$Ym zNJlk1ktwDWhmzpLeWq8AC&NxIb>V~%&uw&d^f&Ylio~?a zuTCDfxvnWtgRSx3!)`>)Ibeb4O`Cxx0*Pu%jqD8o71)XBC9s?0AFYYNw)tyH8mw(&{#E{_dI4+o}WHYuaE}w(-3cU}_JE0@i-Q zj5(!Yszz;7i8IB9eDwt|-L{W~DC@76drFu!6Fa36vSZU^`Ym9Ts~oPGg^lA$1=u-x z%z8izo1O+9YLWKRw|W5=3ijjY|d>9x0?6P8$x+>|aKzwHZ;b=Aqq$*$0W2Uoo|J75MFhs;_DZ)4Qq( zeP-1}x}KH{=5Y58wC{oAT^dMV;RriXQ@tnlQKrh$a@rd3)4DzkPQMnd-2hFy#6WR3 zx`ENHsVWVfI`<}e!UBD8QFv}L+R4`Lm^yFhgA>NOj<7kyJJ{Etmi+*jF0^(Rj5KAS ztqLimCDQk~^+wu9M>AYHI^ID%Vc)IrdwYeGqR&U`Epaug&w|jbajUl9!Eq3MW$(kt zQMrIAE8z7g)IPcm63j|>jM&F0C<`&c)IL!0ua#I`703064n%#8bEn^?aflMh?({xg zLMd*vKoXgcW|`97Ov)U4PhJ3BS|ljV(iTm$aM>vkO>9y zXBxmml(8aK6EWu}US&%f_L3dq%!gfqu5G&cc=J~OO+?yPpz{*_nuv>xEC8hk;R>fn zhV(rN^*A__i&ciaiWH>d&ahi3v|zU^10T;}J!JG@$rc=jh=SQTfLu0{Gk}T2{>--qscp=Z>N)as~G_g;wTK28=TH ze1mN@Cth-b-ULdwoAoPG$EFWZZZr^ukPhHKejO-YCeni}iraktc?cN=x6bYVe89kz z$J#?9EyCn<*X{L~fGE_Z{|wM$bQr;B4jc@gNbs2g-bAuBnX(LR`_U`g#jUK{ZG%6= z+~E7vyk~Ys-xYjxLvYY;x+SGaw@(8}Y5rX9hQpoj8`>#1o=)T%^*v-f|O4q)A}Cw~yk0J^9jDW25@1TbI?R1%Ru^`MA@yayK1xuiswSa!6h| z^8RwIm4%MX(o8`=rruf1_n=KwHKzy+xEZ&*!n~wOI96<{^isu9@Dyk14BzL>BXl!L zC}O*G?e-0WoLv{_k#!9$If=r&Anm~BF|i!+h$`%=;Bo7j75mt$ik9qW7d9K6x$=q> zmN|=b!t+j|3U!%V#;Opa+49HyQkhKYmCrqO$NyMVkv3u|`Giu!63|*LE`3a*A23_6JTB7@T{~#*3)PQhTTKAAUJ|H}8 zM?{H49Wne?Fmp>|t)CRNc;+ZP2xA27VH?)N1rXJOTbv{f`eY>)pL+n6Id3(Z2^@H> zrGk;|iDdF$o+rr{#s*iTwv=1hP^Bh&U43Lk_ z-5Q#1@VLy%1iK7J^O5im^}`4BW2WEhwsX&FZTxP|XmBx(VE8G-kjevE_@P-*$K?w` zQgc==U-~v~({ME2aN<&w_=%yd9D90q#5^7>Q>4pv>%*CRmV^6c`m)wMgxy4-Z@(VFw6$J5ZRY&h~IiA9U78X)hoVZZurdVLT&b*x~I|wiR%VbBecV86F47uU-ehQ zladGIsJhkoKHb6MD&%IbKvU|~NRo14H&Z=xGWrqDxPk1sPT~QJ^5_hlQFRfIo7h&#yaGELf>d1sY0<%NJRQBX6M=$nopAL__waT#VHror9z%}*}mzzO3*C0 zk2OElumRPF94u}m@_KoiQsQHV>WjKG)So-LJ;aGMe7+eneDtd)`2=E?H|nkie0qf1 z)5u;gJBZ(g(V$n@+liRX?2BFZ^J;vd1apQJZ zau-xBj|7NJP`udc9_2#1A=Q{|z|E*35atH@C(O>H_V}FLZFefcinvdLBihfZ1W`n& z4Zkr2X9|3+@)PJN*Uq3@Z}+Ln@1HEan=BpYv;AI4+{g(OeS7mB7ubW`54aqrjw^i+ zY6ha@gPwvGT1CY5Yyo0ZF461xa*d^|uj$l=5p73F?%CV-%SJd?U*~EmOQQqeYj+DB z;AB^pfqALha#-vI8B3Qet|D?{q^VrDoiU;Zygch;v~OfILT_WQ2UZ+s6CFV<8-h3HfGEIvcGoKkD(q@!fjz!Rk<8eh|E2C$gok1~=Dm5v z)S?>x5Sz=diw*G0+t+|0EmnXHJ3IM=w~$&K0>7suZ%~kxm8E%dz3Mh`ZPDbGs3&_j z>2iX|PRhV0%H1SjZq|6a1gG}p#K)ys>e@NDWWU=P!oNr1eDpP#utbc7NhCO=vDC0$ zk<&p-qTQwP^Rub=yn)^ew+w}nc|wIn(f%zDv}<9yZkGIiOUX0C`_&-l_^8sX8^!GF zX8weqw$E^NbpK*P{+~-t{v~Vuyct`f!o1_>Dg|p^h6f;`$xDGiM06R3^Te%V0V`?v zd^>V#(vSr^!`1q$QT)4&n=sRq#q^{)=MZWE^2c7&*>6Za{fLIfZX?ofi+UA^?{<&V zdBXF4N=(@5`YN}%0UHy^5?(%}yd$$i9 zc?S*T&i%sc^NX3s(F6SmHdUVbDH{A!dI%Njzt7f-cmzl}n9$;}C_PgT0+5ZT zK(HRPs>no-l>T%Ipn3X-+p;YH&zMmktZxgDbE$++YKat61s_4%KeXO0UWN9(+N(`; z9u0eF{-$=-lYJ$(lqdPma5W(KwIuy|umy_#g-DK%Om50-t+0lUvlP~2&{w}vB{97s zcK>cYF?ApJdCxd$hn=rZyv3zLwy56u)2ukWUE2mPF8xQjIpv40?(m7X%JJAOIT9P; zR(kwugV%f6_Ke?6=RbHgW{HG!zb53Il@fk=49O04gfX~(42*pL8vs1Oj+i@+(E;YN zGwXZbvY{UWwlI3cuV?%l+Zz?RptqmDds)M%<*m5N;FENrUwnbzp})Tdsws&6GPd>; z0OjQ-Aez;_PX4k3w$$)%Ji_WkYZC^FkW1 zKT-v8+e`Z_e4oieO6l)T6E(6k_P#WfQ}ZTdVMN*$HFi^CYDKJ{!h2^6SPFf8gYwno zC0is-g^jhVxgMOzjs7PhO2l76EUgE*8RnqX>Ly^luuE<&7I}K)lc)>Ml zBWpu3_G>3ZHKFD3ucDeU4+KXb$E^TXSP6iQ&{Vc?Z6jhqVE`fm@4w!xuiy+>!B2-<)SJ8?yIA((T~ep!PDbcKJ#JPYLC?@<4yG5qgivAFDxZ@e&>MulP`ql%#H2 z5WiDAPTZ~UFbR7UrQ7jy+0iY#83$6hW#f}oT{B8PyIpg4bqm@Z+aaL6El?xsQ{?+f z-xb+enO*;6x_`l61&yo3WGJ5Xt?FmG7krY`4@O^{D=~g~%8BcUPvWx6AGNXULwZ~4 zXRkoAONp)BhEG;jmRkqI)ylRU%zY9Hqi6lBh>U(wW?3^9G8}`rUo?^KFWL-OXrBTP z#s91v5kJq>$`8-{wE))fqi#I+vvy^et~}76ZiG}R#Obd?2FN-K-?{-r`T0vF5xP!K z`<@0!2coWQiv4TK&kw)72s1vEc?)`g%~Pq!7p;ChxI?kW4}V-2DcrRE8nlPDB2g=I z?gscq6D zPm%%Q||&*~TET+9mbQ zu?v~Rf=X|`F7bKXwP$~HtN!mgD!;%EKW3G${Qb`%n*Y}E`M;f<`K!CUvi--I`JWh* z6>YGhp#Yrp?-p@Qg2Xg<#DY5Fqaqn|04;KEe`8ADUEQ*9bHmsQZRJ^rl2?udZ0R!q zf#k3O;8GUo5(2Ow2`oUm7l+_%f7#63=11N)T$3n=9EK8an~wW|EW?@x5Fuc36}U1t z0zegjO@gYyAgryK3Xz;3rimZ7kr68qpF~jtjpAD9*or^g24Gl0;UH6P8E#Lcivnm- z0ChX|w{ze#Tugijg8=#(i-Lz(5bMBGRFL1%s`CTjz!Vw?%?9KFW_J_%ZXHB#))F4J za+j46`|px5ogAnI&$^Cy_dx{t+HBr$6)WW%EP;yj1{s((AZISHPnEs45kRZ}+4xyt z@oQvK8Oo3<3DE~%g807TewihRKg>Ofap=lDR>tbjAXn>@+UPV8AkFnSjiouVU8|4< zh&i_OEQ%@T3I_$fJ|Hc$>LaMi0U?W@rhyqLogcq4QC24WPg3!xRE~1k&F)+8ea^L? zii%2l+n_s!y6u5B1Btl^)^)=X-5K}|1SDh;yu@w1(=`FpS&V-VY(;t{bf5;v=!ZaMf|7vfagMKmlan&bxuZ;0O z7~{XQEUt{ze{`%a(=lOyA7gv~OJ)4#amIP-gS30wkssy$^X!V;|5ML?WzG5@wZ3~Y zvyejLu(qH^d4uAqS`^_NkJwb4=k0v5DkzF=pi@0}qx~yX8 zLK)x?$+=S8U9gnOt}hf#eREv+v*I=MNE>iwb3nUesdA3*Z8M|q;uj|n^NtfWBz`-e O$MnZGkL7K?_5Lqf@f30Z diff --git a/docs/source/_static/setup/ecosystem-light.svg b/docs/source/_static/setup/ecosystem-light.svg index 52b5f54c5941..cd9b1b98fb37 100644 --- a/docs/source/_static/setup/ecosystem-light.svg +++ b/docs/source/_static/setup/ecosystem-light.svg @@ -52,7 +52,7 @@ Layer 4: Backend packages (two columns) ══════════════════════════════════════════════════════ --> - + isaaclab_physx · isaaclab_ovphysx · isaaclab_ov Articulation · Rigid Body · Rigid Object Collection · Deformable @@ -76,7 +76,7 @@ Isaac Sim (optional) PhysX · RTX Rendering · USD / Omniverse ROS / ROS 2 · URDF & MJCF importers - required for the PhysX backend + required for Isaac Sim features diff --git a/docs/source/overview/developer-guide/repo_structure.rst b/docs/source/overview/developer-guide/repo_structure.rst index ecc56f9b9608..92fd0f90dcdd 100644 --- a/docs/source/overview/developer-guide/repo_structure.rst +++ b/docs/source/overview/developer-guide/repo_structure.rst @@ -17,8 +17,8 @@ Repository organization ├── source │ ├── isaaclab # core framework │ ├── isaaclab_physx # PhysX backend (requires Isaac Sim) - │ ├── isaaclab_ovphysx # Standalone PhysX backend (does not require Isaac Sim) - │ ├── isaaclab_ov # Standalone RTX renderer (does not require Isaac Sim) + │ ├── isaaclab_ovphysx # standalone PhysX backend (requires ovphysx) + │ ├── isaaclab_ov # OVRTX renderer backend (requires ovrtx) │ ├── isaaclab_newton # Newton backend (kit-less) │ ├── isaaclab_assets # pre-configured robot & sensor assets │ ├── isaaclab_tasks # pre-built RL/IL environments @@ -43,10 +43,11 @@ Repository organization ├── tools └── VERSION -Isaac Lab supports two physics backends — **PhysX** (via Isaac Sim) and **Newton** (a Warp-native -kit-less backend) — through a factory pattern that dispatches to the active backend at runtime. -The ``source`` directory contains all packages that compose Isaac Lab, while ``scripts`` contains -standalone Python applications for training, evaluation, and tooling. +Isaac Lab supports the **PhysX** and **Newton** physics engines through backend packages. The +default PhysX path runs through Isaac Sim, while ``ovphysx`` supports standalone PhysX workflows +without launching Isaac Sim and Newton provides a Warp-native kit-less backend. The ``source`` +directory contains all packages that compose Isaac Lab, while ``scripts`` contains standalone +Python applications for training, evaluation, and tooling. See :doc:`/source/overview/core-concepts/multi_backend_architecture` for details on the backend system, and :doc:`/source/setup/ecosystem` for a full package-layer overview. @@ -57,7 +58,7 @@ The packages under ``source/`` are installed as Python packages using `setuptools `__. They are organized into three groups: -**Core and physics backends** +**Core, physics backends, and renderers** * **isaaclab**: The core framework. Provides :mod:`~isaaclab.sim` (simulation context and configuration), :class:`~isaaclab.scene.InteractiveScene`, asset and sensor base classes and @@ -68,9 +69,10 @@ groups: (:mod:`~isaaclab.terrains`), and human-input device support (:mod:`~isaaclab.devices`). * **isaaclab_physx**: PhysX-backed implementations of articulations, rigid bodies, deformable objects, Fabric views, the Isaac RTX renderer, and USD spawners. Requires Isaac Sim. -* **isaaclab_ovphysx**: OmniVerse PhysX backend variant with an OmniVerse-managed physics - context. Requires Isaac Sim. -* **isaaclab_ov**: OvRTX renderer backend. Requires Isaac Sim. +* **isaaclab_ovphysx**: Standalone PhysX backend variant using ``ovphysx`` and the + TensorBindingsAPI. Requires the ``ovphysx`` package and can run without launching Isaac Sim. +* **isaaclab_ov**: OVRTX renderer backend for RTX-based tiled camera rendering. Requires the + ``ovrtx`` package and can run without Isaac Sim. * **isaaclab_newton**: Newton-backed implementations of articulations, rigid bodies, rigid object collections, cameras, USD spawners, and the Warp renderer. Supports :ref:`kit-less installation ` without Isaac Sim. diff --git a/docs/source/setup/ecosystem.rst b/docs/source/setup/ecosystem.rst index 31bf64b8ca8c..17105bbea5cd 100644 --- a/docs/source/setup/ecosystem.rst +++ b/docs/source/setup/ecosystem.rst @@ -8,13 +8,14 @@ Isaac Lab is a modular, extensible framework for robot learning built on top of reinforcement learning, learning from demonstrations, and motion planning — while staying easy to use and easy to extend. -Isaac Lab supports two physics backends: +Isaac Lab supports two physics engines through multiple backend packages: -* **PhysX** (via `Isaac Sim`_) — the default backend, with access to GPU-accelerated rigid-body - simulation, deformable objects, Fabric views, tiled RTX rendering, ROS/ROS2, URDF/MJCF - importers, and the full Omniverse toolchain. -* **Newton** — a Warp-native backend that can run **without Isaac Sim** installed, enabling - lightweight kit-less deployments and GPU-parallel simulation using `Warp`_. +* **PhysX** — the default backend through `Isaac Sim`_, with access to GPU-accelerated + rigid-body simulation, deformable objects, Fabric views, tiled RTX rendering, ROS/ROS2, + URDF/MJCF importers, and the full Omniverse toolchain. PhysX can also be used through the + standalone ``ovphysx`` runtime for kit-less workflows that do not launch Isaac Sim. +* **Newton** — a Warp-native backend that can run in kit-less mode, enabling lightweight + deployments and GPU-parallel simulation using `Warp`_. .. note:: @@ -54,13 +55,18 @@ Isaac Lab is organized into a set of focused packages that can be used independe procedural terrain generation (:mod:`~isaaclab.terrains`), and human-input device support (:mod:`~isaaclab.devices`). -**Physics backends** +**Physics and renderer backends** -* ``isaaclab_physx`` / ``isaaclab_ovphysx`` — PhysX-backed implementations of articulations, +* ``isaaclab_physx`` — PhysX-backed implementations of articulations, rigid bodies, deformable objects, Fabric views, the Isaac RTX renderer, and USD spawners. Requires Isaac Sim. +* ``isaaclab_ovphysx`` — standalone PhysX-backed implementations built on ``ovphysx`` and + TensorBindingsAPI. Requires the ``ovphysx`` package and can run without launching Isaac Sim. +* ``isaaclab_ov`` — Omniverse renderer package that provides the OVRTX renderer for + RTX-based tiled camera rendering. Requires the ``ovrtx`` package and can be used in + kit-less workflows without Isaac Sim. * ``isaaclab_newton`` — Newton-backed implementations of articulations, rigid bodies, and the - Warp renderer. Supports a kit-less installation without Isaac Sim. + Warp renderer. Supports kit-less installation without Isaac Sim. **Extensions** From 4def90a252d052c4749113158ae543a06fdda82f Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Sat, 16 May 2026 20:59:18 -0700 Subject: [PATCH 5/6] update wheel job to pass for doc only changes --- .github/workflows/wheel.yml | 100 +++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 0cad2933e949..841d395afa32 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -8,12 +8,6 @@ name: Build PIP Wheel on: pull_request: types: [opened, synchronize, reopened] - paths: - - 'apps/**' - - 'VERSION' - - 'source/**' - - 'tools/wheel_builder/**' - - '.github/workflows/wheel.yml' push: branches: - main @@ -26,6 +20,7 @@ concurrency: permissions: contents: read + pull-requests: read jobs: build-wheel: @@ -34,13 +29,103 @@ jobs: timeout-minutes: 5 steps: + - name: Detect wheel-relevant changes + id: changes + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + EVENT_NAME: ${{ github.event_name }} + REPO: ${{ github.repository }} + run: | + set -euo pipefail + + # Keep this workflow unconditionally triggered on PRs so required + # branch-protection checks are always reported. The build steps below + # run only when inputs that can affect the wheel have changed. + patterns=( + $'^apps/\tStandalone apps packaged in the wheel' + $'^VERSION$\tPackage version' + $'^source/\tPython packages' + $'^tools/wheel_builder/\tWheel build tooling' + $'^\.github/workflows/wheel\.yml$\tThis workflow file' + ) + + render_table() { + local files="$1" entry regex desc count sample + echo "| Pattern | What it covers | Matched files |" + echo "|---|---|---|" + for entry in "${patterns[@]}"; do + IFS=$'\t' read -r regex desc <<< "$entry" + count=$(printf '%s\n' "$files" | grep -cE "$regex" || true) + if [ "$count" -gt 0 ]; then + sample=$(printf '%s\n' "$files" | grep -E "$regex" | head -3 | paste -sd ', ' -) + [ "$count" -gt 3 ] && sample="$sample (and $((count - 3)) more)" + echo "| \`$regex\` | $desc | $sample |" + else + echo "| \`$regex\` | $desc | - |" + fi + done + } + + any_match() { + local files="$1" entry regex + for entry in "${patterns[@]}"; do + IFS=$'\t' read -r regex _ <<< "$entry" + if printf '%s\n' "$files" | grep -qE "$regex"; then + return 0 + fi + done + return 1 + } + + decide() { + local decision="$1" reason="$2" files="${3:-}" + echo "run_build=$decision" >> "$GITHUB_OUTPUT" + { + echo "## Wheel build gating" + echo "" + if [ "$decision" = "true" ]; then + echo "The wheel build will **run**: $reason." + else + echo "The wheel build will be **skipped**: $reason." + fi + if [ -n "$files" ]; then + echo "" + render_table "$files" + fi + } >> "$GITHUB_STEP_SUMMARY" + } + + if [ "$EVENT_NAME" != "pull_request" ]; then + decide true "non-PR event ($EVENT_NAME)" + exit 0 + fi + + if ! changed_files="$(gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/files" --jq '.[].filename')"; then + echo "::warning::Could not list changed files; defaulting to building the wheel" + decide true "fail-safe (could not list changed files)" + exit 0 + fi + + if any_match "$changed_files"; then + decide true "wheel-relevant paths changed" "$changed_files" + else + decide false "no wheel-relevant paths changed" "$changed_files" + fi + + - name: Skip wheel build + if: steps.changes.outputs.run_build == 'false' + run: echo "Skipping wheel build because this PR does not change wheel inputs." + - name: Checkout code + if: steps.changes.outputs.run_build == 'true' uses: actions/checkout@v6 with: fetch-depth: 1 lfs: true - name: Setup Python + if: steps.changes.outputs.run_build == 'true' uses: actions/setup-python@v5 with: python-version: "3.12" @@ -51,6 +136,7 @@ jobs: # isaaclab--build-. The wheel inside follows # PEP 440 (VERSION+buildN.SHA7) since pip requires that format. - name: Compute wheel metadata + if: steps.changes.outputs.run_build == 'true' id: meta run: | set -euo pipefail @@ -59,12 +145,14 @@ jobs: echo "artifact_name=isaaclab-${version}-build${{ github.run_number }}-${sha_slug}" >> "$GITHUB_OUTPUT" - name: Build wheel + if: steps.changes.outputs.run_build == 'true' env: WHEEL_BUILD_NUMBER: ${{ github.run_number }} WHEEL_SHA: ${{ github.sha }} run: bash tools/wheel_builder/build.sh - name: Upload wheel artifact + if: steps.changes.outputs.run_build == 'true' uses: actions/upload-artifact@v7 with: name: ${{ steps.meta.outputs.artifact_name }} From 6a5ad9934c451704a262fc43f23723623c23f8fe Mon Sep 17 00:00:00 2001 From: Kelly Guo Date: Sat, 16 May 2026 21:39:33 -0700 Subject: [PATCH 6/6] update image path --- .../source/experimental-features/visuo_tactile_sensor.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/experimental-features/visuo_tactile_sensor.rst b/docs/source/experimental-features/visuo_tactile_sensor.rst index e1b389e45c1c..4e3d3897c6ab 100644 --- a/docs/source/experimental-features/visuo_tactile_sensor.rst +++ b/docs/source/experimental-features/visuo_tactile_sensor.rst @@ -9,7 +9,7 @@ Visuo-Tactile Sensor The visuo-tactile sensor in Isaac Lab provides realistic tactile feedback through integration with TacSL (Tactile Sensor Learning) [Akinola2025]_. It is designed to simulate high-fidelity tactile interactions, generating both visual and force-based data that mirror real-world tactile sensors like GelSight devices. The sensor can provide tactile RGB images, force field distributions, and other intermediate tactile measurements essential for robotic manipulation tasks requiring fine tactile feedback. -.. figure:: ../../../_static/overview/sensors/tacsl_diagram.jpg +.. figure:: ../_static/overview/sensors/tacsl_diagram.jpg :align: center :figwidth: 100% :alt: Tactile sensor with RGB visualization and force fields @@ -142,7 +142,7 @@ For a complete list of available options: .. note:: The demo examples are based on the Gelsight R1.5, which is a prototype sensor that is now discontinued. The same procedure can be adapted for other visuotactile sensors. -.. figure:: ../../../_static/overview/sensors/tacsl_demo.jpg +.. figure:: ../_static/overview/sensors/tacsl_demo.jpg :align: center :figwidth: 100% :alt: TacSL tactile sensor demo showing RGB tactile images and force field visualizations @@ -163,12 +163,12 @@ Output Tactile Data :widths: 50 50 :class: borderless - * - .. figure:: ../../../_static/overview/sensors/tacsl_taxim_example.jpg + * - .. figure:: ../_static/overview/sensors/tacsl_taxim_example.jpg :align: center :figwidth: 80% :alt: Tactile output with RGB visualization - - .. figure:: ../../../_static/overview/sensors/tacsl_force_field_example.jpg + - .. figure:: ../_static/overview/sensors/tacsl_force_field_example.jpg :align: center :figwidth: 80% :alt: Tactile output with force field visualization