Cloning Environments#
Isaac Lab uses a template-based cloning system to efficiently replicate environments for parallel simulation. Instead of authoring each environment individually on the USD stage, you define a single template and let the cloner stamp out copies with optional per-environment variation.
This guide covers the cloning API and how to customize environment creation.
How Cloning Works#
The cloning pipeline has three stages:
Template authoring – You place one or more prototype prims under a template root (default
/World/template). Each prototype is a variant of an asset (e.g., different robot configurations or object meshes).Clone plan – The cloner discovers prototypes, enumerates all possible combinations (one per prototype group), and assigns a combination to each environment using a strategy.
Replication – The selected prototypes are replicated to per-environment prim paths via USD spec copying and physics-backend-specific replication.
Most users interact with cloning indirectly through
InteractiveScene, which calls
clone_from_template() during clone_environments().
For advanced use cases, you can call the cloning utilities directly.
Basic Usage#
The simplest case is homogeneous cloning – every environment gets the same assets:
from isaaclab.cloner import TemplateCloneCfg, clone_from_template
from isaaclab.sim import SimulationContext
sim = SimulationContext()
stage = sim.stage
# Spawn a single prototype under the template root using a spawner
import isaaclab.sim as sim_utils
spawn_cfg = sim_utils.UsdFileCfg(usd_path="path/to/robot.usd")
spawn_cfg.func("/World/template/Robot/proto_asset_0", spawn_cfg)
# Configure and clone
clone_cfg = TemplateCloneCfg(device=sim.cfg.device)
clone_from_template(stage, num_clones=128, template_clone_cfg=clone_cfg)
This creates 128 environments at /World/envs/env_0 through /World/envs/env_127,
each containing a copy of the robot.
Configuration Reference#
TemplateCloneCfg controls the cloning behavior:
Field |
Default |
Description |
|---|---|---|
|
|
Root path under which prototype prims are authored. |
|
|
Name prefix used to discover prototype prims. The cloner finds all prims whose
base name starts with this identifier (e.g., |
|
|
Destination path template. The |
|
|
Whether to replicate USD prim specs to destination paths. |
|
|
Whether to perform physics-backend-specific replication. |
|
|
Backend-specific physics replication function. Set automatically by
|
|
|
Optional callback to prebuild visualizer artifacts from the clone plan. |
|
|
Strategy function for assigning prototypes to environments. See Cloning Strategies below. |
|
|
Torch device for mapping buffers. |
|
|
Enable cloning in Fabric (PhysX only, experimental). |
Cloning Strategies#
When multiple prototypes exist in the template, the clone strategy determines which prototype each environment receives. Isaac Lab provides two built-in strategies:
Random (default)
Each environment receives a randomly sampled prototype combination:
from isaaclab.cloner import TemplateCloneCfg, random
clone_cfg = TemplateCloneCfg(
clone_strategy=random,
device="cuda:0",
)
This is useful for domain randomization and curriculum learning where you want diverse environments.
Sequential
Prototypes are assigned in round-robin order (env_id % num_combinations):
from isaaclab.cloner import TemplateCloneCfg, sequential
clone_cfg = TemplateCloneCfg(
clone_strategy=sequential,
device="cuda:0",
)
This produces a deterministic, balanced distribution – useful for reproducible experiments.
Custom strategies can be written as any callable matching the signature
(combinations: torch.Tensor, num_clones: int, device: str) -> torch.Tensor,
where combinations has shape (num_combinations, num_groups) and the return
value has shape (num_clones, num_groups).
Heterogeneous Environments#
To create environments with different assets, place multiple prototypes under the same group in the template:
# Spawn three different object prototypes under the same group
import isaaclab.sim as sim_utils
sim_utils.CuboidCfg(size=(0.5, 0.5, 0.5)).func(
"/World/template/Object/proto_asset_0", sim_utils.CuboidCfg(size=(0.5, 0.5, 0.5))
)
sim_utils.ConeCfg(radius=0.25, height=0.5).func(
"/World/template/Object/proto_asset_1", sim_utils.ConeCfg(radius=0.25, height=0.5)
)
sim_utils.SphereCfg(radius=0.25).func(
"/World/template/Object/proto_asset_2", sim_utils.SphereCfg(radius=0.25)
)
clone_cfg = TemplateCloneCfg(
clone_strategy=sequential,
device="cuda:0",
)
clone_from_template(stage, num_clones=128, template_clone_cfg=clone_cfg)
# env_0 gets Cuboid, env_1 gets Cone, env_2 gets Sphere, env_3 gets Cuboid, ...
When prototypes span multiple groups (e.g., different robots and different objects), the cloner enumerates the Cartesian product of all groups and assigns combinations using the selected strategy.
Environment Positioning#
Environments are arranged in a grid layout using grid_transforms():
from isaaclab.cloner import grid_transforms
positions, orientations = grid_transforms(
N=128, # number of environments
spacing=2.0, # meters between neighbors
up_axis="Z",
device="cuda:0",
)
# positions: (128, 3), orientations: (128, 4) identity quaternions
InteractiveScene calls this automatically based on
InteractiveSceneCfg.env_spacing.
Collision Filtering#
By default, assets in different environments can collide with each other. To prevent
cross-environment collisions (the typical setup for parallel RL), use
filter_collisions():
from isaaclab.cloner import filter_collisions
filter_collisions(
stage=stage,
physicsscene_path="/physicsScene",
collision_root_path="/World/collisions",
prim_paths=[f"/World/envs/env_{i}" for i in range(128)],
global_paths=["/World/defaultGroundPlane"], # collides with all envs
)
Note
Collision filtering uses PhysX collision groups and is only applicable to the PhysX backend. The Newton backend handles per-environment isolation through its world system.
Physics Backend Replication#
Each physics backend has its own replication function that registers cloned prims with the physics engine:
PhysX:
physx_replicate()– Uses the PhysX replicator interface for fast physics body registration.Newton:
newton_physics_replicate()– Builds a NewtonModelBuilderwith per-environment worlds, supporting heterogeneous spawning.
These functions are set automatically when using InteractiveScene.
For direct usage:
import torch
from isaaclab_physx.cloner import physx_replicate
physx_replicate(
stage=stage,
sources=["/World/envs/env_0/Robot"],
destinations=["/World/envs/env_{}/Robot"], # {} is replaced with env index
env_ids=torch.arange(128),
mapping=torch.ones(1, 128, dtype=torch.bool),
device="cuda:0",
)
See Also#
Spawning Multiple Assets – spawning different assets per environment
Optimize Stage Creation – fabric cloning and stage-in-memory optimizations