SAP 耦合器#
半解析原始(Semi-Analytic Primal,SAP)耦合器使用一种凸的半解析求解器来求解刚体与 FEM 软体之间的接触,该求解器源自 Drake 所用的模型(论文)。当刚体机器人操作中等变形的体积物体(抓取、按压、抬升),并且你需要接触力在持续载荷下保持稳定与准确时,就使用它。
SAP 处理两类求解器:Rigid 与 FEM。对于布料和高度可变形的物体,请改用IPC 耦合器;对于多求解器场景(MPM、SPH、PBD)或可微分仿真,请使用求解器与耦合中介绍的默认耦合器。
要求#
SAP 耦合有四条硬性要求。Genesis World 会在构建时逐项检查,任一项不满足都会抛出错误:
64 位精度: 使用
precision="64"初始化,因为该求解器在 32 位下条件数很差。隐式 FEM 求解器: 任何 FEM 实体都必须使用
FEMOptions(use_implicit_solver=True) 进行仿真。仅限刚体或 FEM: SAP 耦合刚体与 FEM 求解器。其他求解器(MPM、SPH、PBD)不受支持。
成对的关节等式约束: 关节等式约束必须指定两个关节,因此不支持将单个关节固定在某个常量的模型(见刚体约束)。
SAP 不支持可微分仿真。进入梯度路径的调用会抛出错误,并提示你改用默认耦合器。
最小示例#
完整脚本见 examples/sap_coupling/fem_sphere_and_cube.py,它把一个 FEM 立方体落到 FEM 球体上。以下三处选择启用了 SAP 耦合:
import genesis as gs
gs.init(backend=gs.gpu, precision="64") # SAP requires 64-bit
scene = gs.Scene(
sim_options=gs.options.SimOptions(dt=1 / 60, substeps=2),
fem_options=gs.options.FEMOptions(use_implicit_solver=True), # SAP requires implicit FEM
coupler_options=gs.options.SAPCouplerOptions(),
)
选择耦合器只需一行:把 SAPCouplerOptions() 作为 coupler_options 传入。其余部分都是普通的 Genesis 场景。用弹性材质添加 FEM 实体,然后照常步进:
sphere = scene.add_entity(
morph=gs.morphs.Sphere(pos=(0.0, 0.0, 0.1), radius=0.1),
material=gs.materials.FEM.Elastic(model="linear_corotated", E=1e5, nu=0.4),
)
求解器参数#
SAP 运行一个外层凸求解器,其 Newton 步由预条件共轭梯度(PCG)内层循环求解,并通过线搜索进行修正。下面的默认值针对典型的操作场景调校;当接触力看起来有噪声或抓取发生漂移时,应收紧容差。
参数 |
默认值 |
含义 |
|---|---|---|
|
|
每步外层 SAP(Newton)迭代次数 |
|
|
每个 Newton 步的最大 PCG 迭代次数 |
|
|
每个 Newton 步的最大线搜索迭代次数 |
|
|
SAP 收敛的绝对容差 |
|
|
SAP 收敛的相对容差 |
|
|
PCG 内层求解的收敛阈值 |
|
|
精确线搜索的充分下降容差 |
|
|
线搜索的最大步长 |
|
|
接触耗散时间尺度 |
|
|
法向力正则化 |
|
|
摩擦正则化 |
接触模型参数#
SAP 用一个柔顺的流体弹性(hydroelastic)压力场来建模接触。刚度参数决定表面对相互穿透的抵抗强度;接触类型参数决定每个接触对的离散方式。
参数 |
默认值 |
含义 |
|---|---|---|
|
|
流体弹性(压力场)接触的刚度 |
|
|
点接触的刚度 |
|
|
是否耦合刚体与 FEM 求解器 |
|
|
是否使用四面体检测 FEM 自接触 |
另有三个参数用于为每个接触对选择接触离散方式。每个参数接受以下取值之一:
"tet": 基于四面体化的接触。默认值,对大多数网格也是最准确的选择。"vert": 基于顶点的接触,更适合非常粗糙的网格,例如单个立方体或四面体。"none": 禁用该接触对的接触。
参数 |
默认值 |
可接受取值 |
|---|---|---|
|
|
|
|
|
|
|
|
|
Note
rigid_rigid_contact_type 声明为接受 "vert",但求解器只实现了 "tet" 和 "none";传入 "vert" 会抛出错误。刚体-刚体接触请使用 "tet" 或 "none"。
抓取可变形物体#
examples/sap_coupling/franka_grasp_fem_sphere.py 让 Franka 机械臂抓取并抬起一个 FEM 球体,这正是 SAP 擅长的工作负载。刚体立方体的变体见 franka_grasp_rigid_cube.py。
稳定的抓取需要比默认值更严格的收敛,因为求解过于宽松时,物体会在多个时间步后从手指间滑出。该示例同时收紧了 PCG 阈值和 SAP 容差,并禁用了机械臂的自碰撞,以便手指完全闭合:
scene = gs.Scene(
sim_options=gs.options.SimOptions(dt=1 / 60, substeps=2),
rigid_options=gs.options.RigidOptions(enable_self_collision=False),
fem_options=gs.options.FEMOptions(use_implicit_solver=True, pcg_threshold=1e-10),
coupler_options=gs.options.SAPCouplerOptions(
pcg_threshold=1e-10,
sap_convergence_atol=1e-10,
sap_convergence_rtol=1e-10,
linesearch_ftol=1e-10,
),
)
若要把 FEM 物体的某个目标顶点固定在原位(这是固定约束而非抓取),参见 fem_fixed_constraint.py,它设置 FEMOptions(enable_vertex_constraints=True),并用 set_vertex_constraints 驱动顶点。