Files
Mujoco_WASM/wasm/web_platform/README.md
T

7.0 KiB
Raw Blame History

MuJoCo Web 仿真平台

基于 MuJoCo 官方 JavaScript/WASM 绑定的中文桌面仿真平台。平台依赖与当前源码版本一致的 @mujoco/mujoco 默认入口(单线程);本工作区现有 wasm/dist/ 是启用线程构建的产物,因此不作为 MVP 运行入口。所有模型和资源只写入浏览器内的 Emscripten MEMFS,不上传到服务器。

MVP 功能

  • 导入单个/多个 MJCF(XML)、URDF 和关联资源
  • 兼容常见 ROS URDF:规范化重复 material、解析 package:// 工程内资源路径
  • URDF 导入时可选为 hinge/slide 关节生成 motor 驱动器,并可用 kp/kv 调整对应 MJCF 关节刚度与阻尼,并将可调位置/朝向的摄像头固连到指定机器人 Body
  • 导入保留相对路径的文件夹或 ZIP 工程
  • 多模型入口选择、中文加载和编译错误
  • Three.js primitive、mesh、材质/贴图显示与对象选择
  • 播放、暂停、单步、重置、0.25×–4× 速度
  • actuator 滑杆、hinge/slide 关节拖动、动态 body 外力拖拽
  • 导入单文件 .py 控制器,通过本地 Pyodide 在 mj_step 前按仿真时间同步执行
  • 导入 mjlab 导出的 policy.onnx,在浏览器本地执行 Go2-W 平衡/速度策略推理
  • FPS、物理耗时和主线程步进预算提示

开发

从仓库根目录运行:

npm install --prefix wasm
npm run dev:platform --prefix wasm

打开 Vite 输出的 HTTP 地址。应用不支持通过 file:// 直接打开,也不注册 Service Worker/PWA。

质量检查

npm run typecheck:platform --prefix wasm
npm run lint:platform --prefix wasm
npm run test:platform --prefix wasm
npm run build:platform --prefix wasm
npm run test:e2e:platform --prefix wasm

E2E 默认使用系统安装的 Google Chrome。若没有 Chrome,可修改 playwright.config.ts 或运行 npx playwright install chromium 后移除 channel: 'chrome'

生产构建与本地静态部署

npm run build:platform --prefix wasm
python3 -m http.server 8080 --directory wasm/web-platform-dist

访问 http://127.0.0.1:8080/。构建使用 base: './',可部署到任意静态子目录。静态服务器需将 .wasm 返回为 application/wasmPython 3.11+、Vite preview、Nginx 等常见服务器均支持。

工程导入约定

  • 文件夹和 ZIP 中必须至少有一个根元素为 <mujoco><robot>.xml/.urdf
  • 只有一个入口时自动加载;多个入口优先根目录 model.xmlscene.xml 或唯一 URDF,否则弹窗选择。
  • XML 的 include、mesh 和贴图路径必须相对于入口/编译器配置可解析。
  • 路径穿越、绝对路径、加密 ZIP、重复路径会被拒绝。
  • 默认限制:2000 个文件、单文件 128 MiB、总解压大小 512 MiB、ZIP 文件 128 MiB。
  • 文件夹或 ZIP 中的 .py 会显示在“控制 → Python 控制器”;也可以在加载模型后单独导入不超过 1 MiB 的 .py

Python 控制器

Python 控制器是可信的单文件脚本,必须同步定义 step(ctx, state);可选定义 NAMECONTROL_HZ(限制为 1500 Hz)、init(api)command(name, state)reset(state)dispose(state)init 可用 api.joint(name)api.actuator(name)api.sensor(name)api.body(name) 预解析 IDstep 可用 ctx.qpos(id)ctx.qvel(id)ctx.sensor(id)ctx.body_quat(id)ctx.body_position(id) 读取状态,并用 ctx.set_control(id, value) 写入经过有限值检查和 actuator 限幅的控制量。定义 command 后,界面会显示停止、前进、后退、左转、右转和起跳按钮,并分别传入 stopforwardbackwardturn_leftturn_rightjump。所有回调都必须同步;异常会自动停止控制器或显示诊断,运行期异常还会暂停仿真并清零 ctrl

当前 Python 与 MuJoCo 都运行在主线程,以保证闭环调用严格位于 mj_step 前。仅运行可信脚本;死循环仍可能阻塞页面。Pyodide 及 Python 标准库由 npm 包随生产构建离线发布,不从 CDN 下载;暂不支持第三方 Python 包、pip 或多文件 import。

ONNX 强化学习策略

平台只负责策略推理,训练仍在 Python/mjlab 中完成。当前内置任务兼容 unitree_rl_mjlab Go2 velocity 的部署观测顺序:

base_ang_vel(3) + projected_gravity(3) + velocity_command(3)
+ gait_phase(2) + joint_pos_rel(12) + joint_vel_rel(12) + last_action(12)
= 47 维观测

策略必须具有一个 float32 输入和至少一个 float32 输出,输入末维为 47、输出末维为 12。动作按 FL、FR、RL、RR 的 hip/thigh/calf 顺序解释,转换为 default_joint_pos + 0.25 * action 的关节目标。对于 motor 模型,平台使用与部署配置一致的 kp/kd 执行位置 PD;对于 position actuator,直接写入目标位置。Go2-W 的四个轮电机在此首版腿式策略中保持零力矩。

使用步骤:

  1. 导入浮动基座 Go2-W MJCF/URDF,确保腿部关节与 actuator 使用 Unitree 标准命名;
  2. 打开右侧“控制 → ONNX 强化学习策略”;
  3. 从工程中选择或单独导入 policy.onnx
  4. 加载策略,设置前向、侧向和偏航速度,启用策略后播放仿真。

ONNX Runtime Web 的推理接口是异步的。物理循环会在每个 mj_step 前持续施加最近一次已完成的动作,并以 50 Hz 提交新观测;界面会显示推理耗时和次数。ONNX 与 Python 控制器互斥,启用其中一个会停止另一个。

Important

当前内置契约是参考 mjlab Go2 的 12 腿关节策略,不是包含四个轮电机动作的 16 自由度 Go2-W 专用策略。若训练 Go2-W 轮式策略,需要后续同时扩展训练端部署配置和浏览器任务清单,确保观测、动作及归一化完全一致。

示例

fixtures/ 包含(用于测试和手工验收,不会打进生产构建):

  • mjcf_include/MJCF include、OBJ/STL mesh 和 PNG texture
  • urdf_mesh/:引用 OBJ 的 URDF
  • python_controller/:倒立摆模型及 balance.py PD 控制器;
  • invalid.xml:无效模型;
  • missing-resource.xml:缺失资源错误示例。

在“打开文件夹”中选择夹具目录即可加载。

当前限制

  • 仅面向桌面版 Chrome、Edge、Firefox;未适配手机和平板。
  • 物理运行在主线程、单线程 WASM。超出每帧预算时限制追帧并提示。
  • ONNX Runtime Web 当前使用单线程 WASM;策略必须将观测归一化包含在导出的 ONNX 图内,平台不会额外加载训练 checkpoint 的运行均值。
  • 不支持 Xacro、账号或云端保存;Python 控制器暂不支持第三方包和不可信代码隔离。
  • 关节拖动只支持 hinge/slideball/free joint 只读。
  • MuJoCo WASM 本身不支持 DAE mesh。平台会移除 DAE visual,并以 collision 几何显示;DAE collision 会替换为半径 0.05 m 的占位球体并在界面警告。高精度仿真应先将 DAE 转为 OBJ/STL 或改为 URDF primitive。
  • 导入工程只存在当前页面内存,刷新页面后需重新导入。