align terrain settings with go2_rl_gym.
This commit is contained in:
@@ -15,10 +15,10 @@ from isaaclab.terrains import TerrainImporterCfg
|
||||
from isaaclab.utils import configclass
|
||||
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR
|
||||
from isaaclab.utils.noise import AdditiveUniformNoiseCfg as Unoise
|
||||
import isaaclab.terrains as terrain_gen
|
||||
|
||||
import robot_lab.tasks.go2.mdp as mdp
|
||||
from robot_lab.assets.unitree import GO2_CFG_ROBOTLAB, GO2_CFG_UNITREE
|
||||
from robot_lab.tasks.go2.mdp.terrain import DEFAULT_TERRAIN_CFG
|
||||
|
||||
JOINT_NAMES = [
|
||||
"FL_hip_joint", "FL_thigh_joint", "FL_calf_joint",
|
||||
@@ -35,47 +35,7 @@ BASE_HEIGHT_TARGET = 0.38 # base height target for rewards, set as an attribute
|
||||
# Terrain definition
|
||||
##
|
||||
|
||||
TERRAIN_CFG = terrain_gen.TerrainGeneratorCfg(
|
||||
size=(8.0, 8.0),
|
||||
border_width=25.0,
|
||||
num_rows=10,
|
||||
num_cols=20,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
use_cache=False,
|
||||
sub_terrains={
|
||||
"pyramid_stairs": terrain_gen.MeshPyramidStairsTerrainCfg(
|
||||
proportion=0.15,
|
||||
step_height_range=(0.05, 0.25),
|
||||
step_width=0.3,
|
||||
platform_width=3.0,
|
||||
border_width=1.0,
|
||||
holes=False,
|
||||
),
|
||||
"pyramid_stairs_inv": terrain_gen.MeshInvertedPyramidStairsTerrainCfg(
|
||||
proportion=0.20,
|
||||
step_height_range=(0.05, 0.25),
|
||||
step_width=0.3,
|
||||
platform_width=3.0,
|
||||
border_width=1.0,
|
||||
holes=False,
|
||||
),
|
||||
"boxes": terrain_gen.MeshRandomGridTerrainCfg(
|
||||
proportion=0.15, grid_width=0.45, grid_height_range=(0.025, 0.1), platform_width=2.0
|
||||
),
|
||||
"random_rough": terrain_gen.HfRandomUniformTerrainCfg(
|
||||
proportion=0.15, noise_range=(0.01, 0.06), noise_step=0.01, border_width=0.25
|
||||
),
|
||||
"flat": terrain_gen.MeshPlaneTerrainCfg(proportion=0.15),
|
||||
"hf_pyramid_slope": terrain_gen.HfPyramidSlopedTerrainCfg(
|
||||
proportion=0.1, slope_range=(0.0, 0.5), platform_width=2.0, border_width=0.25
|
||||
),
|
||||
"hf_pyramid_slope_inv": terrain_gen.HfInvertedPyramidSlopedTerrainCfg(
|
||||
proportion=0.1, slope_range=(0.0, 0.5), platform_width=2.0, border_width=0.25
|
||||
),
|
||||
},
|
||||
)
|
||||
TERRAIN_CFG = DEFAULT_TERRAIN_CFG
|
||||
|
||||
|
||||
##
|
||||
@@ -517,8 +477,8 @@ class Go2EnvCfg(ManagerBasedRLEnvCfg):
|
||||
|
||||
# Physics material settings from subclass
|
||||
self.sim.physics_material = self.scene.terrain.physics_material
|
||||
self.sim.physx.gpu_max_rigid_patch_count = 10 * 2**15
|
||||
self.sim.physx.gpu_collision_stack_size = int(64 * 1024 * 1024) # 128 MB
|
||||
self.sim.physx.gpu_max_rigid_patch_count = 512 * 1024
|
||||
self.sim.physx.gpu_collision_stack_size = int(128 * 1024 * 1024) # 128 MB
|
||||
self.sim.physx.enable_external_forces_every_iteration = True
|
||||
|
||||
# Update sensor periods
|
||||
|
||||
@@ -373,23 +373,42 @@ class Go2RLGymCommandCfg(CommandTermCfg):
|
||||
'ang_vel_yaw': [-2.0, 2.0], # min max [rad/s]
|
||||
}]
|
||||
"""List for command range curriculums at specific training iterations"""
|
||||
# terrain_max_command_ranges: dict[str, dict] = {
|
||||
# 'random_rough':
|
||||
# {'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'hf_pyramid_slope':
|
||||
# {'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'hf_pyramid_slope_inv':
|
||||
# {'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'pyramid_stairs':
|
||||
# {'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'pyramid_stairs_inv':
|
||||
# {'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'boxes':
|
||||
# {'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'flat':
|
||||
# {'lin_vel_x': [-2.0, 2.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-2.0, 2.0]},
|
||||
# }
|
||||
terrain_max_command_ranges: dict[str, dict] = {
|
||||
'random_rough':
|
||||
'wave':
|
||||
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
'hf_pyramid_slope':
|
||||
'slope':
|
||||
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
'hf_pyramid_slope_inv':
|
||||
'rough_slope':
|
||||
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
'pyramid_stairs':
|
||||
'stairs_up':
|
||||
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
'pyramid_stairs_inv':
|
||||
'stairs_down':
|
||||
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
'boxes':
|
||||
'obstacles':
|
||||
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'stepping_stones':
|
||||
# {'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
# 'gap':
|
||||
# {'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5]},
|
||||
'flat':
|
||||
{'lin_vel_x': [-2.0, 2.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-2.0, 2.0]},
|
||||
}
|
||||
|
||||
resampling_time: float = 5.0
|
||||
resampling_time_range: tuple[float, float] = (5.0, 5.0)
|
||||
"""Time before command are changed [s]"""
|
||||
|
||||
265
source/robot_lab/robot_lab/tasks/go2/mdp/terrain.py
Normal file
265
source/robot_lab/robot_lab/tasks/go2/mdp/terrain.py
Normal file
@@ -0,0 +1,265 @@
|
||||
# Copyright (c) 2024-2025 Ziqi Fan
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""Terrain presets for the Go2 task.
|
||||
|
||||
This module keeps two terrain configurations side by side:
|
||||
|
||||
1. ``ORIGINAL_TERRAIN_CFG``:
|
||||
The original RobotLab terrain setup that existed before Gym-alignment changes.
|
||||
This is the default selection used by ``env_cfg.py`` so existing training behavior
|
||||
is not changed.
|
||||
|
||||
2. ``GYM_ALIGNED_TERRAIN_CFG``:
|
||||
A Gym-oriented terrain setup derived from:
|
||||
- ``legged_gym/envs/go2/go2_config.py``
|
||||
- ``legged_gym/utils/terrain.py``
|
||||
and interpreted with ``IS_HARD = True``.
|
||||
|
||||
Only the terrain generator presets live here. The environment can choose either
|
||||
configuration without modifying the rest of the task code.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
|
||||
import isaaclab.terrains as terrain_gen
|
||||
from isaaclab.utils import configclass
|
||||
from isaaclab.terrains.height_field import hf_terrains
|
||||
from isaaclab.terrains.height_field.utils import height_field_to_mesh
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Original RobotLab terrain setup
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
ORIGINAL_TERRAIN_CFG = terrain_gen.TerrainGeneratorCfg(
|
||||
size=(8.0, 8.0),
|
||||
border_width=25.0,
|
||||
num_rows=10,
|
||||
num_cols=20,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
use_cache=False,
|
||||
sub_terrains={
|
||||
"pyramid_stairs": terrain_gen.MeshPyramidStairsTerrainCfg(
|
||||
proportion=0.15,
|
||||
step_height_range=(0.05, 0.25),
|
||||
step_width=0.3,
|
||||
platform_width=3.0,
|
||||
border_width=1.0,
|
||||
holes=False,
|
||||
),
|
||||
"pyramid_stairs_inv": terrain_gen.MeshInvertedPyramidStairsTerrainCfg(
|
||||
proportion=0.20,
|
||||
step_height_range=(0.05, 0.25),
|
||||
step_width=0.3,
|
||||
platform_width=3.0,
|
||||
border_width=1.0,
|
||||
holes=False,
|
||||
),
|
||||
"boxes": terrain_gen.MeshRandomGridTerrainCfg(
|
||||
proportion=0.15,
|
||||
grid_width=0.45,
|
||||
grid_height_range=(0.025, 0.1),
|
||||
platform_width=2.0,
|
||||
),
|
||||
"random_rough": terrain_gen.HfRandomUniformTerrainCfg(
|
||||
proportion=0.15,
|
||||
noise_range=(0.01, 0.06),
|
||||
noise_step=0.01,
|
||||
border_width=0.25,
|
||||
),
|
||||
"flat": terrain_gen.MeshPlaneTerrainCfg(proportion=0.15),
|
||||
"hf_pyramid_slope": terrain_gen.HfPyramidSlopedTerrainCfg(
|
||||
proportion=0.1,
|
||||
slope_range=(0.0, 0.5),
|
||||
platform_width=2.0,
|
||||
border_width=0.25,
|
||||
),
|
||||
"hf_pyramid_slope_inv": terrain_gen.HfInvertedPyramidSlopedTerrainCfg(
|
||||
proportion=0.1,
|
||||
slope_range=(0.0, 0.5),
|
||||
platform_width=2.0,
|
||||
border_width=0.25,
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Gym-aligned terrain setup
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def _gym_signed_pyramid_slope_height_field(
|
||||
difficulty: float,
|
||||
cfg: terrain_gen.HfPyramidSlopedTerrainCfg,
|
||||
random_inverted: bool,
|
||||
) -> np.ndarray:
|
||||
"""Generate a Gym-style pyramid slope with optional random sign."""
|
||||
slope = cfg.slope_range[0] + difficulty * (cfg.slope_range[1] - cfg.slope_range[0])
|
||||
if random_inverted and np.random.rand() < 0.5:
|
||||
slope = -slope
|
||||
|
||||
width_pixels = int(cfg.size[0] / cfg.horizontal_scale)
|
||||
length_pixels = int(cfg.size[1] / cfg.horizontal_scale)
|
||||
height_max = int(slope * cfg.size[0] / 2 / cfg.vertical_scale)
|
||||
center_x = int(width_pixels / 2)
|
||||
center_y = int(length_pixels / 2)
|
||||
|
||||
x = np.arange(0, width_pixels)
|
||||
y = np.arange(0, length_pixels)
|
||||
xx, yy = np.meshgrid(x, y, sparse=True)
|
||||
xx = (center_x - np.abs(center_x - xx)) / center_x
|
||||
yy = (center_y - np.abs(center_y - yy)) / center_y
|
||||
xx = xx.reshape(width_pixels, 1)
|
||||
yy = yy.reshape(1, length_pixels)
|
||||
|
||||
hf_raw = height_max * xx * yy
|
||||
|
||||
platform_width = int(cfg.platform_width / cfg.horizontal_scale / 2)
|
||||
x_pf = width_pixels // 2 - platform_width
|
||||
y_pf = length_pixels // 2 - platform_width
|
||||
z_pf = hf_raw[x_pf, y_pf]
|
||||
hf_raw = np.clip(hf_raw, min(0, z_pf), max(0, z_pf))
|
||||
|
||||
return np.rint(hf_raw).astype(np.int16)
|
||||
|
||||
|
||||
@height_field_to_mesh
|
||||
def gym_wave_terrain(difficulty: float, cfg) -> np.ndarray:
|
||||
"""Gym-style wave terrain: wave plus random uniform roughness."""
|
||||
wave = hf_terrains.wave_terrain.__wrapped__(difficulty, cfg)
|
||||
rough = hf_terrains.random_uniform_terrain.__wrapped__(difficulty, cfg)
|
||||
return np.rint(wave + rough).astype(np.int16)
|
||||
|
||||
|
||||
@height_field_to_mesh
|
||||
def gym_slope_terrain(difficulty: float, cfg) -> np.ndarray:
|
||||
"""Gym-style slope terrain with 50/50 positive and negative slopes."""
|
||||
return _gym_signed_pyramid_slope_height_field(difficulty, cfg, random_inverted=True)
|
||||
|
||||
|
||||
@height_field_to_mesh
|
||||
def gym_rough_slope_terrain(difficulty: float, cfg) -> np.ndarray:
|
||||
"""Gym-style rough slope terrain: slope plus random uniform roughness."""
|
||||
slope = _gym_signed_pyramid_slope_height_field(difficulty, cfg, random_inverted=False)
|
||||
rough = hf_terrains.random_uniform_terrain.__wrapped__(difficulty, cfg)
|
||||
return np.rint(slope + rough).astype(np.int16)
|
||||
|
||||
|
||||
@configclass
|
||||
class GymWaveTerrainCfg(terrain_gen.HfTerrainBaseCfg):
|
||||
function = gym_wave_terrain
|
||||
amplitude_range: tuple[float, float] = (0.1, 0.28)
|
||||
num_waves: int = 5
|
||||
noise_range: tuple[float, float] = (-0.05, 0.05)
|
||||
noise_step: float = 0.005
|
||||
downsampled_scale: float = 0.2
|
||||
|
||||
|
||||
@configclass
|
||||
class GymSlopeTerrainCfg(terrain_gen.HfTerrainBaseCfg):
|
||||
function = gym_slope_terrain
|
||||
slope_range: tuple[float, float] = (0.1, 0.568)
|
||||
platform_width: float = 3.0
|
||||
|
||||
|
||||
@configclass
|
||||
class GymRoughSlopeTerrainCfg(terrain_gen.HfTerrainBaseCfg):
|
||||
function = gym_rough_slope_terrain
|
||||
slope_range: tuple[float, float] = (0.1, 0.568)
|
||||
platform_width: float = 3.0
|
||||
noise_range: tuple[float, float] = (-0.05, 0.05)
|
||||
noise_step: float = 0.005
|
||||
downsampled_scale: float = 0.2
|
||||
|
||||
|
||||
GYM_ALIGNED_TERRAIN_CFG = terrain_gen.TerrainGeneratorCfg(
|
||||
size=(8.0, 8.0),
|
||||
border_width=25.0,
|
||||
num_rows=10,
|
||||
num_cols=20,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
use_cache=False,
|
||||
sub_terrains={
|
||||
"wave": GymWaveTerrainCfg(
|
||||
proportion=0.05,
|
||||
border_width=0.0,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
),
|
||||
"slope": GymSlopeTerrainCfg(
|
||||
proportion=0.20,
|
||||
border_width=0.0,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
),
|
||||
"rough_slope": GymRoughSlopeTerrainCfg(
|
||||
proportion=0.05,
|
||||
border_width=0.0,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
),
|
||||
"stairs_up": terrain_gen.HfInvertedPyramidStairsTerrainCfg(
|
||||
proportion=0.25,
|
||||
step_height_range=(0.05, 0.257),
|
||||
step_width=0.31,
|
||||
platform_width=3.0,
|
||||
border_width=0.0,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
),
|
||||
"stairs_down": terrain_gen.HfPyramidStairsTerrainCfg(
|
||||
proportion=0.10,
|
||||
step_height_range=(0.05, 0.257),
|
||||
step_width=0.31,
|
||||
platform_width=3.0,
|
||||
border_width=0.0,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
),
|
||||
"obstacles": terrain_gen.HfDiscreteObstaclesTerrainCfg(
|
||||
proportion=0.20,
|
||||
obstacle_width_range=(1.0, 2.0),
|
||||
obstacle_height_range=(0.05, 0.275),
|
||||
num_obstacles=20,
|
||||
platform_width=3.0,
|
||||
border_width=0.0,
|
||||
horizontal_scale=0.1,
|
||||
vertical_scale=0.005,
|
||||
slope_threshold=0.75,
|
||||
),
|
||||
# "stepping_stones": terrain_gen.HfSteppingStonesTerrainCfg(
|
||||
# proportion=0.0,
|
||||
# stone_height_max=0.0,
|
||||
# stone_width_range=(0.075, 1.575),
|
||||
# stone_distance_range=(0.05, 0.10),
|
||||
# holes_depth=-10.0,
|
||||
# platform_width=4.0,
|
||||
# border_width=0.0,
|
||||
# horizontal_scale=0.1,
|
||||
# vertical_scale=0.005,
|
||||
# slope_threshold=0.75,
|
||||
# ),
|
||||
# "gap": terrain_gen.MeshGapTerrainCfg(
|
||||
# proportion=0.0,
|
||||
# gap_width_range=(0.0, 0.9),
|
||||
# platform_width=3.0,
|
||||
# ),
|
||||
"flat": terrain_gen.MeshPlaneTerrainCfg(proportion=0.15),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_TERRAIN_CFG = GYM_ALIGNED_TERRAIN_CFG
|
||||
Reference in New Issue
Block a user