88from typing import TYPE_CHECKING
99
1010from pxr import Usd
11-
11+ import logging
1212import isaaclab .sim .utils .prims as prim_utils
1313from isaaclab .sim .spawners .from_files import UsdFileCfg
1414
1515if TYPE_CHECKING :
1616 from . import wrappers_cfg
1717
18+ logger = logging .getLogger (__name__ )
19+
1820
1921def spawn_multi_asset (
2022 prim_path : str ,
@@ -24,11 +26,14 @@ def spawn_multi_asset(
2426 clone_in_fabric : bool = False ,
2527 replicate_physics : bool = False ,
2628) -> Usd .Prim :
27- """Spawn multiple assets based on the provided configurations .
29+ """Spawn multiple assets into numbered prim paths derived from the provided configuration .
2830
29- This function spawns multiple assets based on the provided configurations. The assets are spawned
30- in the order they are provided in the list. If the :attr:`~MultiAssetSpawnerCfg.random_choice` parameter is
31- set to True, a random asset configuration is selected for each spawn.
31+ Assets are created in the order they appear in ``cfg.assets_cfg`` using the base name in ``prim_path``,
32+ which must contain ``.*`` (for example, ``/World/Env_0/asset_.*`` spawns ``asset_0``, ``asset_1``, ...).
33+ The prefix portion of ``prim_path`` may also include ``.*`` (for example, ``/World/env_.*/asset_.*``);
34+ this is only allowed when :attr:`~isaaclab.sim.spawners.wrappers.wrappers_cfg.MultiAssetSpawnerCfg.enable_clone`
35+ is True, in which case assets are spawned under the first match (``env_0``) and that structure is cloned to
36+ other matching environments.
3237
3338 Args:
3439 prim_path: The prim path to spawn the assets.
@@ -41,7 +46,27 @@ def spawn_multi_asset(
4146 Returns:
4247 The created prim at the first prim path.
4348 """
44- # spawn everything first in a "Dataset" prim
49+ split_path = prim_path .split ("/" )
50+ prefix_path , base_name = "/" .join (split_path [:- 1 ]), split_path [- 1 ]
51+ if ".*" in prefix_path and not cfg .enable_clone :
52+ raise ValueError (
53+ f" Found '.*' in prefix path '{ prefix_path } ' but enable_clone is False. Set enable_clone=True to allow"
54+ f" this pattern, which would replicate all { len (cfg .assets_cfg )} assets into every environment that"
55+ " matches the prefix. If you want heterogeneous assets across envs, instead of set enable_clone to True"
56+ "spawn them under a single template (e.g., /World/Template/Robot) and use the cloner to place"
57+ "them at their final paths."
58+ )
59+ if ".*" not in base_name :
60+ raise ValueError (
61+ f" The base name '{ base_name } ' in the prim path '{ prim_path } ' must contain '.*' to indicate"
62+ " the path each individual multiple-asset to be spawned."
63+ )
64+ if cfg .random_choice :
65+ logger .warning (
66+ "`random_choice` parameter in `spawn_multi_asset` is deprecated, and nothing will happen. "
67+ "Use `isaaclab.scene.interactive_scene_cfg.InteractiveSceneCfg.random_heterogeneous_cloning` instead."
68+ )
69+
4570 proto_prim_paths = list ()
4671 for index , asset_cfg in enumerate (cfg .assets_cfg ):
4772 # append semantic tags if specified
@@ -56,8 +81,8 @@ def spawn_multi_asset(
5681 attr_value = getattr (cfg , attr_name )
5782 if hasattr (asset_cfg , attr_name ) and attr_value is not None :
5883 setattr (asset_cfg , attr_name , attr_value )
59- # spawn single instance
60- proto_prim_path = prim_path .replace (".*" , f" { index } " )
84+
85+ proto_prim_path = f" { prefix_path } / { base_name .replace ('.*' , str ( index )) } "
6186 asset_cfg .func (
6287 proto_prim_path ,
6388 asset_cfg ,
@@ -69,7 +94,7 @@ def spawn_multi_asset(
6994 # append to proto prim paths
7095 proto_prim_paths .append (proto_prim_path )
7196
72- return prim_utils .get_prim_at_path (proto_prim_paths [0 ])
97+ return prim_utils .find_first_matching_prim (proto_prim_paths [0 ])
7398
7499
75100def spawn_multi_usd_file (
0 commit comments