1. 恢复项的方向与单位
取 K=100\,\mathrm{s^{-2}}、B=20\,\mathrm{s^{-1}}、d=0.8、r=-0.02\,\mathrm m、u=0.1\,\mathrm{m/s}。求两项参考加速度及总值。
解答恢复项的方向与单位
位置误差要求向上恢复,向上的离开速度则引起向下阻尼;总目标由这两项相加确定。实际法向力还需与自由加速度比较。
球体进入接触边界以后,恢复力应当多大?这既取决于位置与速度,也取决于系统原有的加速度,以及接触方向上的惯性。上一章给出了 Ja=Ja_u+Af。本章在这个关系上建立软约束:先给出希望达到的加速度,再用正则量控制实际响应与目标之间的差距。
贯穿例仍为质量 2\,\mathrm{kg}、半径 0.2\,\mathrm m 的球体,姿态固定,仅能平移。法向朝上,重力加速度为 -9.81\,\mathrm{m/s^2}。位置误差取 r=\texttt{dist}-\texttt{includemargin},法向速度取 u=J_nv。本章的一维推导采用当前已激活的法向行;接触是否进入 EFC 由上一章的距离判定决定。
一根弹簧受压后产生恢复力,一个黏性阻尼元件在运动时产生与速度相反的力。设位移误差为 r、速度为 u=\dot r,弹性系数和阻尼系数分别为 k_s,b_s,则
把两种力除以质量,便得到恢复加速度系数。它们的单位分别为时间的平方倒数和时间的倒数。
将 Newton 方程除以质量,位置项与速度项的系数分别变成 k_s/m 和 b_s/m。自然角频率 \omega_0=\sqrt{k_s/m} 与阻尼比 \zeta=b_s/(2\sqrt{mk_s}) 将它们写成标准的二阶恢复方程。
代回上式得到标准形式
例如 m=2\,\mathrm{kg}、k_s=200\,\mathrm{N/m}、b_s=40\,\mathrm{N\,s/m},有 \omega_0=10\,\mathrm{s^{-1}}、\zeta=1。若 r=-0.01\,\mathrm m、u=-0.1\,\mathrm{m/s},弹簧与阻尼分别向上提供 2\,\mathrm N 和 4\,\mathrm N,合成恢复加速度 3\,\mathrm{m/s^2}。
MuJoCo 用类似的恢复结构建立参考伪加速度。记位置恢复系数为 K,速度系数为 B,阻抗为 d。当前固定平面的法向雅可比恒定,参考值为
当 r<0 时,位置项向上;当 u<0 时,阻尼项也向上;离开平面时,阻尼项改变符号。参考值表达希望恢复的运动趋势,实际力还需通过惯量与允许力的范围求出。若某个几何残差满足 \ddot r=Ja+c,将指定的残差加速度转换为伪加速度时,还要减去曲率项 c。本地源码对 connect 和 weld 等式执行这一修正。
参考加速度给出了恢复运动的目标。下一步要决定系统愿意以多大的力去接近它:惯性较大的方向需要更大的力,允许保留较多目标偏差的约束则产生更柔和的响应。软约束方程把这两种影响放到同一次求解中。
先考虑一条双边约束或当前处于二次区域内的法向行。若精确达到目标,则应满足 Ja=a_{\rm ref}。软约束允许保留一部分目标偏差,并令力与这部分偏差成比例:
式(11.6)回答给定接触力会产生什么加速度。本节增加一条由加速度偏差确定力的软关系,将两者联立即可求出实际响应。
D 是加速度误差到力的响应系数。R 越大,同样的误差产生的力越小。在平移方向中,R 的单位是质量的倒数,D 的单位是质量。将这条关系与动力学合并,即可同时求得力和加速度。
在这一受力分支中,动力学给出 Ja=Ja_u+Af,软约束给出 Rf=a_{\rm ref}-Ja。两个式子共同决定力:分子是尚需补足的加速度,分母是惯性响应与软约束正则量之和。最终加速度处于自由值与目标值之间。
因为 A\geq0、R>0,分母为正:
实际伪加速度成为自由值与参考值的加权组合。定义 d_{\rm eff}=A/(A+R) 后,两者权重分别为 1-d_{\rm eff} 与 d_{\rm eff}。
固定 A>0 和参考目标,可以先看两端情形。当 R\to0 时,Ja\to a_{\rm ref},得到精确达到加速度目标的硬约束极限;当 R 增大时,力减小,实际加速度逐渐靠近自由值。这里的“硬”描述本次目标的精确程度,目标中仍可包含对已有位置和速度误差的恢复项。
从已求得的标量解出发,分别取极限:
一条长度残差行的有效质量为 m_{\rm eff}=1/A。硬约束力等于有效质量乘上所需加速度修正;有限 R 把这个力乘以小于一的因子 A/(A+R)。多行系统还要检查目标是否相容、约束是否冗余。
对于单独一条法向行,允许力为 f\geq0。在这一条件下,二次目标的最优解取为
目标导数为 (A+R)f+Ja_u-a_{\rm ref}。若无约束极小点为正,它位于允许区间内部,导数为零。若极小点为负,目标在 f\geq0 上从边界起单调增加,最小值位于 f=0。因此法向行具有接触受力与零力两个分支。恢复目标小于自由伪加速度时,最优法向力为零。
多条双边行合在一起时,正则矩阵 R 为正对角矩阵,方程仍是 (A+R)f=-b,其中 b=Ja_u-a_{\rm ref}。跨行耦合由 A 保留。摩擦接触的各方向还共享一个允许力锥,求解时按接触块处理它们的联系。
逐行正的正则量为每个力方向增加了正曲率。即使两行在广义空间中产生相同作用,正则化目标仍会选出唯一的力分配。
上一章证明了 A 半正定。对任意非零 x,
因此双边二次目标严格凸,冗余行也有唯一的正则化力分配。计算满足 (A+R)f=-b 的解后,可以再用 a=a_u+M^{-1}J^{\mathsf T}f 返回广义空间。
前一节的正则量控制达到目标加速度所需的力。换一个质量不同的物体,同一正则量会产生不同响应,因此参数还需要参照系统在约束方向上的惯性尺度。阻抗将这种相对软硬程度表达成一个便于调节的数。
MuJoCo 以阻抗 d 和参考逆惯量尺度 \widehat A 构造基础正则量:
阻抗靠近一时,正则量减小,响应更接近参考目标;阻抗靠近零时,正则量增大,响应更接近自由运动。源码将阻抗限制在 [0.0001,0.9999],并为 R 设置正的数值下界。这里的 \widehat A 取自上一章的 diagApprox 或精确对角模式。
设定阻抗 d 先通过参考惯性尺度 \widehat A 生成 R,实际响应再通过精确惯性 A 求得。独立行的真实混合权重为 d_{\rm eff}=A/(A+R);当两种惯性尺度相同时,它才恰好等于输入的 d。
独立标量行且 \widehat A=A>0 时,约去公共因子 A:
例如 A=\widehat A=0.5\,\mathrm{kg^{-1}}、d=0.9,则 R=1/18\,\mathrm{kg^{-1}},D=18\,\mathrm{kg}。若 Ja_u=-9.81、a_{\rm ref}=2,有 f=(2+9.81)/(0.5+1/18)=21.258\,\mathrm N,最终加速度为 0.819\,\mathrm{m/s^2}。
若改用 \widehat A=1,则 R=1/9,实际权重变为 0.5/(0.5+1/9)=9/11。设定阻抗仍为 0.9,实际混合比例则由两种惯性尺度共同决定。
设定阻抗相同,惯性尺度估计不同,实际混合比例也会改变。图中把横轴固定为输入 d,分别画出它本身和 d_{\rm eff};比值 \widehat A/A 为一时,两条曲线应该重合。
由 R=\frac{1-d}{d}\widehat A,较大的 \widehat A 产生较大的正则量。于是目标权重 d_{\rm eff}=\frac{A}{A+R} 减小,响应更靠近自由加速度,恢复作用更弱。在下图将逆惯量比值调到大于一,可比较实际权重与输入阻抗。
改变比值 \widehat A/A,比较设定阻抗与实际混合权重。横轴为 d,两条曲线在 \widehat A=A 时重合,图例可以分别控制。
以 d=0.9 为例,惯性尺度比取 1 时实际权重也是 0.9;取 2 时,代入 d_{\rm eff}=d/[d+(1-d)\widehat A/A] 得到 9/11\approx0.8182。图上同一个横坐标对应的两条纵值正是这两个权重。
参考逆惯量偏大时,同一阻抗会生成更大的正则量,实际响应偏向自由加速度;参考逆惯量偏小时,则更靠近目标。这解释了调节阻抗时还需要关注当前方向的惯性尺度。
多行系统的 A 含非对角项,且摩擦方向的 R 会按接触锥重新调整。此时可直接使用矩阵方程分析响应;独立标量行的加权平均提供局部直观解释。
在独立行且 \widehat A=A 的条件下,阻抗权重还可以把软约束换算成通常的弹簧阻尼。若自由加速度和曲率项均为零、阻抗恒定,且采用双边恢复或处于单边受力分支,则实际恢复方程为 \ddot r+dB\dot r+Kd^2r=0。因此位置系数包含两次阻抗:参考目标中的一次,以及目标变成实际响应时的一次。
在零自由加速度、零曲率且处于受力分支时,代入 a_{\rm ref}=-B\dot r-Kdr:
与 f=-b_{\rm eff}\dot r-k_{\rm eff}r 逐项比较,得到 b_{\rm eff}=m_{\rm eff}dB、k_{\rm eff}=m_{\rm eff}Kd^2。这组固定系数对应恒定阻抗;位置相关阻抗则让这些权重随当前误差改变。
给出刚度和阻尼后,还需要理解它们会让误差多快衰减、是否往复振荡。时间常数和阻尼比直接描述这些运动特征,因而可以用它们来生成参考加速度的系数。
式(12.1)规定参考值的组成,式(12.3)规定系统实际达到它的比例。因此,把参数解释为恢复时间时,要同时考虑参考系数和阻抗。
标准格式的 solref 为两个正数 (t_c,\zeta),分别指定时间常数和阻尼比。设 solimp 的第二个参数为 d_w。在通常的非退化数值范围内,源码生成
这些系数的缩放可以从双边线性恢复模型推出。双边模型允许恢复力沿正、负两个方向作用。单边接触在受力分支满足同一方程;进入零力分支或退出 EFC 后,运动按相应分支继续演化。取独立标量行、\widehat A=A、零自由加速度、恒定阻抗 d=d_w,并取零曲率。双边恢复运动便满足下面的二阶方程。
希望阻尼项系数为 2/t_c,弹性项系数为 1/(t_c^2\zeta^2)。与一般形式 \ddot r+2\zeta\omega_0\dot r+\omega_0^2r=0 比较,有 \omega_0=1/(t_c\zeta)。逐项相等给出
再分别除以 d_w 与 d_w^2,即得标准格式。阻抗随位置变化或存在外载荷时,应代入完整方程计算响应。
在上述双边线性模型中,令初速度为零。\zeta<1 时位移衰减并振荡,\zeta=1 时得到重根形式,\zeta>1 时由两个不同的衰减指数相加。三种响应都由同一个特征方程的根确定。
代入 r=e^{\sigma t},并除去非零的指数因子:
取 r(0)=r_0、\dot r(0)=0,记 y=r/r_0。当 0<\zeta<1,令 \omega=t_c^{-1}\sqrt{\zeta^{-2}-1},有
实部给出衰减,虚部给出振荡。当 \zeta=1,重根解的初值确定为
当 \zeta>1,两根为负且互异,由 C_1+C_2=1、\sigma_1C_1+\sigma_2C_2=0 解得
在固定 t_c 下增大阻尼比,会降低位置恢复系数并保留速度系数,因而过阻尼时出现更慢的衰减分量。
恢复速度由整条时间曲线体现。下面固定初速度为零,用同一初始位移比较三种阻尼情形;横轴是实际时间,纵轴除以初始位移,使曲线只反映时间常数与阻尼比的作用。
图中展示双边线性恢复方程的解析解,采用恒定 d=d_w、\widehat A=A、零自由加速度与零初速度,纵轴为归一化位移 r(t)/r(0)。参数从 t_c=0.3\,\mathrm s 开始,便于观察恢复过程;播放进度按真实时间推进,共 2\,\mathrm s。
临界阻尼且 t_c=0.3\,\mathrm s 时,在 t=t_c 的读数为 r(t)/r(0)=2/e\approx0.7358;在 t=2t_c 时为 3/e^2\approx0.4060。曲线的每个进度点都直接取解析式的当前时间值,因此可以据此核对时间轴与归一化位移。
固定时间常数时,提高阻尼比会降低位置恢复系数,而速度系数保持相同。过阻尼曲线因此出现更慢的衰减成分。把这组参数用于单边接触时,运动还会在零力和接触退出处转入相应分支。
开启 refsafe 时,正格式使用的时间常数会被夹到至少两倍步长:t_c^{\rm used}=\max(t_c,2h)。例如步长 h=0.005\,\mathrm s,输入 t_c=0.004\,\mathrm s 时,系数实际使用 0.01\,\mathrm s。这一规则把恢复时间与积分分辨率联系起来,具体的稳定性仍与积分方法和模型有关。
直接格式把两个非正数解释为刚度和阻尼的负值。写成 solref=(-\kappa,-\beta),其中 \kappa,\beta\geq0,有
直接格式沿用相同的独立、恒定阻抗条件后,实际恢复方程的速度和位置系数就是 \beta 与 \kappa。因此两种输入格式可以逐项匹配,而无需重新求一次运动轨迹。
仍在上述独立、恒定阻抗条件下:
因此与标准格式产生相同响应的参数为
例如 (t_c,\zeta)=(0.02,1) 对应直接格式 (-2500,-100)。直接格式中的零允许关闭对应项;两个数都为零时,两项均为零。
直接格式按指定系数计算,refsafe 的时间常数夹取仅用于正格式。若一个参数为正,另一个为零或负,源码发出混合格式警告,并恢复默认 solref=(0.02,1),再应用时间步安全规则。源码还以 mjMINVAL 保护系数公式的分母。
接触刚进入响应区时可以较软,压缩加深后逐渐变硬。为表达这种变化,阻抗需要成为误差大小的函数;曲线的两端确定响应强弱,中间的连接方式决定过渡是否平滑。
solimp 的五个参数依次为 (d_0,d_w,w,m_p,p):零误差处阻抗、宽度边界处阻抗、过渡宽度、中间连接点和幂指数。先将误差归一化为 x=|r|/w,再用形状函数连接两端。
参数经过源码约束后,d_0,d_w,m_p\in[0.0001,0.9999],w\geq0,p\geq1。两端阻抗可按任意大小顺序给定:d_w>d_0 时随误差幅度增大,d_w<d_0 时随误差幅度减小。
曲线的中间参数 m_p 同时指定连接点的横、纵坐标。两段分别从左端和右端建立幂函数,在连接点具有相同函数值与斜率;p>1 时还与两侧常值段平滑相接。
第一段设为 ax^p,要求连接点为 (m_p,m_p),因此 am_p^p=m_p,得到 a=m_p^{1-p}。第二段从右端写成 1-b(1-x)^p,代入同一个连接点:
两边的函数值都为 m_p。分别求导:
在连接点的左右极限均为 p,所以曲线及一阶导数连续。p>1 时两端导数为零,与常值饱和段相接;p=1 时两个表达都化为 y=x,连接点对曲线形状不再产生影响。
在过渡区 0<|r|<w,阻抗导数由形状函数斜率、宽度缩放和误差符号三部分相乘得到。阻抗只依赖误差幅度,因此正负两侧取值相同,导数方向相反。
在 0<|r|<w 的过渡区内,dx/dr=\operatorname{sgn}(r)/w,链式法则给出
例如 \texttt{solimp}=(0.2,0.8,0.1,0.25,2)、r=0.0125\,\mathrm m,有 x=0.125,
改成 r=-0.0125 时阻抗相同,导数反号。源码将导数存入 KBIP 的第四项 P。
函数入口先处理常值分支:当 d_0=d_w 或 w\leq\texttt{mjMINVAL} 时,返回 (d_0+d_w)/2,导数为零。其余分支在 x=0 和 x\geq1 返回对应端点值,存储导数取零。特别在 p=1 时,r=0 与 |r|=w 具有折点,端点处存储的零是实现的取值约定;过渡区内仍按上述单侧导数计算。
一个位置相关阻抗函数要回答两个问题:当前误差下的响应强度是多少,误差略微变化时强度又会改变多少。下图将 d 与 d^{\prime} 分别作为纵轴,可以把阻抗曲线的陡缓与导数的大小逐点对应。
改变五个参数,切换阻抗或导数。实线为当前幂指数,虚线为同一端点和宽度下的线性过渡。零宽度会进入常值分支;负误差侧的导数随符号反转。
宽度决定过渡发生的距离范围,幂指数和连接点决定范围内的形状。缩小宽度会使同样的阻抗变化集中在更短距离内,因此导数中的 1/w 也会相应增大。
目前每个误差都只用一个数值查询阻抗。空间等式与摩擦接触包含多个方向:一个物体位置偏移会同时产生三行,接触法向与摩擦方向也属于同一个接触。为让它们具有一致的恢复强度,MuJoCo 先为整组构造一个标量误差,再把查询结果共享给各行。
一条 connect、一条 weld 或一个摩擦接触包含多行。它们先由一个标量查询阻抗曲线,再把阻抗及导数写入整组。逐行的恢复误差、速度和惯性尺度则保留各自的值。
| 行组 | 查询阻抗的位置量 | 共享范围 |
|---|---|---|
| 普通标量行 | \texttt{pos}-\texttt{margin} | 当前一行 |
| connect | \|r_{\rm trans}\| | 三个平移残差 |
| weld | \|(r_{\rm trans},r_\theta)\| | 六个残差;姿态残差含 torquescale |
| 椭圆接触 | \texttt{dist}-\texttt{includemargin} | 该接触全部物理方向 |
| 棱锥接触 | \texttt{dist}-\texttt{includemargin} | 该接触全部棱行 |
一组残差先取长度 \rho=\|r\|,再查询标量函数 d(\rho)。沿哪个残差分量改变,取决于范数对该分量的导数;在 \rho>0 时,阻抗梯度沿残差向量方向。
connect 使用标量 \rho=\|r\| 查询 d(\rho)。在 \rho>0 处,d\rho=(r^{\mathsf T}dr)/\rho,因此
KBIP 中复制到各行的 P 为标量查询函数的导数 d'(\rho)。需要完整的向量梯度时,还要乘上范数的导数。weld 的查询向量已经包含姿态残差尺度,计算时使用同一个六维残差。
自由度干摩擦、肌腱干摩擦及椭圆接触的摩擦方向使用 K=0,参考值仅保留速度项。椭圆接触可通过非零的 solreffriction 为这些方向单独指定参考参数;默认的 (0,0) 表示沿用接触 solref。该字段同样进行格式校验和正格式时间常数夹取。棱锥的每条棱行含法向贡献,因而保留位置恢复项。
摩擦参数在这里有两项独立作用。摩擦系数限定可接受的切向力或力矩范围;impratio 调整法向与摩擦方向接近各自参考目标的相对强度。增大摩擦范围与减小切向正则量会沿不同途径改变结果,后续求解器再把两者合在同一个锥问题中。
基础正则量先逐行由 (1-d)\widehat A_i/d 形成。接着,摩擦接触根据 impratio 和各方向摩擦系数调整它们。对椭圆接触,记最终法向正则量为 R_n,第一摩擦方向系数为 \mu_1,则
这些调整使缩放后的摩擦方向具有相同二次权重:R_j\mu_j^2 对各摩擦方向相同。物理摩擦系数确定允许力范围,正则量则确定软响应的权重,两者共同进入后续的锥求解。
正则项为 \frac12\sum_iR_if_i^2。令 \widetilde f_i=\sqrt{R_i}f_i,它变为各方向相同权重的平方和。物理锥条件为
换变量后,每个摩擦方向相对于法向的尺度为 \mu_j\sqrt{R_j/R_n}。上述调整使它们相同:
这就是源码写入 contact.mu 的正则化锥系数。若各方向系数相同且 impratio 为一,则所有 R_j=R_n。增大 impratio 会降低摩擦方向的正则量。
棱锥分支以第一条棱行的基础值 R_0 开始,先形成 R_1=R_0/\texttt{impratio} 和 \widetilde\mu=\mu_1\sqrt{R_1/R_0},再把全部棱行统一设为
这里 R_0 来自第一条棱行的惯性尺度;它的雅可比已经含有法向和摩擦方向的组合。对当前仅平移球体,在通常近似分支中,该行尺度为 (1+\mu_1^2)/m。因此应沿棱行装配过程计算 R_0。源码完成摩擦调整后,令 D_i=1/R_i,并把 efc_diagA 重写成 R_id/(1-d),使最终存储量保持这一对应关系。
至此可以按固定顺序完成一次接触计算:由距离和速度得到恢复误差与行速度,查询阻抗,生成参考系数和参考加速度,再结合惯性及正则量求力。下面在同一个初始状态上列出这些中间量,便于检查数值与符号。
取共享模型的初始状态:球心高度 0.19\,\mathrm m,法向速度 u=-0.1\,\mathrm{m/s},margin 为 0.02\,\mathrm m。因此 r=-0.03\,\mathrm m。设置 \texttt{solref}=(0.02,1)、\texttt{solimp}=(0.9,0.95,0.02,0.5,2)、步长 h=0.005\,\mathrm s。先单独求法向行,其 A=\widehat A=1/m=0.5\,\mathrm{kg^{-1}}。
本例的压入误差已超过阻抗过渡宽度,因而使用饱和值 d=0.95。位置项与接近速度项都朝上,参考伪加速度约为 89.4737\,\mathrm{m/s^2}。
时间常数 0.02 大于两倍步长 0.01,保持原值。归一化误差为 |r|/w=1.5,处于饱和段:
代入正格式系数:
阻尼与位置项分别为
将参考值与重力加速度相减,再除以 A+R,本例得到法向力约 188.639\,\mathrm N。力返回动力学后,实际法向加速度约为 84.5095\,\mathrm{m/s^2};它与参考值的差正好产生同一个软约束力。
自由加速度为 Ja_u=-9.81,目标偏差 b=-9.81-89.4737=-99.2837。无约束的标量力为正,故位于法向受力分支:
由 Newton 方程返回:
也可用阻抗加权核对:0.05(-9.81)+0.95(89.4737)=84.5095。最终目标偏差为 Ja-a_{\rm ref}=-4.9642,乘以 -D 后重新得到同一个法向力。
参考加速度较大并不直接等于接触力较大;力还经过 A+R 的换算,并接受非负限制。下面固定球体惯性,沿位置误差改变这组输入,比较所得法向力与维持静止所需的 mg。
沿用球体质量与位置边界,改变恢复误差、速度和参考参数。曲线仅在 r<0 的激活区计算法向行;r\geq0 时该接触退出 EFC,力取零。水平线为重力平衡所需的 mg。
力曲线与 mg 的交点给出零速度时可能的支撑位置。速度不为零时,阻尼项使整条受力曲线改变,所以一个正在接近的球在同一高度可能产生更大的力;静止误差还需同时令速度为零。
配套程序 soft_contact.py 返回 K,B,d,d',R,D,a_{\rm ref},再由独立标量求解函数计算力。reference 的输入误差为恢复误差,速度为 Jv;参数 curvature 表示需要从几何残差加速度目标中减去的已知曲率项,默认取零。
from efc import model_data
from soft_contact import reference, scalar_force
model = model_data()
error = model["position"][2] - model["radius"] - model["margin"]
p = reference(error, model["velocity"][2],
model["solref"], model["solimp"], model["timestep"],
diag_approx=1/model["mass"])
result = scalar_force(model["gravity"][2], p["aref"],
1/model["mass"], p["R"])
print(p)
print(result)
在 notes/series_html 目录运行以下命令。计算仅使用 Python 标准库;检查程序分别核对分段导数、恢复方程、单边最优性与静止平衡。
python3 examples/soft_contact.py
python3 examples/check_soft_contact.py
球体静止时,法向力需要平衡重力:f_*=mg。软约束通过有限的恢复误差产生这一支撑力。因此静止状态应同时满足速度为零、最终加速度为零、位置恢复项与外载荷相配。
静止支撑满足 Ja=0、u=0。此时参考恢复项通过有限误差提供支撑力;当 \widehat A=A 时,平衡误差满足 r_*=(1-d)Ja_u/(Kd^2),其中阻抗须在未知平衡位置查询。
平衡时 Ja=0、u=0,从动力学得到 f_*=-Ja_u/A。恢复关系则给出 Rf_*=a_{\rm ref}=-Kdr_*。逐项代入:
若 \widehat A=A,用 R=(1-d)A/d 化简:
负号对应位于激活边界以内。阻抗取值应在平衡位置查询:d=d(r_*),所以位置相关阻抗通常给出一个隐式方程。
本例恒定阻抗 d=0.95 时,平衡误差为 -0.1962\,\mathrm{mm}。采用实际位置相关曲线后,平衡点附近阻抗约为 0.90005,误差增至约 -0.43696\,\mathrm{mm};物理间隙还要加回 margin。
先令 d=d_w=0.95 恒定,采用正格式系数:
共享模型的曲线在零误差处从 d_0=0.9 起步。将 d=0.9 代入作初值,得到约 -0.0004372\,\mathrm m;再按该误差查询阻抗并求解平衡关系,得到
记进入约束的边界为 m_c=0.02\,\mathrm m,此时物理间隙为 s_*=m_c+r_*\approx0.0195630\,\mathrm m,球心高度约为 0.2195630\,\mathrm m。正 margin 使本例的平衡位置位于两表面分离的区域。将 margin 设为零,物理间隙便等于恢复误差。
平衡点同时满足动力学受力平衡与软约束恢复关系。下面直接画最终法向加速度关于误差的曲线,零点就是能让球保持静止的位置。改变 margin 时,恢复误差方程保持相同,球心的物理高度随边界平移。
曲线给出激活法向分支的最终加速度,并延拓到零误差的单侧极限;与零线的交点是静止误差。改变 margin 会平移物理支撑高度,恢复误差的方程保持相同。
在零点两侧,若加速度方向分别把球推向零点,位置恢复具有局部稳定作用;运动中的衰减还由速度阻尼决定。平衡力等于重力,有限位置误差则为这个支撑力提供所需的恢复项。
在本例的独立平移方向中,A=\widehat A=1/m,质量从位置平衡公式中约去,所以同组参数可给出相同的静止误差,支撑力则随质量成比例变化。关节耦合、惯量近似和摩擦块调整改变这一简化关系,分析时可回到一般平衡方程。
本章所用函数均位于 engine_core_constraint.c。它们在同一次约束构造中依次确定参数、组内阻抗、正则量与参考加速度。
| 函数 | 计算内容 |
|---|---|
| getsolparam | 取对象参数;检查两种 solref 格式;实施 refsafe;限制 solimp 参数 |
| getposdim | 确定阻抗查询位置及共享参数的行组维数 |
| getimpedance | 按分段曲线求 d 和对标量输入的导数 |
| mj_makeImpedance | 写入基础 R 和 KBIP;调整摩擦方向;求 D 并重写最终 diagA |
| mj_referenceConstraint | 计算 Jv,形成 -Bu-Kdr 并修正 connect/weld 曲率 |
| mj_constraintUpdate_impl | 给定目标偏差后先算 -D(Ja-a_{\rm ref}),再处理各类允许力分支 |
KBIP 的四个连续分量依次为 K,B,d,d'。以下是参考加速度的源码表达:
d->efc_aref[i] = -KBIP[4*i+1]*d->efc_vel[i]
-KBIP[4*i]*KBIP[4*i+2]
*(d->efc_pos[i]-d->efc_margin[i]);阻抗导数保存在第四项,参考加速度公式本身使用第三项阻抗。对由范数查询的行组,理解第四项时还需使用前述链式法则。
官方 Modeling — Solver parameters 介绍参数的使用方式;本文的分支、存储与默认处理已按本地 MuJoCo 3.10.0 核对。
取 K=100\,\mathrm{s^{-2}}、B=20\,\mathrm{s^{-1}}、d=0.8、r=-0.02\,\mathrm m、u=0.1\,\mathrm{m/s}。求两项参考加速度及总值。
位置误差要求向上恢复,向上的离开速度则引起向下阻尼;总目标由这两项相加确定。实际法向力还需与自由加速度比较。
一条法向行有 A=0.5、R=0.1、Ja_u=-10。分别对目标 a_{\rm ref}=2 与 a_{\rm ref}=-12 求力和最终伪加速度。
第一个目标给出
第二个目标的无约束极小点为 (-12+10)/0.6=-10/3,取非负边界后 f=0,于是 Ja=-10。此时二次目标在零处的导数为 Ja_u-a_{\rm ref}=2>0,符合边界最优条件。
设 d_w=0.8、h=0.01\,\mathrm s,正格式为 (0.005,2) 且 refsafe 开启。求实际时间常数、K,B,以及相同系数的直接格式。
直接格式需要 \kappa=Kd_w^2=625、\beta=Bd_w=100,所以取 (-625,-100)。正格式原输入先经过时间常数夹取,比较时使用夹取后的值。
取 \texttt{solimp}=(0.2,0.8,0.1,0.25,2),求 r=0.0625\,\mathrm m 和 r=-0.0625\,\mathrm m 时的阻抗与导数。再把宽度改为零。
正误差处 y'=2(0.375/0.75)=1,故 d'=0.6/0.1=6\,\mathrm{m^{-1}};负误差处为 -6\,\mathrm{m^{-1}},阻抗相同。宽度为零时返回 (0.2+0.8)/2=0.5,导数为零。
connect 的残差为 r=(0.003,0.004,0)^{\mathsf T}\,\mathrm m,查询得到 d=0.8、d'=10\,\mathrm{m^{-1}}。求完整的阻抗梯度,并说明三行 KBIP 中各保存什么。
三行的阻抗均保存 0.8,第四项均保存对标量范数输入的导数 10。三个向量梯度分量来自进一步乘以范数导数。
椭圆接触的 R_n=0.1,impratio 为 2,两个滑动系数为 0.6 和 0.3。求两个切向正则量和正则化锥系数。
两方向的 R_j\mu_j^2 都为 0.018,因此正则化变量中的摩擦方向获得相同尺度。
独立法向行取 d=d_w=0.9、t_c=0.03\,\mathrm s、\zeta=1,重力为 9.81\,\mathrm{m/s^2},margin 为 0.001\,\mathrm m。求平衡误差和物理间隙。
球体在激活边界以内形成支撑,物理表面仍保有正间隙。质量若加倍,独立模型中的同组参数保持该误差,支撑力加倍。
用配套程序重算共享模型的初始法向力。然后把速度设为零,在 stationary_error 给出的误差处计算力和加速度。写出两个状态的区别,并检查 f=-D(Ja-a_{\rm ref})。
初始恢复误差为 -0.03\,\mathrm m、速度为 -0.1\,\mathrm{m/s},计算得到 a_{\rm ref}\approx89.473684、f=188.639\,\mathrm N、Ja=84.5095\,\mathrm{m/s^2}。代入 -38(84.5095-89.473684) 得到同一个力。
平衡误差约为 -0.000436956\,\mathrm m;零速度下,力为 19.62\,\mathrm N,最终加速度在数值精度内为零。此时 a_{\rm ref}=Rf 仍为正,它通过有限目标偏差产生支撑力。