上一篇整理:01:四足 RL 到底在学什么
写在前面:这一篇先把 MDP 当成“读代码的对照表”
上一篇主要是在整理一个直觉问题:四足机器人强化学习到底在学什么?
这一篇我想开始补 MDP。说实话,MDP 这个东西我现在也还不是那种“完全吃透”的状态。它在书上看起来很标准:状态、动作、转移、奖励、折扣因子。但一放到四足机器人代码里,就会变成 observation、action、reward terms、reset、domain randomization、sim step 这些工程细节。
所以这篇不是想写成教程,而是给自己搭一个对照表:
以后看 legged_gym / Isaac Lab / PPO 代码时,知道哪些代码大概对应 MDP 里的哪个部分。
MDP 的全称是 Markov Decision Process,中文常翻译为马尔可夫决策过程。现在我先把它理解成:用一套符号描述“机器人看到什么、做什么、环境怎么变、这一步得多少分”。
一句话结论
我现在对四足 locomotion MDP 的理解是:每个控制周期里,机器人根据当前观测输出一个动作,仿真器或真实物理世界把它推进到下一状态,同时给一个 reward;训练要做的,就是慢慢找到一个长期 reward 更高的策略。
最短可以写成:
stπatPst+1,rt
对应到四足机器人里就是:
当前机器人状态/观测 ↓ policy 关节动作 / 关节目标 ↓ physics 下一帧机器人状态 + reward
|
MDP 的标准定义:先记住五个符号
书上通常把 MDP 写成一个五元组。我先把它当作一个索引,不急着要求自己一步到位完全理解:
M=(S,A,P,R,γ)
其中:
- S:状态空间,state space。
- A:动作空间,action space。
- P:状态转移概率,transition probability。
- R:奖励函数,reward function。
- γ:折扣因子,discount factor。
有些资料也会把初始状态分布 ρ0 和终止条件也写进去,例如:
s0∼ρ0(s)
我目前先记住上面这五个元素就够用了,后面看代码时再一点点对应。
1. 状态空间 S:先理解成“真实世界全量状态”
理论上的 state st 表示环境在时刻 t 的完整状态。
对于四足机器人,如果写得非常完整,状态可能包括:
st={qt,q˙t,pbase,Rbase,vbase,ωbase,ct,μ,m,⋯}
这个式子其实我也不会一眼就完全记住,先拆开看:
- qt:关节角。
- q˙t:关节速度。
- pbase:机身位置。
- Rbase:机身姿态。
- vbase:机身线速度。
- ωbase:机身角速度。
- ct:足端接触状态。
- μ:地面摩擦系数。
- m:机器人质量/动力学参数。
这里我暂时不用机器人学里常见的“左上角坐标系标记”写法。网页显示时它很容易显得上下标错位。这篇先用更朴素的变量名,例如 pbase、ωbase,重点先理解 MDP 结构。
真实物理世界当然还包含更多信息,比如地形、接触力、电机温度、延迟、外部扰动等。
但在四足 RL 论文和代码里,policy 通常拿不到完整 state,而是拿到 observation。
2. 观测 ot:代码里更常见的是 observation
严格来说,很多四足机器人 locomotion 问题更接近 POMDP,也就是 partially observable MDP。因为 policy 看到的不是完整状态 st,而是观测 ot。
可以写成:
ot=Ω(st)
其中 Ω 是从真实状态到观测的映射。
在四足速度跟踪任务里,常见 observation 可能包括:
ot=ωbasegtqt−qdefaultq˙tctcmdat−1
这里每一项大概表示:
- ωbase:机身角速度,通常来自 IMU。
- gt:重力方向在机身坐标系下的投影,用来表示姿态。
- qt−qdefault:当前关节角相对默认站姿的偏移。
- q˙t:关节速度。
- ctcmd:速度命令,比如 vxcmd,vycmd,ωzcmd。
- at−1:上一帧动作,用来帮助策略输出更平滑。
所以在工程里,经常不是写:
at=π(st)
而是写:
at=π(ot)
这点我觉得很关键:理论上讲 state,但代码里经常写 obs。真实机器人部署时,policy 也只能拿到传感器能提供的量,而不是仿真器内部完整状态。
3. 动作空间 A:先搞清楚 action 具体代表什么
动作 at 是 policy 在每一步输出的控制量。
理论上动作可以有很多选择:
- 直接输出关节力矩。
- 输出关节位置目标。
- 输出关节位置目标偏移。
- 输出足端位置目标。
- 输出 gait 参数或更高层命令。
在很多四足 locomotion RL 里,policy 输出的是关节位置目标偏移。假设机器人有 12 个主动关节,则:
at∈R12
常见做法可以写成:
qttarget=qdefault+αat
其中:
- qdefault 是默认站姿关节角。
- at 是神经网络输出的动作。
- α 是 action scale,用来限制动作幅度。
然后底层 PD 控制器把目标关节角转成力矩:
τt=Kp(qttarget−qt)−Kdq˙t
所以我看代码时要注意:policy 输出的 action 不一定就是最终电机力矩,中间可能还有 action scale、默认姿态、PD 控制器这些东西。
4. 转移概率 P:这部分通常藏在仿真器里
MDP 中的转移概率写作:
P(st+1∣st,at)
意思是:在状态 st 下执行动作 at,下一状态是 st+1 的概率。
对于四足机器人,这个转移由动力学决定:
st+1∼P(⋅∣st,at)
如果在仿真器里,我可以先粗略理解为:
Isaac Gym / Isaac Lab / MuJoCo / RaiSim 根据当前状态和动作积分一步动力学 得到下一状态
|
如果忽略随机性,也可以写成确定性形式:
st+1=f(st,at)
但实际训练时,通常会加入 domain randomization,例如随机化:
- 摩擦系数。
- 机身质量。
- 电机强度。
- 地面高度。
- 传感器噪声。
- 控制延迟。
- 外部推力扰动。
这样转移就更像随机过程:
st+1∼P(st+1∣st,at,ξ)
其中 ξ 可以理解为被随机化的环境参数。
5. 奖励函数 R:最像工程调参的部分
奖励函数是我觉得最工程、也最容易看晕的部分。它不像 MDP 定义那么干净,代码里经常是一堆 reward term 加权相加。
MDP 里通常写作:
rt=R(st,at,st+1)
在四足速度跟踪里,reward 往往由很多项组成:
rt=wvrtvel+wωrtyaw+whrtheight−wτrttorque−wartaction−wsrtslip
拆开理解:
- rtvel:线速度跟踪奖励。
- rtyaw:角速度跟踪奖励。
- rtheight:机身高度稳定奖励。
- rttorque:力矩惩罚。
- rtaction:动作变化惩罚。
- rtslip:足端打滑惩罚。
- w∗:各项权重。
速度跟踪奖励常见写法是指数形式:
rtvel=exp(−σv∥vxy,tcmd−vxy,t∥2)
角速度跟踪也类似:
rtyaw=exp(−σω(ωz,tcmd−ωz,t)2)
动作平滑可以惩罚相邻动作差:
rtaction=∥at−at−1∥2
能耗或力矩惩罚可以写成:
rttorque=∥τt∥2
这些公式不是标准答案,更像是我现在用来理解 reward 结构的模板:
想让它做的事 → 正奖励 不想让它做的事 → 惩罚项
|
6. 折扣因子 γ:先理解成“眼前和长期的权衡”
强化学习不是只看当前一步奖励,而是看一段时间里的累计表现。这个对四足很重要,因为“当前一步看起来不错”的动作,可能下一秒就让机器人摔倒。
从时刻 t 开始的 return 写作:
Gt=k=0∑∞γkrt+k
其中:
0≤γ≤1
如果 γ 接近 0,policy 更短视,只关心眼前奖励。
如果 γ 接近 1,policy 更关注长期表现。
四足机器人里,如果只看眼前一步,可能会学出奇怪动作,比如瞬间蹬一下获得速度,但马上摔倒。折扣累计奖励会鼓励 policy 在长期内保持稳定。
Policy:先记成 observation 到 action 的函数
策略 π 表示“看到状态或观测后如何选动作”。
随机策略写作:
π(at∣ot)
意思是:在观测 ot 下选择动作 at 的概率。
确定性策略可以写作:
at=π(ot)
PPO 训练时常用随机策略,因为训练阶段需要探索。我现在先把它理解成:网络不是只输出一个动作,也可能输出一个动作分布,例如高斯分布:
at∼N(μθ(ot),Σθ)
其中:
- μθ(ot) 是网络输出的动作均值。
- Σθ 是动作方差或协方差。
- θ 是神经网络参数。
部署到真实机器人时,常常直接取均值动作:
at=μθ(ot)
这样动作更稳定。
Value function:我先理解成“这个状态后面有没有前途”
有了 return,就可以定义价值函数。
状态价值函数:
Vπ(s)=Eπ[Gt∣st=s]
意思是:如果当前在状态 s,之后一直按照策略 π 行动,期望能拿到多少累计奖励。
动作价值函数:
Qπ(s,a)=Eπ[Gt∣st=s,at=a]
意思是:当前在状态 s,先执行动作 a,之后再按照策略 π 行动,期望累计奖励是多少。
我目前的直觉是:
放到四足机器人里:
- 如果机器人身体正、速度接近命令、脚下接触稳定,那么 V 应该较高。
- 如果机器人快摔倒了、姿态倾斜很大,那么 V 应该较低。
- 在快摔倒时能把身体拉回来的动作,其 Q 应该更高。
Bellman 关系:先记住“当前 + 未来”
价值函数最重要的一点是可以递推。
对于给定策略 π,Bellman expectation equation 可以写作:
Vπ(s)=Ea∼π,s′∼P[R(s,a,s′)+γVπ(s′)]
也就是:
当前状态的价值 = 当前一步奖励 + 下一状态价值的折扣期望
|
这句话我先记下来:很多强化学习算法,本质上都绕不开“当前 reward + 下一步价值”这个递推思想。后面看 PPO / critic 的时候应该还会反复遇到。
最优价值函数可以写作:
V∗(s)=amaxEs′∼P[R(s,a,s′)+γV∗(s′)]
最优策略则可以理解为:
π∗(s)=argamaxEs′∼P[R(s,a,s′)+γV∗(s′)]
四足机器人里当然不可能真的枚举所有状态和动作,维度太高。所以后面才会用神经网络去近似 policy 和 value。
把速度跟踪任务写成 MDP:我的当前理解
如果把一个最小速度跟踪任务写成 MDP,我现在会这样对照:
状态 / 观测
ot=ωbasegtqt−qdefaultq˙tvx,tcmdvy,tcmdωz,tcmdat−1
动作
at∈R12
qttarget=qdefault+αat
转移
st+1∼P(⋅∣st,at)
在仿真里就是 physics step。
奖励
rt=rttracking+rtstability−rtenergy−rtsmooth
其中速度跟踪可以写为:
rttracking=exp(−σv∥vxy,tcmd−vxy,t∥2)+exp(−σω(ωz,tcmd−ωz,t)2)
终止条件
episode 结束条件可以写成:
dt=1[∣ϕt∣>ϕmax ∨ ∣θt∣>θmax ∨ t≥T]
其中 ϕt 和 θt 可以理解为 roll / pitch。超过阈值说明机器人姿态太差,可能已经摔倒。
Markov 性:我现在还需要慢慢消化的一点
Markov 性的意思是:未来只依赖当前状态和当前动作,不依赖更早历史。
数学上写作:
P(st+1∣st,at,st−1,at−1,⋯)=P(st+1∣st,at)
也就是说,如果 st 已经包含足够信息,那么过去发生过什么理论上就不重要。这个说起来简单,但放到机器人上我觉得还挺容易混淆。
但四足机器人实际观测往往不完全 Markov。例如:
- policy 不一定知道真实接触力。
- policy 不一定知道地面摩擦系数。
- policy 不一定知道电机延迟。
- 只看单帧观测可能不知道速度趋势。
所以工程上常用一些办法补信息:
- 把上一帧动作 at−1 放进 observation。
- 堆叠多帧历史观测。
- 使用 RNN / LSTM。
- 加入 privileged information 训练 critic。
- 做 domain randomization,让 policy 对未知参数更鲁棒。
所以 observation design 不是随便拼几个量,而是在尽量让 policy 看到“足够接近 Markov”的信息。这个点我后面看代码时要特别留意。
MDP 和代码之间怎么对应:以后读代码就按这个找
如果看 Isaac Gym / legged_gym / Isaac Lab 这一类代码,MDP 元素通常会散落在不同函数里。
我先记一个粗略对应关系:
compute_observations() → o_t policy(obs) → a_t pre_physics_step() → 把 action 转成控制目标 physics step → P(s_{t+1}|s_t,a_t) compute_reward() → r_t check_termination() → done / reset
|
也就是说,MDP 不是单独写在某个文件里的一个公式,而是分布在环境代码的各个部分。
我后面读代码时可以按这个顺序找:
- observation 由哪些量拼出来。
- action 代表什么控制量。
- reward 由哪些项组成。
- termination 条件是什么。
- reset 时随机化了哪些东西。
这五个问题搞清楚,基本就知道这个 locomotion task 的 MDP 是怎么定义的。
这一篇我自己的理解:先有框架,不假装全懂
写到这里,我感觉 MDP 对我现在最有用的地方,不是背定义,而是提供一个检查清单。
看一篇四足 RL 论文或一段环境代码时,我可以问:
- 这里的 state / observation 是什么?
- policy 输出的 action 是什么?
- physics / simulator 怎么把状态推进到下一步?
- reward 到底鼓励了什么,惩罚了什么?
- episode 什么时候结束?
- 它有没有满足 Markov 性?如果没有,靠什么补?
这些问题应该比单纯说“用了 PPO”更基础。
因为 PPO 只是优化算法,MDP 才是任务本身。如果 MDP 定义得不好,比如 observation 缺关键信息、action 过于难学、reward 有漏洞,那么换再高级的算法也可能学不出稳定步态。这个判断我现在还需要通过代码和实验继续验证。
小结
这一篇先把 MDP 放到四足机器人 locomotion 里做一个自学版理解:
- S:机器人和环境真实状态。
- ot:policy 实际看到的观测。
- A:policy 输出的动作,常见是 12 维关节目标偏移。
- P:由仿真器或真实动力学决定的状态转移。
- R:速度跟踪、稳定性、能耗、动作平滑等 reward 组合。
- γ:长期奖励折扣。
- V / Q:状态或动作的长期价值。
- Bellman 关系:当前价值等于当前奖励加下一状态价值。
下一步再看 PPO 时,很多符号应该就不会那么突兀了。PPO 不是凭空来的,它是在这个 MDP 上,用采样数据去更新 policy,让长期累计奖励变大。
这一篇我先接受自己只是“建立框架”,不是完全掌握。后面看 observation、reward、PPO 代码时,再不断把这些符号和实际实现对上。