194 lines
6.2 KiB
Markdown
194 lines
6.2 KiB
Markdown
# MuJoCo Web 地图导入与编辑设计
|
||
|
||
> 状态:V1/V2 与 V3 地图编辑能力已实现。当前阶段只聚焦地图导入、可视化、受约束编辑、事务应用和地图包导出。
|
||
|
||
## 1. 目标
|
||
|
||
平台在不修改 `@mujoco/mujoco` WASM 内核的前提下,支持:
|
||
|
||
1. 内置 MJCF 物理地图:平地、坡道、楼梯和随机障碍物。
|
||
2. 工程地图包:`map.json`、简化 MJCF 碰撞层、可选自包含 GLB 视觉层和出生点。
|
||
3. Schema V2 创作层:通过 `map.scene.json` 编辑受支持的静态原语。
|
||
4. 将完全可识别的只读静态 MJCF 显式转换为可编辑副本。
|
||
5. 在浏览器中事务式重新编译,并导出独立地图 ZIP。
|
||
|
||
当前阶段不扩展机器人运动控制或其他地图上层应用。
|
||
|
||
## 2. 坐标与分层
|
||
|
||
所有地图统一使用:
|
||
|
||
- 米制;
|
||
- Z-up;
|
||
- 右手坐标系;
|
||
- `+X` 前方;
|
||
- 物理层、视觉层、创作层和出生点共享世界原点。
|
||
|
||
地图拆分为三类资产:
|
||
|
||
- `physics/world.xml`:MuJoCo 使用的简化静态碰撞层;
|
||
- `visuals/scene.glb`:Three.js 使用的高精度视觉层;
|
||
- `authoring/map.scene.json`:编辑器的规范源。
|
||
|
||
高面数视觉模型不得直接作为大型地图碰撞网格。
|
||
|
||
## 3. 地图包结构
|
||
|
||
```text
|
||
maps/warehouse/
|
||
├── map.json
|
||
├── physics/
|
||
│ ├── world.xml
|
||
│ └── meshes/*.obj
|
||
├── visuals/
|
||
│ └── scene.glb
|
||
└── authoring/
|
||
└── map.scene.json
|
||
```
|
||
|
||
Schema V1 支持物理层、视觉层和出生点。Schema V2 增加创作层:
|
||
|
||
```json
|
||
{
|
||
"schemaVersion": 2,
|
||
"id": "warehouse",
|
||
"name": "仓库",
|
||
"coordinateSystem": { "units": "m", "up": "Z", "forward": "+X" },
|
||
"physics": { "source": "physics/world.xml" },
|
||
"visual": { "source": "visuals/scene.glb" },
|
||
"authoring": { "source": "authoring/map.scene.json" },
|
||
"spawnPoints": [
|
||
{ "id": "main", "name": "主入口", "position": [0, 0, 0.35], "yawDeg": 0 }
|
||
]
|
||
}
|
||
```
|
||
|
||
声明 `authoring.source` 时必须同时声明 `physics.source`。
|
||
|
||
## 4. 安全导入
|
||
|
||
所有地图文件必须进入 `ProjectManifest` 和 `MemfsWorkspace`,禁止运行时直接读取任意主机路径。
|
||
|
||
资源引用必须拒绝:
|
||
|
||
- HTTP/HTTPS 和其他协议;
|
||
- 绝对路径、UNC、盘符路径;
|
||
- NUL、编码绕过和路径穿越;
|
||
- 不存在的工程资源;
|
||
- 重复路径及超出导入配额的文件。
|
||
|
||
视觉层仅支持自包含 GLB 2.0。暂不支持外部 glTF 依赖、Draco、KTX2 或视觉层隐藏坐标修正。
|
||
|
||
## 5. 物理地图约束
|
||
|
||
工程物理层只允许静态 `worldbody` 和必要的基础 asset。拒绝:
|
||
|
||
- joint 和动态 body;
|
||
- mocap;
|
||
- actuator、sensor、tendon、equality;
|
||
- include;
|
||
- default class;
|
||
- 依赖不兼容 compiler 角度语义的姿态;
|
||
- 无法安全重写的资源路径。
|
||
|
||
地图碰撞 geom 使用 `group="2"`,并通过稳定命名空间 `__platform_map_<mapId>_...` 与机器人隔离。
|
||
|
||
## 6. 创作文档
|
||
|
||
`map.scene.json` 是唯一编辑规范源,支持:
|
||
|
||
- box;
|
||
- cylinder;
|
||
- capsule;
|
||
- ramp;
|
||
- stairs;
|
||
- 出生点。
|
||
|
||
每个对象包含稳定 ID、名称、类型、世界位姿、原语参数、摩擦、颜色和启用状态。对象不超过 2,000 个,出生点不超过 500 个,生成 geom 不超过 10,000 个。
|
||
|
||
`MapDocumentCompiler` 根据创作文档确定性生成 `physics/world.xml`。生成结果只使用 quaternion,不依赖 Euler 角。
|
||
|
||
## 7. 编辑交互
|
||
|
||
地图面板提供“场景 · 资产库 → 认证资产”入口。用户可以点击添加,或把资产卡片拖到画布的 XY 平面落位;落点按 0.1 m 归一化并根据原语尺寸自动贴地。当前没有可编辑地图时,首个资产会立即创建 `map.json`、空物理层和创作层骨架,切换到新场景并作为未应用草稿进入 Three.js 预览;此阶段不调用 MuJoCo。用户点击“应用并重新编译”后才生成并事务提交实际物理层。
|
||
|
||
React 中的 `MapEditSession` 是草稿唯一来源。Three.js 预览层只负责:
|
||
|
||
- 草稿原语显示;
|
||
- 射线拾取和高亮;
|
||
- 世界坐标平移;
|
||
- 绕世界 Z 轴旋转;
|
||
- 原语尺寸缩放;
|
||
- 出生点预览;
|
||
- 操纵器和临时资源生命周期。
|
||
|
||
交互规则:
|
||
|
||
- `W`:移动;
|
||
- `E`:旋转;
|
||
- `S`:缩放;
|
||
- `Delete`/`Backspace`:删除;
|
||
- `Escape`:取消选择;
|
||
- `Ctrl+Z`:撤销;
|
||
- `Ctrl+Y` 或 `Ctrl+Shift+Z`:重做。
|
||
|
||
拖动 TransformControls 操纵轴期间禁用 OrbitControls;在画布空白区域按住鼠标左键仍可旋转相机。连续拖动只在 `mouseUp` 时提交一次历史记录。缩放必须写回原语参数,不能把 Three.js 节点 scale 作为持久数据。
|
||
|
||
## 8. 只读地图转换
|
||
|
||
外部 MJCF 默认只读。只有完全可逆的静态原语地图可显式创建可编辑副本。
|
||
|
||
允许转换:
|
||
|
||
- box;
|
||
- cylinder;
|
||
- capsule;
|
||
- 由嵌套静态 body 组成的世界位姿;
|
||
- pos、quat、size、friction、rgba 和出生点。
|
||
|
||
遇到下列内容必须整体拒绝,禁止静默丢弃:
|
||
|
||
- plane、mesh、heightfield;
|
||
- asset、材质和碰撞过滤扩展;
|
||
- joint、site、light 或其他未知结构;
|
||
- euler、axisangle、xyaxes、zaxis、fromto;
|
||
- 不能确认无损的 compiler 配置。
|
||
|
||
## 9. 事务边界
|
||
|
||
应用编辑草稿或转换地图时,顺序固定为:
|
||
|
||
1. 生成候选创作层;
|
||
2. 确定性生成候选物理层;
|
||
3. 创建候选 manifest;
|
||
4. 在新的 MEMFS 工作区编译 MuJoCo;
|
||
5. Viewer 成功 attach 新会话;
|
||
6. 最后提交 manifest、地图选择和编辑状态;
|
||
7. 释放旧会话和旧工作区。
|
||
|
||
任一步失败都必须恢复旧仿真和旧工程状态,同时保留用户草稿。
|
||
|
||
## 10. 导出
|
||
|
||
浏览器导入文件不保证可写,因此不直接覆盖源目录。地图通过 ZIP 导出,包含:
|
||
|
||
- `map.json`;
|
||
- 物理层及其显式 asset;
|
||
- 可选视觉层;
|
||
- 可选创作层。
|
||
|
||
ZIP 内路径保持工程相对结构,并继续执行路径安全校验。
|
||
|
||
## 11. 验证重点
|
||
|
||
- Schema V1/V2 兼容性;
|
||
- 路径穿越和协议绕过拒绝;
|
||
- 地图物理合成和命名空间隔离;
|
||
- GLB 自包含校验及资源释放;
|
||
- 编辑文档严格校验;
|
||
- 确定性 MJCF 输出;
|
||
- Undo/Redo 和视口变换写回;
|
||
- 只读转换的白名单与整体拒绝;
|
||
- 编译或 Viewer attach 失败后的事务回滚;
|
||
- 地图 ZIP 资产完整性。
|