Source code for isaaclab.sim.spawners.wrappers.wrappers
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.# All rights reserved.## SPDX-License-Identifier: BSD-3-Clausefrom__future__importannotationsimportrandomimportrefromtypingimportTYPE_CHECKINGimportcarbimportisaacsim.core.utils.primsasprim_utilsimportisaacsim.core.utils.stageasstage_utilsfrompxrimportSdf,Usdimportisaaclab.simassim_utilsfromisaaclab.sim.spawners.from_filesimportUsdFileCfgifTYPE_CHECKING:from.importwrappers_cfg
[docs]defspawn_multi_asset(prim_path:str,cfg:wrappers_cfg.MultiAssetSpawnerCfg,translation:tuple[float,float,float]|None=None,orientation:tuple[float,float,float,float]|None=None,)->Usd.Prim:"""Spawn multiple assets based on the provided configurations. This function spawns multiple assets based on the provided configurations. The assets are spawned in the order they are provided in the list. If the :attr:`~MultiAssetSpawnerCfg.random_choice` parameter is set to True, a random asset configuration is selected for each spawn. Args: prim_path: The prim path to spawn the assets. cfg: The configuration for spawning the assets. translation: The translation of the spawned assets. Default is None. orientation: The orientation of the spawned assets in (w, x, y, z) order. Default is None. Returns: The created prim at the first prim path. """# resolve: {SPAWN_NS}/AssetName# note: this assumes that the spawn namespace already exists in the stageroot_path,asset_path=prim_path.rsplit("/",1)# check if input is a regex expression# note: a valid prim path can only contain alphanumeric characters, underscores, and forward slashesis_regex_expression=re.match(r"^[a-zA-Z0-9/_]+$",root_path)isNone# resolve matching prims for source prim path expressionifis_regex_expressionandroot_path!="":source_prim_paths=sim_utils.find_matching_prim_paths(root_path)# if no matching prims are found, raise an erroriflen(source_prim_paths)==0:raiseRuntimeError(f"Unable to find source prim path: '{root_path}'. Please create the prim before spawning.")else:source_prim_paths=[root_path]# find a free prim path to hold all the template primstemplate_prim_path=stage_utils.get_next_free_path("/World/Template")prim_utils.create_prim(template_prim_path,"Scope")# spawn everything first in a "Dataset" primproto_prim_paths=list()forindex,asset_cfginenumerate(cfg.assets_cfg):# append semantic tags if specifiedifcfg.semantic_tagsisnotNone:ifasset_cfg.semantic_tagsisNone:asset_cfg.semantic_tags=cfg.semantic_tagselse:asset_cfg.semantic_tags+=cfg.semantic_tags# override settings for propertiesattr_names=["mass_props","rigid_props","collision_props","activate_contact_sensors","deformable_props"]forattr_nameinattr_names:attr_value=getattr(cfg,attr_name)ifhasattr(asset_cfg,attr_name)andattr_valueisnotNone:setattr(asset_cfg,attr_name,attr_value)# spawn single instanceproto_prim_path=f"{template_prim_path}/Asset_{index:04d}"asset_cfg.func(proto_prim_path,asset_cfg,translation=translation,orientation=orientation)# append to proto prim pathsproto_prim_paths.append(proto_prim_path)# resolve prim paths for spawning and cloningprim_paths=[f"{source_prim_path}/{asset_path}"forsource_prim_pathinsource_prim_paths]# acquire stagestage=stage_utils.get_current_stage()# manually clone prims if the source prim path is a regex expression# note: unlike in the cloner API from Isaac Sim, we do not "reset" xforms on the copied prims.# This is because the "spawn" calls during the creation of the proto prims already handles this operation.withSdf.ChangeBlock():forindex,prim_pathinenumerate(prim_paths):# spawn single instanceenv_spec=Sdf.CreatePrimInLayer(stage.GetRootLayer(),prim_path)# randomly select an asset configurationifcfg.random_choice:proto_path=random.choice(proto_prim_paths)else:proto_path=proto_prim_paths[index%len(proto_prim_paths)]# copy the proto primSdf.CopySpec(env_spec.layer,Sdf.Path(proto_path),env_spec.layer,Sdf.Path(prim_path))# delete the dataset prim after spawningprim_utils.delete_prim(template_prim_path)# set carb setting to indicate Isaac Lab's environments that different prims have been spawned# at varying prim paths. In this case, PhysX parser shouldn't optimize the stage parsing.# the flag is mainly used to inform the user that they should disable `InteractiveScene.replicate_physics`carb_settings_iface=carb.settings.get_settings()carb_settings_iface.set_bool("/isaaclab/spawn/multi_assets",True)# return the primreturnprim_utils.get_prim_at_path(prim_paths[0])
[docs]defspawn_multi_usd_file(prim_path:str,cfg:wrappers_cfg.MultiUsdFileCfg,translation:tuple[float,float,float]|None=None,orientation:tuple[float,float,float,float]|None=None,)->Usd.Prim:"""Spawn multiple USD files based on the provided configurations. This function creates configuration instances corresponding the individual USD files and calls the :meth:`spawn_multi_asset` method to spawn them into the scene. Args: prim_path: The prim path to spawn the assets. cfg: The configuration for spawning the assets. translation: The translation of the spawned assets. Default is None. orientation: The orientation of the spawned assets in (w, x, y, z) order. Default is None. Returns: The created prim at the first prim path. """# needed here to avoid circular importsfrom.wrappers_cfgimportMultiAssetSpawnerCfg# parse all the usd filesifisinstance(cfg.usd_path,str):usd_paths=[cfg.usd_path]else:usd_paths=cfg.usd_path# make a template usd configusd_template_cfg=UsdFileCfg()forattr_name,attr_valueincfg.__dict__.items():# skip names we know are not presentifattr_namein["func","usd_path","random_choice"]:continue# set the attribute into the templatesetattr(usd_template_cfg,attr_name,attr_value)# create multi asset configuration of USD filesmulti_asset_cfg=MultiAssetSpawnerCfg(assets_cfg=[])forusd_pathinusd_paths:usd_cfg=usd_template_cfg.replace(usd_path=usd_path)multi_asset_cfg.assets_cfg.append(usd_cfg)# set random choicemulti_asset_cfg.random_choice=cfg.random_choice# propagate the contact sensor settings# note: the default value for activate_contact_sensors in MultiAssetSpawnerCfg is False.# This ends up overwriting the usd-template-cfg's value when the `spawn_multi_asset`# function is called. We hard-code the value to the usd-template-cfg's value to ensure# that the contact sensor settings are propagated correctly.ifhasattr(cfg,"activate_contact_sensors"):multi_asset_cfg.activate_contact_sensors=cfg.activate_contact_sensors# call the original functionreturnspawn_multi_asset(prim_path,multi_asset_cfg,translation,orientation)