Hello,
I use the GridCloner to clone an environment and I would like to add distinct objects to each of those environments in order to do grasping tasks on objects with different shapes (as mentioned in this issue).
To give a more concrete example of what I try to do, let’s suppose I have an environment composed of an ur5e robot that I clone. In each cloned environments, I’d like to add a distinct object. I would thus like to have a situation as follows:
However, I get is the following image in which the red cube from env_0 is also copied in env_1 and env_2.
This is due to the fact any object added to the first environment is copied in all the cloned environments. Here is the code I used for this test:
# Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto. Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#
from omni.isaac.kit import SimulationApp
simulation_app = SimulationApp({"headless": False})
from omni.isaac.core import World
from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.utils.stage import add_reference_to_stage, get_stage_units
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.cloner import GridCloner
from omni.isaac.core.objects.cuboid import DynamicCuboid
from omni.isaac.core.objects import DynamicCylinder, DynamicSphere
import numpy as np
import carb
import sys
assets_root_path = get_assets_root_path()
if assets_root_path is None:
carb.log_error("Could not find Isaac Sim assets folder")
simulation_app.close()
sys.exit()
my_world = World(stage_units_in_meters=1.0)
my_world.scene.add_default_ground_plane()
# create initial robot
base_env_path = "/World/ur5es"
env_robot_paths = f"{base_env_path}/ur5e"
source_env_path = f"{env_robot_paths}_0"
asset_path = assets_root_path + "/Isaac/Robots/UniversalRobots/ur5e/ur5e.usd"
add_reference_to_stage(usd_path=asset_path, prim_path=source_env_path)
# create GridCloner instance
cloner = GridCloner(spacing=2)
# generate paths for clones
target_paths = cloner.generate_paths(env_robot_paths, 3)
# clone
position_offsets = np.array([[0, 0, 1]] * 3)
positions = cloner.clone(
source_prim_path=source_env_path,
prim_paths=target_paths,
position_offsets=position_offsets,
replicate_physics=False,
base_env_path=base_env_path,
)
# create ArticulationView
ur5es = ArticulationView(prim_paths_expr=f"{env_robot_paths}_*", name="ur5e_view")
my_world.scene.add(ur5es)
# Add an object in the first env
name = "cube"
prim_path = f"{source_env_path}/{name}"
prim = my_world.scene.add(
DynamicCuboid(
prim_path=prim_path, # The prim path of the cube in the USD stage
name=name, # The unique name used to retrieve the object from the scene later on
position=positions[0], # Using the current stage units which is in meters by default.
scale=np.array([0.2, 0.2, 0.2]), # most arguments accept mainly numpy arrays.
color=np.array([1., 0, 0.0]), # RGB channels, going from 0-1
))
# Add a second object in the second env
name = "cylinder"
prim_path = f"{env_robot_paths}_1/{name}"
prim = my_world.scene.add(
DynamicCylinder(
prim_path=prim_path, # The prim path of the cube in the USD stage
name=name, # The unique name used to retrieve the object from the scene later on
position=positions[1], # Using the current stage units which is in meters by default.
scale=np.array([0.2, 0.2, 0.2]), # most arguments accept mainly numpy arrays.
color=np.array([0, 1.0, 0.0]), # RGB channels, going from 0-1
))
# Add an other object in the third env
name = "sphere"
prim_path = f"{env_robot_paths}_2/{name}"
prim = my_world.scene.add(
DynamicCuboid(
prim_path=prim_path, # The prim path of the cube in the USD stage
name=name, # The unique name used to retrieve the object from the scene later on
position=positions[2], # Using the current stage units which is in meters by default.
scale=np.array([0.2, 0.2, 0.2]), # most arguments accept mainly numpy arrays.
color=np.array([0, 0, 1.0]), # RGB channels, going from 0-1
))
my_world.reset()
while True:
my_world.step()
simulation_app.close()
In the response from my first issue, it seems that the solution provided in the code example copies the same objects to different environments so it does not provide a solution to my problem. I would thus like to know if it is possible to add distinct objects to the cloned environments or if it the GridCloner is actually not made for that.