OmniIsaacGymEnvs

repository·main·Indexed 21 days ago

https://github.com/isaac-sim/omniisaacgymenvs

Reinforcement Learning (RL) environments built on NVIDIA Isaac Sim's core and gym frameworks. It utilizes the rl_games library for PPO training and supports high-performance parallel simulation, multi-GPU and multi-node training, and integration with Tensorboard and Weights & Biases. Compatible with Isaac Sim version 4.0.0 or later.

Tokens
17.4K
Snippets
38
Records
69
Agent score
77%

What's inside OmniIsaacGymEnvs

  1. Understand causes of non-determinism in GPU simulation

    main

    Even with fixed seeds, achieving perfect determinism in GPU-accelerated simulations is challenging due to several factors:

    1. GPU Work Scheduling

    GPU scheduling can alter the order of operations. Because of floating-point numeric storage, changes in execution order can cause small differences in the least significant bits, which diverge over thousands of simulation frames.

    2. Domain Randomization Timing

    Certain parameters, such as object scales, cannot be randomized during runtime without breaking determinism or causing simulation issues. These must be set at setup time using the on_startup condition for Domain Randomization.

    3. Floating Point Precision and World Origin

    Environments placed far from the world origin (0, 0, 0) accumulate floating-point errors. This can cause states to differ even when the same actions are applied to the same initial states.

    • Workaround: Place all actors/environments at the world origin (0, 0, 0) and filter out collisions between them. Note that this may cause a 15-50% performance degradation.

    4. Resetting into Contact States

    If actors are reset into a state where they are already in contact with other actors, the simulation may become non-deterministic. This is because contacts are re-computed from scratch during each reset scenario and cannot guarantee identical results across computations.

  2. Use ArticulationView and RigidPrimView for Physics Access

    main

    In Isaac Sim, physics state access is managed through ArticulationView or RigidPrimView objects. These are initialized using regex expressions to match object paths, eliminating the need for manual handle retrieval.

    Key API Changes from Isaac Gym Preview:

    • No acquire/refresh: Use set/get APIs directly on the view objects.
    • Direct Tensor Access: APIs work with tensors directly; no explicit wrapping/un-wrapping is required.
    • Indexing: Most APIs support an optional indices parameter to operate on a subset of environments. When using indices, the shape of the state buffer must match the dimension of the indices list.
    • Naming: dof is renamed to joint. root_states is split into world_poses and velocities. dof_states are split into joint_positions and joint_velocities.
  3. Use VecEnvBase and VecEnvMT environment wrappers

    main

    Environment wrappers provide the vectorized interface required by RL libraries to communicate with Isaac Sim.

    VecEnvBase (Single-Threaded)

    Standard interface for most RL libraries. It runs in the same thread as the simulation. Key APIs:

    • render(mode="human"): Renders the current frame.
    • seed(seed=-1): Sets the random seed.
    • step(actions): Executes a physics step, computes observations/rewards/dones, and returns buffers.
    • reset(): Resets the environment and re-computes observations.
    • close(): Shuts down the simulator.

    VecEnvMT (Multi-Threaded)

    Designed to isolate the RL policy in a separate thread from the simulation and rendering. This prevents UI interactions from interfering with the training loop.

    • Requirement: You must implement a TrainerMT class with a run() method to initiate the RL loop.
    • Timeout: VecEnvMT has a default 90-second timeout. If the RL thread or simulation thread waits longer than this for the other, an exception is thrown. Increase this via VecEnvMT.initialize(timeout=...) for complex scenes.
    • Note: Currently only supported within the extension workflow.
  4. How the Extension Workflow works

    main

    The extension workflow (introduced in Isaac Sim 2023.1.0) provides a UI-driven experience for running reinforcement learning environments, separating scene creation from training execution.

    Key Benefits:

    • Faster Iteration: You can re-create scenes or re-launch training runs without closing the Isaac Sim app.
    • Hot Reloading: Changes to task code or configuration parameters are picked up when clicking the LOAD or Train buttons.
    • Separation of Concerns: The UI manages scene loading, while the RL policy runs on a separate thread using a multi-threaded VecEnv base environment. Communication between the UI thread and the RL thread occurs via multi-threaded queues.

    Workflow Concept:

    1. Load Scene: Use the UI to select a task and click LOAD to populate the stage with assets.
    2. Run RL: Click START to launch the RL thread for training or inference.
    3. Iterate: Modify code/configs and click LOAD or START again to apply changes without a full app restart.
  5. Avoid multiple setter calls per simulation step in omni.isaac.core

    main

    When using ArticulationView, RigidPrimView, or RigidContactView from omni.isaac.core, you must only call a specific setter API once per simulation step per view instance. Subsequent calls to the same setter API within the same step will override previous calls, effectively voiding them.

    To apply changes to multiple indices or objects, you should aggregate all desired states into a single buffer and make one call to the setter API before calling my_world.step().

    # INCORRECT: Subsequent calls override previous ones
    my_view.set_world_poses(positions=[[0, 0, 1]], orientations=[[1, 0, 0, 0]], indices=[0])
    my_view.set_world_poses(positions=[[0, 1, 1]], orientations=[[1, 0, 0, 0]], indices=[1])
    my_world.step()
    
    # CORRECT: Use a single call with combined buffers
    my_view.set_world_poses(positions=[[0, 0, 1], [0, 1, 1]], orientations=[[1, 0, 0, 0], [1, 0, 0, 0]], indices=[0, 1])
    my_world.step()
  6. Using Warp for Reinforcement Learning in OmniIsaacGymEnvs

    main

    To achieve high-performance GPU acceleration for complex computations in reinforcement learning, you can use Warp instead of PyTorch. Warp allows you to write regular Python functions that are JIT-compiled into efficient CPU or GPU kernels.

    In omniisaacgymenvs, you can implement tasks using the RLTaskWarp base class. This class manages observation, reward, reset, and progress buffers as Warp arrays. This architecture enables you to implement reward and observation logic as Warp kernels, which are JIT-compiled to native CUDA code for parallel GPU acceleration.

  7. How Domain Randomization (DR) works in OmniverseIsaacGymEnvs

    main

    Domain Randomization (DR) is used to make reinforcement learning agents robust to physical variations (e.g., for sim2real transfer) by repeatedly randomizing simulation dynamics during training.

    OmniverseIsaacGymEnvs supports "on the fly" domain randomization via the omni.replicator.isaac extension. This allows dynamics to change without reloading assets or re-parsing files.

    Users can implement DR in two ways:

    1. Python API: Directly using methods from the omni.replicator.isaac extension.
    2. YAML Interface: Specifying DR settings in the task configuration .yaml file (the recommended approach for most users).

    DR can be applied to five main parameter groups:

    • observations: Noise added to agent observations.
    • actions: Noise added to agent actions.
    • simulation: Physical parameters for the entire scene (e.g., gravity).
    • rigid_prim_views: Properties of rigid prims (e.g., material_properties).
    • articulation_views: Properties of articulations (e.g., joint stiffness).
  8. How instanceable USD assets reduce memory usage

    main

    In Isaac Sim, increasing the number of environments (numEnvs) often leads to running out of RAM because omni.isaac.cloner creates full copies of visual and collision meshes for every environment.

    By converting USD assets to be instanceable, the framework can use a single copy of the mesh data on the stage, with all other environments merely referencing that one copy. This significantly reduces memory consumption. To achieve this, the asset hierarchy must be structured so that mesh prims are children of Xform prims, which act as the instanceable points referencing a master USD file containing the mesh definitions.

  9. How the RL Framework components work together

    main

    The RL ecosystem in omniisaacgymenvs consists of three primary components:

    1. Task: The core logic layer where observations, rewards, and actions are computed. It interacts directly with the simulation actors.
    2. RL Policy: The learning algorithm (e.g., PPO via rl_games) that consumes observations and produces actions.
    3. Environment Wrapper: The interface layer that facilitates communication between the Task and the RL Policy. It provides a vectorized API (like gym.Env) to the policy.

    Tasks are typically implemented by inheriting from RLTask, which provides common utilities for configuration parsing and buffer initialization.

    class MyNewTask(RLTask):
        # Task logic (observations, rewards, etc.)
        ...
    
    # The wrapper connects the Task to the Policy
    env = VecEnvBase(headless=False)
    env.set_task(my_task_instance)
    
    # The policy interacts with the wrapper
    obs, rew, done, info = env.step(actions)
  10. Handle stale values in cloth simulation getter APIs

    main

    When using the GPU pipeline with cloth simulation, getter APIs may return stale data if called immediately after a setter API but before a simulation step. The physics simulation must execute a step to refresh the GPU buffers with the new states.

    To ensure you receive the most recent states, call the getter API after my_world.step() has been executed.

    my_view.set_world_positions(positions=[[0, 0, 1]], indices=[0])
    # Values may be stale here (may not match [[0, 0, 1]])
    positions = my_view.get_world_positions() 
    
    my_world.step()
    # Values will be updated and reflect the new states here
    positions = my_view.get_world_positions() 
  11. Optimize memory consumption and prevent Segmentation Faults

    main

    Memory consumption increases with the number of environments and objects. If you encounter out-of-memory errors or Segmentation Faults, try reducing the number of environments or decreasing the GPU buffer sizes in the task configuration file.

    Approximate Memory Estimates:

    Task# of EnvsCPU MemGPU Mem
    Humanoid10244.85 GB3.55 GB
    Humanoid40966.55 GB4.46
    Shadow Hand10249.43 GB5.97 GB
    Shadow Hand409612.4 GB7.83 GB
    Shadow Hand1638418.5 GB14.0 GB
  12. Enable USD synchronization for simulation states

    main

    When using the GPU pipeline, updates to scene states do not automatically sync to USD. This means values in the Isaac Sim UI may appear incorrect or outdated during simulation, and updates made via USD APIs will not sync with the physics engine.

    To enable full USD synchronization, switch to the CPU pipeline and disable fabric in your task configuration:

    1. Set pipeline=cpu
    2. Set use_fabric: False in the task config.