Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add digit locomotion examples #1892

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
52 changes: 52 additions & 0 deletions source/isaaclab_assets/isaaclab_assets/robots/agility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

import pathlib
from typing import Literal

import isaaclab.sim as sim_utils
from isaaclab.actuators import IdealPDActuatorCfg, ImplicitActuatorCfg
from isaaclab.assets.articulation import ArticulationCfg
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR

FILE_DIR = pathlib.Path(__file__).parent


def get_digit_articulation_cfg(
fixed_base: bool = False,
actuator_type: Literal["explicit", "implicit"] = "implicit",
) -> ArticulationCfg:
"""
Get an articulation config for a Agility Digit robot.
The robot can be made hanging in the air with the parameter `fixed_base`.
"""
if actuator_type == "implicit":
ActuatorCfg = ImplicitActuatorCfg
elif actuator_type == "explicit":
ActuatorCfg = IdealPDActuatorCfg

articulation_cfg = ArticulationCfg(
spawn=sim_utils.UsdFileCfg(
usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Agility/Digit/digit_v4.usd",
activate_contact_sensors=True,
),
init_state=ArticulationCfg.InitialStateCfg(
pos=(0.0, 0.0, 1.05),
),
soft_joint_pos_limit_factor=0.9,
actuators={
"all": ActuatorCfg(
joint_names_expr=".*",
stiffness=None,
damping=None,
),
},
)

if fixed_base:
articulation_cfg.init_state.pos = (0.0, 0.0, 2.0)
articulation_cfg.spawn.articulation_props.fix_root_link = True

return articulation_cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

import gymnasium as gym

from . import agents

##
# Register Gym environments.
##
gym.register(
id="Isaac-Velocity-Flat-Digit-v0",
entry_point="isaaclab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.flat_env_cfg:DigitFlatEnvCfg",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DigitFlatPPORunnerCfg",
},
)


gym.register(
id="Isaac-Velocity-Flat-Digit-Play-v0",
entry_point="isaaclab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.flat_env_cfg:DigitFlatEnvCfg_PLAY",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DigitFlatPPORunnerCfg",
},
)


gym.register(
id="Isaac-Velocity-Rough-Digit-v0",
entry_point="isaaclab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.rough_env_cfg:DigitRoughEnvCfg",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DigitRoughPPORunnerCfg",
},
)


gym.register(
id="Isaac-Velocity-Rough-Digit-Play-v0",
entry_point="isaaclab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.rough_env_cfg:DigitRoughEnvCfg_PLAY",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DigitRoughPPORunnerCfg",
},
)


gym.register(
id="Isaac-Velocity-LocoManip-Digit-v0",
entry_point="isaaclab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.loco_manip_env_cfg:DigitLocoManipEnvCfg",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DigitLocoManipPPORunnerCfg",
},
)


gym.register(
id="Isaac-Velocity-LocoManip-Digit-Play-v0",
entry_point="isaaclab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.loco_manip_env_cfg:DigitLocoManipEnvCfg_PLAY",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DigitLocoManipPPORunnerCfg",
},
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause



from isaaclab_rl.rsl_rl import RslRlOnPolicyRunnerCfg, RslRlPpoActorCriticCfg, RslRlPpoAlgorithmCfg

from isaaclab.utils import configclass


@configclass
class DigitRoughPPORunnerCfg(RslRlOnPolicyRunnerCfg):
num_steps_per_env = 24
max_iterations = 3000
save_interval = 50
experiment_name = "digit_rough"
empirical_normalization = False
policy = RslRlPpoActorCriticCfg(
init_noise_std=1.0,
actor_hidden_dims=[512, 256, 128],
critic_hidden_dims=[512, 256, 128],
activation="elu",
)
algorithm = RslRlPpoAlgorithmCfg(
value_loss_coef=1.0,
use_clipped_value_loss=True,
clip_param=0.2,
entropy_coef=0.01,
num_learning_epochs=5,
num_mini_batches=4,
learning_rate=1.0e-3,
schedule="adaptive",
gamma=0.99,
lam=0.95,
desired_kl=0.01,
max_grad_norm=1.0,
)


@configclass
class DigitFlatPPORunnerCfg(DigitRoughPPORunnerCfg):
def __post_init__(self):
super().__post_init__()

self.max_iterations = 2000
self.experiment_name = "digit_flat"

self.policy.actor_hidden_dims = [128, 128, 128]
self.policy.critic_hidden_dims = [128, 128, 128]


@configclass
class DigitLocoManipPPORunnerCfg(DigitRoughPPORunnerCfg):
def __post_init__(self):
super().__post_init__()

self.max_iterations = 2000
self.experiment_name = "digit_loco_manip"

self.policy.actor_hidden_dims = [256, 128, 128]
self.policy.critic_hidden_dims = [256, 128, 128]
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

from isaaclab.utils import configclass

from .rough_env_cfg import DigitRoughEnvCfg


@configclass
class DigitFlatEnvCfg(DigitRoughEnvCfg):
def __post_init__(self):
super().__post_init__()

# Change terrain to flat.
self.scene.terrain.terrain_type = "plane"
self.scene.terrain.terrain_generator = None
# Remove height scanner.
self.scene.height_scanner = None
self.observations.policy.height_scan = None
# Remove terrain curriculum.
self.curriculum.terrain_levels = None


class DigitFlatEnvCfg_PLAY(DigitFlatEnvCfg):

def __post_init__(self) -> None:
super().__post_init__()

# Make a smaller scene for play.
self.scene.num_envs = 50
self.scene.env_spacing = 2.5
# Disable randomization for play.
self.observations.policy.enable_corruption = False
# Remove random pushing.
self.randomization.base_external_force_torque = None
self.randomization.push_robot = None
self.randomization.reset_base.params = {
"pose_range": {
"x": (-0.0, 0.0),
"y": (-0.0, 0.0),
"yaw": (-3.1415 * 0, 3.1415 * 0),
},
"velocity_range": {
"x": (-0.0, 0.0),
"y": (-0.0, 0.0),
"z": (-0.0, 0.0),
"roll": (-0.0, 0.0),
"pitch": (-0.0, 0.0),
"yaw": (-0.0, 0.0),
},
}

self.commands.base_velocity.ranges.heading = (0.0, 0.0)
Loading
Loading