-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test and check for texture randomization #1705
Changes from all commits
735e19b
8bd9412
39f96a4
39f35f3
e72b07a
25c2900
b20d49f
5693fa9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,6 +196,13 @@ def __init__(self, cfg: EventTermCfg, env: ManagerBasedEnv): | |
event_name = cfg.params.get("event_name") | ||
texture_rotation = cfg.params.get("texture_rotation", (0.0, 0.0)) | ||
|
||
# check to make sure replicate_physics is set to False, else raise warning | ||
if env.cfg.scene.replicate_physics: | ||
raise ValueError( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shall we include the ValueError in the docstring? |
||
"Unable to randomize visual texture material - ensure InteractiveSceneCfg's replicate_physics parameter" | ||
" is set to False." | ||
) | ||
|
||
# convert from radians to degrees | ||
texture_rotation = tuple(math.degrees(angle) for angle in texture_rotation) | ||
|
||
|
@@ -212,9 +219,7 @@ def __init__(self, cfg: EventTermCfg, env: ManagerBasedEnv): | |
|
||
# Create the omni-graph node for the randomization term | ||
def rep_texture_randomization(): | ||
prims_group = rep.get.prims( | ||
path_pattern=f"{asset_entity.cfg.prim_path}/{body_names_regex}/visuals" | ||
) | ||
prims_group = rep.get.prims(path_pattern=f"{asset_entity.cfg.prim_path}/{body_names_regex}/visuals") | ||
|
||
with prims_group: | ||
rep.randomizer.texture( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
# Copyright (c) 2022-2025, The Isaac Lab Project Developers. | ||
# All rights reserved. | ||
# | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
|
||
""" | ||
This script checks the functionality of texture randomization applied to the cartpole scene. | ||
""" | ||
|
||
"""Launch Isaac Sim Simulator first.""" | ||
|
||
|
||
import argparse | ||
|
||
from omni.isaac.lab.app import AppLauncher | ||
|
||
# add argparse arguments | ||
parser = argparse.ArgumentParser(description="Check applying texture randomization to the cartpole scene.") | ||
parser.add_argument("--num_envs", type=int, default=16, help="Number of environments to spawn.") | ||
parser.add_argument( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT: I might mention here that this should be set to False, but is left as a CLI arg for testing purposes? |
||
"--replicate_physics", | ||
type=bool, | ||
default=False, | ||
help="Replicates physics properties across all environments. For texture randomization, it must be set to False.", | ||
) | ||
|
||
# append AppLauncher cli args | ||
AppLauncher.add_app_launcher_args(parser) | ||
# parse the arguments | ||
args_cli = parser.parse_args() | ||
|
||
# launch omniverse app | ||
app_launcher = AppLauncher(args_cli) | ||
simulation_app = app_launcher.app | ||
|
||
"""Rest everything follows.""" | ||
|
||
import math | ||
import torch | ||
|
||
import omni.isaac.lab.envs.mdp as mdp | ||
from omni.isaac.lab.envs import ManagerBasedEnv, ManagerBasedEnvCfg | ||
from omni.isaac.lab.managers import EventTermCfg as EventTerm | ||
from omni.isaac.lab.managers import ObservationGroupCfg as ObsGroup | ||
from omni.isaac.lab.managers import ObservationTermCfg as ObsTerm | ||
from omni.isaac.lab.managers import SceneEntityCfg | ||
from omni.isaac.lab.utils import configclass | ||
from omni.isaac.lab.utils.assets import NVIDIA_NUCLEUS_DIR | ||
|
||
from omni.isaac.lab_tasks.manager_based.classic.cartpole.cartpole_env_cfg import CartpoleSceneCfg | ||
|
||
|
||
@configclass | ||
class ActionsCfg: | ||
"""Action specifications for the environment.""" | ||
|
||
joint_efforts = mdp.JointEffortActionCfg(asset_name="robot", joint_names=["slider_to_cart"], scale=5.0) | ||
|
||
|
||
@configclass | ||
class ObservationsCfg: | ||
"""Observation specifications for the environment.""" | ||
|
||
@configclass | ||
class PolicyCfg(ObsGroup): | ||
"""Observations for policy group.""" | ||
|
||
# observation terms (order preserved) | ||
joint_pos_rel = ObsTerm(func=mdp.joint_pos_rel) | ||
joint_vel_rel = ObsTerm(func=mdp.joint_vel_rel) | ||
|
||
def __post_init__(self) -> None: | ||
self.enable_corruption = False | ||
self.concatenate_terms = True | ||
|
||
# observation groups | ||
policy: PolicyCfg = PolicyCfg() | ||
|
||
|
||
@configclass | ||
class EventCfg: | ||
"""Configuration for events.""" | ||
|
||
# on reset | ||
cart_texture_randomizer = EventTerm( | ||
func=mdp.randomize_visual_texture_material, | ||
mode="reset", | ||
params={ | ||
"asset_cfg": SceneEntityCfg("robot", body_names=["cart"]), | ||
"texture_paths": [ | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Bamboo_Planks/Bamboo_Planks_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Cherry/Cherry_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Oak/Oak_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Timber/Timber_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Timber_Cladding/Timber_Cladding_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Walnut_Planks/Walnut_Planks_BaseColor.png", | ||
], | ||
"event_name": "cart_texture_randomizer", | ||
"texture_rotation": (math.pi / 2, math.pi / 2), | ||
}, | ||
) | ||
|
||
pole_texture_randomizer = EventTerm( | ||
func=mdp.randomize_visual_texture_material, | ||
mode="reset", | ||
params={ | ||
"asset_cfg": SceneEntityCfg("robot", body_names=["pole"]), | ||
"texture_paths": [ | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Bamboo_Planks/Bamboo_Planks_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Cherry/Cherry_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Oak/Oak_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Timber/Timber_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Timber_Cladding/Timber_Cladding_BaseColor.png", | ||
f"{NVIDIA_NUCLEUS_DIR}/Materials/Base/Wood/Walnut_Planks/Walnut_Planks_BaseColor.png", | ||
], | ||
"event_name": "pole_texture_randomizer", | ||
"texture_rotation": (math.pi / 2, math.pi / 2), | ||
}, | ||
) | ||
|
||
reset_cart_position = EventTerm( | ||
func=mdp.reset_joints_by_offset, | ||
mode="reset", | ||
params={ | ||
"asset_cfg": SceneEntityCfg("robot", joint_names=["slider_to_cart"]), | ||
"position_range": (-1.0, 1.0), | ||
"velocity_range": (-0.1, 0.1), | ||
}, | ||
) | ||
|
||
reset_pole_position = EventTerm( | ||
func=mdp.reset_joints_by_offset, | ||
mode="reset", | ||
params={ | ||
"asset_cfg": SceneEntityCfg("robot", joint_names=["cart_to_pole"]), | ||
"position_range": (-0.125 * math.pi, 0.125 * math.pi), | ||
"velocity_range": (-0.01 * math.pi, 0.01 * math.pi), | ||
}, | ||
) | ||
|
||
|
||
@configclass | ||
class CartpoleEnvCfg(ManagerBasedEnvCfg): | ||
"""Configuration for the cartpole environment.""" | ||
|
||
# Scene settings | ||
scene = CartpoleSceneCfg(env_spacing=2.5) | ||
|
||
# Basic settings | ||
actions = ActionsCfg() | ||
observations = ObservationsCfg() | ||
events = EventCfg() | ||
|
||
def __post_init__(self): | ||
"""Post initialization.""" | ||
# viewer settings | ||
self.viewer.eye = [4.5, 0.0, 6.0] | ||
self.viewer.lookat = [0.0, 0.0, 2.0] | ||
# step settings | ||
self.decimation = 4 # env step every 4 sim steps: 200Hz / 4 = 50Hz | ||
# simulation settings | ||
self.sim.dt = 0.005 # sim step every 5ms: 200Hz | ||
|
||
|
||
def main(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't a unit test. We should do it properly to check that texture is applied on the prim (besides visual inspection)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The initial idea was to check the textures being applied changed on reset for the prims in the scene, however I was unable to find a way to directly access the albedo map information for each prim. If you have a way to access this information or a different approach I can convert this into a unit test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hapatel-bdai let's take a look at this and figure out how to verify the textures for a little today / tomorrow If we can't figure out how to check that the correct texture was applied, we can have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we didn't quite figure this out looking at the unit test? 😂 would it be possible to check the albedo map attribute in the unit test to at least make sure the expected image path was set correctly? I think the attribute name maps to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We tried that initially but we weren't able to access the albedo map since the textures are being applied through reference not directly. |
||
"""Main function.""" | ||
# parse the arguments | ||
env_cfg = CartpoleEnvCfg() | ||
env_cfg.scene.num_envs = args_cli.num_envs | ||
env_cfg.scene.replicate_physics = args_cli.replicate_physics | ||
|
||
# setup base environment | ||
env = ManagerBasedEnv(cfg=env_cfg) | ||
|
||
# simulate physics | ||
count = 0 | ||
while simulation_app.is_running(): | ||
with torch.inference_mode(): | ||
# reset | ||
if count % 300 == 0: | ||
count = 0 | ||
env.reset() | ||
print("-" * 80) | ||
print("[INFO]: Resetting environment...") | ||
print("[INFO]: A new set of random textures have been applied.") | ||
|
||
# sample random actions | ||
joint_efforts = torch.randn_like(env.action_manager.action) | ||
# step the environment | ||
env.step(joint_efforts) | ||
|
||
# update counter | ||
count += 1 | ||
|
||
# close the environment | ||
env.close() | ||
|
||
|
||
if __name__ == "__main__": | ||
# run the main function | ||
main() | ||
# close sim app | ||
simulation_app.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉