楼主: zjj1995
118 0

[其他] 强化学习人形机器人奖励函数分析 [推广有奖]

  • 0关注
  • 0粉丝

学前班

80%

还不是VIP/贵宾

-

威望
0
论坛币
10 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
30 点
帖子
2
精华
0
在线时间
0 小时
注册时间
2018-8-16
最后登录
2018-8-16

楼主
zjj1995 发表于 2025-11-24 14:50:05 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

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 / σ)
代码体现
torch.square(...)
torch.exp(...)
主要用途 惩罚项(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(指数)形式则更适合表达“应尽量优化达成的目标”,比如轨迹跟踪任务。它能生成数值稳定且归一化的优化目标,有效避免梯度爆炸问题。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:人形机器人 函数分析 机器人 Optimization Acceleration

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-5 18:05