diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..05eb1a2 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,141 @@ +# 本地开发环境 + +本文说明如何在本机安装依赖、启动开发服务器、构建与验证。应用为纯前端项目,数据在浏览器内处理,无需后端服务。 + +## 环境要求 + +| 依赖 | 版本建议 | +|------|----------| +| Node.js | **18+** 或 **20+**(Vite 5 要求 `^18.0.0 \|\| >=20.0.0`) | +| npm | 9+(随 Node 自带即可) | +| 浏览器 | 支持 WebGL 的现代浏览器(Chrome / Firefox / Edge 等) | + +检查版本: + +```bash +node -v # 应 >= v18 +npm -v +``` + +推荐使用 [nvm](https://github.com/nvm-sh/nvm) 管理 Node 版本。若系统默认 `node` 过旧,可先执行 `nvm use 20` 或 `nvm install 20`。 + +## 安装依赖 + +在项目根目录执行: + +```bash +cd /path/to/robot_motion_editor +npm install +``` + +首次安装会拉取 `vite`、`three`、`urdf-loader` 等依赖,生成 `node_modules/` 与 `package-lock.json`。 + +## 启动开发服务器 + +```bash +npm run dev +``` + +或使用仓库提供的脚本(等价于 `npm run dev`): + +```bash +chmod +x run.sh # 首次需要 +./run.sh +``` + +成功启动后终端会显示: + +``` +➜ Local: http://localhost:3000/ +``` + +- 默认端口:**3000**(见 `vite.config.js`) +- 配置中 `open: true`,部分环境会自动打开浏览器;否则请手动访问 [http://localhost:3000](http://localhost:3000) +- 修改 `src/` 下代码会热更新,无需重启 + +### 局域网访问(可选) + +若需从其他设备访问本机开发服务: + +```bash +npm run dev -- --host +``` + +然后使用终端显示的 Network 地址访问。 + +## 生产构建与预览 + +```bash +npm run build # 输出到 dist/ +npm run preview # 本地预览构建结果(默认另一端口,以终端为准) +``` + +构建产物用于静态托管(如 Cloudflare Pages,见根目录 `wrangler.jsonc`)。 + +## 本地验证清单 + +1. 打开 http://localhost:3000 ,页面无报错 +2. 使用仓库内 `example_trajectory.csv` 或自备 CSV 测试「加载轨迹」 +3. 加载包含 URDF 与 mesh 的文件夹测试 3D 显示(需完整模型目录) +4. 打开浏览器开发者工具(F12)确认 Console 无持续报错 + +更详细的操作步骤见 [USAGE.md](./USAGE.md)。 + +## 运行单元测试(可选) + +`tests/` 下为独立 Node 脚本,不依赖 Vite,可在项目根目录执行,例如: + +```bash +node tests/simple-test.js +node tests/trajectory-format-converter-test.js +node tests/com-calculation-test.js +node tests/ik-chain-registry-test.js +``` + +## 视口与 IK 模块 + +- `src/viewportManager.js`:同屏叠显 / 左右分屏、Ghost 材质与显隐。 +- `src/ik/`:`closed-chain-ik` 末端求解(子路径导入,避免旧版 Three 辅助几何体)、`TransformControls` 拖拽、自动关键帧。 +- 工程 JSON 可含 `viewport`、`ik` 字段(见 [docs/REQUIREMENTS-viewport-ik.md](./docs/REQUIREMENTS-viewport-ik.md))。 + +## 常见问题 + +### `npm install` 失败或 Node 版本过低 + +升级 Node 至 18 或 20 后删除 `node_modules` 再安装: + +```bash +rm -rf node_modules +npm install +``` + +### 端口 3000 已被占用 + +临时指定端口: + +```bash +npm run dev -- --port 3001 +``` + +或在 `vite.config.js` 的 `server.port` 中修改默认端口。 + +### 开发服务器已启动但页面空白 + +- 确认访问的是终端打印的 Local 地址 +- 查看浏览器 Console 是否有模块加载错误 +- 尝试无痕模式或禁用可能拦截本地资源的浏览器扩展 + +### WSL / 远程文件系统下热更新不生效 + +`vite.config.js` 已启用 `server.watch.usePolling`,一般可缓解;若仍异常,可重启 `npm run dev`。 + +### 构建时 git 相关警告 + +构建会通过 `git` 命令注入提交信息到前端常量;非 git 仓库或浅克隆时可能显示 `unknown`,不影响本地开发与运行。 + +## 相关文档 + +- [README.md](./README.md) — 功能概览与项目结构 +- [USAGE.md](./USAGE.md) — 编辑器使用说明与 CSV 格式 +- [seed_format.md](./seed_format.md) — seed 轨迹格式说明 +- [docs/REQUIREMENTS-viewport-ik.md](./docs/REQUIREMENTS-viewport-ik.md) — 同屏叠显视口与末端 IK 需求规格(v1.0) diff --git a/README.en.md b/README.en.md index b841b5a..bc52f55 100644 --- a/README.en.md +++ b/README.en.md @@ -1,98 +1,71 @@ # Robot Keyframe Editor -A web-based robot motion editing tool with support for URDF loading, CSV trajectory editing, dual-viewport comparison, and project file management. +A browser-based robot motion trajectory editor with URDF loading, CSV editing, dual-viewport comparison, inverse kinematics (IK) end-effector editing, and project persistence. -**其他语言:** [中文](README.md) +**中文:** [README.md](README.md) -## 🌐 Live Demo +## Live Demo [motion-editor.cyoahs.dev](https://motion-editor.cyoahs.dev) | Hosted on Cloudflare Pages -## 🔒 Privacy & Security +## Demonstrations -✅ **Runs Completely Locally** — All data processing happens in your browser, nothing is uploaded to any server +Screen recordings embedded as GIF for inline preview on GitHub and in Markdown viewers. -## ✨ Core Features +### IK End-Effector Editing -- **Dual-Viewport Comparison**: Original trajectory on the left, edited results on the right with synchronized camera -- **Trajectory Editing**: Residual-based keyframe system with support for joint and base editing -- **Project Save/Load**: Save complete project state (URDF, trajectories, keyframes, edit history) -- **Auto-Save**: Hybrid storage with Cookie + IndexedDB, automatically saves work state -- **Curve Editor**: Visualize joint and base changes over time with Bezier interpolation support -- **Dynamics Visualization**: Real-time display of center of mass position and contact polygon projection -- **Axis Gizmo**: 3D axis indicator in the bottom-right corner, click to switch orthogonal views -- **URDF Parsing**: Automatic loading of URDF and mesh files from a folder -- **Multi-language**: Chinese/English interface switching +Drag the end-effector in the 3D viewport, adjust pose, and write keyframes with configurable solver parameters. -## 💾 Auto-Save Mechanism +![IK end-effector editing](docs/assets/demo/end-effector-ik-edit.gif) -The application uses an intelligent layered storage strategy: +### Joint Editing -- **localStorage (5MB)**: Stores trajectories, keyframes, UI state, and small config files (<50KB) -- **IndexedDB (50MB+)**: Stores large mesh files (e.g., .stl, .dae) -- **Incremental Auto-Save**: Full save only when URDF changes, otherwise saves only trajectory and keyframes -- **Authorization Management**: Synchronously clears all storage when enabling/disabling auto-save +Edit joint trajectories via the sidebar and curve panel with keyframe management. -When auto-save is enabled, refreshing the page automatically restores the last editing state. +![Joint editing](docs/assets/demo/joint-edit.gif) -## Quick Start - -```bash -npm install # Install dependencies -npm run dev # Start development server -npm run build # Production build -``` - -## Usage Guide +### Viewport & Visualization -### Basic Workflow +Configure ghost reference model, overlay/split layout, and playback rate. -1. **Load URDF**: Select a folder containing URDF and mesh files -2. **Load Trajectory**: Load a unitree CSV (base xyz + quaternion xyzw + joint radians) or seed CSV (Frame + cm/degrees); data is converted to unitree internally -3. **Edit Keyframes**: Click DOF names to show curves, adjust parameters and add keyframes (Shift+click for multiple curves) -4. **Save Project**: Save the complete editing state (can be loaded to restore) -5. **Export Trajectory**: Select unitree/seed format and export FPS, then export the combined CSV trajectory; differing FPS values are resampled automatically +![Viewport settings](docs/assets/demo/viewport-settings.gif) -### Project Management +## Privacy -- **Save Project**: Export a project file containing URDF, trajectories, keyframes, and edit history -- **Load Project**: Restore a complete editing state from a saved project file -- **Incremental Editing**: Based on the residual system, only modified portions are stored +All processing runs locally in the browser. No data is uploaded to a server. -### Dynamics Visualization +## Features -- **Center of Mass Display**: Real-time calculation and display of robot center of mass -- **Support Polygon**: Display the convex hull projection of contact points on the ground -- **Stability Indication**: Intuitively assess the static stability of the current pose +- Residual keyframes on CSV base trajectories; linear / Bezier interpolation +- Keyframe clipboard, drag-to-move, keyboard shortcuts +- Drag-and-drop URDF folders and CSV files +- Viewport overlay/split with ghost reference model +- IK end-effector editing via `closed-chain-ik` +- On-demand curve plots with legend; timeline sync +- Project save/load, auto-save, COM visualization, EN/ZH UI -### Quick Features +## Changelog -- **Align Lowest**: The "Align Lowest" button in base control auto-adjusts XYZ to align the edited robot's lowest point with the base trajectory -- **Axis Gizmo**: The 3D axis indicator in the bottom-right corner allows quick switching to orthogonal views by clicking X/Y/Z axes +The following features were developed and contributed by **fandes** ([@fandesfyf](https://github.com/fandesfyf)). -## Tech Stack +| Date | Summary | +|------|---------| +| 2026-05-30 | IK end-effector editing with `closed-chain-ik`; viewport overlay/split and ghost model; drag-and-drop URDF/CSV import | +| 2026-05-31 | Dual IK gizmos and position-priority solve strategy | +| 2026-06-01 | Viewport toolbar, playback rate, timeline zoom, editable FPS | +| 2026-06-03 | IK solver refactor and tuning panel; keyframe clipboard and shortcuts; on-demand curves with legend; timeline–curve view sync | -- Vite: Frontend build tool -- Three.js: 3D graphics rendering -- urdf-loader: URDF parsing -- Vanilla JavaScript: Framework-free development +See [README.md](README.md) for the full feature list (Chinese). -## Project Structure +## Quick Start +```bash +npm install +npm run dev +npm run build ``` -src/ -├── main.js # Application entry point (dual-viewport rendering) -├── urdfLoader.js # URDF loading and parsing -├── trajectoryManager.js # Trajectory and keyframe management -├── trajectoryFormatConverter.js # unitree/seed CSV format conversion -├── jointController.js # Joint control UI -├── baseController.js # Base control UI (with align feature) -├── curveEditor.js # Curve editor -├── comVisualizer.js # Center of mass and support polygon visualization -├── axisGizmo.js # Axis indicator gizmo -├── timelineController.js # Timeline control -└── i18n.js # Internationalization (Chinese/English) -``` + +See [DEVELOPMENT.md](DEVELOPMENT.md) and [USAGE.md](USAGE.md). ## License diff --git a/README.md b/README.md index 80aed11..9e71e7d 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,163 @@ # 机器人关键帧编辑器 -基于 Web 的机器人运动编辑工具,支持 URDF 加载、CSV 轨迹编辑、双视口对比和工程文件管理。 +基于 Web 的机器人运动轨迹编辑工具,支持 URDF 模型加载、CSV 轨迹编辑、双视口对比、逆运动学(IK)末端编辑与工程状态管理。 -**Other language:** [English](README.en.md) +**English:** [README.en.md](README.en.md) -## 🌐 在线体验 +## 在线体验 [motion-editor.cyoahs.dev](https://motion-editor.cyoahs.dev) | 托管于 Cloudflare Pages -## 🔒 隐私安全 +## 功能演示 -✅ **完全本地运行** — 所有数据处理在浏览器完成,无服务器上传 +以下演示基于典型编辑流程录制,可在 README 与 GitHub 页面中直接预览。 -## ✨ 核心特性 +### IK 末端编辑 -- **双视口对比**: 左侧显示原始轨迹,右侧显示编辑结果,相机同步 -- **轨迹编辑**: 基于残差的关键帧系统,支持关节和基体编辑 -- **工程保存/加载**: 保存完整工程状态(URDF、轨迹、关键帧、编辑历史) -- **自动保存**: Cookie + IndexedDB 混合存储,自动保存工作状态 -- **曲线编辑器**: 可视化关节和基体随时间的变化曲线,支持贝塞尔插值 -- **动力学可视化**: 实时显示重心位置和支撑多边形投影 -- **坐标轴指示器**: 右下角3D指示器,点击快速切换正交视角 -- **URDF 解析**: 自动加载文件夹中的 URDF 和 mesh 文件 -- **多语言支持**: 中文/英文界面切换 +在三维视口中拖拽末端执行器,调整位姿并将编辑结果写入当前帧关键帧;支持求解参数在线配置。 -## 💾 自动保存机制 +![IK 末端编辑演示](docs/assets/demo/end-effector-ik-edit.gif) -应用采用智能分层存储策略: +### 关节编辑 -- **localStorage (5MB)**: 存储轨迹、关键帧、UI状态和小型配置文件(<50KB) -- **IndexedDB (50MB+)**: 存储大型 mesh 文件(如 .stl, .dae) -- **自动增量保存**: 仅在 URDF 变化时完整保存,否则仅保存轨迹和关键帧 -- **授权管理**: 启用/禁用自动保存时同步清理所有存储 +通过侧栏关节控制与曲线面板,对轨迹进行关节空间编辑与关键帧管理。 -启用自动保存后,刷新页面将自动恢复上次编辑状态。 +![关节编辑演示](docs/assets/demo/joint-edit.gif) -## 快速开始 +### 视口与可视化设置 -```bash -npm install # 安装依赖 -npm run dev # 启动开发服务器 -npm run build # 生产构建 -``` +配置 Ghost 参考模型、同屏叠显/左右分屏、播放倍率等可视化选项。 + +![视口设置演示](docs/assets/demo/viewport-settings.gif) + +## 隐私与安全 + +所有数据处理均在浏览器本地完成,不上传至服务器。 + +## 主要功能 + +### 轨迹与关键帧 + +- 基于 CSV 基线轨迹的残差关键帧编辑,支持线性与贝塞尔插值 +- 关键帧复制、粘贴、删除与拖动改帧(保留绝对编辑内容) +- 快捷键:`Ctrl+C` / `Ctrl+V`、`Delete` / `Backspace`(右键菜单同步提示) + +### 数据导入 + +- 支持将 URDF 资源目录或 CSV 轨迹文件拖入页面加载 +- 自动解析子目录中的 mesh,兼容 `package://` 路径引用 +- 支持 unitree 与 seed 两种 CSV 格式(自动单位转换) + +### 三维视口 + +- 参考轨迹 Ghost 叠显或左右分屏对比,可选相机同步 +- 视口工具栏:Ghost 显隐、透明度、播放倍率、布局切换 +- 坐标轴指示器快速切换正交视角 + +### IK 末端编辑 + +- 基于 [closed-chain-ik](https://www.npmjs.com/package/closed-chain-ik) 的末端位姿拖拽求解 +- 位置与姿态统一权重配置,参考四元数增量编辑 +- 可选求解日志与运动学校验(见 `tests/`) -## 使用说明 +### 曲线与时间轴 -### 基本流程 +- 按关节名称按需显示曲线;曲线面板图例标识当前编辑对象 +- 时间轴滚轮缩放与平移;曲线与时间轴 X 轴视图双向同步 +- 工程 FPS 可在线修改 -1. **加载 URDF**: 选择包含 URDF 和 mesh 文件的文件夹 -2. **加载轨迹**: 加载 unitree CSV(base xyz + 四元数 xyzw + 关节弧度)或 seed CSV(Frame + cm/degree),内部会自动转换为 unitree 数据 -3. **编辑关键帧**: 点击自由度名称显示曲线,调整参数后添加关键帧(Shift+点击多选曲线) -4. **保存工程**: 保存完整的编辑状态(支持加载恢复) -5. **导出轨迹**: 选择 unitree/seed 格式和导出 FPS 后导出融合后的 CSV 轨迹;FPS 不同时会自动插值重采样 +### 其它 -### 工程管理 +- 工程保存/加载与自动保存(Cookie + IndexedDB) +- 重心与支撑多边形可视化 +- 中英文界面 -- **保存工程**: 导出包含 URDF、轨迹、关键帧、编辑历史的工程文件 -- **加载工程**: 恢复已保存的完整编辑状态 -- **增量编辑**: 基于残差系统,仅存储修改部分 +## 更新记录 -### 动力学可视化 +以下功能由贡献者 **fandes**([@fandesfyf](https://github.com/fandesfyf))开发并提交。 -- **重心显示**: 实时计算并显示机器人重心位置 -- **支撑多边形**: 显示底面接触点构成的凸包投影 -- **稳定性指示**: 直观判断当前姿态的静态稳定性 +| 日期 | 内容 | +|------|------| +| 2026-05-30 | IK 末端编辑与 `closed-chain-ik` 集成;视口叠显/分屏与 Ghost 模型;URDF/CSV 拖入导入 | +| 2026-05-31 | IK 双 Gizmo 与位置优先求解策略 | +| 2026-06-01 | 视口配置工具栏、播放倍率、时间轴缩放与可编辑 FPS | +| 2026-06-03 | IK 求解器重构与调参面板;关键帧剪贴板与快捷键;曲线按需绘制与图例;时间轴与曲线视图同步 | -### 快捷功能 +### 新增与增强功能 -- **平移对齐**: 基座控制中的"平移对齐"按钮可自动调整XYZ,使编辑后机器人的最低点与原始轨迹对齐 -- **坐标轴指示器**: 右下角的3D轴指示器,点击X/Y/Z轴可快速切换到对应的正交视角 +| 类别 | 说明 | +|------|------| +| IK 末端编辑 | 三维手柄拖拽、关键帧自动写入、权重与迭代参数配置 | +| 视口 | Ghost 参考轨迹、叠显/分屏、可视化工具栏 | +| 数据导入 | URDF 目录与 CSV 拖放加载 | +| 关键帧 | 复制/粘贴/删除、拖动改帧、绝对位姿语义 | +| 时间轴 | 缩放、平移、与曲线面板联动 | +| 曲线 | 按关节显示、图例、性能优化 | + +## 自动保存 + +- **localStorage**:轨迹、关键帧与界面状态 +- **IndexedDB**:大型 mesh 资源 +- URDF 未变更时仅增量保存轨迹与关键帧 + +## 快速开始 + +**环境要求:** Node.js 18+(推荐 20+),支持 WebGL 的现代浏览器。 + +```bash +npm install +npm run dev # http://localhost:3000 +npm run build +npm run preview +npm run test:ik-fk # 见 DEVELOPMENT.md +``` + +- 开发说明:[DEVELOPMENT.md](DEVELOPMENT.md) +- 使用手册:[USAGE.md](USAGE.md) +- 视口与 IK 设计:[docs/REQUIREMENTS-viewport-ik.md](docs/REQUIREMENTS-viewport-ik.md) + +## 使用概要 + +1. 加载 URDF(拖入文件夹或文件选择器) +2. 加载 CSV 轨迹(拖入或文件选择器) +3. 编辑关节、基座或 IK 末端,添加/更新关键帧 +4. 可选:在曲线面板查看关节轨迹 +5. 保存工程或导出 CSV + +关键帧快捷键:`Ctrl+C` 复制,`Ctrl+V` 粘贴至播放头,`Delete` 删除。详见应用内「使用说明」与 [USAGE.md](USAGE.md)。 ## 技术栈 -- Vite: 前端构建工具 -- Three.js: 3D 图形渲染 -- urdf-loader: URDF 解析 -- 原生 JavaScript: 无框架依赖 +| 组件 | 说明 | +|------|------| +| Vite | 构建与开发服务 | +| Three.js | 三维渲染 | +| urdf-loader | URDF 解析 | +| closed-chain-ik | 末端 IK 求解 | ## 项目结构 ``` -src/ -├── main.js # 应用主入口(双视口渲染) -├── urdfLoader.js # URDF 加载和解析 -├── trajectoryManager.js # 轨迹和关键帧管理 -├── trajectoryFormatConverter.js # unitree/seed CSV 格式转换 -├── jointController.js # 关节控制 UI -├── baseController.js # 基体控制 UI(含平移对齐) -├── curveEditor.js # 曲线编辑器 -├── comVisualizer.js # 重心和支撑多边形可视化 -├── axisGizmo.js # 坐标轴指示器 -├── timelineController.js # 时间轴控制 -├── cookieManager.js # 自动保存管理(localStorage) -├── indexedDBManager.js # 大文件存储(IndexedDB) -├── themeManager.js # 主题管理 -└── i18n.js # 多语言支持 -``` -├── axisGizmo.js # 坐标轴指示器 -├── timelineController.js # 时间轴控制 -└── i18n.js # 国际化(中文/英文) +robot_motion_editor/ +├── index.html +├── docs/ +│ ├── assets/demo/ # README 演示 GIF +│ └── REQUIREMENTS-viewport-ik.md +├── tests/ +├── DEVELOPMENT.md +├── USAGE.md +└── src/ + ├── main.js + ├── viewportManager.js + ├── viewportToolbar.js + ├── timelineController.js + ├── timelineCurveViewSync.js + ├── curveEditor.js + ├── trajectoryManager.js + ├── fileDropHandler.js + └── ik/ # IK 求解与面板 ``` ## License MIT - diff --git a/USAGE.md b/USAGE.md index 79daab3..2906a1a 100644 --- a/USAGE.md +++ b/USAGE.md @@ -12,11 +12,47 @@ ### 2. 关键帧管理 ✅ 添加关键帧功能 -✅ 删除关键帧功能(两种方式): - - 点击"删除当前关键帧"按钮 - - 右键点击时间轴上的关键帧标记 +✅ 删除关键帧功能: + - 点击「删除当前关键帧」 + - 右键时间轴关键帧标记 → 删除 + - `Delete` / `Backspace`(当前帧或已选关键帧) +✅ 复制 / 粘贴关键帧(右键菜单或 `Ctrl+C` / `Ctrl+V`) +✅ 拖动关键帧标记可改帧号(保留绝对编辑内容) ✅ 关键帧在时间轴上显示为绿色标记 -✅ 鼠标悬停时标记会放大并变色 + +## 视口模式 + +- **同屏叠显**(默认):参考轨迹以半透明 Ghost 与编辑轨迹叠在同一画面;可勾选显隐、调节 Ghost 颜色与透明度(0.35~0.5)。 +- **左右分屏**:与旧版相同,左侧 Base、右侧编辑后轨迹。 + +## IK 末端编辑 + +1. 加载 URDF 与 CSV 后,展开侧栏 **IK末端编辑**。 +2. 勾选 **启用末端拖拽 IK**,在 **末端 Link** 下拉框选择连杆(可用快捷按钮)。 +3. 在 3D 视口中拖拽末端手柄;松手后**自动**在当前帧写入关键帧。 +4. 面板内可调位置/姿态权重与求解参数;可选调试日志。 +5. 播放时间轴时 IK 手柄自动隐藏。 + +## 曲线面板 + +1. 加载 CSV 后,**点击关节名称**即可显示该关节整段轨迹(无需先添加关键帧)。 +2. 右上角图例显示当前曲线名称与 CSV 基线说明。 +3. 曲线区域滚轮缩放、Shift+拖拽平移,与时间轴 **X 轴同步**。 +4. 时间轴「1:1」或曲线「重置缩放」会同时重置两侧视图。 + +## 拖入导入 URDF / CSV + +无需只依赖文件选择按钮,可直接**拖入**资源: + +| 拖入内容 | 说明 | +|----------|------| +| **机器人文件夹** | 含 `.urdf` 及 mesh(如 `meshes/*.stl`)的整个目录;支持子文件夹,路径与 URDF 内引用一致 | +| **单个 CSV** | unitree 或 seed 格式轨迹文件 | +| **混合文件夹** | 若目录内既有 URDF 又有 CSV,会分别识别并加载 | + +拖入时页面会显示全屏提示;松手后开始解析。URDF 加载完成后即可在侧栏编辑关节、启用 IK、添加关键帧,与通过按钮导入相同。 + +> 须使用 **Chrome / Edge / Firefox** 等支持文件夹拖放的现代浏览器;仅拖单个 `.urdf` 而无 mesh 时,模型可能无法完整显示。 ## 使用步骤 @@ -33,14 +69,12 @@ 访问 http://localhost:3000 3. **加载机器人模型** - - 点击"加载 URDF 文件夹" - - 选择包含 URDF 文件和 mesh 文件的完整文件夹 - - 等待模型加载完成 - - 3D 视图中会显示机器人模型 + - **方式 A(推荐)**:将含 `.urdf` 与 mesh 的文件夹**拖入**浏览器窗口 + - **方式 B**:点击「加载 URDF 文件夹」并选择同一目录 + - 等待解析完成,3D 视图中显示机器人 4. **加载轨迹** - - 点击"加载 CSV 轨迹" - - 选择 unitree CSV 或 seed CSV 文件(或使用 example_trajectory.csv) + - 将 `.csv` **拖入**页面,或点击「加载 CSV 轨迹」选择文件(如 `example_trajectory.csv`) - 时间轴会更新为轨迹长度 5. **编辑关键帧** @@ -92,11 +126,22 @@ Frame,root_translateX,root_translateY,root_translateZ,root_rotateX,root_rotateY, ## 快捷操作 +### 3D 视口 - **左键拖动**:旋转视角 - **右键拖动**:平移视角 - **滚轮**:缩放 -- **点击关键帧标记**:跳转到该帧 -- **右键关键帧标记**:删除关键帧 + +### 时间轴 +- **滚轮**:缩放;**Shift+滚轮**:横向平移 +- **空格**:播放/暂停;**← / →**:逐帧 +- **点击关键帧标记**:跳转;**拖动**:移动关键帧 +- **右键关键帧**:复制 / 粘贴 / 删除(菜单显示快捷键) + +### 关键帧 +- **Ctrl+C**:复制;**Ctrl+V**:粘贴到播放头;**Delete**:删除 + +### 曲线 +- **点击关节名**:显示/隐藏曲线(Shift+点击多选) ## 注意事项 diff --git a/docs/REQUIREMENTS-viewport-ik.md b/docs/REQUIREMENTS-viewport-ik.md new file mode 100644 index 0000000..e00b358 --- /dev/null +++ b/docs/REQUIREMENTS-viewport-ik.md @@ -0,0 +1,406 @@ +# 需求规格说明:同屏叠显视口与末端 IK 编辑 + +| 属性 | 内容 | +|------|------| +| 文档版本 | v1.0 | +| 状态 | 待评审 / 待开发 | +| 适用产品 | 机器人关键帧编辑器(robot_motion_editor) | +| 主要参考机型 | **Unitree G1**(URDF + seed/unitree 轨迹) | +| 关联文档 | [DEVELOPMENT.md](../DEVELOPMENT.md)、[USAGE.md](../USAGE.md)、[seed_format.md](../seed_format.md) | + +--- + +## 1. 背景与目标 + +### 1.1 背景 + +当前版本在同一页面内采用**左右分屏**双视口:左侧仅显示 CSV 原始轨迹(Base),右侧显示叠加关键帧残差后的编辑轨迹(Modified)。该方式占用横向空间、对比时需视线左右切换,且无法在同一视角下直观感受姿态偏差。 + +编辑能力以**关节空间**(侧栏滑块、曲线编辑器)和**基座空间**为主,**不具备**末端连杆位姿拖拽与逆运动学(IK)求解。 + +### 1.2 目标 + +1. **默认同屏叠显**:参考轨迹与编辑轨迹处于**同一 3D 画面**;参考模型为**半透明 Ghost**,可调颜色,降低遮挡。 +2. **保留左右分屏**为可选项,满足习惯旧交互的用户。 +3. 基于 **closed-chain-ik** 实现**手臂与腿部**的末端空间编辑;末端 **Link** 通过**下拉框**配置。 +4. 以 **Unitree G1** 为主要验收机型;拖拽末端结束时**自动写入当前帧关键帧**(残差体系与现有一致)。 + +### 1.3 非目标(本期不做) + +- 多机器人/多 URDF 同场景编辑 +- 全身同时多末端 IK(仅**单激活链**求解;其余链静止) +- 云端 IK 服务、实时硬件下发 +- 自动从 GLB 生成 URDF +- 足底闭链双足约束(可作为后续增强项) + +--- + +## 2. 术语 + +| 术语 | 定义 | +|------|------| +| Base 轨迹 | CSV 加载的只读原始运动数据 | +| 编辑轨迹 | Base + 关键帧残差插值后的结果 | +| Ghost 参考模型 | 仅展示 Base 状态的机器人实例,半透明、可配色 | +| 编辑模型 | 展示编辑后状态的机器人实例,不透明(或略高于 Ghost 的不透明度) | +| 末端 Link | URDF 运动链末端 `URDFLink`,作为 IK 目标位姿附着点 | +| IK 链 | 从某固定关节到末端 Link 的串联关节集合 | +| 关键帧残差 | 现有 `trajectoryManager` 中 `residual` / `baseResidual` 机制 | + +--- + +## 3. 用户故事 + +| ID | 作为… | 我希望… | 以便… | +|----|--------|---------|--------| +| US-01 | 动画师 | 默认在同一画面看到半透明参考姿态和实心编辑姿态 | 直接对比偏差而不用左右看 | +| US-02 | 动画师 | 用复选框开关参考/编辑模型及各自重心显示 | 聚焦单条轨迹或减少视觉干扰 | +| US-03 | 动画师 | 自定义参考 Ghost 颜色 | 在不同主题/背景下仍清晰可辨 | +| US-04 | 动画师 | 切换回左右分屏模式 | 沿用旧工作流 | +| US-05 | 动画师 | 在侧栏选择末端 Link 并拖拽 3D 手柄 | 用末端空间直觉调整手臂/腿 | +| US-06 | 动画师 | 拖完末端自动在当前帧打关键帧 | 少点一次按钮、与滑块编辑一致 | +| US-07 | 工程师 | 工程文件保存 IK 链配置(末端 Link 等) | 重开工程无需重新配置 G1 | + +--- + +## 4. 功能需求:视口与模型显示(FR-V) + +### FR-V-01 视口模式 + +| 项 | 说明 | +|----|------| +| 模式 | `overlay`(同屏叠显)、`split`(左右分屏) | +| **默认值** | **`overlay`** | +| 切换入口 | 3D 视口顶部工具条:单选或下拉「视口:同屏叠显 / 左右分屏」 | +| 持久化 | 写入 `localStorage`(键名建议 `viewportMode`),与自动保存 Cookie 逻辑独立;加载工程时可选择是否覆盖(默认沿用用户上次选择) | + +**同屏叠显(overlay)** + +- 单一 `THREE.Scene`、单一 `OrthographicCamera`、单一 `OrbitControls`。 +- 同一画布全宽渲染,**不使用** `setScissor` 左右切分。 +- 同时存在 `robotGhost`(Base)与 `robotEdited`(Modified)两个 `URDFRobot` 实例。 + +**左右分屏(split)** + +- 行为与**当前线上版本**等价:左 Base、右 Modified,相机同步,中间分隔线。 +- 实现上可保留现有双场景路径,或由 `viewportManager` 在两种拓扑间切换。 + +### FR-V-02 Ghost 参考模型 + +| 属性 | 要求 | +|------|------| +| 数据来源 | 当前帧 `trajectoryManager.getBaseState(frame)` | +| 不透明度 | **0.35 ~ 0.50**,默认 **0.40**;可在视口工具条用滑块调节(步进 0.05) | +| 深度写入 | `depthWrite: false`(推荐),减轻与编辑模型重叠时的 z-fighting | +| 渲染顺序 | Ghost `renderOrder` 低于编辑模型,保证编辑模型优先显示 | +| 颜色 | 用户可选预设色 + 自定义颜色(``) | +| 预设色(建议) | 青 `#4ec9b0`、绿 `#6a9955`、蓝 `#569cd6`、紫 `#c586c0`(需适配深/浅主题对比度) | +| 交互 | Ghost **不可**被 TransformControls / 射线选中;`raycast` 对 Ghost 子网格关闭或单独 layer | + +### FR-V-03 编辑模型 + +| 属性 | 要求 | +|------|------| +| 数据来源 | 当前帧 `trajectoryManager.getCombinedState(frame)` | +| 外观 | 保持 URDF 原始材质为主,可做轻微色调区分(可选,默认不改色) | +| 不透明度 | 1.0(不透明) | +| 交互 | IK 手柄、跟随相机、COM/包络线默认绑定编辑模型 | + +### FR-V-04 显示开关(复选框) + +视口左上角(或工具条内)提供: + +| 控件 | 控制对象 | 默认 | +|------|----------|------| +| ☑ 显示参考轨迹 (Ghost) | `robotGhost.visible`、Ghost 关联 COM(若开启) | 开 | +| ☑ 显示编辑轨迹 | `robotEdited.visible`、编辑模型 COM | 开 | + +- 切换即时生效,无需刷新。 +- 图例展示当前 Ghost 色块 + 文案,与复选框对齐。 + +### FR-V-05 重心与包络线 + +| 模式 | Ghost | 编辑 | +|------|-------|------| +| COM 标记颜色 | 与 Ghost 主色一致或降饱和 | 保持现有红色系或主题警告色 | +| 包络线 | 可选:仅编辑模型计算;Ghost 不画包络线(默认) | 与现逻辑一致 | +| 复选框关闭 | 对应实例 COM 隐藏 | 同左 | + +### FR-V-06 相机与辅助 UI + +- 移除 overlay 模式下左右角标「原始轨迹 / 编辑后」;改为**图例 + 复选框**(FR-V-04)。 +- split 模式保留左右角标。 +- 右下角 `axisGizmo` 在两种模式下均使用**全宽视口**计算位置。 +- `followRobot` 仅跟踪 **编辑模型** 根位姿。 + +### FR-V-07 视频导出 + +- `overlay`:导出画面为同屏双色(与屏幕一致,尊重复选框状态)。 +- `split`:保持现有左右拼接导出逻辑。 + +### FR-V-08 工程保存 / 自动保存 + +工程 JSON 扩展字段(向后兼容,旧工程缺省则用默认值): + +```json +{ + "viewport": { + "mode": "overlay", + "ghostOpacity": 0.4, + "ghostColor": "#4ec9b0", + "showGhost": true, + "showEdited": true + } +} +``` + +--- + +## 5. 功能需求:末端 IK(FR-IK) + +### FR-IK-01 技术选型 + +| 项 | 要求 | +|----|------| +| 库 | **closed-chain-ik**(`gkjohnson/closed-chain-ik-js`) | +| URDF 桥接 | `URDFUtils.urdfRobotToIKRoot`、`setIKFromUrdf`、`setUrdfFromIK` | +| 3D 交互 | `THREE.TransformControls`(平移 + 旋转,空间:世界或局部可配置,默认**世界**) | +| 求解时机 | `objectChange` / `dragging-changed` 节流;`dragging-changed` 结束且求解成功时触发关键帧(见 FR-IK-06) | + +依赖新增需在 `package.json` 声明;实施前完成与 `three@0.160`、`urdf-loader@0.12.x` 的 Spike 兼容性验证。 + +### FR-IK-02 IK 链与末端 Link 配置 + +**配置 UI(侧栏区块「IK 编辑」)** + +| 控件 | 说明 | +|------|------| +| 启用 IK | 主开关;关闭时隐藏 TransformControls | +| 末端 Link | **下拉框**,选项为当前 URDF 中所有 `URDFLink` 名称(按字母或树序排序) | +| 链根关节(高级,可折叠) | 可选下拉:自动推断 / 手动选择链上某一 `URDFJoint`;默认**自动** | + +**自动推断规则(G1 及通用人形)** + +从所选末端 Link 向上遍历 URDF 树,直到遇到以下**停止关节**之一: + +- 躯干:`waist_*`、`torso`、`pelvis`、`base_link` 的父关节 +- 或对侧分支(遇到非当前肢体的 `left_` / `right_` 前缀切换) + +链上仅包含 `revolute` / `continuous` / `prismatic` 关节;`fixed` 跳过。 + +**G1 默认预设(加载 G1 URDF 后自动填充下拉默认值,可改)** + +| 预设名 | 建议末端 Link(示例,以实际 URDF 为准) | 备注 | +|--------|----------------------------------------|------| +| 左手 | 含 `left` + `wrist` / `hand` / `palm` 的 link | 7 DOF 臂 | +| 右手 | 含 `right` + `wrist` / `hand` / `palm` | 同上 | +| 左脚 | 含 `left` + `ankle` / `foot` | 腿链 | +| 右脚 | 含 `right` + `ankle` / `foot` | 同上 | + +seed 轨迹关节名参考:[seed_format.md](../seed_format.md)(`left_*_joint_dof` 等),**IK 链以 URDF Link/Joint 名为准**,与 CSV 列通过现有 `jointController` 名称对齐。 + +用户可从下拉框任选 Link(不限于四肢),以满足非标准 mesh 命名。 + +### FR-IK-03 求解行为 + +| 项 | 说明 | +|----|------| +| 求解对象 | **仅 `robotEdited`** | +| 浮动基座 | 当前帧 **combined** 的 root 位姿作为固定约束,**不参与**该链 IK(腰关节若在链内则参与) | +| 关节限位 | 使用 URDF `` | +| 目标 | TransformControls 的位姿 → `Goal` 附着末端 link | +| 失败 | 位置/姿态误差超阈值:不提交关节角、Toast/状态栏提示「IK 无解或超限」、不自动关键帧 | +| 性能 | 单链 DOF ≥ 6 时优先 `WorkerSolver`;拖拽过程 ≤ 30ms/帧 为目标(G1 实机 URDF 测定) | + +### FR-IK-04 腿链附加选项(与臂共用面板) + +| 选项 | 默认 | 说明 | +|------|------|------| +| 锁定足底高度 | 关 | 开启时求解后强制末端 link 原点 z = 拖拽开始时 z(软约束或后处理) | +| 仅位置 / 位置+姿态 | 位置+姿态 | 腿预设默认「位置+姿态」;臂同 | + +### FR-IK-05 与残差 / 关节 UI 同步 + +求解成功后: + +1. `URDFUtils.setUrdfFromIK(robotEdited, ikRoot)` +2. `robotEdited.updateMatrixWorld(true)` +3. `jointController` 从 `robotEdited` 同步滑块数值 +4. `baseController` 若腰/基座在链外则保持 combined 基座不变 + +### FR-IK-06 自动关键帧(已确认) + +| 事件 | 行为 | +|------|------| +| TransformControls **`pointerup` 且 `dragging === false`** | 若 IK 成功且相对求解前有可感知变化(关节角 Δ > 1e-4 rad) | +| 调用 | `trajectoryManager.addKeyframe(currentFrame, jointValues, baseValues)`,逻辑与 `jointController.autoUpdateKeyframe` / 手动「添加关键帧」一致 | +| UI 反馈 | 时间轴当前帧出现关键帧标记;曲线编辑器刷新 | +| 拖动中 | 仅预览,**不**每帧写入关键帧 Map | + +若当前帧**已有**关键帧:视为**更新**该帧残差(覆盖),不新增帧号。 + +### FR-IK-07 播放与时间轴 + +- 播放动画时:**禁用** TransformControls,避免与插值冲突。 +- scrub 时间轴:若 IK 开启,将手柄同步到当前帧末端 link 世界位姿(`forward kinematics` 由 `robotEdited` 姿态得出)。 + +### FR-IK-08 工程持久化 + +```json +{ + "ik": { + "enabled": false, + "endEffectorLink": "left_wrist_yaw_link", + "chainRootJoint": null, + "legLockFootZ": false, + "goalMode": "positionAndOrientation" + } +} +``` + +### FR-IK-09 单激活链 + +- 同时仅 **1 条** IK 链激活(一个末端下拉选择)。 +- 切换末端下拉时:重建 IK 树、重定位 TransformControls。 + +--- + +## 6. Unitree G1 验收基准 + +### 6.1 资产 + +- URDF:官方或团队提供的 **G1** 完整包(mesh + urdf),关节数与 seed 示例一致(腰 3 + 腿 6×2 + 臂 7×2 = 29 可动轴,以实际 URDF 为准)。 +- 轨迹:至少 1 条 **seed 格式** G1 CSV(见 `seed_format.md`)及 1 条 unitree 格式。 + +### 6.2 验收场景 + +| # | 场景 | 通过标准 | +|---|------|----------| +| G1-01 | 加载 G1 URDF + seed CSV,默认 overlay | Ghost 半透明,编辑模型实心,同视角可对比 | +| G1-02 | 调整 Ghost 颜色与不透明度 | 实时生效,工程保存可恢复 | +| G1-03 | 切换 split | 与现版左右分屏行为一致 | +| G1-04 | 左手末端下拉 + 拖拽 | 肩肘腕随动,关节限位不爆 | +| G1-05 | 左脚末端下拉 + 拖拽 | 髋膝踝随动;可选锁足高度 | +| G1-06 | 拖末端松手 | 当前帧自动关键帧,导出 CSV 含修改 | +| G1-07 | 播放中 | 无 TransformControls;播放结束可继续 IK | +| G1-08 | 换右臂/右腿预设 | 下拉切换后链正确 | + +--- + +## 7. UI 线框(逻辑布局) + +``` +┌─ 工具栏(加载 URDF / CSV / 工程…)────────────────────────────┐ +├─ main-content ─────────────────────────────────────────────────┤ +│ ┌─ #viewport ─────────────────────────────┐ ┌─ sidebar ────────┐ │ +│ │ [视口: ●同屏叠显 ○左右分屏] │ │ …基体/关节… │ │ +│ │ ☑参考(Ghost) ☑编辑 Ghost色 [■] 透明[===]│ │ ▶ IK 编辑 │ │ +│ │ ┌图例: ■ 参考 ■ 编辑────────────────┐ │ │ ☑ 启用 IK │ │ +│ │ │ [ 3D:Ghost + 实心编辑模型 ] │ │ │ 末端 Link [▼] │ │ +│ │ │ [ TransformControls @ 末端 ] │ │ │ ☐ 锁足高度 │ │ +│ │ └────────────────────────────────────┘ │ │ 目标: ○位姿 ●位姿+姿态│ +│ │ [相机 / COM / 包络线 … 现有按钮] │ └──────────────────┘ │ +│ └────────────────────────────────────────┘ │ +├─ timeline + curve editor(现有)───────────────────────────────┤ +└────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 8. 架构与模块划分 + +| 模块 | 职责 | +|------|------| +| `src/viewportManager.js` | 模式切换、单/双场景、Ghost 材质、复选框、localStorage | +| `src/main.js` | 编排;`updateRobotState` 重命名为语义化 `robotGhost` / `robotEdited` | +| `src/ik/ikChainRegistry.js` | Link 列表、自动链推断、G1 预设 | +| `src/ik/ikSolverService.js` | closed-chain-ik 封装、Worker、误差判定 | +| `src/ik/endEffectorControls.js` | TransformControls、拖拽生命周期、自动关键帧 | +| `src/ik/ikPanel.js` | 侧栏 DOM 与 i18n | +| `index.html` / `i18n.js` | 新控件与文案 | + +**数据流(IK 一次拖拽)** + +``` +用户拖 TransformControls + → ikSolverService.solve(goal) + → setUrdfFromIK(robotEdited) + → jointController 同步 + → pointerup → trajectoryManager.addKeyframe + → timeline / curveEditor 刷新 +``` + +--- + +## 9. 非功能需求(NFR) + +| ID | 类别 | 要求 | +|----|------|------| +| NFR-01 | 隐私 | IK 仅在浏览器本地计算,无上传 | +| NFR-02 | 兼容 | Chrome / Edge 最近两个大版本;WebGL2 | +| NFR-03 | 性能 | G1 overlay 下 60fps 预览(无 IK 拖拽时) | +| NFR-04 | 可维护 | 视口与 IK 解耦,split 模式回归测试清单固定 | +| NFR-05 | 国际化 | 中文/英文键值入 `i18n.js` | +| NFR-06 | 向后兼容 | 旧工程无 `viewport`/`ik` 字段时使用文档默认值 | + +--- + +## 10. 实施阶段与交付物 + +| 阶段 | 范围 | 交付物 | 建议工期 | +|------|------|--------|----------| +| **P1** | FR-V 全部 + 工程字段 | overlay 默认、Ghost、复选框、split 可选、导出 | 3~5 天 | +| **P2** | FR-IK Spike + 单链臂 | closed-chain-ik 集成、下拉 Link、自动关键帧 | 4~6 天 | +| **P3** | 腿链 + G1 验收 | 锁足、预设、Worker、G1-01~08 通过 | 4~5 天 | +| **P4** | 文档与回归 | USAGE/DEVELOPMENT 更新、测试脚本 | 1~2 天 | + +--- + +## 11. 验收标准(总表) + +### 11.1 视口 + +- [ ] 首次打开默认为**同屏叠显** +- [ ] Ghost 不透明度在 **0.35~0.5** 可调,默认 0.4 +- [ ] Ghost **颜色可选**且可保存到工程 +- [ ] 复选框可独立隐藏参考/编辑模型 +- [ ] **左右分屏**可从 UI 切换且功能与现版一致 +- [ ] 视频导出与当前视口模式一致 + +### 11.2 IK + +- [ ] 使用 **closed-chain-ik** 实现求解 +- [ ] **下拉框**可选择任意末端 Link;臂、腿均可配置 +- [ ] 拖拽末端松手后**自动** `addKeyframe`(更新或新建当前帧) +- [ ] 求解失败有提示且不写关键帧 +- [ ] **G1** URDF + seed CSV 通过第 6.2 节全部场景 + +--- + +## 12. 风险与依赖 + +| 风险 | 缓解 | +|------|------| +| closed-chain-ik 与 three 版本不兼容 | P2 首日 Spike;必要时锁版本 | +| G1 URDF Link 命名与预设不一致 | 预设仅作初始值;以下拉手动选择为准 | +| Ghost + 实心模型 z-fighting | depthWrite off + renderOrder | +| 自动关键帧过于频繁 | 仅在 pointerup + 变化阈值通过时写入 | +| split/overlay 双路径维护成本 | 统一 `viewportManager` API,避免 main.js 分支膨胀 | + +--- + +## 13. 修订记录 + +| 版本 | 日期 | 说明 | +|------|------|------| +| v1.0 | 2026-05-30 | 初稿:视口叠显 + Ghost + closed-chain-ik + G1 + 自动关键帧 | + +--- + +## 14. 已确认产品决策(评审锁定) + +1. 参考模型:**半透明 Ghost**,opacity **0.35~0.5**,**可选颜色**。 +2. 默认视口:**同屏叠显**;**左右分屏**保留为可选项。 +3. IK:**closed-chain-ik**;末端 **Link 下拉配置**;**手臂与腿**均支持。 +4. 主验收机型:**Unitree G1**。 +5. 拖末端:**自动打关键帧**(pointerup,更新当前帧残差)。 diff --git a/docs/assets/demo/end-effector-ik-edit.gif b/docs/assets/demo/end-effector-ik-edit.gif new file mode 100644 index 0000000..5e1dd20 Binary files /dev/null and b/docs/assets/demo/end-effector-ik-edit.gif differ diff --git a/docs/assets/demo/joint-edit.gif b/docs/assets/demo/joint-edit.gif new file mode 100644 index 0000000..31ad27c Binary files /dev/null and b/docs/assets/demo/joint-edit.gif differ diff --git a/docs/assets/demo/viewport-settings.gif b/docs/assets/demo/viewport-settings.gif new file mode 100644 index 0000000..3eb7cd8 Binary files /dev/null and b/docs/assets/demo/viewport-settings.gif differ diff --git a/index.html b/index.html index 09de7b3..e9b5536 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,39 @@ 机器人关键帧编辑器 +