本节摘要:3.1 说过运动方程光滑可微,本节兑现这句话的工程含义:把引擎的推演过程纳入自动微分计算图,损失函数对模型参数、控制输入的梯度可以沿仿真轨迹反传回来。梯度给了「用导数优化物理系统」的能力——系统辨识、控制器参数整定、短时域策略学习都有它的位置;但接触的不连续会让梯度在关键处断裂或失真,知道梯度在哪里可信、在哪里该停手,是这一节真正要交的东西。
上一节是「物理被批量执行」,本节是「物理被求导」。两条延伸共用同一个前提——引擎行为是确定的、参数化的数学过程——只是消费方式不同:前者消费「快」,本节消费「可导」。
把一次仿真看成一个超深复合函数:输入是初始状态、模型参数与控制序列,输出是轨迹末端的某个损失值。链式法则说,损失对任何输入的导数,等于沿计算路径每一步导数的乘积——前提是每一步都可导。3.1 拆过方程的成分:质量矩阵随姿态光滑变化,偏置力光滑,执行器映射光滑——这些环节的导数都存在且可以解析或自动求出。引擎为此提供两层数字接口:一是各环节的解析雅可比(3.4 提过中间量开放读取),二是官方的有限差分导数接口,对「一步转移」直接给出输入输出间的导数矩阵。
「一步可导」到「整条轨迹可导」还差一步工程:把几百上千步的导数链起来反传。这正是上一节批量路线的意外红利——MJX 把引擎写成纯函数编进计算图,自动微分框架顺着就把整条轨迹的梯度算了。两条路线在此汇合:批量执行是可微分的算力底座。
用系统辨识这个最典型的场景看梯度怎么用。问题:真实摆的阻尼参数未知,要求从实测轨迹反推参数。把参数设为待优化变量,仿真的轨迹与实测轨迹的偏差作为损失,梯度下降:
# 思路示意:批量化引擎让仿真进了自动微分图 import jax import jax.numpy as jnp # from mujoco import mjx # 官方批量引擎入口(示意) def simulate_loss(damping, start_state, measured_traj): """把待辨识的阻尼写进模型参数,推演并对照实测轨迹""" # model = 把参数树中的关节阻尼替换为 damping # traj = 用 mjx 的扫描接口从 start_state 推演出整条轨迹 traj = jnp.zeros_like(measured_traj) # 示意占位 return jnp.sum((traj - measured_traj) ** 2) # jax.grad 返回损失对阻尼的导数——「调参方向」由物理直接给出 # grad_damping = jax.grad(simulate_loss)(damping0, start_state, measured)
这段示意代码的要点不是接口,而是问题形态的转换:辨识不再「拟合黑箱」,而是「问物理」——损失对阻尼的导数直接回答「阻尼加大一点,轨迹偏差变小还是变大」,几百组参数的搜索问题变成了沿梯度走几十步的问题。同一形态换个损失函数就是控制器整定:损失换成「跟踪误差加能量」,梯度直接流到控制器增益上。
可微分仿真的诚实手册必须用一半篇幅讲失效模式。三类断裂点按出镜率排序:
断裂一:接触的建立与断开。 接触是「有或无」的离散事件——本步没接触、下步接触了,轨迹对这个事件是不可导的。软约束模型(3.2)把「接触中」的力学做了光滑化,但「接触何时发生」这个门槛依然尖锐。症状:梯度在接近接触的参数区域剧烈振荡或为零,优化在「该不该碰到」上反复横跳。工程对策是时间与空间的平滑化(把接触门槛软化成坡道)或干脆绕开——见后文的短时域策略。
断裂二:长时域的梯度病。 链式法则连乘几百步,导数要么指数爆炸要么指数消失,长轨迹的梯度信号被数值噪声淹没。这跟循环神经网络的古老病史同源。症状是「训练早期有点进步,之后损失平台期纹丝不动」。对策不是修梯度,是缩时域——见下。
断裂三:求解器的迭代过程。 约束求解器迭代到容差即停,迭代次数本身不光滑;解的精度随参数扰动有跳变。批量化引擎对此的处理是「固定迭代次数的松弛求解」,换来光滑但引入近似——梯度可信的前提是「你接受这个近似下的物理」。
三条断裂指向同一个实操结论:梯度法在「短时域、少接触切换、参数连续」的区间内是利器,出了这个区间要主动换工具。
断裂面前的流行解法不是硬扛,而是「梯度管近期,采样管远期」的杂交:策略网络输出目标,用短时域(几十步)的梯度反传直接优化控制序列——时域短到梯度病来不及发作、接触切换次数有限;远期的不确定性交给采样式方法或 RL 处理。运动控制领域的多条工作线(短时域 actor-critic 风格的方法)验证了这条路的性价比:比纯 RL 样本效率高一个量级,比纯轨迹优化多了应对接触的策略层。
一个可判断的分工表压在这里:
| 任务形态 | 梯度法适配度 | 理由 |
|---|---|---|
| 系统辨识、参数校准 | 高 | 时域可短、参数连续、损失光滑 |
| 控制器增益整定 | 高 | 同上,且结构先验丰富 |
| 无接触或轻接触轨迹优化 | 中高 | 梯度基本连续,注意限位切换 |
| 密集接触操控(抓取、插孔) | 低到中 | 接触切换密集,梯度断裂主导 |
| 长时域运动技能 | 低 | 梯度病叠加接触断裂,交给 RL 或杂交 |
把 5.3 的迭代流水线用梯度法升级一遍。背景:某腕部传动机构的摩擦参数实测困难,5.3 的「真机失败—辨识—收窄随机化」循环里,辨识环节原靠网格搜索,一轮要一晚。操作:改梯度辨识——实测轨迹分段喂入,批量化引擎推演对照,梯度下降四十步收敛;损失曲面顺带可视化,暴露出「静摩擦与黏性摩擦在此数据下不可分辨」的病态方向,补做了一组低速实验才解开。结果:辨识从一晚缩到十分钟,且「参数可辨识性」这个网格搜索根本看不见的信息浮出水面。解读:梯度法的真实红利不只是快,还有导数的诊断信息——梯度趋零的方向告诉你「这组数据定不住这个参数」,这比任何拟合度指标都诚实。变式:没有自动微分环境时,官方有限差分接口可以小规模地做同样的事,代价是参数多时差分调用次数爆炸——参数超过十个就老老实实上批量微分。
两条技术路线讲完,最后一节看它们被推到极限的地方:当机器人有几十个自由度、要学的是「全身协调」,仿真与现实的协作会变成什么形态。