diff --git a/UPDATE.md b/UPDATE.md index 8619c89..bdad085 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -1,6 +1,8 @@ # 20260107 ## v0.1.6 1. 加入`go2_rem_cts`, student使用MoE结构, teacher使用普通CTS, 使用非共享权重和全goal输入 +2. 加入`move_down_by_acuumulated_xy_command`选择是否通过累计速度来降低等级 +3. 加入`dynamic_resample_commands`选择是否通过累计速度来动态调整指令采样下限 # 20260106 ## v0.1.5 1. 加入`go2_ac_moe_cts`, 参考MoELoco将MoE加载Actor-Critic上, 使用非共享权重和全goal输入 diff --git a/legged_gym/envs/base/legged_robot.py b/legged_gym/envs/base/legged_robot.py index 8cbf698..cc214fe 100644 --- a/legged_gym/envs/base/legged_robot.py +++ b/legged_gym/envs/base/legged_robot.py @@ -221,7 +221,7 @@ class LeggedRobot(BaseTask): self.episode_length_buf[env_ids] = 0 self.reset_buf[env_ids] = 1 self.commands_resampling_step[env_ids] = self.cfg.commands.resampling_time / self.dt - self.commands_xy_accummulation[env_ids] = 0.0 + self.commands_xy_accumulation[env_ids] = 0.0 if self.cfg.commands.curriculum: self.update_command_curriculum(env_ids) self._resample_commands(env_ids) @@ -442,36 +442,47 @@ class LeggedRobot(BaseTask): self.cfg.commands.command_range_curriculum.pop(i) self._update_env_command_ranges() print(f"Command range updated at iter {current_iter}: {self.command_ranges}") - # 到达边界0.625倍宽度的剩余距离 - remaining_dist = torch.clip(0.625 * self.cfg.terrain.terrain_length - torch.norm(self.commands_xy_accummulation[env_ids], dim=1) * self.cfg.commands.resampling_time, 0.0) - if ((self.max_episode_length - self.episode_length_buf[env_ids]) == 0).any(): - raise ValueError("Some envs have zero remaining episode length during command resampling") - vel_low_bound = torch.clip(remaining_dist / ((self.max_episode_length - self.episode_length_buf[env_ids] + 1e-9) * self.dt), 0.0) - self.commands[env_ids, 0] = sample_disjoint_intervals( - env_ids, - vel_low_bound, - self.env_command_ranges["lin_vel_x"][env_ids, 0], - self.env_command_ranges["lin_vel_x"][env_ids, 1], - self.device - ) - self.commands[env_ids, 1] = sample_disjoint_intervals( - env_ids, - vel_low_bound, - self.env_command_ranges["lin_vel_y"][env_ids, 0], - self.env_command_ranges["lin_vel_y"][env_ids, 1], - self.device - ) - if self.cfg.commands.heading_command: - r = torch.rand(len(env_ids), device=self.device) - lower = self.env_command_ranges["heading"][env_ids, 0] - upper = self.env_command_ranges["heading"][env_ids, 1] - self.commands[env_ids, 3] = (upper - lower) * r + lower + 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) + if self.cfg.commands.dynamic_resample_commands: + # 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(): + raise ValueError("Some envs have zero remaining episode length during command resampling") + vel_low_bound = torch.clip(remaining_dist / ((self.max_episode_length - self.episode_length_buf[env_ids] + 1e-9) * self.dt), 0.0) + self.commands[env_ids, 0] = sample_disjoint_intervals( + env_ids, + vel_low_bound, + self.env_command_ranges["lin_vel_x"][env_ids, 0], + self.env_command_ranges["lin_vel_x"][env_ids, 1], + self.device + ) + self.commands[env_ids, 1] = sample_disjoint_intervals( + env_ids, + vel_low_bound, + self.env_command_ranges["lin_vel_y"][env_ids, 0], + self.env_command_ranges["lin_vel_y"][env_ids, 1], + self.device + ) + if self.cfg.commands.heading_command: + r = torch.rand(len(env_ids), device=self.device) + lower = self.env_command_ranges["heading"][env_ids, 0] + upper = self.env_command_ranges["heading"][env_ids, 1] + self.commands[env_ids, 3] = (upper - lower) * r + lower + else: + r = torch.rand(len(env_ids), device=self.device) + lower = self.env_command_ranges["ang_vel_yaw"][env_ids, 0] + upper = self.env_command_ranges["ang_vel_yaw"][env_ids, 1] + self.commands[env_ids, 2] = (upper - lower) * r + lower + self.commands_resampling_step[env_ids] = self.cfg.commands.resampling_time / self.dt else: - r = torch.rand(len(env_ids), device=self.device) - lower = self.env_command_ranges["ang_vel_yaw"][env_ids, 0] - upper = self.env_command_ranges["ang_vel_yaw"][env_ids, 1] - self.commands[env_ids, 2] = (upper - lower) * r + lower - self.commands_resampling_step[env_ids] = self.cfg.commands.resampling_time / self.dt + self.commands[env_ids, 0] = torch_rand_float(self.command_ranges["lin_vel_x"][0], self.command_ranges["lin_vel_x"][1], (len(env_ids), 1), device=self.device).squeeze(1) + self.commands[env_ids, 1] = torch_rand_float(self.command_ranges["lin_vel_y"][0], self.command_ranges["lin_vel_y"][1], (len(env_ids), 1), device=self.device).squeeze(1) + if self.cfg.commands.heading_command: + self.commands[env_ids, 3] = torch_rand_float(self.command_ranges["heading"][0], self.command_ranges["heading"][1], (len(env_ids), 1), device=self.device).squeeze(1) + else: + self.commands[env_ids, 2] = torch_rand_float(self.command_ranges["ang_vel_yaw"][0], self.command_ranges["ang_vel_yaw"][1], (len(env_ids), 1), device=self.device).squeeze(1) + + # set small commands to zero + self.commands[env_ids, :2] *= (torch.norm(self.commands[env_ids, :2], dim=1) > 0.2).unsqueeze(1) # set small commands to zero # self.commands[env_ids, :2] *= (torch.norm(self.commands[env_ids, :2], dim=1) > 0.2).unsqueeze(1) @@ -559,7 +570,7 @@ class LeggedRobot(BaseTask): self.commands[zero_env_ids, :3] = 0.0 self.stop_heading[zero_env_ids] = True - self.commands_xy_accummulation[env_ids] += self.commands[env_ids, :2] + self.commands_xy_accumulation[env_ids] += self.commands[env_ids, :2] def _compute_torques(self, actions): """ Compute torques from actions. @@ -782,7 +793,7 @@ class LeggedRobot(BaseTask): self.commands = torch.zeros(self.num_envs, self.cfg.commands.num_commands, dtype=torch.float, device=self.device, requires_grad=False) # x vel, y vel, yaw vel, heading self.commands_scale = torch.tensor([self.obs_scales.lin_vel, self.obs_scales.lin_vel, self.obs_scales.ang_vel], device=self.device, requires_grad=False,) # TODO change this self.commands_resampling_step = torch.zeros(self.num_envs, dtype=torch.float, device=self.device, requires_grad=False) - self.commands_xy_accummulation = torch.zeros(self.num_envs, 2, dtype=torch.float, device=self.device, requires_grad=False) + self.commands_xy_accumulation = torch.zeros(self.num_envs, 2, dtype=torch.float, device=self.device, requires_grad=False) self.zero_command_proba = 0.0 self.feet_air_time = torch.zeros(self.num_envs, self.feet_indices.shape[0], dtype=torch.float, device=self.device, requires_grad=False) self.last_contacts = torch.zeros(self.num_envs, len(self.feet_indices), dtype=torch.bool, device=self.device, requires_grad=False) @@ -1118,9 +1129,11 @@ class LeggedRobot(BaseTask): distance = self.max_move_distance[env_ids] # robots that walked far enough progress to harder terains move_up = distance > self.terrain.env_length / 2 - # robots that walked less than half of their required distance go to simpler terrains - # move_down = (distance < torch.norm(self.commands[env_ids, :2], dim=1) * self.max_episode_length_s * 0.5) * ~move_up - move_down = (distance < torch.norm(self.commands_xy_accummulation[env_ids], dim=1) * (self.cfg.commands.resampling_time * (1 - self.zero_command_proba)) * 0.5) * ~move_up + if self.cfg.terrain.move_down_by_acuumulated_xy_command: + move_down = (distance < torch.norm(self.commands_xy_accumulation[env_ids], dim=1) * (self.cfg.commands.resampling_time * (1 - self.zero_command_proba)) * 0.5) * ~move_up + else: + # robots that walked less than half of their required distance go to simpler terrains + move_down = (distance < torch.norm(self.commands[env_ids, :2], dim=1) * self.max_episode_length_s * 0.5) * ~move_up self.terrain_levels[env_ids] += 1 * move_up - 1 * move_down # Robots that solve the last level are sent to a random one diff --git a/legged_gym/envs/base/legged_robot_config.py b/legged_gym/envs/base/legged_robot_config.py index 768cb4c..4365f9b 100644 --- a/legged_gym/envs/base/legged_robot_config.py +++ b/legged_gym/envs/base/legged_robot_config.py @@ -38,6 +38,7 @@ class LeggedRobotCfg(BaseConfig): terrain_proportions = [0.1, 0.1, 0.1, 0.2, 0.2, 0.1, 0.1, 0.1, 0.0] # trimesh only: slope_treshold = 0.75 # slopes above this threshold will be corrected to vertical surfaces + move_down_by_acuumulated_xy_command = False # move down the terrain curriculum based on accumulated xy command distance instead of absolute distance class commands: curriculum = False @@ -53,6 +54,7 @@ class LeggedRobotCfg(BaseConfig): 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 = [] # list for command range curriculums at specific training iterations # eg: [{ # 'iter': 20000, # training iteration at which the command ranges are updated diff --git a/legged_gym/envs/go2/go2_config.py b/legged_gym/envs/go2/go2_config.py index feee3d2..8546c20 100644 --- a/legged_gym/envs/go2/go2_config.py +++ b/legged_gym/envs/go2/go2_config.py @@ -93,6 +93,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.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_acuumulated_xy_command = True # move down the terrain curriculum based on accumulated xy command distance instead of absolute distance class commands(LeggedRobotCfg.commands): curriculum = False @@ -107,6 +108,7 @@ class GO2Cfg(LeggedRobotCfg): 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': 20000, # training iteration at which the command ranges are updated 'lin_vel_x': [-1.0, 1.0], # min max [m/s] diff --git a/legged_gym/envs/go2/go2_config_vanilla.py b/legged_gym/envs/go2/go2_config_vanilla.py new file mode 100644 index 0000000..ff37c27 --- /dev/null +++ b/legged_gym/envs/go2/go2_config_vanilla.py @@ -0,0 +1,313 @@ +# Don't forget to change IS_HARD = False, if you want to use original training setting +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): + 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_acuumulated_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 = 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 = 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