IsaacLab官方例子系列教程(一)

代码源于IsaacLab官方例子,致谢原作者,若作者认为有侵权嫌疑,联系删除。

版本为4.2.0---描述:使用MuJoCo类人机器人向某个方向移动

Environment_ID =  Isaac-Humanoid-v0 人形机器人(ManagerBasedRLEnv)

1、导入相关的包

import omni.isaac.lab.sim as sim_utils
from omni.isaac.lab.actuators import ImplicitActuatorCfg
from omni.isaac.lab.assets import ArticulationCfg, AssetBaseCfg
from omni.isaac.lab.envs import ManagerBasedRLEnvCfg
from omni.isaac.lab.managers import EventTermCfg as EventTerm
from omni.isaac.lab.managers import ObservationGroupCfg as ObsGroup
from omni.isaac.lab.managers import ObservationTermCfg as ObsTerm
from omni.isaac.lab.managers import RewardTermCfg as RewTerm
from omni.isaac.lab.managers import SceneEntityCfg
from omni.isaac.lab.managers import TerminationTermCfg as DoneTerm
from omni.isaac.lab.scene import InteractiveSceneCfg
from omni.isaac.lab.terrains import TerrainImporterCfg
from omni.isaac.lab.utils import configclass
from omni.isaac.lab.utils.assets import ISAAC_NUCLEUS_DIR

import omni.isaac.lab_tasks.manager_based.classic.humanoid.mdp as mdp

2、构造场景

@configclass
class MySceneCfg(InteractiveSceneCfg):
    """Configuration for the terrain scene with a humanoid robot."""

    # terrain  地面
    terrain = TerrainImporterCfg(
        prim_path="/World/ground",
        terrain_type="plane", # 平整地面
        collision_group=-1,
        physics_material=sim_utils.RigidBodyMaterialCfg(static_friction=1.0, dynamic_friction=1.0, restitution=0.0),
        debug_vis=False,
    )

    # robot
    robot = ArticulationCfg(
        prim_path="{ENV_REGEX_NS}/Robot",
        spawn=sim_utils.UsdFileCfg( # 通过USDFile导入机器人实体
            usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Humanoid/humanoid_instanceable.usd",
            rigid_props=sim_utils.RigidBodyPropertiesCfg( # 刚体的属性配置
                disable_gravity=None,
                max_depenetration_velocity=10.0, # 当两个物体在仿真中发生穿透(即它们应该由于碰撞而分开但实际上重叠了)时,允许它们以多大的速度“弹开”以修正这种穿透状态。
                enable_gyroscopic_forces=True, # 指示是否启用陀螺效应力(gyroscopic forces)的模拟。陀螺效应是指当一个旋转的物体受到外力作用时,其旋转轴会发生偏转的现象。
            ),
            articulation_props=sim_utils.ArticulationRootPropertiesCfg(
                enabled_self_collisions=True,
                solver_position_iteration_count=4, # 解决位置约束(即确保物体不会穿透或违反约束)的迭代次数
                solver_velocity_iteration_count=0, # 用于解决速度约束(即确保物体以正确的方式移动)的迭代次数
                sleep_threshold=0.005,# 控制物体何时被视为“休眠”或“静止”的阈值。定义了物体被认为是静止之前所需满足的速度和加速度条件。
                stabilization_threshold=0.001, # 通常用于控制物体在仿真中的稳定性,防止它们由于数值误差或外部扰动而表现出不稳定的行为(如抖动或振荡)。
            ),
            copy_from_source=False,
        ),
        init_state=ArticulationCfg.InitialStateCfg(
            pos=(0.0, 0.0, 1.34),
            joint_pos={".*": 0.0},
        ),
        actuators={
            "body": ImplicitActuatorCfg(
                joint_names_expr=[".*"],
                stiffness={ # 刚度
                    ".*_waist.*": 20.0,
                    ".*_upper_arm.*": 10.0,
                    "pelvis": 10.0,
                    ".*_lower_arm": 2.0,
                    ".*_thigh:0": 10.0,
                    ".*_thigh:1": 20.0,
                    ".*_thigh:2": 10.0,
                    ".*_shin": 5.0,
                    ".*_foot.*": 2.0,
                },
                damping={ # 阻尼
                    ".*_waist.*": 5.0,
                    ".*_upper_arm.*": 5.0,
                    "pelvis": 5.0,
                    ".*_lower_arm": 1.0,
                    ".*_thigh:0": 5.0,
                    ".*_thigh:1": 5.0,
                    ".*_thigh:2": 5.0,
                    ".*_shin": 0.1,
                    ".*_foot.*": 1.0,
                },
            ),
        },
    )

    # lights
    light = AssetBaseCfg(
        prim_path="/World/light",
        spawn=sim_utils.DistantLightCfg(color=(0.75, 0.75, 0.75), intensity=3000.0),
    )

2、构造动作(Actions)

@configclass
class ActionsCfg:
    """Action specifications for the MDP."""

    joint_effort = mdp.JointEffortActionCfg( # 关节 力 动作
        asset_name="robot",
        joint_names=[".*"],
        scale={
            ".*_waist.*": 67.5,
            ".*_upper_arm.*": 67.5,
            "pelvis": 67.5,
            ".*_lower_arm": 45.0,
            ".*_thigh:0": 45.0,
            ".*_thigh:1": 135.0,
            ".*_thigh:2": 45.0,
            ".*_shin": 90.0,
            ".*_foot.*": 22.5,
        },
    )

3、构造观察(observation)

@configclass
class ObservationsCfg:
    """Observation specifications for the MDP."""

    @configclass
    class PolicyCfg(ObsGroup):
        """Observations for the policy."""

        base_height = ObsTerm(func=mdp.base_pos_z)
        base_lin_vel = ObsTerm(func=mdp.base_lin_vel)
        base_ang_vel = ObsTerm(func=mdp.base_ang_vel, scale=0.25)
        base_yaw_roll = ObsTerm(func=mdp.base_yaw_roll) # 表示机器人基座的偏航角(yaw)和横滚角(roll)
        base_angle_to_target = ObsTerm(func=mdp.base_angle_to_target, params={"target_pos": (1000.0, 0.0, 0.0)}) # 机器人基座朝向目标位置的角度
        base_up_proj = ObsTerm(func=mdp.base_up_proj) # 机器人基座在垂直方向(上方向)上的投影
        base_heading_proj = ObsTerm(func=mdp.base_heading_proj, params={"target_pos": (1000.0, 0.0, 0.0)}) # 机器人基座朝向目标位置的投影
        joint_pos_norm = ObsTerm(func=mdp.joint_pos_limit_normalized)
        joint_vel_rel = ObsTerm(func=mdp.joint_vel_rel, scale=0.1) # 表示机器人关节的相对速度 值被缩放了 0.1 倍。
        feet_body_forces = ObsTerm( # 作用在机器人双脚上的力和力矩(wrench)
            func=mdp.body_incoming_wrench, # 力矩(wrench)
            scale=0.01,
            params={"asset_cfg": SceneEntityCfg("robot", body_names=["left_foot", "right_foot"])},
        )
        actions = ObsTerm(func=mdp.last_action)

        def __post_init__(self):
            self.enable_corruption = False
            self.concatenate_terms = True # concatenate_terms(是否将各个观测项连接成一个长的向量,这里设置为 True)。

    # observation groups
    policy: PolicyCfg = PolicyCfg()

4、构造事件(Event)

@configclass
class EventCfg:
    """Configuration for events."""

    reset_base = EventTerm(
        func=mdp.reset_root_state_uniform, # 将机器人的基座(或根节点)状态重置为一个均匀分布的随机状态
        mode="reset", # 环境重置时触发
        params={"pose_range": {}, "velocity_range": {}},
    )

    reset_robot_joints = EventTerm(
        func=mdp.reset_joints_by_offset, # 根据给定的偏移量范围重置机器人的关节位置和速度。
        mode="reset",
        params={
            "position_range": (-0.2, 0.2),
            "velocity_range": (-0.1, 0.1),
        },
    )

5、构造奖励(Reward)

@configclass
class RewardsCfg:
    """Reward terms for the MDP."""

    # (1) Reward for moving forward 对向前方移动的奖励
    progress = RewTerm(func=mdp.progress_reward, weight=1.0, params={"target_pos": (1000.0, 0.0, 0.0)})
    # (2) Stay alive bonus 存活奖励
    alive = RewTerm(func=mdp.is_alive, weight=2.0)
    # (3) Reward for non-upright posture 
    upright = RewTerm(func=mdp.upright_posture_bonus, weight=0.1, params={"threshold": 0.93}) # 旨在鼓励机器人保持直立姿态,因为“直立”(upright)通常意味着稳定且符合期望的姿态
    # (4) Reward for moving in the right direction 向想要的位置移动的奖励
    move_to_target = RewTerm(
        func=mdp.move_to_target_bonus, weight=0.5, params={"threshold": 0.8, "target_pos": (1000.0, 0.0, 0.0)}
    )
    # (5) Penalty for large action commands # 对于大动作的惩罚
    action_l2 = RewTerm(func=mdp.action_l2, weight=-0.01)
    # (6) Penalty for energy consumption # 对能量消耗的惩罚
    energy = RewTerm(
        func=mdp.power_consumption,
        weight=-0.005,
        params={
            "gear_ratio": {
                ".*_waist.*": 67.5,
                ".*_upper_arm.*": 67.5,
                "pelvis": 67.5,
                ".*_lower_arm": 45.0,
                ".*_thigh:0": 45.0,
                ".*_thigh:1": 135.0,
                ".*_thigh:2": 45.0,
                ".*_shin": 90.0,
                ".*_foot.*": 22.5,
            }
        },
    )
    # (7) Penalty for reaching close to joint limits 对于接近关节极限的惩罚
    joint_limits = RewTerm(
        func=mdp.joint_limits_penalty_ratio,
        weight=-0.25,
        params={
            "threshold": 0.98,
            "gear_ratio": {
                ".*_waist.*": 67.5,
                ".*_upper_arm.*": 67.5,
                "pelvis": 67.5,
                ".*_lower_arm": 45.0,
                ".*_thigh:0": 45.0,
                ".*_thigh:1": 135.0,
                ".*_thigh:2": 45.0,
                ".*_shin": 90.0,
                ".*_foot.*": 22.5,
            },
        },
    )

6、Termination

@configclass
class TerminationsCfg: # 终止条件
    """Termination terms for the MDP."""

    # (1) Terminate if the episode length is exceeded
    time_out = DoneTerm(func=mdp.time_out, time_out=True)
    # (2) Terminate if the robot falls # 机器人摔倒
    torso_height = DoneTerm(func=mdp.root_height_below_minimum, params={"minimum_height": 0.8})

7、构造总的环境

@configclass
class HumanoidEnvCfg(ManagerBasedRLEnvCfg):
    """Configuration for the MuJoCo-style Humanoid walking environment."""

    # Scene settings
    scene: MySceneCfg = MySceneCfg(num_envs=4096, env_spacing=5.0)
    # Basic settings
    observations: ObservationsCfg = ObservationsCfg()
    actions: ActionsCfg = ActionsCfg()
    # MDP settings
    rewards: RewardsCfg = RewardsCfg()
    terminations: TerminationsCfg = TerminationsCfg()
    events: EventCfg = EventCfg()

    def __post_init__(self):
        """Post initialization."""
        # general settings
        self.decimation = 2
        self.episode_length_s = 16.0
        # simulation settings
        self.sim.dt = 1 / 120.0
        self.sim.render_interval = self.decimation
        self.sim.physx.bounce_threshold_velocity = 0.2 # 设置了物体开始产生弹跳效果的速度阈值。当物体的速度超过这个阈值(0.2单位/时间)时,物理引擎可能会开始计算并应用弹跳效果
        # default friction material
        self.sim.physics_material.static_friction = 1.0 # 静摩擦系数。静摩擦系数决定了物体在静止状态下抵抗开始滑动的力的大小。
        self.sim.physics_material.dynamic_friction = 1.0 # 动摩擦系数。动摩擦系数决定了物体在滑动状态下持续抵抗滑动的力的大小。
        self.sim.physics_material.restitution = 0.0 # 恢复系数(也称为弹性系数)。恢复系数决定了物体在碰撞后能够保留多少动能。

8、注册任务

import gymnasium as gym

from . import agents

##
# Register Gym environments.
##

gym.register(
    id="Isaac-Humanoid-v0",
    entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
    disable_env_checker=True,
    kwargs={ # 环境(Env) 以及 算法agent(PPO)
        "env_cfg_entry_point": f"{__name__}.humanoid_env_cfg:HumanoidEnvCfg",
        "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:HumanoidPPORunnerCfg",
        "rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml",
        "skrl_cfg_entry_point": f"{agents.__name__}:skrl_ppo_cfg.yaml",
        "sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml",
    },
)

9、MDP的observation部分

9.1 base_yaw_roll(机器人基座的偏航角(yaw)和横滚角(roll))

def base_yaw_roll(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")) -> torch.Tensor:
    """Yaw and roll of the base in the simulation world frame."""
    # extract the used quantities (to enable type-hinting)
    asset: Articulation = env.scene[asset_cfg.name]
    # extract euler angles (in world frame)
    # 从实体的根四元数(asset.data.root_quat_w)中提取欧拉角(Euler angles)。这个函数返回三个角度:roll(横滚角)、pitch(俯仰角)和 yaw(偏航角)。
    roll, _, yaw = math_utils.euler_xyz_from_quat(asset.data.root_quat_w)
    # normalize angle to [-pi, pi]
    # 使用 torch.atan2 函数将 roll 和 yaw 角度规范化到 [-π, π] 范围内。
    roll = torch.atan2(torch.sin(roll), torch.cos(roll))
    yaw = torch.atan2(torch.sin(yaw), torch.cos(yaw))

    # 在 yaw 和 roll 张量的最后一个维度上增加一个维度,最后使二者沿着这个维度拼接起来。
    return torch.cat((yaw.unsqueeze(-1), roll.unsqueeze(-1)), dim=-1)

9.2 在给定环境中某个资产(如机器人)的基座 上方向量 在世界上方向量上的投影。

def base_up_proj(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")) -> torch.Tensor:
    """Projection of the base up vector onto the world up vector."""
    # extract the used quantities (to enable type-hinting)
    asset: Articulation = env.scene[asset_cfg.name]
    # compute base up vector
    # 表示在资产基座坐标系中投影的重力向量(通常指向地心)。由于重力向量是向下的,所以通过取负值得到基座上方向量。
    base_up_vec = -asset.data.projected_gravity_b


    # 第三个分量(在三维空间中通常代表z轴分量,即垂直方向),然后通过 unsqueeze(-1) 在最后一个维度上增加一个维度,使其形状符合某些后续操作的要求
    return base_up_vec[:, 2].unsqueeze(-1)

9.3 在给定环境中某个资产(如机器人)的基座 前方向量 在世界坐标系中目标方向上的投影。

def base_heading_proj(
    env: ManagerBasedEnv, target_pos: tuple[float, float, float], asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")
) -> torch.Tensor:
    """Projection of the base forward vector onto the world forward vector."""
    # extract the used quantities (to enable type-hinting)
    asset: Articulation = env.scene[asset_cfg.name]
    # compute desired heading direction
    to_target_pos = torch.tensor(target_pos, device=env.device) - asset.data.root_pos_w[:, :3]
    to_target_pos[:, 2] = 0.0 # Z轴分量置为0
    to_target_dir = math_utils.normalize(to_target_pos) # 标准化
    # compute base forward vector
    # 在世界坐标系中的 基座前方向量 heading_vec 
    # 使用 math_utils.quat_rotate 函数和  资产的世界四元数 asset.data.root_quat_w  来  旋转  资产的  基座前方向量 asset.data.FORWARD_VEC_B
    heading_vec = math_utils.quat_rotate(asset.data.root_quat_w, asset.data.FORWARD_VEC_B)

    # compute dot product between heading and target direction
    # 批量矩阵乘法(Batch Matrix Multiplication)
    heading_proj = torch.bmm(heading_vec.view(env.num_envs, 1, 3), to_target_dir.view(env.num_envs, 3, 1))

    # 由于我们只关心投影的长度(而不是方向),所以可以将结果重塑为 (env.num_envs, 1)。
    return heading_proj.view(env.num_envs, 1)

9.4 表示在给定环境中某个资产(如机器人)的基座前方向量与到目标位置的向量之间的角度。

def base_angle_to_target(
    env: ManagerBasedEnv, target_pos: tuple[float, float, float], asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")
) -> torch.Tensor:
    """Angle between the base forward vector and the vector to the target."""
    # extract the used quantities (to enable type-hinting)
    asset: Articulation = env.scene[asset_cfg.name]
    # compute desired heading direction
    to_target_pos = torch.tensor(target_pos, device=env.device) - asset.data.root_pos_w[:, :3]
    # 使用 torch.atan2 计算 to_target_pos 在二维平面(x-y平面)上的角度 walk_target_angle,这个角度是相对于x轴正方向的。
    # torch.atan2(y, x) 函数计算的是两个变量 y 和 x 的反正切值,这个值表示的是点 (x, y) 与原点 (0, 0) 之间的连线与 x 轴正方向之间的角度。
    # to_target_pos[:, 1] 表示所有向量的 y 分量。
    # to_target_pos[:, 0] 表示所有向量的 x 分量。
    walk_target_angle = torch.atan2(to_target_pos[:, 1], to_target_pos[:, 0])

    # compute base forward vector
    _, _, yaw = math_utils.euler_xyz_from_quat(asset.data.root_quat_w) # 计算欧拉角(Euler angles),特别是yaw角(绕z轴的旋转角)。
    # normalize angle to target to [-pi, pi]
    angle_to_target = walk_target_angle - yaw # 得到资产基座前方向量与到目标方向的向量之间的角度差 angle_to_target。
    # 确保 angle_to_target 被归一化到 [-pi, pi] 范围内。
    angle_to_target = torch.atan2(torch.sin(angle_to_target), torch.cos(angle_to_target))

    # 使用 .unsqueeze(-1) 在 angle_to_target 的最后一个维度上增加一个大小为1的新维度,使其形状变为 (env.num_envs, 1)。这样做通常是为了与其他期望二维输出的函数或操作兼容。
    return angle_to_target.unsqueeze(-1)

10、MDP的rewards的部分

10.1 upright 保持直立

def upright_posture_bonus(
    env: ManagerBasedRLEnv, threshold: float, asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")
) -> torch.Tensor:
    """Reward for maintaining an upright posture."""
    # 往 base_up_proj 上方向的投影
    up_proj = obs.base_up_proj(env, asset_cfg).squeeze(-1)
    return (up_proj > threshold).float() # 大于 某一个阈值

10.2 向目标方向移动

def move_to_target_bonus(
    env: ManagerBasedRLEnv,
    threshold: float,
    target_pos: tuple[float, float, float],
    asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"),
) -> torch.Tensor:
    """Reward for moving to the target heading."""
    # 基座 向 前方的投影
    heading_proj = obs.base_heading_proj(env, target_pos, asset_cfg).squeeze(-1)

    # 如果元素值大于 threshold,则将其设置为 1.0。
    # 如果元素值不大于 threshold,则将其值除以 threshold 进行缩放。
    return torch.where(heading_proj > threshold, 1.0, heading_proj / threshold)

10.3、在强化学习环境中为朝着目标位置前进的行为提供奖励。

class progress_reward(ManagerTermBase):
    """Reward for making progress towards the target."""

    def __init__(self, env: ManagerBasedRLEnv, cfg: RewardTermCfg):
        # initialize the base class
        super().__init__(cfg, env)
        # create history buffer
        # 存储每个环境的“势能”值,这个值基于当前位置到目标位置的距离计算得出,并除以环境的时间步长(step_dt)进行标准化。
        self.potentials = torch.zeros(env.num_envs, device=env.device)
        # prev_potentials:一个与 potentials 形状相同的张量,用于存储上一个时间步的势能值。
        self.prev_potentials = torch.zeros_like(self.potentials)

    def reset(self, env_ids: torch.Tensor):
        # extract the used quantities (to enable type-hinting)
        asset: Articulation = self._env.scene["robot"]
        # compute projection of current heading to desired heading vector
        target_pos = torch.tensor(self.cfg.params["target_pos"], device=self.device)
        to_target_pos = target_pos - asset.data.root_pos_w[env_ids, :3]
        # reward terms
        # 基于当前位置到目标位置的距离计算得出,并除以环境的时间步长(step_dt)进行标准化
        self.potentials[env_ids] = -torch.norm(to_target_pos, p=2, dim=-1) / self._env.step_dt
        self.prev_potentials[env_ids] = self.potentials[env_ids]

    def __call__(
        self,
        env: ManagerBasedRLEnv,
        target_pos: tuple[float, float, float],
        asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"),
    ) -> torch.Tensor:
        # extract the used quantities (to enable type-hinting)
        asset: Articulation = env.scene[asset_cfg.name]
        # compute vector to target
        target_pos = torch.tensor(target_pos, device=env.device)
        to_target_pos = target_pos - asset.data.root_pos_w[:, :3]
        to_target_pos[:, 2] = 0.0 # Z轴为0
        # update history buffer and compute new potential
        self.prev_potentials[:] = self.potentials[:]
        # 基于当前位置到目标位置的距离计算得出,并除以环境的时间步长(step_dt)进行标准化
        self.potentials[:] = -torch.norm(to_target_pos, p=2, dim=-1) / env.step_dt

        # 当资产朝着目标移动时(距离减小),势能会增加(因为负值变得更小,即更接近0),从而导致正的奖励。
        return self.potentials - self.prev_potentials

10.4、在强化学习环境中,对超出关节限制的行为施加一个惩罚,并且这个惩罚会根据每个关节的传动比(gear ratio)进行加权。

class joint_limits_penalty_ratio(ManagerTermBase):
    """Penalty for violating joint limits weighted by the gear ratio."""

    def __init__(self, env: ManagerBasedRLEnv, cfg: RewardTermCfg):
        # add default argument
        if "asset_cfg" not in cfg.params:
            cfg.params["asset_cfg"] = SceneEntityCfg("robot")
        # extract the used quantities (to enable type-hinting)
        asset: Articulation = env.scene[cfg.params["asset_cfg"].name]
        # resolve the gear ratio for each joint
        # gear_ratio:一个张量,存储了每个环境中每个关节的传动比。
        self.gear_ratio = torch.ones(env.num_envs, asset.num_joints, device=env.device)
        # 匹配 名字 和 值
        index_list, _, value_list = string_utils.resolve_matching_names_values(
            cfg.params["gear_ratio"], asset.joint_names
        )
        self.gear_ratio[:, index_list] = torch.tensor(value_list, device=env.device)
        # 经过归一化处理的传动比,即每个传动比都除以了传动比中的最大值,以确保所有值都在0到1之间。
        self.gear_ratio_scaled = self.gear_ratio / torch.max(self.gear_ratio)

    def __call__(
        self, env: ManagerBasedRLEnv, threshold: float, gear_ratio: dict[str, float], asset_cfg: SceneEntityCfg
    ) -> torch.Tensor:
        # extract the used quantities (to enable type-hinting)
        asset: Articulation = env.scene[asset_cfg.name]

        # compute the penalty over normalized joints
        # 这个函数的作用是将关节的实际位置映射到一个标准化的范围内
        # asset.data.soft_joint_pos_limits[..., 0]:这是关节位置的下限(最小值)
        # asset.data.soft_joint_pos_limits[..., 1]:这是关节位置的上限(最大值)
        joint_pos_scaled = math_utils.scale_transform(
            asset.data.joint_pos, asset.data.soft_joint_pos_limits[..., 0], asset.data.soft_joint_pos_limits[..., 1]
        )

        # scale the violation amount by the gear ratio
        # 计算了超出阈值的违规量(violation_amount)
        violation_amount = (torch.abs(joint_pos_scaled) - threshold) / (1 - threshold)
        violation_amount = violation_amount * self.gear_ratio_scaled

        # 它返回了所有关节违规量的总和作为惩罚。
        return torch.sum((torch.abs(joint_pos_scaled) > threshold) * violation_amount, dim=-1)

10.5、计算能量的消耗

class power_consumption(ManagerTermBase):
    """Penalty for the power consumed by the actions to the environment.

    This is computed as commanded torque times the joint velocity.
    """

    def __init__(self, env: ManagerBasedRLEnv, cfg: RewardTermCfg):
        # add default argument
        if "asset_cfg" not in cfg.params:
            cfg.params["asset_cfg"] = SceneEntityCfg("robot")
        # extract the used quantities (to enable type-hinting)
        asset: Articulation = env.scene[cfg.params["asset_cfg"].name]
        # resolve the gear ratio for each joint
        # gear ratio 关节传动比
        self.gear_ratio = torch.ones(env.num_envs, asset.num_joints, device=env.device)
        # 通过 名字 去 匹配 gear ratio 的 数值
        index_list, _, value_list = string_utils.resolve_matching_names_values(
            cfg.params["gear_ratio"], asset.joint_names
        )
        self.gear_ratio[:, index_list] = torch.tensor(value_list, device=env.device)
        # 对 gear ratio 进行一个类似 归一化 的操作
        self.gear_ratio_scaled = self.gear_ratio / torch.max(self.gear_ratio)

    def __call__(self, env: ManagerBasedRLEnv, gear_ratio: dict[str, float], asset_cfg: SceneEntityCfg) -> torch.Tensor:
        # extract the used quantities (to enable type-hinting)
        asset: Articulation = env.scene[asset_cfg.name]
        # return power = torque * velocity (here actions: joint torques)
        # 计算power
        return torch.sum(torch.abs(env.action_manager.action * asset.data.joint_vel * self.gear_ratio_scaled), dim=-1)

11、agent--rsl_rl_PPO 配置

from omni.isaac.lab.utils import configclass

from omni.isaac.lab_tasks.utils.wrappers.rsl_rl import (
    RslRlOnPolicyRunnerCfg,
    RslRlPpoActorCriticCfg,
    RslRlPpoAlgorithmCfg,
)


@configclass
class HumanoidPPORunnerCfg(RslRlOnPolicyRunnerCfg):
    num_steps_per_env = 32 # 意味着每个环境会运行32步,然后收集的数据用于更新策略。
    max_iterations = 1000
    save_interval = 50 #  保存模型或检查点的间隔迭代次数。
    experiment_name = "humanoid"
    empirical_normalization = False # 是否使用经验归一化。这里设置为False,意味着不使用这种技术来标准化输入特征。
    policy = RslRlPpoActorCriticCfg(
        init_noise_std=1.0, # 初始化时噪声的标准差。
        actor_hidden_dims=[400, 200, 100],
        critic_hidden_dims=[400, 200, 100],
        activation="elu",
    )
    algorithm = RslRlPpoAlgorithmCfg(
        value_loss_coef=1.0, # 价值损失系数。这里设置为1.0,表示价值损失在总损失中的权重。
        use_clipped_value_loss=True, #  是否使用裁剪的价值损失。这里设置为True,是PPO算法的一个关键特性。
        clip_param=0.2, # 裁剪参数。这里设置为0.2,用于控制价值函数更新的幅度。
        entropy_coef=0.0, # 熵系数。这里设置为0.0,
        num_learning_epochs=5, 
        num_mini_batches=4,
        learning_rate=5.0e-4,
        schedule="adaptive", # 学习率调度策略。这里设置为"adaptive",意味着学习率可能会根据训练过程中的某些指标进行调整。
        gamma=0.99,  # 折扣因子。这里设置为0.99,用于计算累积回报。
        lam=0.95,  # 计算优势估计
        desired_kl=0.01,  #期望的KL散度。这里设置为0.01,用于控制策略更新幅度,以避免过大变化。
        max_grad_norm=1.0,  #梯度裁剪的最大范数。这里设置为1.0,用于防止梯度爆炸。
    ) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值