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)
此类奖励采用 高斯核(Gaussian Kernel) 形式,旨在最大化机器人对指令的跟随精度。
| 函数名 | 数学表达式 (Reward) | 物理含义 |
|---|---|---|
_reward_tracking_lin_vel | rt=exp(−∣vcmdxy−vbasexy∣2σtrack)r_t = \exp\left(-\frac{| \mathbf{v}_{cmd}^{xy} - \mathbf{v}_{base}^{xy} |^2}{\sigma_{track}}\right)rt=exp(−σtrack∣vcmdxy−vbasexy∣2) | 线速度追踪。vcmdxy\mathbf{v}_{cmd}^{xy}vcmdxy 为指令速度,σ\sigmaσ 为带宽参数。当误差为 0 时奖励为 1。 |
_reward_tracking_ang_vel | rt=exp(−(ωcmdz−ωbasez)2σtrack)r_t = \exp\left(-\frac{(\omega_{cmd}^{z} - \omega_{base}^{z})^2}{\sigma_{track}}\right)rt=exp(−σtrack(ωcmdz−ωbasez)2) | 角速度追踪。鼓励机器人按照给定的偏航角速度(Yaw)转向。 |
2.2 惩罚与正则化项 (Penalties & Regularization)
此类通常采用 L2 范数(平方和) 形式,在总奖励计算中通常会被赋予负权重,作为 Cost/Penalty 使用,用于约束能量和保持稳定。
| 函数名 | 数学表达式 (Penalty/Cost) | 物理含义 |
|---|---|---|
_reward_lin_vel_z | pt=(vzbase)2p_t = (v_z^{base})^2pt=(vzbase)2 | 限制垂直速度。防止机器人底座上下剧烈震荡。 |
_reward_ang_vel_xy | pt=(ωxbase)2+(ωybase)2p_t = (\omega_x^{base})^2 + (\omega_y^{base})^2pt=(ωxbase)2+(ωybase)2 | 限制横滚/俯仰。保持躯干水平,防止翻车。 |
_reward_orientation | pt=∣gprojxy∣2p_t = | \mathbf{g}_{proj}^{xy} |^2pt=∣gprojxy∣2 | 姿态平衡。重力向量在体坐标系下的 xy 分量应为 0(即重力应垂直向下)。 |
_reward_torques | pt=∑iτi2p_t = \sum_{i} \tau_i^2pt=i∑τi2 | 最小化力矩。降低能耗,防止电机过热,鼓励柔顺动作。 |
_reward_dof_vel | pt=∑iq˙i2p_t = \sum_{i} \dot{q}_i^2pt=i∑q˙i2 | 关节速度阻尼。防止动作过快,增加系统稳定性。 |
_reward_action_rate | pt=∑i(at,i−at−1,i)2p_t = \sum_{i} (a_{t,i} - a_{t-1,i})^2pt=i∑(at,i−at−1,i)2 | 动作平滑。惩罚控制信号的高频抖动,保护执行器。 |
_reward_collision | pt=∑I(∣Fcontact∣>0.1)p_t = \sum \mathbb{I}(|F_{contact}| > 0.1)pt=∑I(∣Fcontact∣>0.1) | 碰撞惩罚。非足部位置接触环境时给予惩罚。 |
2.3 约束与安全限制 (Soft Limits)
用于处理物理限制的软约束,形式通常为单边损失(Hinge Loss)。
- 关节位置/速度/力矩限制:
pt=∑clip(∣x∣−xlimit,min=0)p_t = \sum \text{clip}(|x| - x_{limit}, \min=0)pt=∑clip(∣x∣−xlimit,min=0)
当状态 xxx 超过设定的安全阈值 xlimitx_{limit}xlimit 时,开始计算惩罚。
2.4 步态塑形 (Gait Shaping)
_reward_feet_air_time: 鼓励脚在空中停留更长时间(迈大步),仅在脚触地瞬间给予奖励。_reward_stand_still: 当速度指令极小时,惩罚关节偏离默认位置,强制机器人站立不动。
3. 奖励函数在 PPO 算法中的作用机制
PPO (Proximal Policy Optimization) 是一种 Actor-Critic 架构算法。奖励函数是整个学习过程的指挥棒。
3.1 Total Reward 的计算
在每一个时间步 ttt,各个子奖励项被加权求和:
rtotal,t=∑kwk⋅rk,tr_{total, t} = \sum_{k} w_k \cdot r_{k, t}rtotal,t=k∑wk⋅rk,t
- wk>0w_k > 0wk>0: 用于 Tracking 和 Gait 奖励(鼓励行为)。
- wk<0w_k < 0wk<0: 用于 Penalties(抑制行为)。
3.2 数据流向分析
total_reward 在 PPO 中通过以下路径影响最终策略:
-
价值估计 (Critic Update):
Critic 网络 Vϕ(s)V_\phi(s)Vϕ(s) 学习预测未来的累积回报(Return)。它通过最小化以下损失函数来更新:
Lcritic=Et[(Vϕ(st)−Rt)2]L_{critic} = \mathbb{E}_t \left[ (V_\phi(s_t) - R_t)^2 \right]Lcritic=Et[(Vϕ(st)−Rt)2]
其中 RtR_tRt 是由 rtotalr_{total}rtotal 计算出的真实回报。 -
优势函数计算 (Advantage Estimation):
算法利用 Generalized Advantage Estimation (GAE) 计算优势 A^t\hat{A}_tA^t:
A^t=δt+(γλ)δt+1+…\hat{A}_t = \delta_t + (\gamma \lambda)\delta_{t+1} + \dotsA^t=δt+(γλ)δt+1+…
其中 δt=rtotal,t+γV(st+1)−V(st)\delta_t = r_{total, t} + \gamma V(s_{t+1}) - V(s_t)δt=rtotal,t+γV(st+1)−V(st)。- 关键点:rtotalr_{total}rtotal 直接决定了 δt\delta_tδt 的正负。如果 rtotalr_{total}rtotal 很高,A^t\hat{A}_tA^t 为正,表示当前动作优于平均水平。
-
策略更新 (Actor Update):
Actor 网络 πθ\pi_\thetaπθ 的更新目标是最大化优势:
θ←θ+α∇θ(min(rt(θ)A^t,clip(… )A^t))\theta \leftarrow \theta + \alpha \nabla_\theta \left( \min(r_t(\theta)\hat{A}_t, \text{clip}(\dots)\hat{A}_t) \right)θ←θ+α∇θ(min(rt(θ)A^t,clip(…)A^t))- 若 A^t>0\hat{A}_t > 0A^t>0(奖励高),PPO 增大该动作的概率。
- 若 A^t<0\hat{A}_t < 0A^t<0(奖励低/惩罚高),PPO 减小该动作的概率。
4. 数学特性深度分析:Square vs. Exp
通过分析代码,我们发现所有的奖励项主要归为两类数学形式:平方项 (Square) 和 指数项 (Exp)。这种设计是现代机器人控制领域的标准范式。
4.1 形式对比
| 特性 | Square (平方形式) | Exp (指数/高斯形式) |
|---|---|---|
| 典型式子 | f(x)=x2f(x) = x^2f(x)=x2 | f(x)=exp(−x2/σ)f(x) = \exp(-x^2 / \sigma)f(x)=exp(−x2/σ) |
| 代码体现 | torch.square(...) | torch.exp(...) |
| 主要用途 | 惩罚项 (Penalties) | 任务奖励 (Rewards) |
| 值域 | [0,+∞)[0, +\infty)[0,+∞) | (0,1](0, 1](0,1] |
| 梯度特性 | ∇=2x\nabla = 2x∇=2x (随误差线性增大) | ∇∝x⋅e−x2\nabla \propto x \cdot e^{-x^2}∇∝x⋅e−x2 (先增后减) |
4.2 为什么这样设计?(优劣势分析)
A. 为什么任务项使用 Exp (指数)?
代码中的 _reward_tracking_... 使用了 Exp,这被认为是优于 Square 的选择,原因如下:
- 有界性与归一化 (Boundedness): Exp 函数将奖励限制在 [0,1][0, 1][0,1] 之间。这防止了特定任务的奖励数值过大(例如速度误差极大时),从而掩盖了其他辅助奖励的作用。
- 数值稳定性 (Stability):
- 若使用 Square 作为奖励(负距离),当机器人完全失控时,误差可能无穷大,导致 LossLossLoss 爆炸,梯度更新过猛,由于 PPO 是 On-policy 算法,这会直接破坏策略网络。
- 使用 Exp,当误差极大时,奖励趋近于 0,梯度也趋近于 0。这意味着网络会“忽略”那些极其糟糕的样本,而不是被其误导。
- 核宽可调 (σ\sigmaσ): 通过调节
tracking_sigma,可以直观地定义“什么是好的动作”。σ\sigmaσ 越小,对精度的要求越高。
B. 为什么惩罚项使用 Square (平方)?
代码中的 _reward_torques 等使用 Square,原因如下:
- 强约束力: Square 是凸函数,且其梯度随误差增大而线性增大。这意味着违规越严重,惩罚力度越狠。
- 明确的优化方向: 对于力矩、关节速度等物理量,我们的目标是将其压得越低越好(接近0),Square 函数在 0 点附近有良好的导数性质,能有效地引导优化器。
4.3 结论
- Square 适合表达 “绝对不应该做的事”(软约束、能耗最小化),因为它提供无上限的惩罚信号。
- Exp 适合表达 “尽量做好的事”(目标追踪),因为它提供了数值稳定的、归一化的优化目标,避免了梯度爆炸问题。
888

被折叠的 条评论
为什么被折叠?



