v0.1.8; add configs, fix bugs
This commit is contained in:
@@ -1,8 +1,16 @@
|
|||||||
|
# 20260109
|
||||||
|
## v0.1.8
|
||||||
|
1. 加入两个配置legged_gym/envs/go2/go2_config_vanilla.py和legged_gym/envs/go2/go2_config_vanilla2.py
|
||||||
|
- vanilla: episode长度25, 指令采样步数5, 打开move_down_by_accumulated_xy_command, dynamic_resample_commands, 关闭heading_command, zero_command_curriculum, limit_vel_prob, command_range_curriculum, dynamic_sigma
|
||||||
|
- vanilla2:episode长度20, 指令采样步数10, 打开haeding_command, 关闭move_down_by_accumulated_xy_command, dynamic_resample_commands, zero_command_curriculum, limit_vel_prob, command_range_curriculum, dynamic_sigma
|
||||||
|
2. 加入go2_config_fast_flat_move.py配置
|
||||||
|
3. onnx支持rem-cts导出
|
||||||
# 20260107
|
# 20260107
|
||||||
## v0.1.7
|
## v0.1.7
|
||||||
Fix bug:
|
Fix bug:
|
||||||
1. 修复`cfg.commands.dynamic_resample_commands=False`时, 未根据环境调整指令采样范围的问题
|
1. 修复`cfg.commands.dynamic_resample_commands=False`时, 未根据环境调整指令采样范围的问题
|
||||||
2. 修复`env_command_ranges`初始值问题
|
2. 修复`env_command_ranges`初始值问题
|
||||||
|
3. 修复`dynamic_resample_commands=False`时, 未更新`commands_resampling_step`问题
|
||||||
## v0.1.6
|
## v0.1.6
|
||||||
1. 加入`go2_rem_cts`, student使用MoE结构, teacher使用普通CTS, 使用非共享权重和全goal输入
|
1. 加入`go2_rem_cts`, student使用MoE结构, teacher使用普通CTS, 使用非共享权重和全goal输入
|
||||||
2. 加入`move_down_by_accumulated_xy_command`选择是否通过累计速度来降低等级
|
2. 加入`move_down_by_accumulated_xy_command`选择是否通过累计速度来降低等级
|
||||||
|
|||||||
@@ -426,6 +426,8 @@ class LeggedRobot(BaseTask):
|
|||||||
Args:
|
Args:
|
||||||
env_ids (List[int]): Environments ids for which new commands are needed
|
env_ids (List[int]): Environments ids for which new commands are needed
|
||||||
"""
|
"""
|
||||||
|
if len(env_ids) == 0:
|
||||||
|
return
|
||||||
self.stop_heading[env_ids] = False
|
self.stop_heading[env_ids] = False
|
||||||
# update command curriculum with train steps
|
# update command curriculum with train steps
|
||||||
if len(self.cfg.commands.command_range_curriculum):
|
if len(self.cfg.commands.command_range_curriculum):
|
||||||
@@ -443,6 +445,7 @@ class LeggedRobot(BaseTask):
|
|||||||
self._update_env_command_ranges()
|
self._update_env_command_ranges()
|
||||||
print(f"Command range updated at iter {current_iter}: {self.command_ranges}")
|
print(f"Command range updated at iter {current_iter}: {self.command_ranges}")
|
||||||
remaining_dist = torch.clip(0.625 * self.cfg.terrain.terrain_length - torch.norm(self.commands_xy_accumulation[env_ids], dim=1) * self.cfg.commands.resampling_time, 0.0)
|
remaining_dist = torch.clip(0.625 * self.cfg.terrain.terrain_length - torch.norm(self.commands_xy_accumulation[env_ids], dim=1) * self.cfg.commands.resampling_time, 0.0)
|
||||||
|
self.commands_resampling_step[env_ids] = self.cfg.commands.resampling_time / self.dt
|
||||||
if self.cfg.commands.dynamic_resample_commands:
|
if self.cfg.commands.dynamic_resample_commands:
|
||||||
# arrive at boundary 0.625 times the width of the remaining distance
|
# arrive at boundary 0.625 times the width of the remaining distance
|
||||||
if ((self.max_episode_length - self.episode_length_buf[env_ids]) == 0).any():
|
if ((self.max_episode_length - self.episode_length_buf[env_ids]) == 0).any():
|
||||||
@@ -472,7 +475,6 @@ class LeggedRobot(BaseTask):
|
|||||||
lower = self.env_command_ranges["ang_vel_yaw"][env_ids, 0]
|
lower = self.env_command_ranges["ang_vel_yaw"][env_ids, 0]
|
||||||
upper = self.env_command_ranges["ang_vel_yaw"][env_ids, 1]
|
upper = self.env_command_ranges["ang_vel_yaw"][env_ids, 1]
|
||||||
self.commands[env_ids, 2] = (upper - lower) * r + lower
|
self.commands[env_ids, 2] = (upper - lower) * r + lower
|
||||||
self.commands_resampling_step[env_ids] = self.cfg.commands.resampling_time / self.dt
|
|
||||||
else:
|
else:
|
||||||
self.commands[env_ids, 0] = sample_single_interval(
|
self.commands[env_ids, 0] = sample_single_interval(
|
||||||
env_ids,
|
env_ids,
|
||||||
@@ -859,6 +861,12 @@ class LeggedRobot(BaseTask):
|
|||||||
def _update_env_command_ranges(self):
|
def _update_env_command_ranges(self):
|
||||||
""" Update environment-wise command ranges based on current command ranges and terrain type """
|
""" Update environment-wise command ranges based on current command ranges and terrain type """
|
||||||
if not hasattr(self, 'terrain_ids'):
|
if not hasattr(self, 'terrain_ids'):
|
||||||
|
self.env_command_ranges = {
|
||||||
|
'lin_vel_x': torch.tensor(self.command_ranges['lin_vel_x'], device=self.device, requires_grad=False).repeat(self.num_envs, 1),
|
||||||
|
'lin_vel_y': torch.tensor(self.command_ranges['lin_vel_y'], device=self.device, requires_grad=False).repeat(self.num_envs, 1),
|
||||||
|
'ang_vel_yaw': torch.tensor(self.command_ranges['ang_vel_yaw'], device=self.device, requires_grad=False).repeat(self.num_envs, 1),
|
||||||
|
'heading': torch.tensor(self.command_ranges['heading'], device=self.device, requires_grad=False).repeat(self.num_envs, 1),
|
||||||
|
}
|
||||||
return
|
return
|
||||||
for terrain_id, terrain_command_ranges in enumerate(self.cfg.commands.terrain_max_command_ranges):
|
for terrain_id, terrain_command_ranges in enumerate(self.cfg.commands.terrain_max_command_ranges):
|
||||||
env_ids = (self.terrain_ids == terrain_id).nonzero(as_tuple=False).flatten()
|
env_ids = (self.terrain_ids == terrain_id).nonzero(as_tuple=False).flatten()
|
||||||
@@ -1322,6 +1330,7 @@ class LeggedRobot(BaseTask):
|
|||||||
sigma_y = self._get_dynamic_sigma(torch.abs(self.commands[:, 1]), vmin, vmax)
|
sigma_y = self._get_dynamic_sigma(torch.abs(self.commands[:, 1]), vmin, vmax)
|
||||||
lin_vel_error_sq = torch.square(self.commands[:, :2] - self.base_lin_vel[:, :2])
|
lin_vel_error_sq = torch.square(self.commands[:, :2] - self.base_lin_vel[:, :2])
|
||||||
scaled_error = lin_vel_error_sq[:, 0] / sigma_x + lin_vel_error_sq[:, 1] / sigma_y
|
scaled_error = lin_vel_error_sq[:, 0] / sigma_x + lin_vel_error_sq[:, 1] / sigma_y
|
||||||
|
# print(f"{self.base_lin_vel[:, :2]=}, {lin_vel_error_sq=}")
|
||||||
return torch.exp(-scaled_error)
|
return torch.exp(-scaled_error)
|
||||||
|
|
||||||
def _reward_tracking_ang_vel(self):
|
def _reward_tracking_ang_vel(self):
|
||||||
|
|||||||
339
legged_gym/envs/go2/go2_config_fast_flat_move.py
Normal file
339
legged_gym/envs/go2/go2_config_fast_flat_move.py
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : go2_config_fast_flat_move.py
|
||||||
|
@Time : 2026/01/10 02:31:14
|
||||||
|
@Author : wty-yy
|
||||||
|
@Version : 1.0
|
||||||
|
@Blog : https://wty-yy.github.io/
|
||||||
|
@Desc : go2 fast flat move config file
|
||||||
|
Change command_range_curriculum, init command range
|
||||||
|
'''
|
||||||
|
import math
|
||||||
|
from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO, LeggedRobotCfgCTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMCPCTS, LeggedRobotCfgACMoECTS, LeggedRobotCfgDualMoECTS, LeggedRobotCfgREMCTS
|
||||||
|
|
||||||
|
class GO2Cfg(LeggedRobotCfg):
|
||||||
|
class init_state(LeggedRobotCfg.init_state):
|
||||||
|
pos = [0.0, 0.0, 0.42] # x,y,z [m]
|
||||||
|
default_joint_angles = { # = target angles [rad] when action = 0.0
|
||||||
|
'FL_hip_joint': 0.1, # [rad]
|
||||||
|
'RL_hip_joint': 0.1, # [rad]
|
||||||
|
'FR_hip_joint': -0.1 , # [rad]
|
||||||
|
'RR_hip_joint': -0.1, # [rad]
|
||||||
|
|
||||||
|
'FL_thigh_joint': 0.8, # [rad]
|
||||||
|
'RL_thigh_joint': 1., # [rad]
|
||||||
|
'FR_thigh_joint': 0.8, # [rad]
|
||||||
|
'RR_thigh_joint': 1., # [rad]
|
||||||
|
|
||||||
|
'FL_calf_joint': -1.5, # [rad]
|
||||||
|
'RL_calf_joint': -1.5, # [rad]
|
||||||
|
'FR_calf_joint': -1.5, # [rad]
|
||||||
|
'RR_calf_joint': -1.5, # [rad]
|
||||||
|
}
|
||||||
|
turn_over = False # initialize the robot in a flipped over position
|
||||||
|
# turn_over_proportions = [0.1, 0.3, 0.6] # proportions for backflip, sideflip, noflip
|
||||||
|
turn_over_proportions = [0.0, 0.2, 0.8] # proportions for backflip, sideflip, noflip
|
||||||
|
turn_over_init_heights = { # initial heights range for each flip type
|
||||||
|
'backflip': [0.10, 0.15],
|
||||||
|
'sideflip': [0.16, 0.21],
|
||||||
|
}
|
||||||
|
# turn_over_proportions = [0.0, 1.0, 0.0] # proportions for backflip, sideflip, noflip
|
||||||
|
|
||||||
|
class env(LeggedRobotCfg.env):
|
||||||
|
num_envs = 8192
|
||||||
|
num_observations = 45
|
||||||
|
# obs(45) + base_lin_vel(3) + height_measurements(187)
|
||||||
|
num_privileged_obs = 45 + 3 + 4 + 12 + 12 + 187 # 263
|
||||||
|
# num_privileged_obs = 45 + 3 + 187 # 235
|
||||||
|
# num_privileged_obs = 48 # without height measurements
|
||||||
|
episode_length_s = 25
|
||||||
|
|
||||||
|
class domain_rand(LeggedRobotCfg.domain_rand):
|
||||||
|
### Robot properties ###
|
||||||
|
randomize_friction = True
|
||||||
|
friction_range = [0.0, 2.0]
|
||||||
|
|
||||||
|
randomize_base_mass = True
|
||||||
|
added_mass_range = [-1., 1.]
|
||||||
|
|
||||||
|
randomize_link_mass = True
|
||||||
|
multiplied_link_mass_range = [0.9, 1.1]
|
||||||
|
|
||||||
|
randomize_base_com = True
|
||||||
|
added_base_com_range = [-0.03, 0.03]
|
||||||
|
|
||||||
|
randomize_restitution = True # restitution to robot links (Robot init)
|
||||||
|
restitution_range = [0.0, 0.5]
|
||||||
|
|
||||||
|
### Environment reset ###
|
||||||
|
randomize_pd_gains = True
|
||||||
|
stiffness_multiplier_range = [0.9, 1.1]
|
||||||
|
damping_multiplier_range = [0.9, 1.1]
|
||||||
|
|
||||||
|
randomize_motor_zero_offset = True
|
||||||
|
motor_zero_offset_range = [-0.035, 0.035]
|
||||||
|
|
||||||
|
randomize_motor_strength = True # (Env reset)
|
||||||
|
motor_strength_range = [0.8, 1.2]
|
||||||
|
|
||||||
|
### Environment step ###
|
||||||
|
push_robots = True
|
||||||
|
push_interval_s = 4
|
||||||
|
max_push_vel_xy = 0.4
|
||||||
|
max_push_ang_vel = 0.6
|
||||||
|
|
||||||
|
randomize_action_delay = True # use last_action with 0~20 ms delay, 4 decimation
|
||||||
|
|
||||||
|
class control(LeggedRobotCfg.control):
|
||||||
|
# PD Drive parameters:
|
||||||
|
control_type = 'P'
|
||||||
|
stiffness = {'joint': 20.0} # [N*m/rad]
|
||||||
|
damping = {'joint': 0.5} # [N*m*s/rad]
|
||||||
|
# action scale: target angle = actionScale * action + defaultAngle
|
||||||
|
action_scale = 0.25
|
||||||
|
# decimation: Number of control action updates @ sim DT per policy DT
|
||||||
|
decimation = 4
|
||||||
|
|
||||||
|
class terrain(LeggedRobotCfg.terrain):
|
||||||
|
mesh_type = 'plane'
|
||||||
|
max_init_terrain_level = 5
|
||||||
|
# [wave, slope, rough_slope, stairs up, stairs down, obstacles, stepping_stones, gap, flat]
|
||||||
|
# terrain_proportions = [0.2, 0.05, 0.05, 0.30, 0.05, 0.25, 0.0, 0.0, 0.1] # 更偏向wave
|
||||||
|
terrain_proportions = [0.05, 0.20, 0.05, 0.25, 0.10, 0.20, 0.0, 0.0, 0.15] # 这个更偏向平地斜坡
|
||||||
|
# terrain_proportions = [0.20, 0.05, 0.05, 0.30, 0.15, 0.20, 0.0, 0.0, 0.05] # 更偏向wave和stairs
|
||||||
|
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]
|
||||||
|
# terrain_proportions = [0.3, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]
|
||||||
|
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||||
|
move_down_by_accumulated_xy_command = True # move down the terrain curriculum based on accumulated xy command distance instead of absolute distance
|
||||||
|
|
||||||
|
class commands(LeggedRobotCfg.commands):
|
||||||
|
curriculum = False
|
||||||
|
max_curriculum = 1.
|
||||||
|
num_commands = 4 # default: lin_vel_x, lin_vel_y, ang_vel_yaw (in heading mode ang_vel_yaw is recomputed from heading error)
|
||||||
|
resampling_time = 5. # time before command are changed[s]
|
||||||
|
heading_command = False # if true: compute ang vel command from heading error
|
||||||
|
# start training with zero commands and then gradually increase zero command probability
|
||||||
|
zero_command_curriculum = {'start_iter': 0, 'end_iter': 1500, 'start_value': 0.0, 'end_value': 0.1}
|
||||||
|
limit_ang_vel_at_zero_command_prob = 0.2 # probability of add limiting angular velocity commands when zero command is sampled
|
||||||
|
limit_vel_prob = 0.2 # probability of limiting linear velocity command
|
||||||
|
limit_vel_invert_when_continuous = True # invert the limit logic when using continuous sample limit velocity commands
|
||||||
|
limit_vel = {"lin_vel_x": [-1, 1], "lin_vel_y": [-1, 1], "ang_vel_yaw": [-1, 0, 1]} # sample vel commands from min [-1] or zero [0] or max [1] range only
|
||||||
|
stop_heading_at_limit = True # stop heading updates when vel is limited
|
||||||
|
dynamic_resample_commands = True # sample commands with low bounds
|
||||||
|
command_range_curriculum = [ { # list for command range curriculums at specific training iterations
|
||||||
|
'iter': 5000, # training iteration at which the command ranges are updated
|
||||||
|
'lin_vel_x': [-2.0, 2.0], # min max [m/s]
|
||||||
|
'lin_vel_y': [-1.0, 1.0], # min max [m/s]
|
||||||
|
'ang_vel_yaw': [-2.0, 2.0], # min max [rad/s]
|
||||||
|
'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
}, { # list for command range curriculums at specific training iterations
|
||||||
|
'iter': 10000, # training iteration at which the command ranges are updated
|
||||||
|
'lin_vel_x': [-3.0, 3.0], # min max [m/s]
|
||||||
|
'lin_vel_y': [-1.0, 1.0], # min max [m/s]
|
||||||
|
'ang_vel_yaw': [-2.0, 2.0], # min max [rad/s]
|
||||||
|
'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
}, { # list for command range curriculums at specific training iterations
|
||||||
|
'iter': 20000, # training iteration at which the command ranges are updated
|
||||||
|
'lin_vel_x': [-3.5, 3.5], # min max [m/s]
|
||||||
|
'lin_vel_y': [-0.5, 0.5], # min max [m/s]
|
||||||
|
'ang_vel_yaw': [-1.0, 1.0], # min max [rad/s]
|
||||||
|
'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
}, { # list for command range curriculums at specific training iterations
|
||||||
|
'iter': 30000, # training iteration at which the command ranges are updated
|
||||||
|
'lin_vel_x': [-4.0, 4.0], # min max [m/s]
|
||||||
|
'lin_vel_y': [-0.0, 0.0], # min max [m/s]
|
||||||
|
'ang_vel_yaw': [-0.0, 0.0], # min max [rad/s]
|
||||||
|
'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
}, { # list for command range curriculums at specific training iterations
|
||||||
|
'iter': 40000, # training iteration at which the command ranges are updated
|
||||||
|
'lin_vel_x': [-4.5, 4.5], # min max [m/s]
|
||||||
|
'lin_vel_y': [-0.0, 0.0], # min max [m/s]
|
||||||
|
'ang_vel_yaw': [-0.0, 0.0], # min max [rad/s]
|
||||||
|
'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
turn_over_zero_time = { # if turn_over is true, time robot must be stable before sampling new commands after a turn over
|
||||||
|
"backflip": 5.0,
|
||||||
|
"sideflip": 3.0,
|
||||||
|
}
|
||||||
|
# [wave, slope, rough slope, stairs up, stairs down, obstacles, stepping stones, gap, flat]
|
||||||
|
terrain_max_command_ranges = [
|
||||||
|
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # wave
|
||||||
|
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # slope
|
||||||
|
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # rough slope
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # stairs up
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # stairs down
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # obstacles
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # stepping stones
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # gap
|
||||||
|
{'lin_vel_x': [-2.0, 2.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-2.0, 2.0], 'heading': [-1.57, 1.57]}, # flat
|
||||||
|
]
|
||||||
|
|
||||||
|
class ranges:
|
||||||
|
lin_vel_x = [-1.0, 1.0] # min max [m/s]
|
||||||
|
lin_vel_y = [-1.0, 1.0] # min max [m/s]
|
||||||
|
ang_vel_yaw = [-1.0, 1.0] # min max [rad/s]
|
||||||
|
heading = [-1.57, 1.57] # min max [rad]
|
||||||
|
|
||||||
|
class asset(LeggedRobotCfg.asset):
|
||||||
|
file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/go2/urdf/go2.urdf'
|
||||||
|
name = "go2"
|
||||||
|
foot_name = "foot"
|
||||||
|
penalize_contacts_on = ["thigh", "calf"]
|
||||||
|
terminate_after_contacts_on = ["base"]
|
||||||
|
self_collisions = 1 # 1 to disable, 0 to enable...bitwise filter
|
||||||
|
|
||||||
|
class rewards(LeggedRobotCfg.rewards):
|
||||||
|
soft_dof_pos_limit = 0.9
|
||||||
|
base_height_target = 0.38
|
||||||
|
only_positive_rewards = False
|
||||||
|
max_contact_force = 147. # forces above this value are penalized, go2 weight 15kg
|
||||||
|
curriculum_rewards = [
|
||||||
|
{'reward_name': 'lin_vel_z', 'start_iter': 0, 'end_iter': 1500, 'start_value': 1.0, 'end_value': 0.0},
|
||||||
|
{'reward_name': 'correct_base_height', 'start_iter': 0, 'end_iter': 5000, 'start_value': 1.0, 'end_value': 10.0},
|
||||||
|
# {'reward_name': 'dof_power', 'start_iter': 0, 'end_iter': 3000, 'start_value': 1.0, 'end_value': 0.1},
|
||||||
|
# {'reward_name': 'upright', 'start_iter': 0, 'end_iter': 1500, 'start_value': 1.0, 'end_value': 0.0},
|
||||||
|
]
|
||||||
|
tracking_sigma = 0.25 # tracking reward = exp(-error^2/sigma)
|
||||||
|
dynamic_sigma = { # linear interpolation of sigma based on command velocity, **Must start terrain curriculum first**
|
||||||
|
"min_lin_vel": 0.5, # min abs linear velocity to have default sigma
|
||||||
|
"max_lin_vel": 1.5, # max abs linear velocity to have max sigma
|
||||||
|
"min_ang_vel": 1.0, # min abs angular velocity to have default sigma
|
||||||
|
"max_ang_vel": 2.0, # max abs angular velocity to have max sigma
|
||||||
|
# wave, slope, rough_slope, stairs up, stairs down, obstacles, stepping_stones, gap, flat]
|
||||||
|
# "max_sigma": [1/3, 1/4, 1/4, 1/2.7, 1/2.7, 1/2, 1, 1, 1/4]
|
||||||
|
"max_sigma": [5/12, 1/4, 1/4, 1/2, 1/2, 3/4, 1, 1, 1/4]
|
||||||
|
}
|
||||||
|
min_legs_distance = 0.1 # min distance between legs to not be considered stumbling
|
||||||
|
class scales:
|
||||||
|
# tracking_lin_vel = 1.0
|
||||||
|
# tracking_ang_vel = 0.2
|
||||||
|
# lin_vel_z = -10.0
|
||||||
|
# base_height = -50.0
|
||||||
|
# action_rate = -0.005
|
||||||
|
# similar_to_default = -0.1
|
||||||
|
# dof_power = -1e-3 # 能够明显抑制跳跃
|
||||||
|
# dof_acc = -3e-7
|
||||||
|
|
||||||
|
# tracking_lin_vel = 1.0
|
||||||
|
# tracking_ang_vel = 0.5
|
||||||
|
# lin_vel_z = -2.0
|
||||||
|
# ang_vel_xy = -0.05
|
||||||
|
# dof_acc = -2.5e-7
|
||||||
|
# dof_power = -1e-3 # 能够明显抑制跳跃
|
||||||
|
# # torques = -1e-4 # 无用会走着走着倒了
|
||||||
|
# correct_base_height = -10.0
|
||||||
|
# action_rate = -0.01
|
||||||
|
# action_smoothness = -0.01
|
||||||
|
# collision = -1.0
|
||||||
|
# dof_pos_limits = -2.0
|
||||||
|
# feet_regulation = -0.05
|
||||||
|
# hip_to_default = -0.1
|
||||||
|
# similar_to_default = -0.05
|
||||||
|
|
||||||
|
# CTS reward
|
||||||
|
tracking_lin_vel = 1.0
|
||||||
|
tracking_ang_vel = 0.5
|
||||||
|
lin_vel_z = -2.0
|
||||||
|
ang_vel_xy = -0.05
|
||||||
|
dof_acc = -2.5e-7
|
||||||
|
dof_power = -2e-5
|
||||||
|
torques = -1e-4
|
||||||
|
correct_base_height = -1.0
|
||||||
|
action_rate = -0.01
|
||||||
|
action_smoothness = -0.01
|
||||||
|
collision = -1.0
|
||||||
|
dof_pos_limits = -2.0
|
||||||
|
feet_regulation = -0.05
|
||||||
|
# CTS奖励训出来双脚距离非常近, 真机效果很差, 但是sim2sim能上20cm楼梯, 尝试加入hip_to_default奖励或similar_to_default奖励
|
||||||
|
hip_to_default = -0.05 # 在训练到y=1.5时, 双脚会明显碰撞, 为避免该问题提升hip, 效果更差, 还是保持0.05 (y最大也只到0.1了)
|
||||||
|
# legs_distance = -1.5 # 奖励双脚距离, 避免CTS训练出来双脚距离过近, 尝试加入后robogauge flat验证效果变差, 删除
|
||||||
|
# similar_to_default = -0.01
|
||||||
|
# feet_contact_forces = -1.0 # 尝试加入但并没有起到任何效果, 删除
|
||||||
|
|
||||||
|
turn_over_roll_threshold = math.pi / 4 # threshold on roll to use turn over rewards
|
||||||
|
class turn_over_scales:
|
||||||
|
upright = 1.0
|
||||||
|
# dof_acc = -2.5e-7
|
||||||
|
# dof_power = -2e-5
|
||||||
|
# action_rate = -0.001
|
||||||
|
# action_smoothness = -0.001
|
||||||
|
|
||||||
|
class noise(LeggedRobotCfg.noise):
|
||||||
|
add_noise = True
|
||||||
|
|
||||||
|
class GO2CfgPPO(LeggedRobotCfgPPO):
|
||||||
|
class algorithm(LeggedRobotCfgPPO.algorithm):
|
||||||
|
entropy_coef = 0.01
|
||||||
|
class runner(LeggedRobotCfgPPO.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_ppo'
|
||||||
|
max_iterations = 100000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgCTS(LeggedRobotCfgCTS):
|
||||||
|
class runner(LeggedRobotCfgCTS.runner):
|
||||||
|
num_steps_per_env = 24
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class policy(LeggedRobotCfgCTS.policy):
|
||||||
|
latent_dim = 32
|
||||||
|
norm_type = 'l2norm'
|
||||||
|
|
||||||
|
class GO2CfgMoECTS(LeggedRobotCfgMoECTS):
|
||||||
|
class policy(LeggedRobotCfgMoECTS.policy):
|
||||||
|
obs_no_goal_mask = [True] * 6 + [False] * 3 + [True] * 36 # mask for obs without command info
|
||||||
|
student_expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class algorithm(LeggedRobotCfgMoECTS.algorithm):
|
||||||
|
load_balance_coef = 0.01
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgMoECTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_moe_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgMCPCTS(LeggedRobotCfgMCPCTS):
|
||||||
|
class policy(LeggedRobotCfgMCPCTS.policy):
|
||||||
|
obs_no_goal_mask = [True] * 6 + [False] * 3 + [True] * 36 # mask for obs without command info
|
||||||
|
student_expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgMCPCTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_mcp_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgACMoECTS(LeggedRobotCfgACMoECTS):
|
||||||
|
class policy(LeggedRobotCfgACMoECTS.policy):
|
||||||
|
expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgACMoECTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_ac_moe_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgDualMoECTS(LeggedRobotCfgDualMoECTS):
|
||||||
|
class policy(LeggedRobotCfgDualMoECTS.policy):
|
||||||
|
expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgDualMoECTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_dual_moe_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgREMCTS(LeggedRobotCfgREMCTS):
|
||||||
|
class policy(LeggedRobotCfgREMCTS.policy):
|
||||||
|
expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgREMCTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_rem_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
@@ -1,4 +1,15 @@
|
|||||||
# Don't forget to change IS_HARD = False, if you want to use original training setting
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : go2_config_vanilla.py
|
||||||
|
@Time : 2026/01/10 02:26:04
|
||||||
|
@Author : wty-yy
|
||||||
|
@Version : 1.0
|
||||||
|
@Blog : https://wty-yy.github.io/
|
||||||
|
@Desc : Go2 vanilla training config
|
||||||
|
episode length 25, resample commands 5 sec,
|
||||||
|
open move_down_by_accumulated_xy_command, dynamic_resample_commands
|
||||||
|
close heading_command, zero_command_curriculum, limit_vel_prob, command_range_curriculum, dynamic_sigma
|
||||||
|
'''
|
||||||
import math
|
import math
|
||||||
from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO, LeggedRobotCfgCTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMCPCTS, LeggedRobotCfgACMoECTS, LeggedRobotCfgDualMoECTS, LeggedRobotCfgREMCTS
|
from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO, LeggedRobotCfgCTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMCPCTS, LeggedRobotCfgACMoECTS, LeggedRobotCfgDualMoECTS, LeggedRobotCfgREMCTS
|
||||||
|
|
||||||
@@ -94,7 +105,7 @@ class GO2Cfg(LeggedRobotCfg):
|
|||||||
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]
|
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]
|
||||||
# terrain_proportions = [0.3, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]
|
# terrain_proportions = [0.3, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]
|
||||||
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||||
move_down_by_accumulated_xy_command = False # move down the terrain curriculum based on accumulated xy command distance instead of absolute distance
|
move_down_by_accumulated_xy_command = True # move down the terrain curriculum based on accumulated xy command distance instead of absolute distance
|
||||||
|
|
||||||
class commands(LeggedRobotCfg.commands):
|
class commands(LeggedRobotCfg.commands):
|
||||||
curriculum = False
|
curriculum = False
|
||||||
@@ -110,7 +121,7 @@ class GO2Cfg(LeggedRobotCfg):
|
|||||||
limit_vel_invert_when_continuous = True # invert the limit logic when using continuous sample limit velocity commands
|
limit_vel_invert_when_continuous = True # invert the limit logic when using continuous sample limit velocity commands
|
||||||
limit_vel = {"lin_vel_x": [-1, 1], "lin_vel_y": [-1, 1], "ang_vel_yaw": [-1, 0, 1]} # sample vel commands from min [-1] or zero [0] or max [1] range only
|
limit_vel = {"lin_vel_x": [-1, 1], "lin_vel_y": [-1, 1], "ang_vel_yaw": [-1, 0, 1]} # sample vel commands from min [-1] or zero [0] or max [1] range only
|
||||||
stop_heading_at_limit = True # stop heading updates when vel is limited
|
stop_heading_at_limit = True # stop heading updates when vel is limited
|
||||||
dynamic_resample_commands = False # sample commands with low bounds
|
dynamic_resample_commands = True # sample commands with low bounds
|
||||||
command_range_curriculum = []
|
command_range_curriculum = []
|
||||||
# command_range_curriculum = [{ # list for command range curriculums at specific training iterations
|
# command_range_curriculum = [{ # list for command range curriculums at specific training iterations
|
||||||
# 'iter': 20000, # training iteration at which the command ranges are updated
|
# 'iter': 20000, # training iteration at which the command ranges are updated
|
||||||
|
|||||||
324
legged_gym/envs/go2/go2_config_vanilla2.py
Normal file
324
legged_gym/envs/go2/go2_config_vanilla2.py
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : go2_config_vanilla2.py
|
||||||
|
@Time : 2026/01/10 02:27:28
|
||||||
|
@Author : wty-yy
|
||||||
|
@Version : 1.0
|
||||||
|
@Blog : https://wty-yy.github.io/
|
||||||
|
@Desc : Go2 vanilla2 training config, same as unitree rl gym except domain randomization and rewards
|
||||||
|
episode length 20, resample commands 10 sec,
|
||||||
|
open heading_command
|
||||||
|
close move_down_by_accumulated_xy_command, dynamic_resample_commands, zero_command_curriculum, limit_vel_prob, command_range_curriculum, dynamic_sigma
|
||||||
|
'''
|
||||||
|
import math
|
||||||
|
from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO, LeggedRobotCfgCTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMoECTS, LeggedRobotCfgMCPCTS, LeggedRobotCfgACMoECTS, LeggedRobotCfgDualMoECTS, LeggedRobotCfgREMCTS
|
||||||
|
|
||||||
|
class GO2Cfg(LeggedRobotCfg):
|
||||||
|
class init_state(LeggedRobotCfg.init_state):
|
||||||
|
pos = [0.0, 0.0, 0.42] # x,y,z [m]
|
||||||
|
default_joint_angles = { # = target angles [rad] when action = 0.0
|
||||||
|
'FL_hip_joint': 0.1, # [rad]
|
||||||
|
'RL_hip_joint': 0.1, # [rad]
|
||||||
|
'FR_hip_joint': -0.1 , # [rad]
|
||||||
|
'RR_hip_joint': -0.1, # [rad]
|
||||||
|
|
||||||
|
'FL_thigh_joint': 0.8, # [rad]
|
||||||
|
'RL_thigh_joint': 1., # [rad]
|
||||||
|
'FR_thigh_joint': 0.8, # [rad]
|
||||||
|
'RR_thigh_joint': 1., # [rad]
|
||||||
|
|
||||||
|
'FL_calf_joint': -1.5, # [rad]
|
||||||
|
'RL_calf_joint': -1.5, # [rad]
|
||||||
|
'FR_calf_joint': -1.5, # [rad]
|
||||||
|
'RR_calf_joint': -1.5, # [rad]
|
||||||
|
}
|
||||||
|
turn_over = False # initialize the robot in a flipped over position
|
||||||
|
# turn_over_proportions = [0.1, 0.3, 0.6] # proportions for backflip, sideflip, noflip
|
||||||
|
turn_over_proportions = [0.0, 0.2, 0.8] # proportions for backflip, sideflip, noflip
|
||||||
|
turn_over_init_heights = { # initial heights range for each flip type
|
||||||
|
'backflip': [0.10, 0.15],
|
||||||
|
'sideflip': [0.16, 0.21],
|
||||||
|
}
|
||||||
|
# turn_over_proportions = [0.0, 1.0, 0.0] # proportions for backflip, sideflip, noflip
|
||||||
|
|
||||||
|
class env(LeggedRobotCfg.env):
|
||||||
|
num_envs = 8192
|
||||||
|
num_observations = 45
|
||||||
|
# obs(45) + base_lin_vel(3) + height_measurements(187)
|
||||||
|
num_privileged_obs = 45 + 3 + 4 + 12 + 12 + 187 # 263
|
||||||
|
# num_privileged_obs = 45 + 3 + 187 # 235
|
||||||
|
# num_privileged_obs = 48 # without height measurements
|
||||||
|
episode_length_s = 20
|
||||||
|
|
||||||
|
class domain_rand(LeggedRobotCfg.domain_rand):
|
||||||
|
### Robot properties ###
|
||||||
|
randomize_friction = True
|
||||||
|
friction_range = [0.0, 2.0]
|
||||||
|
|
||||||
|
randomize_base_mass = True
|
||||||
|
added_mass_range = [-1., 1.]
|
||||||
|
|
||||||
|
randomize_link_mass = True
|
||||||
|
multiplied_link_mass_range = [0.9, 1.1]
|
||||||
|
|
||||||
|
randomize_base_com = True
|
||||||
|
added_base_com_range = [-0.03, 0.03]
|
||||||
|
|
||||||
|
randomize_restitution = True # restitution to robot links (Robot init)
|
||||||
|
restitution_range = [0.0, 0.5]
|
||||||
|
|
||||||
|
### Environment reset ###
|
||||||
|
randomize_pd_gains = True
|
||||||
|
stiffness_multiplier_range = [0.9, 1.1]
|
||||||
|
damping_multiplier_range = [0.9, 1.1]
|
||||||
|
|
||||||
|
randomize_motor_zero_offset = True
|
||||||
|
motor_zero_offset_range = [-0.035, 0.035]
|
||||||
|
|
||||||
|
randomize_motor_strength = True # (Env reset)
|
||||||
|
motor_strength_range = [0.8, 1.2]
|
||||||
|
|
||||||
|
### Environment step ###
|
||||||
|
push_robots = True
|
||||||
|
push_interval_s = 4
|
||||||
|
max_push_vel_xy = 0.4
|
||||||
|
max_push_ang_vel = 0.6
|
||||||
|
|
||||||
|
randomize_action_delay = True # use last_action with 0~20 ms delay, 4 decimation
|
||||||
|
|
||||||
|
class control(LeggedRobotCfg.control):
|
||||||
|
# PD Drive parameters:
|
||||||
|
control_type = 'P'
|
||||||
|
stiffness = {'joint': 20.0} # [N*m/rad]
|
||||||
|
damping = {'joint': 0.5} # [N*m*s/rad]
|
||||||
|
# action scale: target angle = actionScale * action + defaultAngle
|
||||||
|
action_scale = 0.25
|
||||||
|
# decimation: Number of control action updates @ sim DT per policy DT
|
||||||
|
decimation = 4
|
||||||
|
|
||||||
|
class terrain(LeggedRobotCfg.terrain):
|
||||||
|
max_init_terrain_level = 5
|
||||||
|
# [wave, slope, rough_slope, stairs up, stairs down, obstacles, stepping_stones, gap, flat]
|
||||||
|
# terrain_proportions = [0.2, 0.05, 0.05, 0.30, 0.05, 0.25, 0.0, 0.0, 0.1] # 更偏向wave
|
||||||
|
terrain_proportions = [0.05, 0.20, 0.05, 0.25, 0.10, 0.20, 0.0, 0.0, 0.15] # 这个更偏向平地斜坡
|
||||||
|
# terrain_proportions = [0.20, 0.05, 0.05, 0.30, 0.15, 0.20, 0.0, 0.0, 0.05] # 更偏向wave和stairs
|
||||||
|
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]
|
||||||
|
# terrain_proportions = [0.3, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]
|
||||||
|
# terrain_proportions = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||||
|
move_down_by_accumulated_xy_command = False # move down the terrain curriculum based on accumulated xy command distance instead of absolute distance
|
||||||
|
|
||||||
|
class commands(LeggedRobotCfg.commands):
|
||||||
|
curriculum = False
|
||||||
|
max_curriculum = 1.
|
||||||
|
num_commands = 4 # default: lin_vel_x, lin_vel_y, ang_vel_yaw (in heading mode ang_vel_yaw is recomputed from heading error)
|
||||||
|
resampling_time = 10. # time before command are changed[s]
|
||||||
|
heading_command = True # if true: compute ang vel command from heading error
|
||||||
|
# start training with zero commands and then gradually increase zero command probability
|
||||||
|
zero_command_curriculum = None
|
||||||
|
# zero_command_curriculum = {'start_iter': 0, 'end_iter': 1500, 'start_value': 0.0, 'end_value': 0.1}
|
||||||
|
limit_ang_vel_at_zero_command_prob = 0.0 # probability of add limiting angular velocity commands when zero command is sampled
|
||||||
|
limit_vel_prob = 0.0 # probability of limiting linear velocity command
|
||||||
|
limit_vel_invert_when_continuous = True # invert the limit logic when using continuous sample limit velocity commands
|
||||||
|
limit_vel = {"lin_vel_x": [-1, 1], "lin_vel_y": [-1, 1], "ang_vel_yaw": [-1, 0, 1]} # sample vel commands from min [-1] or zero [0] or max [1] range only
|
||||||
|
stop_heading_at_limit = True # stop heading updates when vel is limited
|
||||||
|
dynamic_resample_commands = False # sample commands with low bounds
|
||||||
|
command_range_curriculum = []
|
||||||
|
# command_range_curriculum = [{ # list for command range curriculums at specific training iterations
|
||||||
|
# 'iter': 20000, # training iteration at which the command ranges are updated
|
||||||
|
# 'lin_vel_x': [-1.0, 1.0], # min max [m/s]
|
||||||
|
# 'lin_vel_y': [-1.0, 1.0], # min max [m/s]
|
||||||
|
# 'ang_vel_yaw': [-1.5, 1.5], # min max [rad/s]
|
||||||
|
# 'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
# }, { # list for command range curriculums at specific training iterations
|
||||||
|
# 'iter': 50000, # training iteration at which the command ranges are updated
|
||||||
|
# 'lin_vel_x': [-2.0, 2.0], # min max [m/s]
|
||||||
|
# 'lin_vel_y': [-1.0, 1.0], # min max [m/s]
|
||||||
|
# 'ang_vel_yaw': [-2.0, 2.0], # min max [rad/s]
|
||||||
|
# 'heading': [-1.57, 1.57], # min max [rad]
|
||||||
|
# }]
|
||||||
|
turn_over_zero_time = { # if turn_over is true, time robot must be stable before sampling new commands after a turn over
|
||||||
|
"backflip": 5.0,
|
||||||
|
"sideflip": 3.0,
|
||||||
|
}
|
||||||
|
# [wave, slope, rough slope, stairs up, stairs down, obstacles, stepping stones, gap, flat]
|
||||||
|
terrain_max_command_ranges = [
|
||||||
|
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # wave
|
||||||
|
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # slope
|
||||||
|
{'lin_vel_x': [-1.5, 1.5], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # rough slope
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # stairs up
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # stairs down
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # obstacles
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # stepping stones
|
||||||
|
{'lin_vel_x': [-1.0, 1.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-1.5, 1.5], 'heading': [-1.57, 1.57]}, # gap
|
||||||
|
{'lin_vel_x': [-2.0, 2.0], 'lin_vel_y': [-1.0, 1.0], 'ang_vel_yaw': [-2.0, 2.0], 'heading': [-1.57, 1.57]}, # flat
|
||||||
|
]
|
||||||
|
|
||||||
|
class ranges:
|
||||||
|
lin_vel_x = [-2.0, 2.0] # min max [m/s]
|
||||||
|
lin_vel_y = [-1.0, 1.0] # min max [m/s]
|
||||||
|
ang_vel_yaw = [-2.0, 2.0] # min max [rad/s]
|
||||||
|
heading = [-1.57, 1.57] # min max [rad]
|
||||||
|
|
||||||
|
class asset(LeggedRobotCfg.asset):
|
||||||
|
file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/go2/urdf/go2.urdf'
|
||||||
|
name = "go2"
|
||||||
|
foot_name = "foot"
|
||||||
|
penalize_contacts_on = ["thigh", "calf"]
|
||||||
|
terminate_after_contacts_on = ["base"]
|
||||||
|
self_collisions = 1 # 1 to disable, 0 to enable...bitwise filter
|
||||||
|
|
||||||
|
class rewards(LeggedRobotCfg.rewards):
|
||||||
|
soft_dof_pos_limit = 0.9
|
||||||
|
base_height_target = 0.38
|
||||||
|
only_positive_rewards = False
|
||||||
|
max_contact_force = 147. # forces above this value are penalized, go2 weight 15kg
|
||||||
|
curriculum_rewards = [
|
||||||
|
{'reward_name': 'lin_vel_z', 'start_iter': 0, 'end_iter': 1500, 'start_value': 1.0, 'end_value': 0.0},
|
||||||
|
{'reward_name': 'correct_base_height', 'start_iter': 0, 'end_iter': 5000, 'start_value': 1.0, 'end_value': 10.0},
|
||||||
|
# {'reward_name': 'dof_power', 'start_iter': 0, 'end_iter': 3000, 'start_value': 1.0, 'end_value': 0.1},
|
||||||
|
# {'reward_name': 'upright', 'start_iter': 0, 'end_iter': 1500, 'start_value': 1.0, 'end_value': 0.0},
|
||||||
|
]
|
||||||
|
tracking_sigma = 0.25 # tracking reward = exp(-error^2/sigma)
|
||||||
|
dynamic_sigma = None
|
||||||
|
# dynamic_sigma = { # linear interpolation of sigma based on command velocity, **Must start terrain curriculum first**
|
||||||
|
# "min_lin_vel": 0.5, # min abs linear velocity to have default sigma
|
||||||
|
# "max_lin_vel": 1.5, # max abs linear velocity to have max sigma
|
||||||
|
# "min_ang_vel": 1.0, # min abs angular velocity to have default sigma
|
||||||
|
# "max_ang_vel": 2.0, # max abs angular velocity to have max sigma
|
||||||
|
# # wave, slope, rough_slope, stairs up, stairs down, obstacles, stepping_stones, gap, flat]
|
||||||
|
# # "max_sigma": [1/3, 1/4, 1/4, 1/2.7, 1/2.7, 1/2, 1, 1, 1/4]
|
||||||
|
# "max_sigma": [5/12, 1/4, 1/4, 1/2, 1/2, 3/4, 1, 1, 1/4]
|
||||||
|
# }
|
||||||
|
min_legs_distance = 0.1 # min distance between legs to not be considered stumbling
|
||||||
|
class scales:
|
||||||
|
# tracking_lin_vel = 1.0
|
||||||
|
# tracking_ang_vel = 0.2
|
||||||
|
# lin_vel_z = -10.0
|
||||||
|
# base_height = -50.0
|
||||||
|
# action_rate = -0.005
|
||||||
|
# similar_to_default = -0.1
|
||||||
|
# dof_power = -1e-3 # 能够明显抑制跳跃
|
||||||
|
# dof_acc = -3e-7
|
||||||
|
|
||||||
|
# tracking_lin_vel = 1.0
|
||||||
|
# tracking_ang_vel = 0.5
|
||||||
|
# lin_vel_z = -2.0
|
||||||
|
# ang_vel_xy = -0.05
|
||||||
|
# dof_acc = -2.5e-7
|
||||||
|
# dof_power = -1e-3 # 能够明显抑制跳跃
|
||||||
|
# # torques = -1e-4 # 无用会走着走着倒了
|
||||||
|
# correct_base_height = -10.0
|
||||||
|
# action_rate = -0.01
|
||||||
|
# action_smoothness = -0.01
|
||||||
|
# collision = -1.0
|
||||||
|
# dof_pos_limits = -2.0
|
||||||
|
# feet_regulation = -0.05
|
||||||
|
# hip_to_default = -0.1
|
||||||
|
# similar_to_default = -0.05
|
||||||
|
|
||||||
|
# CTS reward
|
||||||
|
tracking_lin_vel = 1.0
|
||||||
|
tracking_ang_vel = 0.5
|
||||||
|
lin_vel_z = -2.0
|
||||||
|
ang_vel_xy = -0.05
|
||||||
|
dof_acc = -2.5e-7
|
||||||
|
dof_power = -2e-5
|
||||||
|
torques = -1e-4
|
||||||
|
correct_base_height = -1.0
|
||||||
|
action_rate = -0.01
|
||||||
|
action_smoothness = -0.01
|
||||||
|
collision = -1.0
|
||||||
|
dof_pos_limits = -2.0
|
||||||
|
feet_regulation = -0.05
|
||||||
|
# CTS奖励训出来双脚距离非常近, 真机效果很差, 但是sim2sim能上20cm楼梯, 尝试加入hip_to_default奖励或similar_to_default奖励
|
||||||
|
hip_to_default = -0.05 # 在训练到y=1.5时, 双脚会明显碰撞, 为避免该问题提升hip, 效果更差, 还是保持0.05 (y最大也只到0.1了)
|
||||||
|
# legs_distance = -1.5 # 奖励双脚距离, 避免CTS训练出来双脚距离过近, 尝试加入后robogauge flat验证效果变差, 删除
|
||||||
|
# similar_to_default = -0.01
|
||||||
|
# feet_contact_forces = -1.0 # 尝试加入但并没有起到任何效果, 删除
|
||||||
|
|
||||||
|
turn_over_roll_threshold = math.pi / 4 # threshold on roll to use turn over rewards
|
||||||
|
class turn_over_scales:
|
||||||
|
upright = 1.0
|
||||||
|
# dof_acc = -2.5e-7
|
||||||
|
# dof_power = -2e-5
|
||||||
|
# action_rate = -0.001
|
||||||
|
# action_smoothness = -0.001
|
||||||
|
|
||||||
|
class noise(LeggedRobotCfg.noise):
|
||||||
|
add_noise = True
|
||||||
|
|
||||||
|
class GO2CfgPPO(LeggedRobotCfgPPO):
|
||||||
|
class algorithm(LeggedRobotCfgPPO.algorithm):
|
||||||
|
entropy_coef = 0.01
|
||||||
|
class runner(LeggedRobotCfgPPO.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_ppo'
|
||||||
|
max_iterations = 100000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgCTS(LeggedRobotCfgCTS):
|
||||||
|
class runner(LeggedRobotCfgCTS.runner):
|
||||||
|
num_steps_per_env = 24
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class policy(LeggedRobotCfgCTS.policy):
|
||||||
|
latent_dim = 32
|
||||||
|
norm_type = 'l2norm'
|
||||||
|
|
||||||
|
class GO2CfgMoECTS(LeggedRobotCfgMoECTS):
|
||||||
|
class policy(LeggedRobotCfgMoECTS.policy):
|
||||||
|
obs_no_goal_mask = [True] * 6 + [False] * 3 + [True] * 36 # mask for obs without command info
|
||||||
|
student_expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class algorithm(LeggedRobotCfgMoECTS.algorithm):
|
||||||
|
load_balance_coef = 0.01
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgMoECTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_moe_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgMCPCTS(LeggedRobotCfgMCPCTS):
|
||||||
|
class policy(LeggedRobotCfgMCPCTS.policy):
|
||||||
|
obs_no_goal_mask = [True] * 6 + [False] * 3 + [True] * 36 # mask for obs without command info
|
||||||
|
student_expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgMCPCTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_mcp_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgACMoECTS(LeggedRobotCfgACMoECTS):
|
||||||
|
class policy(LeggedRobotCfgACMoECTS.policy):
|
||||||
|
expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgACMoECTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_ac_moe_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgDualMoECTS(LeggedRobotCfgDualMoECTS):
|
||||||
|
class policy(LeggedRobotCfgDualMoECTS.policy):
|
||||||
|
expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgDualMoECTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_dual_moe_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
|
|
||||||
|
class GO2CfgREMCTS(LeggedRobotCfgREMCTS):
|
||||||
|
class policy(LeggedRobotCfgREMCTS.policy):
|
||||||
|
expert_num = 8 # number of experts in the student model
|
||||||
|
|
||||||
|
class runner(LeggedRobotCfgREMCTS.runner):
|
||||||
|
run_name = ''
|
||||||
|
experiment_name = 'go2_rem_cts'
|
||||||
|
max_iterations = 150000
|
||||||
|
save_interval = 500
|
||||||
@@ -210,10 +210,13 @@ class _OnnxPolicyExporter(torch.nn.Module):
|
|||||||
|
|
||||||
elif hasattr(policy, "student_moe_encoder"):
|
elif hasattr(policy, "student_moe_encoder"):
|
||||||
self.student_moe_encoder = copy.deepcopy(policy.student_moe_encoder)
|
self.student_moe_encoder = copy.deepcopy(policy.student_moe_encoder)
|
||||||
self.obs_no_goal_mask = copy.deepcopy(policy.obs_no_goal_mask).cpu()
|
|
||||||
self.history_length = policy.history.shape[1]
|
self.history_length = policy.history.shape[1]
|
||||||
self.forward = self.forward_moe_cts
|
self.forward = self.forward_moe_cts
|
||||||
self.input_dim = self.history_length * policy.history.shape[2]
|
self.input_dim = self.history_length * policy.history.shape[2]
|
||||||
|
if hasattr(policy, "obs_no_goal_mask"):
|
||||||
|
self.obs_no_goal_mask = copy.deepcopy(policy.obs_no_goal_mask).cpu()
|
||||||
|
else:
|
||||||
|
self.forward = self.forward_rem_cts
|
||||||
|
|
||||||
else: # PPO
|
else: # PPO
|
||||||
self.forward = self.forward_ppo
|
self.forward = self.forward_ppo
|
||||||
@@ -287,6 +290,17 @@ class _OnnxPolicyExporter(torch.nn.Module):
|
|||||||
|
|
||||||
return self.actor(x), weights, latent
|
return self.actor(x), weights, latent
|
||||||
|
|
||||||
|
def forward_rem_cts(self, x):
|
||||||
|
x = self.normalizer(x)
|
||||||
|
history, obs_dim = self.flatten_obs(x)
|
||||||
|
|
||||||
|
last_obs = history[:, -obs_dim:]
|
||||||
|
|
||||||
|
latent, weights = self.student_moe_encoder(history)
|
||||||
|
x = torch.cat([latent, last_obs], dim=1)
|
||||||
|
|
||||||
|
return self.actor(x), weights, latent
|
||||||
|
|
||||||
def forward_mcp_cts(self, x):
|
def forward_mcp_cts(self, x):
|
||||||
x = self.normalizer(x)
|
x = self.normalizer(x)
|
||||||
history, obs_dim = self.flatten_obs(x)
|
history, obs_dim = self.flatten_obs(x)
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import find_packages
|
|||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
|
|
||||||
setup(name='go2_rl_gym',
|
setup(name='go2_rl_gym',
|
||||||
version='0.1.7',
|
version='0.1.8',
|
||||||
author='Wu Tianyang',
|
author='Wu Tianyang',
|
||||||
license="MIT",
|
license="MIT",
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
|
|||||||
Reference in New Issue
Block a user