【MDP】奖励函数解构学习
阅读说明
本文是笔者基于特定课程、项目代码与个人学习过程整理的工作笔记。部分论断可能不完整、过时或依赖特定版本,请结合原始论文、官方文档及实际源码独立核验。
参考项目
本笔记参考项目:SPIRAL-EDWIN/JC_umi-on-tron
本文侧重从奖励函数实现与奖励融合机制的角度拆解 RFM。若希望结合完整的训练部署链路与实际调参经验理解其工程落地,可对照阅读 【组会分享】RFM/调参;两篇笔记分别对应机制分析与实践复盘,可以结合阅读。
说明¶
- 本文件定义了 EE_pose 任务的奖励/惩罚函数(reward terms)。
- 这些函数会在配置文件中的 RewardsCfg 里通过 RewTerm(func=...) 被调用并乘以对应权重。
- 本文件只负责“计算每一项 reward 的原始值”,最终总奖励由 RewardManager 做加权求和。
-
常见缩写:
- EE: End-Effector,末端执行器
-
SE3: 位姿空间(位置 + 朝向)
-
std: 容忍尺度,数学公式中记作 \(\sigma\);越小越严格(同样误差下 reward 会更低) -
_loco_mani_scale: locomotion/manipulation混合因子,数学公式中记作 \(L(t)\);\(L\to0\) 偏mani,\(L\to1\) 偏loco
-
张量约定:
- 第一维通常是并行环境数 num_envs
- 函数返回 shape 一般为
(num_envs,),表示每个并行env一个标量 reward
运行时三层关系¶
- 本任务在运行时可分为三层:
- 实现层:mdp目录中定义的每个函数如何计算
- 配置层:在
env_cfg中声明actions、commands、rewards、curriculum等项 - 管理器层:由框架的 ActionManager、CommandManager、RewardManager、CurriculumManager、ObservationManager在每个env.step中按顺序调度执行
具体的Task确定具体的配置与 RewardsCfg¶
-
根据要训练的task(task的确定可以参考仿真框架的初步学习显示的
__init__.py文件),可以得到对应的环境配置文件(通过查看"env_cfg_entry_point": ...)

-
进入例如
sf_tron1_arm_env_cfg文件后,找到
这一块代码就是这个任务下奖励函数的配置层
RewardsCfg 和 rewards.py 的关系是什么
RewardsCfg是配置层,供RewardManager查看,决定该task要使用rewards.py中的哪些奖励项,每项权重多少,每项传哪些参数、哪些用默认值rewards.py是实现层,定义每个奖励项具体怎么算(每个奖励项需要哪些参数,这些参数的默认值定义)- 如
safety_reward_exp的计算公式定义等
- 如
他们的关系可以写成:
\[R_t=\sum_{i\in\mathcal I}\omega_i r_i(t)\]
其中:
- \(r_i\) 来自
rewards.py,是具体的奖励函数定义,包括env确定和传参需求确定 - \(\omega_i\) 和 \(params_i\) 来自
RewardsCfg
例如对 safety_reward_exp 的理解:【MDP】奖励函数解构学习
本项目中的 RFM (Reward Fusion Module, 奖励融合机制)¶
这里需要和
commands.py联动理解;并且该项目中的RFM和SUSTech的RFM有一些不同,注意区分
两个基础EE位姿误差:position_error (\(e_{\mathrm{P}}\)) & orientation_error (\(e_{\mathrm{R}}\))¶
这两个误差不是由每个奖励函数重复计算的,而是由
commands.py中的_update_metrics()在每个决策步统一更新,并存入metrics,随后供各个奖励函数读取。
记世界坐标系下的target位姿为 \((\boldsymbol p_{\mathrm{target}}^{\mathrm W},\boldsymbol R_{\mathrm{target}}^{\mathrm W})\),当前EE位姿为 \((\boldsymbol p_{\mathrm{EE}}^{\mathrm W},\boldsymbol R_{\mathrm{EE}}^{\mathrm W})\)。
位置误差 position_error (\(e_{\mathrm{P}}\))¶
-
position_error是target与当前EE之间的三维欧氏距离:\[e_{\mathrm{P}}=\left\|\boldsymbol p_{\mathrm{target}}^{\mathrm W}-\boldsymbol p_{\mathrm{EE}}^{\mathrm W}\right\|_2\]
-
\(e_{\mathrm{P}}\geq0\),单位为m
-
它同时包含x、y、z三个方向的误差,只表示距离大小,不保留误差方向
-
\(e_{\mathrm{P}}=0\) 表示EE的位置与target完全重合
-
朝向误差 orientation_error (\(e_{\mathrm{R}}\))¶
-
orientation_error是当前EE朝向与target朝向之间的最小相对旋转角。代码首先计算相对旋转矩阵:\[\boldsymbol R_{\mathrm{rel}}=(\boldsymbol R_{\mathrm{target}}^{\mathrm W})^{\mathrm T}\boldsymbol R_{\mathrm{EE}}^{\mathrm W}=(\boldsymbol R_{\mathrm{target}}^{\mathrm W})^{-1}\boldsymbol R_{\mathrm{EE}}^{\mathrm W}\]
- 直观上可以理解为两步:
- \((R_{\mathrm{target}}^{\mathrm W})^{-1}\):先消除target相对于世界坐标系的旋转;
- 再乘 \(R_{\mathrm{EE}}^{\mathrm W}\):得到EE相对于target还差多少旋转。
- 直观上可以理解为两步:
-
再根据相对旋转矩阵的迹得到旋转角:
\[e_{\mathrm{R}}=\arccos\left(\operatorname{clamp}\left(\frac{\operatorname{tr}(\boldsymbol R_{\mathrm{rel}})-1}{2},-1,1\right)\right)\]
-
\(e_{\mathrm{R}}\in[0,\pi]\),单位为rad
-
它表示两个frame之间总共相差多少角度,而不是分别计算Roll、Pitch、Yaw的差值
-
\(e_{\mathrm{R}}=0\) 表示EE与target的朝向完全一致
-
朝向误差公式如何理解
- 根据欧拉旋转定理,任意两个三维朝向之间的差异,都可以等效表示为:绕某一根旋转轴转过角度 \(\theta\)。这种表示方式称为轴角表示(Axis–Angle Representation)。
-
相对旋转矩阵为:
\[\boldsymbol R_{\mathrm{rel}}=(\boldsymbol R_{\mathrm{target}}^{\mathrm W})^{\mathrm T} \boldsymbol R_{\mathrm{EE}}^{\mathrm W}\]- 它表示从target frame旋转到当前EE frame,还需要进行怎样的旋转
- 若两个frame朝向完全相同,则 \(\boldsymbol R_{\mathrm{rel}}=\boldsymbol I\)
-
对于三维旋转矩阵,其迹和旋转角满足:
\[\operatorname{tr}(\boldsymbol R_{\mathrm{rel}})=1+2\cos\theta\]
因此可以反推出两个frame之间的最短旋转角:
\[e_{\mathrm{R}}=\theta=\arccos\left(\operatorname{clamp}\left( \frac{\operatorname{tr}(\boldsymbol R_{\mathrm{rel}})-1}{2}, -1,1 \right)\right)\]
其中:
- \(\operatorname{tr}(\boldsymbol R_{\mathrm{rel}})\) 表示相对旋转矩阵主对角线三个元素之和
- \(\arccos\) 是余弦函数的反函数,用于根据 \(\cos\theta\) 还原旋转角 \(\theta\)
clamp(...,-1,1)用于避免浮点误差使输入略微超出 \(\arccos\) 的有效范围 \([-1,1]\)
这里的EE pose对应配置项 body_name 指定的刚体坐标系,而不一定是夹爪TCP
本笔记只讨论 SF 配置。该配置使用 body_name="eef_link",因此这里计算的是 eef_link frame 与 target 之间的位姿误差。
对 safety_reward_exp 安全奖励的理解¶
“safety”:该奖励鼓励“安全姿态和安全运动”
“exp”:把误差通过指数函数做成平滑、有界的奖励
-
在配置文件的
RewardsCfg中,可以得到奖励函数对safety_reward_exp该项奖励的权重和参数分配:- 如图显示:权重weight=1.0;其中参数
base_height_target=0.8,std=sqrt(0.5)而非默认值
- 如图显示:权重weight=1.0;其中参数
-
对于
safety_reward_exp函数本体,在rewards.py中:- 这个函数先构造了两类安全误差:
-
然后把上述两个安全误差(这里统称为 \(E\) )通过指数函数映射成原始安全尺度 \(S\):
\[S=\exp\left(-\frac{E}{\sigma^2}\right)\]
直观理解:
- \(E=0\)时,安全尺度为1(最好)
- \(E\)变大时,安全尺度快速衰减到接近0
-
\(\sigma\)越小,衰减越快(越严格)
-
将归一化后的manipulation safety error和locomotion safety error分别记作 \(E_{\mathrm{mani}}(t)\) 和 \(E_{\mathrm{loco}}(t)\),对应的原始安全尺度为:
\[S_{\mathrm{mani}}(t)=\exp\left(-\frac{E_{\mathrm{mani}}(t)}{\sigma^2}\right),\qquad S_{\mathrm{loco}}(t)=\exp\left(-\frac{E_{\mathrm{loco}}(t)}{\sigma^2}\right)\]
-
\(S_{\mathrm{mani}}(t),S_{\mathrm{loco}}(t)\in(0,1]\);安全误差越小,对应的原始安全尺度越接近1
-
代码传给其他reward使用的缓存值在原始安全尺度上增加了0.4:
_mani_safety_scale对应\(S_{\mathrm{mani}}(t)+0.4\),_loco_safety_scale对应\(S_{\mathrm{loco}}(t)+0.4\)safety_reward_exp本身使用原始安全尺度,并通过阶段门控_loco_mani_scale(\(L\)) 加权计算:
\[r_{\mathrm{safety}}(t)=S_{\mathrm{mani}}(t)\cdot(1-L(t))+S_{\mathrm{loco}}(t)\cdot L(t)\]
- 从这个加权公式可以看出来:门控\(L(t)\to1\)时,奖励函数更看重loco(足/底盘的稳定性);\(L(t)\to0\)时,奖励函数更看重mani(EE操作的安全性/稳定性)
为什么安全尺度缓存值需要增加0.4
如果其他task reward直接乘原始安全尺度\(S\),当机器人当前状态较不安全、\(S\to0\)时,这些task reward也会接近0,使策略几乎无法继续获得位置追踪、姿态追踪和任务进展方面的学习信号。
因此,代码将传给其他reward的安全尺度设置为\(S+0.4\),使其范围由\((0,1]\)变为\((0.4,1.4]\):
- \(S+0.4<1\):当前状态安全性较差,抑制task reward
- \(S+0.4=1\):对应\(S=0.6\),不改变task reward的原始大小
- \(S+0.4>1\):当前状态安全性较好,放大task reward
因而,\(+0.4\)使安全尺度成为一种带下限的软调制(floored soft modulation):它仍然根据安全质量调节task reward,但不会在不安全状态下将task reward完全关闭。
什么是 _loco_mani_scale : Phase-dependent Soft Gate (\(L\))¶
为什么在这里介绍 \(L(t)\)
本文在 safety_reward_exp 中首次引入阶段门控 \(L(t)\),因此将其定义放在本节下。
需要注意,\(L(t)\)不参与 \(S_{\mathrm{mani}}(t)\) 和 \(S_{\mathrm{loco}}(t)\) 本身的计算,而是在二者计算完成后控制它们在 \(r_{\mathrm{safety}}\) 中的融合比例。后续的 reference、position 和 orientation reward 也会复用同一个 \(L(t)\)。
这个参数是一个按环境逐个计算的动态权重,用来在locomotion相关奖励和manipulation相关奖励之间连续调整影响力,范围在 \([0,1]\)
下划线前缀表示这是内部状态缓存,不是外部配置项
- 通俗理解:
- 机器人在reset后,一开始 \(D_{\mathrm{ref}}(t)\) 相对较大,\(L(t)\to1\),系统偏向预期locomotion阶段;随着 \(D_{\mathrm{ref}}(t)\) 下降,\(L(t)\) 逐渐减小并转向预期manipulation阶段
- 随着时间的推移,机器人被预期逐渐由locomotion主导变为manipulation主导,\(L\)逐步变小,系统更偏向EE的精细控制
\(L\) 如何得出¶
-
在
commands.py里先初始化se3_distance_ref和_loco_mani_scaleself.se3_distance_ref = torch.ones(self.num_envs, device=self.device) * 5.0 # 即先给默认值5.0self._env._loco_mani_scale = torch.ones(self.num_envs, device=self.device) # 先给默认值1.0- 下文将代码变量
se3_distance_ref记作\(D_{\mathrm{ref}}(t)\);它表示预期的复合位姿误差,而不是严格的物理距离
-
每决策步更新误差
metrics,并让 \(D_{\mathrm{ref}}(t)\) 按照decrease_vel(记作\(v_{\mathrm{dec}}\))递减- 两次resample之间,\(v_{\mathrm{dec}}\)保持不变
- \(D_{\mathrm{ref}}(t+\Delta t)=\max\left(D_{\mathrm{ref}}(t)-v_{\mathrm{dec}}\cdot\Delta t,\ 0\right)\),其中\(\Delta t=step\_dt\)(决策步)
-
用sigmoid函数将 \(D_{\mathrm{ref}}(t)\) 映射成阶段门控 \(L(t)\)
\[L(t)=\operatorname{sigmoid}\left(\frac{5}{\mathrm{decay\_length}}\left(D_{\mathrm{ref}}(t)-\mu_L\right)\right)\]
- 目前实际调用的参数是\(\mu_L=1.0\), \(\mathrm{decay\_length}=1.0\)
sigmoid函数如何理解
sigmoid函数将任意实数\(z\in(-\infty,+\infty)\)平滑映射到\((0,1)\):
\[\operatorname{sigmoid}(z)=\frac{1}{1+\exp(-z)}\]
它具有以下性质:
- \(z=0\)时,\(\operatorname{sigmoid}(z)=0.5\)
- \(z\gg0\)时,\(\operatorname{sigmoid}(z)\to1\)
- \(z\ll0\)时,\(\operatorname{sigmoid}(z)\to0\)
- 函数连续且单调递增,因此可以在两个阶段之间进行平滑切换,而不是突然从0跳变到1
在阶段门控\(L(t)\)中:
\[z=\frac{5}{\mathrm{decay\_length}}\left(D_{\mathrm{ref}}(t)-\mu_L\right)\]
因此:
- \(D_{\mathrm{ref}}(t)=\mu_L\)时,\(L(t)=0.5\),处于loco与mani的过渡中心
- \(D_{\mathrm{ref}}(t)>\mu_L\)时,\(L(t)\to1\),更偏向locomotion
- \(D_{\mathrm{ref}}(t)<\mu_L\)时,\(L(t)\to0\),更偏向manipulation
decay_length控制过渡区间的宽度:越小切换越陡,越大切换越平缓
-
当reset、命令到期或命令管理器策略触发resample时,重新初始化 \(D_{\mathrm{ref}}(t)\):
\[D_{\mathrm{ref}}(0)=2e_{\mathrm{P}}(0)+e_{\mathrm{R}}(0)\]
-
这里的 \(t=0\) 表示本次command开始后的局部时间原点,而不是episode的全局起点
-
并且在\([0.5,1.4]\)中重新随机采样\(v_{\mathrm{dec}}\)
-
注意,这里的\(2e_{\mathrm{P}}+e_{\mathrm{R}}\) 是人为构造的复合指标,直接混合了 m 与 rad,不是严格具有单一物理单位的 SE(3) 距离
resample是给某些环境重新抽样一个新的命令目标(位置/姿态)并重置相关计时和参考量的过程,由 commands.py 实现
总的来说,就\(L(t)\)的计算而言,实际误差\(e_{\mathrm{P}},e_{\mathrm{R}}\)只在resample时用于初始化\(D_{\mathrm{ref}}\)
两次resample之间,commands.py中的_update_metrics()按照固定的\(v_{\mathrm{dec}}\)递减\(D_{\mathrm{ref}}\),再通过sigmoid映射得到\(L(t)\)
commands.py 在整个流程中的作用
- 生成EE目标命令
- 读取env当前机器人状态并计算误差
- 维护
se3_distance_ref - 把
se3_distance_ref通过 sigmoid 变成_loco_mani_scale - 把这个门控系数交给
rewards.py用于混合locomotion与manipulation的奖励权重
【Locomotion_reward】对track_EE_reference_exp 的理解¶
前面定义的\(D_{\mathrm{ref}}(t)\)表示预期的复合位姿误差;实际复合位姿误差表示为\(D_{\mathrm{actual}}(t)=2e_{\mathrm{P}}(t)+e_{\mathrm{R}}(t)\)
-
二者的误差记作:
\[\varepsilon_{\mathrm{ref}}(t)=\left\lvert D_{\mathrm{ref}}(t)-D_{\mathrm{actual}}(t) \right\rvert\]
- \(\varepsilon_{\mathrm{ref}}\)用来度量实际复合位姿误差是否按照预设的线性下降日程减小
-
核心计算公式:
\[r_{\mathrm{reference}}(t) = \exp\left( -\frac{\overbrace{\max\{\varepsilon_{\mathrm{ref}}(t)-0.5, 0\}}^{\mathclap{\text{Dead zone: }\varepsilon_{\mathrm{ref}}(t)\leq0.5}}}{\sigma^2} \right) \cdot L(t) \cdot \underbrace{(S_{\mathrm{loco}}(t)+0.4)}_{\mathclap{\text{Locomotion safety gating}}}\]
-
这里\(\max\{\varepsilon_{\mathrm{ref}}(t)-0.5, 0\}\)给了一个容忍误差区间:只要实际误差和预期误差相差不超过0.5,指数项为1,表示这一指数核给最大奖励
-
\(L(t)\) 项让\(r_{\mathrm{reference}}(t)\)这一个奖励在预期的locomotion阶段才发挥效用,随着时间的推移,预期进入精确操作阶段之后,\(L(t) \rightarrow 0\),
track_EE_reference_exp几乎不影响manipulation阶段的策略训练 -
\((S_{\mathrm{loco}}(t)+0.4)\)即前面提到的对原始locomotion安全尺度的软调制:除了实际误差和预期误差的差距尽可能小这一奖励因素之外,机器人本身在locomotion阶段的base稳定性等安全指标也必须被考虑,让\(r_{\mathrm{reference}}(t)\) 在安全性较差时被削弱、安全性较好时被增强(这是为了遏制机器人为了达成预期要求而采取极端不安全的方式,让策略更倾向于稳定安全的前提来训练)
-
【Loco-manipulation_reward】对track_EE_pb 的理解(Progress-Based)¶
-
\(G_{\mathrm{walk}}\)根据实时位置误差平滑区分远距离行走与近目标微调:
\[G_{\mathrm{walk}}(t)=\operatorname{sigmoid}\left(\frac{5}{0.25}\left(e_{\mathrm{P}}(t)-0.5\right)\right)=\operatorname{sigmoid}\left(20\left(e_{\mathrm{P}}(t)-0.5\right)\right)\]
- 不同于由时间决定的预期的 \(L(t)\),\(G_{\mathrm{walk}}(t)\) 是由实时位置误差 \(e_{\mathrm{P}}(t)\) 决定的实际距离门控
-
每次resample时,\(b_{\mathrm{P}}(t_r)=e_{\mathrm{P}}(t_r), \qquad b_{\mathrm{R}}(t_r)=e_{\mathrm{R}}(t_r)\)
- 其中 \(t_r\) 表示本次command发生resample的时刻
-
记\(b_{\mathrm{P}}(t-1)\)和\(b_{\mathrm{R}}(t-1)\)为当前决策步之前记录到的历史最小位置误差和朝向误差,则本步产生的非负进步量为:
\[\Delta e_{\mathrm{P}}(t)=\max\{b_{\mathrm{P}}(t-1)-e_{\mathrm{P}}(t),0\},\qquad \Delta e_{\mathrm{R}}(t)=\max\{b_{\mathrm{R}}(t-1)-e_{\mathrm{R}}(t),0\}\]
-
计算进步量后,历史最优误差更新为:
\[b_{\mathrm{P}}(t)=\min\{b_{\mathrm{P}}(t-1),e_{\mathrm{P}}(t)\},\qquad b_{\mathrm{R}}(t)=\min\{b_{\mathrm{R}}(t-1),e_{\mathrm{R}}(t)\}\]
-
定义\(G_{\mathrm{progress}}(t)=0.25+0.75G_{\mathrm{walk}}(t)\),使PB奖励在近目标阶段仍保留25%:
\[r_{\mathrm{pb}}(t) = \left( 2 \cdot \Delta e_{\mathrm{P}}(t) \cdot \underbrace{\exp\left( -\frac{b_{\mathrm{P}}(t)}{0.5} \right)}_{\text{Position best-error scaling}} + \Delta e_{\mathrm{R}}(t) \cdot \underbrace{\exp\left( -\frac{b_{\mathrm{R}}(t)}{0.5} \right)}_{\text{Orientation best-error scaling}} \right) \cdot (S_{\mathrm{loco}}(t)+0.4) \cdot \underbrace{(0.25+0.75G_{\mathrm{walk}}(t))}_{G_{\mathrm{progress}}(t)}\]
-
\(\Delta e_{\mathrm{P}}(t)\) 和\(\Delta e_{\mathrm{R}}(t)\) 即对进步量的奖励
-
当历史最小位置误差已经很小的时候,\(\exp\left( -\frac{b_{\mathrm P}(t)}{0.5} \right)\) 和 \(\exp\left( -\frac{b_{\mathrm R}(t)}{0.5} \right)\) 这两个scale更接近1,会保留更多“误差进一步缩小”所产生的进步奖励;当历史最优误差仍较大时,它们会对进步量进行更强的衰减。
-
这一项奖励使用\((0.25+0.75G_{\mathrm{walk}}(t))\) 而不使用\(L(t)\) 是为了根据实时位置误差调节PB强度:机器人逐渐靠近target的过程中,\(r_{\mathrm{pb}}(t)\) 在 manipulation 阶段对总奖励的影响被削弱
- 远目标:\(G_{\mathrm{walk}}\to1\),所以 \(G_{\mathrm{progress}}\to1\);
- 近目标:\(G_{\mathrm{walk}}\to0\),所以 \(G_{\mathrm{progress}}\to0.25\);
- \(e_{\mathrm{P}}=0.5\) 时:\(G_{\mathrm{progress}}=0.625\)
-
其实 \((0.25+0.75G_{\mathrm{walk}}(t))\) 这一项,最初的公式代码没有
其实最初没有这一项的版本很好理解:
\(\left(2 \cdot \Delta e_{\mathrm{P}}(t) \cdot \exp \left(-\frac{b_{\mathrm{P}}(t)}{0.5} \right) + \Delta e_{\mathrm{R}}(t) \cdot \exp \left(-\frac{b_{\mathrm{R}}(t)}{0.5} \right) \right)\) 本身就趋向于奖励保留近目标时期的进步,但是\((0.25+0.75G_{\mathrm{walk}}(t))\) 的这一项又是遏制近目标进步的影响,所以二者似乎有些矛盾?\((0.25+0.75G_{\mathrm{walk}}(t))\) 的意义是什么?
【Manipulation_reward】对 track_EE_position_exp 的理解¶
-
\(\left( \exp \left( -\frac{e_{\mathrm{P}}(t)}{\sigma^2} \right) + \exp\left( -\frac{5 \cdot e_{\mathrm{P}}(t)}{\sigma^2} \right) \right)\) 即对 \(e_{\mathrm{P}}(t)\) 减小的奖励,\(e_{\mathrm{P}}(t)\) 越小,该指数函数越大(\(\to 1\)):
- 值得注意的是,\(\exp\left( -\frac{5 \cdot e_{\mathrm{P}}(t)}{\sigma^2} \right)\) 这一项通过系数 \(5\) 使第二个指数核衰减更快,因此它只在位置误差非常小时显著增大,用于强化策略对近零定位精度的偏好
-
\(1-L(t)\) 这一项同 \(r_{\mathrm{reference}}(t)\) 公式中的\(L(t)\),即阶段门控,只不过这里是manipulation阶段才保留这一奖励
- \((S_{\mathrm{mani}}(t)+0.4)\) 这一项同上面出现的 \((S_{\mathrm{loco}}(t)+0.4)\),不过是对manipulation阶段原始安全尺度的软调制:
- 事实上结合具体代码可以看出,\((S_{\mathrm{loco}}(t)+0.4)\) 只考虑了base的orientation(roll/pitch 稳定性)、height的限制以及foot_pose_error(足端 XY 偏移),是对locomotion过程中安全稳定的考量;
- 而 \((S_{\mathrm{mani}}(t)+0.4)\) 在包含 \((S_{\mathrm{loco}}(t)+0.4)\) 这三个因素的基础上还考虑了base的线/角速度error(为了防止机器人身体在近目标阶段还和locomotion一样快速移动,“猛冲”过头)、EE的线/角速度(为了防止EE动作过大)、foot线速度、机械臂偏移等因素;
因此,\((S_{\mathrm{mani}}(t)+0.4)\) 确保的是在机器人在全身任务视角下,近目标的时的稳定安全性,这种相对更静态的状态比locomotion阶段对安全的要求更加复杂。
但是两个安全尺度不是完全的包含关系
\(E_{\mathrm{mani}}\) 不是简单地在 \(E_{\mathrm{loco}}\) 原样基础上增加几项,因为共同误差在两者中的系数和归一化也不同
【Manipulation_reward】对track_EE_orientation_exp 的理解¶
- \(\left( \exp \left( -\frac{e_{\mathrm{R}}(t)}{\sigma^2} \right) + \exp\left( -\frac{5 \cdot e_{\mathrm{R}}(t)}{\sigma^2} \right) \right)\) 和\((1-L(t))\)这两项同上,保证manipulation阶段该项奖励对任意误差都能敏感映射
- 值得注意的是 \(\exp\left( -\frac{e_{\mathrm{P}}(t)}{0.5} \right)\) 这个 Position-based gate,它在orientation的奖励中增加了对 \(e_{\mathrm{P}}(t)\) 的考量:
- 这个gate的作用是在 EE 距离较远时强烈抑制 orientation reward,并随着位置误差减小逐渐释放该奖励
- 这意味着 \(r_{\mathrm R}(t)\) 这个奖励同时要在EE已经足够接近target的前提下才会逐渐介入影响,如果机器人离target还很远,那么就“先不急着调整EE的姿态”,而是要等足够接近再调整,这样最高效,各阶段的划分也更清晰
版本与调度顺序
以下 step 顺序与具体仓库代码、提交版本和管理器调度实现强相关,不能视为 Isaac Lab 或 MDP 的通用不变量;正文保留为当时项目代码的阅读记录。
rewards.py在整个MDP中的流程¶
-
首先,根据仿真框架的初步学习 可以在
sf_tron1_arm_env_cfg.py这样的环境配置文件中,定义了仿真环境中的“底层物理时间步”,也叫“仿真步”(sim.step) 和大脑睁眼看世界的“决策步” (env.step) -
在上一个
env.step结束的瞬间,observations.py观测env计算得到参数字典\(obs_k\),打包成一个tuple发送给Policy(神经网络),policy根据PPO算法返回对应的action \(a_k\) - 在该
env.step这个0.02s内: \([t_k,t_k+0.02)\),\(a_k\) 连续作用在其中的4个物理步 - 在时刻\(t_k+0.02\),
terminations.py终止管理器会判定哪些envs中的机器人出现了问题(done,time_out)等,给这些envs打上reset标记 -
同一时刻,
rewards.py奖励管理器会计算这个0.02s内的奖励\(reward_k\)- 注意⚠️,奖励函数不考虑robot在0.02s内是否要reset,它只对reset前的状态打分
-
对有reset标记的envs进行重置resample
-
commands.py命令管理器执行compute(step_dt),内部状态被向前推进step_dt秒- 与此同时,
commands.py还会更新内部状态:计算误差、se3_distance_ref、_loco_mani_scale等- 如何得到
_loco_mani_scale:命令管理器调用_update_metrics()功能,输入se3_distance_ref计算得到。用于下一轮\([t_k+0.02,t_k+0.04)\)末的reward计算
- 如何得到
- 与此同时,
-
然后
observations.py获取当前envs的各个状态参数\(obs_{k+1}\),包括外部状态和已更新的内部状态(仅被注册为观测项的部分,如EE_se3_distance_reference = ObsTerm(func=mdp.EE_se3_distance_ref),这就表明se3_distance_ref会被Observation获取并提供给policy),用于下一轮提交给policy,生成下一个决策步的\(a_{k+1}\),以此循环往复



