SAP Memo
Table of Contents
按你的四步框架,把修正和两个问题的答案都揉进去: #
1. 法向规则 #
我们定义了一套法向力的规则,法向力跟穿透和靠近速度有关(Kelvin–Voigt:弹簧加阻尼,隐式地用步末的穿透),本质上是一根弹簧。整理之后是:
\[\gamma_n = \frac{\hat v_n - v_n}{R_n}\]$\hat v_n = -\phi_0/(h+\tau)$ 是法向力为 0 时的零点,它是一个门槛,不是一个状态:
- 已经穿透时,$\hat v_n > 0$:物体必须以这个速度往外退,力才为 0;
- 还有间隙时,$\hat v_n < 0$:物体只要靠近得不比这个速度快,就没有力。
$v_n < \hat v_n$ 时有推力;$v_n \ge \hat v_n$ 时没有力。SAP 里的”分离”指的是后者,也就是”这一步没有法向力”,不一定是物体在远离。
2. 理想的切向规则 #
理想情况下,摩擦力有三种情况:
- 分离:没有法向力,也就没有摩擦力;
- 滑动:摩擦力 $= \mu F_n$,方向与滑移相反;
- 粘滞:$v_t = 0$,摩擦力 $\le \mu F_n$。
所以理想情况下,摩擦力本身就像一个 projection 操作:$F_n$ 决定上界,摩擦力被限制在这个上界以内。
难点在于粘滞:这时摩擦力是一个约束力,”需要多少就给多少”,由整个系统决定,不是速度的函数。一个速度($v_t = 0$)对应无数个可能的力,没法写成规则,也就没法优化。
3. SAP 的切向规则:用一点点滑动换来静摩擦 #
SAP 的做法是:$\gamma_t = -v_t/R_t$,$v_t$ 是相对滑动速度。通过允许一点点相对滑动,让静摩擦力”需要多少就给多少”变成由速度唯一确定。这和法向用一点点穿透换来弹簧规则是同一个套路。$R_t = \sigma w$,滑动量大约是”没有摩擦时会滑的速度”的 $\sigma$ 倍。
这样做还有一个好处:切向规则的形式和法向一样(切向取 $\hat v_t = 0$),可以统一写成
\[y = R^{-1}(\hat v - v_c)\]$y$ 就是投影前的冲量。然后用 $R$ 范数把 $y$ 投影到摩擦锥上,得到真正的冲量 $\gamma$。在锥里就是粘滞,被截到锥面上就是滑动,被截到锥尖就是分离。
4. 为了能优化:要对称,所以联合投影 #
如果法向和切向分开投影(先算 $F_n$,再把摩擦截到 $\mu F_n$),会发现 Jacobian $\partial\gamma/\partial v$ 不对称:滑动时摩擦上限依赖 $v_n$,但法向不依赖 $v_t$。不对称就写不成”某个凸势能的梯度”,也就没法优化。
| 所以 SAP 把 $y$ 整个一起在 $R$ 范数下投影到三维锥上。这样一来,法向自动获得了对切向速度的耦合:滑动时,法向冲量相当于把 $v_n$ 换成了 $v_n - \mu | v_t | $,而且强度正好和正向耦合相等。用 $R$ 范数,就是为了让两边配平。 |
这种耦合只在滑动时出现,因为只有滑动时摩擦被上界卡住,才依赖法向。粘滞时摩擦没达到上界,和法向无关,正向耦合为 0,反向耦合也必须为 0。分离时两者都是 0。所以耦合不是三种情况都要加,而是哪里有正向耦合,哪里才需要反向耦合。
| 代价是 gliding 伪影:滑动时物体会被多推出约 $\mu | v_t | (h+\tau)$,悬在表面上方滑行。 |
5. 补一句:ICF / Lagged #
“能优化”的精确条件是:冲量场 $\gamma(v_c)$ 无旋(Jacobian 对称)并且单调(势能是凸的)。SAP 是通过”两边都耦合“来满足对称性。Lagged 则是”两边都不耦合“:把摩擦上界冻结成步初算好的 $\mu n_0$,法向和切向完全分开,因此不需要联合投影,也没有 gliding 伪影。代价是摩擦上界滞后一步。
gliding artifacts,到底是允许一点点相对滑动引入的,还是这个耦合引入的 #
是耦合引入的,和”允许一点点相对滑动”无关。有三个证据。
证据 1:伪影的大小和 $R_t$ 无关 #
gliding 那一项是:
\[\hat\mu\,y_r = \mu\frac{R_t}{R_n}\cdot\frac{\|v_t\|}{R_t} = \frac{\mu\|v_t\|}{R_n}\]$R_t$(也就是 $\sigma$)被约掉了。把 $\sigma$ 调大或调小,蠕滑会变,但 gliding 不变。即使让 $\sigma \to 0$(完全不允许滑动),它仍然存在。没有正则化的刚体 Anitescu 凸近似,同样有这个伪影。
证据 2:它只在滑动时出现,而滑动时正则化根本不起作用 #
滑动时 $\gamma_t = -\mu\gamma_n\hat v_t$,和 $R_t$ 无关,正则化在这里已经”失效”了。”允许一点点滑动”只在粘滞时起作用,而粘滞时 $\gamma = y$,没有任何耦合,也就没有 gliding。
证据 3:Lagged 有同样的正则化,却没有 gliding #
Lagged 的摩擦在原点处的刚度也是 $1/(\sigma w)$,”允许一点点滑动”的程度和 SAP 完全相同。但它把摩擦上界冻结成了 $\mu n_0$,没有联合投影,也就没有反向耦合,因此没有 gliding。
两个伪影各管各的 #
| 来源 | 什么时候出现 | 大小 | SAP | Lagged | |||
|---|---|---|---|---|---|---|---|
| 蠕滑 | 切向正则化(允许一点点滑动) | 粘滞时 | 约为”没有摩擦时会滑的速度”的 $\sigma$ 倍 | 有 | 有 | ||
| gliding | 联合投影带来的反向耦合 | 滑动时 | 多推出约 $\mu | v_t | (h+\tau)$ | 有 | 无 |
需要澄清的一点是:之前说”正则化让切向和法向形式统一,所以可以用 $R$ 范数联合投影”。这说的是正则化让联合投影写得出来,但 gliding 不是正则化造成的。真正造成 gliding 的,是”为了对称而让法向依赖 $v_t$”这个选择本身。
最核心最核心的一定要让摩擦力和切向速度联系在一起的原因是啥 #
最核心的原因只有一个:SAP 选择了只把速度当作未知量。
一句话 #
SAP 把一个时间步写成:
\[\min_v\ \tfrac12\|v - v^*\|_M^2 + \sum_i \ell_i(J_i v)\]未知量只有 $v$。力不是未知量,而是 $v$ 的函数 $\gamma(v_c)$。既然力必须由速度算出来,摩擦力也就必须是切向速度的函数。
为什么理想的静摩擦做不到这一点 #
理想静摩擦是:$v_t = 0$,摩擦力可以是 $[-\mu F_n, \mu F_n]$ 中的任意值。
在 $v_t = 0$ 这一点上,一个速度对应无数个力。它不是函数,所以:
- 给定速度 $v$,算不出唯一的 $\gamma$,Newton 法的每一步都没法计算;
- 也写不出光滑的势能 $\ell$,因为 $\ell$ 在那里有尖角,没有 Hessian。
用 $\gamma_t = -v_t/R_t$ 代替它,把”一个点对应一整段力”换成”一条很陡的直线”,就变成了函数。
不这样做的话,替代方案是什么 #
| 替代方案是把力也当成未知量,把静摩擦写成约束:$v_t = 0$,并且 $ | \gamma_t | \le \mu\gamma_n$。传统的 LCP、NCP、PGS,以及各种锥规划方法都是这么做的。 |
代价是:
- 变成带约束的问题,要么不光滑,要么需要 active set、内点法这类更复杂的方法;
- 刚性静摩擦的解可能不唯一(比如四条腿的桌子,每条腿分担多少摩擦是不确定的)。
SAP 的取舍是:接受一点点蠕滑,换来一个只关于速度的、无约束、光滑、严格凸的问题,可以直接用 Newton 法求解,而且解唯一。
所以”摩擦力必须和切向速度联系起来”不是物理上的要求,而是”只解速度“这个求解方式上的要求。法向也是一样:用弹簧代替刚性的”不穿透”约束,同样是为了让法向力成为速度的函数。
primal和dual优化指的是什么? #
这两个词说的是选哪个量作为未知量:
- Primal(原问题):未知量是速度 $v$;
- Dual(对偶问题):未知量是冲量 $\gamma$。
两者描述的是同一个物理问题,最优解对应同一个状态,只是从两个方向去解。
Primal:解速度(SAP 的做法) #
\[\min_v\ \tfrac12(v - v^*)^\top M(v - v^*) + \sum_i \ell_i(J_i v)\]- 未知量的个数 = 自由度数;
- 没有约束。摩擦锥藏在 $\gamma(v_c)$ 这个函数里,通过投影来处理;
- 冲量是速度的函数,所以静摩擦必须正则化成速度的函数(上一个问题的答案);
- Newton 法的矩阵是 $M + \sum_i J_i^\top G_i J_i$。它的稀疏结构和 $M$ 一样,沿运动学树分布。
Dual:解冲量 #
从动量方程把速度消掉:$v = v^* + M^{-1}J^\top\gamma$,所以接触速度是:
\[v_c = \underbrace{Jv^*}_{v_c^*} + \underbrace{JM^{-1}J^\top}_{W}\,\gamma\]Delassus 算子 $W$ 在这里登场了。代入后,问题变成:
\[\min_{\gamma\in\mathcal F}\ \tfrac12\gamma^\top(W + R)\,\gamma + \gamma^\top(v_c^* - \hat v)\]- 未知量的个数 = 3 × 接触数;
- 有约束:$\gamma$ 必须在摩擦锥里;
- 冲量本身就是未知量,静摩擦可以直接当约束处理,原则上不需要正则化。但加上 $R$ 可以保证 $W + R$ 正定,从而解唯一。否则接触有冗余时(比如四条腿的桌子),$W$ 是奇异的,冲量不唯一;
- 矩阵 $W + R$ 需要 $M^{-1}$,而且只要两个接触在同一个物体或同一条链上,它们之间就有耦合,所以通常比较稠密。
可以验证:对这个 dual 问题写出最优性条件,得到的正是”$\gamma$ 是 $y = R^{-1}(\hat v - v_c)$ 在 $R$ 范数下到 $\mathcal F$ 的投影”,也就是 SAP 的投影规则。两个问题互为 Fenchel 对偶,正则化 $R$ 在两边是同一个东西。
对比 #
| Primal(SAP) | Dual | |
|---|---|---|
| 未知量 | 速度 $v$ | 冲量 $\gamma$ |
| 规模 | 自由度数 | 3 × 接触数 |
| 约束 | 无 | $\gamma \in \mathcal F$ |
| 矩阵 | $M + J^\top GJ$,稀疏,跟树结构一致 | $W + R = JM^{-1}J^\top + R$,往往稠密 |
| 典型解法 | Newton + line search,收敛快 | PGS(逐个接触投影)、锥规划、内点法 |
| 优点 | 无约束,收敛快,有全局收敛保证 | 接触少、自由度多时规模小;PGS 实现简单 |
| 缺点 | 规模随自由度增长;需要正则化静摩擦 | 有约束;PGS 在质量比大时收敛很慢 |
和你在对齐的 MuJoCo 的关系 #
MuJoCo 两种都有:Newton 和 CG 求解器在 primal 空间(加速度)里工作,PGS 在 dual 空间(约束力)里工作。它也有正则化 $R$,作用和 SAP 的 $R$ 一样。SAP 和 MuJoCo 默认的 Newton 求解器都是 primal 的,所以它们的结构很像。这也是我们能把刚体场景对齐到 MuJoCo Warp 的原因之一。
法向力模型 #
法向力用线性 Kelvin–Voigt 模型,并且取步末的穿透量:
\[\phi(v_n) \approx \phi_0 + h\,v_n,\qquad f_n = -k\,(\phi + \tau v_n) = -k\big(\phi_0 + (h+\tau)v_n\big)\]我现在有点迷糊,我们一点点来,线性 Kelvin–Voigt 模型是啥
Kelvin–Voigt 模型是什么 #
它就是一根弹簧和一个阻尼器并联:
┌──/\/\/\/──┐ 弹簧 k
────┤ ├────
└───[ | ]───┘ 阻尼 c
两个元件的伸缩量相同,所以力直接相加:
\[f = k\,\delta + c\,\dot\delta\]其中 $\delta$ 是压缩量。弹簧项和压缩量成正比,阻尼项和压缩速度成正比。”线性”指的是两项都是一次的。Drake 里还有非线性的 Hunt–Crossley 模型,那是另一回事。
习惯上会把阻尼写成 $c = k\tau$:
\[f = k\,(\delta + \tau\,\dot\delta)\]$\tau = c/k$ 的单位是秒,就是图里的 dissipation time scale。它表示阻尼和弹簧的相对强弱:$\tau = 0$ 是纯弹簧,碰撞后会完全弹回;$\tau$ 越大,能量耗散越多。
法向冲量形式 #
好,接着做下一步:把力变成冲量,再整理成 $R_n^{-1}(\hat v_n - v_n)$ 的形式。
第一步:力乘以 $h$,得到冲量 #
求解器解的是速度,动量方程里用的是冲量(力 × 时间),所以:
\[\gamma_n = h\,f_n = -h k\big(\phi_0 + (h+\tau)\,v_n\big)\]第二步:把 $(h+\tau)$ 提出来 #
\[\gamma_n = -h k (h+\tau)\Big(\frac{\phi_0}{h+\tau} + v_n\Big) = \underbrace{h k (h+\tau)}_{R_n^{-1}}\Big(\underbrace{-\frac{\phi_0}{h+\tau}}_{\hat v_n} - v_n\Big)\]这就是:
\[\gamma_n = R_n^{-1}\,(\hat v_n - v_n),\qquad R_n = \frac{1}{h k (h+\tau)},\qquad \hat v_n = -\frac{\phi_0}{h+\tau}\]为什么是除h+tau,tau这个不是当时法向力里面和速度耦合的吗 #
回到这个式子:
\[f_n = -k\big(\phi_0 + h\,v_n + \tau\,v_n\big)\]括号里有两项都乘着 $v_n$:
- $h\,v_n$ 来自隐式离散化:这一步走完,位置变了 $h v_n$;
- $\tau\,v_n$ 来自阻尼器:速度本身产生的阻尼力。
合起来,$v_n$ 的系数就是 $(h+\tau)$。$\hat v_n$ 的定义是”力为零时的速度”,也就是解方程:
\[\phi_0 + (h+\tau)\,v_n = 0 \;\Rightarrow\; v_n = -\frac{\phi_0}{h+\tau}\]所以除以 $(h+\tau)$ 并没有引入新的物理,只是求这个线性函数的零点。系数是什么就除以什么。$\tau$ 之所以在分母里,恰恰是因为它和 $v_n$ 耦合。
推出法向力和法向冲量之后,怎么体现摩擦问题优化的? #
第一步:只有法向的一维例子 #
一个质量为 $m$ 的方块落向地面。没有接触力时,它这一步的速度会是 $v^*$。
动量方程:
\[m(v - v^*) = \gamma_n(v)\]Kelvin–Voigt 推出来的法向冲量(只推不拉,所以有个 $\max$):
\[\gamma_n(v) = \max\big(0,\ R_n^{-1}(\hat v_n - v)\big)\]这两条联立,就能解出 $v$。现在换个角度,定义一个势能:
\[\ell(v) = \tfrac12 R_n^{-1}\big(\max(0,\ \hat v_n - v)\big)^2 = \tfrac12 R_n\gamma_n^2\]对它求导,正好是 $\ell’(v) = -\gamma_n(v)$。于是考虑这个优化问题:
\[\min_v\ \underbrace{\tfrac12 m(v - v^*)^2}_{\text{动能项}} + \underbrace{\ell(v)}_{\text{接触势能}}\]令导数为零:
\[m(v - v^*) - \gamma_n(v) = 0\]这就是动量方程。 所以”解动量方程”和”求这个函数的最小值”是同一件事。而且这个函数是凸的(两项都是凸的),所以最小值唯一,可以用 Newton 法求。
第二步:加上摩擦,$\max$ 变成了锥投影 #
一维时,”只推不拉”就是一个 $\max(0,\cdot)$。它其实就是把 $y_n$ 投影到集合 ${\gamma_n \ge 0}$ 上。
| 加上摩擦后,冲量变成三维的,允许的集合从半直线 ${\gamma_n \ge 0}$ 变成了摩擦锥 ${ | \gamma_t | \le \mu\gamma_n}$。 |
| 一维(只有法向) | 三维(法向 + 摩擦) | |
|---|---|---|
| 试探冲量 | $y_n = R_n^{-1}(\hat v_n - v_n)$ | $y = R^{-1}(\hat v - v_c)$ |
| 限制 | $\gamma_n \ge 0$ | $\gamma \in \mathcal F$(摩擦锥) |
| 怎么得到冲量 | $\max(0, y_n)$ | 在 $R$ 范数下投影到 $\mathcal F$ |
| 势能 | $\tfrac12 R_n\gamma_n^2$ | $\tfrac12\gamma^\top R\gamma$ |
| 关键性质 | $\ell’ = -\gamma_n$ | $\nabla_{v_c}\ell = -\gamma$ |
锥投影就是 $\max(0,\cdot)$ 的三维版本。 摩擦就是通过这一步进入问题的:它决定了 $\gamma_t$ 怎样被截断,同时也决定了 $\ell$ 的形状。而选 $R$ 范数,就是为了让最后一行的梯度关系在三维时依然成立。
第三步:整个系统 #
多个接触、多个自由度时,接触速度是 $v_{c,i} = J_i v$,问题变成:
\[\min_v\ \tfrac12(v - v^*)^\top M(v - v^*) + \sum_i \ell_i(J_i v)\]用链式法则求梯度,令其为零:
\[M(v - v^*) - \sum_i J_i^\top\gamma_i = 0\]这还是动量方程:广义动量的变化等于所有接触冲量(通过 $J^\top$ 搬回广义坐标)之和。
所以有两层”优化” #
- 内层(每个接触各自做,有闭式解):给定 $v_c$,在 $R$ 范数下把 $y$ 投影到锥上,得到 $\gamma$。这一步编码了摩擦的物理:粘滞、滑动、分离三种情况。
- 外层(全局,用 Newton 法):对整体速度 $v$ 最小化上面的总代价。每次 Newton 迭代都要调用内层来得到 $\gamma_i$ 和它的导数 $G_i = -\partial\gamma_i/\partial v_c$,然后解:
所以,Kelvin–Voigt 给出的是法向的物理,正则化给出的是切向的物理,锥投影把两者拼在一起并加上 Coulomb 限制。最后,”$\nabla\ell = -\gamma$”这个性质把它们变成了一个可以用 Newton 法求解的凸优化问题。
到底什么是“在 $R$ 范数下投影到 $\mathcal F$” #
我们一个词一个词来,最后用一组具体数字算一遍。
1. “投影”:在集合里找离某个点最近的点 #
给定一个点 $y$ 和一个集合 $\mathcal F$:
- 如果 $y$ 在 $\mathcal F$ 里,投影就是 $y$ 自己;
- 如果不在,就在 $\mathcal F$ 里找一个离 $y$ 最近的点。
最简单的例子是投影到半直线 ${\gamma_n \ge 0}$ 上:$y_n = 3$ 就还是 3,$y_n = -2$ 最近的点是 0。结果就是 $\max(0, y_n)$。
2. “$\mathcal F$”:摩擦锥 #
$\mathcal F = {\gamma : |\gamma_t| \le \mu\gamma_n}$,就是所有物理上允许的冲量:法向只能推,摩擦不能超过 $\mu$ 倍法向。为了画图,只看一个切向方向,它就是一个 V 字形区域:
γ_n
↑
╲ │ ╱
╲ 𝓕 │ ╱ 边界:|γ_t| = μ γ_n
╲ │ ╱
╲ │ ╱
───────╲│╱────────→ γ_t
3. “在 $R$ 范数下”:用什么尺子量”最近” #
“最近”取决于怎么量距离。
欧氏距离:$d^2 = \Delta\gamma_t^2 + \Delta\gamma_n^2$。到 $y$ 等距离的点组成圆。
$R$ 范数:$d^2 = R_t\,\Delta\gamma_t^2 + R_n\,\Delta\gamma_n^2$。到 $y$ 等距离的点组成椭圆。$R_t$ 很小,所以椭圆沿 $\gamma_t$ 方向拉得很长:在切向走很远,距离才增加一点点;在法向稍微动一下,距离就增加很多。
投影的几何做法:以 y 为中心画等距离曲线,慢慢放大,第一次碰到锥的那个点就是投影结果 γ。
欧氏:圆 R 范数:扁椭圆
γ_n γ_n
↑ ╱ ↑ ╱
│ ╱ ●γ │ ╱
│ ╱ ╱ ╲ │ ╱
│ ╱ ( ×y ) ──│●─(─────×y─────)
│ ╱ │╱γ
────────┼──────────→ γ_t ─────────┼──────────→ γ_t
圆往斜上方碰到锥边 椭圆横着拉长,几乎水平地碰到锥边
→ γ_n 被抬高很多 → γ_n 几乎不变,只砍了 γ_t
4. 算一组数字 #
取 $\mu = 0.5$,$R_t = 0.01$,$R_n = 1$,试探冲量 $y = (y_t, y_n) = (4,\ 1)$。检查:$\lvert y_t\rvert = 4 > \mu y_n = 0.5$,在锥外面,需要投影。
欧氏投影:
\[\gamma_n = \frac{y_n + \mu|y_t|}{1+\mu^2} = \frac{1 + 2}{1.25} = 2.4,\qquad \gamma_t = 1.2\]法向冲量从 1 变成了 2.4。只因为物体在滑,法向力就翻了一倍多,物理上说不通。
$R$ 范数投影($\tilde\mu = \mu R_t/R_n = 0.005$):
\[\gamma_n = \frac{y_n + \tilde\mu|y_t|}{1+\mu\tilde\mu} = \frac{1 + 0.02}{1.0025} \approx 1.017,\qquad \gamma_t = \mu\gamma_n \approx 0.509\]法向几乎没变,摩擦从 4 被截到了 0.509,正好落在锥边上,就是 Coulomb 滑动摩擦。
5. 为什么 $R$ 范数这把尺子是对的 #
$y_t = 4$ 之所以这么大,是因为 $y_t = -v_t/R_t$,而 $R_t$ 被人为地设得很小(极硬的粘性摩擦)。所以这个大数字只是正则化”放大”出来的,并不是一个真实的物理需求。
$R$ 把冲量换算回速度:切向改动 $\Delta\gamma_t$,对应的速度只变 $R_t\Delta\gamma_t$,很小;法向改动 $\Delta\gamma_n$,对应的速度变 $R_n\Delta\gamma_n$,很大。$R$ 范数 $\Delta\gamma^\top R\,\Delta\gamma$ 的单位是”冲量 × 速度”,也就是能量。所以:
在 $R$ 范数下投影 = 找一个物理上允许的冲量,使它和试探冲量之间的”能量差”最小。
这个能量差会按每个方向各自的刚度来衡量,而不是把不同刚度放大出来的数字直接放在一起比较。
写成公式就是图里 (26) 式的左半边:
\[\gamma = \arg\min_{\gamma\in\mathcal F}\ (\gamma - y)^\top R\,(\gamma - y)\]此外还有上一节说的数学上的好处:用这把尺子,才能保证 $\nabla_{v_c}\ell = -\gamma$,从而把整个时间步变成一个凸优化问题。
y是不是就是投影前的gamma #
对,可以这么理解。$y$ 就是投影前的冲量:
\[y = R^{-1}(\hat v - v_c)\]它是在不管摩擦锥限制的情况下,只按弹簧阻尼(法向)和粘性摩擦(切向)算出来的冲量。投影之后才是真正用的冲量:
\[\gamma = P_{\mathcal F}(y)\]- 粘滞时,$y$ 本来就在锥里,$\gamma = y$,两者相同;
- 滑动时,$\gamma$ 是 $y$ 被截到锥面上的结果;
- 分离时,$\gamma = 0$。
有一点要注意:$y$ 和 $\gamma$ 都依赖于当前的接触速度 $v_c$,不是固定不变的数。Newton 法每迭代一次,$v$ 就会变,$v_c = Jv$ 跟着变,$y$ 要重新算,然后再投影得到新的 $\gamma$。代码里也是这样:_eval_contact_point 每次调用都先由 vc 算出 y,再投影得到 gamma。
所以准确地说,$y$ 是”在当前速度猜测下,投影前的冲量“。
还是没懂 #
还是没懂,首先我在优化一个系统,一个包含frictional contact考量的系统,会有个未知的速度变量让我求解。然后我定义了法向冲量的规则,我能通过这个速度变量得到法向冲量。同时,我是不是也应该有一套规则,直接从速度变量算出切向冲量。但这个时候,我需要去检查,法向冲量和切向冲量耦合在一起是不是在摩擦锥里。
对,你的理解完全正确。我按你的思路把它整理成一个流程,再补上最后一块。
你说的流程 #
给定速度变量的当前值 $v$,先算接触速度 $v_c = Jv$,然后:
1. 法向规则(Kelvin–Voigt):从速度直接算出法向冲量
\[y_n = R_n^{-1}(\hat v_n - v_n)\]2. 切向规则(粘性摩擦):从速度直接算出切向冲量
\[y_t = -v_t / R_t\]3. 检查:两者合在一起,$(y_t, y_n)$ 在不在摩擦锥里?
这三步就是你说的。$y$ 就是这两条规则直接算出来的结果,还没经过检查。
你缺的是第 4 步:检查不通过怎么办 #
4. 修正:
检查通过($ y_t \le \mu y_n$):两条规则的结果都合法,直接用,$\gamma = y$。这时切向冲量确实就是粘性规则给出的,而这个粘性规则极硬,所以物体几乎不滑。这种情况起了个名字叫”粘滞”。 - 检查不通过:要把它修正成锥里的某个点。投影就是”怎么修正”的规则:找锥里离 $y$ 最近($R$ 范数)的点。结果是摩擦被截到 $\mu\gamma_n$(滑动),或者全部为零(分离)。法向也可能被顺带微调一点。
所以,1 到 4 合起来,就是一个完整的函数:
\[v \;\to\; v_c = Jv \;\to\; y \;\to\; \gamma = P_{\mathcal F}(y)\]输入速度,输出一个保证在锥里的冲量。
容易混淆的一点:检查不是优化问题的约束 #
你可能会以为”摩擦锥”是加在优化问题上的一个约束,即优化器要在满足锥约束的前提下去找 $v$。不是这样的。
检查和修正都发生在冲量函数的内部。不管优化器试的是什么 $v$,这个函数吐出来的 $\gamma$ 永远在锥里,因为它已经被投影过了。所以优化器本身没有任何约束:
\[\min_v\ \tfrac12\|v - v^*\|_M^2 + \sum_i \ell_i(J_i v)\]它只管找一个 $v$,使得动量方程 $M(v - v^*) = \sum_i J_i^\top\gamma_i(J_i v)$ 成立。这就是 SAP 名字里 “Unconstrained” 的意思:锥的限制被藏进了 $\gamma(v_c)$ 这个函数,而不是作为优化问题的约束出现。
切向规则是怎么定义出来的 #
切向规则不是从物理推出来的,而是人为选的。法向规则有物理来源(弹簧阻尼),切向没有。下面说明它是怎么被”选”出来的。
1. 想要的东西写不成函数 #
我们需要一条”从速度算出切向冲量”的规则,也就是一个函数 $\gamma_t = g(v_t)$。
真实的静摩擦是:$v_t = 0$,冲量可以是 $[-\mu\gamma_n, \mu\gamma_n]$ 里的任意值。在 $v_t = 0$ 这一点上,一个速度对应无数个冲量,它不是函数。所以没法直接用。
2. 那就选一个最简单的、近似它的函数 #
最简单的选择是一条过原点、很陡的直线:
\[\gamma_t = -\frac{v_t}{R_t}\]这相当于在切向加了一个阻尼器,阻尼系数 $c_t$ 很大:$f_t = -c_t v_t$,乘以 $h$ 得到冲量,于是 $R_t = 1/(h c_t)$。只要 $R_t$ 足够小,不滑就需要很大的冲量,所以 $v_t$ 会非常接近 0,这样就近似了 $v_t = 0$。
3. 为什么正好是这个形式 #
关键是要和法向规则长得一样。法向是:
\[\gamma_n = R_n^{-1}(\hat v_n - v_n)\]切向写成同样的形式,取 $\hat v_t = 0$(切向没有弹簧,没有”想回去的位置”,目标就是不滑):
\[\gamma_t = R_t^{-1}(\hat v_t - v_t) = R_t^{-1}(0 - v_t)\]于是三个方向可以统一写成:
\[y = R^{-1}(\hat v - v_c),\qquad R = \text{diag}(R_t, R_t, R_n)\]这样统一的好处是:后面的投影(在 $R$ 范数下)、代价 $\ell = \tfrac12\gamma^\top R\gamma$,以及 $\nabla\ell = -\gamma$ 这个性质,都可以对三个方向一起成立。如果切向选了别的形状(比如 Lagged 那种光滑曲线),就要换一套构造方法。
4. 最后定 $R_t$ 的大小 #
这是唯一需要权衡的地方:
- 太大:蠕滑明显,抓不住东西;
- 太小:条件数差,Newton 和 PCG 难收敛。
选 $R_t = \sigma w$,让蠕滑比例固定为约 $\sigma$,条件数固定为 $1/\sigma$,与物体轻重无关。这就是前面讲过的内容。
总结:切向规则 = “用一个极硬的线性阻尼器近似静摩擦”。选线性,是为了和法向统一成 $R^{-1}(\hat v - v_c)$;选 $\hat v_t = 0$,是因为目标就是不滑;选 $R_t = \sigma w$,是为了在蠕滑和条件数之间取得一个与尺度无关的折中。
MuJoCo 其实也是同样的思路:它在每个约束方向(包括摩擦方向)上都加了一个正则化项 $R$。SAP 的这套构造和它是一脉相承的。
这两个速度是怎么回到摩擦锥的 #
先澄清一点:摩擦锥在冲量空间里,不在速度空间里。速度本身不需要”回到锥里”,需要在锥里的是冲量。
速度是怎么变成锥里的冲量的 #
分两步:
第一步:两条规则把速度换成冲量(这一步还不管锥)
\[v_c = (v_t, v_n) \;\longrightarrow\; y = \Big(-\frac{v_t}{R_t},\ \frac{\hat v_n - v_n}{R_n}\Big)\]第二步:在冲量空间里检查、投影
\[y \;\longrightarrow\; \gamma = P_{\mathcal F}(y) \in \mathcal F\]所以,”回到锥里”的是 $y$(投影前的冲量),而不是速度。速度只是输入。
反过来看:三种情况在速度空间里长什么样 #
把 $y$ 的定义代进三个区域的判断条件,就能直接用速度来写。
粘滞:$\lvert y_t \rvert \le \mu y_n$ \(\frac{\lvert v_t\rvert}{R_t} \le \mu\frac{\hat v_n - v_n}{R_n} \quad\Longrightarrow\quad \|v_t\| \le \hat\mu\,(\hat v_n - v_n),\qquad \hat\mu = \mu\frac{R_t}{R_n}\) $\hat\mu$ 很小,所以粘滞时滑移速度必须非常小,和法向压得多紧成正比。
分离:$y_n + \hat\mu,\lvert y_t\rvert \le 0$ \(\frac{\hat v_n - v_n}{R_n} + \mu\frac{R_t}{R_n}\cdot\frac{\|v_t\|}{R_t} \le 0 \quad\Longrightarrow\quad v_n - \hat v_n \ge \mu\,\|v_t\|\) 也就是法向速度超过平衡点足够多,物体在分开。
滑动:介于两者之间。
画在速度空间里(横轴是 $\lvert v_t\rvert$,纵轴是 $v_n - \hat v_n$):
v_n − v̂_n
↑ ╱
│ 分离 ╱ 斜率 1/μ:v_n − v̂_n = μ‖v_t‖
│ ╱
│ ╱
│ ╱ 滑动
─────┼────────────────→ ‖v_t‖
│╲
│ 粘滞(一条极窄的楔形,斜率 1/μ̂,几乎贴着纵轴)
↓
两个空间对照:
| 冲量空间($y$) | 速度空间($v_c$) | |
|---|---|---|
| 粘滞 | 摩擦锥内部 $\lvert y_t\rvert \le \mu y_n$ | 贴着纵轴的极窄楔形 $\lvert v_t\rvert \le \hat\mu(\hat v_n - v_n)$ |
| 分离 | 锥尖下方的区域 | 锥 $v_n - \hat v_n \ge \mu\lvert v_t\rvert$ |
| 滑动 | 其他 | 其他 |
这两个图是对偶的:冲量空间里的摩擦锥,对应速度空间里的”分离锥”。
分离条件 $v_n - \hat v_n \ge \mu\lvert v_t\rvert$ 还再次暴露了前面说的 gliding 伪影:滑得越快,物体需要更大的法向速度才算”分离”。这正是法向和切向在投影里耦合的结果。