Genesis World: Universal and Generative Physics Engine

repository·main·Indexed 12 days ago

https://github.com/genesis-embodied-ai/genesis-world

A scalable simulation platform for physical AI featuring a unified multi-physics engine (Rigid, FEM, MPM, Particle, uipc) and photo-realistic rendering (Nyx, Luisa, Pyrender). It provides a Pythonic interface for robotics environments, ML pipelines, and agentic simulation, scaling from local kernels to datacenter GPUs. Version 1.3.2 supports asset parsing for URDF, MJCF, OBJ, GLB, and USD.

Tokens
11.5K
Snippets
25
Records
57
Agent score
99%

What's inside Genesis World

  1. What is Genesis World?

    main
    Genesis World is a simulation platform for physical AI development. It provides a Pythonic simulation interface that integrates a unified multi-physics engine, a photo-realistic renderer, and a cross-platform compiler. The platform is designed to scale from local laptop kernels to datacenter-grade GPUs, making it suitable for robotics environments, ML pipelines, data generation, and agentic simulation.
  2. Explore Genesis World Demos by Layer

    main

    Genesis World provides runnable demos organized into three functional layers that mirror its core architecture:

    1. Physics: Demonstrates various solvers including Rigid body, FEM (Finite Element Method), MPM (Material Point Method), SPH (Smoothed Particle Hydrodynamics), PBD (Position Based Dynamics), and Stable Fluids. It also includes examples of multi-solver coupling (e.g., cloth on rigid bodies, rigid + MPM).
    2. Rendering: Provides camera sensor setups including built-in paths (Nyx, Luisa, Pyrender) and advanced walkthroughs via the genesis-nyx repository (covering PBR materials, light types, and 3D Gaussian splatting).
    3. Simulation Interface: Covers practical robotics and simulation tasks such as robot control, GUI tools (ImGui), heterogeneous environments, domain randomization, and a wide array of sensors (Depth, IMU, Lidar, Tactile, Contact Force, etc.).
  3. Available Franka Panda MuJoCo models

    main

    The franka_sim asset directory contains MuJoCo XML models for the Franka Panda robot. There are two primary configurations available:

    1. Single Franka Panda: Defined in franka_panda.xml.
    2. Dual Franka Panda (bi-franka): Defined in bi-franka_panda.xml, providing a setup with two Franka robots.
    | Model Name | XML File |
    | :--- | :--- |
    | Franka Panda | `franka_panda.xml` |
    | Bi-Franka Panda | `bi-franka_panda.xml` |
  4. Understand the relationship between USD Prims and Genesis Links

    main

    When parsing USD, there is a mapping between a USD Prim (denoted $i$) and a corresponding Genesis link (denoted $i'$).

    There is no direct relationship between the local transform of a USD parent-child pair ($T^i_j$) and the Genesis parent-child pair ($Q^{i'}_{j'}$). Instead, the relationship is defined in world space:

    $$T^w_i = Q^w_{i'} imes S^{i'}_i$$

    Where:

    • $T^w_i$ is the world-space transform of the USD Prim.
    • $Q^w_{i'}$ is the world-space transform of the Genesis link.
    • $S^{i'}_i$ is the scale matrix that transforms from the Genesis link to the USD prim (this scale is baked into the meshes on link $i'$).
  5. Avoid state change detection via snapshot comparison

    main

    Never attempt to detect changes in the simulation state by comparing two snapshots of data for equality (e.g., if current_state == previous_state:).

    This approach is prohibited because:

    1. It is computationally expensive (requires a gather and a compare).
    2. It fails under zero-copy conditions (where both snapshots alias the same memory and will always appear equal).
    3. It duplicates the source of truth.

    Correct Approach: Use Genesis's dedicated change-detection facilities, such as solver StateChange subscriptions.

  6. Use index variables and type tags in kernels

    main

    When writing kernels, use specific naming conventions for indices to avoid ambiguity:

    • Loop and Held Indices: Use the format i_<short code>, where the code is a 1-2 letter type tag (e.g., i_b for batch, i_d for dof, i_l for link, i_g for geom).
    • Nested Indices: Use j_ for a second nested index of the same type (e.g., i_d and j_d for nested dof loops).
    • Relative (Offset) Indices: Append a trailing underscore to indicate an index that will be offset (e.g., i_c_). Use i_c_start and i_c_end for absolute boundaries.
    • Persistent Tensors: The _idx suffix is reserved strictly for persistent tensors/fields (e.g., contact_sort_idx). Never use _idx for local loop counters.
    • Batch Functions: A @qd.func that processes a single environment (the first argument i_b) called from a batch loop must be suffixed _batch (e.g., func_solve_mass_batch).

    Common Type Tags:

    • i_b: batch/environment
    • i_c: contact
    • i_d: dof
    • i_e: entity
    • i_g/i_ga/i_gb: geom(s)
    • i_l/i_la/i_lb: link(s)
    • i_v: vertex
    • i_f: face
    • i_con: constraint
    • i_p/i_q: current/previous item in a sort
  7. Drone Technical Specifications and Controls

    main

    The drone simulations in this directory use the following technical configuration:

    • Model: Crazyflie 2.X (urdf/drones/cf2x.urdf)
    • Base Hover RPM: Approximately 14468
    • Control Method: Differential RPM control. Movement is achieved by varying individual rotor RPMs to create directional thrust (e.g., adjusting front/back rotor pairs for forward/backward movement).
    • Safety Limits: RPM changes are automatically clipped to a safe range of 0-25000 RPM.
    • Physics: Includes realistic gravity and aerodynamics.
  8. Name containers and nested structures in Genesis

    main

    To maintain consistency in data structures, follow these naming patterns:

    • Single Attribute Containers: Name them parent-type-first with the plural s on the first word only (e.g., links_dof_start, not dof_start_links). Alternatively, use a suffix like _pair, _set, _map, or _list.
    • Nested Containers: Order words from highest to lowest in the hierarchy, applying plural markers at each level of nesting (e.g., geoms_vertices_idx).
    • Avoid Generic Prefixes: Do not use all_ for containers; name the content specifically (e.g., joints_xanchor, links_inertia_i).
  9. Follow Genesis coding philosophy and priorities

    main

    When contributing to Genesis, adhere to these core principles:

    • Reference Implementation: Use genesis/engine/solvers/rigid/ as the gold standard for naming, kernel structure, and organization.
    • Code Quality over Consistency: Always prioritize Genesis conventions over the style of original research code or prototypes you are porting.
    • Performance Priorities:
      • Initialization/Scene Construction: Prioritize maintainability and clarity over micro-optimization.
      • Runtime Hot Paths: Prioritize efficiency. Minimize GPU-CPU transfers and use bulk, vectorized operations.
    • No Legacy/Dead Code: Remove unused helpers, commented-out experiments, and proactive private helpers. Experimental subsystems should not carry deprecation burdens.
    • Contribution Criteria: A contribution is only accepted if it provides measurable benefit in Speed (significant gain on tests/benchmarks/), Robustness (new unit tests covering corner cases), or Ease of Use (removing tuning parameters rather than adding them).
  10. How USD scaling is handled in Genesis

    main

    Genesis link transforms are rigid only (rotation and translation), meaning they do not support scaling. To maintain the visual appearance of USD assets that include scaling, the Genesis USD parser decomposes the USD transform $T$ (rotation $R$, scaling $S$, and translation $t$) into a rigid transform $Q$ and a scale matrix $S$ such that $T = Q imes S$.

    • The rigid component $Q$ is used for the Genesis link transform.
    • The scale component $S$ is baked into the mesh geometry (via geom_ST) to preserve the intended size and appearance.

    Handling Reflections (Negative Scale): If a USD asset uses negative scaling (e.g., (-1, -1, -1)) to create a reflection, the parser ensures the Genesis link transform remains a proper rotation ($\det Q = +1$). The reflection is absorbed into the scale matrix $S$ by flipping the first column of $R$ and the first row of $S$.

    Consequences for Collision Shapes: Because $S$ can contain negative values, primitive collision dimensions (like sphere radius or box extents) are calculated using the absolute value of the scale diagonal: np.abs(np.diag(S)). This ensures collision sizes remain positive while the baked mesh maintains the correct handedness.