本节视频
配音由 AI 合成。 视频章节、文字稿与出处
文字稿
文字稿
知行问
写好几十行文字,电脑里的杯子,就会自己摔下来?这一集,我们用物理仿真器,从一段 XML 写出一个抓取场景。再一步一步让它动起来。
用 XML 描述世界
MuJoCo,意思是多关节接触动力学。它是个物理引擎,读一段 XML,把世界搭出来。最外层是世界的根。往里放物体,物体上再挂几何体。每个 body 都有位置和朝向。桌子摆在中间,杯子放在桌子上方一点点。我们的世界里,就三样东西:一张桌子、一只杯子、一个两指夹爪。几何体有好几种:平面、盒子、球、胶囊、圆柱,还有网格。桌子用盒子,杯子用圆柱。网格、纹理这些,叫资产 asset。模型里引用它们,比如给桌子贴一层木纹。杯子接一个自由关节到世界。这样它能平移、能转,有六个自由度,所以会往下掉。MuJoCo 的关节一共四种。球关节、滑动关节、转动关节,还有这个自由关节。有意思的是,你可以不写质量。它会按体积和默认密度来算。默认密度是水的密度,每立方米一千公斤。还有重力。默认的重力竖直向下。九点八一米每二次方秒,约等于地表重力。顺便说一句,这个仿真器不规定单位。你自己定一套,前后自洽就行。长度用米,质量用公斤,时间用秒。几何体还能设颜色和材质。但这些只影响好不好看。真正参与计算的,是形状和接触。还能放标记点和传感器。比如触觉传感器,能读出接触的法向力。力和力矩传感器,读出标记点上的力和力矩。接触是软的。solref 控制时标和阻尼比。solimp 控制约束阻抗。重复的属性,可以写进一个默认类。像网页的样式表一样层层沿用,省得每个都写一遍。所以搭一个世界,要先说清楚:里面有什么、怎么连、有多重。
一步一步推进物理
建好的世界,先分成两半。不变的部分叫 mjModel,会变的状态叫 mjData。状态就是两个向量:位置和速度。物理,就是不断更新这两个数。步进之前,别忘了给一个初始状态。杯子摆哪儿、速度多少,都从这儿开始。只想算一下受力、不想让时间走,就调用 mj forward。它刷新状态,但时间不动。真要推进,靠一个函数:mj step。每调用一次,时间就前进一个步长。默认步长是两毫秒。文档说,它是速度和精度的权衡:越小越准、越稳,但越慢。默认是半隐式欧拉积分。平滑的系统,适合用四阶龙格-库塔。本例,用 implicitfast。想重来,一句 mj resetData,状态就回到最初。或者,直接跳到一个关键帧。MuJoCo 跑这种小模型,通常比真实时间还快。可接触一多,就慢下来了。现在让杯子从桌面上方落下。一放手,它就往下掉,砸到桌面,弹一下,最后停住。杯子和桌子一碰,就产生接触。仿真器把接触力,转成一个优化问题来求解。每个接触点,都能读出来:位置、法向、还有力。接触个数,也能直接读到。还有个坑:默认情况下,父子物体之间不检测碰撞。桌子是静态的,杯子照样会砸上去。要是杯子停不住、数字飞了,多半是时间步太大,物理发散了。把时间步调小,通常就稳了。动手一下。在 Notebook 里反复步进。把杯子高度,画成一条曲线。曲线上看得清清楚楚。先下落,再触底、弹一下,最后停在桌面高度。原来物理引擎,就是把定律,一小步一小步算出来!
抓一下
光有杯子还不够,得有会动的手。给机械手装两根手指,底座再加一条竖直滑轨。两根手指,其实就是两个小盒子。装在滑动关节上,一开、一合。每根手指,配一个位置执行器。你给它一个目标位置,它就使劲往那儿靠。控制信号,写进 data 的控制量里。再给个控制范围,手指就不会张过头。抓之前,先把机械手移到杯子两边,对准中心。位置歪了,合拢就会扑空。抓取脚本分两步。第一步,合拢手指,压住杯子。第二步,抬起底座。手指为什么能夹住?靠的是接触点上的摩擦力。压得越紧,能提的重量越大。平的手指容易打滑。可以调大摩擦,或者提高接触维度,让它连转动都挡住。合拢之后,底座往上抬。夹得够紧,杯子就跟着离开桌面。一次最简单的抓取。手指上装个触觉传感器,就能读出夹得有多紧。数字太小,说明快滑了。成没成,看两条曲线。一条是手指位置,一条是杯子高度。杯子升起来,就是抓住了。还能把这一幕渲染成图。它可以离屏渲染,出彩色图和深度图。跑不通,就只留曲线。深度图有什么用?后面训练视觉策略,它正好能当输入。看,杯子真的被抬起来了!但这套抓杯子的动作,是我们手写的脚本。换个杯子位置,就得重新调。真正要的,是让模型自己学。回顾一下,三个要点。一,MuJoCo 用一段 XML 描述世界。二,mj step 一步一步推进物理。三,加执行器和脚本,就能试着抓。从头搭一个能动的世界,原来这么快!场景有了,机器人怎么从数据里,学会自己动作?下一集见!
证据与出处
1000 · 不写质量时,MuJoCo 按几何体积与默认密度推算质量;默认密度 1000,即水的密度(MKS) [O] · MuJoCo 文档 · Overview(v3.14.0)
9.81 · MuJoCo 默认重力向量竖直向下,约 9.81 米每二次方秒,即地球表面重力(MKS) [O] · MuJoCo 文档 · Overview(v3.14.0)
2 毫秒 · MuJoCo 默认仿真步长 0.002 秒;它是每个物理仿真都有的速度-精度权衡里最重要的参数 [O] · MuJoCo 文档 · XML Reference(v3.14.0)
动手与自测
小测公开,答案与解析在作答后显示;图文课里的练习答案需登录查看。

第 2.1 集的视频用一段 MJCF(MuJoCo 的 XML 模型格式)搭了一个抓取场景:一张桌子、一只杯子、一个两指夹爪。它讲了三件事:MJCF 用 worldbody、body、geom、joint 描述世界;mj_step 一步一步推进物理,默认步长 0.002 秒,是速度和精度的权衡;加上位置执行器和一段“合拢、抬起”的脚本就能试着抓,成败看手指位置和杯子高度两条曲线。片中的三张数字卡都出自 MuJoCo 官方文档:默认步长 0.002 秒、默认重力 9.81、默认密度 1000。本篇是这一集的图文课与练习,不重复文字稿,而是回答一个视频只点到的问题:几十行 XML 为什么就够了?答案是很多值没写,却并不是没有,它们取了默认值。本课把这些默认值逐项补出来,用一只假想的杯子算出它们意味着多重、多快、多少步,再看两条文档写明却容易忽略的规则:数值发散不一定怪步长,父子物体不碰撞也有例外。贯穿全文的规则:XML 里没写的值要连同它假定的单位一起写出来,才算读懂了一个模型。
本节视频、文字稿与出处在本页上方,全季安排见课程大纲。这是 L2“动手”的第一集。上一课物理AI实验室 1.8:评测,把“净增 2”拆成配对表,再给失败标签和随机种子算一笔账结尾问:想自己在仿真里搭个抓取场景吗?本课接着回答。步长变小会让计算量怎样增加、不同引擎的接触近似怎样让两条轨迹分叉,物理AI实验室 1.4:仿真器地图,手算步长代价、找出接触分叉点,再给三个提速数字标清基线已经讲过;两指靠摩擦夹住杯子需要多大的力,物理AI实验室 1.3:传感器,用一只杯子手算像素、深度量程与夹紧力已经手算过。本课不再重复,只讲 MuJoCo 文档里与这一集直接相关的几段。
公开小测的 5 道题附完整解析;登录后可完成三项练习:给一只虚构杯子补出质量与重量,再审一份把长度改成厘米、却保留默认重力和密度的模型;读一份虚构的下落日志,判断数值发散来自步长还是初始穿透;给一棵虚构夹爪的 body 树逐对判断碰撞,再审四次抓取记录。每项都附分步解法、常见错误与 20 分评分标准。
一、hello.xml 里没写出来的值
MuJoCo 文档的 Overview 一章给了一个最小的 MJCF 例子 hello.xml。原文说,它定义了一个固定在世界上的平面、一盏灯,和一个有 6 个自由度的浮动盒子,“free”关节就是做这件事的;模拟时,盒子会落到地面上。下面是文档里的原文件:
<mujoco>
<worldbody>
<light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
<body pos="0 0 1">
<joint type="free"/>
<geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
</body>
</worldbody>
</mujoco>
这 10 行里没有质量、没有重力、没有步长,也没有一条碰撞规则。文档在讲后面一个较长的例子时解释了原因,以下两句各自独立摘录:
Inertial properties are inferred from the geom shape under a uniform density assumption.
Collision rules are defined automatically. Friction properties, gravity, simulation time step etc. are set to their defaults.
片中三张数字卡对应的三处默认值,原句如下,各自独立摘录。第一句出自 XML Reference 的 option 一节,后两句出自 Overview 的“Units are unspecified”一节:
timestep : real, “0.002” Simulation time step in seconds. This is the single most important parameter affecting the speed-accuracy trade-off which is inherent in every physics simulation.
The default value of gravity is (0, 0, -9.81), which corresponds to Earth surface gravity in MKS.
The default value of geom density (used to infer body masses and inertias) is 1000, which corresponds to the density of water in MKS.
| 没写的值 | 默认值 | 写在哪个元素上 | 文档还说了什么 | 这句话没说什么 |
|---|---|---|---|---|
| 步长 | 0.002 s | option 的 timestep | 越小越准、越稳;要实时运行,步长必须大于每步的 CPU 时间 | 某个模型该用多大步长;文档说稳定性还取决于求解器参数,建议两者一起调 |
| 重力 | (0, 0, −9.81) | option 的 gravity | 对应 MKS 单位制下的地表重力 | 它并不规定你必须用 MKS;文档原话是,我们也可能在土卫二上用 CGS |
| 质量与惯量 | 由 geom 的形状和密度 1000 推算 | geom 的 density(属性列表里也有 mass) | 1000 对应 MKS 下水的密度;惯量按均匀密度假设推算 | 它算出的是实心物体的质量,不知道杯子是空心的 |
| 碰撞规则 | 自动定义 | 不写 | 默认排除直接父子关系的 body 之间的碰撞,静态父物体除外(见第四节) | 所引文字没有展开其他过滤方式 |
三张数字卡都属 O 级(官方一手):这是 MuJoCo 文档对自家软件的描述,本站没有运行 MuJoCo 去核对。本课读的是 2026-10-12 抓取的 stable 版文档,片中数字卡标注为 v3.14.0;文档会随版本更新。
编译之后,值放在哪。Overview 说,MJCF 由内置编译器编译成低层数据结构 mjModel;mjModel 存模型描述,预期保持不变;mjData 存全部动态变量和中间结果,由 mjModel 在运行时生成。XML Reference 又说,option 元素与 mjModel.opt 里的 mjOption 一一对应。所以步长和重力最终都在 mjModel 里,而杯子此刻在哪、多快,在 mjData 里。文档还写明,这些选项可以在每个仿真步之前修改,但在一步之内不应修改。文档里最短的仿真循环只有一行:
while (d->time < 10) mj_step(m, d);
按默认步长,这一行要调用 mj_step 约 10 ÷ 0.002 = 5000 次(本课的算术)。视频里桌子用盒子、杯子用圆柱、杯子接自由关节,正是 hello.xml 这种写法的放大版。
登录后继续阅读本课其余各节、自测题与答案。
局限 / 注意
- 步长 0.002 s、重力 (0, 0, −9.81)、密度 1000、实时条件、发散排查和父子碰撞规则都来自 MuJoCo 官方文档(Overview 与 XML Reference),属 O 级。本课读的是 2026-10-12 抓取的 stable 版本,片中数字卡标注为 v3.14.0;本站没有运行 MuJoCo 核对其中任何一项。
- 本课依据的是两页文档的摘录:不含 geom 的 size 怎样换算成尺寸、求解器参数(solref、solimp 等)的具体含义、Collision detection 一节和 contype、conaffinity 等其他过滤方式;“Surprising Collisions”一节在摘录中没有读完。“RK4 时须大于 4 倍”是本课对文档括号里那句话的字面读法。
- 第二、三节的杯子尺寸、桌面高度、0.03 m、0.1 ms 与 0.6 ms 的 CPU 时间、z = 0.440 m 等都是本课的假设;0.503 kg、4.93 N、0.0782 s、第 40 步、20 倍、约 3.3 倍、5000 次等是本课的算术。自由落体估算忽略了离散积分、软接触和空气,不等于 MuJoCo 的输出。
- 第五节的杯子 C、厘米版和毫米版文件、木材密度 600、运行 A–C、body 树、执行器与控制范围设置、触觉读数、G1–G4 和队友的报告都是练习用的虚构;算出的 0.339 kg、589 kg/m³、33.3 N、0.0639 s、0.800 m 等只在这些假设下成立。排查顺序和三问检查法是本课对文档的整理,评分标准是教学建议。
- 本文没有核对片中 Notebook、互动画面和曲线的实现与数据。视频里的抓取是一段手写脚本;仿真里抓得起来,不等于真机安全或可靠,纸面计算和仿真结果都不是硬件安全验证。
链接
- 物理AI实验室:一套每个数字都能核对的物理 AI 课程(课程大纲)
- 物理AI实验室 1.8:评测,把“净增 2”拆成配对表,再给失败标签和随机种子算一笔账
- 物理AI实验室 1.4:仿真器地图,手算步长代价、找出接触分叉点,再给三个提速数字标清基线
- 物理AI实验室 1.3:传感器,用一只杯子手算像素、深度量程与夹紧力
- 把验收过的 CAD 零件装上机械臂仿真:质量核对、可移植的 MJCF 与 OpenUSD 导出
- MuJoCo 文档 · Overview(hello.xml、模型与数据分离、单位、发散与父子碰撞)
- MuJoCo 文档 · XML Reference(option 的 timestep)



