Reward 移植¶
reward 项是大多数移植 bug 藏身之处。本食谱记录了常见的 reward 项及其 UniLab 惯用写法。
模式:线性 / 二次跟踪误差¶
# Legged Gym
def _reward_tracking_lin_vel(self):
err = torch.sum(torch.square(self.commands[:, :2] - self.base_lin_vel[:, :2]), dim=1)
return torch.exp(-err / self.cfg.rewards.tracking_sigma)
# UniLab
def reward_tracking_lin_vel(self, state):
err = np.sum((state.commands[:, :2] - state.base_lin_vel[:, :2]) ** 2, axis=1)
return np.exp(-err / self.cfg.tracking_sigma)
注意:
UniLab 的 reward 项在一个
state批次上运算(CPU 上的 NumPy);没有 逐 env 循环,也没有torch。返回逐 env 的标量 reward(形状为
(n_envs,))。
模式:接触条件奖励¶
def reward_feet_air_time(self, state):
contact = state.foot_contact # bool, (n_envs, n_feet)
air_time = state.last_air_time # float, (n_envs, n_feet)
first_contact = contact & ~state.prev_contact
reward = (air_time - self.cfg.air_time_threshold) * first_contact
return reward.sum(axis=1)
注意:
UniLab 的
state携带了prev_contact,因此你无需自己管理边沿检测。参见unilab.envs.locomotion.common.rewards。
模式:动作平滑惩罚¶
def reward_action_rate(self, state):
return -np.sum((state.action - state.prev_action) ** 2, axis=1)
它已经是 unilab.envs.locomotion.common.rewards 中的现成辅助函数。
模式:姿态惩罚¶
def reward_dof_pos_limits(self, state):
lower = self.cfg.dof_pos_lower
upper = self.cfg.dof_pos_upper
deviation = (
np.maximum(0, lower - state.dof_pos) +
np.maximum(0, state.dof_pos - upper)
)
return -np.sum(deviation, axis=1)
终止处理¶
UniLab 把终止信号与终止惩罚分离开。env 的 terminations() 返回一个
布尔掩码;reward registry 可以包含一个消费它的 termination_penalty 项。
def reward_termination(self, state):
return -state.termination.astype(np.float32) * self.cfg.termination_penalty
另请参阅¶
unilab.training.rewardunilab.envs.locomotion.common.rewards