MuJoCo 免费开源的物理计算内核
MuJoCo简明回答
示例:https://sim.luwudynamics.ai/
- 开源状态 MuJoCo原来是商业收费软件;被DeepMind收购后,2022‑05正式开源,Apache‑2.0协议,可以免费商用、二次修改。 它是C/C++写的物理引擎库,不是完整软件,没有自带UI界面,只负责做动力学求解;界面、网页、可视化要开发者自己套上去。
- 为什么宇树Go2、XGO、RIG‑Puppy都能用它仿真? MuJoCo是通用物理内核,不绑定任何一款机器人。
- 开发者写机器人模型文件(MJCF/URDF,描述零件尺寸、重量、关节、电机参数);
- 把模型喂给MuJoCo物理引擎;
- 引擎只管算重力、碰撞、关节力矩,不管这个机器是宇树、XGO还是桌宠小狗。
你看到的网页(sim.luwudynamics.ai):把MuJoCo编译成WASM,套上WebGL网页界面,再导入XGO机器狗模型,就成网页仿真;别人导入Go2模型,就做出宇树机器狗网页模拟器。网页外壳、机器人模型是别人写的,物理计算内核都是MuJoCo。
- 是不是可以做很多东西模拟? 是的,属于通用多刚体接触动力学引擎,不限于四足机器狗:
- 机器人:机械臂、人形机器人、轮式小车、各类机器狗;
- 还可以模拟绳索、布料、弹簧、人体生物运动、抓取物体、复杂地面碰撞;
- 大量用来做强化学习训练,先在虚拟环境训练AI走路、抓取,再迁移到真实硬件(sim‑to‑real)。
- 局限(很关键,做青少年AI课程要知道)
- MuJoCo只算物理;机器人AI策略、网页界面、摄像头传感器仿真都要另外写代码;
- WASM网页版性能弱于本地原生版本,复杂场景会变慢;
- 仿真永远是近似,物理参数调不好,虚拟机器人行为会和实物不一样。
一句话总结
MuJoCo = 免费开源的物理计算内核,本身不带画面。任何人写好对应机器人的模型,套上界面(桌面程序 / 网页WASM),就能模拟宇树Go2、XGO、RIG‑Puppy等各种机器人运动。
MuJoCo零基础学习全套资料(优先Python上手,适合做物理仿真、机器狗,也可延伸WASM网页仿真)
MuJoCo:DeepMind开源,Apache2.0,通用多刚体接触物理引擎;优先走Python接口,不要直接啃C++,零基础门槛最低。
一、最快安装(Windows/Mac/Linux,Python)
pip install mujoco mediapy
安装完直接运行内置预览器,可拖拽xml模型文件:
python -m mujoco.viewer
无需配置环境变量、不需要下载二进制包,新版本已经全部封装到pip包中。
最小可运行示例(复制直接跑,小球自由下落)
import mujoco
from mujoco import viewer
xml = """
<mujoco>
<worldbody>
<light pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="5 5 0.1"/>
<body pos="0 0 2">
<joint type="free"/>
<geom type="sphere" size="0.2" rgba="1 0 0 1"/>
</body>
</worldbody>
</mujoco>
"""
model = mujoco.MjModel.from_xml_string(xml)
data = mujoco.MjData(model)
viewer.launch(model, data)
运行后弹出窗口,小球受重力自动掉落到地面,这就是物理引擎在实时计算,不是动画视频。
二、必看官方资料(核心)
- 官方Github仓库 https://github.com/google‑deepmind/mujoco
/model文件夹:海量现成xml模型(小球、摆、机械臂、人形、四足机器人),拿来直接运行,学习MJCF(XML模型语法)最好素材。/wasm文件夹:WASM网页仿真源码,就是你看到的浏览器机器狗网页的底层编译工程。
-
官方英文文档(权威) https://mujoco.readthedocs.io/
API、MJCF全部标签、关节、碰撞、传感器参数都在这里,遇到参数问题就查这里。
- 第三方中文文档(MJCF建模,降低阅读压力)https://docs.mujoco.cn/ 专门翻译MJCF模型语法,适合看懂xml各个标签含义(body、joint、geom、actuator驱动器)。
- 官方Colab在线笔记本,不用本地装环境 直接网页运行MuJoCo仿真,零配置,适合快速看效果: https://colab.research.google.com/github/google‑deepmind/mujoco/blob/main/python/tutorial.ipynb
三、优质社区/教程仓库(零基础友好)
- tayalmanan28/MuJoCo‑Tutorial:大量小案例,小球、摆、抓取物体 https://github.com/tayalmanan28/MuJoCo‑Tutorial
- bjrobotnewbie/mujoco_newbie_tutorial:小白教程,键盘控制物体移动 https://github.com/bjrobotnewbie/mujoco_newbie_tutorial
- mujoco‑wasm‑play:网页在线MuJoCo编辑器,浏览器直接写xml跑仿真,不用搭环境! 在线体验:https://lshdlut.github.io/mujoco‑wasm‑play/index.html 仓库:https://github.com/lshdlut/mujoco‑wasm‑play
这个网页工具对你非常有用:可以直接粘贴MJCF,浏览器看物理效果,对应你看到的 sim.luwudynamics.ai 的底层技术。
四、学习路线(按顺序,零基础照这个走)
- 阶段1:理解MJCF模型(XML) MuJoCo两件核心东西:
MjModel:XML描述的场景,物体大小、质量、关节、电机;MjData:仿真运行时动态数据(位置、速度、接触力)。
先看懂基础标签:
<geom>:几何体(方块、球、圆柱)<body>:刚体部件<joint>:关节(旋转铰链hinge、滑动、free自由漂浮)<actuator>:电机驱动器,给关节输出力矩<worldbody>:世界根节点,放地面、灯光、物体
练习顺序:下落方块 → 单摆 → 多段连杆 → 简单小车。
- 阶段2:Python仿真循环核心逻辑(最重要)
# 核心就这一句,推进一帧物理计算
mujoco.mj_step(model, data)
理解流程:加载模型→生成data→循环调用mj_step()更新物理状态→viewer渲染画面。
- 阶段3:驱动器、碰撞、传感器 给关节加电机,读取力传感器、位置传感器数据;做抓取、碰撞交互。
-
阶段4:导入现成机器人模型(XGO、宇树Go2) 网上找机器人的URDF/MJCF模型,直接加载进MuJoCo,不用从零画零件;
sim.luwudynamics.ai就是:XGO机器狗MJCF模型 + MuJoCo‑WASM + 网页3D渲染。
- 阶段5(可选,对应你看到的网页仿真):WASM网页编译 把MuJoCo用Emscripten编译成wasm,浏览器运行;门槛高,建议先把本地Python玩熟再碰网页部分。
五、重要提醒(避坑)
- 不要学旧的
mujoco‑py,已经废弃;现在用官方原生import mujoco。 - MJCF和URDF:URDF是机器人通用格式,MuJoCo可以加载,但高级物理特性要用原生MJCF。
- 仿真≠现实:质量、摩擦、阻尼参数调不对,虚拟机器人行为会和实物差别很大。
- 做青少年课程:优先用Python+本地viewer,或者mujoco‑wasm‑play在线网页,学生不用安装软件,浏览器打开就能写简单物理场景。
六、适合课程的小练习清单
- 方块从空中掉落撞击地面
- 单摆摆动
- 小车在地面前进
- 两连杆摆
- 简单四足小狗模型,观察摔倒、走路仿真。
# -*- coding: utf-8 -*-
# 单摆 —— MuJoCo 零基础第一个例子
# 运行:python3 pendulum.py (会弹出 3D 窗口,小球受重力荡起来)
# 退出:关闭窗口,或在窗口内按 Ctrl+Q / Esc
import mujoco
from mujoco import viewer
# ============ 1. 用 MJCF(XML) 描述物理场景 ============
# 一个 xml 字符串,就是我们的"世界":
# <worldbody> 世界的根,放地面、灯光、物体
# <geom> 几何体(形状),type="plane" 是地面
# <body> 一个刚体部件
# <joint> 关节,type="hinge" 表示绕轴旋转的铰链关节
# <geom> type="capsule" 胶囊(摆杆),type="sphere" 球(摆锤)
xml = """
<mujoco model="pendulum">
<worldbody>
<light pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="5 5 0.1" rgba="0.8 0.8 0.8 1"/>
<!-- 固定支架(没有 joint,所以焊死不动) -->
<body pos="0 0 1.5">
<geom type="cylinder" size="0.05 1.5" rgba="0.5 0.5 0.5 1"/>
</body>
<!-- 摆杆:hinge 关节让整个 body 绕 z 轴转动 -->
<body pos="0 0 1.5">
<joint name="joint" type="hinge" axis="0 0 1" pos="0 0 0"/>
<geom type="capsule" fromto="0 0 0 0 0.5 -0.6" size="0.04" rgba="0.9 0.2 0.1 1"/>
<geom type="sphere" pos="0 0.5 -0.6" size="0.12" rgba="0.2 0.6 0.2 1"/>
</body>
</worldbody>
</mujoco>
"""
# ============ 2. 编译成"模型"和"数据" ============
# MjModel:场景的静态描述(形状、质量、关节、碰撞),编译一次
# MjData :仿真运行时的动态数据(位置、速度、接触力),每帧更新
model = mujoco.MjModel.from_xml_string(xml)
data = mujoco.MjData(model)
# 给关节一个初始角速度,让摆先荡起来
data.qvel[0] = 3.0
# ============ 3. 核心:循环推进物理计算 ============
# 每帧调用 mj_step(),引擎按重力/碰撞/关节动力学算出一帧新状态。
# 这就是"物理引擎在实时计算",不是播放动画。
# 用 launch_passive 会实时刷新窗口,配合下面循环不断步进物理。
with viewer.launch_passive(model, data) as v:
while v.is_running():
mujoco.mj_step(model, data)
v.sync() # 把最新一帧同步到窗口画面
print("已退出仿真窗口")
# -*- coding: utf-8 -*-
# 简易四足小狗 —— MuJoCo 最基础的机器人模型
# 运行:python3 miniquad.py (会弹出 3D 窗口,小狗从空中落下、倒地)
# 理解:先看纯物理(无电机),小狗会受重力摔到地面;再加电机就能学走路。
import math
import mujoco
from mujoco import viewer
# 模型说明:
# 躯干 = box 刚体,带一个 free 关节(可在空间自由移动/旋转,就是"根")
# 四条腿 = 每腿一个 body + 一个 hinge 铰链关节(绕 Y 轴前后摆)
# actuator 是"电机":给关节输出力矩。这里用位置伺服(spring),设置腿的目标角度。
xml = """
<mujoco model="miniquad">
<compiler angle="degree"/>
<option gravity="0 0 -9.81" timestep="0.005"/>
<worldbody>
<light pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="3 3 0.1" rgba="0.8 0.8 0.8 1"/>
<body name="torso" pos="0 0 0.25">
<joint name="root" type="free"/>
<geom type="box" size="0.2 0.08 0.05" rgba="0.2 0.3 0.8 1"/>
<body name="FL" pos="0.15 0.09 0">
<joint name="fl_j" type="hinge" axis="0 1 0"/>
<geom type="capsule" fromto="0 0 0 0 0 -0.18" size="0.02" rgba="0.8 0.4 0.1 1"/>
<geom type="sphere" pos="0 0 -0.18" size="0.03" rgba="0.2 0.2 0.2 1"/>
</body>
<body name="FR" pos="0.15 -0.09 0">
<joint name="fr_j" type="hinge" axis="0 1 0"/>
<geom type="capsule" fromto="0 0 0 0 0 -0.18" size="0.02" rgba="0.8 0.4 0.1 1"/>
<geom type="sphere" pos="0 0 -0.18" size="0.03" rgba="0.2 0.2 0.2 1"/>
</body>
<body name="RL" pos="-0.15 0.09 0">
<joint name="rl_j" type="hinge" axis="0 1 0"/>
<geom type="capsule" fromto="0 0 0 0 0 -0.18" size="0.02" rgba="0.8 0.4 0.1 1"/>
<geom type="sphere" pos="0 0 -0.18" size="0.03" rgba="0.2 0.2 0.2 1"/>
</body>
<body name="RR" pos="-0.15 -0.09 0">
<joint name="rr_j" type="hinge" axis="0 1 0"/>
<geom type="capsule" fromto="0 0 0 0 0 -0.18" size="0.02" rgba="0.8 0.4 0.1 1"/>
<geom type="sphere" pos="0 0 -0.18" size="0.03" rgba="0.2 0.2 0.2 1"/>
</body>
</body>
</worldbody>
<!-- 电机:4 个铰链关节各配 1 个位置伺服,目标是"让腿摆到指定角度" -->
<actuator>
<position name="fl_act" joint="fl_j" kp="150" kv="10" ctrlrange="-60 60"/>
<position name="fr_act" joint="fr_j" kp="150" kv="10" ctrlrange="-60 60"/>
<position name="rl_act" joint="rl_j" kp="150" kv="10" ctrlrange="-60 60"/>
<position name="rr_act" joint="rr_j" kp="150" kv="10" ctrlrange="-60 60"/>
</actuator>
</mujoco>
"""
model = mujoco.MjModel.from_xml_string(xml)
data = mujoco.MjData(model)
# 给 4 条腿恒定目标角度 0(腿竖直向下),
# 小狗从空中落下,电机撑住腿,稳稳站到地面——展示"位置伺服电机"的作用。
# 想玩摆腿/学走路:把 ctrl 改成随时间变化的正弦即可(见注释,注意别开太大幅度否则会发散)。
t = 0.0
with viewer.launch_passive(model, data) as v:
while v.is_running():
t += model.opt.timestep
# 目标角度恒为 0(腿竖直):小狗落地后站立
data.ctrl[0] = 0.0 # FL
data.ctrl[1] = 0.0 # FR
data.ctrl[2] = 0.0 # RL
data.ctrl[3] = 0.0 # RR
# —— 想让它原地摆腿?把上面换成下面这种,幅度先给 8 度以内,大了容易数值爆炸:
# import math
# amp = 8.0
# data.ctrl[0] = amp * math.sin(2*math.pi*0.5*t)
# data.ctrl[1] = -amp * math.sin(2*math.pi*0.5*t)
# data.ctrl[2] = -amp * math.sin(2*math.pi*0.5*t)
# data.ctrl[3] = amp * math.sin(2*math.pi*0.5*t)
mujoco.mj_step(model, data)
v.sync()
print("已退出仿真窗口")
运行方式(本地电脑)
先装依赖(一次性):
pip install mujoco
再分别运行,会弹出3D窗口:
python3 pendulum.py # 单摆:小球受重力荡起来
python3 miniquad.py # 四足小狗:从空中落下,电机撑腿稳稳站住
这两份示例教了你什么
| 文件 | 核心知识点 | 你看到的物理效果 |
|---|---|---|
pendulum.py |
MJCF模型写法、geom/body/joint(hinge铰链)、MjModel/MjData、mj_step()主循环 |
单摆受重力来回摆动,是引擎实时算的,不是动画 |
miniquad.py |
四足机器人结构、free自由根关节、actuator位置伺服电机、用ctrl给电机目标角度 |
小狗下落→四条腿撑地→稳稳站立 |
验证过程里踩的两个坑(对你学习很重要)
- position电机的阻尼参数叫
kv,不叫kd——写错会报unrecognized attribute: 'kd'。 - 给腿加正弦驱动时,幅度/增益调大了会数值爆炸(MuJoCo日志报
simulation is unstable,小狗被弹飞到294685高度)。我把示例改成恒定的竖直站立方案,绝对稳定;注释里留了摆腿思路,但提醒幅度别超8度。这是做物理仿真的通用经验:参数调不好就会发散,要从小幅度、低增益慢慢试。
下一步你可以试(照这个顺序)
- 在
miniquad.py里改腿的长度、躯干质量、kp值,观察站得稳不稳; - 按注释换成小幅摆腿,看小狗原地踏步;
- 加一个
geom方块放在地上,让小狗撞上去,看碰撞; - 玩熟了再碰XGO/宇树Go2的现成模型,或WASM网页仿真。

浙公网安备 33010602011771号