1. 代码引用
相关代码来源于 legged_gym 框架。
#------------ reward functions----------------
def _reward_lin_vel_z(self):
# Penalize z axis base linear velocity
return torch.square(self.base_lin_vel[:, 2])
def _reward_ang_vel_xy(self):
# Penalize xy axes base angular velocity
return torch.sum(torch.square(self.base_ang_vel[:, :2]), dim=1)
def _reward_orientation(self):
# Penalize non flat base orientation
return torch.sum(torch.square(self.projected_gravity[:, :2]), dim=1)
def _reward_base_height(self):
# Penalize base height away from target
base_height = torch.mean(self.root_states[:, 2].unsqueeze(1) - self.measured_heights, dim=1)
return torch.square(base_height - self.cfg.rewards.base_height_target)
def _reward_torques(self):
# Penalize torques
return torch.sum(torch.square(self.torques), dim=1)
def _reward_dof_vel(self):
# Penalize dof velocities
return torch.sum(torch.square(self.dof_vel), dim=1)
def _reward_dof_acc(self):
# Penalize dof accelerations
return torch.sum(torch.square((self.last_dof_vel - self.dof_vel) / self.dt), dim=1)
def _reward_action_rate(self):
# Penalize changes in actions
return torch.sum(torch.square(self.last_actions - self.actions), dim=1)
def _reward_collision(self):
# Penalize collisions on selected bodies
return torch.sum(1.*(torch.norm(self.contact_forces[:, self.penalised_contact_indices, :], dim=-1) > 0.1), dim=1)
def _reward_termination(self):
# Terminal reward / penalty
return self.reset_buf * ~self.time_out_buf
def _reward_dof_pos_limits(self):
# Penalize dof positions too close to the limit
out_of_limits = -(self.dof_pos - self.dof_pos_limits[:, 0]).clip(max=0.) # lower limit
out_of_limits += (self.dof_pos - self.dof_pos_limits[:, 1]).clip(min=0.)
return torch.sum(out_of_limits, dim=1)
def _reward_dof_vel_limits(self):
# Penalize dof velocities too close to the limit
# clip to max error = 1 rad/s per joint to avoid huge penalties
return torch.sum((torch.abs(self.dof_vel) - self.dof_vel_limits*self.cfg.rewards.soft_dof_vel_limit).clip(min=0., max=1.), dim=1)
def _reward_torque_limits(self):
# penalize torques too close to the limit
return torch.sum((torch.abs(self.torques) - self.torque_limits*self.cfg.rewards.soft_torque_limit).clip(min=0.), dim=1)
def _reward_tracking_lin_vel(self):
# Tracking of linear velocity commands (xy axes)
lin_vel_error = torch.sum(torch.square(self.commands[:, :2] - self.base_lin_vel[:, :2]), dim=1)
return torch.exp(-lin_vel_error/self.cfg.rewards.tracking_sigma)
def _reward_tracking_ang_vel(self):
# Tracking of angular velocity commands (yaw)
ang_vel_error = torch.square(self.commands[:, 2] - self.base_ang_vel[:, 2])
return torch.exp(-ang_vel_error/self.cfg.rewards.tracking_sigma)
def _reward_feet_air_time(self):
# Reward long steps
# Need to filter the contacts because the contact reporting of PhysX is unreliable on meshes
contact = self.contact_forces[:, self.feet_indices, 2] > 1.
contact_filt = torch.logical_or(contact, self.last_contacts)
self.last_contacts = contact
first_contact = (self.feet_air_time > 0.) * contact_filt
self.feet_air_time += self.dt
rew_airTime = torch.sum((self.feet_air_time - 0.5) * first_contact, dim=1) # reward only on first contact with the ground
rew_airTime *= torch.norm(self.commands[:, :2], dim=1) > 0.1 #no reward for zero command
self.feet_air_time *= ~contact_filt
return rew_airTime
def _reward_stumble(self):
# Penalize feet hitting vertical surfaces
return torch.any(torch.norm(self.contact_forces[:, self.feet_indices, :2], dim=2) >\
5 *torch.abs(self.contact_forces[:, self.feet_indices, 2]), dim=1)
def _reward_stand_still(self):
# Penalize motion at zero commands
return torch.sum(torch.abs(self.dof_pos - self.default_dof_pos), dim=1) * (torch.norm(self.commands[:, :2], dim=1) < 0.1)
def _reward_feet_contact_forces(self):
# penalize high contact forces
return torch.sum((torch.norm(self.contact_forces[:, self.feet_indices, :], dim=-1) - self.cfg.rewards.max_contact_force).clip(min=0.), dim=1)
2. 奖励函数的数学建模与详细解析
在机器人强化学习(RL)任务中,奖励函数的设计通常涵盖三个关键方面:任务追踪(Tracking)、正则化或惩罚项(Regularization/Penalties),以及步态风格控制(Gait/Style)。以下是对代码中各项奖励机制的数学表达及其物理意义的系统分析。
2.1 核心任务追踪奖励(Tracking Rewards)
此类奖励采用高斯核函数形式,目的在于提升机器人对目标指令的跟随精度。当实际状态与期望状态一致时,奖励值达到最大(即为1)。
| 函数名称 | 数学表达式(Reward) | 物理含义 |
|---|---|---|
| 线速度追踪 | rt = exp(|vxycmd vxybase| / σtrack) | 衡量机器人基座在水平面内实际速度与指令速度之间的偏差。σ 为平滑参数,误差越小奖励越高。 |
_reward_tracking_lin_vel
| 函数名称 | 数学表达式(Reward) | 物理含义 |
|---|---|---|
| 角速度追踪 | rt = exp((ωzcmd ωzbase) / σtrack) | 鼓励机器人准确实现指定的偏航角速度(Yaw Rate),用于精确转向控制。 |
_reward_tracking_ang_vel
2.2 正则化与惩罚项(Penalties & Regularization)
这些项多以 L2 范数(平方和)形式出现,在总奖励计算中被赋予负权重,作为代价项使用,用以约束能耗、保持稳定性和动作平顺性。
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 垂直速度限制 | pt = (vbasez) | 抑制机器人底座在垂直方向上的剧烈震荡,增强运动平稳性。 |
_reward_lin_vel_z
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 横滚与俯仰抑制 | pt = (ωbasex) + (ωbasey) | 防止躯干过度倾斜,维持身体平衡,避免翻倒风险。 |
_reward_ang_vel_xy
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 姿态平衡控制 | pt = |gxyproj| | 确保重力向量在机体坐标系下的 xy 分量趋近于零,表示机器人保持竖直姿态。 |
_reward_orientation
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 力矩最小化 | pt = Σ τi | 降低关节驱动力矩总和,减少能量消耗并防止电机过热。 |
_reward_torques
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 关节速度阻尼 | pt = Σ (qi) | 限制关节运动速率,提高系统动态稳定性。 |
_reward_dof_vel
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 动作平滑性约束 | pt = Σ (at,i at1,i) | 惩罚控制信号的突变,减少执行器抖动,延长硬件寿命。 |
_reward_action_rate
| 函数名称 | 数学表达式(Penalty/Cost) | 物理含义 |
|---|---|---|
| 碰撞检测惩罚 | pt = Σ (|Fcontact| > 0.1) | 若非足部区域接触环境表面,则施加惩罚,防止异常支撑行为。 |
_reward_collision
2.3 安全软约束(Soft Limits)
此类项用于处理物理系统的边界限制,常采用单边铰链损失(Hinge Loss)形式:
pt = Σ clip(|x| xlimit, min=0)
当状态变量 x(如关节角度、速度或力矩)超出预设的安全阈值 xlimit 时,开始施加惩罚,从而实现软性限幅保护。
2.4 步态塑形机制(Gait Shaping)
该部分奖励设计用于引导特定步行模式:
- 鼓励脚部在摆动阶段停留更长时间,实现大步幅行走;仅在脚掌触地瞬间给予正向反馈。
_reward_feet_air_time
- 当速度指令接近零时,若关节偏离默认站立位置,则施加惩罚,迫使机器人保持静止直立姿态。
_reward_stand_still
3. 奖励函数在 PPO 算法中的作用机制
PPO(Proximal Policy Optimization)是一种基于 Actor-Critic 架构的强化学习算法。在整个训练过程中,奖励函数充当“指挥官”角色,直接影响策略更新的方向与效率。
3.1 总奖励的构建方式
在每个时间步 t,所有子项奖励与惩罚项经过加权求和后得到总体奖励值:
Rtotal = Σ wi · ri + Σ cj · pj
其中 wi 和 cj 分别为各奖励项与惩罚项的可调权重系数,用于平衡不同目标之间的优先级。
在强化学习策略优化中,总奖励的计算方式如下:
rtotal, t = ∑k wk rk, t
其中权重 wk 的正负性决定了其作用方向:
- wk > 0:用于 Tracking 和 Gait 等正向行为奖励,鼓励智能体执行特定动作。
- wk < 0:对应各类惩罚项(Penalties),抑制不期望的行为表现。
3.2 数据流向分析
total_reward
在PPO算法框架中,上述奖励结构通过以下三个关键阶段影响最终策略输出:
价值网络更新(Critic Update)
价值网络 V(s) 的目标是预测状态 s 下未来累积回报。该网络通过最小化均方误差进行参数更新:
Lcritic = t[(V(st) Rt)]
其中 Rt 是基于 rtotal 计算出的真实回报序列。
优势函数估计(Advantage Estimation)
采用广义优势估计(Generalized Advantage Estimation, GAE)方法计算优势值 t:
t = δt + (γλ)δt+1 + …
其中 δt = rtotal,t + γV(st+1) V(st)。
关键机制:rtotal 直接决定 δt 的符号与大小。当 rtotal,t 较高时,优势值 t 倾向于正值,表示当前动作优于平均策略水平。
策略网络更新(Actor Update)
策略网络 πθ 的更新遵循如下梯度方向:
θ ← θ + αθ [ min(rt(θ)t, clip(…)t) ]
具体行为表现为:
- 若 t > 0(即综合奖励较高),PPO 将提升该动作被选择的概率;
- 若 t < 0(奖励较低或惩罚较重),则降低该动作的发生概率。
4. 数学形式深度解析:平方函数 vs. 指数函数
从实现代码可观察到,所有奖励项主要采用两种数学表达形式——平方项(Square)与指数项(Exp)。这种设计已成为现代机器人控制任务中的标准实践。
4.1 形式对比
| 特性 | 平方形式(Square) | 指数/高斯形式(Exp) |
|---|---|---|
| 典型表达式 | f(x) = x | f(x) = exp(x / σ) |
| 代码体现 | |
|
| 主要用途 | 惩罚项(Penalties) | 任务相关奖励(Rewards) |
| 值域范围 | [0, +∞) | (0, 1] |
| 梯度特性 | = 2x(随误差线性增长) | ∝ x ex(先上升后下降) |
4.2 设计动因分析:为何任务项偏好指数形式?
如代码所示,
_reward_tracking_... 中采用了指数形式,相较于平方形式具有多项优势:
有界性与归一化能力
指数函数将输出奖励限制在 (0,1] 区间内,避免了单一任务因误差过大(如速度偏差剧烈)而导致奖励值异常膨胀,从而防止其主导整体奖励信号,干扰其他辅助目标的学习过程。
数值稳定性强
若将平方函数作为奖励项(尤其是负距离形式),当智能体严重失控时,误差可能趋于无穷,导致损失函数爆炸,引发梯度剧烈波动。由于PPO属于on-policy算法,此类不稳定更新会直接破坏策略网络。而使用指数形式时,即使误差极大,奖励趋近于0,梯度也随之衰减至接近零,使网络自动“忽略”极端不良样本,避免被误导。
核宽度可调节(σ 参数)
通过调整 σ 参数,可以灵活控制奖励响应的敏感区间。较大的 σ 允许更大误差仍获得可观奖励,适合初期探索;较小的 σ 则要求更高精度,适用于精细控制阶段。这一可调性增强了奖励函数对不同训练阶段的适应能力。
σ 越小,表示对动作精度的要求越高,能够更直观地界定“什么是好的动作”。
在代码实现中,常采用 Square(平方)作为惩罚项,例如图示中的
_reward_torques。其主要原因包括:
强约束力
Square 函数属于凸函数,其梯度随着误差的增大呈线性增长。这意味着偏差越大,所受到的惩罚也越强,从而形成更强的优化驱动力。
明确的优化方向
针对力矩、关节速度等物理变量,通常希望它们尽可能趋近于零。Square 函数在零点附近具有良好的导数特性,能有效引导优化过程向目标靠近。
tracking_sigma
4.3 结论
使用 Square 更适用于描述“绝对不应发生的行为”,如软约束或能耗最小化问题,因为它能提供随误差增大而不断增强、无上限的惩罚信号。
而 Exp(指数)形式则更适合表达“应尽量优化达成的目标”,比如轨迹跟踪任务。它能生成数值稳定且归一化的优化目标,有效避免梯度爆炸问题。


雷达卡


京公网安备 11010802022788号







