














示例:https://sim.luwudynamics.ai/
你看到的网页(sim.luwudynamics.ai):把MuJoCo编译成WASM,套上WebGL网页界面,再导入XGO机器狗模型,就成网页仿真;别人导入Go2模型,就做出宇树机器狗网页模拟器。网页外壳、机器人模型是别人写的,物理计算内核都是MuJoCo。
MuJoCo = 免费开源的物理计算内核,本身不带画面。任何人写好对应机器人的模型,套上界面(桌面程序 / 网页WASM),就能模拟宇树Go2、XGO、RIG‑Puppy等各种机器人运动。
MuJoCo:DeepMind开源,Apache2.0,通用多刚体接触物理引擎;优先走Python接口,不要直接啃C++,零基础门槛最低。
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)
运行后弹出窗口,小球受重力自动掉落到地面,这就是物理引擎在实时计算,不是动画视频。
/model文件夹:海量现成xml模型(小球、摆、机械臂、人形、四足机器人),拿来直接运行,学习MJCF(XML模型语法)最好素材。/wasm文件夹:WASM网页仿真源码,就是你看到的浏览器机器狗网页的底层编译工程。官方英文文档(权威) https://mujoco.readthedocs.io/
API、MJCF全部标签、关节、碰撞、传感器参数都在这里,遇到参数问题就查这里。
这个网页工具对你非常有用:可以直接粘贴MJCF,浏览器看物理效果,对应你看到的 sim.luwudynamics.ai 的底层技术。
MjModel:XML描述的场景,物体大小、质量、关节、电机;MjData:仿真运行时动态数据(位置、速度、接触力)。先看懂基础标签:
<geom>:几何体(方块、球、圆柱)<body>:刚体部件<joint>:关节(旋转铰链hinge、滑动、free自由漂浮)<actuator>:电机驱动器,给关节输出力矩<worldbody>:世界根节点,放地面、灯光、物体练习顺序:下落方块 → 单摆 → 多段连杆 → 简单小车。
# 核心就这一句,推进一帧物理计算
mujoco.mj_step(model, data)
理解流程:加载模型→生成data→循环调用mj_step()更新物理状态→viewer渲染画面。
阶段4:导入现成机器人模型(XGO、宇树Go2) 网上找机器人的URDF/MJCF模型,直接加载进MuJoCo,不用从零画零件;
sim.luwudynamics.ai就是:XGO机器狗MJCF模型 + MuJoCo‑WASM + 网页3D渲染。
mujoco‑py,已经废弃;现在用官方原生import mujoco。# -*- 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给电机目标角度 |
小狗下落→四条腿撑地→稳稳站立 |
kv,不叫kd——写错会报 unrecognized attribute: 'kd'。simulation is unstable,小狗被弹飞到294685高度)。我把示例改成恒定的竖直站立方案,绝对稳定;注释里留了摆腿思路,但提醒幅度别超8度。这是做物理仿真的通用经验:参数调不好就会发散,要从小幅度、低增益慢慢试。miniquad.py里改腿的长度、躯干质量、kp值,观察站得稳不稳;geom方块放在地上,让小狗撞上去,看碰撞;此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。