E6:优化、柔性体与多物理边界的综合源码地图#

学习首页 · Drake 目录

Sim Atlas 学习首页 · 原生扩展 · 标量能力

本篇固定在 Drake 1.57.0 / 1e1466ba466e7ce8fa9fcca4e086ce1383e5427d,承接 E1–E5,完成 B7 从原生对象到具体能力与失败点的综合追踪。下文给出公开原生模块、内部实现与外部依赖的归属;不以目录、模板参数或论文名字充当运行验收。

1. 优化程序、接触 solver 与 Simulator 各解什么#

MathematicalProgram 组织决策变量、目标和约束,例如:

\[ \min_z f(z),\qquad g(z)\le0,\qquad h(z)=0. \]

Solve 根据问题属性及实际可用 solver 选择后端,或显式调用某个 SolverInterface;不是每个问题都由 SAP 解。SAP 是 E3 的离散接触速度问题,Simulator 则推进 System/事件/积分器。把三者都称为“求解器”会掩盖变量、容差和结果意义的差异,见MathematicalProgram 归属和Solve 分派合同。

路径

决策量 / 结果

能力边界

InverseKinematics

某姿态的 q 与几何/运动学约束

E2 已解释:姿态可行不等于控制可执行

KinematicTrajectoryOptimization

B-spline 路径 r(s) 与时长 T,q(t)=r(t/T)

轨迹导数是 qdot,不是所有模型的广义速度 v;动力学和碰撞约束需明确添加

DirectCollocation

连续状态和输入轨迹及时间间隔

原生假设 FOH 输入、三次状态曲线和配点动力学;不自动覆盖混杂接触/事件

DirectTranscription

采样状态/输入,一步更新约束

有特定单周期离散或显式 Euler 连续入口,不是任意完整仿真图

GraphOfConvexSets

图上的路径、每个凸集内连续变量、边成本/约束

凸松弛可能不紧;rounding/restriction 的可行路径不是任意问题的全局最优保证

原生 MultilayerPerceptron

端口输入输出、Context 中权重/偏置、解析 backprop

是具体网络 System,不是完整学习库、GPU 物理或训练服务

KinematicTrajectoryOptimization 的 s 无量纲、T 单位 s;对 T>0,有 \(\dot q=r'(s)/T\)、\(\ddot q=r''(s)/T^2\)。四元数模型里 qdot=N(q)v,不能把 qdot bounds 无条件叫关节速度/基座角速度限制,见轨迹对象与 qdot 约定。若只在有限 s 点添加非线性避障约束,也不能把它当成整个连续曲线碰撞自由的证明。

GCS 的原生选项区分 mixed-integer 问题、凸松弛和候选路径 rounding;固定源码明确说松弛不能解所有原始 NP-hard 实例。见GCS 松弛与 rounding。这类算法的结果、初值、求解器与容差需要记录,不能仅看“路径画出来了”宣布可执行抓取。

MLP 以 \(x_{i+1}=\sigma(W_i x_i+b_i)\) 组织层,权重保存在 Context;其 Backpropagation 使用解析梯度,预期 double,不要求 AutoDiff。见原生 MLP 对象和解析 backprop API。这补充 E5 的 Gym 接口边界:Drake 有具体学习相关组件,但 Gym 不因此变成训练器,MLP 的局部梯度也不自动穿过接触轨迹。

1.1 外部 solver 身份和成功状态#

SolverInterface 的 available() 表示编译进当前 Drake,enabled() 表示运行配置允许使用,AreProgramAttributesSatisfied() 表示问题类型兼容;三者都不是“已经求得有效解”。商业/开源后端及实际构建配置属于另一层依赖,不能把源码里有接口写成此设备已安装/获许可。见solver 可用性与属性。

最后仍需检查 MathematicalProgramResult 的结果状态、残差和问题自身物理约束。局部非线性优化成功不证明全局最优;求解器容差不修复错误坐标、失真的惯量或漏掉的动力学。本轮既未检测本机 solver available/enabled,也未运行任何 Solve。

2. 三种容易混淆的“软”模型#

模型

是否增加物体内部变形自由度

本版本归属

刚体 hydroelastic 接触

原有刚体 q/v;压力场用于接触表面与力,不把刚体变成 FEM 网格

SceneGraph + MultibodyPlant 原生接触;见 E3

DeformableModel / FEM

固定体积网格的节点位置/速度/加速度,内部形状可变化

原生实验性功能,非空 model 限 double、离散 Plant、SAP

MPM 内部算法

粒子与背景网格的内部状态/能量计算

固定源码有 internal 实现和 private Bazel 目标,不能当作公开 Plant/Python 功能

DeformableModel 以固定拓扑体积网格和近似 signed distance field 描述柔性体,每个 body 建 FEM 模型,见模型与注册合同。这不是仅给 rigid geometry 填一个柔软材质;也不能从 volumetric FEM 推断已提供切割、拓扑断裂、壳/布料、绳索或通用流体模拟器。

3. FEM:字段、状态、离散与接触链#

注册前取得 plant.mutable_deformable_model(),传 GeometryInstance、DeformableBodyConfig、model instance 和 resolution_hint;在 Plant Finalize 前完成。resolution_hint 单位 m,指导网格细化,近似对应 primitive 网格边长;它不是 dt 或求解容差。原生注册要求 double 和离散 Plant,见前述 RegisterDeformableBody 合同。Python 绑定明确注册 double 的 DeformableModel 及两种 RegisterDeformableBody 重载,见模型注册绑定;材料枚举和 Config 的实际 getter/setter 见FEM 配置绑定。C++ 的 element_subdivision_count setter 并未在这段 Python Config 绑定中暴露;内部 integrator/parallelism 等方法也不能想象成普通 Python setter。

DeformableBodyConfig 字段

单位 / 合法假设

固定默认值及解释

Young's modulus E

Pa,E>0

1e8;体积材料刚度,不等于 point stiffness N/m

Poisson ratio nu

无量纲,−1<nu<0.5

0.49;接近不可压缩时需考虑数值条件,不能设成恰好 0.5

mass density rho

kg/m³,rho>0

1500;由体积积分形成质量

mass damping alpha

s⁻¹,非负

0;Rayleigh 质量项

stiffness damping beta

s,非负

0;Rayleigh 刚度项

material model

离散枚举

kLinearCorotated;还列 kCorotated、kNeoHookean、kLinear

element subdivision count

整数 0…4

0;细分外部体积力求积,不等于增加接触/时间子步

这些是固定源码默认值,未用于拟合真实材料或运行实验,见字段与范围。线性弹性适合小应变/小转动假设;corotated 等本构处理旋转的方式不同,不可把改枚举当作同一模型的纯加速选项。此处不对材料模型做准确度/速度排名。

Rayleigh damping 为 \(D=\alpha M+\beta K\)。若以模式频率 \(\omega_n>0\) [s⁻¹] 线性化,阻尼比为:

\[ \zeta_n=\frac12\left(\frac{\alpha}{\omega_n}+\beta\omega_n\right). \]

alpha 和 beta 分别在低/高频有不同作用,不是同一个“阻尼百分比”。刚体运动的零频极限不能直接除以零代入此式;源码说明质量阻尼会影响刚体运动,见Rayleigh 模型。

固定实现差异:DeformableBodyConfig 的两个 damping setter 检查的是旧成员非负,然后才赋新值;并非立即检验传入参数。因此从默认 0 调用一次负值 setter,不应依据注释声称它已被该 setter 拒绝。下游构建 FEM 时把系数交给 DampingModel,后者确实对传入值做非负检查;校验只是可能推迟,不能理解为负阻尼合法。见setter 实现、材料构建调用和下游入参检查。没有在本机执行这个缺陷路径,也没有修改上游。

线性四面体单元和一阶基础求积在 DeformableBody 中选定;每个 body 声明长度为 3*num_dofs 的离散块,按 [q,v,a] 保存节点状态。q 是节点位置,不是刚体四元数/关节配置向量;num_dofs 对应节点平移自由度。见单元与状态装配。不要只读 plant.num_positions() 或刚体 [q;v] 端口,就假定拿到了所有柔性节点状态。

原生柔性 API

数据合同与生命周期

GetDiscreteStateIndex(id)

Finalize 后取得该 body 所属离散块索引;不是刚体 position_start

SetPositions(context,id,q) / SetVelocities(context,id,v)

q、v 分别为 3×N 节点矩阵,单位 m、m/s;使用所属 Plant Context,节点数及有限值需合法

GetPositions / GetVelocities

各返回 3×N 值矩阵;不是 body pose 的 4×4 齐次变换

GetPositionsAndVelocities

返回 3×2N,前 N 列位置、后 N 列速度;不能误当 6×N 或完整 q/v/a

AddFixedConstraint

Finalize 前以 X_BA 和 X_BG 选择参考网格中受约束顶点,并固定到同一 Plant 的刚体;形状未选中任何顶点会抛错

AddExternalForce

注册体积力场;Python 绑定通过 Clone 保存,不能靠随后改原 Python 对象假定已更新 Plant

上述矩阵/Context 合同见节点状态接口,固定约束见参考网格选点与前置条件,Python 状态/外力绑定见实际可调用入口。这些是 API 数据形状,不是本轮生成的节点数据。

内部 free-motion integrator 选择 VelocityNewmarkScheme(h,1.0,0.5),源码明确写出位置中点规则:

\[ q_{n+1}=q_n+\frac h2(v_n+v_{n+1}). \]

它属于柔性模型内部时间更新,不能等同刚体 E3 的 q0+hN(q0)v_next,也不由给 Simulator 换一个连续积分器来替代,见柔性时间积分配置。

有约束时,DeformableDriver 先求 free-motion FEM 状态和切线矩阵的 Schur complement;参与接触/约束的速度进入接触求解结果,再恢复未参与节点的速度增量,最后通过该内部 integrator 得到下一 FEM 状态。无参与节点时直接用 free-motion 状态。见自由状态与 Schur 数据和求解后重建节点状态。因此“只有表面节点接触”不意味着内部节点完全不动;刚柔耦合也不是把刚体 contact force 矩阵按行贴到所有节点。

非空 DeformableModel 的系统资源声明再次检查 discrete/SAP;标量转换只允许空模型,详见可微篇。固定源码允许 kSap、kLagged、kSimilar 对应的 SAP solver 条件,不能把“SAP”误写成只允许 kSap 近似,见真实模式检查。

4. MPM 目录、气动力与真正的多物理范围#

固定树确实有 multibody/mpm:mpm::internal::MpmModel 以粒子数据和网格速度增量描述 backward-Euler 弹性能量与残差,见内部 MPM 方程与对象。但该包的 Bazel 默认 visibility 和 package library 均是 private,并保留“等被 MbP 等使用后再公开”的 TODO,见实际可见性。不能从这个目录推导存在 pydrake.MpmSimulator、可用流体/粒子场景或 GPU MPM。内部测试/算法存在、公开集成、绑定可达、实际运行是不同证据。

原生多物理相关入口还有外力模型。例如 Propeller 是无状态 System,将 command 乘 thrust_ratio 得到沿 propeller z 轴的 N、乘 moment_ratio 得到 N·m,通过 ExternallyAppliedSpatialForce 接到 Plant;默认 command 可解释为 N,但调整系数后命令单位需重新声明。它没有自动建电机电流、转子惯量或流体场,见Propeller 原生合同。

Wing 给出粗粒度平板气/水翼近似,使用 body pose、spatial velocity、可选 world wind 和流体密度输入,输出空间力。固定模型的 \(C_L=2\sin\alpha\cos\alpha\)、\(C_D=2\sin^2\alpha\)、\(C_M=0\);surface area 单位 m²、density kg/m³。这是特定力模型,不是 Navier–Stokes 网格求解或完整流固耦合,见Wing 方程与端口及构造参数量纲。

自定义热/流/电模型可以通过 Systems 状态、事件与外力端口耦合,但“可以扩展”只说明存在编程接缝,不意味着当前 Plant 已内建温度场、电路、燃烧或通用 CFD。外部引擎/学习框架/消息桥的时钟、单位、线程、数据复制和许可由实际适配层负责;E5 已解释 host/GPU 和外部 RNG 边界。本课程不虚构一个统一跨引擎/多物理 wrapper。

5. 从一个问题走完整条源码链#

以“离散机械臂受力后,记录末端受力并研究对控制输入的局部敏感度”为阅读任务,下面每一步均有独立合同,不需要先运行实验才能理解。

步骤

原生链 / 对应课程

此处应回答的问题

建模与身份

Parser → body/joint/actuator → Finalize;E1

资产单位、nq/nv、惯量和 model instance 是否一致?Finalize 后哪些结构已冻结?

系统拓扑

Plant ↔ SceneGraph;controller/reference → actuation;E2

哪些输入直通,哪些是状态;几何 QueryObject 属于哪个 Context?

配置与时间

h、contact model、approximation、sampled outputs;E1/E3

控制周期、Plant 更新和 Simulator 内部步如何区分?

碰撞/材料

query → point/hydro 数据 → 组合材料;E3

接触 pair/shape/scalar 是否支持;材料单位和组合律是什么?

约束与求解

manager → SapDriver → free motion / contact problem → SAP

vstar、J、R、gamma 和终止条件各代表什么?失败在哪里抛出?

输出与采样

ContactResults / generalized forces / sensors;E3/E4

力在哪一侧、哪个点、哪个 frame、哪个物理时间?是否保持的旧输出?

标量/优化

System converter →新 Context/seed→几何→SAP→评价量;本阶段

研究的是输入、初态还是参数导数;哪段抽取 double 或不可微?

数据与复现

logger trigger → 副本 → 元数据;E5

发布时刻是否等于观测时刻;reset/RNG/失败样本保存什么?

若加入柔性体,第三至第五步改为含独立 FEM [q,v,a] 状态及 DeformableDriver,标量能力也被非空 DeformableModel 收紧;不能只把 rigidity 标志换成 false,继续沿用刚体 AD 结论。若用优化器规划轨迹,规划模型还要满足优化方法的状态/输入假设,不能以仿真图能构造代替可优化性。

推荐阅读顺序是先看公开调用的前置条件,再看实际 if constexpr/throw 分支和 driver 装配,最后回到绑定与数据拥有者。对注释/实现差异保留两者的固定出处;不要用最新版文档或不同语言绑定补填本版本的空白。

6. 易错点与带答案练习#

  1. MathematicalProgram Solve 和 SAP 是否同一个 solver? 答:不是;前者针对用户优化程序分派后端,后者求当前离散接触速度问题,Simulator 则推进系统时间。

  2. KinematicTrajectoryOptimization 的 qdot bounds 是否总等于 v bounds? 答:否;qdot=N(q)v,含四元数等模型尤其不同,必须按原生坐标映射解释。

  3. GCS 凸松弛返回结果是否保证原图全局最优可执行路径? 答:不保证松弛紧或 rounding 完美;还需实际路径可行性和模型执行约束。

  4. 把刚体改成 hydroelastic 是否新增节点变形状态? 答:没有;刚体 hydro 接触与固定体积网格 FEM 是不同模型,后者显式维护节点 q/v/a。

  5. 两个 damping setter 接受一次负的新值是否说明负阻尼合法? 答:不是;固定实现先误查旧成员,但下游 DampingModel 对传入系数检查非负,可能在材料构建时拒绝。

  6. MPM 源码目录存在,能否宣称公开 Python 流体引擎已经可用? 答:不能;此版本是 internal 对象/private 包,尚无由这里证明的公开 Plant/绑定集成。

  7. 加入柔性体后刚体 SAP 的 AD 结论能否原样保留? 答:不能;非空 DeformableModel 限 double,Finalize 会移除 AD/symbolic 转换,必须重新审整条链。

本阶段完成源码课程,不改变 DexLab #117 的 Drake 运行资格。后续实验仍复用 DexLab;E7 留给两条路线的全文审校及证据入口整合。静态验收。

课程来源 · GitHub · 许可