diff --git a/docs/source/overview/environments.rst b/docs/source/overview/environments.rst index fd374ea877..f88c121016 100644 --- a/docs/source/overview/environments.rst +++ b/docs/source/overview/environments.rst @@ -53,8 +53,12 @@ Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-sty | | | | | | |cartpole-direct-link| | | +------------------+-----------------------------+-------------------------------------------------------------------------+ - | |cartpole| | |cartpole-camera-rgb-link| | Move the cart to keep the pole upwards in the classic cartpole control | - | | | using perceptive inputs | + | |cartpole| | |manager-camera-rgb-link| | Move the cart to keep the pole upwards in the classic cartpole control | + | | | and perceptive inputs | + | | |manager-camera-dpt-link| | | + | | | | + | | |cartpole-camera-rgb-link| | | + | | | | | | |cartpole-camera-dpt-link| | | +------------------+-----------------------------+-------------------------------------------------------------------------+ @@ -68,11 +72,14 @@ Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-sty .. |humanoid-direct-link| replace:: `Isaac-Humanoid-Direct-v0 `__ .. |ant-direct-link| replace:: `Isaac-Ant-Direct-v0 `__ +.. |manager-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-v0 `__ +.. |manager-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-v0 `__ .. |cartpole-direct-link| replace:: `Isaac-Cartpole-Direct-v0 `__ +.. |manager-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-v0 `__ +.. |manager-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-v0 `__ .. |cartpole-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-Camera-Direct-v0 `__ .. |cartpole-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-Camera-Direct-v0 `__ - Manipulation ~~~~~~~~~~~~ diff --git a/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst b/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst index 7d81007d9a..05d6084ef1 100644 --- a/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst +++ b/source/extensions/omni.isaac.lab/docs/CHANGELOG.rst @@ -1,6 +1,13 @@ Changelog --------- +0.22.15 (2024-09-20) +~~~~~~~~~~~~~~~~~~~~ + +Added +^^^^^ + +* Added :meth:`grab_images` to be able to use images for an observation term in manager based environments 0.24.14 (2024-09-20) ~~~~~~~~~~~~~~~~~~~~ @@ -9,10 +16,9 @@ Added ^^^^^ * Added :meth:`convert_perspective_depth_to_orthogonal_depth`. :meth:`unproject_depth` assumes -that the input depth image is orthogonal. The new :meth:`convert_perspective_depth_to_orthogonal_depth` -can be used to convert a perspective depth image into an orthogonal depth image, so that the point cloud -can be unprojected correctly with :meth:`unproject_depth`. - + that the input depth image is orthogonal. The new :meth:`convert_perspective_depth_to_orthogonal_depth` + can be used to convert a perspective depth image into an orthogonal depth image, so that the point cloud + can be unprojected correctly with :meth:`unproject_depth`. 0.24.13 (2024-09-08) ~~~~~~~~~~~~~~~~~~~~ diff --git a/source/extensions/omni.isaac.lab/omni/isaac/lab/envs/mdp/observations.py b/source/extensions/omni.isaac.lab/omni/isaac/lab/envs/mdp/observations.py index d59299183f..c5b51fc6ae 100644 --- a/source/extensions/omni.isaac.lab/omni/isaac/lab/envs/mdp/observations.py +++ b/source/extensions/omni.isaac.lab/omni/isaac/lab/envs/mdp/observations.py @@ -17,7 +17,7 @@ import omni.isaac.lab.utils.math as math_utils from omni.isaac.lab.assets import Articulation, RigidObject from omni.isaac.lab.managers import SceneEntityCfg -from omni.isaac.lab.sensors import RayCaster +from omni.isaac.lab.sensors import Camera, RayCaster, RayCasterCamera, TiledCamera if TYPE_CHECKING: from omni.isaac.lab.envs import ManagerBasedEnv, ManagerBasedRLEnv @@ -182,6 +182,41 @@ def body_incoming_wrench(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg) -> tor return link_incoming_forces.view(env.num_envs, -1) +def grab_images( + env: ManagerBasedEnv, + sensor_cfg: SceneEntityCfg = SceneEntityCfg("tiled_camera"), + data_type: str = "rgb", + convert_perspective_to_orthogonal: bool = False, + normalize: bool = True, +) -> torch.Tensor: + """Grab all of the latest images of a specific datatype produced by a specific camera. + + Args: + env: The environment the cameras are placed within. + sensor_cfg: The desired sensor to read from. Defaults to SceneEntityCfg("tiled_camera"). + data_type: The data type to pull from the desired camera. Defaults to "rgb". + convert_perspective_to_orthogonal: Whether to convert perspective + depth images to orthogonal depth images. Defaults to False. + normalize: Set to True to normalize images. Defaults to True. + + Returns: + The images produced at the last timestep + """ + sensor: TiledCamera | Camera | RayCasterCamera = env.scene.sensors[sensor_cfg.name] + images = sensor.data.output[data_type] + if (data_type == "distance_to_camera") and convert_perspective_to_orthogonal: + images = math_utils.convert_perspective_depth_to_orthogonal_depth(images, sensor.data.intrinsic_matrices) + + if normalize: + if data_type == "rgb": + images = images / 255 + mean_tensor = torch.mean(images, dim=(1, 2), keepdim=True) + images -= mean_tensor + elif "distance_to" in data_type or "depth" in data_type: + images[images == float("inf")] = 0 + return images.clone() + + """ Actions. """ diff --git a/source/extensions/omni.isaac.lab_tasks/docs/CHANGELOG.rst b/source/extensions/omni.isaac.lab_tasks/docs/CHANGELOG.rst index 5e224d9a9e..2614630bd7 100644 --- a/source/extensions/omni.isaac.lab_tasks/docs/CHANGELOG.rst +++ b/source/extensions/omni.isaac.lab_tasks/docs/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog --------- +0.10.6 (2024-09-25) +~~~~~~~~~~~~~~~~~~~ + +Added +^^^^^ +* Added ``Isaac-Cartpole-RGB-Camera-v0`` and ``Isaac-Cartpole-Depth-Camera-v0`` + manager based camera cartpole environments. + + 0.10.5 (2024-09-11) ~~~~~~~~~~~~~~~~~~~ diff --git a/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/__init__.py b/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/__init__.py index 573860da04..7a3070d775 100644 --- a/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/__init__.py +++ b/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/__init__.py @@ -10,6 +10,7 @@ import gymnasium as gym from . import agents +from .cartpole_camera_env_cfg import CartpoleDepthCameraEnvCfg, CartpoleRGBCameraEnvCfg from .cartpole_env_cfg import CartpoleEnvCfg ## @@ -28,3 +29,23 @@ "sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml", }, ) + +gym.register( + id="Isaac-Cartpole-RGB-Camera-v0", + entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": CartpoleRGBCameraEnvCfg, + "rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_camera_ppo_cfg.yaml", + }, +) + +gym.register( + id="Isaac-Cartpole-Depth-Camera-v0", + entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": CartpoleDepthCameraEnvCfg, + "rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_camera_ppo_cfg.yaml", + }, +) diff --git a/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/agents/rl_games_camera_ppo_cfg.yaml b/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/agents/rl_games_camera_ppo_cfg.yaml new file mode 100644 index 0000000000..7d1dcf7945 --- /dev/null +++ b/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/agents/rl_games_camera_ppo_cfg.yaml @@ -0,0 +1,95 @@ +params: + seed: 42 + + # environment wrapper clipping + env: + # added to the wrapper + clip_observations: 5.0 + # can make custom wrapper? + clip_actions: 1.0 + + algo: + name: a2c_continuous + + model: + name: continuous_a2c_logstd + + # doesn't have this fine grained control but made it close + network: + name: actor_critic + separate: False + space: + continuous: + mu_activation: None + sigma_activation: None + + mu_init: + name: default + sigma_init: + name: const_initializer + val: 0 + fixed_sigma: True + cnn: + type: conv2d + activation: relu + initializer: + name: default + regularizer: + name: None + convs: + - filters: 32 + kernel_size: 8 + strides: 4 + padding: 0 + - filters: 64 + kernel_size: 4 + strides: 2 + padding: 0 + - filters: 64 + kernel_size: 3 + strides: 1 + padding: 0 + + mlp: + units: [512] + activation: elu + initializer: + name: default + + load_checkpoint: False # flag which sets whether to load the checkpoint + load_path: '' # path to the checkpoint to load + + config: + name: cartpole_camera + env_name: rlgpu + device: 'cuda:0' + device_name: 'cuda:0' + multi_gpu: False + ppo: True + mixed_precision: False + normalize_input: False + normalize_value: True + num_actors: -1 # configured from the script (based on num_envs) + reward_shaper: + scale_value: 1.0 + normalize_advantage: True + gamma: 0.99 + tau : 0.95 + learning_rate: 1e-4 + lr_schedule: adaptive + kl_threshold: 0.008 + score_to_win: 20000 + max_epochs: 500 + save_best_after: 50 + save_frequency: 25 + grad_norm: 1.0 + entropy_coef: 0.0 + truncate_grads: True + e_clip: 0.2 + horizon_length: 64 + minibatch_size: 2048 + mini_epochs: 4 + critic_coef: 2 + clip_value: True + seq_length: 4 + bounds_loss_coef: 0.0001 diff --git a/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py b/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py new file mode 100644 index 0000000000..889e844843 --- /dev/null +++ b/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py @@ -0,0 +1,86 @@ +# Copyright (c) 2022-2024, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +import omni.isaac.lab.sim as sim_utils +from omni.isaac.lab.envs.mdp.observations import grab_images +from omni.isaac.lab.managers import ObservationGroupCfg as ObsGroup +from omni.isaac.lab.managers import ObservationTermCfg as ObsTerm +from omni.isaac.lab.managers import SceneEntityCfg +from omni.isaac.lab.sensors import TiledCameraCfg +from omni.isaac.lab.utils import configclass + +from omni.isaac.lab_tasks.manager_based.classic.cartpole.cartpole_env_cfg import CartpoleEnvCfg, CartpoleSceneCfg + +## +# Scene definition +## + + +@configclass +class CartpoleRGBCameraSceneCfg(CartpoleSceneCfg): + tiled_camera: TiledCameraCfg = TiledCameraCfg( + prim_path="{ENV_REGEX_NS}/Camera", + offset=TiledCameraCfg.OffsetCfg(pos=(-7.0, 0.0, 3.0), rot=(0.9945, 0.0, 0.1045, 0.0), convention="world"), + data_types=["rgb"], + spawn=sim_utils.PinholeCameraCfg( + focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 20.0) + ), + width=80, + height=80, + ) + + +@configclass +class CartpoleDepthCameraSceneCfg(CartpoleSceneCfg): + tiled_camera: TiledCameraCfg = TiledCameraCfg( + prim_path="{ENV_REGEX_NS}/Camera", + offset=TiledCameraCfg.OffsetCfg(pos=(-7.0, 0.0, 3.0), rot=(0.9945, 0.0, 0.1045, 0.0), convention="world"), + data_types=["distance_to_camera"], + spawn=sim_utils.PinholeCameraCfg( + focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 20.0) + ), + width=80, + height=80, + ) + + +@configclass +class RGBObservationsCfg: + """Observation specifications for the MDP.""" + + @configclass + class RGBCameraPolicyCfg(ObsGroup): + """Observations for policy group.""" + + image = ObsTerm(func=grab_images, params={"sensor_cfg": SceneEntityCfg("tiled_camera"), "data_type": "rgb"}) + + def __post_init__(self) -> None: + self.enable_corruption = False + self.concatenate_terms = True + + policy: ObsGroup = RGBCameraPolicyCfg() + + +@configclass +class DepthObservationsCfg: + @configclass + class DepthCameraPolicyCfg(RGBObservationsCfg.RGBCameraPolicyCfg): + image = ObsTerm( + func=grab_images, params={"sensor_cfg": SceneEntityCfg("tiled_camera"), "data_type": "distance_to_camera"} + ) + + policy: ObsGroup = DepthCameraPolicyCfg() + + +@configclass +class CartpoleRGBCameraEnvCfg(CartpoleEnvCfg): + scene: CartpoleSceneCfg = CartpoleRGBCameraSceneCfg(num_envs=1024, env_spacing=20) + observations = RGBObservationsCfg() + + +@configclass +class CartpoleDepthCameraEnvCfg(CartpoleEnvCfg): + scene: CartpoleSceneCfg = CartpoleDepthCameraSceneCfg(num_envs=1024, env_spacing=20) + observations = DepthObservationsCfg()