Madrona MJX

repository·main·Indexed 41 days ago

https://github.com/shacklettbp/madrona_mjx

A high-throughput batch renderer bridge between the MJX physics engine and the Madrona engine, enabling GPU-resident rendering for training vision-based reinforcement learning policies. Version 0.0.1 supports rigid body rendering, camera and light transforms, and domain randomization. Note: This project is deprecated in favor of MJWarp.

Tokens
4.8K
Snippets
11
Records
22
Agent score
51%

What's inside Madrona MJX

  1. Important constraints and configuration for Madrona MJX

    main

    When using Madrona MJX, adhere to the following technical requirements and constraints:

    Data Requirements

    • Camera Requirement: An MJCF file must include a camera; otherwise, the application will crash.
    • Batching: The MJX Model passed to the Madrona Renderer must be batched such that arrays have the shape [num_worlds, ...]. Non-domain-randomized MJX model attributes must be manually tiled to this shape.
    • World Count: The number of worlds must be known and initialized at the start. All worlds are rendered every time; you cannot disable rendering for specific worlds. This implies that training and evaluation must share the same batch size.

    Resource and Lifecycle Constraints

    • Renderer Singleton: Only one renderer instance can be initialized at a time. You cannot create two separate environments (e.g., one for training and one for evaluation) that each use their own batch renderer instance.
    • Memory Management: Use the MADRONA_MWGPU_DEVICE_HEAP_SIZE environment variable to adjust how much memory Madrona pre-allocates on the GPU. If you do not allocate enough memory for your use case, an error will be thrown.

    Supported Features

    • Rigid body rendering (position/rotation changes).
    • Camera position and rotation changes.
    • Light position and rotation changes.
    • Geometry color, size, and texture domain randomization.
    • Light parameter domain randomization.

    Unsupported Features

    • Deformable bodies.
    • Particle systems.
    • Muscles, Tendons, and Composites (except for rigid body components).
  2. Set unique visual properties via the init function

    main

    Madrona MJX supports domain randomization by allowing unique visual properties (e.g., lighting conditions, textures, colors, or sizes) to be set per world.

    These properties are configured once using the init function. While instance and camera transforms are updated every frame via the render function, visual properties are static after initialization.

    Note: If you require per-frame updates for visual properties, you must manually modify the render function in sim.cpp to accept and apply these properties.

  3. How the Madrona MJX rendering pipeline works

    main

    The rendering pipeline translates MJX state into Madrona's GPU-based Entity-Component-System (ECS) format to enable high-throughput rendering via the Madrona Batch Renderer.

    Core Components:

    • MadronaBatchRenderer (Python/Bindings): The user-facing interface that manages geometry and exposes tensors.
    • Manager (C++): The orchestration layer. It initializes Madrona's internal components, processes geometry, manages state copies from the simulator into pre-allocated buffers, and invokes the batch renderer.
    • sim.cpp (Taskgraph): Defines a GPU-based Taskgraph. This taskgraph transforms simulator data into Madrona-compatible components and archetypes (contiguous GPU arrays) required by the renderer.
  4. Understand the Madrona MJX state model

    main

    When integrating a custom simulator, you must map your simulator's state to Madrona's state abstractions. The state is composed of four primary entities:

    • Environments: A namespace encapsulating a set of object instances and views (e.g., a single simulation world).
    • Objects: Global 3D assets consisting of triangle meshes and optional textures. Objects are identified by a global ID and are not tied to a specific environment.
    • Instances: Specific occurrences of an Object within an Environment. Each instance maintains its own transform (position and rotation) and refers back to its parent Object ID.
    • View: Camera parameters (width, height, and FOV) specific to an Environment. The batch renderer processes all views across all environments. Currently, all views in a batch share the same dimensions and FOV.
  5. Define and load geometry for custom simulators

    main

    To integrate a custom simulator, you must modify the geometry loading process in mgr.cpp, specifically the loadRenderObjects function. Madrona's geometry format is hierarchical:

    1. Mesh: A collection of arrays (triangles, normals, UVs, etc.) representing a shape.
    2. Object: A group of one or more meshes that are rendered together as a single entity.

    To implement custom asset loading, your code must produce an array of SourceObject structures. You can achieve this via:

    • Using the Madrona-provided AssetImporter class to load files (e.g., .obj, .gltf) from disk, which populates an ImportedAssets structure.
    • Manually filling the SourceObject array.
    • A hybrid approach using AssetImporter for some assets and manual configuration for others.

    Once the SourceObject array is created, pass it to the AssetProcessor's BVH utility functions to generate the final structures required for the renderer's initialization.

  6. Install Madrona MJX via source build

    main

    Madrona MJX requires building the renderer from source and then installing the Python wrapper.

    Prerequisites

    1. Install system libraries:

    sudo apt install libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev mesa-common-dev 2. Install CUDA 12.5.1 or earlier. 3. Install Jax (Note: versions >= 0.6.0 are incompatible). Use: pip install -U "jax[cuda12]<0.6.0" or pip install "jax[cuda12_local]" to avoid version mismatches. 4. Install MuJoCo and MuJoCo MJX (requires mujoco-mjx >= 3.2.7): pip install -U mujoco mujoco-mjx.

    Build Steps

    git clone https://github.com/shacklettbp/madrona_mjx.git
    cd madrona_mjx
    git submodule update --init --recursive
    mkdir build
    cd build
    cmake ..
    make -j
    
    cd ..
    pip install -e .

    Note on Vulkan: If your machine lacks Vulkan and you encounter an assertion failure at madrona::render::vk::Backend::Init::init, use cmake -DLOAD_VULKAN=OFF .. instead of cmake ...

    git clone https://github.com/shacklettbp/madrona_mjx.git
    
    cd madrona_mjx
    git submodule update --init --recursive
    mkdir build
    cd build
    cmake ..
    make -j
    
    cd ..
    pip install -e .
  7. Use the Madrona MJX rendering interface

    main

    The madrona_mjx Python module acts as a renderer interface that translates MJX simulation state into Madrona's GPU-based ECS state for high-throughput rendering.

    To use the renderer, follow this lifecycle:

    1. Initialize the physics simulator (e.g., MJX).
    2. Initialize the Madrona renderer using MadronaBatchRenderer, providing geometry and instance counts. Pass the simulator's initial state to the renderer's .init() method.
    3. Step the simulation in a loop.
    4. Render the current step by passing the simulator's current state to renderer.render().
    5. Retrieve output using renderer.rgbd_tensors() to get the rendered RGB and depth data.
    # Initialize the physics simulator
    my_simulator = Simulator(...)
    
    # Initialize the Madrona renderer
    renderer = MadronaBatchRenderer(geometry, num_instances, ...)
    renderer.init(my_simulator.initial_state())
    
    for _ in range(num_steps):
        # Step the simulation
        my_simulator.step()
    
        # Render the output of the current simulation step
        renderer.render(my_simulator.get_state())
    
        # Retrieve the output tensors
        rendered_output_tensors = renderer.rgbd_tensors()
  8. Install Madrona MJX via Conda/mamba

    main

    If using Conda or Mamba, follow these steps to set up the environment and build the renderer:

    mamba create -n madmjx python=3.11
    mamba activate madmjx
    mamba install cuda==12.5.1 cudnn cuda-nvcc cmake
    mamba install xorg-xorgproto
    pip install "jax[cuda12_local]" mujoco-mjx mujoco brax
    mkdir build && cd build
    cmake .. -DLOAD_VULKAN=OFF
    make -j
    
    cd ..
    pip install -e .

    Troubleshooting Conda Environment:

    • If scripts/viewer.py fails due to missing CUDA libraries: export XLA_FLAGS=--xla_gpu_cuda_data_dir=$CONDA_PREFIX
    • If you have issues rendering the viewer: export PYGLFW_LIBRARY_VARIANT=x11
    mamba create -n madmjx python=3.11
    mamba activate madmjx
    mamba install cuda==12.5.1 cudnn cuda-nvcc cmake
    mamba install xorg-xorgproto
    pip install "jax[cuda12_local]" mujoco-mjx mujoco brax
    mkdir build && cd build
    cmake .. -DLOAD_VULKAN=OFF
    make -j
    
    cd ..
    pip install -e .
  9. Configure environments in the ECS

    main

    To configure environments for rendering, you must create the appropriate ECS (Entity Component System) constructs within sim.cpp.

    Inside the Sim class constructor, create entities for every instance that requires rendering. For each entity, you must configure:

    • The Object ID.
    • Basic properties such as the initial position.

    Critical Requirement: The order in which you create these entities must remain consistent throughout the simulation. This consistency is required so that you can correctly map updated transforms from your simulator to the renderer during the simulation rollout.

  10. Optimize Madrona MJX initialization with kernel caching

    main

    Madrona compiles CUDA kernels during initialization, which is expensive. You can skip this step in subsequent runs by setting environment variables to point to a cache directory.

    Set the following environment variables:

    • MADRONA_MWGPU_KERNEL_CACHE: Path to the Madrona megakernel cache.
    • MADRONA_BVH_KERNEL_CACHE: Path to the BVH kernel cache.

    Example usage:

    MADRONA_MWGPU_KERNEL_CACHE=build/kernel_cache MADRONA_BVH_KERNEL_CACHE=build/bvh_cache python scripts/viewer.py --mjcf mujoco_menagerie/franka_emika_panda/mjx_single_cube_camera.xml
    MADRONA_MWGPU_KERNEL_CACHE=build/kernel_cache MADRONA_BVH_KERNEL_CACHE=build/bvh_cache python scripts/viewer.py --mjcf mujoco_menagerie/franka_emika_panda/mjx_single_cube_camera.xml
  11. Deprecation Notice: Migrate to MJWarp

    main

    This project is deprecated and no longer actively maintained.

    High-throughput batch rendering is now natively supported within the MuJoCo ecosystem via MJWarp.

    Recommendation: All users should migrate to the official MJX renderer (using the warp backend) for better long-term support, performance, and feature parity. An example of using the warp backend in MJX can be found here.