isaaclab.cloner#

Submodules

path

Segment-boundary-safe prim-path primitives for the cloner.

query

Queries over the prototype/clone relation a ClonePlan describes.

Classes

ClonePlan

Description of a single replication layout, consumed by replicate().

CloneCfg

Configuration for environment replication.

InclusionSet

Legal clone combination defined by explicitly listing active assets.

ReplicateSession

Folds make_clone_plan() and replicate() into a with block.

UsdReplicateContext

Queue and apply USD replication work for one stage.

Functions

clone_plan_from_env_0(source, destination, ...)

Build a single-source clone plan that targets every env from one source row.

make_clone_plan(cfgs, num_clones, ...[, ...])

Build a ClonePlan from asset cfgs.

make_valid_clone_combinations(asset_names, ...)

Build the valid clone-combination variant tensor.

num_spawn_variants(spawn_cfg)

Return the number of spawn variants declared by one spawner configuration.

grid_transforms(N[, spacing, up_axis, device])

Create a centered grid of transforms for N instances.

replicate(plan, *, stage[, replicate_physics])

Drain REPLICATION_QUEUE against plan, dispatch each backend, publish the plan.

queue_replication(cfg)

Register cfg for cloning when replicate() next runs.

usd_replicate(stage, sources, destinations, ...)

Replicate USD prims to per-environment destinations.

filter_collisions(stage, physicsscene_path, ...)

Create inverted collision groups for clones (PhysX only).

Clone plan#

The ClonePlan value type and the constructors that build one.

A plan is the whole description of a replication layout: which prototypes exist, where each one is cloned to, and which envs each one populates. It is built once, queried through query, and executed by replicate().

Three constructors cover the ways a layout is specified:

Classes:

ClonePlan

Description of a single replication layout, consumed by replicate().

Functions:

grid_transforms(N[, spacing, up_axis, device])

Create a centered grid of transforms for N instances.

num_spawn_variants(spawn_cfg)

Return the number of spawn variants declared by one spawner configuration.

make_valid_clone_combinations(asset_names, ...)

Build the valid clone-combination variant tensor.

make_clone_plan(cfgs, num_clones, ...[, ...])

Build a ClonePlan from asset cfgs.

clone_plan_from_env_0(source, destination, ...)

Build a single-source clone plan that targets every env from one source row.

class isaaclab.cloner.clone_plan.ClonePlan[source]#

Bases: object

Description of a single replication layout, consumed by replicate().

Attributes:

sources

Source prim paths, one per replication row.

destinations

Destination path templates with "{}" for the env id, one per row.

clone_mask

Bool tensor [len(sources), num_clones]; True if env j comes from row i.

env_ids

Long tensor [num_clones] of target env ids.

positions

Per-env world positions [m], shape [num_clones, 3], or None.

cfg_rows

id(cfg) to the row indices the cfg owns.

Methods:

__init__(sources, destinations, clone_mask)

sources: tuple[str, ...]#

Source prim paths, one per replication row.

destinations: tuple[str, ...]#

Destination path templates with "{}" for the env id, one per row.

clone_mask: torch.Tensor#

Bool tensor [len(sources), num_clones]; True if env j comes from row i.

env_ids: torch.Tensor | None = None#

Long tensor [num_clones] of target env ids.

Optional for plans used only with iter_sources() or path_to_source(); required by replicate().

positions: torch.Tensor | None = None#

Per-env world positions [m], shape [num_clones, 3], or None.

__init__(sources: tuple[str, ...], destinations: tuple[str, ...], clone_mask: torch.Tensor, env_ids: torch.Tensor | None = None, positions: torch.Tensor | None = None, cfg_rows: dict[int, tuple[int, ...]] = <factory>) None#
cfg_rows: dict[int, tuple[int, ...]]#

id(cfg) to the row indices the cfg owns.

isaaclab.cloner.clone_plan.grid_transforms(N: int, spacing: float = 1.0, up_axis: str = 'z', device='cpu')[source]#

Create a centered grid of transforms for N instances.

Computes (x, y) coordinates in a roughly square grid centered at the origin with the provided spacing, places the third coordinate according to up_axis, and returns identity orientations. This matches the grid layout used by isaaclab.terrains.TerrainImporter for consistent environment positioning.

Parameters:
  • N – Number of instances.

  • spacing – Distance between neighboring grid positions [m].

  • up_axis – Up axis for positions (“z”, “y”, or “x”).

  • device – Torch device for returned tensors.

Returns:

  • pos is a tensor of shape (N, 3) with positions [m].

  • ori is a tensor of shape (N, 4) with identity quaternions in (x, y, z, w).

Return type:

A tuple (pos, ori) where

isaaclab.cloner.clone_plan.num_spawn_variants(spawn_cfg: Any) int[source]#

Return the number of spawn variants declared by one spawner configuration.

MultiAssetSpawnerCfg declares one variant per asset configuration and MultiUsdFileCfg one per USD path; every other spawner declares a single variant.

Parameters:

spawn_cfg – Spawner configuration to inspect.

Returns:

The number of spawn variants the configuration expands into.

isaaclab.cloner.clone_plan.make_valid_clone_combinations(asset_names: Sequence[str], variant_counts: Sequence[int], clone_combinations: Sequence[InclusionSet] | None = None, device: str = 'cpu', *, all_asset_names: Sequence[str] | None = None) torch.Tensor[source]#

Build the valid clone-combination variant tensor.

Each combination contributes rows in proportion to its weight, split evenly across its spawn variants and interleaved round-robin, so any prefix of the tensor samples every combination.

Parameters:
  • asset_names – Clone-planned scene asset names, one per tensor column.

  • variant_counts – Number of spawn variants per clone-planned asset.

  • clone_combinations – Legal clone combinations; assets not mentioned by any combination are active in every row. None uses the full cartesian product of variants.

  • device – Torch device for the output tensor. Defaults to "cpu".

  • all_asset_names – Optional full scene asset-name list; combination entries may reference assets that are not clone-planned.

Returns:

A [num_valid_combinations, num_assets] tensor of source variant indices, -1 where an asset is absent.

Raises:

ValueError – If the inputs are inconsistent or no valid rows result.

isaaclab.cloner.clone_plan.make_clone_plan(cfgs: Iterable[Any], num_clones: int, env_spacing: float, device: str, *, clone_strategy: Callable = <function sequential>, valid_set: torch.Tensor | None = None) ClonePlan[source]#

Build a ClonePlan from asset cfgs.

Iterates cfgs, identifies env-scoped cfgs with a spawn, expands MultiAssetSpawnerCfg / MultiUsdFileCfg into per-variant prototype rows, runs clone_strategy to assign prototypes to envs, and returns a self-contained ClonePlan with cfg_rows populated.

Each input cfg’s spawn_path / spawn_paths is mutated so the subsequent asset constructor spawns the prototype into its first active environment. Cfgs whose prim_path is global (not under the env root /World/envs/) or that lack a spawn are skipped — they do not appear in the plan and are not replicated.

Parameters:
  • cfgs – Asset cfgs with resolved prim_path (no {ENV_REGEX_NS} macros).

  • num_clones – Number of target envs.

  • env_spacing – Distance between neighboring grid env origins [m].

  • device – Torch device for plan tensors.

  • clone_strategy – Function that assigns prototype combinations to envs. Defaults to sequential().

  • valid_set – Optional [num_combos, num_groups] long tensor of valid prototype combinations. None (default) uses the full cartesian product of every group’s prototype indices.

Returns:

A ClonePlan whose sources/destinations/clone_mask describe the flat prototype-to-env mapping and whose cfg_rows maps each cfg to the rows it owns.

isaaclab.cloner.clone_plan.clone_plan_from_env_0(source: str, destination: str, num_clones: int, device: str, positions: torch.Tensor | None = None) ClonePlan[source]#

Build a single-source clone plan that targets every env from one source row.

Auto-populates ClonePlan.cfg_rows from REPLICATION_QUEUE, including only cfgs whose prim_path falls under the env-root prefix of destination. Must be called after all asset constructors have run, so their cfgs are already registered in the queue; otherwise those assets will be skipped by the subsequent replicate() call.

Parameters:
  • source – Source prim path (typically /World/envs/env_0).

  • destination – Destination template with "{}" for the env id.

  • num_clones – Number of target envs.

  • device – Torch device for the mask and env id buffers.

  • positions – Optional per-env world positions [m], shape [num_clones, 3].

Returns:

A ClonePlan with a single source row covering every env.

Path#

Segment-boundary-safe prim-path primitives for the cloner.

A prim path is a sequence of /-delimited segments, not a character string, and the stdlib string operations cross those boundaries silently: str.startswith() reports that ".../Robot" contains ".../RobotArm". This module encodes the boundary semantics once.

Two kinds of prefix appear in the cloner. A root is a concrete prefix path ("/World/envs/env_0"); relative_to(), under() and rebase() work against one. A template carries a single "{}" clone slot standing for one segment ("/World/envs/env_{}/Robot"); split(), match() and relativize() work against one. Reach them through the package, as cloner.path.rebase(...).

Classes:

TemplateMatch

The "{}" text a template captured ("3", or a wildcard ".*"), and the path below it.

Functions:

split(template)

Split a clone destination template around its "{}" clone slot.

match(path_expr, template)

Match path_expr against a destination template, capturing the instance slot.

relative_to(path, root)

Strip a concrete root prefix off path on a segment boundary.

under(path, root)

Return whether path lies within the subtree rooted at root.

rebase(path, src_root, dst_root)

Rebase path from one concrete root prefix onto another on a segment boundary.

relativize(path_expr, template)

Return the part of path_expr below a template's instance root.

class isaaclab.cloner.path.TemplateMatch[source]#

The "{}" text a template captured ("3", or a wildcard ".*"), and the path below it.

Attributes:

instance

Alias for field number 0

suffix

Alias for field number 1

Methods:

__new__(_cls, instance, suffix)

Create new instance of TemplateMatch(instance, suffix)

instance: str#

Alias for field number 0

suffix: str#

Alias for field number 1

static __new__(_cls, instance: str, suffix: str)#

Create new instance of TemplateMatch(instance, suffix)

isaaclab.cloner.path.split(template: str) tuple[str, str][source]#

Split a clone destination template around its "{}" clone slot.

The clone slot represents one concrete environment/instance path segment.

Parameters:

template – Destination path template with exactly one "{}" for the instance id.

Returns:

The (prefix, suffix) strings around the clone slot. A trailing slash is insignificant, so an instance-root template (".../env_{}") yields an empty suffix.

Raises:

ValueError – If template does not hold exactly one clone slot. A second slot would survive into the suffix and break the later str.format that fills the first.

isaaclab.cloner.path.match(path_expr: str, template: str) TemplateMatch | None[source]#

Match path_expr against a destination template, capturing the instance slot.

The "{}" slot matches one path segment’s worth of text, whether a concrete id (3) or a wildcard (.*). Recovering that text is the only way to tell which instance a concrete clone path belongs to without slicing the string by hand.

Parameters:
  • path_expr – Path or path expression on the clone (destination) side.

  • template – Destination path template with "{}" for the instance id.

Returns:

A TemplateMatch with the captured instance text and the asset-relative suffix, or None when path_expr is not under the template’s instance root.

Example

>>> match("/World/envs/env_3/Robot/base", "/World/envs/env_{}/Robot")
TemplateMatch(instance='3', suffix='/base')
isaaclab.cloner.path.relative_to(path: str, root: str) str | None[source]#

Strip a concrete root prefix off path on a segment boundary.

Unlike slicing or str.removeprefix(), this returns None rather than a mid-segment remainder when path is not under root.

Parameters:
  • path – Path to make relative.

  • root – Concrete subtree root. A trailing slash is insignificant, and "/" is the root of every path.

Returns:

The suffix below root (starting with /, or "" when path equals root), or None when path is not under root.

isaaclab.cloner.path.under(path: str, root: str) bool[source]#

Return whether path lies within the subtree rooted at root.

Boundary-correct membership test: unlike str.startswith(), it does not match across a segment boundary (".../Robot" does not contain ".../RobotArm").

Parameters:
  • path – Candidate descendant path.

  • root – Concrete subtree root.

Returns:

True when path equals root or is a descendant of it.

isaaclab.cloner.path.rebase(path: str, src_root: str, dst_root: str) str[source]#

Rebase path from one concrete root prefix onto another on a segment boundary.

Unlike str.replace(), this swaps only a boundary-aligned prefix and touches only the leading occurrence.

Parameters:
  • path – Path to rebase.

  • src_root – Concrete source root prefix.

  • dst_root – Concrete destination root prefix.

Returns:

The rebased path, or path unchanged when it is not under src_root.

isaaclab.cloner.path.relativize(path_expr: str, template: str) str | None[source]#

Return the part of path_expr below a template’s instance root.

The suffix half of match(), for callers that do not need the captured instance.

Parameters:
  • path_expr – Path or path expression on the clone (destination) side.

  • template – Destination path template with "{}" for the instance id.

Returns:

The asset-relative suffix (starting with /, or "" when path_expr is exactly the template root), or None when path_expr is not under the root.

Query#

Queries over the prototype/clone relation a ClonePlan describes.

Each plan row pairs a prototype path that exists once on the stage with a destination template and the environments it populates, so the relation is partial in both directions: a prototype reaches only the environments its row covers, and an environment holds only the assets whose rows cover it. path_to_clone(), path_env_ids() and path_to_source() are the three ways to walk it; iter_sources() is path_to_source() for callers that need every variant behind one template.

Environment ids are not mask columns. Column j stands for env_ids[j], which is the number replicate() formats into the template. These functions take and return environment ids throughout.

A path belongs to the nearest row containing it: the deepest prototype root, or the template leaving the shortest suffix. Rows tying there are one asset’s variants, and the environment picks between them. test/cloner/test_clone_plan_algebra.py pins that down.

The path primitives are aliased pth because path is a parameter name here.

Functions:

path_env_ids(plan, path)

Return the environments a prototype path is replicated to.

path_to_clone(plan, path, env_id)

Return the clone of a prototype path in one environment.

path_to_source(plan, path_expr[, env_id])

Resolve a clone-side expression to the prototype it was cloned from.

iter_sources(plan, path_expr)

Yield every populated plan row whose destination owns a path expression.

isaaclab.cloner.query.path_env_ids(plan: ClonePlan, path: str) tuple[int, ...][source]#

Return the environments a prototype path is replicated to.

Parameters:
  • plan – Active clone plan.

  • path – Prototype path.

Returns:

The ascending env ids populated from path’s owning rows, empty when the plan does not own path.

isaaclab.cloner.query.path_to_clone(plan: ClonePlan, path: str, env_id: int) str | None[source]#

Return the clone of a prototype path in one environment.

Only the prototype root is swapped; everything below it is carried through unchanged.

Parameters:
  • plan – Active clone plan.

  • path – Prototype path.

  • env_id – Target environment id.

Returns:

The clone path in env_id, or None when path is unowned, env_id is not targeted by the plan, or no owning row populates it. Where several variants share the prototype subtree, the variant populating env_id is used.

isaaclab.cloner.query.path_to_source(plan: ClonePlan, path_expr: str, env_id: int | None = None) tuple[str, str, str] | None[source]#

Resolve a clone-side expression to the prototype it was cloned from.

A concrete clone path names its environment in the template’s clone slot, and that environment selects which variant to report — which is what lets this undo path_to_clone() for a heterogeneous asset. A wildcard expression (.../env_.*/...) names no environment and stands for all of them, so it resolves to the first populated variant unless env_id says which one to take.

Parameters:
  • plan – Active clone plan.

  • path_expr – Clone-side path expression (e.g. a sensor’s prim_path, with .* env wildcard) or a concrete clone path.

  • env_id – Environment whose variant to resolve. Defaults to the one path_expr names when it is concrete, and to no particular environment otherwise.

Returns:

A (source_path, destination_glob, asset_suffix) tuple, where asset_suffix is the part of path_expr below the owning template. None when path_expr matches no row, or no matching row populates the requested environment, letting callers fall back to direct stage resolution.

Partial-env coverage is supported: when the matching rows cover only a subset of envs (an asset present in some envs but not others, as in heterogeneous scenes), the returned glob resolves to just those envs.

Raises:

ValueError – When path_expr is owned by multiple distinct, equally near templates.

isaaclab.cloner.query.iter_sources(plan: ClonePlan, path_expr: str) Iterator[tuple[str, str, str, tuple[int, ...]]][source]#

Yield every populated plan row whose destination owns a path expression.

Where path_to_source() names one variant, this yields them all, for callers that must visit each prototype behind a destination template (loading one mesh per variant).

Example

For a row with prototype root "/World/source/Robot", destination template "/World/scenes/{}/Robot" and env ids (0, 2), querying "/World/scenes/.*/Robot/base" yields ("/World/source/Robot", "/World/scenes/{}/Robot", "/World/source/Robot/base", (0, 2)).

Parameters:
  • plan – Clone plan to query.

  • path_expr – Clone-side prim path or path expression.

Yields:

(source_root, destination_template, source_path, env_ids) per row of the nearest owning template, in row order. Rows populating no env are skipped.