From a34ceab59a20af3d955411ef5c4b45dfdc708dd9 Mon Sep 17 00:00:00 2001 From: Omid Heidari Date: Mon, 5 May 2025 18:52:24 -0500 Subject: [PATCH 1/3] added valkyrie added robot and task use env variable for valkyrie path pre-commit checks docs added persona to contributors --- CONTRIBUTORS.md | 1 + .../tasks/locomotion/valkyrie_flat.jpg | Bin 0 -> 84935 bytes docs/source/overview/environments.rst | 5 + .../isaaclab_assets/robots/__init__.py | 1 + .../isaaclab_assets/robots/valkyrie.py | 120 ++++++++++++ .../velocity/config/g1/rough_env_cfg.py | 2 +- .../velocity/config/valkyrie/__init__.py | 59 ++++++ .../config/valkyrie/agents/__init__.py | 4 + .../config/valkyrie/agents/rsl_rl_ppo_cfg.py | 51 ++++++ .../valkyrie/agents/skrl_flat_ppo_cfg.yaml | 82 +++++++++ .../valkyrie/agents/skrl_rough_ppo_cfg.yaml | 80 ++++++++ .../velocity/config/valkyrie/flat_env_cfg.py | 87 +++++++++ .../velocity/config/valkyrie/rough_env_cfg.py | 172 ++++++++++++++++++ 13 files changed, 663 insertions(+), 1 deletion(-) create mode 100644 docs/source/_static/tasks/locomotion/valkyrie_flat.jpg create mode 100644 source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/__init__.py create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_flat_ppo_cfg.yaml create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/flat_env_cfg.py create mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/rough_env_cfg.py diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ec5d3e73449..31f88bedfd1 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -16,6 +16,7 @@ Guidelines for modifications: * ETH Zurich * NVIDIA Corporation & Affiliates * University of Toronto +* Persona AI, Inc. --- diff --git a/docs/source/_static/tasks/locomotion/valkyrie_flat.jpg b/docs/source/_static/tasks/locomotion/valkyrie_flat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..17df922d27d8ecf22aad4325de8c7ba1e043b9fd GIT binary patch literal 84935 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
    Hveg5L2JS8OY5(G(c!lVkxVed5D_f0I07TS&K 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 literal 0 HcmV?d00001 diff --git a/docs/source/overview/environments.rst b/docs/source/overview/environments.rst index 3a855fbb466..63c6e06e73b 100644 --- a/docs/source/overview/environments.rst +++ b/docs/source/overview/environments.rst @@ -242,6 +242,8 @@ Environments based on legged locomotion tasks. +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+ | |velocity-rough-g1| | |velocity-rough-g1-link| | Track a velocity command on rough terrain with the Unitree G1 robot | +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+ + | |velocity-flat-valkyrie| | |velocity-flat-valkyrie-link| | Track a velocity command on flat terrain with the Valkyrie robot | + +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+ .. |velocity-flat-anymal-b-link| replace:: `Isaac-Velocity-Flat-Anymal-B-v0 `__ .. |velocity-rough-anymal-b-link| replace:: `Isaac-Velocity-Rough-Anymal-B-v0 `__ @@ -272,6 +274,8 @@ Environments based on legged locomotion tasks. .. |velocity-flat-g1-link| replace:: `Isaac-Velocity-Flat-G1-v0 `__ .. |velocity-rough-g1-link| replace:: `Isaac-Velocity-Rough-G1-v0 `__ +.. |velocity-flat-valkyrie-link| replace:: `Isaac-Velocity-Flat-Valkyrie-v0 `__ + .. |velocity-flat-anymal-b| image:: ../_static/tasks/locomotion/anymal_b_flat.jpg .. |velocity-rough-anymal-b| image:: ../_static/tasks/locomotion/anymal_b_rough.jpg @@ -290,6 +294,7 @@ Environments based on legged locomotion tasks. .. |velocity-rough-h1| image:: ../_static/tasks/locomotion/h1_rough.jpg .. |velocity-flat-g1| image:: ../_static/tasks/locomotion/g1_flat.jpg .. |velocity-rough-g1| image:: ../_static/tasks/locomotion/g1_rough.jpg +.. |velocity-flat-valkyrie| image:: ../_static/tasks/locomotion/valkyrie_flat.jpg Navigation ~~~~~~~~~~ diff --git a/source/isaaclab_assets/isaaclab_assets/robots/__init__.py b/source/isaaclab_assets/isaaclab_assets/robots/__init__.py index c23cf8e3ce2..0337337337d 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/__init__.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/__init__.py @@ -24,3 +24,4 @@ from .spot import * from .unitree import * from .universal_robots import * +from .valkyrie import * diff --git a/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py b/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py new file mode 100644 index 00000000000..1474e3aeda7 --- /dev/null +++ b/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py @@ -0,0 +1,120 @@ +# Copyright (c) 2022-2025, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +""" +Configuration for the Valkyrie robot from IHMC Robotics. +""" + +import os + +import isaaclab.sim as sim_utils +from isaaclab.actuators import ImplicitActuatorCfg +from isaaclab.assets.articulation import ArticulationCfg + +# get valkyrie usd path +VAL_ASSET_DIR = os.getenv("VAL_ASSET_DIR") + "/valkyrie.usd" + +spawn_usd = sim_utils.UsdFileCfg( + usd_path=VAL_ASSET_DIR, + activate_contact_sensors=True, + rigid_props=sim_utils.RigidBodyPropertiesCfg( + disable_gravity=False, + retain_accelerations=False, + linear_damping=0.0, + angular_damping=0.0, + max_linear_velocity=1000.0, + max_angular_velocity=1000.0, + max_depenetration_velocity=1.0, + ), + articulation_props=sim_utils.ArticulationRootPropertiesCfg( + enabled_self_collisions=False, solver_position_iteration_count=8, solver_velocity_iteration_count=4 + ), +) + +VALKYRIE_CFG = ArticulationCfg( + spawn=spawn_usd, + init_state=ArticulationCfg.InitialStateCfg( + pos=(0.0, 0.0, 1.2), + joint_pos={ + ".*HipPitch": -0.20, + ".*KneePitch": 0.42, + ".*AnklePitch": -0.23, + "leftShoulderPitch": 0.27, + "rightShoulderPitch": 0.27, + "leftElbowPitch": -0.7, + "rightElbowPitch": 0.7, + "leftShoulderRoll": -1.2, + "rightShoulderRoll": 1.2, + }, + joint_vel={".*": 0.0}, + ), + soft_joint_pos_limit_factor=0.9, + actuators={ + "torso": ImplicitActuatorCfg( + effort_limit=2000, + joint_names_expr=["torso.*"], + stiffness={ + "torsoPitch": 150.0, + "torsoRoll": 150.0, + "torsoYaw": 150.0, + }, + damping={ + "torsoPitch": 5.0, + "torsoRoll": 5.0, + "torsoYaw": 5.0, + }, + armature=0.01, + ), + "legs": ImplicitActuatorCfg( + joint_names_expr=[ + ".*HipYaw", + ".*HipRoll", + ".*HipPitch", + ".*Knee.*", + ], + effort_limit=300, + velocity_limit=100.0, + stiffness={ + ".*HipYaw": 150.0, + ".*HipRoll": 150.0, + ".*HipPitch": 200.0, + ".*Knee.*": 200.0, + }, + damping={ + ".*HipYaw": 5.0, + ".*HipRoll": 5.0, + ".*HipPitch": 5.0, + ".*Knee.*": 5.0, + }, + armature={ + ".*Hip.*": 0.01, + ".*Knee.*": 0.01, + }, + ), + "feet": ImplicitActuatorCfg( + effort_limit=20, + joint_names_expr=[".*AnklePitch", ".*AnkleRoll"], + stiffness=20.0, + damping=2.0, + armature=0.01, + ), + "arms": ImplicitActuatorCfg( + joint_names_expr=[ + ".*Shoulder.*", + ".*Elbow.*", + ".*Forearm.*", + ], + effort_limit=300, + velocity_limit=100.0, + stiffness=40.0, + damping=10.0, + armature={ + ".*Shoulder.*": 0.01, + ".*Elbow.*": 0.01, + ".*Forearm.*": 0.001, + }, + ), + }, +) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/g1/rough_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/g1/rough_env_cfg.py index 1eff2bf5555..bcfa21c8af6 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/g1/rough_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/g1/rough_env_cfg.py @@ -47,7 +47,7 @@ class G1Rewards(RewardsCfg): }, ) - # Penalize ankle joint limits + # PenalizIsaac-Velocity-Flat-Valkyrie-v0e ankle joint limits dof_pos_limits = RewTerm( func=mdp.joint_pos_limits, weight=-1.0, diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py new file mode 100644 index 00000000000..f7b415c03d5 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py @@ -0,0 +1,59 @@ +# 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, flat_env_cfg, rough_env_cfg + +## +# Register Gym environments. +## + +gym.register( + id="Isaac-Velocity-Rough-Valkyrie-v0", + entry_point="isaaclab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": rough_env_cfg.ValkyrieRoughEnvCfg, + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:ValkyrieRoughPPORunnerCfg", + "skrl_cfg_entry_point": f"{agents.__name__}:skrl_rough_ppo_cfg.yaml", + }, +) + + +gym.register( + id="Isaac-Velocity-Rough-Valkyrie-Play-v0", + entry_point="isaaclab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": rough_env_cfg.ValkyrieRoughEnvCfg_PLAY, + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:ValkyrieRoughPPORunnerCfg", + "skrl_cfg_entry_point": f"{agents.__name__}:skrl_rough_ppo_cfg.yaml", + }, +) + + +gym.register( + id="Isaac-Velocity-Flat-Valkyrie-v0", + entry_point="isaaclab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": flat_env_cfg.ValkyrieFlatEnvCfg, + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:ValkyrieFlatPPORunnerCfg", + "skrl_cfg_entry_point": f"{agents.__name__}:skrl_flat_ppo_cfg.yaml", + }, +) + + +gym.register( + id="Isaac-Velocity-Flat-Valkyrie-Play-v0", + entry_point="isaaclab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": flat_env_cfg.ValkyrieFlatEnvCfg_PLAY, + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:ValkyrieFlatPPORunnerCfg", + "skrl_cfg_entry_point": f"{agents.__name__}:skrl_flat_ppo_cfg.yaml", + }, +) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/__init__.py new file mode 100644 index 00000000000..e75ca2bc3f9 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2022-2025, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py new file mode 100644 index 00000000000..f77b97d4710 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py @@ -0,0 +1,51 @@ +# Copyright (c) 2022-2025, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +from omni.isaac.lab.utils import configclass +from omni.isaac.lab_tasks.utils.wrappers.rsl_rl import ( + RslRlOnPolicyRunnerCfg, + RslRlPpoActorCriticCfg, + RslRlPpoAlgorithmCfg, +) + + +@configclass +class G1RoughPPORunnerCfg(RslRlOnPolicyRunnerCfg): + num_steps_per_env = 24 + max_iterations = 3000 + save_interval = 50 + experiment_name = "g1_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.008, + 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 G1FlatPPORunnerCfg(G1RoughPPORunnerCfg): + def __post_init__(self): + super().__post_init__() + + self.max_iterations = 1500 + self.experiment_name = "g1_flat" + self.policy.actor_hidden_dims = [256, 128, 128] + self.policy.critic_hidden_dims = [256, 128, 128] diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_flat_ppo_cfg.yaml b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_flat_ppo_cfg.yaml new file mode 100644 index 00000000000..8d544a32b5f --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_flat_ppo_cfg.yaml @@ -0,0 +1,82 @@ +seed: 42 + + +# Models are instantiated using skrl's model instantiator utility +# https://skrl.readthedocs.io/en/latest/api/utils/model_instantiators.html +models: + separate: False + policy: # see gaussian_model parameters + class: GaussianMixin + clip_actions: False + clip_log_std: True + min_log_std: -20.0 + max_log_std: 2.0 + initial_log_std: 0.0 + network: + - name: net + input: STATES + layers: [256, 128, 128] + activations: elu + output: ACTIONS + value: # see deterministic_model parameters + class: DeterministicMixin + clip_actions: False + network: + - name: net + input: STATES + layers: [256, 128, 128] + activations: elu + output: ONE + + +# Rollout memory +# https://skrl.readthedocs.io/en/latest/api/memories/random.html +memory: + class: RandomMemory + memory_size: -1 # automatically determined (same as agent:rollouts) + + +# PPO agent configuration (field names are from PPO_DEFAULT_CONFIG) +# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html +agent: + class: PPO + # The agent collects number of environment steps during each episode. + # The collected data is then divided into and used for optimization epochs. + rollouts: 24 # number of steps to take in each rollout + learning_epochs: 5 # + mini_batches: 4 # number of mini baches + discount_factor: 0.99 + lambda: 0.95 + learning_rate: 1.0e-03 + learning_rate_scheduler: KLAdaptiveLR + learning_rate_scheduler_kwargs: + kl_threshold: 0.01 + state_preprocessor: null + state_preprocessor_kwargs: null + value_preprocessor: null + value_preprocessor_kwargs: null + random_timesteps: 0 + learning_starts: 0 + grad_norm_clip: 1.0 + ratio_clip: 0.2 # clipping coefficient for computing the clipped surrogate objective + value_clip: 0.2 # clipping coefficient for computing the value loss (if clip_predicted_values is True) + clip_predicted_values: True # clip predicted values during value loss computation + entropy_loss_scale: 0.008 # 0.008 # the bigger, the more exploratin + value_loss_scale: 1.0 + kl_threshold: 0.0 + rewards_shaper_scale: 1.0 + time_limit_bootstrap: False + # logging and checkpoint + experiment: + directory: "valk_flat" + experiment_name: "" + write_interval: auto + checkpoint_interval: auto + + +# Sequential trainer +# https://skrl.readthedocs.io/en/latest/api/trainers/sequential.html +trainer: + class: SequentialTrainer + timesteps: 36000 + environment_info: log diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml new file mode 100644 index 00000000000..07e71559e52 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml @@ -0,0 +1,80 @@ +seed: 42 + + +# Models are instantiated using skrl's model instantiator utility +# https://skrl.readthedocs.io/en/latest/api/utils/model_instantiators.html +models: + separate: False + policy: # see gaussian_model parameters + class: GaussianMixin + clip_actions: False + clip_log_std: True + min_log_std: -20.0 + max_log_std: 2.0 + initial_log_std: 0.0 + network: + - name: net + input: STATES + layers: [512, 256, 128] + activations: elu + output: ACTIONS + value: # see deterministic_model parameters + class: DeterministicMixin + clip_actions: False + network: + - name: net + input: STATES + layers: [512, 256, 128] + activations: elu + output: ONE + + +# Rollout memory +# https://skrl.readthedocs.io/en/latest/api/memories/random.html +memory: + class: RandomMemory + memory_size: -1 # automatically determined (same as agent:rollouts) + + +# PPO agent configuration (field names are from PPO_DEFAULT_CONFIG) +# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html +agent: + class: PPO + rollouts: 24 + learning_epochs: 5 + mini_batches: 4 + discount_factor: 0.99 + lambda: 0.95 + learning_rate: 1.0e-03 + learning_rate_scheduler: KLAdaptiveLR + learning_rate_scheduler_kwargs: + kl_threshold: 0.01 + state_preprocessor: null + state_preprocessor_kwargs: null + value_preprocessor: null + value_preprocessor_kwargs: null + random_timesteps: 0 + learning_starts: 0 + grad_norm_clip: 1.0 + ratio_clip: 0.2 + value_clip: 0.2 + clip_predicted_values: True + entropy_loss_scale: 0.008 + value_loss_scale: 1.0 + kl_threshold: 0.0 + rewards_shaper_scale: 1.0 + time_limit_bootstrap: False + # logging and checkpoint + experiment: + directory: "g1_rough" + experiment_name: "" + write_interval: auto + checkpoint_interval: auto + + +# Sequential trainer +# https://skrl.readthedocs.io/en/latest/api/trainers/sequential.html +trainer: + class: SequentialTrainer + timesteps: 72000 + environment_info: log diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/flat_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/flat_env_cfg.py new file mode 100644 index 00000000000..5a9e34c2166 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/flat_env_cfg.py @@ -0,0 +1,87 @@ +# Copyright (c) 2022-2025, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +from isaaclab.managers import SceneEntityCfg +from isaaclab.utils import configclass + +from .rough_env_cfg import ValkyrieRoughEnvCfg + + +@configclass +class ValkyrieFlatEnvCfg(ValkyrieRoughEnvCfg): + def __post_init__(self): + # post init of parent + super().__post_init__() + + # change terrain to flat + self.scene.terrain.terrain_type = "plane" + self.scene.terrain.terrain_generator = None + # no height scan + self.scene.height_scanner = None + self.observations.policy.height_scan = None + # no terrain curriculum + self.curriculum.terrain_levels = None + + # Rewards + self.rewards.track_lin_vel_xy_exp.weight = 2.0 + self.rewards.track_ang_vel_z_exp.weight = 1.0 + self.rewards.flat_orientation_l2.weight = -1.0 + + self.rewards.lin_vel_z_l2.weight = -0.2 + self.rewards.action_rate_l2.weight = -0.005 + + self.rewards.feet_air_time.weight = 2.5 + self.rewards.feet_air_time.params["threshold"] = 0.4 + + # penalize joint limit if they cross soft limit + self.rewards.feet_pos_limits.weight = -1.0 + self.rewards.torso_roll_pos_limits.weight = -1.0 + + self.rewards.joint_deviation_hip.weight = -0.4 + self.rewards.joint_deviation_feet.weight = -0.4 + self.rewards.joint_deviation_arms.weight = -1.0 + self.rewards.joint_deviation_torso.weight = -1.0 + self.rewards.joint_deviation_torso_roll.weight = -1.0 + + self.rewards.feet_slide.weight = -0.1 + + self.rewards.dof_acc_l2.weight = -1.25e-7 + self.rewards.dof_acc_l2.params["asset_cfg"] = SceneEntityCfg("robot", joint_names=[".*Hip.*", ".*Knee.*"]) + self.rewards.dof_torques_l2.weight = -1.5e-7 + self.rewards.dof_torques_l2.params["asset_cfg"] = SceneEntityCfg("robot", joint_names=[".*Hip.*", ".*Knee.*"]) + # Commands + self.commands.base_velocity.ranges.lin_vel_x = (0.0, 1.0) + self.commands.base_velocity.ranges.lin_vel_y = (-0.5, 0.5) + self.commands.base_velocity.ranges.ang_vel_z = (-1.0, 1.0) + + +class ValkyrieFlatEnvCfg_PLAY(ValkyrieFlatEnvCfg): + def __post_init__(self) -> None: + # post init of parent + 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.events.base_external_force_torque = None + self.events.push_robot = None + + self.commands.base_velocity.ranges.lin_vel_x = (0.0, 1.0) + self.commands.base_velocity.ranges.lin_vel_y = (0.0, 0.0) + self.commands.base_velocity.ranges.ang_vel_z = (0.0, 0.0) + self.events.reset_base.params = { + "pose_range": {"x": (0, 0), "y": (0, 0), "yaw": (0, 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), + }, + } diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/rough_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/rough_env_cfg.py new file mode 100644 index 00000000000..df703b519cd --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/rough_env_cfg.py @@ -0,0 +1,172 @@ +# Copyright (c) 2022-2025, The Isaac Lab Project Developers. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +## +# Pre-defined configs +## +from isaaclab_assets import VALKYRIE_CFG + +from isaaclab.managers import RewardTermCfg as RewTerm +from isaaclab.managers import SceneEntityCfg +from isaaclab.utils import configclass + +import isaaclab_tasks.manager_based.locomotion.velocity.mdp as mdp +from isaaclab_tasks.manager_based.locomotion.velocity.velocity_env_cfg import LocomotionVelocityRoughEnvCfg, RewardsCfg + + +@configclass +class ValkyrieRewards(RewardsCfg): + """Reward terms for the MDP.""" + + termination_penalty = RewTerm(func=mdp.is_terminated, weight=-200.0) + track_lin_vel_xy_exp = RewTerm( + func=mdp.track_lin_vel_xy_yaw_frame_exp, + weight=1.0, + params={"command_name": "base_velocity", "std": 0.5}, + ) + track_ang_vel_z_exp = RewTerm( + func=mdp.track_ang_vel_z_world_exp, weight=2.0, params={"command_name": "base_velocity", "std": 0.5} + ) + feet_air_time = RewTerm( + func=mdp.feet_air_time_positive_biped, + weight=0.6, + params={ + "command_name": "base_velocity", + "sensor_cfg": SceneEntityCfg("contact_forces", body_names=["leftFoot", "rightFoot"]), + "threshold": 0.4, + }, + ) + feet_slide = RewTerm( + func=mdp.feet_slide, + weight=-0.1, + params={ + "sensor_cfg": SceneEntityCfg("contact_forces", body_names=["leftFoot", "rightFoot"]), + "asset_cfg": SceneEntityCfg("robot", body_names=["leftFoot", "rightFoot"]), + }, + ) + + # Penalize ankle joint limits + feet_pos_limits = RewTerm( + func=mdp.joint_pos_limits, + weight=-1.0, + params={"asset_cfg": SceneEntityCfg("robot", joint_names=[".*AnklePitch"])}, + ) + torso_roll_pos_limits = RewTerm( + func=mdp.joint_pos_limits, + weight=-1.0, + params={"asset_cfg": SceneEntityCfg("robot", joint_names=["torsoRoll"])}, + ) + # Penalize deviation from default of the joints that are not essential for locomotion + joint_deviation_feet = RewTerm( + func=mdp.joint_deviation_l1, + weight=-0.4, + params={"asset_cfg": SceneEntityCfg("robot", joint_names=[".*AnkleRoll"])}, + ) + joint_deviation_hip = RewTerm( + func=mdp.joint_deviation_l1, + weight=-0.1, + params={"asset_cfg": SceneEntityCfg("robot", joint_names=[".*HipYaw", ".*HipRoll"])}, + ) + joint_deviation_torso = RewTerm( + func=mdp.joint_deviation_l1, + weight=-0.4, + params={"asset_cfg": SceneEntityCfg("robot", joint_names=["torsoPitch", "torsoYaw"])}, + ) + joint_deviation_torso_roll = RewTerm( + func=mdp.joint_deviation_l1, + weight=-0.4, + params={"asset_cfg": SceneEntityCfg("robot", joint_names=["torsoRoll"])}, + ) + joint_deviation_arms = RewTerm( + func=mdp.joint_deviation_l1, + weight=-0.1, + params={ + "asset_cfg": SceneEntityCfg( + "robot", + joint_names=[ + ".*Shoulder.*", + ".*ElbowPitch", + ], + ) + }, + ) + + +@configclass +class ValkyrieRoughEnvCfg(LocomotionVelocityRoughEnvCfg): + rewards: ValkyrieRewards = ValkyrieRewards() + + def __post_init__(self): + # post init of parent + super().__post_init__() + # Scene + self.scene.robot = VALKYRIE_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot") + self.scene.height_scanner.prim_path = "{ENV_REGEX_NS}/Robot/torsoYawLink" + + # Randomization + self.events.push_robot = None + self.events.add_base_mass = None + self.events.reset_robot_joints.params["position_range"] = (1.0, 1.0) + self.events.base_external_force_torque.params["asset_cfg"].body_names = ["torsoYawLink"] + self.events.reset_base.params = { + "pose_range": {"x": (-0.5, 0.5), "y": (-0.5, 0.5), "yaw": (-3.14, 3.14)}, + "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), + }, + } + + # Rewards + self.rewards.lin_vel_z_l2.weight = 0.0 + self.rewards.undesired_contacts = None + self.rewards.flat_orientation_l2.weight = -1.0 + self.rewards.action_rate_l2.weight = -0.005 + self.rewards.dof_acc_l2.weight = -1.25e-7 + self.rewards.dof_acc_l2.params["asset_cfg"] = SceneEntityCfg("robot", joint_names=[".*Hip.*", ".*Knee.*"]) + self.rewards.dof_torques_l2.weight = -1.5e-7 + self.rewards.dof_torques_l2.params["asset_cfg"] = SceneEntityCfg( + "robot", joint_names=[".*Hip.*", ".*Knee.*", ".*Ankle.*"] + ) + + # Commands + self.commands.base_velocity.ranges.lin_vel_x = (0.0, 1.0) + self.commands.base_velocity.ranges.lin_vel_y = (-0.0, 0.0) + self.commands.base_velocity.ranges.ang_vel_z = (-1.0, 1.0) + + # terminations + self.terminations.base_contact.params["sensor_cfg"].body_names = ["torso.*", ".*Hip.*"] + + +@configclass +class ValkyrieRoughEnvCfg_PLAY(ValkyrieRoughEnvCfg): + def __post_init__(self): + # post init of parent + super().__post_init__() + + # make a smaller scene for play + self.scene.num_envs = 50 + self.scene.env_spacing = 2.5 + self.episode_length_s = 40.0 + # spawn the robot randomly in the grid (instead of their terrain levels) + self.scene.terrain.max_init_terrain_level = None + # reduce the number of terrains to save memory + if self.scene.terrain.terrain_generator is not None: + self.scene.terrain.terrain_generator.num_rows = 5 + self.scene.terrain.terrain_generator.num_cols = 5 + self.scene.terrain.terrain_generator.curriculum = False + + self.commands.base_velocity.ranges.lin_vel_x = (1.0, 1.0) + self.commands.base_velocity.ranges.lin_vel_y = (0.0, 0.0) + self.commands.base_velocity.ranges.ang_vel_z = (-1.0, 1.0) + self.commands.base_velocity.ranges.heading = (0.0, 0.0) + # disable randomization for play + self.observations.policy.enable_corruption = False + # remove random pushing + self.events.base_external_force_torque = None + self.events.push_robot = None From cd47997830b25fd62d3bdca91cb8ff88819a3971 Mon Sep 17 00:00:00 2001 From: Omid Heidari Date: Fri, 9 May 2025 10:47:00 -0500 Subject: [PATCH 2/3] removed rough and rsl --- .../velocity/config/valkyrie/__init__.py | 24 ------ .../config/valkyrie/agents/rsl_rl_ppo_cfg.py | 51 ------------ .../valkyrie/agents/skrl_rough_ppo_cfg.yaml | 80 ------------------- 3 files changed, 155 deletions(-) delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py index f7b415c03d5..eaf2ff61d0e 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/__init__.py @@ -11,30 +11,6 @@ # Register Gym environments. ## -gym.register( - id="Isaac-Velocity-Rough-Valkyrie-v0", - entry_point="isaaclab.envs:ManagerBasedRLEnv", - disable_env_checker=True, - kwargs={ - "env_cfg_entry_point": rough_env_cfg.ValkyrieRoughEnvCfg, - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:ValkyrieRoughPPORunnerCfg", - "skrl_cfg_entry_point": f"{agents.__name__}:skrl_rough_ppo_cfg.yaml", - }, -) - - -gym.register( - id="Isaac-Velocity-Rough-Valkyrie-Play-v0", - entry_point="isaaclab.envs:ManagerBasedRLEnv", - disable_env_checker=True, - kwargs={ - "env_cfg_entry_point": rough_env_cfg.ValkyrieRoughEnvCfg_PLAY, - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:ValkyrieRoughPPORunnerCfg", - "skrl_cfg_entry_point": f"{agents.__name__}:skrl_rough_ppo_cfg.yaml", - }, -) - - gym.register( id="Isaac-Velocity-Flat-Valkyrie-v0", entry_point="isaaclab.envs:ManagerBasedRLEnv", diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py deleted file mode 100644 index f77b97d4710..00000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/rsl_rl_ppo_cfg.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2022-2025, The Isaac Lab Project Developers. -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -from omni.isaac.lab.utils import configclass -from omni.isaac.lab_tasks.utils.wrappers.rsl_rl import ( - RslRlOnPolicyRunnerCfg, - RslRlPpoActorCriticCfg, - RslRlPpoAlgorithmCfg, -) - - -@configclass -class G1RoughPPORunnerCfg(RslRlOnPolicyRunnerCfg): - num_steps_per_env = 24 - max_iterations = 3000 - save_interval = 50 - experiment_name = "g1_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.008, - 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 G1FlatPPORunnerCfg(G1RoughPPORunnerCfg): - def __post_init__(self): - super().__post_init__() - - self.max_iterations = 1500 - self.experiment_name = "g1_flat" - self.policy.actor_hidden_dims = [256, 128, 128] - self.policy.critic_hidden_dims = [256, 128, 128] diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml deleted file mode 100644 index 07e71559e52..00000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/valkyrie/agents/skrl_rough_ppo_cfg.yaml +++ /dev/null @@ -1,80 +0,0 @@ -seed: 42 - - -# Models are instantiated using skrl's model instantiator utility -# https://skrl.readthedocs.io/en/latest/api/utils/model_instantiators.html -models: - separate: False - policy: # see gaussian_model parameters - class: GaussianMixin - clip_actions: False - clip_log_std: True - min_log_std: -20.0 - max_log_std: 2.0 - initial_log_std: 0.0 - network: - - name: net - input: STATES - layers: [512, 256, 128] - activations: elu - output: ACTIONS - value: # see deterministic_model parameters - class: DeterministicMixin - clip_actions: False - network: - - name: net - input: STATES - layers: [512, 256, 128] - activations: elu - output: ONE - - -# Rollout memory -# https://skrl.readthedocs.io/en/latest/api/memories/random.html -memory: - class: RandomMemory - memory_size: -1 # automatically determined (same as agent:rollouts) - - -# PPO agent configuration (field names are from PPO_DEFAULT_CONFIG) -# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html -agent: - class: PPO - rollouts: 24 - learning_epochs: 5 - mini_batches: 4 - discount_factor: 0.99 - lambda: 0.95 - learning_rate: 1.0e-03 - learning_rate_scheduler: KLAdaptiveLR - learning_rate_scheduler_kwargs: - kl_threshold: 0.01 - state_preprocessor: null - state_preprocessor_kwargs: null - value_preprocessor: null - value_preprocessor_kwargs: null - random_timesteps: 0 - learning_starts: 0 - grad_norm_clip: 1.0 - ratio_clip: 0.2 - value_clip: 0.2 - clip_predicted_values: True - entropy_loss_scale: 0.008 - value_loss_scale: 1.0 - kl_threshold: 0.0 - rewards_shaper_scale: 1.0 - time_limit_bootstrap: False - # logging and checkpoint - experiment: - directory: "g1_rough" - experiment_name: "" - write_interval: auto - checkpoint_interval: auto - - -# Sequential trainer -# https://skrl.readthedocs.io/en/latest/api/trainers/sequential.html -trainer: - class: SequentialTrainer - timesteps: 72000 - environment_info: log From 7886bc54a4c033af96354fc41ad619244b3ec66c Mon Sep 17 00:00:00 2001 From: Omid Heidari Date: Fri, 9 May 2025 17:33:37 -0500 Subject: [PATCH 3/3] fixed path to ISAACLAB_NUCLEUS_DIR --- source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py b/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py index 1474e3aeda7..05a7c79a0d6 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/valkyrie.py @@ -7,17 +7,13 @@ Configuration for the Valkyrie robot from IHMC Robotics. """ -import os - import isaaclab.sim as sim_utils from isaaclab.actuators import ImplicitActuatorCfg from isaaclab.assets.articulation import ArticulationCfg - -# get valkyrie usd path -VAL_ASSET_DIR = os.getenv("VAL_ASSET_DIR") + "/valkyrie.usd" +from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR spawn_usd = sim_utils.UsdFileCfg( - usd_path=VAL_ASSET_DIR, + usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/Valkyrie/valkyrie.usd", activate_contact_sensors=True, rigid_props=sim_utils.RigidBodyPropertiesCfg( disable_gravity=False,