四足机器人强化学习系列 02:用四足机器人理解 MDP

先补理论? 强化学习理论基础已按 MDP → 价值学习 → 策略梯度与 PPO 整理独立阅读顺序,并附完整推导与计算示例。

上一篇整理: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→πat→Pst+1,rts_t \xrightarrow{\pi} a_t \xrightarrow{P} s_{t+1},\quad r_t

对应到四足机器人里就是:

当前机器人状态/观测
↓ policy
关节动作 / 关节目标
↓ physics
下一帧机器人状态 + reward

MDP 的标准定义:先记住五个符号

书上通常把 MDP 写成一个五元组。我先把它当作一个索引,不急着要求自己一步到位完全理解:

M=(S,A,P,R,γ)\mathcal{M}=(\mathcal{S},\mathcal{A},P,R,\gamma)

其中:

  • S\mathcal{S}:状态空间,state space。
  • A\mathcal{A}:动作空间,action space。
  • PP:状态转移概率,transition probability。
  • RR:奖励函数,reward function。
  • γ\gamma:折扣因子,discount factor。

有些资料也会把初始状态分布 ρ0\rho_0 和终止条件也写进去,例如:

s0∼ρ0(s)s_0\sim \rho_0(s)

我目前先记住上面这五个元素就够用了,后面看代码时再一点点对应。

1. 状态空间 S\mathcal{S}:先理解成“真实世界全量状态”

理论上的 state sts_t 表示环境在时刻 tt 的完整状态。

对于四足机器人,如果写得非常完整,状态可能包括:

st={qt,q˙t,pbase,Rbase,vbase,ωbase,ct,μ,m,⋯ }s_t=\{q_t,\dot q_t,p_{\mathrm{base}},R_{\mathrm{base}},v_{\mathrm{base}},\omega_{\mathrm{base}},c_t,\mu,m,\cdots\}

这个式子其实我也不会一眼就完全记住,先拆开看:

  • qtq_t:关节角。
  • q˙t\dot q_t:关节速度。
  • pbasep_{\mathrm{base}}:机身位置。
  • RbaseR_{\mathrm{base}}:机身姿态。
  • vbasev_{\mathrm{base}}:机身线速度。
  • ωbase\omega_{\mathrm{base}}:机身角速度。
  • ctc_t:足端接触状态。
  • μ\mu:地面摩擦系数。
  • mm:机器人质量/动力学参数。

这里我暂时不用机器人学里常见的“左上角坐标系标记”写法。网页显示时它很容易显得上下标错位。这篇先用更朴素的变量名,例如 pbasep_{\mathrm{base}}、ωbase\omega_{\mathrm{base}},重点先理解 MDP 结构。

真实物理世界当然还包含更多信息,比如地形、接触力、电机温度、延迟、外部扰动等。

但在四足 RL 论文和代码里,policy 通常拿不到完整 state,而是拿到 observation。

2. 观测 oto_t:代码里更常见的是 observation

严格来说,很多四足机器人 locomotion 问题更接近 POMDP,也就是 partially observable MDP。因为 policy 看到的不是完整状态 sts_t,而是观测 oto_t。

可以写成:

ot=Ω(st)o_t=\Omega(s_t)

其中 Ω\Omega 是从真实状态到观测的映射。

在四足速度跟踪任务里,常见 observation 可能包括:

ot=[ωbasegtqt−qdefaultq˙tctcmdat−1]o_t= \begin{bmatrix} \omega_{\mathrm{base}} \\ g_t \\ q_t-q_{\mathrm{default}} \\ \dot q_t \\ c_t^{\mathrm{cmd}} \\ a_{t-1} \end{bmatrix}

这里每一项大概表示:

  • ωbase\omega_{\mathrm{base}}:机身角速度,通常来自 IMU。
  • gtg_t:重力方向在机身坐标系下的投影,用来表示姿态。
  • qt−qdefaultq_t-q_{\mathrm{default}}:当前关节角相对默认站姿的偏移。
  • q˙t\dot q_t:关节速度。
  • ctcmdc_t^{\mathrm{cmd}}:速度命令,比如 vxcmd,vycmd,ωzcmdv_x^{\mathrm{cmd}},v_y^{\mathrm{cmd}},\omega_z^{\mathrm{cmd}}。
  • at−1a_{t-1}:上一帧动作,用来帮助策略输出更平滑。

所以在工程里,经常不是写:

at=π(st)a_t=\pi(s_t)

而是写:

at=π(ot)a_t=\pi(o_t)

这点我觉得很关键:理论上讲 state,但代码里经常写 obs。真实机器人部署时,policy 也只能拿到传感器能提供的量,而不是仿真器内部完整状态。

3. 动作空间 A\mathcal{A}:先搞清楚 action 具体代表什么

动作 ata_t 是 policy 在每一步输出的控制量。

理论上动作可以有很多选择:

  • 直接输出关节力矩。
  • 输出关节位置目标。
  • 输出关节位置目标偏移。
  • 输出足端位置目标。
  • 输出 gait 参数或更高层命令。

在很多四足 locomotion RL 里,policy 输出的是关节位置目标偏移。假设机器人有 12 个主动关节,则:

at∈R12a_t\in\mathbb{R}^{12}

常见做法可以写成:

qttarget=qdefault+αatq_t^{\mathrm{target}}=q^{\mathrm{default}}+\alpha a_t

其中:

  • qdefaultq^{\mathrm{default}} 是默认站姿关节角。
  • ata_t 是神经网络输出的动作。
  • α\alpha 是 action scale,用来限制动作幅度。

然后底层 PD 控制器把目标关节角转成力矩。更完整的 PD 形式可以写成:

τt=Kp(qttarget−qt)+Kd(q˙ttarget−q˙t)\tau_t=K_p(q_t^{\mathrm{target}}-q_t)+K_d(\dot q_t^{\mathrm{target}}-\dot q_t)

在很多 legged locomotion RL 实现里,目标关节速度通常默认取 0,也就是 q˙ttarget=0\dot q_t^{\mathrm{target}}=0,所以才会简化成:

τt=Kp(qttarget−qt)−Kdq˙t\tau_t=K_p(q_t^{\mathrm{target}}-q_t)-K_d\dot q_t

注意这里的位置误差方向是 qttarget−qtq_t^{\mathrm{target}}-q_t。如果写成 qt−qttargetq_t-q_t^{\mathrm{target}},符号就反了,会变成离目标越远越往反方向推。

所以我看代码时要注意:policy 输出的 action 不一定就是最终电机力矩,中间可能还有 action scale、默认姿态、PD 控制器、目标速度假设和 torque clipping 这些东西。

4. 转移概率 PP:这部分通常藏在仿真器里

MDP 中的转移概率写作:

P(st+1∣st,at)P(s_{t+1}\mid s_t,a_t)

意思是:在状态 sts_t 下执行动作 ata_t,下一状态是 st+1s_{t+1} 的概率。

对于四足机器人,这个转移由动力学决定:

st+1∼P(⋅∣st,at)s_{t+1}\sim P(\cdot\mid s_t,a_t)

如果在仿真器里,我可以先粗略理解为:

Isaac Gym / Isaac Lab / MuJoCo / RaiSim
根据当前状态和动作积分一步动力学
得到下一状态

如果忽略随机性,也可以写成确定性形式:

st+1=f(st,at)s_{t+1}=f(s_t,a_t)

但实际训练时,通常会加入 domain randomization,例如随机化:

  • 摩擦系数。
  • 机身质量。
  • 电机强度。
  • 地面高度。
  • 传感器噪声。
  • 控制延迟。
  • 外部推力扰动。

这样转移就更像随机过程:

st+1∼P(st+1∣st,at,ξ)s_{t+1}\sim P(s_{t+1}\mid s_t,a_t,\xi)

其中 ξ\xi 可以理解为被随机化的环境参数。

5. 奖励函数 RR:最像工程调参的部分

奖励函数是我觉得最工程、也最容易看晕的部分。它不像 MDP 定义那么干净,代码里经常是一堆 reward term 加权相加。

MDP 里通常写作:

rt=R(st,at,st+1)r_t=R(s_t,a_t,s_{t+1})

在四足速度跟踪里,reward 往往由很多项组成:

rt=wvrtvel+wωrtyaw+whrtheight−wτrttorque−wartaction−wsrtslipr_t=w_v r_t^{\mathrm{vel}}+w_\omega r_t^{\mathrm{yaw}}+w_h r_t^{\mathrm{height}} -w_\tau r_t^{\mathrm{torque}}-w_a r_t^{\mathrm{action}}-w_s r_t^{\mathrm{slip}}

拆开理解:

  • rtvelr_t^{\mathrm{vel}}:线速度跟踪奖励。
  • rtyawr_t^{\mathrm{yaw}}:角速度跟踪奖励。
  • rtheightr_t^{\mathrm{height}}:机身高度稳定奖励。
  • rttorquer_t^{\mathrm{torque}}:力矩惩罚。
  • rtactionr_t^{\mathrm{action}}:动作变化惩罚。
  • rtslipr_t^{\mathrm{slip}}:足端打滑惩罚。
  • w∗w_*:各项权重。

速度跟踪奖励常见写法是指数形式:

rtvel=exp⁡(−∥vxy,tcmd−vxy,t∥2σv)r_t^{\mathrm{vel}} =\exp\left(-\frac{\lVert v_{xy,t}^{\mathrm{cmd}}-v_{xy,t}\rVert^2}{\sigma_v}\right)

角速度跟踪也类似:

rtyaw=exp⁡(−(ωz,tcmd−ωz,t)2σω)r_t^{\mathrm{yaw}} =\exp\left(-\frac{(\omega_{z,t}^{\mathrm{cmd}}-\omega_{z,t})^2}{\sigma_\omega}\right)

动作平滑可以惩罚相邻动作差:

rtaction=∥at−at−1∥2r_t^{\mathrm{action}}=\lVert a_t-a_{t-1}\rVert^2

能耗或力矩惩罚可以写成:

rttorque=∥τt∥2r_t^{\mathrm{torque}}=\lVert \tau_t\rVert^2

这些公式不是标准答案,更像是我现在用来理解 reward 结构的模板:

想让它做的事 → 正奖励
不想让它做的事 → 惩罚项

6. 折扣因子 γ\gamma:先理解成“眼前和长期的权衡”

强化学习不是只看当前一步奖励,而是看一段时间里的累计表现。这个对四足很重要,因为“当前一步看起来不错”的动作,可能下一秒就让机器人摔倒。

从时刻 tt 开始的 return 写作:

Gt=∑k=0∞γkrt+kG_t=\sum_{k=0}^{\infty}\gamma^k r_{t+k}

其中:

0≤γ≤10\le\gamma\le1

如果 γ\gamma 接近 0,policy 更短视,只关心眼前奖励。

如果 γ\gamma 接近 1,policy 更关注长期表现。

四足机器人里,如果只看眼前一步,可能会学出奇怪动作,比如瞬间蹬一下获得速度,但马上摔倒。折扣累计奖励会鼓励 policy 在长期内保持稳定。

Policy:先记成 observation 到 action 的函数

策略 π\pi 表示“看到状态或观测后如何选动作”。

随机策略写作:

π(at∣ot)\pi(a_t\mid o_t)

意思是:在观测 oto_t 下选择动作 ata_t 的概率。

确定性策略可以写作:

at=π(ot)a_t=\pi(o_t)

PPO 训练时常用随机策略,因为训练阶段需要探索。我现在先把它理解成:网络不是只输出一个动作,也可能输出一个动作分布,例如高斯分布:

at∼N(μθ(ot),Σθ)a_t\sim\mathcal{N}(\mu_\theta(o_t),\Sigma_\theta)

其中:

  • μθ(ot)\mu_\theta(o_t) 是网络输出的动作均值。
  • Σθ\Sigma_\theta 是动作方差或协方差。
  • θ\theta 是神经网络参数。

部署到真实机器人时,常常直接取均值动作:

at=μθ(ot)a_t=\mu_\theta(o_t)

这样动作更稳定。

Value function:我先理解成“这个状态后面有没有前途”

有了 return,就可以定义价值函数。

状态价值函数:

Vπ(s)=Eπ[Gt∣st=s]V^\pi(s)=\mathbb{E}_\pi\left[G_t\mid s_t=s\right]

意思是:如果当前在状态 ss,之后一直按照策略 π\pi 行动,期望能拿到多少累计奖励。

动作价值函数:

Qπ(s,a)=Eπ[Gt∣st=s,at=a]Q^\pi(s,a)=\mathbb{E}_\pi\left[G_t\mid s_t=s,a_t=a\right]

意思是:当前在状态 ss,先执行动作 aa,之后再按照策略 π\pi 行动,期望累计奖励是多少。

我目前的直觉是:

V:这个状态好不好
Q:这个状态下做这个动作好不好

放到四足机器人里:

  • 如果机器人身体正、速度接近命令、脚下接触稳定,那么 VV 应该较高。
  • 如果机器人快摔倒了、姿态倾斜很大,那么 VV 应该较低。
  • 在快摔倒时能把身体拉回来的动作,其 QQ 应该更高。

Bellman 关系:先记住“当前 + 未来”

价值函数最重要的一点是可以递推。

对于给定策略 π\pi,Bellman expectation equation 可以写作:

Vπ(s)=Ea∼π, s′∼P[R(s,a,s′)+γVπ(s′)]V^\pi(s)=\mathbb{E}_{a\sim\pi,\,s'\sim P} \left[R(s,a,s')+\gamma V^\pi(s')\right]

也就是:

当前状态的价值 = 当前一步奖励 + 下一状态价值的折扣期望

这句话我先记下来:很多强化学习算法,本质上都绕不开“当前 reward + 下一步价值”这个递推思想。后面看 PPO / critic 的时候应该还会反复遇到。

最优价值函数可以写作:

V∗(s)=max⁡aEs′∼P[R(s,a,s′)+γV∗(s′)]V^*(s)=\max_a\mathbb{E}_{s'\sim P} \left[R(s,a,s')+\gamma V^*(s')\right]

最优策略则可以理解为:

π∗(s)=arg⁡max⁡aEs′∼P[R(s,a,s′)+γV∗(s′)]\pi^*(s)=\arg\max_a\mathbb{E}_{s'\sim P} \left[R(s,a,s')+\gamma V^*(s')\right]

四足机器人里当然不可能真的枚举所有状态和动作,维度太高。所以后面才会用神经网络去近似 policy 和 value。

把速度跟踪任务写成 MDP:我的当前理解

如果把一个最小速度跟踪任务写成 MDP,我现在会这样对照:

状态 / 观测

ot=[ωbasegtqt−qdefaultq˙tvx,tcmdvy,tcmdωz,tcmdat−1]o_t= \begin{bmatrix} \omega_{\mathrm{base}} \\ g_t \\ q_t-q_{\mathrm{default}} \\ \dot q_t \\ v_{x,t}^{\mathrm{cmd}} \\ v_{y,t}^{\mathrm{cmd}} \\ \omega_{z,t}^{\mathrm{cmd}} \\ a_{t-1} \end{bmatrix}

动作

at∈R12a_t\in\mathbb{R}^{12}

qttarget=qdefault+αatq_t^{\mathrm{target}}=q^{\mathrm{default}}+\alpha a_t

转移

st+1∼P(⋅∣st,at)s_{t+1}\sim P(\cdot\mid s_t,a_t)

在仿真里就是 physics step。

奖励

rt=rttracking+rtstability−rtenergy−rtsmoothr_t=r_t^{\mathrm{tracking}}+r_t^{\mathrm{stability}}-r_t^{\mathrm{energy}}-r_t^{\mathrm{smooth}}

其中速度跟踪可以写为:

rttracking=exp⁡(−∥vxy,tcmd−vxy,t∥2σv)+exp⁡(−(ωz,tcmd−ωz,t)2σω)r_t^{\mathrm{tracking}} =\exp\left(-\frac{\lVert v_{xy,t}^{\mathrm{cmd}}-v_{xy,t}\rVert^2}{\sigma_v}\right) +\exp\left(-\frac{(\omega_{z,t}^{\mathrm{cmd}}-\omega_{z,t})^2}{\sigma_\omega}\right)

终止条件

episode 结束条件可以写成:

dt=1[∣ϕt∣>ϕmax⁡ ∨ ∣θt∣>θmax⁡ ∨ t≥T]d_t=\mathbf{1}\left[|\phi_t|>\phi_{\max}\ \lor\ |\theta_t|>\theta_{\max}\ \lor\ t\ge T\right]

其中 ϕt\phi_t 和 θt\theta_t 可以理解为 roll / pitch。超过阈值说明机器人姿态太差,可能已经摔倒。

Markov 性:我现在还需要慢慢消化的一点

Markov 性的意思是:未来只依赖当前状态和当前动作,不依赖更早历史。

数学上写作:

P(st+1∣st,at,st−1,at−1,⋯ )=P(st+1∣st,at)P(s_{t+1}\mid s_t,a_t,s_{t-1},a_{t-1},\cdots) =P(s_{t+1}\mid s_t,a_t)

也就是说,如果 sts_t 已经包含足够信息,那么过去发生过什么理论上就不重要。这个说起来简单,但放到机器人上我觉得还挺容易混淆。

但四足机器人实际观测往往不完全 Markov。例如:

  • policy 不一定知道真实接触力。
  • policy 不一定知道地面摩擦系数。
  • policy 不一定知道电机延迟。
  • 只看单帧观测可能不知道速度趋势。

所以工程上常用一些办法补信息:

  • 把上一帧动作 at−1a_{t-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 不是单独写在某个文件里的一个公式,而是分布在环境代码的各个部分。

我后面读代码时可以按这个顺序找:

  1. observation 由哪些量拼出来。
  2. action 代表什么控制量。
  3. reward 由哪些项组成。
  4. termination 条件是什么。
  5. 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\mathcal{S}:机器人和环境真实状态。
  • oto_t:policy 实际看到的观测。
  • A\mathcal{A}:policy 输出的动作,常见是 12 维关节目标偏移。
  • PP:由仿真器或真实动力学决定的状态转移。
  • RR:速度跟踪、稳定性、能耗、动作平滑等 reward 组合。
  • γ\gamma:长期奖励折扣。
  • VV / QQ:状态或动作的长期价值。
  • Bellman 关系:当前价值等于当前奖励加下一状态价值。

下一步再看 PPO 时,很多符号应该就不会那么突兀了。PPO 不是凭空来的,它是在这个 MDP 上,用采样数据去更新 policy,让长期累计奖励变大。

这一篇我先接受自己只是“建立框架”,不是完全掌握。后面看 observation、reward、PPO 代码时,再不断把这些符号和实际实现对上。

知识共享许可协议