Unverified Commit c42fc738 authored by Pascal Roth's avatar Pascal Roth Committed by GitHub

Changes from `omni.log` to python logging (#3912)

# Description

Changes from `omni.log` to an own python logger for IsaacLab. The
logging information are formatted as follows:

```
14:09:39 [manager_based_env.py] WARNING: The render interval (1) is smaller than the decimation (2). Multiple render calls will happen for each environment step. If this is not intended, set the render interval to be equal to the decimation.
```

All logs are saved to a temp file. Carb initialized a logging handler:

```
<_CarbLogHandler <stderr> (NOTSET)>
```

which is removed when configuring our handler.

## Type of change

- Bug fix (non-breaking change which fixes an issue)


## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [ ] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------
Signed-off-by: 's avatarooctipus <zhengyuz@nvidia.com>
Co-authored-by: 's avatarooctipus <zhengyuz@nvidia.com>
parent 92238362
......@@ -56,10 +56,9 @@ simulation_app = app_launcher.app
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 @@ if args_cli.enable_pinocchio:
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 main() -> 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 main() -> 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 main() -> 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 main() -> 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
......
......@@ -64,23 +64,26 @@ simulation_app = app_launcher.app
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."
)
......
......@@ -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:
......
......@@ -60,12 +60,12 @@ simulation_app = app_launcher.app
"""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 @@ from isaaclab_rl.rl_games import MultiObserver, PbtAlgoObserver, RlGamesGpuEnv,
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."
)
......
......@@ -73,11 +73,11 @@ if version.parse(installed_version) < version.parse(RSL_RL_VERSION):
"""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 @@ import isaaclab_tasks # noqa: F401
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."
)
......
......@@ -73,12 +73,12 @@ signal.signal(signal.SIGINT, cleanup_pbar)
"""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 @@ from isaaclab_rl.sb3 import Sb3VecEnvWrapper, process_sb3_cfg
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."
)
......
......@@ -73,11 +73,11 @@ simulation_app = app_launcher.app
"""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 @@ from isaaclab_rl.skrl import SkrlVecEnvWrapper
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."
)
......
......@@ -90,12 +90,11 @@ simulation_app = app_launcher.app
# 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 @@ from isaaclab.managers import DatasetExportMode
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
......
......@@ -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 @@ if TYPE_CHECKING:
RemotizedPDActuatorCfg,
)
# import logger
logger = logging.getLogger(__name__)
"""
Implicit Actuator Models.
......@@ -57,7 +58,7 @@ class ImplicitActuator(ActuatorBase):
# 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 <ImplicitActuatorCfg> 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 @@ class ImplicitActuator(ActuatorBase):
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 <ImplicitActuatorCfg> 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"
......
......@@ -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 @@ class ArticulationData:
@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 @@ class ArticulationData:
@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 @@ class ArticulationData:
@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 @@ class ArticulationData:
@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 @@ class ArticulationData:
@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 @@ class ArticulationData:
@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 @@ class ArticulationData:
@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."
)
......
......@@ -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 @@ from .deformable_object_data import DeformableObjectData
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 @@ class DeformableObject(AssetBase):
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 @@ class DeformableObject(AssetBase):
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)
......
......@@ -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 @@ from .rigid_object_data import RigidObjectData
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 @@ class RigidObject(AssetBase):
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 @@ class RigidObject(AssetBase):
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)
......
......@@ -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 @@ from .rigid_object_collection_data import RigidObjectCollectionData
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 @@ class RigidObjectCollection(AssetBase):
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 @@ class RigidObjectCollection(AssetBase):
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)
......
......@@ -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 @@ if TYPE_CHECKING:
from .surface_gripper_cfg import SurfaceGripperCfg
# import logger
logger = logging.getLogger(__name__)
class SurfaceGripper(AssetBase):
"""A surface gripper actuator class.
......@@ -315,8 +318,8 @@ class SurfaceGripper(AssetBase):
)
# 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()
......
......@@ -8,6 +8,7 @@
This module provides utility functions to help with controller implementations.
"""
import logging
import os
import re
......@@ -15,10 +16,11 @@ from isaacsim.core.utils.extensions import enable_extension
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'<joint name="{joint}" type="revolute">'
new_str = f'<joint name="{joint}" type="fixed">'
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'<joint name="{joint}" type="revolute">'
new_str = f'<joint name="{joint}" type="fixed">'
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:
......
......@@ -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 @@ with contextlib.suppress(ModuleNotFoundError):
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 @@ class ManusViveIntegration:
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 @@ class ManusViveIntegration:
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 @@ class ManusViveIntegration:
)
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
......
......@@ -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 @@ class GR1TR2DexRetargeting:
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 @@ class GR1TR2DexRetargeting:
# 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.
......
......@@ -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 @@ class UnitreeG1DexRetargeting:
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 @@ class UnitreeG1DexRetargeting:
# 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.
......
......@@ -10,11 +10,13 @@ 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__)
# 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 @@ class G1TriHandDexRetargeting:
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 @@ class G1TriHandDexRetargeting:
# 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.
......
......@@ -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
......@@ -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 @@ with contextlib.suppress(ModuleNotFoundError):
# 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
......@@ -8,6 +8,7 @@ from __future__ import annotations
import builtins
import gymnasium as gym
import inspect
import logging
import math
import numpy as np
import torch
......@@ -19,7 +20,6 @@ from typing import Any, ClassVar
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 .direct_marl_env_cfg import DirectMARLEnvCfg
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 @@ class DirectMARLEnv(gym.Env):
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 @@ class DirectMARLEnv(gym.Env):
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 @@ class DirectMARLEnv(gym.Env):
# 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
......
......@@ -8,6 +8,7 @@ from __future__ import annotations
import builtins
import gymnasium as gym
import inspect
import logging
import math
import numpy as np
import torch
......@@ -20,7 +21,6 @@ from typing import Any, ClassVar
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
......@@ -37,6 +37,9 @@ from .direct_rl_env_cfg import DirectRLEnvCfg
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.
......@@ -96,7 +99,7 @@ class DirectRLEnv(gym.Env):
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:
......@@ -122,7 +125,7 @@ class DirectRLEnv(gym.Env):
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"):
......@@ -568,17 +571,17 @@ class DirectRLEnv(gym.Env):
"""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
......
......@@ -4,13 +4,13 @@
# SPDX-License-Identifier: BSD-3-Clause
import builtins
import logging
import torch
import warnings
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
......@@ -27,6 +27,9 @@ from .manager_based_env_cfg import ManagerBasedEnvCfg
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.
......@@ -90,7 +93,7 @@ class ManagerBasedEnv:
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:
......@@ -122,7 +125,7 @@ class ManagerBasedEnv:
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
......
......@@ -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 @@ if TYPE_CHECKING:
from . import actions_cfg
# import logger
logger = logging.getLogger(__name__)
class BinaryJointAction(ActionTerm):
"""Base class for binary joint actions.
......@@ -54,7 +56,7 @@ class BinaryJointAction(ActionTerm):
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}]"
)
......
......@@ -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 @@ if TYPE_CHECKING:
from . import actions_cfg
# import logger
logger = logging.getLogger(__name__)
class JointAction(ActionTerm):
r"""Base class for joint actions.
......@@ -64,7 +66,7 @@ class JointAction(ActionTerm):
)
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}]"
)
......
......@@ -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 @@ if TYPE_CHECKING:
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 @@ class JointPositionToLimitsAction(ActionTerm):
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}]"
)
......
......@@ -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 @@ if TYPE_CHECKING:
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 @@ class NonHolonomicAction(ActionTerm):
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}]"
)
......
......@@ -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 @@ if TYPE_CHECKING:
from . import rmpflow_actions_cfg
# import logger
logger = logging.getLogger(__name__)
class RMPFlowAction(ActionTerm):
......@@ -62,11 +64,11 @@ class RMPFlowAction(ActionTerm):
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
......
......@@ -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 @@ if TYPE_CHECKING:
from . import actions_cfg
# import logger
logger = logging.getLogger(__name__)
class SurfaceGripperBinaryAction(ActionTerm):
"""Surface gripper binary action.
......@@ -48,7 +50,7 @@ class SurfaceGripperBinaryAction(ActionTerm):
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}"
)
......
......@@ -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 @@ if TYPE_CHECKING:
from . import actions_cfg
# import logger
logger = logging.getLogger(__name__)
class DifferentialInverseKinematicsAction(ActionTerm):
r"""Inverse Kinematics action term.
......@@ -78,11 +81,11 @@ class DifferentialInverseKinematicsAction(ActionTerm):
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 @@ class OperationalSpaceControllerAction(ActionTerm):
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}]"
)
......
......@@ -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 @@ if TYPE_CHECKING:
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 @@ class UniformVelocityCommand(CommandTerm):
" 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."
)
......
......@@ -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 @@ class EventManager(ManagerBase):
"""
# 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 @@ class EventManager(ManagerBase):
)
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 @@ class EventManager(ManagerBase):
# 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
......
......@@ -7,12 +7,12 @@ from __future__ import annotations
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 @@ from .scene_entity_cfg import SceneEntityCfg
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 @@ class ManagerBase(ABC):
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)
......@@ -19,13 +19,13 @@ The marker prototypes can be configured with the :class:`VisualizationMarkersCfg
# 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.sim.utils import attach_stage_to_usd_context
from isaaclab.utils.configclass import configclass
from isaaclab.utils.math import convert_quat
# import logger
logger = logging.getLogger(__name__)
@configclass
class VisualizationMarkersCfg:
......
......@@ -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 isaaclab.terrains import TerrainImporter, TerrainImporterCfg
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 @@ class InteractiveScene:
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 @@ class InteractiveScene:
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 @@ class InteractiveScene:
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.")
......
......@@ -6,6 +6,7 @@
from __future__ import annotations
import json
import logging
import numpy as np
import re
import torch
......@@ -36,6 +37,9 @@ from .camera_data import CameraData
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 @@ class Camera(SensorBase):
# 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"
......
......@@ -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 @@ from .frame_transformer_data import FrameTransformerData
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 @@ class FrameTransformer(SensorBase):
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 @@ class FrameTransformer(SensorBase):
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}"
)
......
......@@ -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 @@ from .ray_caster_data import RayCasterData
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 @@ class RayCaster(SensorBase):
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 @@ class RayCaster(SensorBase):
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 @@ class RayCaster(SensorBase):
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
......
......@@ -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.converters.mesh_converter_cfg import MeshConverterCfg
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 @@ class MeshConverter(AssetConverterBase):
# 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."
)
......
......@@ -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 ..utils import (
)
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)
......
......@@ -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."""
......@@ -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 @@ from typing import Any
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 isaaclab.sim.utils import create_new_stage_in_memory, use_stage
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 @@ class SimulationContext(_SimulationContext):
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 @@ class SimulationContext(_SimulationContext):
# 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 @@ class SimulationContext(_SimulationContext):
"""
# 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 @@ class SimulationContext(_SimulationContext):
# 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 @@ class SimulationContext(_SimulationContext):
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():
......
......@@ -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 @@ from isaaclab.utils.assets import check_usd_path_with_timeout
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:
......
......@@ -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 @@ from isaaclab.utils.assets import NVIDIA_NUCLEUS_DIR
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:
......
......@@ -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 @@ from isaaclab.utils import to_camel_case
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 = [
......
......@@ -10,7 +10,9 @@ from __future__ import annotations
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 carb
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 @@ from . import schemas
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 apply_nested(func: Callable) -> Callable:
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 @@ def select_usd_variants(prim_path: str, variants: object | dict[str, str], stage
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
......@@ -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 @@ if TYPE_CHECKING:
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 @@ class TerrainGenerator:
# 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 @@ class TerrainGenerator:
"""
# 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
......
......@@ -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 @@ from .utils import create_prim_from_mesh
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.
......@@ -211,7 +213,7 @@ class TerrainImporter:
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)"
)
......@@ -376,7 +378,7 @@ class TerrainImporter:
.. 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."
)
......@@ -389,7 +391,7 @@ class TerrainImporter:
.. 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."
)
......
......@@ -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 @@ from typing import TYPE_CHECKING, Optional
import carb
import omni
import omni.log
with suppress(ImportError):
# isaacsim.gui is not available when running in headless mode.
......@@ -22,6 +22,9 @@ if TYPE_CHECKING:
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 @@ class ImagePlot(UIWidgetWrapper):
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")
......
......@@ -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 @@ from .ui_visualizer_base import UiVisualizerBase
if TYPE_CHECKING:
import omni.ui
# import logger
logger = logging.getLogger(__name__)
@configclass
class ManagerLiveVisualizerCfg:
......@@ -79,7 +82,7 @@ class ManagerLiveVisualizer(UiVisualizerBase):
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 @@ class ManagerLiveVisualizer(UiVisualizerBase):
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 @@ class ManagerLiveVisualizer(UiVisualizerBase):
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 @@ class ManagerLiveVisualizer(UiVisualizerBase):
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."
)
......
......@@ -7,6 +7,7 @@ from __future__ import annotations
import contextlib
import inspect
import logging
import numpy as np
import threading
import time
......@@ -15,12 +16,14 @@ from collections.abc import Callable
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 @@ class VisualizationManager:
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 @@ class XRVisualization:
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__}"
)
......
......@@ -15,6 +15,7 @@ For more information, please check information on `Omniverse Nucleus`_.
import asyncio
import io
import logging
import os
import tempfile
import time
......@@ -23,6 +24,9 @@ from typing import Literal
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
......@@ -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...."
)
......
......@@ -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"
)
......
......@@ -30,13 +30,13 @@ simulation_app = SimulationApp({"headless": args_cli.headless})
"""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.carb import set_carb_setting
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)
......
......@@ -40,11 +40,10 @@ simulation_app = SimulationApp({"headless": args_cli.headless})
"""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.prims import Articulation
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)
......
......@@ -35,10 +35,9 @@ simulation_app = SimulationApp({"headless": True})
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.api.simulation_context import SimulationContext
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment