如是我闻: 终于让我给摸索出来了,在这里描述一下问题场景。
假使说我们有一个机械臂操作的任务,这样婶的
Isaac Lab | Push
我们想做多目标的任务,这时候需要向环境中添加第二个目标,像这样
Isaac Lab | Add target
那么就需要改动如下代码。
1. 添加新的目标命令
假如你的环境保留了IsaacLab他提供的的文件结构,像这样
我们应该有一个叫做 ****_env_cfg.py
的文件环境名,在lift环境里,有一个 lift_env_cfg.py
,在reach 环境中,有一个reach_env_cfg.py
。也许你有一个自己命名的文件,但是没有关系。
在 ****_env_cfg.py
中,我们包装了如环境设置ObjectTableSceneCfg
,目标命令CommandsCfg
,动作空间ActionCfg
,观察空间ObservationCfg
,随机化事件EvetCfg
,奖励函数RewardsCfg
,终止条件TerminationsCfg
等项
我们首先需要改动的在 ****_env_cfg.py
中,找到目标命令类CommandsCfg
,他可能长这样
@configclass
class CommandsCfg:
"""Command terms for the MDP."""
object_pose = mdp.UniformPoseCommandCfg(
asset_name="robot",
body_name=MISSING, # will be set by agent env cfg
resampling_time_range=(5.0, 5.0),
debug_vis=True,
ranges=mdp.UniformPoseCommandCfg.Ranges(
pos_x=(0.3, 0.7), pos_y=(-0.3, 0.3), pos_z=(0.0, 0.0), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0)
),
)
这里只写了一个目标命令object_pose
,我们直接复制粘贴,可以得到
@configclass
class CommandsCfg:
"""Command terms for the MDP."""
object_pose = mdp.UniformPoseCommandCfg(
asset_name="robot",
body_name=MISSING, # will be set by agent env cfg
resampling_time_range=(5.0, 5.0),
debug_vis=True,
ranges=mdp.UniformPoseCommandCfg.Ranges(
pos_x=(0.3, 0.7), pos_y=(-0.3, 0.3), pos_z=(0.0, 0.0), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0)
),
)
object2_pose = mdp.UniformPoseCommandCfg(
asset_name="robot",
body_name=MISSING, # will be set by agent env cfg
resampling_time_range=(5.0, 5.0),
debug_vis=True,
ranges=mdp.UniformPoseCommandCfg.Ranges(
pos_x=(0.3, 0.7), pos_y=(-0.3, 0.3), pos_z=(0.0, 0.0), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0)
),
)
这样我们就有两个目标命令了(傻笑)。
2. 将新的目标命令添加到观察空间中
还是在这个****_env_cfg.py
文件中,找到观察空间类ObservationCfg
@configclass
class ObservationsCfg:
"""Observation specifications for the MDP."""
@configclass
class PolicyCfg(ObsGroup):
"""Observations for policy group."""
joint_pos = ObsTerm(func=mdp.joint_pos_rel)
joint_vel = ObsTerm(func=mdp.joint_vel_rel)
object_position = ObsTerm(func=mdp.object_position_in_robot_root_frame)
target1_object1_position = ObsTerm(func=mdp.generated_commands, params={"command_name": "object_pose"})
# Add object2 position in robot root frame
object2_position = ObsTerm(func=mdp.object2_position_in_robot_root_frame)
actions = ObsTerm(func=mdp.last_action)
def __post_init__(self):
self.enable_corruption = True
self.concatenate_terms = True
# observation groups
policy: PolicyCfg = PolicyCfg()
这里我们需要添加新的target_object_position
,所以object2_position
后面会加一句。
@configclass
class ObservationsCfg:
"""Observation specifications for the MDP."""
@configclass
class PolicyCfg(ObsGroup):
"""Observations for policy group."""
joint_pos = ObsTerm(func=mdp.joint_pos_rel)
joint_vel = ObsTerm(func=mdp.joint_vel_rel)
object_position = ObsTerm(func=mdp.object_position_in_robot_root_frame)
target1_object1_position = ObsTerm(func=mdp.generated_commands, params={"command_name": "object_pose"})
# Add object2 position in robot root frame
object2_position = ObsTerm(func=mdp.object2_position_in_robot_root_frame)
target2_object2_position = ObsTerm(func=mdp.generated_commands, params={"command_name": "object2_pose"})
actions = ObsTerm(func=mdp.last_action)
def __post_init__(self):
self.enable_corruption = True
self.concatenate_terms = True
# observation groups
policy: PolicyCfg = PolicyCfg()
当然这里使用的是我个人的一种情况举例,只是为了告诉老铁们如果添加了新的目标到环境里,不要忘了把他加到观察空间中哦!
3. 把body_name的名字传进去
事情是这样的,让我们回过头去看目标命令类的代码CommandsCfg
@configclass
class CommandsCfg:
"""Command terms for the MDP."""
object_pose = mdp.UniformPoseCommandCfg(
asset_name="robot",
body_name=MISSING, # will be set by agent env cfg
resampling_time_range=(5.0, 5.0),
debug_vis=True,
ranges=mdp.UniformPoseCommandCfg.Ranges(
pos_x=(0.3, 0.7), pos_y=(-0.3, 0.3), pos_z=(0.0, 0.0), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0)
),
)
object2_pose = mdp.UniformPoseCommandCfg(
asset_name="robot",
body_name=MISSING, # will be set by agent env cfg
resampling_time_range=(5.0, 5.0),
debug_vis=True,
ranges=mdp.UniformPoseCommandCfg.Ranges(
pos_x=(0.3, 0.7), pos_y=(-0.3, 0.3), pos_z=(0.0, 0.0), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0)
),
)
他的body_name属性是没有(Missing)的,他的注释后面说 will be set by agent env cfg,会被agent的环境配置传进来,这就神奇了。
众所周知,agent的环境配置在这个文件夹下,以lift任务为例
打开我们想更改的配置文件,我们能看到这样的代码
@configclass
class Franka2CubePushEnvCfg(Push2EnvCfg):
def __post_init__(self):
# post init of parent
super().__post_init__()
# Set Franka as robot
self.scene.robot = FRANKA_PANDA_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
# Set actions for the specific robot type (franka)
self.actions.body_joint_pos = mdp.JointPositionActionCfg(
asset_name="robot", joint_names=["panda_joint.*"], scale=0.5, use_default_offset=True
)
self.actions.finger_joint_pos = mdp.BinaryJointPositionActionCfg(
asset_name="robot",
joint_names=["panda_finger.*"],
open_command_expr={"panda_finger_.*": 0.04},
close_command_expr={"panda_finger_.*": 0.0},
)
# Set the body name for the end effector
self.commands.object_pose.body_name = "panda_hand"
可以看到是在最后一行,他把panda_hand
的名字传进来了, 所以我们要为新的目标命令也把名字传过去,修改后的代码会像
@configclass
class Franka2CubePushEnvCfg(Push2EnvCfg):
def __post_init__(self):
# post init of parent
super().__post_init__()
# Set Franka as robot
self.scene.robot = FRANKA_PANDA_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
# Set actions for the specific robot type (franka)
self.actions.body_joint_pos = mdp.JointPositionActionCfg(
asset_name="robot", joint_names=["panda_joint.*"], scale=0.5, use_default_offset=True
)
self.actions.finger_joint_pos = mdp.BinaryJointPositionActionCfg(
asset_name="robot",
joint_names=["panda_finger.*"],
open_command_expr={"panda_finger_.*": 0.04},
close_command_expr={"panda_finger_.*": 0.0},
)
# Set the body name for the end effector
self.commands.object_pose.body_name = "panda_hand"
self.commands.object2_pose.body_name = "panda_hand"
4. 设计新的奖励函数
这一步就说不明白了,因为大家搓出来的任务都不大一样。但终归我们加了新的目标,是为了做新的强化学习训练的,那就又得为新的目标更改新的奖励函数。
但是通过上面的步骤,新的目标标记会出现在环境中就是这样
非常的有品
以上