MuJoCo 刚柔耦合仿真:3 个示例跑通 + 参数速查指南
【免费下载链接】mujocoMulti-Joint dynamics with Contact. A general purpose physics simulator.项目地址: https://gitcode.com/GitHub_Trending/mu/mujoco
让机械爪捏住易拉罐又压不碎鸡蛋,关键在弹性参数怎么设。本文只讲 MuJoCo 刚柔耦合的用法:怎么读示例、怎么调参,不推公式、不读源码。读完你能做到:
- 加载官方柔体示例并运行
- 调整
young、poisson等参数,肉眼看出差异 - 排查"仿真爆炸"这类常见发散问题
核心机制拆解:刚柔耦合的三块积木
先把概念说透。刚柔耦合指的是刚体和柔体在同一个仿真里互相接触、互相影响。MuJoCo 的柔体不是"一整块会形变的物体",而是把它拆成一张点阵:每个顶点算一个小刚体,点与点之间用类似弹簧的弹性元件连着。你捏它时看到形变,本质是这张"弹簧网"被压扁了。
拆开看就三块,各管一件事:
- flexcomp(形变复合体):把网格或格子点阵展开成一堆小质点加弹性元件,是柔体的骨架
- elasticity(弹性材料模型):用圣维南-柯西本构(大变形、线性应力-应变的材料近似)描述软硬,靠
young、poisson、damping三个参数 - contact(接触处理):负责柔体与刚体之间、以及柔体自己和自己之间的碰撞响应
刚体部分照常用geom和body写,柔体写进flexcomp,两边的接触由同一个求解器统一解出来——这就是"耦合"。
跟着 3 个示例跑通柔体仿真
三个示例由浅入深:先玩纯软体,再看布料这种薄壳,最后是刚柔耦合的抓取。每个示例都从仓库自带文件开始,改一两处即可。
示例 1:bunny——最直观的软体按压
🔧 打开 model/flex/bunny.xml。兔子是bunny.obj网格做的外皮,dof="trilinear"表示顶点位移用线性插值近似。关键就三行:
<flexcomp type="mesh" file="bunny.obj" dim="2" dof="trilinear"> <elasticity young="1e3" poisson="0.1" damping="0.001" elastic2d="none"/> <contact selfcollide="none" internal="false"/> </flexcomp>把young从1e3改成1e5,再跑一次。
你会看到:顶部的按压块(由press执行器驱动)把兔子往下压,兔子凹陷后回弹。young=1e3时凹得很深、弹得软;young=1e5时几乎压不动,像硬橡胶。
示例 2:flag——薄壳与布料
🔧 打开 model/flex/flag.xml。旗子是一个9 19 1的平面点阵,风来自option标签:
<option wind="5 5 0" density="10"/> ... <flexcomp type="grid" count="9 19 1" spacing=".05 .05 .05" mass="10"> <edge equality="true" damping="0.001"/> </flexcomp>把wind="5 5 0"的第一个数从5改成15,再跑。
你会看到:旗子在风里持续翻动,波浪从左端传到右端。edge equality="true"让每根边不可伸缩,所以旗子只晃不扯——这正是布料该有的行为。风速翻倍,波纹明显更快更乱。
示例 3:gripper——刚柔耦合抓取
🔧 打开 model/flex/gripper.xml。这是刚柔耦合的完整形态:手指是cap.obj网格做的柔性指尖,夹爪本体是刚体,中间还夹着目标方块。指尖的关键结构:
<flexcomp type="mesh" file="cap.obj" dim="3"> <edge equality="true" solimp="0.95 0.99 0.001 0.5 2"/> <pin id="0 2 3 ... 217"/> </flexcomp>pin把指尖上一排点钉死在手指刚体上,edge equality="true"让边长不变。合起来就是一根能弯曲、不能拉长的"软手指"。这个示例的<option>里用了integrator="implicitfast",专门应对这种接触刚硬的场景。
改两个地方观察:solimp开头两个数(0.95 0.99)控制指尖回弹和吸震,调小后指尖贴合物体更"死";grasp执行器的kp="200"是握力增益,调大夹得更紧。
你会看到:两个手指同步合拢(靠equality里的关节等式约束),指尖弯向方块贴上去,随后lift执行器把整只手抬起,方块跟着离开地面。这就是刚柔耦合抓取的完整链条。
参数速查与避坑
常用参数对照如下,范围取自仓库内官方示例的实际取值:
| 参数 | 物理含义 | 推荐范围 | 调大 / 调小会怎样 |
|---|---|---|---|
young | 杨氏模量,材料软硬 | 1e3 ~ 1e5(官方示例取值) | 调大变硬、压不变形;调小变"果冻",一碰就塌 |
poisson | 泊松比——拉伸时长轴缩短多少的比值 | 0.1 ~ 0.45,必须小于 0.5 | 接近 0.5 时近似不可压缩,数值上容易"锁体积"变刚硬 |
damping | 瑞利阻尼系数,消耗振动能量 | 0.001 ~ 0.1 | 调大回弹衰减快;调小或为 0 会久晃不停 |
timestep | 积分步长 | 1e-4 ~ 5e-3 | 调大仿真变快,过大直接发散;官方柔体示例多用0.001 |
solimp | 接触阻抗,前两位近似恢复系数和阻尼 | 0.9 0.99 附近常见 | 调大更弹跳,调小更"粘滞" |
参数定义来自官方文档 doc/XMLreference.rst 的 flex/elasticity 一节,
poisson的合法范围[0, 0.5)也在那里。
⚠️ 两个最容易踩的坑:
- 步长过大导致发散:现象是柔体瞬间"爆炸"、顶点飞出屏幕、能量读数飙到 inf。解法:先把
timestep降一个数量级(如0.001→1e-4)再逐步加回;接触场景可像 gripper 那样换integrator="implicitfast",它能容忍更大的步长。 - 2D 布料忘了
elastic2d:它默认是none,即弹性材料对 2D 面片没有贡献,布料只靠edge维持形状。想要拉伸或弯曲阻力,要显式设成stretch或both,否则布料行为会和你预期的差很远。
官方示例资源与进阶路径
三个文件各练一个方向:
- model/flex/flag.xml:薄膜与风场,练
edge和wind - model/flex/jelly.xml:3D 体积软体,练
young和count网格密度 - model/flex/softbox.xml:
dof="radial"的盒子,练压缩时的体积表现
进阶路径分三级:
- 新手:用 simulate/ 或 python/tutorial.ipynb 加载上面的示例,一次只改一个参数,记录现象
- 进阶:通读 doc/XMLreference.rst 里
flexcomp与elasticity两节,自己搭一个grid类型的柔体 - 贡献者:对照 CONTRIBUTING.md 的贡献指南,把自己的示例模型提交回仓库
收藏本文,下次调参回来翻表。
【免费下载链接】mujocoMulti-Joint dynamics with Contact. A general purpose physics simulator.项目地址: https://gitcode.com/GitHub_Trending/mu/mujoco
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考