feat(training): release V0.8 自调参 Agent
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
# 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 资产完整性。
|
||||
@@ -0,0 +1,104 @@
|
||||
# 奖励函数自调参 Agent 实施计划
|
||||
|
||||
## Context
|
||||
|
||||
当前项目已有完整的本地训练链路:React/Vite 前端通过 `LocalTrainingClient` 调用仅监听 loopback 的 Python `training_server`,服务再启动内置 `training_server/rl` 中的 Go2 + mjlab/RSL-RL 训练器,并产出 `policy.onnx`。现有请求只包含环境数、迭代数、随机种子、设备和 W&B 模式;奖励项与权重固定在任务配置中,服务主要从标准输出解析迭代进度,尚未向前端提供结构化奖励曲线或自动调参循环。
|
||||
|
||||
第一版范围已确定为 `Unitree-Go2-Flat`,优化优先级依次为:速度跟踪、动作平滑、姿态稳定、减少跌倒、足端滑移、能耗。Agent 可以调整现有奖励权重、启停白名单奖励项以及修改获准的阈值/核宽等参数,但不能生成或执行任意 Python 奖励代码。系统同时提供全自动与逐轮审批模式,在本地 RTX 5080 上串行训练,通过云端 API 调用 Agent;独立打开一个参考 Isaac/TensorBoard 交互方式的监控网页,展示曲线、trial 对比、参数 diff 与最佳策略。
|
||||
|
||||
目标是在现有安全边界内增加一个可审计、可暂停、可恢复、可回退的调参闭环。云端只接收裁剪后的数值配置、曲线摘要和评估指标,不接收机器人资产、checkpoint、源代码、训练服务访问令牌或本地路径。已确认使用 DeepSeek 官方 OpenAI-compatible API(Base URL `https://api.deepseek.com`)和精确模型标识 `deepseek-v4-flash`;API key 仅从训练服务环境变量读取。目标占比采用 `35/20/15/15/10/5`,逐轮审批时基线自动运行、之后每个建议等待批准。最佳结果保存为命名 preset 并可用于后续训练,不覆盖仓库内 Python 默认值。
|
||||
|
||||
## Approach
|
||||
|
||||
采用“确定性试验编排 + 独立评估 + 云端 Agent 建议”的分层方案,而不是让 LLM 直接改源码或决定 trial 是否有效:
|
||||
|
||||
1. **白名单参数空间**:为每个 reward term 定义固定符号、默认值、上下界、是否允许置零及单轮最大变化;开放权重,以及 `std`、`command_threshold`、`target_height`、步态 `period/threshold`、姿态分段容差等少量参数。保留当前 15 个奖励项,并新增默认关闭(权重为 0)的 `electrical_power`,以覆盖能耗目标。`track_linear_velocity`、`track_angular_velocity`、`body_orientation_l2`、`is_terminated`、`joint_pos_limits`、`action_rate_l2` 不允许关闭;其余白名单项可置零。每个 proposal 最多改 4 个标量,非零权重幅值单轮限制在前值的 `0.5×–2×`(同时受绝对上下界约束),符号不可翻转,Go2 trot 的足序 offset 不开放。Agent 只能返回结构化 patch,服务端合并并二次校验。
|
||||
2. **权重无关的质量指标**:现有 `Episode_Reward/*` 已由 mjlab `RewardManager` 自动记录,但它随权重变化,不能直接作为优化目标。新增固定定义的速度误差、动作加速度、姿态误差、跌倒率、接触足滑移速度和正向机械功率指标;训练曲线用于诊断,最终排名采用固定命令集与固定评估种子得到的这些指标,避免通过放大奖励权重“刷高总奖励”。
|
||||
3. **指标与产物管线**:调参 trial 强制使用本地 TensorBoard writer;训练脚本接受服务端生成的明确输出目录与奖励配置文件,保存 `env.yaml`、Agent patch、checkpoint、ONNX 和评估结果。服务通过 TensorBoard EventAccumulator 增量读取 scalar 并写入 SQLite,曲线 API 按 LTTB/桶聚合降采样;不依赖脆弱的控制台正则解析指标。
|
||||
4. **独立评估与评分**:增加无探索噪声的评估入口,使用同一组站立、前进/侧移、转向和组合速度命令,对每个 rung 的 checkpoint 运行相同场景。速度目标内部按线速度/角速度误差 `80/20` 合并;六个顶层目标按已确认的 `35% / 20% / 15% / 15% / 10% / 5%` 聚合。对所有“越低越好”的原始指标使用创建 session 时冻结的基线尺度 `scale=max(abs(baseline), physical_floor)`,计算并裁剪相对改善 `(baseline-current)/scale`;跌倒率不得高于基线 `+2%`,速度误差不得恶化超过 `5%`,否则该 trial 不可晋级。输出原始指标、各目标改善、总分和 3-seed 均值/离散度,确保后续新增 trial 不会改变旧 trial 的分数。
|
||||
5. **DeepSeek Agent 与数值搜索协作**:采用 PydanticAI 的 OpenAI-compatible provider 连接 `deepseek-v4-flash`,以严格类型的 `RewardProposal` 返回最多 4 项参数 patch、依据、预期影响和置信度;优先使用模型 JSON/structured-output 能力,能力探测失败时退回 PydanticAI 的 prompted JSON + 本地 Pydantic 校验,不授予 Agent 任何 shell、文件或网络工具。Optuna study 记录完整参数/分数并执行 successive-halving;Agent proposal 作为 enqueue/fixed trial 进入 study,只有显式启用 fallback 时才由 Optuna sampler 代提候选。模型使用低温度、60 秒超时和最多 2 次结构化修复;每次仅发送最多 12 个 trial 摘要、每条曲线最多 64 个降采样点,并记录脱敏 prompt hash、模型名、token usage、批准操作与最终 patch。服务对输出执行有限数值、符号、边界、最大步长、重复配置和高风险组合校验,校验失败要求 Agent 修正,不能静默执行。
|
||||
6. **session 状态机**:基线自动运行 → 短预算 trial → 固定评估 → Agent 建议 →(自动批准或进入 `awaiting_approval`)→ 下一 trial → successive-halving 晋级 → 最佳配置复核。逐轮审批支持接受、拒绝并附反馈、手动修改后接受;暂停不杀死已完成数据,停止会终止当前进程组。完成后把最佳 reward patch 保存为不可变命名 preset,并提供“从 preset 新建普通训练/新 tuning session”、导出 JSON、下载/导入 ONNX;不写回 `velocity_env_cfg.py`。
|
||||
7. **默认 RTX 5080 预算**:12 个唯一配置(含基线)、4096 个并行环境、GPU `0`;所有配置先训练 300 iterations,前 4 名从自身 checkpoint 续训到 900,前 2 名续训到 2000,总量约等于 4.1 次完整 2000-iteration 训练。连续 4 个建议无显著提升时提前停止;trial 数、环境数和各 rung 可在 4–20 / 合法服务范围内调整。搜索期固定训练 seed 控制方差,晋级候选使用 3 个固定评估 seed 复核。
|
||||
8. **独立监控网页**:新增 Vite 多页面入口 `tuning.html`,从现有训练面板用新标签页打开。页面采用 TensorBoard 风格的 run 选择、平滑、缩放、悬浮值、标签过滤和多 trial 叠加图,并增加 Agent 决策时间线、API 连通性测试、审批卡片、参数 diff、排行榜、暂停/恢复/停止、preset 导出及最佳 ONNX 下载/导入。新标签页 URL 只携带 session ID;训练服务 token 通过同源、校验 origin 的一次性 `postMessage` 交接并仅存于新标签页 `sessionStorage`,失败时回退到手工输入,绝不放入 query/hash。“导入最佳策略”由 dashboard 向仍打开的 workbench 发送同源消息,workbench 使用自身 client 下载并调用现有 `onPolicyReady`;无 opener 时回退为文件下载。图表使用轻量 `uPlot`,不启动或 iframe 嵌入第二个 TensorBoard 服务。
|
||||
9. **API 与落盘边界**:新增 capabilities/Agent 测试、session 创建与详情、trial/metrics 查询、proposal 批准/拒绝、pause/resume/cancel、preset 列表/导出和最佳 artifact 下载接口;继续沿用现有 Bearer Token、Host/Origin 校验与 32 KiB 请求限制。SQLite 使用 WAL 和每线程连接,默认位于已忽略的 `training_server/rl/logs/auto_tuning/tuning.sqlite3`,trial 产物位于同目录的 session 子目录;API 永远只接受 ID,不接受客户端文件路径。启动时把遗留 `training/evaluating` 状态标记为 `interrupted`,从最后完整 checkpoint 显式恢复,不尝试盲目重连旧 PID。
|
||||
10. **DeepSeek 配置**:使用 `DEEPSEEK_API_KEY`、`MUJOCO_TUNING_AGENT_BASE_URL`(默认 `https://api.deepseek.com`)和 `MUJOCO_TUNING_AGENT_MODEL`(默认 `deepseek-v4-flash`);可配置 timeout,但 API key 不提供 CLI 参数,避免进入 shell history。健康接口仅返回 `configured/model/baseUrl`,连接测试返回能力与脱敏错误,不返回 key 或完整供应商响应。未配置云端 key 时普通训练保持可用,tuning capability 明确显示不可用;自动模式不静默退回 Optuna,只有用户在 session 中显式勾选 fallback 才允许。
|
||||
|
||||
初始权重白名单如下;负项只能保持负号,正项只能保持正号。绝对边界与单轮 `0.5×–2×` 限制同时生效,实际启用前用基线 smoke test 校验量纲:
|
||||
|
||||
| Reward term | 当前值 | 允许范围 | 可关闭 |
|
||||
| --- | ---: | ---: | :---: |
|
||||
| `track_linear_velocity` | 1.0 | 0.5–3.0 | 否 |
|
||||
| `track_angular_velocity` | 1.0 | 0.25–2.0 | 否 |
|
||||
| `body_orientation_l2` | -1.0 | -3.0–-0.1 | 否 |
|
||||
| `pose` | 1.0 | 0–2.5 | 是 |
|
||||
| `body_ang_vel` | -0.05 | -0.2–0 | 是 |
|
||||
| `angular_momentum` | -0.025 | -0.1–0 | 是 |
|
||||
| `is_terminated` | -200 | -400–-50 | 否 |
|
||||
| `joint_acc_l2` | -2.5e-7 | -2e-6–0 | 是 |
|
||||
| `joint_pos_limits` | -10 | -30–-2 | 否 |
|
||||
| `action_rate_l2` | -0.05 | -0.2–-0.005 | 否 |
|
||||
| `foot_gait` | 0.5 | 0–1.5 | 是 |
|
||||
| `foot_clearance` | -1.0 | -3.0–0 | 是 |
|
||||
| `foot_slip` | -0.25 | -1.0–0 | 是 |
|
||||
| `soft_landing` | -1e-3 | -5e-3–0 | 是 |
|
||||
| `stand_still` | -1.0 | -3.0–0 | 是 |
|
||||
| `electrical_power`(新增) | 0 | -5e-3–0 | 是 |
|
||||
|
||||
参数白名单限制为:线速度 `std=0.25–1.0`、角速度 `std=0.35–1.2`;`pose` 三档 std 使用当前 Go2 数组的 `0.5×–2×` 缩放因子,walking/running threshold 分别为 `0.05–0.5` / `1.0–2.5` 且保持有序;`foot_gait.period=0.4–0.8`、`threshold=0.45–0.65`;`foot_clearance.target_height=0.06–0.16`;各运动相关 `command_threshold=0.02–0.30`。结构对象、函数名、传感器名、asset selector、步态 offset 和终止角度不开放。
|
||||
|
||||
## Files to modify
|
||||
|
||||
关键修改与新增路径:
|
||||
|
||||
- `training_server/rl/src/tasks/velocity/velocity_env_cfg.py`:挂载固定质量指标与可选能耗奖励项。
|
||||
- `training_server/rl/src/tasks/velocity/config/go2/env_cfgs.py`:Go2 参数默认值及白名单配置应用入口。
|
||||
- `training_server/rl/src/tasks/velocity/mdp/metrics.py`(新增)与 `mdp/__init__.py`:权重无关的六类质量指标。
|
||||
- `training_server/rl/src/tasks/velocity/mdp/rewards.py`:仅在现有函数无法覆盖白名单参数时补充实现;优先复用 mjlab 内置项。
|
||||
- `training_server/rl/scripts/train.py`:显式 run 目录、奖励 patch、checkpoint 续训和 TensorBoard 配置。
|
||||
- `training_server/rl/scripts/evaluate.py`(新增):固定命令/seed 的 checkpoint 评估与 JSON 结果。
|
||||
- `training_server/rl/src/tasks/velocity/rl/runner.py`:保持 checkpoint/ONNX 对应关系,必要时暴露最终 checkpoint 元数据。
|
||||
- `training_server/tuning/`(新增):schema/目标函数、SQLite storage、TensorBoard ingest、PydanticAI advisor、Optuna sampler 与 session orchestrator,避免继续膨胀单文件服务。
|
||||
- `training_server/server.py`:组合现有训练 manager 与 tuning manager,增加 `/api/tuning/*` 路由和启动配置。
|
||||
- `training_server/tests/test_server.py` 及新增 `training_server/tests/test_tuning_*.py`:API、状态机、存储、Agent 校验与 fake trainer 集成测试。
|
||||
- `training_server/requirements.txt`(新增)与 `requirements-dev.txt`:加入并固定经 Python 3.12 实测的 `pydantic-ai-slim[openai]`、Optuna 和 TensorBoard;保留 `training_server/rl/requirements.txt` 只承载 mjlab 训练栈,避免职责混杂。
|
||||
- `web_platform/tuning.html`、`web_platform/src/tuning/`(新增):独立监控入口、dashboard、uPlot 曲线、审批/参数 diff/排行榜。
|
||||
- `web_platform/src/training/types.ts` 与 `LocalTrainingClient.ts`:调参 API 类型与方法;必要时按职责拆出 `TuningClient.ts`。
|
||||
- `web_platform/src/training/LocalTrainingPanel.tsx`:创建 session 的基础入口及“在新网页打开”按钮。
|
||||
- `web_platform/vite.config.ts`:多页面构建入口;`package.json` / lockfile 增加 `uplot`。
|
||||
- `.gitignore`、`README.md`、`training_server/README.md`、`web_platform/README.md`:忽略本地状态/产物并记录安装、安全和使用流程。
|
||||
|
||||
## Reuse
|
||||
|
||||
- 复用 `training_server/server.py` 的 Bearer Token、loopback/CORS 限制、无 shell 参数数组、训练任务互斥、进程组取消和 ONNX 下载机制;tuning 与普通训练共享同一个 GPU 活动锁。
|
||||
- 复用 `training_server/rl/scripts/train.py` 的 tyro/dataclass 配置和现有 checkpoint resume 流程,新增 patch 应用层而不是改写源文件。
|
||||
- 复用 mjlab `RewardManager` 自动产生的 `Episode_Reward/<term>`、`MetricsManager` 的 `Episode_Metrics/<term>`、`TerminationManager` 的 `Episode_Termination/<term>`,以及 RSL-RL TensorBoard scalar writer。
|
||||
- 复用当前 `mean_action_acc`、`feet_slip`、`body_orientation_l2` 等计算;能耗优先复用 mjlab 的 `electrical_power_cost`,不重复实现扭矩功率算法。
|
||||
- 复用 `VelocityOnPolicyRunner.save()` 的 checkpoint + `policy.onnx` 同步导出和元数据附加;晋级 trial 从自己的 checkpoint 恢复。
|
||||
- 参考已安装 mjlab 的 `scripts/play.py` / tracking evaluate 结构实现仓库内最小速度任务评估入口。
|
||||
- 复用 `LocalTrainingClient` 的鉴权/错误处理、`LocalTrainingPanel` 的连接信息与取消/策略下载交互,以及共享 `Button`、`Badge`、`Tabs`、`ProgressBar` 等 UI。
|
||||
- 当前前端没有路由器或图表库,故使用 Vite MPA 而非引入整套路由;图表仅新增面向大量 scalar 的 `uPlot`。
|
||||
|
||||
## Steps
|
||||
|
||||
- [x] 固化 `Unitree-Go2-Flat` 的 15 个现有 reward term schema:当前值、符号、上下界、启停规则、可调参数、每次最多 4 项、`0.5×–2×` 变化率和跨参数约束,并为能耗加入默认关闭项。
|
||||
- [x] 增加权重无关的六类训练/评估指标,定义归一化方向、目标阈值、默认 `35/20/15/15/10/5` 聚合权重、失败/NaN/过早跌倒惩罚。
|
||||
- [x] 扩展训练入口以接收服务生成的 patch 文件与明确 run 目录,支持同配置 checkpoint 晋级续训,并强制保存完整配置快照。
|
||||
- [x] 实现固定命令集、固定 seed、无探索噪声的独立评估入口,产生可验证 JSON 与 TensorBoard scalars。
|
||||
- [x] 实现 TensorBoard scalar 增量采集、SQLite schema/migration、曲线降采样及 session/trial/proposal/audit 持久化。
|
||||
- [x] 实现 tuning orchestrator、successive-halving、共享 GPU 互斥、提前停止、崩溃恢复、暂停/取消和最佳产物选择。
|
||||
- [x] 通过 PydanticAI OpenAI-compatible provider 接入官方 `deepseek-v4-flash` 和 Optuna study,实现环境变量密钥、连接/能力测试、脱敏上下文、结构化输出、重试/修复、超时、usage 审计与显式 Agent 不可用状态。
|
||||
- [x] 实现自动批准与 `awaiting_approval` 两条状态路径,包括接受、拒绝反馈、手动修订后接受及完整审计记录。
|
||||
- [x] 扩展 `/api/tuning/*`、健康信息、指标查询和最佳 ONNX 下载,并补齐 TypeScript 类型/客户端。
|
||||
- [x] 新增 `tuning.html` TensorBoard 风格 dashboard 与现有面板的新标签页入口,完成曲线、筛选/平滑/缩放、trial 对比、Agent 时间线、审批、diff、排行榜和控制操作。
|
||||
- [x] 添加 Python/TypeScript/组件/E2E 测试,更新依赖锁、忽略规则、安全说明和安装/使用文档。
|
||||
|
||||
## Verification
|
||||
|
||||
- 单元测试:参数 schema 与边界、目标分数、建议约束、状态转换、失败/取消/恢复、最佳 trial 选择、API 鉴权。
|
||||
- 集成测试:使用轻量 fake trainer 产生确定性 TensorBoard events/评估 JSON,并用 fake PydanticAI model 返回合法、越界、重复和畸形 proposal,完整跑通多 trial 调参而不依赖 GPU 或真实云端 API。
|
||||
- 前端测试:表单校验、轮询、曲线渲染、参数 diff、自动/审批分支、跨标签页无 URL 密钥交接、停止、preset 与最佳结果操作。
|
||||
- 真实训练 smoke test:在本地 RTX 5080 / GPU 0 上先用 256–512 environments、10–20 iterations 跑基线与 2 个 trial,验证 TensorBoard 指标、评估 JSON、checkpoint、ONNX、参数快照和数据库记录一一对应;再单独确认 4096 environments 不 OOM 后启用默认预算。
|
||||
- 确定性检查:相同 checkpoint + 相同命令/seed 的评估分数在容差内一致;改变 reward 权重不会直接改变固定质量指标的定义或归一化。
|
||||
- 恢复检查:分别在训练、评估、等待审批时重启服务;确认 session 从 SQLite 恢复且不会重复启动 trial,活动子进程能被停止。
|
||||
- 回归:`npm run typecheck`、`npm run lint`、`npm run test`、`npm run test:training-server`、`npm run build`、`npm run test:e2e`;具备依赖时执行 `npm run lint:python`。
|
||||
- 安全检查:非法奖励名、符号翻转、越界/NaN/Inf、超大 patch、路径注入、重复 proposal、并发普通训练/session、伪造 artifact 路径和 Agent 超时均被拒绝或进入明确状态;API key 不出现在响应、日志、SQLite 或浏览器存储中。
|
||||
@@ -0,0 +1,178 @@
|
||||
# 参考 URDF-Studio 补全前端组件计划
|
||||
|
||||
## Context
|
||||
|
||||
目标是在不改变现有 MuJoCo 导入、编译、仿真、渲染和资源生命周期逻辑的前提下,参考本机 `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio` 的前端信息架构与视觉样式,逐项补全 `wasm/web_platform` 缺少的前端组件。
|
||||
|
||||
关键约束:
|
||||
|
||||
- 只借鉴前端布局、视觉语言与交互组织,不直接迁移 URDF-Studio 的机器人解析、编辑或 Three.js 运行时。
|
||||
- 新组件接入前必须先向用户展示候选清单、用途、影响范围并逐项获得确认。
|
||||
- 第一批 A–H 已按批准计划实施;后续新增组件仍遵循先确认再接入。
|
||||
|
||||
初步现状:
|
||||
|
||||
- 本项目 UI 高度集中在 `wasm/web_platform/src/app/App.tsx`,已有顶部工具栏、工程/模型结构左栏、三维视口、模型控制右栏、底部性能状态栏、入口选择、加载态和诊断卡片。
|
||||
- MuJoCo 与 Three.js 对象由 `MainThreadPhysicsAdapter`、`MuJoCoViewer` 和 React refs 持有;Zustand 仅保存 UI 可消费快照。后续 UI 重构应保持这一边界。
|
||||
- URDF-Studio 已将 Header、WorkspaceSidebars、Viewer overlays、通用 UI 控件、拖动窗口、设置弹窗等拆成独立组件,可作为组件边界和样式参考。
|
||||
- 当前资源树和模型结构树已具备纯数据构建函数及单测,不应重写;只需替换字符图标、颜色和行样式,并保留原有树语义。
|
||||
- 当前没有 `App.tsx` 级组件测试;后续应通过抽出无状态壳层组件来增加 UI 测试,避免在测试中初始化 WebGL/WASM。
|
||||
|
||||
已确认产品方向:
|
||||
|
||||
- 第一批聚焦工作台外壳:顶部工具栏、可折叠侧栏、视口工具、底部状态栏、通知与弹窗。
|
||||
- 只采用 URDF-Studio 的专业工作台风格,保留 MuJoCo 平台品牌、中文信息架构和现有布局特色,不做像素级复刻。
|
||||
- 允许新增 `lucide-react`,用于替代当前字符/Emoji 图标并统一视觉语言。
|
||||
|
||||
## Approach
|
||||
|
||||
1. 对照两个项目的页面壳层、工具栏、左右侧栏、视口叠层、弹窗/通知和基础控件,形成“已有 / 缺少 / 不适用”的组件差异表。
|
||||
2. 将候选组件按纯展示、现有动作封装、需要新增产品能力三类分级;第一目标只推荐前两类,避免触碰底层 MuJoCo 逻辑。
|
||||
3. 第一批 A–H 已全部获得用户确认;后续若发现需要新增候选组件,必须再次确认,不能顺带加入。
|
||||
4. 先建立精简语义样式令牌和无状态基础组件,再拆分 `App.tsx` 的布局组件;业务回调继续由 `App` 注入,adapter/viewer 生命周期不下沉到展示组件。
|
||||
5. 第一批布局采用 40px 紧凑 Header、现有左右固定侧栏和 28px 状态栏;交互模式工具组停靠在 Header 中央。右栏默认展开“模型信息、当前选择、关节”,折叠其他低频分区。
|
||||
6. 不照搬 URDF-Studio 的移动端底部工具条、复杂响应式菜单或 Floating UI。保持当前 `min-w-[1024px]` 桌面产品边界。
|
||||
7. 每批只接入少量组件并执行回归验证,确保模型导入、仿真和三维交互行为不变。
|
||||
|
||||
## Files to modify
|
||||
|
||||
- `wasm/web_platform/src/app/App.tsx`:仅保留 viewer/adapter 生命周期、业务状态和事件编排,以 props 连接新 UI 组件。
|
||||
- `wasm/web_platform/src/app/components/WorkbenchHeader.tsx`:品牌区、文件导入、仿真传输控制、速度、面板/主题动作与中央工具栏插槽。
|
||||
- `wasm/web_platform/src/app/components/ViewerToolDock.tsx`:select/joint/force 模式与相机复位的图标工具组。
|
||||
- `wasm/web_platform/src/app/components/SidebarPanel.tsx`:左右侧栏壳层、标题、折叠分区和滚动区域。
|
||||
- `wasm/web_platform/src/app/components/StatusBar.tsx`:性能、WASM 和快捷键状态。
|
||||
- `wasm/web_platform/src/app/components/EntrySelectionDialog.tsx`:多入口选择的领域弹窗。
|
||||
- `wasm/web_platform/src/app/components/DiagnosticNotice.tsx`:诊断摘要、路径和可展开详情。
|
||||
- `wasm/web_platform/src/app/components/WorkspaceOverlays.tsx`:加载 HUD、空工作区和中心叠层组织。
|
||||
- `wasm/web_platform/src/components/ui/Button.tsx`、`IconButton.tsx`、`Tooltip.tsx`、`Select.tsx`、`Dialog.tsx`、`CollapsibleSection.tsx`、`ToolbarToggleGroup.tsx`:第一批基础控件。
|
||||
- `wasm/web_platform/src/components/ui/index.ts`:稳定导出边界。
|
||||
- `wasm/web_platform/src/project/ProjectTree.tsx`、`ModelStructureTree.tsx`:仅做令牌化视觉和 Lucide 图标替换,保留构树逻辑及公开 props。
|
||||
- `wasm/web_platform/src/app/ErrorBoundary.tsx`:使用新基础控件和语义样式,不改错误边界行为。
|
||||
- `wasm/web_platform/src/styles.css`、`wasm/web_platform/tailwind.config.cjs`:颜色、表面、文字、强调色、滚动条、焦点环和组件令牌;移除依赖深色工具类覆盖的主题实现。
|
||||
- `wasm/web_platform/src/app/components/*.test.tsx`、`wasm/web_platform/src/components/ui/*.test.tsx`:新增组件测试。
|
||||
- `wasm/web_platform/e2e/app.spec.ts`:保持业务断言并更新因图标化/折叠带来的交互定位。
|
||||
- `wasm/package.json` / `wasm/package-lock.json`:加入已确认的 `lucide-react`;不引入 `@floating-ui/react`。
|
||||
|
||||
## Reuse
|
||||
|
||||
本项目继续复用:
|
||||
|
||||
- `wasm/web_platform/src/app/App.tsx` 中的导入、加载、播放/暂停、单步、重置、模式切换及面板状态回调。
|
||||
- `wasm/web_platform/src/stores/useAppStore.ts` 的工程、快照、选择、性能和诊断状态。
|
||||
- `wasm/web_platform/src/project/ProjectTree.tsx` 与 `ModelStructureTree.tsx`。
|
||||
- `wasm/web_platform/src/simulation/PhysicsAdapter.ts` 和 `SimulationSession.ts`(保持不改或仅由现有接口调用)。
|
||||
- `wasm/web_platform/src/viewer/MuJoCoViewer.ts`(保持渲染和交互接口不变)。
|
||||
|
||||
样式/结构参考(只读来源):
|
||||
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/app/components/Header.tsx`
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/app/components/workspace/WorkspaceSidebars.tsx`
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/app/components/AppLayoutView.tsx`
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/shared/components/ui/`
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/shared/components/Panel/OptionsPanel.tsx`:参考可折叠分区及紧凑面板标题,不移植拖动/悬浮窗逻辑。
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/features/urdf-viewer/components/ViewerToolbar.tsx`:参考图标化工具模式组和活动态,不移植 Portal/移动端工具条。
|
||||
- `/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/styles/index.css`:仅提炼语义表面、边框、文字、强调色、滚动条和 focus ring;不复制其 AI、编辑器、字体缩放等无关样式。
|
||||
|
||||
### 第一批组件(已确认)
|
||||
|
||||
| 编号 | 候选组件 | 复用现有能力 | 预期变化 | 底层风险 |
|
||||
|---|---|---|---|---|
|
||||
| A ✅ | `WorkbenchHeader` | 导入、播放、单步、重置、速度、主题、面板开关回调 | 40px 紧凑品牌栏,动作分组,Lucide 图标 + 文案/提示 | 低,仅回调透传 |
|
||||
| B ✅ | `ViewerToolDock` + `ToolbarToggleGroup` | select/joint/force 模式、相机复位 | Header 中央停靠工具组,活动态更清晰 | 低,仅调用现有 mode/viewer API |
|
||||
| C ✅ | `SidebarPanel` + `CollapsibleSection` | 左右侧栏现有内容和开关 | 统一面板标题、滚动条、分区折叠;保留 resize-x;右栏低频区默认折叠 | 低,内容插槽化 |
|
||||
| D ✅ | `StatusBar` | 时间、FPS、step、内存、WASM、预算警告 | 图标化状态、语义色和更紧凑层级 | 低,纯展示 |
|
||||
| E ✅ | `Dialog` + `EntrySelectionDialog` | 多入口 `loadEntry` | Portal、Esc、焦点圈定、焦点恢复和统一弹窗外观 | 低,不改入口判断/加载 |
|
||||
| F ✅ | `DiagnosticNotice` | `AppDiagnostic` | 摘要以通知样式展示,可展开技术详情;保留手动关闭 | 低,不改错误生成 |
|
||||
| G ✅ | `LoadingOverlay` + `EmptyWorkspace` | `loading`、空状态、拖放导入 | 统一 HUD、图标、引导层次,不伪造加载百分比 | 低,纯展示 |
|
||||
| H ✅ | 基础 UI:`Button`、`IconButton`、`Tooltip`、`Select` | 替换 `.btn/.icon-btn/.field` | 统一尺寸、变体、禁用态、focus ring;Tooltip 不增加 Floating UI 依赖 | 低,HTML 原生语义 |
|
||||
|
||||
## Steps
|
||||
|
||||
- [x] 审计 URDF-Studio 页面布局、样式令牌和第一批组件职责。
|
||||
- [x] 审计本项目已有组件及其与 MuJoCo/viewer 的耦合边界。
|
||||
- [x] 形成第一批组件差异矩阵;排除源码编辑、属性编辑、导出、快照、AI、测量、绘制、撤销/重做、移动端工具条等新增业务能力。
|
||||
- [x] 获得用户对第一批 A–H、Header 中央工具组和右栏默认折叠策略的确认。
|
||||
- [x] **基础层**:安装 `lucide-react`;定义 light/dark 语义 CSS 变量并映射到 Tailwind;实现 Button、IconButton、Tooltip、Select、Dialog、CollapsibleSection、ToolbarToggleGroup。Tooltip 使用 hover/focus CSS 展示,Dialog 使用 portal、Esc、焦点圈定和焦点恢复。
|
||||
- [x] **工作台壳层**:实现 40px `WorkbenchHeader`,左侧保留 MuJoCo 品牌和文件动作,中间放 select/joint/force 工具组,右侧放相机、侧栏和主题动作;保留按钮可访问名称及原有回调。
|
||||
- [x] **侧栏拆分**:实现 `SidebarPanel`,将左栏工程资源/模型结构和右栏模型信息、URDF、警告、选择、Actuator、关节、外力内容从 `App.tsx` 搬入展示组件;业务回调和 `adapter.current` 调用仍在 `App` 中生成后传入。右栏“模型信息、当前选择、关节”默认展开,其余默认折叠,警告出现时自动展开。
|
||||
- [x] **叠层与反馈**:用 `WorkspaceOverlays` 组织空态/加载态,用 `EntrySelectionDialog` 替换内联入口对话框,用 `DiagnosticNotice` 替换诊断卡;不改变 loading/diagnostic/entries 的状态来源和加载时序。
|
||||
- [x] **状态栏与树视觉**:实现 `StatusBar`;为两棵现有树替换 Emoji/字符图标并应用语义令牌,不改 `buildProjectTree`、`buildBodyTree` 或选择/hover 行为。
|
||||
- [x] **收敛 App**:删除已迁移的内联 `PanelTitle`、`EmptyImport`、`EntryDialog`、`DiagnosticCard` 等展示函数;将无状态滑杆展示移入侧栏组件,不改数值换算、范围或 onChange 逻辑。
|
||||
- [x] **测试与验收**:为基础控件、折叠区、Header 回调、Dialog 焦点/Esc、诊断详情和状态栏增加 Testing Library 测试;更新 E2E 图标/折叠定位并跑完整回归。
|
||||
|
||||
## Verification
|
||||
|
||||
- 运行 `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`,全部通过。
|
||||
- 新组件测试覆盖:Header 各动作只触发一次;模式按钮 `aria-pressed`;折叠区默认状态;Dialog Esc/Tab/焦点恢复;诊断详情展开与关闭;Loading/Empty 的互斥显示。
|
||||
- 用现有 MJCF、URDF、文件夹和 ZIP 路径回归导入及入口切换。
|
||||
- 回归播放/暂停、单步、重置、速度、关节、actuator、外力、碰撞显示、选择和相机复位。
|
||||
- 检查 adapter/viewer 初始化与销毁次数,确认 UI 拆分未造成重复会话、重复渲染循环或 WASM 资源泄漏。
|
||||
- 对照 URDF-Studio 检查布局密度、层级、悬停/选中/禁用态及深浅主题;桌面窄宽度下检查折叠与溢出。
|
||||
- 对新增弹窗、菜单和提示执行键盘操作、焦点管理和 ARIA 冒烟检查。
|
||||
|
||||
## Implementation Result
|
||||
|
||||
- 已完成 A–H 第一批组件和 `lucide-react` 接入;MuJoCo adapter、viewer、manifest 和业务命令仍由 `App.tsx` 持有。
|
||||
- `App.tsx` 已收敛为生命周期/事件编排层;工作台 Header、工具组、侧栏、状态栏、弹窗、诊断和加载/空态均拆为展示组件。
|
||||
- 深浅主题完成语义令牌化,并在 1440×900 下完成暗色、亮色人工截图检查。
|
||||
- 审查发现并修复:必选入口弹窗重渲染抢焦点、原生输入焦点可见性、模型树 ARIA 层级、侧栏重开折叠状态丢失和侧栏按钮展开状态缺失。
|
||||
- 验证结果:TypeScript、ESLint、12 个测试文件共 28 个单元/组件测试、5 个 Playwright E2E 和生产构建全部通过。
|
||||
- 已知非阻塞项:生产构建仍有约 972 KiB 主 JS chunk 警告,与原 MVP 记录的代码分割遗留项一致。
|
||||
|
||||
## Second Batch Result
|
||||
|
||||
- [x] `ResizablePanel` / `PanelResizeHandle`:支持鼠标拖动、键盘调整、ARIA 数值和本地宽度持久化。
|
||||
- [x] `TreeSearchField`:工程树和模型结构树支持本地过滤,并保留匹配节点的祖先路径。
|
||||
- [x] `ViewportHUD`:复用现有仿真、交互模式和选择状态,在视口内提供轻量状态反馈。
|
||||
- [x] `ShortcutHelpDialog`:Header 帮助入口集中说明现有键盘与鼠标操作。
|
||||
- [x] `Badge`、`Tabs`、`Separator`、`Skeleton`:补齐基础层,并升级模型加载反馈。
|
||||
- [x] 侧栏标签页:左栏拆分“工程 / 模型结构”,右栏拆分“属性 / 控制”;非活动面板保持挂载,保留树和折叠状态。
|
||||
- [x] 第二批验证:TypeScript、ESLint、14 个测试文件共 36 个测试、生产构建及 5 个 Playwright E2E 全部通过;完成加载模型和快捷键弹窗的人工截图检查。
|
||||
- [x] 审查修复:Tabs roving tabindex/方向键导航、侧栏宽度边界与指针取消清理、Dialog 打开时快捷键隔离、搜索结果目录锁定展开,以及重编译失败快照清理和新 Session 速度恢复。
|
||||
|
||||
## Third Batch Result
|
||||
|
||||
- [x] `ConfirmDialog`:统一替换移除工程的原生确认框。
|
||||
- [x] `CommandPalette`:支持 Header 入口、`Ctrl+K`、搜索、方向键和 Enter,复用现有仿真/视口/布局动作。
|
||||
- [x] `PerformancePopover`:从状态栏查看 FPS、物理步进、内存与预算状态。
|
||||
- [x] `Kbd`、`PropertyRow`、`CopyButton`:统一快捷键和属性展示,并支持复制已有选择信息。
|
||||
- [x] `TreeSearchSummary`、`SearchHighlight`、`EmptySearchState`:显示匹配数量、高亮命中并统一无结果反馈。
|
||||
- [x] `ViewportFullscreenToggle`:支持浏览器全屏进入、退出及状态同步。
|
||||
- [x] 第三批验证:TypeScript、ESLint、16 个测试文件共 42 个测试、生产构建及 5 个 Playwright E2E 全部通过;完成命令面板和完整工作台截图检查。
|
||||
- [x] 审查修复:全屏元素内 Dialog Portal、Popover 与命令面板互斥关闭、树搜索计数同源、Clipboard API 降级,以及命令面板 combobox/listbox 活动项关联。
|
||||
|
||||
## Fourth Batch Result
|
||||
|
||||
- [x] `ToastViewport` / `NotificationCenter`:模型加载成功、兼容提示和编译失败进入会话通知队列,并提供即时 Toast。
|
||||
- [x] `LayoutSettingsDialog`:统一左右栏显示、宽度重置和默认/宽视口/工程浏览/控制调试预设。
|
||||
- [x] `ProjectBreadcrumb` / `EntrySwitcher`:展示工程入口路径,并可在多入口工程中直接切换。
|
||||
- [x] `VirtualTreeViewport`:大型工程文件树及 Body/Joint 树超过阈值时启用窗口化渲染。
|
||||
- [x] `SettingsDialog`:集中管理主题、角度单位、碰撞几何、关节高级信息和外力强度。
|
||||
- [x] Header 接入通知、布局和设置入口;1024px 产品边界下隐藏品牌长标题以避免工具区重叠。
|
||||
- [x] 第四批验证:TypeScript、ESLint、18 个测试文件共 49 个测试、生产构建及 5 个 Playwright E2E 全部通过。
|
||||
|
||||
- [x] 审查修复:入口切换加载锁与禁用态、1024px Header 轨道约束及 E2E 边界检查、虚拟树 roving active descendant/方向键导航和层级展开折叠。
|
||||
|
||||
## Fifth Batch Result
|
||||
|
||||
- [x] `ToolbarOverflowMenu`:1024px 工具区通过“更多”菜单承载命令、布局、设置、全屏、帮助与主题动作。
|
||||
- [x] 通用 `Popover` / `DropdownMenu`:统一外部点击、Escape、焦点恢复及菜单方向键行为,并重构性能和通知弹层。
|
||||
- [x] `ImportProgressPanel` / `ProgressBar`:在不改变转换逻辑的前提下显示读取、资源处理、WASM/编译和视口创建阶段。
|
||||
- [x] `DiagnosticsDrawer` / EventLog:按全部、警告和错误分类查看、复制及清空会话事件。
|
||||
- [x] `SearchableCombobox`:多入口工程支持路径搜索和键盘选择。
|
||||
- [x] `ErrorRecoveryPanel`:诊断反馈提供重试入口、复制详情和返回工程树动作。
|
||||
- [x] `LiveRegion`:统一 Toast、加载阶段和诊断变化的辅助技术播报。
|
||||
- [x] 第五批验证:TypeScript、ESLint、20 个测试文件共 56 个测试和生产构建通过;Playwright E2E 完整回归覆盖更多菜单、事件日志与错误恢复。
|
||||
|
||||
- [x] 审查修复:拖放文件收集与导入共享互斥锁、仅模型编译错误允许重试、菜单首项聚焦及触发器恢复、Combobox 完整状态与 Tab 关闭、事件日志按活动标签惰性挂载、Toast 单一 live region。
|
||||
- [x] 信息归并:从“模型与控制”侧栏移除 `URDF 兼容处理` 分区,完整兼容处理明细仅保留在通知中心与事件日志。
|
||||
|
||||
## Confirmed Decisions
|
||||
|
||||
1. 第一批 A–H 全部纳入。
|
||||
2. 只采用 URDF-Studio 的专业工作台风格,保留 MuJoCo 品牌、中文界面和当前左右栏布局。
|
||||
3. 允许引入 `lucide-react`,不引入 `@floating-ui/react`。
|
||||
4. select/joint/force 工具组停靠在 Header 中央。
|
||||
5. 右侧默认展开模型信息、当前选择和关节;其他低频分区折叠,警告出现时自动展开。
|
||||
6. 第一批不新增编辑、导出、快照、AI、测量、绘制、撤销/重做等产品能力。
|
||||
7. 后续任何超出 A–H 的新组件都需再次向用户确认。
|
||||
Reference in New Issue
Block a user