parkour/legged_gym/legged_gym/envs/go2/go2_config.py

281 lines
9.6 KiB
Python

""" Basic model configs for Unitree Go2 """
import numpy as np
import os.path as osp
from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO
go2_action_scale = 0.5
go2_const_dof_range = dict(
Hip_max= 1.0472,
Hip_min= -1.0472,
Front_Thigh_max= 3.4907,
Front_Thigh_min= -1.5708,
Rear_Thingh_max= 4.5379,
Rear_Thingh_min= -0.5236,
Calf_max= -0.83776,
Calf_min= -2.7227,
)
class Go2RoughCfg( LeggedRobotCfg ):
class env:
num_envs = 4096
num_observations = None # No use, use obs_components
num_privileged_obs = None # No use, use privileged_obs_components
use_lin_vel = False # to be decided
num_actions = 12
send_timeouts = True # send time out information to the algorithm
episode_length_s = 20 # episode length in seconds
obs_components = [
"lin_vel",
"ang_vel",
"projected_gravity",
"commands",
"dof_pos",
"dof_vel",
"last_actions",
"height_measurements",
]
class sensor:
class proprioception:
obs_components = ["ang_vel", "projected_gravity", "commands", "dof_pos", "dof_vel"]
latency_range = [0.005, 0.045] # [s]
latency_resampling_time = 5.0 # [s]
class terrain:
selected = "TerrainPerlin"
mesh_type = None
measure_heights = True
# x: [-0.5, 1.5], y: [-0.5, 0.5] range for go2
measured_points_x = [i for i in np.arange(-0.5, 1.51, 0.1)]
measured_points_y = [i for i in np.arange(-0.5, 0.51, 0.1)]
horizontal_scale = 0.025 # [m]
vertical_scale = 0.005 # [m]
border_size = 5 # [m]
curriculum = False
static_friction = 1.0
dynamic_friction = 1.0
restitution = 0.
max_init_terrain_level = 5 # starting curriculum state
terrain_length = 4.
terrain_width = 4.
num_rows= 16 # number of terrain rows (levels)
num_cols = 16 # number of terrain cols (types)
slope_treshold = 1.
TerrainPerlin_kwargs = dict(
zScale= 0.07,
frequency= 10,
)
class commands( LeggedRobotCfg.commands ):
heading_command = False
resampling_time = 5 # [s]
lin_cmd_cutoff = 0.2
ang_cmd_cutoff = 0.2
class ranges( LeggedRobotCfg.commands.ranges ):
lin_vel_x = [-1.0, 1.5]
lin_vel_y = [-1., 1.]
ang_vel_yaw = [-2., 2.]
class init_state( LeggedRobotCfg.init_state ):
pos = [0., 0., 0.5] # [m]
default_joint_angles = { # 12 joints in the order of simulation
"FL_hip_joint": 0.1,
"FL_thigh_joint": 0.7,
"FL_calf_joint": -1.5,
"FR_hip_joint": -0.1,
"FR_thigh_joint": 0.7,
"FR_calf_joint": -1.5,
"RL_hip_joint": 0.1,
"RL_thigh_joint": 1.0,
"RL_calf_joint": -1.5,
"RR_hip_joint": -0.1,
"RR_thigh_joint": 1.0,
"RR_calf_joint": -1.5,
}
class control( LeggedRobotCfg.control ):
stiffness = {'joint': 40.}
damping = {'joint': 1.}
action_scale = go2_action_scale
computer_clip_torque = False
motor_clip_torque = True
class asset( LeggedRobotCfg.asset ):
file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/go2/urdf/go2.urdf'
name = "go2"
foot_name = "foot"
front_hip_names = ["FL_hip_joint", "FR_hip_joint"]
rear_hip_names = ["RL_hip_joint", "RR_hip_joint"]
penalize_contacts_on = ["thigh", "calf"]
terminate_after_contacts_on = ["base"]
sdk_dof_range = go2_const_dof_range
dof_velocity_override = 35.
class termination:
termination_terms = [
"roll",
"pitch",
]
roll_kwargs = dict(
threshold= 3.0, # [rad]
)
pitch_kwargs = dict(
threshold= 3.0, # [rad] # for leap, jump
)
class domain_rand( LeggedRobotCfg.domain_rand ):
randomize_com = True
class com_range:
x = [-0.2, 0.2]
y = [-0.1, 0.1]
z = [-0.05, 0.05]
randomize_motor = True
leg_motor_strength_range = [0.8, 1.2]
randomize_base_mass = True
added_mass_range = [1.0, 3.0]
randomize_friction = True
friction_range = [0., 2.]
init_base_pos_range = dict(
x= [0.05, 0.6],
y= [-0.25, 0.25],
)
init_base_rot_range = dict(
roll= [-0.75, 0.75],
pitch= [-0.75, 0.75],
)
init_base_vel_range = dict(
x= [-0.2, 1.5],
y= [-0.2, 0.2],
z= [-0.2, 0.2],
roll= [-1., 1.],
pitch= [-1., 1.],
yaw= [-1., 1.],
)
init_dof_vel_range = [-5, 5]
push_robots = True
max_push_vel_xy = 0.5 # [m/s]
push_interval_s = 2
class rewards( LeggedRobotCfg.rewards ):
class scales:
tracking_lin_vel = 1.
tracking_ang_vel = 1.
energy_substeps = -2e-5
stand_still = -2.
dof_error_named = -1.
dof_error = -0.01
# penalty for hardware safety
exceed_dof_pos_limits = -0.4
exceed_torque_limits_l1norm = -0.4
dof_vel_limits = -0.4
dof_error_names = ["FL_hip_joint", "FR_hip_joint", "RL_hip_joint", "RR_hip_joint"]
only_positive_rewards = False
soft_dof_vel_limit = 0.9
soft_dof_pos_limit = 0.9
soft_torque_limit = 0.9
class normalization( LeggedRobotCfg.normalization ):
class obs_scales( LeggedRobotCfg.normalization.obs_scales ):
lin_vel = 1.
height_measurements_offset = -0.2
clip_actions_method = None # let the policy learns not to exceed the limits
class noise( LeggedRobotCfg.noise ):
add_noise = False
class viewer( LeggedRobotCfg.viewer ):
pos = [-1., -1., 0.4]
lookat = [0., 0., 0.3]
class sim( LeggedRobotCfg.sim ):
body_measure_points = { # transform are related to body frame
"base": dict(
x= [i for i in np.arange(-0.24, 0.41, 0.03)],
y= [-0.08, -0.04, 0.0, 0.04, 0.08],
z= [i for i in np.arange(-0.061, 0.071, 0.03)],
transform= [0., 0., 0.005, 0., 0., 0.],
),
"thigh": dict(
x= [
-0.16, -0.158, -0.156, -0.154, -0.152,
-0.15, -0.145, -0.14, -0.135, -0.13, -0.125, -0.12, -0.115, -0.11, -0.105, -0.1, -0.095, -0.09, -0.085, -0.08, -0.075, -0.07, -0.065, -0.05,
0.0, 0.05, 0.1,
],
y= [-0.015, -0.01, 0.0, -0.01, 0.015],
z= [-0.03, -0.015, 0.0, 0.015],
transform= [0., 0., -0.1, 0., 1.57079632679, 0.],
),
"calf": dict(
x= [i for i in np.arange(-0.13, 0.111, 0.03)],
y= [-0.015, 0.0, 0.015],
z= [-0.015, 0.0, 0.015],
transform= [0., 0., -0.11, 0., 1.57079632679, 0.],
),
}
logs_root = osp.join(osp.dirname(osp.dirname(osp.dirname(osp.dirname(osp.abspath(__file__))))), "logs")
class Go2RoughCfgPPO( LeggedRobotCfgPPO ):
class algorithm( LeggedRobotCfgPPO.algorithm ):
entropy_coef = 0.01
clip_min_std = 0.2
learning_rate = 1e-4
optimizer_class_name = "AdamW"
class policy( LeggedRobotCfgPPO.policy ):
# configs for estimator module
estimator_obs_components = [
"ang_vel",
"projected_gravity",
"commands",
"dof_pos",
"dof_vel",
"last_actions",
]
estimator_target_components = ["lin_vel"]
replace_state_prob = 1.0
class estimator_kwargs:
hidden_sizes = [128, 64]
nonlinearity = "CELU"
# configs for (critic) encoder
encoder_component_names = ["height_measurements"]
encoder_class_name = "MlpModel"
class encoder_kwargs:
hidden_sizes = [128, 64]
nonlinearity = "CELU"
encoder_output_size = 32
critic_encoder_component_names = ["height_measurements"]
init_noise_std = 0.5
# configs for policy: using recurrent policy with GRU
rnn_type = 'gru'
mu_activation = None
class runner( LeggedRobotCfgPPO.runner ):
policy_class_name = "EncoderStateAcRecurrent"
algorithm_class_name = "EstimatorPPO"
experiment_name = "rough_go2"
resume = False
load_run = None
run_name = "".join(["Go2Rough",
("_pEnergy" + np.format_float_scientific(Go2RoughCfg.rewards.scales.energy_substeps, precision= 1, trim= "-") if Go2RoughCfg.rewards.scales.energy_substeps != 0 else ""),
("_pDofErr" + np.format_float_scientific(Go2RoughCfg.rewards.scales.dof_error, precision= 1, trim= "-") if Go2RoughCfg.rewards.scales.dof_error != 0 else ""),
("_pDofErrN" + np.format_float_scientific(Go2RoughCfg.rewards.scales.dof_error_named, precision= 1, trim= "-") if Go2RoughCfg.rewards.scales.dof_error_named != 0 else ""),
("_pStand" + np.format_float_scientific(Go2RoughCfg.rewards.scales.stand_still, precision= 1, trim= "-") if Go2RoughCfg.rewards.scales.stand_still != 0 else ""),
("_noResume" if not resume else "_from" + "_".join(load_run.split("/")[-1].split("_")[:2])),
])
max_iterations = 2000
save_interval = 2000
log_interval = 100