Unverified Commit 2804ff3a authored by glvov-bdai's avatar glvov-bdai Committed by GitHub

Create Manager Based Cartpole Vision Example Environments (#995)

# Description

Adds manager based cartpole vision example environments. 

Also uses the`convert_perspective_depth_to_orthogonal_depth `
functionality introduced in #976 , contains a duplicate copy of the
method and test for completeness of the PR. Will be synced with main to
remove this duplicate copy once #976 is merged into main, or #976 will
be synced with main if this PR is merged first

## Type of change

- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## Screenshots

![image](https://github.com/user-attachments/assets/4cce3923-b199-4469-b8d0-9d8d8abb3456)

## Checklist

- [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
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

## Testing

Training converged in both RGB and Depth at similar rates to the direct
environments

---------
Signed-off-by: 's avatargarylvov <67614381+garylvov@users.noreply.github.com>
Signed-off-by: 's avatarglvov-bdai <glvov@theaiinstitute.com>
Co-authored-by: 's avatargarylvov <gary.lvov@gmail.com>
Co-authored-by: 's avatargarylvov <67614381+garylvov@users.noreply.github.com>
Co-authored-by: 's avatarJames Smith <142246516+jsmith-bdai@users.noreply.github.com>
parent f8d80cb1
...@@ -53,8 +53,12 @@ Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-sty ...@@ -53,8 +53,12 @@ Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-sty
| | | | | | | |
| | |cartpole-direct-link| | | | | |cartpole-direct-link| | |
+------------------+-----------------------------+-------------------------------------------------------------------------+ +------------------+-----------------------------+-------------------------------------------------------------------------+
| |cartpole| | |cartpole-camera-rgb-link| | Move the cart to keep the pole upwards in the classic cartpole control | | |cartpole| | |manager-camera-rgb-link| | Move the cart to keep the pole upwards in the classic cartpole control |
| | | using perceptive inputs | | | | and perceptive inputs |
| | |manager-camera-dpt-link| | |
| | | |
| | |cartpole-camera-rgb-link| | |
| | | |
| | |cartpole-camera-dpt-link| | | | | |cartpole-camera-dpt-link| | |
+------------------+-----------------------------+-------------------------------------------------------------------------+ +------------------+-----------------------------+-------------------------------------------------------------------------+
...@@ -68,11 +72,14 @@ Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-sty ...@@ -68,11 +72,14 @@ Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-sty
.. |humanoid-direct-link| replace:: `Isaac-Humanoid-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/humanoid/humanoid_env.py>`__ .. |humanoid-direct-link| replace:: `Isaac-Humanoid-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/humanoid/humanoid_env.py>`__
.. |ant-direct-link| replace:: `Isaac-Ant-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/ant/ant_env.py>`__ .. |ant-direct-link| replace:: `Isaac-Ant-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/ant/ant_env.py>`__
.. |manager-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py>`__
.. |manager-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py>`__
.. |cartpole-direct-link| replace:: `Isaac-Cartpole-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/cartpole/cartpole_env.py>`__ .. |cartpole-direct-link| replace:: `Isaac-Cartpole-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/cartpole/cartpole_env.py>`__
.. |manager-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py>`__
.. |manager-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py>`__
.. |cartpole-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-Camera-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/cartpole/cartpole_camera_env.py>`__ .. |cartpole-camera-rgb-link| replace:: `Isaac-Cartpole-RGB-Camera-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/cartpole/cartpole_camera_env.py>`__
.. |cartpole-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-Camera-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/cartpole/cartpole_camera_env.py>`__ .. |cartpole-camera-dpt-link| replace:: `Isaac-Cartpole-Depth-Camera-Direct-v0 <https://github.com/isaac-sim/IsaacLab/blob/main/source/extensions/omni.isaac.lab_tasks/omni/isaac/lab_tasks/direct/cartpole/cartpole_camera_env.py>`__
Manipulation Manipulation
~~~~~~~~~~~~ ~~~~~~~~~~~~
......
Changelog 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) 0.24.14 (2024-09-20)
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
...@@ -9,10 +16,9 @@ Added ...@@ -9,10 +16,9 @@ Added
^^^^^ ^^^^^
* Added :meth:`convert_perspective_depth_to_orthogonal_depth`. :meth:`unproject_depth` assumes * 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` 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 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`. can be unprojected correctly with :meth:`unproject_depth`.
0.24.13 (2024-09-08) 0.24.13 (2024-09-08)
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
......
...@@ -17,7 +17,7 @@ from typing import TYPE_CHECKING ...@@ -17,7 +17,7 @@ from typing import TYPE_CHECKING
import omni.isaac.lab.utils.math as math_utils import omni.isaac.lab.utils.math as math_utils
from omni.isaac.lab.assets import Articulation, RigidObject from omni.isaac.lab.assets import Articulation, RigidObject
from omni.isaac.lab.managers import SceneEntityCfg 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: if TYPE_CHECKING:
from omni.isaac.lab.envs import ManagerBasedEnv, ManagerBasedRLEnv from omni.isaac.lab.envs import ManagerBasedEnv, ManagerBasedRLEnv
...@@ -182,6 +182,41 @@ def body_incoming_wrench(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg) -> tor ...@@ -182,6 +182,41 @@ def body_incoming_wrench(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg) -> tor
return link_incoming_forces.view(env.num_envs, -1) 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. Actions.
""" """
......
Changelog 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) 0.10.5 (2024-09-11)
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
......
...@@ -10,6 +10,7 @@ Cartpole balancing environment. ...@@ -10,6 +10,7 @@ Cartpole balancing environment.
import gymnasium as gym import gymnasium as gym
from . import agents from . import agents
from .cartpole_camera_env_cfg import CartpoleDepthCameraEnvCfg, CartpoleRGBCameraEnvCfg
from .cartpole_env_cfg import CartpoleEnvCfg from .cartpole_env_cfg import CartpoleEnvCfg
## ##
...@@ -28,3 +29,23 @@ gym.register( ...@@ -28,3 +29,23 @@ gym.register(
"sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml", "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",
},
)
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
# 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()
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