diff --git a/scripts/environments/teleoperation/teleop_se3_agent.py b/scripts/environments/teleoperation/teleop_se3_agent.py index 32f125b194f..85f1cbdf2f8 100644 --- a/scripts/environments/teleoperation/teleop_se3_agent.py +++ b/scripts/environments/teleoperation/teleop_se3_agent.py @@ -56,10 +56,9 @@ import gymnasium as gym +import logging import torch -import omni.log - from isaaclab.devices import Se3Gamepad, Se3GamepadCfg, Se3Keyboard, Se3KeyboardCfg, Se3SpaceMouse, Se3SpaceMouseCfg from isaaclab.devices.openxr import remove_camera_configs from isaaclab.devices.teleop_device_factory import create_teleop_device @@ -73,6 +72,9 @@ import isaaclab_tasks.manager_based.locomanipulation.pick_place # noqa: F401 import isaaclab_tasks.manager_based.manipulation.pick_place # noqa: F401 +# import logger +logger = logging.getLogger(__name__) + def main() -> None: """ @@ -106,12 +108,12 @@ def main() -> None: env = gym.make(args_cli.task, cfg=env_cfg).unwrapped # check environment name (for reach , we don't allow the gripper) if "Reach" in args_cli.task: - omni.log.warn( + logger.warning( f"The environment '{args_cli.task}' does not support gripper control. The device command will be" " ignored." ) except Exception as e: - omni.log.error(f"Failed to create environment: {e}") + logger.error(f"Failed to create environment: {e}") simulation_app.close() return @@ -183,7 +185,9 @@ def stop_teleoperation() -> None: args_cli.teleop_device, env_cfg.teleop_devices.devices, teleoperation_callbacks ) else: - omni.log.warn(f"No teleop device '{args_cli.teleop_device}' found in environment config. Creating default.") + logger.warning( + f"No teleop device '{args_cli.teleop_device}' found in environment config. Creating default." + ) # Create fallback teleop device sensitivity = args_cli.sensitivity if args_cli.teleop_device.lower() == "keyboard": @@ -199,8 +203,8 @@ def stop_teleoperation() -> None: Se3GamepadCfg(pos_sensitivity=0.1 * sensitivity, rot_sensitivity=0.1 * sensitivity) ) else: - omni.log.error(f"Unsupported teleop device: {args_cli.teleop_device}") - omni.log.error("Supported devices: keyboard, spacemouse, gamepad, handtracking") + logger.error(f"Unsupported teleop device: {args_cli.teleop_device}") + logger.error("Supported devices: keyboard, spacemouse, gamepad, handtracking") env.close() simulation_app.close() return @@ -210,15 +214,15 @@ def stop_teleoperation() -> None: try: teleop_interface.add_callback(key, callback) except (ValueError, TypeError) as e: - omni.log.warn(f"Failed to add callback for key {key}: {e}") + logger.warning(f"Failed to add callback for key {key}: {e}") except Exception as e: - omni.log.error(f"Failed to create teleop device: {e}") + logger.error(f"Failed to create teleop device: {e}") env.close() simulation_app.close() return if teleop_interface is None: - omni.log.error("Failed to create teleop interface") + logger.error("Failed to create teleop interface") env.close() simulation_app.close() return @@ -253,7 +257,7 @@ def stop_teleoperation() -> None: should_reset_recording_instance = False print("Environment reset complete") except Exception as e: - omni.log.error(f"Error during simulation step: {e}") + logger.error(f"Error during simulation step: {e}") break # close the simulator diff --git a/scripts/imitation_learning/isaaclab_mimic/generate_dataset.py b/scripts/imitation_learning/isaaclab_mimic/generate_dataset.py index a260151f4b1..019a65ddcde 100644 --- a/scripts/imitation_learning/isaaclab_mimic/generate_dataset.py +++ b/scripts/imitation_learning/isaaclab_mimic/generate_dataset.py @@ -64,23 +64,26 @@ import asyncio import gymnasium as gym import inspect +import logging import numpy as np import random import torch -import omni - from isaaclab.envs import ManagerBasedRLMimicEnv import isaaclab_mimic.envs # noqa: F401 if args_cli.enable_pinocchio: import isaaclab_mimic.envs.pinocchio_envs # noqa: F401 + from isaaclab_mimic.datagen.generation import env_loop, setup_async_generation, setup_env_config from isaaclab_mimic.datagen.utils import get_env_name_from_dataset, setup_output_paths import isaaclab_tasks # noqa: F401 +# import logger +logger = logging.getLogger(__name__) + def main(): num_envs = args_cli.num_envs @@ -110,7 +113,7 @@ def main(): # Check if the mimic API from this environment contains decprecated signatures if "action_noise_dict" not in inspect.signature(env.target_eef_pose_to_action).parameters: - omni.log.warn( + logger.warning( f'The "noise" parameter in the "{env_name}" environment\'s mimic API "target_eef_pose_to_action", ' "is deprecated. Please update the API to take action_noise_dict instead." ) diff --git a/scripts/reinforcement_learning/ray/mlflow_to_local_tensorboard.py b/scripts/reinforcement_learning/ray/mlflow_to_local_tensorboard.py index 64f3cb707ba..232673d4444 100644 --- a/scripts/reinforcement_learning/ray/mlflow_to_local_tensorboard.py +++ b/scripts/reinforcement_learning/ray/mlflow_to_local_tensorboard.py @@ -66,6 +66,7 @@ def process_run(args): def download_experiment_tensorboard_logs(uri: str, experiment_name: str, download_dir: str) -> None: """Download MLflow experiment logs and convert to TensorBoard format.""" + # import logger logger = logging.getLogger(__name__) try: diff --git a/scripts/reinforcement_learning/rl_games/train.py b/scripts/reinforcement_learning/rl_games/train.py index f4952df5f2f..22d82229930 100644 --- a/scripts/reinforcement_learning/rl_games/train.py +++ b/scripts/reinforcement_learning/rl_games/train.py @@ -60,12 +60,12 @@ """Rest everything follows.""" import gymnasium as gym +import logging import math import os import random from datetime import datetime -import omni from rl_games.common import env_configurations, vecenv from rl_games.common.algo_observer import IsaacAlgoObserver from rl_games.torch_runner import Runner @@ -86,6 +86,9 @@ import isaaclab_tasks # noqa: F401 from isaaclab_tasks.utils.hydra import hydra_task_config +# import logger +logger = logging.getLogger(__name__) + # PLACEHOLDER: Extension template (do not remove this comment) @@ -169,7 +172,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen if isinstance(env_cfg, ManagerBasedRLEnvCfg): env_cfg.export_io_descriptors = args_cli.export_io_descriptors else: - omni.log.warn( + logger.warning( "IO descriptors are only supported for manager based RL environments. No IO descriptors will be exported." ) diff --git a/scripts/reinforcement_learning/rsl_rl/train.py b/scripts/reinforcement_learning/rsl_rl/train.py index 8b66feb28aa..77ab3caee1b 100644 --- a/scripts/reinforcement_learning/rsl_rl/train.py +++ b/scripts/reinforcement_learning/rsl_rl/train.py @@ -73,11 +73,11 @@ """Rest everything follows.""" import gymnasium as gym +import logging import os import torch from datetime import datetime -import omni from rsl_rl.runners import DistillationRunner, OnPolicyRunner from isaaclab.envs import ( @@ -96,6 +96,9 @@ from isaaclab_tasks.utils import get_checkpoint_path from isaaclab_tasks.utils.hydra import hydra_task_config +# import logger +logger = logging.getLogger(__name__) + # PLACEHOLDER: Extension template (do not remove this comment) torch.backends.cuda.matmul.allow_tf32 = True @@ -151,7 +154,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen if isinstance(env_cfg, ManagerBasedRLEnvCfg): env_cfg.export_io_descriptors = args_cli.export_io_descriptors else: - omni.log.warn( + logger.warning( "IO descriptors are only supported for manager based RL environments. No IO descriptors will be exported." ) diff --git a/scripts/reinforcement_learning/sb3/train.py b/scripts/reinforcement_learning/sb3/train.py index be43b3b8ac8..94e76dec8ad 100644 --- a/scripts/reinforcement_learning/sb3/train.py +++ b/scripts/reinforcement_learning/sb3/train.py @@ -73,12 +73,12 @@ def cleanup_pbar(*args): """Rest everything follows.""" import gymnasium as gym +import logging import numpy as np import os import random from datetime import datetime -import omni from stable_baselines3 import PPO from stable_baselines3.common.callbacks import CheckpointCallback, LogEveryNTimesteps from stable_baselines3.common.vec_env import VecNormalize @@ -98,6 +98,8 @@ def cleanup_pbar(*args): import isaaclab_tasks # noqa: F401 from isaaclab_tasks.utils.hydra import hydra_task_config +# import logger +logger = logging.getLogger(__name__) # PLACEHOLDER: Extension template (do not remove this comment) @@ -145,7 +147,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen if isinstance(env_cfg, ManagerBasedRLEnvCfg): env_cfg.export_io_descriptors = args_cli.export_io_descriptors else: - omni.log.warn( + logger.warning( "IO descriptors are only supported for manager based RL environments. No IO descriptors will be exported." ) diff --git a/scripts/reinforcement_learning/skrl/train.py b/scripts/reinforcement_learning/skrl/train.py index d73a2a40262..8dc051ee8a4 100644 --- a/scripts/reinforcement_learning/skrl/train.py +++ b/scripts/reinforcement_learning/skrl/train.py @@ -73,11 +73,11 @@ """Rest everything follows.""" import gymnasium as gym +import logging import os import random from datetime import datetime -import omni import skrl from packaging import version @@ -111,6 +111,9 @@ import isaaclab_tasks # noqa: F401 from isaaclab_tasks.utils.hydra import hydra_task_config +# import logger +logger = logging.getLogger(__name__) + # PLACEHOLDER: Extension template (do not remove this comment) # config shortcuts @@ -183,7 +186,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen if isinstance(env_cfg, ManagerBasedRLEnvCfg): env_cfg.export_io_descriptors = args_cli.export_io_descriptors else: - omni.log.warn( + logger.warning( "IO descriptors are only supported for manager based RL environments. No IO descriptors will be exported." ) diff --git a/scripts/tools/record_demos.py b/scripts/tools/record_demos.py index 4eeef711a1c..8fe3ad387e8 100644 --- a/scripts/tools/record_demos.py +++ b/scripts/tools/record_demos.py @@ -90,12 +90,11 @@ # Third-party imports import gymnasium as gym +import logging import os import time import torch -# Omniverse logger -import omni.log import omni.ui as ui from isaaclab.devices import Se3Keyboard, Se3KeyboardCfg, Se3SpaceMouse, Se3SpaceMouseCfg @@ -119,6 +118,9 @@ import isaaclab_tasks # noqa: F401 from isaaclab_tasks.utils.parse_cfg import parse_env_cfg +# import logger +logger = logging.getLogger(__name__) + class RateLimiter: """Convenience class for enforcing rates in loops.""" @@ -201,7 +203,7 @@ def create_environment_config( env_cfg = parse_env_cfg(args_cli.task, device=args_cli.device, num_envs=1) env_cfg.env_name = args_cli.task.split(":")[-1] except Exception as e: - omni.log.error(f"Failed to parse environment configuration: {e}") + logger.error(f"Failed to parse environment configuration: {e}") exit(1) # extract success checking function to invoke in the main loop @@ -210,7 +212,7 @@ def create_environment_config( success_term = env_cfg.terminations.success env_cfg.terminations.success = None else: - omni.log.warn( + logger.warning( "No success termination term was found in the environment." " Will not be able to mark recorded demos as successful." ) @@ -251,7 +253,7 @@ def create_environment(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg) -> gym.En env = gym.make(args_cli.task, cfg=env_cfg).unwrapped return env except Exception as e: - omni.log.error(f"Failed to create environment: {e}") + logger.error(f"Failed to create environment: {e}") exit(1) @@ -276,26 +278,28 @@ def setup_teleop_device(callbacks: dict[str, Callable]) -> object: if hasattr(env_cfg, "teleop_devices") and args_cli.teleop_device in env_cfg.teleop_devices.devices: teleop_interface = create_teleop_device(args_cli.teleop_device, env_cfg.teleop_devices.devices, callbacks) else: - omni.log.warn(f"No teleop device '{args_cli.teleop_device}' found in environment config. Creating default.") + logger.warning( + f"No teleop device '{args_cli.teleop_device}' found in environment config. Creating default." + ) # Create fallback teleop device if args_cli.teleop_device.lower() == "keyboard": teleop_interface = Se3Keyboard(Se3KeyboardCfg(pos_sensitivity=0.2, rot_sensitivity=0.5)) elif args_cli.teleop_device.lower() == "spacemouse": teleop_interface = Se3SpaceMouse(Se3SpaceMouseCfg(pos_sensitivity=0.2, rot_sensitivity=0.5)) else: - omni.log.error(f"Unsupported teleop device: {args_cli.teleop_device}") - omni.log.error("Supported devices: keyboard, spacemouse, handtracking") + logger.error(f"Unsupported teleop device: {args_cli.teleop_device}") + logger.error("Supported devices: keyboard, spacemouse, handtracking") exit(1) # Add callbacks to fallback device for key, callback in callbacks.items(): teleop_interface.add_callback(key, callback) except Exception as e: - omni.log.error(f"Failed to create teleop device: {e}") + logger.error(f"Failed to create teleop device: {e}") exit(1) if teleop_interface is None: - omni.log.error("Failed to create teleop interface") + logger.error("Failed to create teleop interface") exit(1) return teleop_interface diff --git a/source/isaaclab/isaaclab/actuators/actuator_pd.py b/source/isaaclab/isaaclab/actuators/actuator_pd.py index 162005dfd17..9caf72415d1 100644 --- a/source/isaaclab/isaaclab/actuators/actuator_pd.py +++ b/source/isaaclab/isaaclab/actuators/actuator_pd.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - from isaaclab.utils import DelayBuffer, LinearInterpolation from isaaclab.utils.types import ArticulationActions @@ -25,6 +24,8 @@ RemotizedPDActuatorCfg, ) +# import logger +logger = logging.getLogger(__name__) """ Implicit Actuator Models. @@ -57,7 +58,7 @@ def __init__(self, cfg: ImplicitActuatorCfg, *args, **kwargs): # effort limits if cfg.effort_limit_sim is None and cfg.effort_limit is not None: # throw a warning that we have a replacement for the deprecated parameter - omni.log.warn( + logger.warning( "The object has a value for 'effort_limit'." " This parameter will be removed in the future." " To set the effort limit, please use 'effort_limit_sim' instead." @@ -79,7 +80,7 @@ def __init__(self, cfg: ImplicitActuatorCfg, *args, **kwargs): if cfg.velocity_limit_sim is None and cfg.velocity_limit is not None: # throw a warning that previously this was not set # it leads to different simulation behavior so we want to remain backwards compatible - omni.log.warn( + logger.warning( "The object has a value for 'velocity_limit'." " Previously, although this value was specified, it was not getting used by implicit" " actuators. Since this parameter affects the simulation behavior, we continue to not" diff --git a/source/isaaclab/isaaclab/assets/articulation/articulation.py b/source/isaaclab/isaaclab/assets/articulation/articulation.py index deb8b6479f5..bbdb1dfbff3 100644 --- a/source/isaaclab/isaaclab/assets/articulation/articulation.py +++ b/source/isaaclab/isaaclab/assets/articulation/articulation.py @@ -8,12 +8,12 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from prettytable import PrettyTable from typing import TYPE_CHECKING -import omni.log import omni.physics.tensors.impl.api as physx from isaacsim.core.simulation_manager import SimulationManager from isaacsim.core.version import get_version @@ -31,6 +31,9 @@ if TYPE_CHECKING: from .articulation_cfg import ArticulationCfg +# import logger +logger = logging.getLogger(__name__) + class Articulation(AssetBase): """An articulation asset class. @@ -706,10 +709,10 @@ def write_joint_position_limit_to_sim( ) if warn_limit_violation: # warn level will show in console - omni.log.warn(violation_message) + logger.warning(violation_message) else: # info level is only written to log file - omni.log.info(violation_message) + logger.info(violation_message) # set into simulation self.root_physx_view.set_dof_limits(self._data.joint_pos_limits.cpu(), indices=physx_env_ids.cpu()) @@ -907,7 +910,7 @@ def write_joint_dynamic_friction_coefficient_to_sim( env_ids: Sequence[int] | None = None, ): if int(get_version()[2]) < 5: - omni.log.warn("Setting joint dynamic friction coefficients are not supported in Isaac Sim < 5.0") + logger.warning("Setting joint dynamic friction coefficients are not supported in Isaac Sim < 5.0") return # resolve indices physx_env_ids = env_ids @@ -933,7 +936,7 @@ def write_joint_viscous_friction_coefficient_to_sim( env_ids: Sequence[int] | None = None, ): if int(get_version()[2]) < 5: - omni.log.warn("Setting joint viscous friction coefficients are not supported in Isaac Sim < 5.0") + logger.warning("Setting joint viscous friction coefficients are not supported in Isaac Sim < 5.0") return # resolve indices physx_env_ids = env_ids @@ -1037,7 +1040,7 @@ def set_external_force_and_torque( self._external_torque_b.flatten(0, 1)[indices] = torques.flatten(0, 1) if is_global != self._use_global_wrench_frame: - omni.log.warn( + logger.warning( f"The external wrench frame has been changed from {self._use_global_wrench_frame} to {is_global}. This" " may lead to unexpected behavior." ) @@ -1332,7 +1335,7 @@ def set_spatial_tendon_stiffness( env_ids: The environment indices to set the stiffness for. Defaults to None (all environments). """ if int(get_version()[2]) < 5: - omni.log.warn( + logger.warning( "Spatial tendons are not supported in Isaac Sim < 5.0. Please update to Isaac Sim 5.0 or later." ) return @@ -1363,7 +1366,7 @@ def set_spatial_tendon_damping( env_ids: The environment indices to set the damping for. Defaults to None (all environments). """ if int(get_version()[2]) < 5: - omni.log.warn( + logger.warning( "Spatial tendons are not supported in Isaac Sim < 5.0. Please update to Isaac Sim 5.0 or later." ) return @@ -1394,7 +1397,7 @@ def set_spatial_tendon_limit_stiffness( env_ids: The environment indices to set the limit stiffness for. Defaults to None (all environments). """ if int(get_version()[2]) < 5: - omni.log.warn( + logger.warning( "Spatial tendons are not supported in Isaac Sim < 5.0. Please update to Isaac Sim 5.0 or later." ) return @@ -1425,7 +1428,7 @@ def set_spatial_tendon_offset( env_ids: The environment indices to set the offset for. Defaults to None (all environments). """ if int(get_version()[2]) < 5: - omni.log.warn( + logger.warning( "Spatial tendons are not supported in Isaac Sim < 5.0. Please update to Isaac Sim 5.0 or later." ) return @@ -1518,7 +1521,7 @@ def _initialize_impl(self): raise RuntimeError(f"Failed to create articulation at: {root_prim_path_expr}. Please check PhysX logs.") if int(get_version()[2]) < 5: - omni.log.warn( + logger.warning( "Spatial tendons are not supported in Isaac Sim < 5.0: patching spatial-tendon getter" " and setter to use dummy value" ) @@ -1527,19 +1530,19 @@ def _initialize_impl(self): self._root_physx_view.get_spatial_tendon_dampings = lambda: torch.empty(0, device=self.device) self._root_physx_view.get_spatial_tendon_limit_stiffnesses = lambda: torch.empty(0, device=self.device) self._root_physx_view.get_spatial_tendon_offsets = lambda: torch.empty(0, device=self.device) - self._root_physx_view.set_spatial_tendon_properties = lambda *args, **kwargs: omni.log.warn( + self._root_physx_view.set_spatial_tendon_properties = lambda *args, **kwargs: logger.warning( "Spatial tendons are not supported in Isaac Sim < 5.0: Calling" " set_spatial_tendon_properties has no effect" ) # log information about the articulation - omni.log.info(f"Articulation initialized at: {self.cfg.prim_path} with root '{root_prim_path_expr}'.") - omni.log.info(f"Is fixed root: {self.is_fixed_base}") - omni.log.info(f"Number of bodies: {self.num_bodies}") - omni.log.info(f"Body names: {self.body_names}") - omni.log.info(f"Number of joints: {self.num_joints}") - omni.log.info(f"Joint names: {self.joint_names}") - omni.log.info(f"Number of fixed tendons: {self.num_fixed_tendons}") + logger.info(f"Articulation initialized at: {self.cfg.prim_path} with root '{root_prim_path_expr}'.") + logger.info(f"Is fixed root: {self.is_fixed_base}") + logger.info(f"Number of bodies: {self.num_bodies}") + logger.info(f"Body names: {self.body_names}") + logger.info(f"Number of joints: {self.num_joints}") + logger.info(f"Joint names: {self.joint_names}") + logger.info(f"Number of fixed tendons: {self.num_fixed_tendons}") # container for data access self._data = ArticulationData(self.root_physx_view, self.device) @@ -1718,7 +1721,7 @@ def _process_actuators_cfg(self): ) # log information on actuator groups model_type = "implicit" if actuator.is_implicit_model else "explicit" - omni.log.info( + logger.info( f"Actuator collection: {actuator_name} with model '{actuator_cfg.class_type.__name__}'" f" (type: {model_type}) and joint names: {joint_names} [{joint_ids}]." ) @@ -1762,7 +1765,7 @@ def _process_actuators_cfg(self): # perform some sanity checks to ensure actuators are prepared correctly total_act_joints = sum(actuator.num_joints for actuator in self.actuators.values()) if total_act_joints != (self.num_joints - self.num_fixed_tendons): - omni.log.warn( + logger.warning( "Not all actuators are configured! Total number of actuated joints not equal to number of" f" joints available: {total_act_joints} != {self.num_joints - self.num_fixed_tendons}." ) @@ -1778,7 +1781,7 @@ def _process_actuators_cfg(self): fmt = [f"{v:.2e}" if isinstance(v, float) else str(v) for v in resolution_detail] t.add_row([actuator_group_str, property_str, *fmt]) group_count += 1 - omni.log.warn(f"\nActuatorCfg-USD Value Discrepancy Resolution (matching values are skipped): \n{t}") + logger.warning(f"\nActuatorCfg-USD Value Discrepancy Resolution (matching values are skipped): \n{t}") def _process_tendons(self): """Process fixed and spatial tendons.""" @@ -2002,7 +2005,7 @@ def _log_articulation_info(self): effort_limits[index], ]) # convert table to string - omni.log.info(f"Simulation parameters for joints in {self.cfg.prim_path}:\n" + joint_table.get_string()) + logger.info(f"Simulation parameters for joints in {self.cfg.prim_path}:\n" + joint_table.get_string()) # read out all fixed tendon parameters from simulation if self.num_fixed_tendons > 0: @@ -2040,7 +2043,7 @@ def _log_articulation_info(self): ft_offsets[index], ]) # convert table to string - omni.log.info( + logger.info( f"Simulation parameters for fixed tendons in {self.cfg.prim_path}:\n" + tendon_table.get_string() ) @@ -2072,7 +2075,7 @@ def _log_articulation_info(self): st_offsets[index], ]) # convert table to string - omni.log.info( + logger.info( f"Simulation parameters for spatial tendons in {self.cfg.prim_path}:\n" + tendon_table.get_string() ) @@ -2091,7 +2094,7 @@ def write_joint_friction_to_sim( .. deprecated:: 2.1.0 Please use :meth:`write_joint_friction_coefficient_to_sim` instead. """ - omni.log.warn( + logger.warning( "The function 'write_joint_friction_to_sim' will be deprecated in a future release. Please" " use 'write_joint_friction_coefficient_to_sim' instead." ) @@ -2109,7 +2112,7 @@ def write_joint_limits_to_sim( .. deprecated:: 2.1.0 Please use :meth:`write_joint_position_limit_to_sim` instead. """ - omni.log.warn( + logger.warning( "The function 'write_joint_limits_to_sim' will be deprecated in a future release. Please" " use 'write_joint_position_limit_to_sim' instead." ) @@ -2128,7 +2131,7 @@ def set_fixed_tendon_limit( .. deprecated:: 2.1.0 Please use :meth:`set_fixed_tendon_position_limit` instead. """ - omni.log.warn( + logger.warning( "The function 'set_fixed_tendon_limit' will be deprecated in a future release. Please" " use 'set_fixed_tendon_position_limit' instead." ) diff --git a/source/isaaclab/isaaclab/assets/articulation/articulation_data.py b/source/isaaclab/isaaclab/assets/articulation/articulation_data.py index 6d974dd37d6..172a002a3a3 100644 --- a/source/isaaclab/isaaclab/assets/articulation/articulation_data.py +++ b/source/isaaclab/isaaclab/assets/articulation/articulation_data.py @@ -3,16 +3,19 @@ # # SPDX-License-Identifier: BSD-3-Clause +import logging import torch import weakref -import omni.log import omni.physics.tensors.impl.api as physx from isaacsim.core.simulation_manager import SimulationManager import isaaclab.utils.math as math_utils from isaaclab.utils.buffers import TimestampedBuffer +# import logger +logger = logging.getLogger(__name__) + class ArticulationData: """Data container for an articulation. @@ -1091,7 +1094,7 @@ def com_quat_b(self) -> torch.Tensor: @property def joint_limits(self) -> torch.Tensor: """Deprecated property. Please use :attr:`joint_pos_limits` instead.""" - omni.log.warn( + logger.warning( "The `joint_limits` property will be deprecated in a future release. Please use `joint_pos_limits` instead." ) return self.joint_pos_limits @@ -1099,7 +1102,7 @@ def joint_limits(self) -> torch.Tensor: @property def default_joint_limits(self) -> torch.Tensor: """Deprecated property. Please use :attr:`default_joint_pos_limits` instead.""" - omni.log.warn( + logger.warning( "The `default_joint_limits` property will be deprecated in a future release. Please use" " `default_joint_pos_limits` instead." ) @@ -1108,7 +1111,7 @@ def default_joint_limits(self) -> torch.Tensor: @property def joint_velocity_limits(self) -> torch.Tensor: """Deprecated property. Please use :attr:`joint_vel_limits` instead.""" - omni.log.warn( + logger.warning( "The `joint_velocity_limits` property will be deprecated in a future release. Please use" " `joint_vel_limits` instead." ) @@ -1117,7 +1120,7 @@ def joint_velocity_limits(self) -> torch.Tensor: @property def joint_friction(self) -> torch.Tensor: """Deprecated property. Please use :attr:`joint_friction_coeff` instead.""" - omni.log.warn( + logger.warning( "The `joint_friction` property will be deprecated in a future release. Please use" " `joint_friction_coeff` instead." ) @@ -1126,7 +1129,7 @@ def joint_friction(self) -> torch.Tensor: @property def default_joint_friction(self) -> torch.Tensor: """Deprecated property. Please use :attr:`default_joint_friction_coeff` instead.""" - omni.log.warn( + logger.warning( "The `default_joint_friction` property will be deprecated in a future release. Please use" " `default_joint_friction_coeff` instead." ) @@ -1135,7 +1138,7 @@ def default_joint_friction(self) -> torch.Tensor: @property def fixed_tendon_limit(self) -> torch.Tensor: """Deprecated property. Please use :attr:`fixed_tendon_pos_limits` instead.""" - omni.log.warn( + logger.warning( "The `fixed_tendon_limit` property will be deprecated in a future release. Please use" " `fixed_tendon_pos_limits` instead." ) @@ -1144,7 +1147,7 @@ def fixed_tendon_limit(self) -> torch.Tensor: @property def default_fixed_tendon_limit(self) -> torch.Tensor: """Deprecated property. Please use :attr:`default_fixed_tendon_pos_limits` instead.""" - omni.log.warn( + logger.warning( "The `default_fixed_tendon_limit` property will be deprecated in a future release. Please use" " `default_fixed_tendon_pos_limits` instead." ) diff --git a/source/isaaclab/isaaclab/assets/deformable_object/deformable_object.py b/source/isaaclab/isaaclab/assets/deformable_object/deformable_object.py index 982b2f72c81..a98a8f42f60 100644 --- a/source/isaaclab/isaaclab/assets/deformable_object/deformable_object.py +++ b/source/isaaclab/isaaclab/assets/deformable_object/deformable_object.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log import omni.physics.tensors.impl.api as physx from isaacsim.core.simulation_manager import SimulationManager from pxr import PhysxSchema, UsdShade @@ -24,6 +24,9 @@ if TYPE_CHECKING: from .deformable_object_cfg import DeformableObjectCfg +# import logger +logger = logging.getLogger(__name__) + class DeformableObject(AssetBase): """A deformable object asset class. @@ -307,7 +310,7 @@ def _initialize_impl(self): material_prim = mat_prim break if material_prim is None: - omni.log.info( + logger.info( f"Failed to find a deformable material binding for '{root_prim.GetPath().pathString}'." " The material properties will be set to default values and are not modifiable at runtime." " If you want to modify the material properties, please ensure that the material is bound" @@ -343,14 +346,14 @@ def _initialize_impl(self): self._material_physx_view = None # log information about the deformable body - omni.log.info(f"Deformable body initialized at: {root_prim_path_expr}") - omni.log.info(f"Number of instances: {self.num_instances}") - omni.log.info(f"Number of bodies: {self.num_bodies}") + logger.info(f"Deformable body initialized at: {root_prim_path_expr}") + logger.info(f"Number of instances: {self.num_instances}") + logger.info(f"Number of bodies: {self.num_bodies}") if self._material_physx_view is not None: - omni.log.info(f"Deformable material initialized at: {material_prim_path_expr}") - omni.log.info(f"Number of instances: {self._material_physx_view.count}") + logger.info(f"Deformable material initialized at: {material_prim_path_expr}") + logger.info(f"Number of instances: {self._material_physx_view.count}") else: - omni.log.info("No deformable material found. Material properties will be set to default values.") + logger.info("No deformable material found. Material properties will be set to default values.") # container for data access self._data = DeformableObjectData(self.root_physx_view, self.device) diff --git a/source/isaaclab/isaaclab/assets/rigid_object/rigid_object.py b/source/isaaclab/isaaclab/assets/rigid_object/rigid_object.py index 9de2a137636..ee13c56ee19 100644 --- a/source/isaaclab/isaaclab/assets/rigid_object/rigid_object.py +++ b/source/isaaclab/isaaclab/assets/rigid_object/rigid_object.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log import omni.physics.tensors.impl.api as physx from isaacsim.core.simulation_manager import SimulationManager from pxr import UsdPhysics @@ -24,6 +24,9 @@ if TYPE_CHECKING: from .rigid_object_cfg import RigidObjectCfg +# import logger +logger = logging.getLogger(__name__) + class RigidObject(AssetBase): """A rigid object asset class. @@ -436,7 +439,7 @@ def set_external_force_and_torque( self._external_torque_b[env_ids, body_ids] = torques if is_global != self._use_global_wrench_frame: - omni.log.warn( + logger.warning( f"The external wrench frame has been changed from {self._use_global_wrench_frame} to {is_global}. This" " may lead to unexpected behavior." ) @@ -505,10 +508,10 @@ def _initialize_impl(self): raise RuntimeError(f"Failed to create rigid body at: {self.cfg.prim_path}. Please check PhysX logs.") # log information about the rigid body - omni.log.info(f"Rigid body initialized at: {self.cfg.prim_path} with root '{root_prim_path_expr}'.") - omni.log.info(f"Number of instances: {self.num_instances}") - omni.log.info(f"Number of bodies: {self.num_bodies}") - omni.log.info(f"Body names: {self.body_names}") + logger.info(f"Rigid body initialized at: {self.cfg.prim_path} with root '{root_prim_path_expr}'.") + logger.info(f"Number of instances: {self.num_instances}") + logger.info(f"Number of bodies: {self.num_bodies}") + logger.info(f"Body names: {self.body_names}") # container for data access self._data = RigidObjectData(self.root_physx_view, self.device) diff --git a/source/isaaclab/isaaclab/assets/rigid_object_collection/rigid_object_collection.py b/source/isaaclab/isaaclab/assets/rigid_object_collection/rigid_object_collection.py index b607f06d088..ff223d7c5bc 100644 --- a/source/isaaclab/isaaclab/assets/rigid_object_collection/rigid_object_collection.py +++ b/source/isaaclab/isaaclab/assets/rigid_object_collection/rigid_object_collection.py @@ -5,15 +5,13 @@ from __future__ import annotations +import logging import re import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.kit.app -import omni.log import omni.physics.tensors.impl.api as physx -import omni.timeline from isaacsim.core.simulation_manager import SimulationManager from pxr import UsdPhysics @@ -27,6 +25,9 @@ if TYPE_CHECKING: from .rigid_object_collection_cfg import RigidObjectCollectionCfg +# import logger +logger = logging.getLogger(__name__) + class RigidObjectCollection(AssetBase): """A rigid object collection class. @@ -545,7 +546,7 @@ def set_external_force_and_torque( self._external_torque_b[env_ids[:, None], object_ids] = torques if is_global != self._use_global_wrench_frame: - omni.log.warn( + logger.warning( f"The external wrench frame has been changed from {self._use_global_wrench_frame} to {is_global}. This" " may lead to unexpected behavior." ) @@ -648,9 +649,9 @@ def _initialize_impl(self): raise RuntimeError("Failed to create rigid body collection. Please check PhysX logs.") # log information about the rigid body - omni.log.info(f"Number of instances: {self.num_instances}") - omni.log.info(f"Number of distinct objects: {self.num_objects}") - omni.log.info(f"Object names: {self.object_names}") + logger.info(f"Number of instances: {self.num_instances}") + logger.info(f"Number of distinct objects: {self.num_objects}") + logger.info(f"Object names: {self.object_names}") # container for data access self._data = RigidObjectCollectionData(self.root_physx_view, self.num_objects, self.device) diff --git a/source/isaaclab/isaaclab/assets/surface_gripper/surface_gripper.py b/source/isaaclab/isaaclab/assets/surface_gripper/surface_gripper.py index 50a17d85efe..0e510852f79 100644 --- a/source/isaaclab/isaaclab/assets/surface_gripper/surface_gripper.py +++ b/source/isaaclab/isaaclab/assets/surface_gripper/surface_gripper.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging import torch import warnings from typing import TYPE_CHECKING -import omni.log from isaacsim.core.utils.extensions import enable_extension from isaacsim.core.version import get_version @@ -21,6 +21,9 @@ from .surface_gripper_cfg import SurfaceGripperCfg +# import logger +logger = logging.getLogger(__name__) + class SurfaceGripper(AssetBase): """A surface gripper actuator class. @@ -315,8 +318,8 @@ def _initialize_impl(self) -> None: ) # log information about the surface gripper - omni.log.info(f"Surface gripper initialized at: {self._cfg.prim_path} with root '{gripper_prim_path_expr}'.") - omni.log.info(f"Number of instances: {self._num_envs}") + logger.info(f"Surface gripper initialized at: {self._cfg.prim_path} with root '{gripper_prim_path_expr}'.") + logger.info(f"Number of instances: {self._num_envs}") # Reset grippers self.reset() diff --git a/source/isaaclab/isaaclab/controllers/utils.py b/source/isaaclab/isaaclab/controllers/utils.py index b674b267acb..b1341f4b04f 100644 --- a/source/isaaclab/isaaclab/controllers/utils.py +++ b/source/isaaclab/isaaclab/controllers/utils.py @@ -8,6 +8,7 @@ This module provides utility functions to help with controller implementations. """ +import logging import os import re @@ -15,10 +16,11 @@ enable_extension("isaacsim.asset.exporter.urdf") -import nvidia.srl.tools.logger as logger -import omni.log from nvidia.srl.from_usd.to_urdf import UsdToUrdf +# import logger +logger = logging.getLogger(__name__) + def convert_usd_to_urdf(usd_path: str, output_path: str, force_conversion: bool = True) -> tuple[str, str]: """Convert a USD file to URDF format. @@ -35,7 +37,7 @@ def convert_usd_to_urdf(usd_path: str, output_path: str, force_conversion: bool "edge_names_to_remove": None, "root": None, "parent_link_is_body_1": None, - "log_level": logger.level_from_name("ERROR"), + "log_level": logging.ERROR, } urdf_output_dir = os.path.join(output_path, "urdf") @@ -90,11 +92,11 @@ def change_revolute_to_fixed(urdf_path: str, fixed_joints: list[str], verbose: b old_str = f'' new_str = f'' if verbose: - omni.log.warn(f"Replacing {joint} with fixed joint") - omni.log.warn(old_str) - omni.log.warn(new_str) + logger.warning(f"Replacing {joint} with fixed joint") + logger.warning(old_str) + logger.warning(new_str) if old_str not in content: - omni.log.warn(f"Error: Could not find revolute joint named '{joint}' in URDF file") + logger.warning(f"Error: Could not find revolute joint named '{joint}' in URDF file") content = content.replace(old_str, new_str) with open(urdf_path, "w") as file: @@ -127,9 +129,9 @@ def change_revolute_to_fixed_regex(urdf_path: str, fixed_joints: list[str], verb old_str = f'' new_str = f'' if verbose: - omni.log.warn(f"Replacing {joint} with fixed joint") - omni.log.warn(old_str) - omni.log.warn(new_str) + logger.warning(f"Replacing {joint} with fixed joint") + logger.warning(old_str) + logger.warning(new_str) content = content.replace(old_str, new_str) with open(urdf_path, "w") as file: diff --git a/source/isaaclab/isaaclab/devices/openxr/manus_vive_utils.py b/source/isaaclab/isaaclab/devices/openxr/manus_vive_utils.py index 3044579136e..db22628dfaa 100644 --- a/source/isaaclab/isaaclab/devices/openxr/manus_vive_utils.py +++ b/source/isaaclab/isaaclab/devices/openxr/manus_vive_utils.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD-3-Clause import contextlib +import logging import numpy as np from time import time -import omni.log from isaacsim.core.utils.extensions import enable_extension # For testing purposes, we need to mock the XRCore @@ -18,6 +18,9 @@ from pxr import Gf +# import logger +logger = logging.getLogger(__name__) + # Mapping from Manus joint index (0-24) to joint name. Palm (25) is calculated from middle metacarpal and proximal. HAND_JOINT_MAP = { # Wrist @@ -144,7 +147,7 @@ def update_vive(self): if self.scene_T_lighthouse_static is None: self._initialize_coordinate_transformation() except Exception as e: - omni.log.error(f"Vive tracker update failed: {e}") + logger.error(f"Vive tracker update failed: {e}") def _initialize_coordinate_transformation(self): """ @@ -216,7 +219,7 @@ def _initialize_coordinate_transformation(self): choose_A = False elif len(self._pairA_trans_errs) % 10 == 0 or len(self._pairB_trans_errs) % 10 == 0: print("Computing pairing of Vive trackers with wrists") - omni.log.info( + logger.info( f"Pairing Vive trackers with wrists: error of pairing A: {errA}, error of pairing B: {errB}" ) if choose_A is None: @@ -245,7 +248,7 @@ def _initialize_coordinate_transformation(self): ) except Exception as e: - omni.log.error(f"Failed to initialize coordinate transformation: {e}") + logger.error(f"Failed to initialize coordinate transformation: {e}") def _transform_vive_data(self, device_data: dict) -> dict: """Transform Vive tracker poses to scene coordinates. @@ -433,7 +436,7 @@ def get_openxr_wrist_matrix(hand: str) -> Gf.Matrix4d: return None return joint.pose_matrix except Exception as e: - omni.log.warn(f"OpenXR {hand} wrist fetch failed: {e}") + logger.warning(f"OpenXR {hand} wrist fetch failed: {e}") return None diff --git a/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/fourier/gr1_t2_dex_retargeting_utils.py b/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/fourier/gr1_t2_dex_retargeting_utils.py index c0a7b056e81..929456f7509 100644 --- a/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/fourier/gr1_t2_dex_retargeting_utils.py +++ b/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/fourier/gr1_t2_dex_retargeting_utils.py @@ -3,17 +3,20 @@ # # SPDX-License-Identifier: BSD-3-Clause +import logging import numpy as np import os import torch import yaml from scipy.spatial.transform import Rotation as R -import omni.log from dex_retargeting.retargeting_config import RetargetingConfig from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR, retrieve_file_path +# import logger +logger = logging.getLogger(__name__) + # The index to map the OpenXR hand joints to the hand joints used # in Dex-retargeting. _HAND_JOINTS_INDEX = [1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 22, 23, 24, 25] @@ -104,7 +107,7 @@ def __init__( self.dof_names = self.left_dof_names + self.right_dof_names self.isaac_lab_hand_joint_names = hand_joint_names - omni.log.info("[GR1T2DexRetargeter] init done.") + logger.info("[GR1T2DexRetargeter] init done.") def _update_yaml_with_urdf_path(self, yaml_path: str, urdf_path: str): """Update YAML file with the correct URDF path. @@ -121,16 +124,16 @@ def _update_yaml_with_urdf_path(self, yaml_path: str, urdf_path: str): # Update the URDF path in the configuration if "retargeting" in config: config["retargeting"]["urdf_path"] = urdf_path - omni.log.info(f"Updated URDF path in {yaml_path} to {urdf_path}") + logger.info(f"Updated URDF path in {yaml_path} to {urdf_path}") else: - omni.log.warn(f"Unable to find 'retargeting' section in {yaml_path}") + logger.warning(f"Unable to find 'retargeting' section in {yaml_path}") # Write the updated configuration back to the file with open(yaml_path, "w") as file: yaml.dump(config, file) except Exception as e: - omni.log.error(f"Error updating YAML file {yaml_path}: {e}") + logger.error(f"Error updating YAML file {yaml_path}: {e}") def convert_hand_joints(self, hand_poses: dict[str, np.ndarray], operator2mano: np.ndarray) -> np.ndarray: """Prepares the hand joints data for retargeting. diff --git a/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/inspire/g1_dex_retargeting_utils.py b/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/inspire/g1_dex_retargeting_utils.py index 802e73aca4a..3f637bb49f8 100644 --- a/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/inspire/g1_dex_retargeting_utils.py +++ b/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/inspire/g1_dex_retargeting_utils.py @@ -3,17 +3,20 @@ # # SPDX-License-Identifier: BSD-3-Clause +import logging import numpy as np import os import torch import yaml from scipy.spatial.transform import Rotation as R -import omni.log from dex_retargeting.retargeting_config import RetargetingConfig from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR, retrieve_file_path +# import logger +logger = logging.getLogger(__name__) + # The index to map the OpenXR hand joints to the hand joints used # in Dex-retargeting. _HAND_JOINTS_INDEX = [1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 22, 23, 24, 25] @@ -107,7 +110,7 @@ def __init__( self.dof_names = self.left_dof_names + self.right_dof_names self.isaac_lab_hand_joint_names = hand_joint_names - omni.log.info("[UnitreeG1DexRetargeter] init done.") + logger.info("[UnitreeG1DexRetargeter] init done.") def _update_yaml_with_urdf_path(self, yaml_path: str, urdf_path: str): """Update YAML file with the correct URDF path. @@ -124,16 +127,16 @@ def _update_yaml_with_urdf_path(self, yaml_path: str, urdf_path: str): # Update the URDF path in the configuration if "retargeting" in config: config["retargeting"]["urdf_path"] = urdf_path - omni.log.info(f"Updated URDF path in {yaml_path} to {urdf_path}") + logger.info(f"Updated URDF path in {yaml_path} to {urdf_path}") else: - omni.log.warn(f"Unable to find 'retargeting' section in {yaml_path}") + logger.warning(f"Unable to find 'retargeting' section in {yaml_path}") # Write the updated configuration back to the file with open(yaml_path, "w") as file: yaml.dump(config, file) except Exception as e: - omni.log.error(f"Error updating YAML file {yaml_path}: {e}") + logger.error(f"Error updating YAML file {yaml_path}: {e}") def convert_hand_joints(self, hand_poses: dict[str, np.ndarray], operator2mano: np.ndarray) -> np.ndarray: """Prepares the hand joints data for retargeting. diff --git a/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/trihand/g1_dex_retargeting_utils.py b/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/trihand/g1_dex_retargeting_utils.py index 78d8ed667f9..0e474043869 100644 --- a/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/trihand/g1_dex_retargeting_utils.py +++ b/source/isaaclab/isaaclab/devices/openxr/retargeters/humanoid/unitree/trihand/g1_dex_retargeting_utils.py @@ -10,11 +10,13 @@ import yaml from scipy.spatial.transform import Rotation as R -import omni.log from dex_retargeting.retargeting_config import RetargetingConfig from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR, retrieve_file_path +# import logger +logger = logging.getLogger(__name__) + # yourdfpy loads visual/collision meshes with the hand URDFs; these aren't needed for # retargeting and clutter the logs, so we suppress them. logging.getLogger("dex_retargeting.yourdfpy").setLevel(logging.ERROR) @@ -101,7 +103,7 @@ def __init__( self.dof_names = self.left_dof_names + self.right_dof_names self.isaac_lab_hand_joint_names = hand_joint_names - omni.log.info("[G1DexRetargeter] init done.") + logger.info("[G1DexRetargeter] init done.") def _update_yaml_with_urdf_path(self, yaml_path: str, urdf_path: str): """Update YAML file with the correct URDF path. @@ -118,16 +120,16 @@ def _update_yaml_with_urdf_path(self, yaml_path: str, urdf_path: str): # Update the URDF path in the configuration if "retargeting" in config: config["retargeting"]["urdf_path"] = urdf_path - omni.log.info(f"Updated URDF path in {yaml_path} to {urdf_path}") + logger.info(f"Updated URDF path in {yaml_path} to {urdf_path}") else: - omni.log.warn(f"Unable to find 'retargeting' section in {yaml_path}") + logger.warning(f"Unable to find 'retargeting' section in {yaml_path}") # Write the updated configuration back to the file with open(yaml_path, "w") as file: yaml.dump(config, file) except Exception as e: - omni.log.error(f"Error updating YAML file {yaml_path}: {e}") + logger.error(f"Error updating YAML file {yaml_path}: {e}") def convert_hand_joints(self, hand_poses: dict[str, np.ndarray], operator2mano: np.ndarray) -> np.ndarray: """Prepares the hand joints data for retargeting. diff --git a/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py b/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py index 41e13078eb5..7da044f0211 100644 --- a/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py +++ b/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py @@ -55,7 +55,10 @@ def remove_camera_configs(env_cfg: Any) -> Any: The modified environment configuration with cameras removed. """ - import omni.log + import logging + + # import logger + logger = logging.getLogger(__name__) from isaaclab.managers import SceneEntityCfg from isaaclab.sensors import CameraCfg @@ -64,7 +67,7 @@ def remove_camera_configs(env_cfg: Any) -> Any: attr = getattr(env_cfg.scene, attr_name) if isinstance(attr, CameraCfg): delattr(env_cfg.scene, attr_name) - omni.log.info(f"Removed camera config: {attr_name}") + logger.info(f"Removed camera config: {attr_name}") # Remove any ObsTerms for the camera if hasattr(env_cfg.observations, "policy"): @@ -74,6 +77,6 @@ def remove_camera_configs(env_cfg: Any) -> Any: for param_value in obsterm.params.values(): if isinstance(param_value, SceneEntityCfg) and param_value.name == attr_name: delattr(env_cfg.observations.policy, attr_name) - omni.log.info(f"Removed camera observation term: {attr_name}") + logger.info(f"Removed camera observation term: {attr_name}") break return env_cfg diff --git a/source/isaaclab/isaaclab/devices/teleop_device_factory.py b/source/isaaclab/isaaclab/devices/teleop_device_factory.py index a02029645b6..addc1fec0ad 100644 --- a/source/isaaclab/isaaclab/devices/teleop_device_factory.py +++ b/source/isaaclab/isaaclab/devices/teleop_device_factory.py @@ -7,10 +7,9 @@ import contextlib import inspect +import logging from collections.abc import Callable -import omni.log - from isaaclab.devices import DeviceBase, DeviceCfg from isaaclab.devices.gamepad import Se2Gamepad, Se2GamepadCfg, Se3Gamepad, Se3GamepadCfg from isaaclab.devices.keyboard import Se2Keyboard, Se2KeyboardCfg, Se3Keyboard, Se3KeyboardCfg @@ -37,6 +36,9 @@ # May fail if xr is not in use from isaaclab.devices.openxr import ManusVive, ManusViveCfg, OpenXRDevice, OpenXRDeviceCfg +# import logger +logger = logging.getLogger(__name__) + # Map device types to their constructor and expected config type DEVICE_MAP: dict[type[DeviceCfg], type[DeviceBase]] = { Se3KeyboardCfg: Se3Keyboard, @@ -120,5 +122,5 @@ def create_teleop_device( for key, callback in callbacks.items(): device.add_callback(key, callback) - omni.log.info(f"Created teleoperation device: {device_name}") + logger.info(f"Created teleoperation device: {device_name}") return device diff --git a/source/isaaclab/isaaclab/envs/direct_marl_env.py b/source/isaaclab/isaaclab/envs/direct_marl_env.py index 0e7429117fc..98b1682586a 100644 --- a/source/isaaclab/isaaclab/envs/direct_marl_env.py +++ b/source/isaaclab/isaaclab/envs/direct_marl_env.py @@ -8,6 +8,7 @@ import builtins import gymnasium as gym import inspect +import logging import math import numpy as np import torch @@ -19,7 +20,6 @@ import isaacsim.core.utils.torch as torch_utils import omni.kit.app -import omni.log import omni.physx from isaacsim.core.version import get_version @@ -35,6 +35,9 @@ from .ui import ViewportCameraController from .utils.spaces import sample_space, spec_to_gym_space +# import logger +logger = logging.getLogger(__name__) + class DirectMARLEnv(gym.Env): """The superclass for the direct workflow to design multi-agent environments. @@ -89,7 +92,7 @@ def __init__(self, cfg: DirectMARLEnvCfg, render_mode: str | None = None, **kwar if self.cfg.seed is not None: self.cfg.seed = self.seed(self.cfg.seed) else: - omni.log.warn("Seed not set for the environment. The environment creation may not be deterministic.") + logger.warning("Seed not set for the environment. The environment creation may not be deterministic.") # create a simulation context to control the simulator if SimulationContext.instance() is None: @@ -115,7 +118,7 @@ def __init__(self, cfg: DirectMARLEnvCfg, render_mode: str | None = None, **kwar f"({self.cfg.decimation}). Multiple render calls will happen for each environment step." "If this is not intended, set the render interval to be equal to the decimation." ) - omni.log.warn(msg) + logger.warning(msg) # generate scene with Timer("[INFO]: Time taken for scene creation", "scene_creation"): @@ -602,17 +605,17 @@ def _configure_env_spaces(self): # show deprecation message and overwrite configuration if self.cfg.num_actions is not None: - omni.log.warn("DirectMARLEnvCfg.num_actions is deprecated. Use DirectMARLEnvCfg.action_spaces instead.") + logger.warning("DirectMARLEnvCfg.num_actions is deprecated. Use DirectMARLEnvCfg.action_spaces instead.") if isinstance(self.cfg.action_spaces, type(MISSING)): self.cfg.action_spaces = self.cfg.num_actions if self.cfg.num_observations is not None: - omni.log.warn( + logger.warning( "DirectMARLEnvCfg.num_observations is deprecated. Use DirectMARLEnvCfg.observation_spaces instead." ) if isinstance(self.cfg.observation_spaces, type(MISSING)): self.cfg.observation_spaces = self.cfg.num_observations if self.cfg.num_states is not None: - omni.log.warn("DirectMARLEnvCfg.num_states is deprecated. Use DirectMARLEnvCfg.state_space instead.") + logger.warning("DirectMARLEnvCfg.num_states is deprecated. Use DirectMARLEnvCfg.state_space instead.") if isinstance(self.cfg.state_space, type(MISSING)): self.cfg.state_space = self.cfg.num_states diff --git a/source/isaaclab/isaaclab/envs/direct_rl_env.py b/source/isaaclab/isaaclab/envs/direct_rl_env.py index e43c4db7a28..c83cce768ad 100644 --- a/source/isaaclab/isaaclab/envs/direct_rl_env.py +++ b/source/isaaclab/isaaclab/envs/direct_rl_env.py @@ -8,6 +8,7 @@ import builtins import gymnasium as gym import inspect +import logging import math import numpy as np import torch @@ -19,7 +20,6 @@ import isaacsim.core.utils.torch as torch_utils import omni.kit.app -import omni.log import omni.physx from isaacsim.core.simulation_manager import SimulationManager from isaacsim.core.version import get_version @@ -36,6 +36,9 @@ from .ui import ViewportCameraController from .utils.spaces import sample_space, spec_to_gym_space +# import logger +logger = logging.getLogger(__name__) + class DirectRLEnv(gym.Env): """The superclass for the direct workflow to design environments. @@ -95,7 +98,7 @@ def __init__(self, cfg: DirectRLEnvCfg, render_mode: str | None = None, **kwargs if self.cfg.seed is not None: self.cfg.seed = self.seed(self.cfg.seed) else: - omni.log.warn("Seed not set for the environment. The environment creation may not be deterministic.") + logger.warning("Seed not set for the environment. The environment creation may not be deterministic.") # create a simulation context to control the simulator if SimulationContext.instance() is None: @@ -121,7 +124,7 @@ def __init__(self, cfg: DirectRLEnvCfg, render_mode: str | None = None, **kwargs f"({self.cfg.decimation}). Multiple render calls will happen for each environment step." "If this is not intended, set the render interval to be equal to the decimation." ) - omni.log.warn(msg) + logger.warning(msg) # generate scene with Timer("[INFO]: Time taken for scene creation", "scene_creation"): @@ -551,17 +554,17 @@ def _configure_gym_env_spaces(self): """Configure the action and observation spaces for the Gym environment.""" # show deprecation message and overwrite configuration if self.cfg.num_actions is not None: - omni.log.warn("DirectRLEnvCfg.num_actions is deprecated. Use DirectRLEnvCfg.action_space instead.") + logger.warning("DirectRLEnvCfg.num_actions is deprecated. Use DirectRLEnvCfg.action_space instead.") if isinstance(self.cfg.action_space, type(MISSING)): self.cfg.action_space = self.cfg.num_actions if self.cfg.num_observations is not None: - omni.log.warn( + logger.warning( "DirectRLEnvCfg.num_observations is deprecated. Use DirectRLEnvCfg.observation_space instead." ) if isinstance(self.cfg.observation_space, type(MISSING)): self.cfg.observation_space = self.cfg.num_observations if self.cfg.num_states is not None: - omni.log.warn("DirectRLEnvCfg.num_states is deprecated. Use DirectRLEnvCfg.state_space instead.") + logger.warning("DirectRLEnvCfg.num_states is deprecated. Use DirectRLEnvCfg.state_space instead.") if isinstance(self.cfg.state_space, type(MISSING)): self.cfg.state_space = self.cfg.num_states diff --git a/source/isaaclab/isaaclab/envs/manager_based_env.py b/source/isaaclab/isaaclab/envs/manager_based_env.py index 9ddc538aa41..8ace2a7d8f6 100644 --- a/source/isaaclab/isaaclab/envs/manager_based_env.py +++ b/source/isaaclab/isaaclab/envs/manager_based_env.py @@ -4,12 +4,12 @@ # SPDX-License-Identifier: BSD-3-Clause import builtins +import logging import torch from collections.abc import Sequence from typing import Any import isaacsim.core.utils.torch as torch_utils -import omni.log import omni.physx from isaacsim.core.simulation_manager import SimulationManager from isaacsim.core.version import get_version @@ -26,6 +26,9 @@ from .ui import ViewportCameraController from .utils.io_descriptors import export_articulations_data, export_scene_data +# import logger +logger = logging.getLogger(__name__) + class ManagerBasedEnv: """The base environment encapsulates the simulation scene and the environment managers for the manager-based workflow. @@ -89,7 +92,7 @@ def __init__(self, cfg: ManagerBasedEnvCfg): if self.cfg.seed is not None: self.cfg.seed = self.seed(self.cfg.seed) else: - omni.log.warn("Seed not set for the environment. The environment creation may not be deterministic.") + logger.warning("Seed not set for the environment. The environment creation may not be deterministic.") # create a simulation context to control the simulator if SimulationContext.instance() is None: @@ -121,7 +124,7 @@ def __init__(self, cfg: ManagerBasedEnvCfg): f"({self.cfg.decimation}). Multiple render calls will happen for each environment step. " "If this is not intended, set the render interval to be equal to the decimation." ) - omni.log.warn(msg) + logger.warning(msg) # counter for simulation steps self._sim_step_counter = 0 diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/binary_joint_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/binary_joint_actions.py index 501c221dec6..3ef078b6627 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/binary_joint_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/binary_joint_actions.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - import isaaclab.utils.string as string_utils from isaaclab.assets.articulation import Articulation from isaaclab.managers.action_manager import ActionTerm @@ -21,6 +20,9 @@ from . import actions_cfg +# import logger +logger = logging.getLogger(__name__) + class BinaryJointAction(ActionTerm): """Base class for binary joint actions. @@ -54,7 +56,7 @@ def __init__(self, cfg: actions_cfg.BinaryJointActionCfg, env: ManagerBasedEnv) self._joint_ids, self._joint_names = self._asset.find_joints(self.cfg.joint_names) self._num_joints = len(self._joint_ids) # log the resolved joint names for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions.py index 8d5e7ebd4b3..6f48dd6dfdc 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - import isaaclab.utils.string as string_utils from isaaclab.assets.articulation import Articulation from isaaclab.managers.action_manager import ActionTerm @@ -21,6 +20,9 @@ from . import actions_cfg +# import logger +logger = logging.getLogger(__name__) + class JointAction(ActionTerm): r"""Base class for joint actions. @@ -64,7 +66,7 @@ def __init__(self, cfg: actions_cfg.JointActionCfg, env: ManagerBasedEnv) -> Non ) self._num_joints = len(self._joint_ids) # log the resolved joint names for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions_to_limits.py b/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions_to_limits.py index 2667f7e86a6..a944a83a438 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions_to_limits.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/joint_actions_to_limits.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - import isaaclab.utils.math as math_utils import isaaclab.utils.string as string_utils from isaaclab.assets.articulation import Articulation @@ -22,6 +21,9 @@ from . import actions_cfg +# import logger +logger = logging.getLogger(__name__) + class JointPositionToLimitsAction(ActionTerm): """Joint position action term that scales the input actions to the joint limits and applies them to the @@ -56,7 +58,7 @@ def __init__(self, cfg: actions_cfg.JointPositionToLimitsActionCfg, env: Manager self._joint_ids, self._joint_names = self._asset.find_joints(self.cfg.joint_names) self._num_joints = len(self._joint_ids) # log the resolved joint names for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/non_holonomic_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/non_holonomic_actions.py index 1fb50f1fea8..298eaefd946 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/non_holonomic_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/non_holonomic_actions.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - import isaaclab.utils.string as string_utils from isaaclab.assets.articulation import Articulation from isaaclab.managers.action_manager import ActionTerm @@ -22,6 +21,9 @@ from . import actions_cfg +# import logger +logger = logging.getLogger(__name__) + class NonHolonomicAction(ActionTerm): r"""Non-holonomic action that maps a two dimensional action to the velocity of the robot in @@ -92,11 +94,11 @@ def __init__(self, cfg: actions_cfg.NonHolonomicActionCfg, env: ManagerBasedEnv) self._joint_ids = [x_joint_id[0], y_joint_id[0], yaw_joint_id[0]] self._joint_names = [x_joint_name[0], y_joint_name[0], yaw_joint_name[0]] # log info for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) - omni.log.info( + logger.info( f"Resolved body name for the action term {self.__class__.__name__}: {self._body_name} [{self._body_idx}]" ) diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/rmpflow_task_space_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/rmpflow_task_space_actions.py index b270a7b92c1..fa3e819eb5d 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/rmpflow_task_space_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/rmpflow_task_space_actions.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - import isaaclab.utils.math as math_utils import isaaclab.utils.string as string_utils from isaaclab.assets.articulation import Articulation @@ -22,6 +21,9 @@ from . import rmpflow_actions_cfg +# import logger +logger = logging.getLogger(__name__) + class RMPFlowAction(ActionTerm): @@ -62,11 +64,11 @@ def __init__(self, cfg: rmpflow_actions_cfg.RMPFlowActionCfg, env: ManagerBasedE self._jacobi_joint_ids = [i + 6 for i in self._joint_ids] # log info for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) - omni.log.info( + logger.info( f"Resolved body name for the action term {self.__class__.__name__}: {self._body_name} [{self._body_idx}]" ) # Avoid indexing across all joints for efficiency diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/surface_gripper_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/surface_gripper_actions.py index 4313fbeacd2..ad2e6fe2ee2 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/surface_gripper_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/surface_gripper_actions.py @@ -5,12 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - from isaaclab.assets.surface_gripper import SurfaceGripper from isaaclab.managers.action_manager import ActionTerm @@ -19,6 +18,9 @@ from . import actions_cfg +# import logger +logger = logging.getLogger(__name__) + class SurfaceGripperBinaryAction(ActionTerm): """Surface gripper binary action. @@ -48,7 +50,7 @@ def __init__(self, cfg: actions_cfg.SurfaceGripperBinaryActionCfg, env: ManagerB super().__init__(cfg, env) # log the resolved asset name for debugging - omni.log.info( + logger.info( f"Resolved surface gripper asset for the action term {self.__class__.__name__}: {self.cfg.asset_name}" ) diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py index a764c1f0aff..0c996d654a2 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log from pxr import UsdPhysics import isaaclab.utils.math as math_utils @@ -27,6 +27,9 @@ from . import actions_cfg +# import logger +logger = logging.getLogger(__name__) + class DifferentialInverseKinematicsAction(ActionTerm): r"""Inverse Kinematics action term. @@ -78,11 +81,11 @@ def __init__(self, cfg: actions_cfg.DifferentialInverseKinematicsActionCfg, env: self._jacobi_joint_ids = [i + 6 for i in self._joint_ids] # log info for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) - omni.log.info( + logger.info( f"Resolved body name for the action term {self.__class__.__name__}: {self._body_name} [{self._body_idx}]" ) # Avoid indexing across all joints for efficiency @@ -306,11 +309,11 @@ def __init__(self, cfg: actions_cfg.OperationalSpaceControllerActionCfg, env: Ma self._jacobi_joint_idx = [i + 6 for i in self._joint_ids] # log info for debugging - omni.log.info( + logger.info( f"Resolved joint names for the action term {self.__class__.__name__}:" f" {self._joint_names} [{self._joint_ids}]" ) - omni.log.info( + logger.info( f"Resolved ee body name for the action term {self.__class__.__name__}:" f" {self._ee_body_name} [{self._ee_body_idx}]" ) diff --git a/source/isaaclab/isaaclab/envs/mdp/commands/velocity_command.py b/source/isaaclab/isaaclab/envs/mdp/commands/velocity_command.py index 64d22b4003f..5b7e3ade4f6 100644 --- a/source/isaaclab/isaaclab/envs/mdp/commands/velocity_command.py +++ b/source/isaaclab/isaaclab/envs/mdp/commands/velocity_command.py @@ -7,12 +7,11 @@ from __future__ import annotations +import logging import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log - import isaaclab.utils.math as math_utils from isaaclab.assets import Articulation from isaaclab.managers import CommandTerm @@ -23,6 +22,9 @@ from .commands_cfg import NormalVelocityCommandCfg, UniformVelocityCommandCfg +# import logger +logger = logging.getLogger(__name__) + class UniformVelocityCommand(CommandTerm): r"""Command generator that generates a velocity command in SE(2) from uniform distribution. @@ -65,7 +67,7 @@ def __init__(self, cfg: UniformVelocityCommandCfg, env: ManagerBasedEnv): " parameter is set to None." ) if self.cfg.ranges.heading and not self.cfg.heading_command: - omni.log.warn( + logger.warning( f"The velocity command has the 'ranges.heading' attribute set to '{self.cfg.ranges.heading}'" " but the heading command is not active. Consider setting the flag for the heading command to True." ) diff --git a/source/isaaclab/isaaclab/managers/event_manager.py b/source/isaaclab/isaaclab/managers/event_manager.py index 639be925e0a..a23cec17863 100644 --- a/source/isaaclab/isaaclab/managers/event_manager.py +++ b/source/isaaclab/isaaclab/managers/event_manager.py @@ -8,19 +8,21 @@ from __future__ import annotations import inspect +import logging import torch from collections.abc import Sequence from prettytable import PrettyTable from typing import TYPE_CHECKING -import omni.log - from .manager_base import ManagerBase from .manager_term_cfg import EventTermCfg if TYPE_CHECKING: from isaaclab.envs import ManagerBasedEnv +# import logger +logger = logging.getLogger(__name__) + class EventManager(ManagerBase): """Manager for orchestrating operations based on different simulation events. @@ -185,7 +187,7 @@ def apply( """ # check if mode is valid if mode not in self._mode_term_names: - omni.log.warn(f"Event mode '{mode}' is not defined. Skipping event.") + logger.warning(f"Event mode '{mode}' is not defined. Skipping event.") return # check if mode is interval and dt is not provided @@ -348,7 +350,7 @@ def _prepare_terms(self): ) if term_cfg.mode != "reset" and term_cfg.min_step_count_between_reset != 0: - omni.log.warn( + logger.warning( f"Event term '{term_name}' has 'min_step_count_between_reset' set to a non-zero value" " but the mode is not 'reset'. Ignoring the 'min_step_count_between_reset' value." ) @@ -370,7 +372,7 @@ def _prepare_terms(self): # can be initialized before the simulation starts. # this is done to ensure that the USD-level randomization is possible before the simulation starts. if inspect.isclass(term_cfg.func) and term_cfg.mode == "prestartup": - omni.log.info(f"Initializing term '{term_name}' with class '{term_cfg.func.__name__}'.") + logger.info(f"Initializing term '{term_name}' with class '{term_cfg.func.__name__}'.") term_cfg.func = term_cfg.func(cfg=term_cfg, env=self._env) # check if mode is a new mode diff --git a/source/isaaclab/isaaclab/managers/manager_base.py b/source/isaaclab/isaaclab/managers/manager_base.py index 081c3e271ec..11ed7e3defc 100644 --- a/source/isaaclab/isaaclab/managers/manager_base.py +++ b/source/isaaclab/isaaclab/managers/manager_base.py @@ -7,12 +7,12 @@ import copy import inspect +import logging import weakref from abc import ABC, abstractmethod from collections.abc import Sequence from typing import TYPE_CHECKING, Any -import omni.log import omni.timeline import isaaclab.utils.string as string_utils @@ -24,6 +24,9 @@ if TYPE_CHECKING: from isaaclab.envs import ManagerBasedEnv +# import logger +logger = logging.getLogger(__name__) + class ManagerTermBase(ABC): """Base class for manager terms. @@ -404,11 +407,11 @@ def _process_term_cfg_at_play(self, term_name: str, term_cfg: ManagerTermBaseCfg if value.body_ids is not None: msg += f"\n\tBody names: {value.body_names} [{value.body_ids}]" # print the information - omni.log.info(msg) + logger.info(msg) # store the entity term_cfg.params[key] = value # initialize the term if it is a class if inspect.isclass(term_cfg.func): - omni.log.info(f"Initializing term '{term_name}' with class '{term_cfg.func.__name__}'.") + logger.info(f"Initializing term '{term_name}' with class '{term_cfg.func.__name__}'.") term_cfg.func = term_cfg.func(cfg=term_cfg, env=self._env) diff --git a/source/isaaclab/isaaclab/markers/visualization_markers.py b/source/isaaclab/isaaclab/markers/visualization_markers.py index ce4611289bc..ab38d06d2c3 100644 --- a/source/isaaclab/isaaclab/markers/visualization_markers.py +++ b/source/isaaclab/isaaclab/markers/visualization_markers.py @@ -19,13 +19,13 @@ # needed to import for allowing type-hinting: np.ndarray | torch.Tensor | None from __future__ import annotations +import logging import numpy as np import torch from dataclasses import MISSING import isaacsim.core.utils.stage as stage_utils import omni.kit.commands -import omni.log import omni.physx.scripts.utils as physx_utils from isaacsim.core.utils.stage import get_current_stage from pxr import Gf, PhysxSchema, Sdf, Usd, UsdGeom, UsdPhysics, Vt @@ -36,6 +36,9 @@ from isaaclab.utils.configclass import configclass from isaaclab.utils.math import convert_quat +# import logger +logger = logging.getLogger(__name__) + @configclass class VisualizationMarkersCfg: diff --git a/source/isaaclab/isaaclab/scene/interactive_scene.py b/source/isaaclab/isaaclab/scene/interactive_scene.py index 15739c33ad7..6772f77bba7 100644 --- a/source/isaaclab/isaaclab/scene/interactive_scene.py +++ b/source/isaaclab/isaaclab/scene/interactive_scene.py @@ -3,13 +3,12 @@ # # SPDX-License-Identifier: BSD-3-Clause +import logging import torch from collections.abc import Sequence from typing import Any import carb -import omni.log -import omni.usd from isaacsim.core.cloner import GridCloner from isaacsim.core.prims import XFormPrim from isaacsim.core.utils.stage import get_current_stage @@ -37,6 +36,9 @@ from .interactive_scene_cfg import InteractiveSceneCfg +# import logger +logger = logging.getLogger(__name__) + class InteractiveScene: """A scene that contains entities added to the simulation. @@ -222,7 +224,7 @@ def clone_environments(self, copy_from_source: bool = False): carb_settings_iface = carb.settings.get_settings() has_multi_assets = carb_settings_iface.get("/isaaclab/spawn/multi_assets") if has_multi_assets and self.cfg.replicate_physics: - omni.log.warn( + logger.warning( "Varying assets might have been spawned under different environments." " However, the replicate physics flag is enabled in the 'InteractiveScene' configuration." " This may adversely affect PhysX parsing. We recommend disabling this property." @@ -260,7 +262,7 @@ def clone_environments(self, copy_from_source: bool = False): if (not self.cfg.replicate_physics and self.cfg.filter_collisions) or self.device == "cpu": # if scene is specified through cfg, this is already taken care of if not self._is_scene_setup_from_cfg(): - omni.log.warn( + logger.warning( "Collision filtering can only be automatically enabled when replicate_physics=True and using GPU" " simulation. Please call scene.filter_collisions(global_prim_paths) to filter collisions across" " environments." @@ -324,7 +326,7 @@ def physics_scene_path(self) -> str: for prim in self.stage.Traverse(): if prim.HasAPI(PhysxSchema.PhysxSceneAPI): self._physics_scene_path = prim.GetPrimPath().pathString - omni.log.info(f"Physics scene prim path: {self._physics_scene_path}") + logger.info(f"Physics scene prim path: {self._physics_scene_path}") break if self._physics_scene_path is None: raise RuntimeError("No physics scene found! Please make sure one exists.") diff --git a/source/isaaclab/isaaclab/sensors/camera/camera.py b/source/isaaclab/isaaclab/sensors/camera/camera.py index 8d3fe257df6..c7a208ba8ec 100644 --- a/source/isaaclab/isaaclab/sensors/camera/camera.py +++ b/source/isaaclab/isaaclab/sensors/camera/camera.py @@ -6,6 +6,7 @@ from __future__ import annotations import json +import logging import numpy as np import re import torch @@ -36,6 +37,9 @@ if TYPE_CHECKING: from .camera_cfg import CameraCfg +# import logger +logger = logging.getLogger(__name__) + class Camera(SensorBase): r"""The camera sensor for acquiring visual data. @@ -148,7 +152,7 @@ def __init__(self, cfg: CameraCfg): # checks for Isaac Sim v4.5 as this issue exists there if int(isaac_sim_version[2]) == 4 and int(isaac_sim_version[3]) == 5: if "semantic_segmentation" in self.cfg.data_types or "instance_segmentation_fast" in self.cfg.data_types: - omni.log.warn( + logger.warning( "Isaac Sim 4.5 introduced a bug in Camera and TiledCamera when outputting instance and semantic" " segmentation outputs for instanceable assets. As a workaround, the instanceable flag on assets" " will be disabled in the current workflow and may lead to longer load times and increased memory" diff --git a/source/isaaclab/isaaclab/sensors/frame_transformer/frame_transformer.py b/source/isaaclab/isaaclab/sensors/frame_transformer/frame_transformer.py index ae7811d31ec..b6d2e766302 100644 --- a/source/isaaclab/isaaclab/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab/isaaclab/sensors/frame_transformer/frame_transformer.py @@ -5,12 +5,12 @@ from __future__ import annotations +import logging import re import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log from isaacsim.core.simulation_manager import SimulationManager from pxr import UsdPhysics @@ -32,6 +32,9 @@ if TYPE_CHECKING: from .frame_transformer_cfg import FrameTransformerCfg +# import logger +logger = logging.getLogger(__name__) + class FrameTransformer(SensorBase): """A sensor for reporting frame transforms. @@ -149,10 +152,10 @@ def _initialize_impl(self): self._apply_source_frame_offset = True # Handle source frame offsets if is_identity_pose(source_frame_offset_pos, source_frame_offset_quat): - omni.log.verbose(f"No offset application needed for source frame as it is identity: {self.cfg.prim_path}") + logger.debug(f"No offset application needed for source frame as it is identity: {self.cfg.prim_path}") self._apply_source_frame_offset = False else: - omni.log.verbose(f"Applying offset to source frame as it is not identity: {self.cfg.prim_path}") + logger.debug(f"Applying offset to source frame as it is not identity: {self.cfg.prim_path}") # Store offsets as tensors (duplicating each env's offsets for ease of multiplication later) self._source_frame_offset_pos = source_frame_offset_pos.unsqueeze(0).repeat(self._num_envs, 1) self._source_frame_offset_quat = source_frame_offset_quat.unsqueeze(0).repeat(self._num_envs, 1) @@ -229,12 +232,12 @@ def _initialize_impl(self): target_offsets[frame_name] = {"pos": offset_pos, "quat": offset_quat} if not self._apply_target_frame_offset: - omni.log.info( + logger.info( f"No offsets application needed from '{self.cfg.prim_path}' to target frames as all" f" are identity: {frames[1:]}" ) else: - omni.log.info( + logger.info( f"Offsets application needed from '{self.cfg.prim_path}' to the following target frames:" f" {non_identity_offset_frames}" ) diff --git a/source/isaaclab/isaaclab/sensors/ray_caster/ray_caster.py b/source/isaaclab/isaaclab/sensors/ray_caster/ray_caster.py index 8e2f6541fe9..723d669d8a0 100644 --- a/source/isaaclab/isaaclab/sensors/ray_caster/ray_caster.py +++ b/source/isaaclab/isaaclab/sensors/ray_caster/ray_caster.py @@ -5,13 +5,14 @@ from __future__ import annotations +import logging import numpy as np import re import torch from collections.abc import Sequence from typing import TYPE_CHECKING -import omni.log +import omni import omni.physics.tensors.impl.api as physx import warp as wp from isaacsim.core.prims import XFormPrim @@ -31,6 +32,9 @@ if TYPE_CHECKING: from .ray_caster_cfg import RayCasterCfg +# import logger +logger = logging.getLogger(__name__) + class RayCaster(SensorBase): """A ray-casting sensor. @@ -149,7 +153,7 @@ def _initialize_impl(self): else: self._view = XFormPrim(self.cfg.prim_path, reset_xform_properties=False) found_supported_prim_class = True - omni.log.warn(f"The prim at path {prim.GetPath().pathString} is not a physics prim! Using XFormPrim.") + logger.warning(f"The prim at path {prim.GetPath().pathString} is not a physics prim! Using XFormPrim.") # check if prim view class is found if not found_supported_prim_class: raise RuntimeError(f"Failed to find a valid prim view class for the prim paths: {self.cfg.prim_path}") @@ -192,14 +196,14 @@ def _initialize_warp_meshes(self): indices = np.asarray(mesh_prim.GetFaceVertexIndicesAttr().Get()) wp_mesh = convert_to_warp_mesh(points, indices, device=self.device) # print info - omni.log.info( + logger.info( f"Read mesh prim: {mesh_prim.GetPath()} with {len(points)} vertices and {len(indices)} faces." ) else: mesh = make_plane(size=(2e6, 2e6), height=0.0, center_zero=True) wp_mesh = convert_to_warp_mesh(mesh.vertices, mesh.faces, device=self.device) # print info - omni.log.info(f"Created infinite plane mesh prim: {mesh_prim.GetPath()}.") + logger.info(f"Created infinite plane mesh prim: {mesh_prim.GetPath()}.") # add the warp mesh to the list self.meshes[mesh_prim_path] = wp_mesh @@ -265,7 +269,7 @@ def _update_buffers_impl(self, env_ids: Sequence[int]): self.cfg.ray_alignment = "base" msg += " Setting ray_alignment to 'base'." # log the warning - omni.log.warn(msg) + logger.warning(msg) # ray cast based on the sensor poses if self.cfg.ray_alignment == "world": # apply horizontal drift to ray starting position in ray caster frame diff --git a/source/isaaclab/isaaclab/sim/converters/mesh_converter.py b/source/isaaclab/isaaclab/sim/converters/mesh_converter.py index a35167fad99..30ea04c28df 100644 --- a/source/isaaclab/isaaclab/sim/converters/mesh_converter.py +++ b/source/isaaclab/isaaclab/sim/converters/mesh_converter.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: BSD-3-Clause import asyncio +import logging import os import omni @@ -17,6 +18,9 @@ from isaaclab.sim.schemas import schemas from isaaclab.sim.utils import export_prim_to_file +# import logger +logger = logging.getLogger(__name__) + class MeshConverter(AssetConverterBase): """Converter for a mesh file in OBJ / STL / FBX format to a USD file. @@ -87,7 +91,7 @@ def _convert_asset(self, cfg: MeshConverterCfg): # Correct the name to a valid identifier and update the basename mesh_file_basename_original = mesh_file_basename mesh_file_basename = Tf.MakeValidIdentifier(mesh_file_basename) - omni.log.warn( + logger.warning( f"Input file name '{mesh_file_basename_original}' is an invalid identifier for the mesh prim path." f" Renaming it to '{mesh_file_basename}' for the conversion." ) diff --git a/source/isaaclab/isaaclab/sim/schemas/schemas.py b/source/isaaclab/isaaclab/sim/schemas/schemas.py index 482b6745842..20ea93bb703 100644 --- a/source/isaaclab/isaaclab/sim/schemas/schemas.py +++ b/source/isaaclab/isaaclab/sim/schemas/schemas.py @@ -6,9 +6,9 @@ # needed to import for allowing type-hinting: Usd.Stage | None from __future__ import annotations +import logging import math -import omni.log import omni.physx.scripts.utils as physx_utils from isaacsim.core.utils.stage import get_current_stage from omni.physx.scripts import deformableUtils as deformable_utils @@ -22,6 +22,9 @@ ) from . import schemas_cfg +# import logger +logger = logging.getLogger(__name__) + """ Articulation root properties. """ @@ -151,12 +154,12 @@ def modify_articulation_root_properties( # if we found a fixed joint, enable/disable it based on the input # otherwise, create a fixed joint between the world and the root link if existing_fixed_joint_prim is not None: - omni.log.info( + logger.info( f"Found an existing fixed joint for the articulation: '{prim_path}'. Setting it to: {fix_root_link}." ) existing_fixed_joint_prim.GetJointEnabledAttr().Set(fix_root_link) elif fix_root_link: - omni.log.info(f"Creating a fixed joint for the articulation: '{prim_path}'.") + logger.info(f"Creating a fixed joint for the articulation: '{prim_path}'.") # note: we have to assume that the root prim is a rigid body, # i.e. we don't handle the case where the root prim is not a rigid body but has articulation api on it @@ -527,10 +530,10 @@ def activate_contact_sensors(prim_path: str, threshold: float = 0.0, stage: Usd. rb.CreateSleepThresholdAttr().Set(0.0) # add contact report API with threshold of zero if not child_prim.HasAPI(PhysxSchema.PhysxContactReportAPI): - omni.log.verbose(f"Adding contact report API to prim: '{child_prim.GetPrimPath()}'") + logger.debug(f"Adding contact report API to prim: '{child_prim.GetPrimPath()}'") cr_api = PhysxSchema.PhysxContactReportAPI.Apply(child_prim) else: - omni.log.verbose(f"Contact report API already exists on prim: '{child_prim.GetPrimPath()}'") + logger.debug(f"Contact report API already exists on prim: '{child_prim.GetPrimPath()}'") cr_api = PhysxSchema.PhysxContactReportAPI.Get(stage, child_prim.GetPrimPath()) # set threshold to zero cr_api.CreateThresholdAttr().Set(threshold) diff --git a/source/isaaclab/isaaclab/sim/simulation_cfg.py b/source/isaaclab/isaaclab/sim/simulation_cfg.py index 380dba26c51..9cf7f71c369 100644 --- a/source/isaaclab/isaaclab/sim/simulation_cfg.py +++ b/source/isaaclab/isaaclab/sim/simulation_cfg.py @@ -410,3 +410,9 @@ class SimulationCfg: Creating the stage in memory can reduce start-up time. """ + + logging_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "WARNING" + """The logging level. Default is "WARNING".""" + + save_logs_to_file: bool = True + """Save logs to a file. Default is True.""" diff --git a/source/isaaclab/isaaclab/sim/simulation_context.py b/source/isaaclab/isaaclab/sim/simulation_context.py index 83277635acf..fb260421f99 100644 --- a/source/isaaclab/isaaclab/sim/simulation_context.py +++ b/source/isaaclab/isaaclab/sim/simulation_context.py @@ -6,9 +6,12 @@ import builtins import enum import glob +import logging import numpy as np import os import re +import sys +import tempfile import time import toml import torch @@ -22,7 +25,6 @@ import carb import flatdict import isaacsim.core.utils.stage as stage_utils -import omni.log import omni.physx import omni.usd from isaacsim.core.api.simulation_context import SimulationContext as _SimulationContext @@ -36,7 +38,7 @@ from .simulation_cfg import SimulationCfg from .spawners import DomeLightCfg, GroundPlaneCfg -from .utils import bind_physics_material +from .utils import ColoredFormatter, RateLimitFilter, bind_physics_material class SimulationContext(_SimulationContext): @@ -132,6 +134,9 @@ def __init__(self, cfg: SimulationCfg | None = None): if stage_utils.get_current_stage() is None: raise RuntimeError("The stage has not been created. Did you run the simulator?") + # setup logger + self.logger = self._setup_logger() + # create stage in memory if requested if self.cfg.create_stage_in_memory: self._initial_stage = create_new_stage_in_memory() @@ -254,7 +259,7 @@ def __init__(self, cfg: SimulationCfg | None = None): # add warning about enabling stabilization for large step sizes if not self.cfg.physx.enable_stabilization and (self.cfg.dt > 0.0333): - omni.log.warn( + self.logger.warning( "Large simulation step size (> 0.0333 seconds) is not recommended without enabling stabilization." " Consider setting the `enable_stabilization` flag to True in the PhysxCfg, or reducing the" " simulation step size if you run into physics issues." @@ -408,7 +413,7 @@ def set_render_mode(self, mode: RenderMode): """ # check if mode change is possible -- not possible when no GUI is available if not self._has_gui: - omni.log.warn( + self.logger.warning( f"Cannot change render mode when GUI is disabled. Using the default render mode: {self.render_mode}." ) return @@ -661,7 +666,7 @@ def _apply_physics_settings(self): # note: we disable it by default to avoid the overhead of contact processing when it isn't needed. # The physics flag gets enabled when a contact sensor is created. if hasattr(self.cfg, "disable_contact_processing"): - omni.log.warn( + self.logger.warning( "The `disable_contact_processing` attribute is deprecated and always set to True" " to avoid unnecessary overhead. Contact processing is automatically enabled when" " a contact sensor is created, so manual configuration is no longer required." @@ -979,6 +984,46 @@ def _app_control_on_stop_handle_fn(self, event: carb.events.IEvent): self.render() return + """ + Logger. + """ + + def _setup_logger(self): + """Sets up the logger.""" + root_logger = logging.getLogger() + root_logger.setLevel(self.cfg.logging_level) + + # remove existing handlers + if root_logger.hasHandlers(): + for handler in root_logger.handlers: + root_logger.removeHandler(handler) + + handler = logging.StreamHandler(sys.stdout) + handler.setLevel(self.cfg.logging_level) + + formatter = ColoredFormatter(fmt="%(asctime)s [%(filename)s] %(levelname)s: %(message)s", datefmt="%H:%M:%S") + handler.setFormatter(formatter) + handler.addFilter(RateLimitFilter(interval_seconds=5)) + root_logger.addHandler(handler) + + # --- File handler (optional) --- + if self.cfg.save_logs_to_file: + temp_dir = tempfile.gettempdir() + log_file_path = os.path.join(temp_dir, f"isaaclab_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log") + + file_handler = logging.FileHandler(log_file_path, mode="w", encoding="utf-8") + file_handler.setLevel(logging.DEBUG) + file_formatter = logging.Formatter( + fmt="%(asctime)s [%(filename)s:%(lineno)d] %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S" + ) + file_handler.setFormatter(file_formatter) + root_logger.addHandler(file_handler) + + # Print the log file path once at startup + print(f"[INFO] IsaacLab logging to file: {log_file_path}") + + return root_logger + @contextmanager def build_simulation_context( @@ -1066,7 +1111,7 @@ def build_simulation_context( yield sim except Exception: - omni.log.error(traceback.format_exc()) + sim.logger.error(traceback.format_exc()) raise finally: if not sim.has_gui(): diff --git a/source/isaaclab/isaaclab/sim/spawners/from_files/from_files.py b/source/isaaclab/isaaclab/sim/spawners/from_files/from_files.py index a3c8a44015a..04592a4066d 100644 --- a/source/isaaclab/isaaclab/sim/spawners/from_files/from_files.py +++ b/source/isaaclab/isaaclab/sim/spawners/from_files/from_files.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging from typing import TYPE_CHECKING import isaacsim.core.utils.prims as prim_utils import omni.kit.commands -import omni.log from pxr import Gf, Sdf, Usd # from Isaac Sim 4.2 onwards, pxr.Semantics is deprecated @@ -33,6 +33,9 @@ if TYPE_CHECKING: from . import from_files_cfg +# import logger +logger = logging.getLogger(__name__) + @clone def spawn_from_usd( @@ -183,7 +186,7 @@ def spawn_ground_plane( # avoiding this step if stage is in memory since the "ChangePropertyCommand" kit command # is not supported in stage in memory if is_current_stage_in_memory(): - omni.log.warn( + logger.warning( "Ground plane color modification is not supported while the stage is in memory. Skipping operation." ) @@ -282,7 +285,7 @@ def _spawn_from_usd_file( scale=cfg.scale, ) else: - omni.log.warn(f"A prim already exists at prim path: '{prim_path}'.") + logger.warning(f"A prim already exists at prim path: '{prim_path}'.") # modify variants if hasattr(cfg, "variants") and cfg.variants is not None: diff --git a/source/isaaclab/isaaclab/sim/spawners/materials/visual_materials.py b/source/isaaclab/isaaclab/sim/spawners/materials/visual_materials.py index 3c79f6f679e..30cd153a79c 100644 --- a/source/isaaclab/isaaclab/sim/spawners/materials/visual_materials.py +++ b/source/isaaclab/isaaclab/sim/spawners/materials/visual_materials.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging from typing import TYPE_CHECKING import isaacsim.core.utils.prims as prim_utils import omni.kit.commands -import omni.log from pxr import Usd from isaaclab.sim.utils import attach_stage_to_usd_context, clone, safe_set_attribute_on_usd_prim @@ -18,6 +18,9 @@ if TYPE_CHECKING: from . import visual_materials_cfg +# import logger +logger = logging.getLogger(__name__) + @clone def spawn_preview_surface(prim_path: str, cfg: visual_materials_cfg.PreviewSurfaceCfg) -> Usd.Prim: diff --git a/source/isaaclab/isaaclab/sim/spawners/sensors/sensors.py b/source/isaaclab/isaaclab/sim/spawners/sensors/sensors.py index 0a385902a55..e10bf63b5c3 100644 --- a/source/isaaclab/isaaclab/sim/spawners/sensors/sensors.py +++ b/source/isaaclab/isaaclab/sim/spawners/sensors/sensors.py @@ -5,11 +5,11 @@ from __future__ import annotations +import logging from typing import TYPE_CHECKING import isaacsim.core.utils.prims as prim_utils import omni.kit.commands -import omni.log from pxr import Sdf, Usd from isaaclab.sim.utils import attach_stage_to_usd_context, clone @@ -18,6 +18,8 @@ if TYPE_CHECKING: from . import sensors_cfg +# import logger +logger = logging.getLogger(__name__) CUSTOM_PINHOLE_CAMERA_ATTRIBUTES = { "projection_type": ("cameraProjectionType", Sdf.ValueTypeNames.Token), @@ -110,7 +112,7 @@ def spawn_camera( # TODO: Adjust to handle aperture offsets once supported by omniverse # Internal ticket from rendering team: OM-42611 if cfg.horizontal_aperture_offset > 1e-4 or cfg.vertical_aperture_offset > 1e-4: - omni.log.warn("Camera aperture offsets are not supported by Omniverse. These parameters will be ignored.") + logger.warning("Camera aperture offsets are not supported by Omniverse. These parameters will be ignored.") # custom attributes in the config that are not USD Camera parameters non_usd_cfg_param_names = [ diff --git a/source/isaaclab/isaaclab/sim/utils.py b/source/isaaclab/isaaclab/sim/utils.py index 338ec5d843a..158f2fc6112 100644 --- a/source/isaaclab/isaaclab/sim/utils.py +++ b/source/isaaclab/isaaclab/sim/utils.py @@ -10,7 +10,9 @@ import contextlib import functools import inspect +import logging import re +import time from collections.abc import Callable, Generator from typing import TYPE_CHECKING, Any @@ -18,7 +20,6 @@ import isaacsim.core.utils.stage as stage_utils import omni import omni.kit.commands -import omni.log from isaacsim.core.cloner import Cloner from isaacsim.core.utils.carb import get_carb_setting from isaacsim.core.utils.stage import get_current_stage @@ -38,6 +39,9 @@ if TYPE_CHECKING: from .spawners.spawner_cfg import SpawnerCfg +# import logger +logger = logging.getLogger(__name__) + """ Attribute - Setters. """ @@ -76,7 +80,7 @@ def safe_set_attribute_on_usd_schema(schema_api: Usd.APISchemaBase, name: str, v else: # think: do we ever need to create the attribute if it doesn't exist? # currently, we are not doing this since the schemas are already created with some defaults. - omni.log.error(f"Attribute '{attr_name}' does not exist on prim '{schema_api.GetPath()}'.") + logger.error(f"Attribute '{attr_name}' does not exist on prim '{schema_api.GetPath()}'.") raise TypeError(f"Attribute '{attr_name}' does not exist on prim '{schema_api.GetPath()}'.") @@ -201,7 +205,7 @@ def wrapper(prim_path: str | Sdf.Path, *args, **kwargs): count_success += 1 # check if we were successful in applying the function to any prim if count_success == 0: - omni.log.warn( + logger.warning( f"Could not perform '{func.__name__}' on any prims under: '{prim_path}'." " This might be because of the following reasons:" "\n\t(1) The desired attribute does not exist on any of the prims." @@ -424,7 +428,7 @@ def bind_physics_material( has_deformable_body = prim.HasAPI(PhysxSchema.PhysxDeformableBodyAPI) has_particle_system = prim.IsA(PhysxSchema.PhysxParticleSystem) if not (has_physics_scene_api or has_collider or has_deformable_body or has_particle_system): - omni.log.verbose( + logger.debug( f"Cannot apply physics material '{material_path}' on prim '{prim_path}'. It is neither a" " PhysX scene, collider, a deformable body, nor a particle system." ) @@ -1022,14 +1026,14 @@ class TableVariants: for variant_set_name, variant_selection in variants.items(): # Check if the variant set exists on the prim. if not existing_variant_sets.HasVariantSet(variant_set_name): - omni.log.warn(f"Variant set '{variant_set_name}' does not exist on prim '{prim_path}'.") + logger.warning(f"Variant set '{variant_set_name}' does not exist on prim '{prim_path}'.") continue variant_set = existing_variant_sets.GetVariantSet(variant_set_name) # Only set the variant selection if it is different from the current selection. if variant_set.GetVariantSelection() != variant_selection: variant_set.SetVariantSelection(variant_selection) - omni.log.info( + logger.info( f"Setting variant selection '{variant_selection}' for variant set '{variant_set_name}' on" f" prim '{prim_path}'." ) @@ -1080,7 +1084,7 @@ def attach_stage_to_usd_context(attaching_early: bool = False): # early attach warning msg if attaching_early: - omni.log.warn( + logger.warning( "Attaching stage in memory to USD context early to support an operation which doesn't support stage in" " memory." ) @@ -1140,7 +1144,7 @@ def use_stage(stage: Usd.Stage) -> Generator[None, None, None]: """ isaac_sim_version = float(".".join(get_version()[2])) if isaac_sim_version < 5: - omni.log.warn("[Compat] Isaac Sim < 5.0 does not support thread-local stage contexts. Skipping use_stage().") + logger.warning("[Compat] Isaac Sim < 5.0 does not support thread-local stage contexts. Skipping use_stage().") yield # no-op else: with stage_utils.use_stage(stage): @@ -1155,7 +1159,7 @@ def create_new_stage_in_memory() -> Usd.Stage: """ isaac_sim_version = float(".".join(get_version()[2])) if isaac_sim_version < 5: - omni.log.warn( + logger.warning( "[Compat] Isaac Sim < 5.0 does not support creating a new stage in memory. Falling back to creating a new" " stage attached to USD context." ) @@ -1179,3 +1183,44 @@ def get_current_stage_id() -> int: if stage_id < 0: stage_id = stage_cache.Insert(stage).ToLongInt() return stage_id + + +""" +Logger. +""" + + +# --- Colored formatter --- +class ColoredFormatter(logging.Formatter): + COLORS = { + "WARNING": "\033[33m", # orange/yellow + "ERROR": "\033[31m", # red + "CRITICAL": "\033[31m", # red + "INFO": "\033[0m", # reset + "DEBUG": "\033[0m", + } + RESET = "\033[0m" + + def format(self, record): + color = self.COLORS.get(record.levelname, self.RESET) + message = super().format(record) + return f"{color}{message}{self.RESET}" + + +# --- Custom rate-limited warning filter --- +class RateLimitFilter(logging.Filter): + def __init__(self, interval_seconds=5): + super().__init__() + self.interval = interval_seconds + self.last_emitted = {} + + def filter(self, record): + """Allow WARNINGs only once every few seconds per message.""" + if record.levelno != logging.WARNING: + return True + now = time.time() + msg_key = record.getMessage() + if msg_key not in self.last_emitted or (now - self.last_emitted[msg_key]) > self.interval: + self.last_emitted[msg_key] = now + return True + return False diff --git a/source/isaaclab/isaaclab/terrains/terrain_generator.py b/source/isaaclab/isaaclab/terrains/terrain_generator.py index 456aa88c174..26b4b9efa00 100644 --- a/source/isaaclab/isaaclab/terrains/terrain_generator.py +++ b/source/isaaclab/isaaclab/terrains/terrain_generator.py @@ -5,14 +5,13 @@ from __future__ import annotations +import logging import numpy as np import os import torch import trimesh from typing import TYPE_CHECKING -import omni.log - from isaaclab.utils.dict import dict_to_md5_hash from isaaclab.utils.io import dump_yaml from isaaclab.utils.timer import Timer @@ -25,6 +24,9 @@ from .sub_terrain_cfg import FlatPatchSamplingCfg, SubTerrainBaseCfg from .terrain_generator_cfg import TerrainGeneratorCfg +# import logger +logger = logging.getLogger(__name__) + class TerrainGenerator: r"""Terrain generator to handle different terrain generation functions. @@ -126,7 +128,7 @@ def __init__(self, cfg: TerrainGeneratorCfg, device: str = "cpu"): # throw a warning if the cache is enabled but the seed is not set if self.cfg.use_cache and self.cfg.seed is None: - omni.log.warn( + logger.warning( "Cache is enabled but the seed is not set. The terrain generation will not be reproducible." " Please set the seed in the terrain generator configuration to make the generation reproducible." ) @@ -302,7 +304,7 @@ def _add_sub_terrain( """ # sample flat patches if specified if sub_terrain_cfg.flat_patch_sampling is not None: - omni.log.info(f"Sampling flat patches for sub-terrain at (row, col): ({row}, {col})") + logger.info(f"Sampling flat patches for sub-terrain at (row, col): ({row}, {col})") # convert the mesh to warp mesh wp_mesh = convert_to_warp_mesh(mesh.vertices, mesh.faces, device=self.device) # sample flat patches based on each patch configuration for that sub-terrain diff --git a/source/isaaclab/isaaclab/terrains/terrain_importer.py b/source/isaaclab/isaaclab/terrains/terrain_importer.py index a8a2712f251..f5c90962133 100644 --- a/source/isaaclab/isaaclab/terrains/terrain_importer.py +++ b/source/isaaclab/isaaclab/terrains/terrain_importer.py @@ -5,13 +5,12 @@ from __future__ import annotations +import logging import numpy as np import torch import trimesh from typing import TYPE_CHECKING -import omni.log - import isaaclab.sim as sim_utils from isaaclab.markers import VisualizationMarkers from isaaclab.markers.config import FRAME_MARKER_CFG @@ -21,6 +20,9 @@ if TYPE_CHECKING: from .terrain_importer_cfg import TerrainImporterCfg +# import logger +logger = logging.getLogger(__name__) + class TerrainImporter: r"""A class to handle terrain meshes and import them into the simulator. @@ -208,7 +210,7 @@ def import_ground_plane(self, name: str, size: tuple[float, float] = (2.0e6, 2.0 if "diffuse_color" in material: color = material["diffuse_color"] else: - omni.log.warn( + logger.warning( "Visual material specified for ground plane but no diffuse color found." " Using default color: (0.0, 0.0, 0.0)" ) @@ -373,7 +375,7 @@ def warp_meshes(self): .. deprecated:: v2.1.0 The `warp_meshes` attribute is deprecated. It is no longer stored inside the class. """ - omni.log.warn( + logger.warning( "The `warp_meshes` attribute is deprecated. It is no longer stored inside the `TerrainImporter` class." " Returning an empty dictionary." ) @@ -386,7 +388,7 @@ def meshes(self) -> dict[str, trimesh.Trimesh]: .. deprecated:: v2.1.0 The `meshes` attribute is deprecated. It is no longer stored inside the class. """ - omni.log.warn( + logger.warning( "The `meshes` attribute is deprecated. It is no longer stored inside the `TerrainImporter` class." " Returning an empty dictionary." ) diff --git a/source/isaaclab/isaaclab/ui/widgets/image_plot.py b/source/isaaclab/isaaclab/ui/widgets/image_plot.py index 5b61daae85f..08497ba7002 100644 --- a/source/isaaclab/isaaclab/ui/widgets/image_plot.py +++ b/source/isaaclab/isaaclab/ui/widgets/image_plot.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause +import logging import numpy as np from contextlib import suppress from matplotlib import cm @@ -10,7 +11,6 @@ import carb import omni -import omni.log with suppress(ImportError): # isaacsim.gui is not available when running in headless mode. @@ -22,6 +22,9 @@ import isaacsim.gui.components import omni.ui +# import logger +logger = logging.getLogger(__name__) + class ImagePlot(UIWidgetWrapper): """An image plot widget to display live data. @@ -115,7 +118,7 @@ def update_image(self, image: np.ndarray): image = (image * 255).astype(np.uint8) elif self._curr_mode == "Colorization": if image.ndim == 3 and image.shape[2] == 3: - omni.log.warn("Colorization mode is only available for single channel images") + logger.warning("Colorization mode is only available for single channel images") else: image = (image - image.min()) / (image.max() - image.min()) colormap = cm.get_cmap("jet") diff --git a/source/isaaclab/isaaclab/ui/widgets/manager_live_visualizer.py b/source/isaaclab/isaaclab/ui/widgets/manager_live_visualizer.py index a7cc31c070b..bf4d43a4d2e 100644 --- a/source/isaaclab/isaaclab/ui/widgets/manager_live_visualizer.py +++ b/source/isaaclab/isaaclab/ui/widgets/manager_live_visualizer.py @@ -5,13 +5,13 @@ from __future__ import annotations +import logging import numpy import weakref from dataclasses import MISSING from typing import TYPE_CHECKING import omni.kit.app -import omni.log from isaacsim.core.api.simulation_context import SimulationContext from isaaclab.managers import ManagerBase @@ -24,6 +24,9 @@ if TYPE_CHECKING: import omni.ui +# import logger +logger = logging.getLogger(__name__) + @configclass class ManagerLiveVisualizerCfg: @@ -79,7 +82,7 @@ def __init__(self, manager: ManagerBase, cfg: ManagerLiveVisualizerCfg = Manager if term_name in self._manager.active_terms: self.term_names.append(term_name) else: - omni.log.error( + logger.error( f"ManagerVisualizer Failure: ManagerTerm ({term_name}) does not exist in" f" Manager({self.cfg.manager_name})" ) @@ -94,17 +97,17 @@ def __init__(self, manager: ManagerBase, cfg: ManagerLiveVisualizerCfg = Manager if term_name in self._manager.active_terms[group]: self.term_names.append(f"{group}-{term_name}") else: - omni.log.error( + logger.error( f"ManagerVisualizer Failure: ManagerTerm ({term_name}) does not exist in" f" Group({group})" ) else: - omni.log.error( + logger.error( f"ManagerVisualizer Failure: Group ({group}) does not exist in" f" Manager({self.cfg.manager_name})" ) else: - omni.log.error( + logger.error( f"ManagerVisualizer Failure: Manager({self.cfg.manager_name}) does not utilize grouping of" " terms." ) @@ -148,7 +151,7 @@ def _set_env_selection_impl(self, env_idx: int): if env_idx > 0 and env_idx < self._manager.num_envs: self._env_idx = env_idx else: - omni.log.warn(f"Environment index is out of range (0, {self._manager.num_envs - 1})") + logger.warning(f"Environment index is out of range (0, {self._manager.num_envs - 1})") def _set_vis_frame_impl(self, frame: omni.ui.Frame): """Updates the assigned frame that can be used for visualizations. @@ -227,7 +230,7 @@ def _set_debug_vis_impl(self, debug_vis: bool): image = ImagePlot(image=numpy.array(term), label=name) self._term_visualizers.append(image) else: - omni.log.warn( + logger.warning( f"ManagerLiveVisualizer: Term ({name}) is not a supported data type for" " visualization." ) diff --git a/source/isaaclab/isaaclab/ui/xr_widgets/scene_visualization.py b/source/isaaclab/isaaclab/ui/xr_widgets/scene_visualization.py index 2cac77b859b..f88fc4de374 100644 --- a/source/isaaclab/isaaclab/ui/xr_widgets/scene_visualization.py +++ b/source/isaaclab/isaaclab/ui/xr_widgets/scene_visualization.py @@ -7,6 +7,7 @@ import contextlib import inspect +import logging import numpy as np import threading import time @@ -15,12 +16,14 @@ from enum import Enum from typing import Any, Union -import omni.log from pxr import Gf from isaaclab.sim import SimulationContext from isaaclab.ui.xr_widgets import show_instruction +# import logger +logger = logging.getLogger(__name__) + class TriggerType(Enum): """Enumeration of trigger types for visualization callbacks. @@ -432,7 +435,7 @@ def _validate_callback_signature(self, trigger: TriggerType, callback: Callable) raise # If we can't inspect the signature (e.g., built-in functions), # just log a warning and proceed - omni.log.warn(f"Could not validate callback signature for {trigger.name}: {e}") + logger.warning(f"Could not validate callback signature for {trigger.name}: {e}") class XRVisualization: @@ -600,7 +603,7 @@ def assign_manager(cls, manager: type[VisualizationManager]) -> None: manager: Type of the visualization manager to assign """ if cls._instance is not None: - omni.log.error( + logger.error( f"Visualization system already initialized to {type(cls._instance._visualization_manager).__name__}," f" cannot assign manager {manager.__name__}" ) diff --git a/source/isaaclab/isaaclab/utils/assets.py b/source/isaaclab/isaaclab/utils/assets.py index ef61e9f89af..353767c0310 100644 --- a/source/isaaclab/isaaclab/utils/assets.py +++ b/source/isaaclab/isaaclab/utils/assets.py @@ -15,6 +15,7 @@ import asyncio import io +import logging import os import tempfile import time @@ -23,6 +24,9 @@ import carb import omni.client +# import logger +logger = logging.getLogger(__name__) + NUCLEUS_ASSET_ROOT_DIR = carb.settings.get_settings().get("/persistent/isaac/asset_root/cloud") """Path to the root directory on the Nucleus Server.""" @@ -168,9 +172,9 @@ def check_usd_path_with_timeout(usd_path: str, timeout: float = 300, log_interva if now >= next_log_time: elapsed = int(now - start_time) if first_log: - omni.log.warn(f"Checking server availability for USD path: {usd_path} (timeout: {timeout}s)") + logger.warning(f"Checking server availability for USD path: {usd_path} (timeout: {timeout}s)") first_log = False - omni.log.warn(f"Waiting for server response... ({elapsed}s elapsed)") + logger.warning(f"Waiting for server response... ({elapsed}s elapsed)") next_log_time += log_interval loop.run_until_complete(asyncio.sleep(0.1)) # Yield to allow async work @@ -199,8 +203,8 @@ async def _is_usd_path_available(usd_path: str, timeout: float) -> bool: result, _ = await asyncio.wait_for(omni.client.stat_async(usd_path), timeout=timeout) return result == omni.client.Result.OK except asyncio.TimeoutError: - omni.log.warn(f"Timed out after {timeout}s while checking for USD: {usd_path}") + logger.warning(f"Timed out after {timeout}s while checking for USD: {usd_path}") return False except Exception as ex: - omni.log.warn(f"Exception during USD file check: {type(ex).__name__}: {ex}") + logger.warning(f"Exception during USD file check: {type(ex).__name__}: {ex}") return False diff --git a/source/isaaclab/isaaclab/utils/math.py b/source/isaaclab/isaaclab/utils/math.py index f8ad612a916..9dfb59f413e 100644 --- a/source/isaaclab/isaaclab/utils/math.py +++ b/source/isaaclab/isaaclab/utils/math.py @@ -8,13 +8,15 @@ # needed to import for allowing type-hinting: torch.Tensor | np.ndarray from __future__ import annotations +import logging import math import numpy as np import torch import torch.nn.functional from typing import Literal -import omni.log +# import logger +logger = logging.getLogger(__name__) """ General @@ -694,7 +696,7 @@ def quat_rotate(q: torch.Tensor, v: torch.Tensor) -> torch.Tensor: The rotated vector in (x, y, z). Shape is (..., 3). """ # deprecation - omni.log.warn( + logger.warning( "The function 'quat_rotate' will be deprecated in favor of the faster method 'quat_apply'." " Please use 'quat_apply' instead...." ) @@ -714,7 +716,7 @@ def quat_rotate_inverse(q: torch.Tensor, v: torch.Tensor) -> torch.Tensor: Returns: The rotated vector in (x, y, z). Shape is (..., 3). """ - omni.log.warn( + logger.warning( "The function 'quat_rotate_inverse' will be deprecated in favor of the faster method 'quat_apply_inverse'." " Please use 'quat_apply_inverse' instead...." ) diff --git a/source/isaaclab/isaaclab/utils/sensors.py b/source/isaaclab/isaaclab/utils/sensors.py index 92d603fcd8a..09d065f0432 100644 --- a/source/isaaclab/isaaclab/utils/sensors.py +++ b/source/isaaclab/isaaclab/utils/sensors.py @@ -3,7 +3,10 @@ # # SPDX-License-Identifier: BSD-3-Clause -import omni +import logging + +# import logger +logger = logging.getLogger(__name__) def convert_camera_intrinsics_to_usd( @@ -33,11 +36,11 @@ def convert_camera_intrinsics_to_usd( # warn about non-square pixels if abs(f_x - f_y) > 1e-4: - omni.log.warn("Camera non square pixels are not supported by Omniverse. The average of f_x and f_y are used.") + logger.warning("Camera non square pixels are not supported by Omniverse. The average of f_x and f_y are used.") # warn about aperture offsets if abs((c_x - float(width) / 2) > 1e-4 or (c_y - float(height) / 2) > 1e-4): - omni.log.warn( + logger.warning( "Camera aperture offsets are not supported by Omniverse. c_x and c_y will be half of width and height" ) diff --git a/source/isaaclab/test/deps/isaacsim/check_floating_base_made_fixed.py b/source/isaaclab/test/deps/isaacsim/check_floating_base_made_fixed.py index dbe12e8265f..8d3535c1b7c 100644 --- a/source/isaaclab/test/deps/isaacsim/check_floating_base_made_fixed.py +++ b/source/isaaclab/test/deps/isaacsim/check_floating_base_made_fixed.py @@ -30,13 +30,13 @@ """Rest everything follows.""" +import logging import torch import isaacsim.core.utils.nucleus as nucleus_utils import isaacsim.core.utils.prims as prim_utils import isaacsim.core.utils.stage as stage_utils import omni.kit.commands -import omni.log import omni.physx from isaacsim.core.api.world import World from isaacsim.core.prims import Articulation @@ -44,13 +44,16 @@ from isaacsim.core.utils.viewports import set_camera_view from pxr import PhysxSchema, UsdPhysics +# import logger +logger = logging.getLogger(__name__) + # check nucleus connection if nucleus_utils.get_assets_root_path() is None: msg = ( "Unable to perform Nucleus login on Omniverse. Assets root path is not set.\n" "\tPlease check: https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/overview.html#omniverse-nucleus" ) - omni.log.error(msg) + logger.error(msg) raise RuntimeError(msg) diff --git a/source/isaaclab/test/deps/isaacsim/check_legged_robot_clone.py b/source/isaaclab/test/deps/isaacsim/check_legged_robot_clone.py index c26f627a220..3231001efcc 100644 --- a/source/isaaclab/test/deps/isaacsim/check_legged_robot_clone.py +++ b/source/isaaclab/test/deps/isaacsim/check_legged_robot_clone.py @@ -40,11 +40,10 @@ """Rest everything follows.""" +import logging import os import torch -import omni.log - try: import isaacsim.storage.native as nucleus_utils except ModuleNotFoundError: @@ -57,13 +56,16 @@ from isaacsim.core.utils.carb import set_carb_setting from isaacsim.core.utils.viewports import set_camera_view +# import logger +logger = logging.getLogger(__name__) + # check nucleus connection if nucleus_utils.get_assets_root_path() is None: msg = ( "Unable to perform Nucleus login on Omniverse. Assets root path is not set.\n" "\tPlease check: https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/overview.html#omniverse-nucleus" ) - omni.log.error(msg) + logger.error(msg) raise RuntimeError(msg) diff --git a/source/isaaclab/test/deps/isaacsim/check_ref_count.py b/source/isaaclab/test/deps/isaacsim/check_ref_count.py index 2683bd3e989..a3d13331942 100644 --- a/source/isaaclab/test/deps/isaacsim/check_ref_count.py +++ b/source/isaaclab/test/deps/isaacsim/check_ref_count.py @@ -35,10 +35,9 @@ import ctypes import gc +import logging import torch # noqa: F401 -import omni.log - try: import isaacsim.storage.native as nucleus_utils except ModuleNotFoundError: @@ -49,13 +48,16 @@ from isaacsim.core.prims import Articulation from isaacsim.core.utils.carb import set_carb_setting +# import logger +logger = logging.getLogger(__name__) + # check nucleus connection if nucleus_utils.get_assets_root_path() is None: msg = ( "Unable to perform Nucleus login on Omniverse. Assets root path is not set.\n" "\tPlease check: https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/overview.html#omniverse-nucleus" ) - omni.log.error(msg) + logger.error(msg) raise RuntimeError(msg)