diff --git a/.codex b/.codex new file mode 100644 index 00000000..e69de29b diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc1c521e..e9aef729 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,10 +11,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12", "3.13"] + python-version: ["3.12", "3.13"] steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 diff --git a/.gitignore b/.gitignore index 9cbdaf70..e12024cb 100644 --- a/.gitignore +++ b/.gitignore @@ -22,8 +22,22 @@ poetry.lock botpy.log nano.*.save .DS_Store -uv.lock package-lock.json node_modules/ .claude/scheduled_tasks.lock .claude/worktrees/ +.codex/ + +# ROS workspace build artifacts +robotics +# robotics/ros_ws/build/ +# robotics/ros_ws/install/ +# robotics/ros_ws/log/ + +# Local simulation planning docs +docs/simulation-agent-workflow.md +docs/simulation-development-flow.md + +# Local robotics docs +robotics/README.md +robotics/README.general.md \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..e4fba218 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..56ef8c86 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,24 @@ +# RoboClaw Agent 开发指南 + +运用第一性原理思考,拒绝经验主义和路径盲从,不要假设我完全清楚目标,保持审慎,从原始需求和问题出发,若目标模糊请停下和我讨论,若目标清晰但路径非最优,请直接建议更短、更低成本的办法。 + +--- + +## 工作规范 + +### 架构原则 + +- 对象优先:所有功能从对象建模出发——先识别实体与职责边界,再设计对象间的协作关系。 +- 物理文件组织必须直接反映逻辑架构。目录名、文件名、包结构要让人一眼看出模块职责和层级关系。如果架构调整了,文件结构必须同步调整。 + +### 代码规范 + +- 框架代码放 `roboclaw/embodied/`,用户资产放 `~/.roboclaw/workspace/embodied/`。 +- 不写向后兼容代码。不保留旧接口、不做 fallback 适配、不写 deprecated wrapper。旧的不要了就直接删掉。 +- 不用 try/except 吞错误。有报错就让它直接抛出来,不要静默捕获。只在确实需要处理特定异常时才 catch。 +- 复用优先。已有实现的功能不要重复造轮子,先找现有代码再决定是否新写。 +- 单个 .py 文件不超过 1000 行。超过时必须将独立逻辑拆分到单独的模块。 +- 嵌套不超过 3 层缩进。超过时应将内层逻辑提取为独立函数。 + + +--- diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 07728c68..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,50 +0,0 @@ -# RoboClaw Agent 开发指南 - -> 相关文档: -> - 产品愿景:[`docs/product-vision.md`](docs/product-vision.md) -> - 架构设计:[`docs/architecture.md`](docs/architecture.md) -> - 架构对比(LeRobot / dimos / RoboClaw):[`docs/architecture-comparison.md`](docs/architecture-comparison.md) - ---- - -运用第一性原理思考,拒绝经验主义和路径盲从,不要假设我完全清楚目标,保持审慎,从原始需求和问题出发,若目标模糊请停下和我讨论,若目标清晰但路径非最优,请直接建议更短、更低成本的办法。 - ---- - -## 前置依赖 - -建议安装 [Codex 插件](https://github.com/openai/codex-plugin-cc) 以启用 Claude + Codex 并行协作。 - -## 工作规范 - -### 并行协作(Claude sub-agent + Codex sub-agent) - -所有非 trivial 的实现任务,必须起两个并行 **sub-agent** 写完全相同的代码: -- **Claude sub-agent**:用 Agent tool 启动,`isolation: "worktree"` 在独立 git worktree 中工作。 -- **Codex sub-agent**:手动创建 git worktree(`git worktree add /tmp/roboclaw-codex-xxx HEAD`),然后用 `/codex:rescue` 在该 worktree 中执行。 -- 两个 sub-agent **同时启动**,写完全相同的任务。完成后对比两个版本,取各自优点合并到主分支。 -- 合并后清理所有 worktree。 - -### 提交前双路审查 - -commit 前必须跑两个 review(同样用 sub-agent 并行): -- **Claude sub-agent** 执行 `/simplify`:检查代码复用、质量、效率。发现问题直接修。 -- **Codex sub-agent** 执行 `/codex:review`:从独立视角审查,发现盲点。大的改动可追加 `/codex:adversarial-review` 挑战设计假设。 -- 审查必须覆盖本文件中的所有代码规范(缩进层数、文件行数、try/except、复用等),不能只看功能正确性。 - -### 架构原则 - -- 对象优先:所有功能从对象建模出发——先识别实体与职责边界,再设计对象间的协作关系。 -- 物理文件组织必须直接反映逻辑架构。目录名、文件名、包结构要让人一眼看出模块职责和层级关系。如果架构调整了,文件结构必须同步调整。 - -### 代码规范 - -- 框架代码放 `roboclaw/embodied/`,用户资产放 `~/.roboclaw/workspace/embodied/`。 -- 不写向后兼容代码。不保留旧接口、不做 fallback 适配、不写 deprecated wrapper。旧的不要了就直接删掉。 -- 不用 try/except 吞错误。有报错就让它直接抛出来,不要静默捕获。只在确实需要处理特定异常时才 catch。 -- 复用优先。已有实现的功能不要重复造轮子,先找现有代码再决定是否新写。 -- 单个 .py 文件不超过 1000 行。超过时必须将独立逻辑拆分到单独的模块。 -- 嵌套不超过 3 层缩进。超过时应将内层逻辑提取为独立函数。 - - ---- diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 00000000..47dc3e3d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/README.md b/README.md index 0cdeedc3..df609fab 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ ## 📢 News +- **2026-04-11** Web dashboard for the full embodied workflow. - **2026-03-24** Conversational arm setup, calibration, teleoperation, data collection, training, and inference. - **2026-03-17** Embodied framework skeleton, domain contracts, and assembly-centered onboarding controller. - **2026-03-12** Repository created. diff --git a/docs/DOCKERINSTALLATION.md b/docs/DOCKERINSTALLATION.md index 10e1dfc8..cdf2a52a 100644 --- a/docs/DOCKERINSTALLATION.md +++ b/docs/DOCKERINSTALLATION.md @@ -9,7 +9,7 @@ If you do not want Docker, use [INSTALLATION.md](./INSTALLATION.md). Start from a clean clone: ```bash -git clone https://github.com/MINT-SJTU/RoboClaw.git +git clone --recurse-submodules https://github.com/MINT-SJTU/RoboClaw.git cd RoboClaw ``` diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index e2e4e9a2..065df9bf 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -1,42 +1,64 @@ # RoboClaw Installation Guide -This guide is the native host installation path. If you want Docker-based workflows, use: +This guide is the native host installation path. RoboClaw uses `uv` as the only supported Python environment and dependency workflow. If you want Docker-based workflows, use: - [Docker Installation](./DOCKERINSTALLATION.md) -## 1. Prerequisites +## 1. Install uv -Start from a clean clone: +Install `uv` with the official installer: ```bash -git clone https://github.com/MINT-SJTU/RoboClaw.git +curl -LsSf https://astral.sh/uv/install.sh | sh +``` + +Verify that `uv` is available: + +```bash +uv --version +``` + +## 2. Clone RoboClaw + +Start from a clean clone and fetch submodules: + +```bash +git clone --recurse-submodules https://github.com/MINT-SJTU/RoboClaw.git cd RoboClaw ``` -## 2. Install RoboClaw +The embodied engine lives in `roboclaw/embodied/engine` as a git submodule and is required during installation. -Install the package in editable mode: +If you already cloned the repository without submodules, run: ```bash -pip install -e ".[dev]" +git submodule update --init --recursive ``` -After installation, the `roboclaw` command should be available: +## 3. Sync the Project with uv + +RoboClaw pins Python with `.python-version` and uses `uv sync` to create `.venv` and install all default development dependencies: ```bash -roboclaw --help +uv sync +``` + +After sync, verify that the `roboclaw` command is available: + +```bash +uv run roboclaw --help ``` Expected result: - commands such as `onboard`, `status`, `agent`, and `provider` are listed -## 3. Initialize RoboClaw +## 4. Initialize RoboClaw Run: ```bash -roboclaw onboard +uv run roboclaw onboard ``` This should create `~/.roboclaw/config.json`, `~/.roboclaw/workspace/`, and the initial workspace scaffold. You can verify it with: @@ -57,12 +79,12 @@ You should see at least: ~/.roboclaw/workspace/memory/MEMORY.md ``` -## 4. Verify Status Output +## 5. Verify Status Output Run: ```bash -roboclaw status +uv run roboclaw status ``` Check that: @@ -72,14 +94,14 @@ Check that: - the current `Model` looks correct - provider status matches the actual state of your machine -## 5. Configure the Model Provider +## 6. Configure the Model Provider Before testing `roboclaw agent`, make sure the model provider is configured. First run: ```bash -roboclaw status +uv run roboclaw status ``` This tells you which providers are already available on the current machine. @@ -93,8 +115,8 @@ If you are using an OAuth-based provider, log in directly. The current codebase supports: ```bash -roboclaw provider login openai-codex -roboclaw provider login github-copilot +uv run roboclaw provider login openai-codex +uv run roboclaw provider login github-copilot ``` ### 5.2 API key provider @@ -127,7 +149,7 @@ Common API key providers include: Then run: ```bash -roboclaw status +uv run roboclaw status ``` Check that: @@ -135,12 +157,12 @@ Check that: - the current `Model` is correct - the provider you want to use is no longer `not set` -## 6. Verify the Basic Model Path +## 7. Verify the Basic Model Path Run one minimal message to confirm that RoboClaw can respond: ```bash -roboclaw agent -m "hello" +uv run roboclaw agent -m "hello" ``` Check that: @@ -149,18 +171,10 @@ Check that: - the agent returns a normal reply - failures point clearly to model configuration, provider setup, network, or permissions -## 7. Launch the Web Dashboard +## 8. Launch the Web Dashboard The web dashboard provides a browser-based UI for chatting with RoboClaw. -### Prerequisites - -Install the web optional dependency (if not already included in `.[dev]`): - -```bash -pip install -e ".[web]" -``` - Install the frontend dependencies: ```bash @@ -174,7 +188,7 @@ Build the frontend and start the server: ```bash cd ui && npm run build && cd .. -roboclaw web start +uv run roboclaw web start ``` Open **http://127.0.0.1:8765** in your browser. @@ -183,7 +197,7 @@ Open **http://127.0.0.1:8765** in your browser. ```bash # Terminal 1: start backend -roboclaw web start +uv run roboclaw web start # Terminal 2: start frontend dev server cd ui @@ -195,7 +209,7 @@ Open **http://localhost:5173** in your browser. The Vite dev server proxies `/ap ### Options ```bash -roboclaw web start --host 0.0.0.0 --port 9000 +uv run roboclaw web start --host 0.0.0.0 --port 9000 ``` | Flag | Default | Description | diff --git a/docs/architecture-comparison.md b/docs/architecture-comparison.md deleted file mode 100644 index 08986ca0..00000000 --- a/docs/architecture-comparison.md +++ /dev/null @@ -1,397 +0,0 @@ -# Architecture Comparison: LeRobot / dimos / RoboClaw - -> 2026-03-23 — 三方架构对比与 RoboClaw 定位分析 - ---- - -## 0. 架构总览图 - -### LeRobot 架构 - -``` - 没有 Agent / LLM 层,CLI 直连一切 - -┌─ CLI(用户入口,18 commands)─────────────────────────────────────────────────┐ -│ ┌───────┐ ┌────────┐ ┌───────────┐ ┌──────┐ ┌───────────┐ ┌────────────┐ │ -│ │ train │ │ record │ │teleoperate│ │ eval │ │ calibrate │ │ find-* │ │ -│ └───────┘ └────────┘ └───────────┘ └──────┘ └───────────┘ └────────────┘ │ -└───────┬──────────────────────────┬──────────────────────────────┬───────────┘ - │ │ │ - ▼ ▼ ▼ -┌─ Policies(策略层)──────┐ ┌─ Dataset(数据层)─────────┐ ┌─ Hardware(硬件层)──┐ -│ │ │ │ │ │ -│ ACT Diffusion │ │ LeRobotDataset │ │ Robot (ABC) │ -│ VQ-BeT Pi0 / Pi0.5 │ │ Parquet + MP4 │ │ ├─ Teleoperator │ -│ SmolVLA GR00T N1.5 │ │ ▼ │ │ ├─ Camera │ -│ HIL-SERL TDMPC │ │ HuggingFace Hub │ │ └─ MotorsBus │ -│ 14 policies │ │ push / pull / streaming │ │ ├─ Dynamixel │ -│ │ │ │ │ ├─ Feetech │ -│ ┌──────────────────┐ │ │ Stats Video Encoder │ │ └─ Damiao / ... │ -│ │Processor Pipeline│ │ │ Delta Timestamps │ │ │ -│ │norm→tok→delta→bat│ │ └────────────────────────────┘ │ 11 robots │ -│ └──────────────────┘ │ │ SO100 Koch LeKiwi │ -│ │ ┌─ Sim Envs(仿真,4 envs)─┐ │ Reachy2 Unitree G1 │ -│ ┌──────────────────┐ │ │ ALOHA LIBERO │ │ │ -│ │gRPC Async Infer. │ │ │ MetaWorld PushT │ │ 13 teleop devices │ -│ │PolicyServer↔Robot│ │ │ (全部第三方 wrapper) │ │ leader arm 手柄 │ -│ └──────────────────┘ │ └────────────────────────────┘ │ 键盘 手机 ... │ -└──────────────────────────┘ └──────────────────────┘ - -特征:数据 + 训练管线业界最强(14 算法 / Hub 生态 / 11 机器人) -缺失:没有 Agent / LLM / 自然语言 / 安全框架 / 内置仿真 / Web 可视化 -``` - ---- - -### dimos 架构 - -``` -┌─ UI(用户入口)─────────┐ ┌──────────────┐ -│ ┌─────┐ ┌────────────┐ │ 消息/回复 │ LLM │ -│ │ CLI │ │ Web UI │ │◄────────────────────────────────────│ (大模型) │ -│ └─────┘ │ FastAPI/WS │ │ │ GPT-4o │ -│ └────────────┘ │ │ Claude │ -└──────────┬──────────────┘ │ Ollama │ - │ 消息 └──────┬───────┘ - ▼ │ -┌─ Agent Layer(智能体层)─────────────────────────────────────────────┘ -│ 工具调用/回复 -│ LangGraph Agent VLM Agent MCP Server -│ @skill → StructuredTool 自动转换 -└──────────┬──────────────────────────────────────────────────────────┐ - ▼ │ -┌─ Core(模块/蓝图引擎)─────────────────────────────────────────┐ │ -│ Module (forkserver 进程隔离) │ │ -│ Blueprint (声明式组合 + autoconnect 自动连线) │ │ -│ In[T] / Out[T] 类型化流 │ │ -└────┬──────────┬──────────────┬──────────────┬──────────────────┘ │ - ▼ ▼ ▼ ▼ │ -┌─ Percep. ┐ ┌─ Navig. ──┐ ┌─ Manip. ──┐ ┌─ Control ──────────┐ │ -│ YOLO 2D/3D│ │ A* 规划 │ │ Pick&Place│ │ Tick Loop │ │ -│ Person ReID│ │ 前沿探索 │ │ GraspGen │ │ read→compute→ │ │ -│ Obj Track │ │ 视觉伺服 │ │ 运动规划 │ │ arbitrate→route→ │ │ -│ Spatial │ │ Costmap │ │ (Drake) │ │ write │ │ -└─────┬─────┘ └──────────┘ └──────────┘ └──────────┬──────────┘ │ - ▼ ▼ │ -┌─ Memory ──────┐ ┌─ Transport ──────────────────────┐ │ -│ CLIP 嵌入 │ │ LCM SHM ROS2 Bridge DDS │ │ -│ ChromaDB │ └──────────────┬───────────────────┘ │ -│ 时空 RAG │ ▼ │ -└───────────────┘ ┌─ Hardware ──────┐ ┌─ Sim ──────┐ │ - │ Go2 G1 xArm7 │ │ MuJoCo │ │ -┌─ Teleop ──────┐ │ Piper MAVLink │ │ Replay │ │ -│ 键盘 手机 │──▶│ │ └────────────┘ │ -│ Meta Quest │ └─────────────────┘ │ -└───────────────┘ │ - │ - 没有数据采集 / 训练 / 算法 / Dataset ◄────────────────────────┘ - 没有低成本臂 (SO101/Koch) - -特征:Agent + 感知 + 导航 + 空间记忆业界最强 -缺失:完全没有数据采集、训练、策略算法 — 所有行为都是手写 Skill -``` - ---- - -### RoboClaw 终极架构 - -从第一性原理出发的核心洞察: - -``` -1. RoboClaw 不是 "带 Agent 的机器人框架",而是 "会控制机器人的 Agent" - → Agent 是架构中心,不是附属模块 - -2. LeRobot 的数据+训练管线已是业界最优,重写是浪费 - → 直接作为引擎集成,RoboClaw 做驾驶舱 - -3. 安全不能靠 prompt 提醒,必须是架构级强制 - → Safety Gateway 拦截每一条到硬件的指令 - -4. Agent(慢脑,LLM)和 Control Runtime(快脑,确定性)必须分离 - → Agent 决定做什么(100ms+),Control 决定怎么做(20ms 级) -``` - -``` -┌─ Interface(接入层)─────────────────────────────────────────────────────────┐ -│ │ -│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────────────────┐ │ -│ │ CLI │ │ Web UI │ │ Channels │ │ -│ │ roboclaw │ │ 控制面板 │ │ Discord Telegram WeChat ... │ │ -│ │ agent │ │ 仿真查看器 │ │ │ │ -│ └──────┬──────┘ └──────┬───────┘ └────────────────┬────────────────┘ │ -│ └─────────────────┴────────────────────────────┘ │ -└──────────────────────────────────────┬───────────────────────────────────────┘ - │ 消息/回复 - ▼ -┌─ Agent Runtime(慢脑 · 智能体运行时)────────────────────┐ ┌──────────┐ -│ │ │ LLM │ -│ ┌──────────────────────────────────────────────────┐ │ │ (大模型) │ -│ │ Agent Loop │◀══╪══════▶│ │ -│ │ 对话理解 → 意图分析 → 工具调用 │ │ │ Claude │ -│ └──────────────────────────────────────────────────┘ │ │ GPT │ -│ │ │ Local │ -│ ┌──────────┐ ┌──────────────┐ ┌────────────────┐ │ └──────────┘ -│ │ Memory │ │ Spawn + Tool │ │ Lifecycle Mgr │ │ -│ │ 对话记忆 │ │ 子agent 派发 │ │ 生命周期管理 │ │ -│ │ 用户偏好 │ │ 工具调用 │ │ 阶段状态追踪 │ │ -│ └──────────┘ └──────┬───────┘ └────────────────┘ │ -└──────────────────────────┬───────────────────────────────┘ - │ 调用 Skill - ▼ -┌─ Skill Ecosystem(技能生态 · Skill to Any Embodiment)──────────────────────┐ -│ │ -│ ┌─ Primitive(原语)──┐ ┌─ Skill(技能)─────┐ ┌─ Policy(策略)────────┐ │ -│ │ 本体绑定 · 原子动作 │ │ 本体无关 · 可组合 │ │ 学习获得 · 可部署 │ │ -│ │ move_joint │ │ pick_and_place │ │ ACT checkpoint │ │ -│ │ open_gripper │ │ pour_water │ │ Diffusion checkpoint │ │ -│ │ set_velocity │ │ stack_blocks │ │ VLA fine-tune │ │ -│ └──────────────────────┘ └────────────────────┘ └───────────────────────┘ │ -│ │ -│ Skill Hub:社区共享 · 上传 / 下载 / 复用 · 能力匹配 · 自动适配 │ -└──────────┬──────────────────────┬───────────────────────────┬────────────────┘ - │ 派发 │ │ - │ ▲ 注册 Primitive │ ▲ 注册 Policy │ ▲ 提供感知 - ▼ │ ▼ │ ▼ │ -┌═ Embodiment Engine ════╗ ┌─ Learning Engine ─────┐ ┌─ Perception Engine ────┐ -║ (控制 + 安全) ║ │ (数据 + 训练 + 部署) │ │ (感知 + 视觉 + 记忆) │ -║ ║ │ │ │ │ -║ ┌────────────────────┐ ║ │ ┌───────────────────┐ │ │ ┌───────────────────┐ │ -║ │ Control Dispatch │ ║ │ │ Data Collector │ │ │ │ Camera Manager │ │ -║ │ 意图 → Primitive │ ║ │ │ Episode 录制 │ │ │ │ 多相机 / 流媒体 │ │ -║ │ 遥操作调度 │ ║ │ │ 采集 GUI │ │ │ └───────────────────┘ │ -║ └────────────────────┘ ║ │ └───────────────────┘ │ │ ┌───────────────────┐ │ -║ ┌────────────────────┐ ║ │ ┌───────────────────┐ │ │ │ Detection │ │ -║ │ Embodiment Reg. │ ║ │ │ Dataset Manager │ │ │ │ YOLO / DINO │ │ -║ │ Manifest / 能力 │ ║ │ │ Parquet + MP4 │ │ │ │ 分割 / 追踪 │ │ -║ │ Builtins / 用户 │ ║ │ │ Hub 推拉 │ │ │ └───────────────────┘ │ -║ └────────────────────┘ ║ │ │ 编辑 / 回放 │ │ │ ┌───────────────────┐ │ -║ ╔════════════════════╗ ║ │ └───────────────────┘ │ │ │ VLM │ │ -║ ║ Safety Gateway ║ ║ │ ┌───────────────────┐ │ │ │ 场景理解 / 问答 │ │ -║ ║ 关节限位 / 力矩 ║ ║ │ │ Policy Library │ │ │ │ 视觉反馈给 Agent │ │ -║ ║ 碰撞检测 / 急停 ║ ║ │ │ ACT Diffusion │ │ │ └───────────────────┘ │ -║ ║ 每条指令必经此处 ║ ║ │ │ Pi0 SmolVLA │ │ │ ┌───────────────────┐ │ -║ ╚════════════════════╝ ║ │ │ GR00T VQ-BeT ... │ │ │ │ Spatial Memory │ │ -║ ║ │ └───────────────────┘ │ │ │ 嵌入 + 向量库 │ │ -║ RoboClaw 自研 ║ │ ┌───────────────────┐ │ │ │ 空间 RAG │ │ -║ ║ │ │ Train + Deploy │ │ │ └───────────────────┘ │ -║ ║ │ │ 训练编排 / 调参 │ │ │ │ -║ ║ │ │ gRPC 推理服务 │ │ │ │ -║ ║ │ │ 部署监督 / 复位 │ │ │ │ -║ ║ │ └───────────────────┘ │ │ │ -║ ║ │ LeRobot 驱动 │ │ 标准 ML 库驱动 │ -╚════════════════════════╝ └───────────┬───────────┘ └───────────┬───────────┘ - │ │ │ - └────────────────────────┼─────────────────────────┘ - │ - ▼ -┌─ ROS2(统一通信层 · 三引擎共享 · 唯一传输协议)──────────────────────────────┐ -│ /joint_commands /joint_states /camera/* /gripper /episode /safety │ -└──────────────────────┬──────────────────────────────────┬────────────────────┘ - │ │ - ▼ ▼ -┌─ Real World(真机)──────────┐ ◀══ sim-to-real ══▶ ┌─ Sim World(仿真)──────────┐ -│ │ 同一 ROS2 接口 │ │ -│ ┌─────────┐ ┌────────────┐ │ 无缝切换 │ ┌──────────────────────┐ │ -│ │ Robot │ │ Sensor │ │ │ │ MuJoCo Runtime │ │ -│ └─────────┘ └────────────┘ │ │ │ + Web 3D Viewer │ │ -└──────────────┬────────────────┘ └──────────────┬───────────────┘ - ▲ ▲ - │ │ - └────────────────────────┬───────────────────────────────┘ - │ 注入新本体 -┌─ Embodiment Onboarding(任意本体接入 · 零代码范式)─────────────────────────────────┐ -│ │ -│ 对话描述硬件 → Agent 生成 manifest → 自动生成 adapter → 引导校准 → 即刻可用 │ -│ │ -│ 真机:探测串口 → 识别协议 → 生成 ROS2 adapter → 校准 ──▶ Real World │ -│ 仿真:提供 URDF/MJCF 或对话描述 → 加载/生成仿真模型 → ROS2 adapter ──▶ Sim World │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -``` - -``` -三者关系: - LeRobot → 最好的 "数据 → 训练 → 策略" 管线,但没有 Agent 入口 - dimos → 最好的 "Agent → 感知 → 控制" 架构,但没有学习能力 - RoboClaw → Agent 驾驶舱 + LeRobot 引擎 + 安全框架 + 感知层 = 完整闭环 - -两个世界的关系: - · 暴露完全相同的 ROS2 接口(topic 名 / 消息类型) - · 策略在仿真训练验证 → 零修改部署到真机 - · 没有硬件的用户从 Sim World 开始(L0),有硬件后切到 Real World(L1+) -``` - ---- - -## 1. LeRobot — "数据驱动的机器人学习工具箱" - -**仓库**: [huggingface/lerobot](https://github.com/huggingface/lerobot) | v0.5.1 | Apache-2.0 | Python >=3.12 - -### 核心优势(做得很好的) - -- **数据集格式**: Parquet + MP4,分块存储,Hub 原生推拉,delta timestamps 做时序关联。业界最好的机器人数据格式。 -- **14 个策略算法**: ACT、Diffusion Policy、VQ-BeT、TDMPC、SAC/HIL-SERL、Pi0/Pi0Fast/Pi0.5、SmolVLA、GR00T N1.5、XVLA 等。每个策略统一 `configuration + modeling + processor` 三件套。 -- **硬件抽象**: Robot / Teleoperator / Camera / MotorsBus 四层,接新机器人只需实现 ~6 个抽象方法。工厂 + 注册表模式(draccus.ChoiceRegistry)。 -- **11 种机器人**: SO100/SO101、Koch、LeKiwi、Hope JR、Reachy2、Unitree G1、EarthRover 等。 -- **13 种遥操作设备**: Leader arm、手柄、键盘、手机、Homunculus 等。 -- **训练管线**: 完整 train → eval → checkpoint,支持分布式(Accelerate),step-based 训练循环。 -- **gRPC 异步推理**: 大模型跑远程 GPU,机器人本地控制,延迟追踪。 -- **18 个 CLI 命令**: 覆盖硬件发现、校准、遥操作、录制、训练、评估全流程。 -- **Hub 生态**: 数据集和模型一键推拉 Hugging Face Hub,支持流式加载大数据集。 -- **视频编码**: libsvtav1/h264/hevc,硬件加速,流式/批量编码。 -- **在线 RL**: HIL-SERL 分布式 learner-actor 架构。 -- **处理器管线**: 可组合的 normalize → tokenize → batch → device 链。 - -### 做得不好 / 没有的 - -- **没有自然语言接口** — 全部 CLI + 配置文件驱动,用户必须理解命令行参数和 draccus 配置层级。 -- **仿真很浅** — 只有 4 个第三方 wrapper(ALOHA/PushT/LIBERO/MetaWorld),没有内置仿真器、没有 URDF/MJCF 加载、没有 Web 查看器。 -- **没有 sim-to-real 流水线** — 没有域随机化、没有迁移工具。仿真和真机是完全独立的工作流。 -- **没有自动硬件发现/配置** — 用户必须手动指定串口、电机 ID、相机索引。 -- **配置复杂** — draccus 嵌套 dataclass 层级深,错误信息不友好。 -- **没有安全框架** — 只有 `max_relative_target` 位置限制,没有碰撞检测、力矩限制、急停。 -- **没有技能组合** — 每次录制是单一任务,不能链式组合行为。 -- **没有 Web 可视化** — 用 Rerun,需要本地桌面。 -- **没有 ROS2 集成** — 机器人类型几乎全是串口总线伺服臂。 -- **没有多机器人协调**。 -- **没有部署/边缘推理流水线**(量化/ONNX/模型优化)。 -- **数据管线只支持录制** — 不能导入 ROS bag、CSV 等外部格式。 - -### 源码结构 - -``` -src/lerobot/ -├── async_inference/ # gRPC 远程策略推理 -├── cameras/ # OpenCV, RealSense, ZMQ, Reachy2 -├── configs/ # 训练/评估/管线配置 -├── data_processing/ # SARM 标注处理 -├── datasets/ # LeRobotDataset (Parquet+MP4), Hub 集成 -├── envs/ # 仿真环境 wrapper (LIBERO, MetaWorld) -├── model/ # 运动学 -├── motors/ # Dynamixel, Feetech, Damiao, Robstride -├── optim/ # 优化器/学习率调度器工厂 -├── policies/ # 14 个策略实现 -├── processor/ # 预处理/后处理管线 -├── rl/ # 在线 RL (HIL-SERL) -├── robots/ # 11 种机器人 -├── scripts/ # 18 个 CLI 入口 -├── teleoperators/ # 13 种遥操作设备 -├── templates/ # 模型卡模板 -├── transport/ # gRPC protobuf -├── utils/ # 17 个工具模块 -└── types.py # 核心类型定义 -``` - ---- - -## 2. dimos — "物理空间的 Agent 操作系统" - -**仓库**: [dimensionalOS/dimos](https://github.com/dimensionalOS/dimos) | Pre-release | Python 3.12+ - -### 核心优势(做得很好的) - -- **Module/Blueprint 架构**: 类型化流(`In[T]`/`Out[T]`)+ `autoconnect()` 自动连线,forkserver 进程隔离。Blueprint 不可变,每次修改返回新实例。 -- **LLM Agent 集成**: LangChain/LangGraph,`@skill` 装饰器自动转 `StructuredTool`,MCP Server 支持。GPT-4o/Claude/Ollama 多后端。 -- **空间记忆**: CLIP 嵌入 + ChromaDB 向量库 + 机器人位姿 = 时空语义 RAG。"厨房在哪?"这种查询能工作。 -- **感知栈全面**: YOLO 2D/3D 检测、人员 ReID、目标追踪、VLM 视觉问答、空间注册。 -- **导航**: A* 重规划、前沿探索(wavefront)、视觉伺服、ROS nav bridge。 -- **操控栈**: 抓取生成(GraspGen)、运动规划(Drake)、轨迹生成、拾放流程。 -- **控制协调器**: 单 tick 循环(read → compute → arbitrate → route → write),关节级优先级仲裁。 -- **多传输后端**: LCM、共享内存、ROS2 bridge、DDS。 -- **回放模式**: 不需要硬件/仿真器就能开发测试。 -- **硬件广度**: 四足(Go2/B1)、人形(G1)、臂(xArm7/Piper)、无人机。 - -### 做得不好 / 没有的 - -- **完全没有学习管线** — 没有 episode 录制、没有数据集格式、没有 ACT/Diffusion 训练、没有 checkpoint 管理。所有行为都是手写 skill。 -- **没有低成本臂支持** — 只有 xArm7(商用价格)和 Piper,没有 SO100/SO101/Koch 等教育/爱好者平台。 -- **依赖极重** — LangChain/Ultralytics/MuJoCo/OpenAI/Whisper/ChromaDB/sentence-transformers/rerun-sdk... 版本冲突维护负担大。 -- **LangChain 强耦合** — 锁定特定版本(如 `langchain==1.2.3`),LangChain API 频繁变动带来脆弱性。 -- **Unitree 中心** — 技能、system prompt、Blueprint 主要围绕 Go2 设计。接新机器人仍需大量代码。 -- **ROS2 不是原生** — 自建 LCM 传输,ROS2 只是可选桥接。重复造了 ROS2 提供的消息类型/pub-sub/TF。 -- **传输层自己承认需重写** — 代码注释中明确说"需要重写和简化"。 -- **仿真实际只有 MuJoCo** — Genesis/Isaac 目录是占位符。没有 sim-to-real 迁移。 -- **没有多机器人协调**。 -- **没有实时安全保证** — Python 线程 + sleep 定时,安全约束只在 system prompt 层面。 -- **操控规划依赖 Drake** — 重依赖,平台兼容问题。 - -### 源码结构 - -``` -dimos/ -├── core/ # Module 基类, Blueprint 引擎, 流系统, 传输层, 守护进程 -├── agents/ # LLM Agent (LangChain/LangGraph), VLM, Ollama, MCP -├── robot/ # 硬件适配: unitree/ (Go2, G1, B1), drone/, manipulators/ (xArm, Piper) -├── control/ # ControlCoordinator — tick 循环, 任务类型 -├── perception/ # 2D/3D 检测 (YOLO), 人员追踪, ReID, 空间感知 -├── navigation/ # A* 规划, 前沿探索, 视觉伺服, ROS nav bridge -├── mapping/ # 代价图, 占据栅格, 体素, 点云, Google Maps/OSM -├── memory/ # CLIP 嵌入, ChromaDB 向量库, 时序记忆 -├── manipulation/ # 操控模块, 拾放, 抓取 (GraspGen), 运动规划 -├── simulation/ # MuJoCo 引擎, Genesis/Isaac 占位符 -├── skills/ # Skill 基类, Unitree/操控/导航/REST 技能 -├── teleop/ # 键盘, 手机, Meta Quest 遥操作 -├── stream/ # 视频 (RTSP, ROS), 音频, 帧处理器 -├── msgs/ # ROS 兼容消息类型 (无 ROS 依赖) -├── models/ # ML 模型: 嵌入, Qwen, 分割, VLM -├── web/ # FastAPI/Flask, WebSocket 可视化 -└── visualization/ # Rerun SDK, 自定义 viewer -``` - ---- - -## 3. 六版图对比矩阵 - -| 版图 | LeRobot | dimos | RoboClaw 现状 | -|------|---------|-------|--------------| -| **本体接入** | ✅ 强(11 机器人,干净抽象) | ✅ 强(四足/人形/臂/无人机) | 🟡 SO101 已通 | -| **控制操作** | 🟡 CLI 控制,无对话 | ✅ 自然语言 + @skill 系统 | 🟡 Agent + ROS2 | -| **感知视觉** | ❌ 基本没有 | ✅ 强(YOLO/ReID/VLM/空间记忆) | 🟡 基础相机 | -| **数据训练** | ✅ 业界最强(14 算法 + 完整管线) | ❌ 完全没有 | 🟡 ACT 骨架 | -| **部署监督** | 🟡 gRPC 推理 | 🟡 MCP,无监督 | ❌ 未开始 | -| **生态扩展** | ✅ Hub 生态 | 🟡 Blueprint 可组合 | 🟡 Onboarding | - ---- - -## 4. RoboClaw 定位策略 - -### 核心思路 - -**不重新造轮子,站在巨人肩上做集成层 + 自然语言胶水层。** - -LeRobot 和 dimos 各做了一半:LeRobot 有最好的数据+训练管线但没有自然语言入口,dimos 有最好的 Agent+感知架构但没有学习能力。RoboClaw 要做的是**把两者最好的部分通过自然语言统一起来**。 - -### 按版图借力 - -| 版图 | 借谁的 | RoboClaw 自己做什么 | -|------|--------|-------------------| -| **本体接入** | LeRobot 的硬件抽象(Motor/Camera/Robot) | 自然语言引导接入 + 自动发现(Onboarding 已有) | -| **控制操作** | dimos 的 Skill → Tool 模式(参考设计) | Agent 调度 + 框架级安全约束(已有 Agent) | -| **感知视觉** | 直接用 Ultralytics/CLIP 等独立库 | 统一感知接口 + 与 Agent 对话结合 | -| **数据训练** | LeRobot 的数据集格式 + 策略实现 | 对话式采集/标注 + 对话选算法/调参 | -| **部署监督** | LeRobot 的 gRPC 推理架构 | 对话式部署 + 人在环监督 | -| **生态扩展** | LeRobot 的 Hub 生态 | 对话生成 adapter + ClaWHub 社区 | - -### RoboClaw 的真正差异化 - -1. **自然语言是唯一入口** — LeRobot 需要 CLI 命令,dimos 需要理解 Blueprint 配置,RoboClaw 全程对话。 -2. **零代码本体接入** — 对话描述硬件 → 自动生成 adapter(Onboarding 已有骨架)。 -3. **对话驱动的完整闭环** — 采集 → 训练 → 部署 → 监督,全部通过对话完成。 - ---- - -## 5. 架构启示 - -### 从 LeRobot 学习 - -- **数据集格式**: 采用兼容的 Parquet + MP4 格式,实现与 LeRobot Hub 生态的数据互通。 -- **策略三件套**: `configuration + modeling + processor` 模式,算法可插拔。 -- **处理器管线**: 可组合的预处理/后处理链。 -- **工厂 + 注册表**: draccus.ChoiceRegistry 模式,字符串名实例化。 - -### 从 dimos 学习 - -- **Skill → Tool 自动转换**: `@skill` 装饰器让模块方法自动暴露为 LLM 工具。 -- **空间记忆**: CLIP + 向量库 + 位姿的时空 RAG 架构。 -- **控制协调器**: 单 tick 循环 + 关节级优先级仲裁。 -- **Blueprint 组合**: 声明式模块组合 + 自动连线。 - diff --git a/docs/architecture.md b/docs/architecture.md deleted file mode 100644 index 814f0c85..00000000 --- a/docs/architecture.md +++ /dev/null @@ -1,54 +0,0 @@ -# RoboClaw Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Interface │ -│ CLI · Web UI · Discord · Telegram · WeChat │ -└──────────────────────────────┬──────────────────────────────────┘ - │ -┌──────────────────────────────▼────────────────────┐ ┌───────┐ -│ Agent Runtime │◄─►│ LLM │ -│ Agent loop · Memory · Tool · Spawn · Lifecycle │ └───────┘ -└──────────────────────────────┬────────────────────┘ - │ Invoke skill -┌──────────────────────────────▼──────────────────────────────────┐ -│ Skill Ecosystem │ -│ │ -│ ┌──────────────┐ ┌──────────────────┐ ┌────────────────┐ │ -│ │ Primitive │ │ Skill │ │ Policy │ │ -│ │ Body-bound │ │ Body-agnostic, │ │ Learned, │ │ -│ │ actions │ │ composable │ │ deployable │ │ -│ └──────────────┘ └──────────────────┘ └────────────────┘ │ -│ │ -│ Skill Hub: share · download · reuse · auto-adapt │ -└────┬─────────────────────────┬──────────────────────┬───────────┘ - │ │ │ - ▼ ▼ ▼ -┌──────────────┐ ┌────────────────────┐ ┌─────────────────┐ -│ Embodiment │ │ Learning │ │ Perception │ -│ │ │ │ │ │ -│ Control │ │ Data collector │ │ Camera + │ -│ dispatch │ │ Policy library │ │ Detection │ -│ Embodiment │ │ Train + Deploy │ │ VLM scene │ -│ registry │ │ │ │ understanding │ -│ Safety │ │ │ │ Spatial memory │ -│ gateway │ │ │ │ │ -└──────┬───────┘ └─────────┬──────────┘ └────────┬────────┘ - │ │ │ -┌──────▼─────────────────────▼───────────────────────▼────────┐ -│ Transport │ -└─────────────┬───────────────────────────────────────────────┘ - │ - ┌──────▼──────┐ ┌──────────────┐ - │ Real World │◄──────────►│ Simulation │ - │ │ sim-to- │ │ - │ Robot + │ real │ │ - │ Sensors │ │ │ - └──────┬──────┘ └──────────────┘ - │ -┌─────────────▼───────────────────────────────────────────────┐ -│ Embodiment Onboarding │ -│ Zero-code: describe hardware via dialog │ -└─────────────────────────────────────────────────────────────┘ -``` - diff --git a/docs/development.md b/docs/development.md deleted file mode 100644 index 3d331645..00000000 --- a/docs/development.md +++ /dev/null @@ -1,126 +0,0 @@ -# Development Guide - -## Prerequisites - -- Python 3.11+ -- Git - -## Local Setup - -```bash -# Clone & install in editable mode with dev extras -git clone https://github.com/MINT-SJTU/RoboClaw.git -cd RoboClaw -pip install -e ".[dev]" - -# First-time setup (creates ~/.roboclaw/config.json & workspace) -roboclaw onboard -``` - -## Running Tests - -```bash -# Unit tests (no hardware required) -python -m pytest tests/ -x -q - -# Skip PTY integration tests (useful in minimal CI environments) -python -m pytest tests/ -x -q -m "not pty" - -# Run only PTY integration tests -python -m pytest tests/integration/ -x -q -m pty -``` - -## Stub Mode - -Set `ROBOCLAW_STUB=1` to replace real hardware calls with deterministic -stubs. This allows the full embodied pipeline (scan, identify, calibrate, -teleoperate, record) to run on a laptop without any robot arms or cameras. - -```bash -# Run the agent in stub mode -ROBOCLAW_STUB=1 roboclaw agent - -# PTY integration tests use stub mode automatically -python -m pytest tests/integration/ -x -q -m pty -``` - -What gets stubbed: - -| Component | Real behaviour | Stub behaviour | -|---|---|---| -| `scan_serial_ports()` | reads `/dev/serial/by-*` | returns 2 fake ports | -| `scan_cameras()` | probes `/dev/video*` via OpenCV | returns 1 fake camera | -| `probe_port()` | reads Feetech motor positions | returns motor IDs [1..6] | -| `read_positions()` | reads motor positions via SCS | returns all zeros | -| `run_interactive()` | spawns a subprocess | returns exit-code 0 immediately | -| `_find_moved_port()` | reads motor positions | picks scripted port | - -All stub defaults are overridable via env vars for per-test flexibility: - -| Variable | Default | -|---|---| -| `ROBOCLAW_STUB_PORTS` | 2 fake serial ports (JSON list) | -| `ROBOCLAW_STUB_CAMERAS` | 1 fake camera (JSON list) | -| `ROBOCLAW_STUB_MOTORS` | 6 motors per port (JSON object) | -| `ROBOCLAW_STUB_MOVED_PORT` | first port's by_id | - -All stub logic lives in `roboclaw/embodied/stub.py`. - -## Workspace Reset - -During development you may want to return to a clean state: - -```bash -# Interactive (asks for confirmation) -roboclaw dev reset - -# Non-interactive -roboclaw dev reset --yes - -# Reset and configure a specific model -roboclaw dev reset --yes --model openai/gpt-4o --api-key sk-... -``` - -This deletes `~/.roboclaw/workspace` and `~/.roboclaw/config.json`, then -re-runs `roboclaw onboard` non-interactively. - -## Environment Variables - -| Variable | Purpose | -|---|---| -| `ROBOCLAW_HOME` | Override the base directory (default `~/.roboclaw`). Useful for tests and parallel instances. | -| `ROBOCLAW_STUB` | Set to `1` to activate stub mode (fake hardware). | -| `ROBOCLAW_STUB_PORTS` | JSON list of fake serial ports (override defaults). | -| `ROBOCLAW_STUB_CAMERAS` | JSON list of fake cameras (override defaults). | -| `ROBOCLAW_STUB_MOTORS` | JSON object mapping port by_id → motor ids. | -| `ROBOCLAW_STUB_MOVED_PORT` | by_id of port that identify detects as moved. | - -## Troubleshooting - -### `ModuleNotFoundError: No module named 'lerobot'` - -LeRobot is an optional dependency under the `research` extra: - -```bash -pip install -e ".[research]" -``` - -### PTY tests fail with `ModuleNotFoundError: No module named 'pexpect'` - -Install the dev extra: - -```bash -pip install -e ".[dev]" -``` - -### Terminal messed up after Ctrl-C - -Run `reset` in your shell to restore terminal settings. - -### Tests fail with `roboclaw.config` import errors - -Make sure you installed in editable mode: - -```bash -pip install -e ".[dev]" -``` diff --git a/docs/product-vision.md b/docs/product-vision.md deleted file mode 100644 index 9b10fb2d..00000000 --- a/docs/product-vision.md +++ /dev/null @@ -1,20 +0,0 @@ -# RoboClaw 产品愿景 - -## 为什么做 - -RoboClaw 是一个 AI 原生的具身智能助手。用户说话,机器人执行。 - -- **零门槛** — 从拆箱到控制,全程对话完成。 -- **全生命周期** — 接入 → 校准 → 采集 → 训练 → 部署 → 评估,一个产品走完闭环。 -- **本体无关** — 描述你的硬件,它就能用。 - -## 做什么 - -| 领域 | 目标 | -|------|------| -| 接入 | 任何机器人通过对话从插上线到可使用 | -| 数据与训练 | 遥操作采集、内置训练算法、对话调参(auto-research) | -| 部署与评估 | 一键部署 policy、推理循环、成功率指标、仿真到真机迁移 | -| 控制 | 自然语言 primitive、技能组合、遥操作、安全约束 | -| 感知 | 多相机、VLM 场景理解、空间记忆 | -| 生态 | 本体适配器、算法插件、技能/策略共享 | diff --git a/docs/web-dashboard-debug-log.md b/docs/web-dashboard-debug-log.md deleted file mode 100644 index 36600411..00000000 --- a/docs/web-dashboard-debug-log.md +++ /dev/null @@ -1,103 +0,0 @@ -# Web Dashboard 遥操作/录制 Debug 日志 - -> 2026-04-01 深夜调试记录 - -## 最终状态 - -遥操作和录制均已跑通。核心架构:`session.py` 通过 `SO101Controller` 构建 LeRobot CLI 命令,`subprocess.Popen` 启动子进程执行。 - -## 遇到的 Bug 及根因 - -### 1. LeRobot import 路径错误 - -**现象**: 点击 Connect → `ModuleNotFoundError: No module named 'lerobot.robots.so101_follower'` - -**根因**: rdlwicked 的 `session.py` 直接 import LeRobot 内部 config classes(`SO101FollowerConfig`),但 LeRobot 0.5.0 的模块路径是 `so_follower` 而不是 `so101_follower`。 - -**修复**: 重写 `session.py`,不再直接 import LeRobot 内部类,改为复用 `SO101Controller` 构建 CLI 命令 + subprocess 执行。 - -### 2. 只支持单臂遥操作 - -**现象**: 4 臂配置(2 follower + 2 leader)只走单臂路径。 - -**根因**: `_build_teleop_argv` 只处理了 `len(followers) == 1` 的情况。 - -**修复**: 加 bimanual 分支,使用 `SO101Controller.teleoperate_bimanual()`。 - -### 3. bimanual 校准提示导致 EOFError - -**现象**: `EOFError: EOF when reading a line` — leader 连接时 LeRobot 调 `input("Press ENTER...")` 但子进程没有 stdin。 - -**根因**: `subprocess.Popen` 默认 stdin=None,LeRobot 的 `so_leader.calibrate()` 内部有交互式 `input()` 提示。 - -**修复**: 通过 `stdin=subprocess.PIPE` 创建子进程,写入 `\n\n\n\n` 自动确认校准。 - -### 4. bimanual 临时校准目录提前删除 - -**现象**: 子进程启动后找不到校准文件。 - -**根因**: 使用了 `_bimanual_cal_dirs` context manager,`with` 块结束后 temp dir 被删,但子进程还需要读取。 - -**修复**: 手动创建 temp dirs,存储在 `self._temp_dirs`,在 `stop/disconnect` 时才清理。 - -### 5. headless_patch 在无 TTY 环境 crash - -**现象**: `termios.error: (25, 'Inappropriate ioctl for device')` - -**根因**: `lerobot_wrapper.py` 调 `apply_headless_patch()`,其中 `TTYKeyboardListener.start()` 尝试 `termios.tcgetattr(stdin.fileno())`,但 web 子进程没有 TTY。 - -**修复**: 在 `start()` 开头加 `if not os.isatty(self._fd): return`。 - -### 6. Camera preview 占用摄像头设备(最顽固的问题) - -**现象**: LeRobot 子进程 `TimeoutError: Timed out waiting for frame from camera` - -**根因**: Dashboard 的 `/api/dashboard/camera-preview/{alias}` 端点每次请求都 `cv2.VideoCapture(port)` 打开摄像头拍一帧再 `cap.release()`。但: -- 前端每 1.5 秒轮询 3 个摄像头 = 频繁 open/close -- Linux V4L2 设备释放有延迟,`release()` 不保证立即释放 fd -- 浏览器旧标签页的 JS 代码继续 polling(前端 state 改了但旧代码还在跑) -- OpenCV VideoCapture 对象被 Python GC 延迟回收 - -**修复(多层防御)**: -- 前端:camera preview 默认关闭(`useState(false)`) -- 前端:teleop/record loading 时自动 `setCamerasEnabled(false)` -- 后端:`camera-preview` 端点检查 `session.cameras_locked`,在 preparing/teleoperating/recording 状态返回 503 - -### 7. Servo positions 轮询占用串口 - -**现象**: `ConnectionError: Failed to write 'Lock' on id_=N` — follower 电机通信失败 - -**根因**: `/api/embodied/servo-positions` 每 500ms 打开串口读所有 follower 电机位置。和 LeRobot 子进程争抢同一个串口设备。虽然加了 state 检查,但 `_read_servo_positions` 在线程中运行,和 `start_recording/start_teleop` 之间有竞态。 - -**修复**: -- servo-positions 获取 `session._lock` 后才读串口,和 start_teleop/start_recording 互斥 -- 引入 `preparing` 状态:先释放 lock → 等 5 秒让 in-flight 读取完成 → 再 lock 启动子进程 - -### 8. dataset_root 路径错误 - -**现象**: `FileExistsError: [Errno 17] File exists: '/home/zhaobo/.roboclaw/workspace/embodied/datasets/local'` - -**根因**: `_dataset_path()` 返回完整路径 `datasets/local/name`,但代码错误地用了 `.parent` 导致 `dataset_root` 指向 `datasets/local`。 - -**修复**: 去掉 `.parent`,直接传完整路径。 - -### 9. repo_id 格式错误 - -**现象**: `ValueError: not enough values to unpack (expected 2, got 1)` - -**根因**: LeRobot 要求 `repo_id` 格式为 `owner/name`(如 `local/dataset`),但传的只有 `dataset`。 - -**修复**: 加 `local/` 前缀。 - -### 10. 重复 dataset 名称冲突 - -**现象**: 第二次录制同名 dataset → `FileExistsError` - -**修复**: dataset 名自动追加时间戳 `_{YYYYMMDD_HHMMSS}`。 - -## 潜在风险 - -1. **设备释放延迟**: Linux V4L2/ttyUSB 释放不是原子操作。`preparing` 状态的 5 秒等待是经验值,极端情况可能不够。 -2. **子进程 crash 后 state 不回退**: 如果 LeRobot 子进程 crash,session state 停留在 `teleoperating`/`recording`,需要用户手动点 Stop 才能恢复。 -3. **camera preview 的 OpenCV 资源泄漏**: `_capture_preview_bytes` 每次 open/close 不够可靠。长时间运行后可能累积未释放的 fd。 -4. **单进程架构限制**: 所有硬件访问(preview/servo/teleop/record)在同一个 Python 进程中通过 threading 和 subprocess 协调,竞态风险高。理想方案是独立的 hardware server 进程。 diff --git a/pyproject.toml b/pyproject.toml index a44cbaa9..edd8851c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,9 @@ dependencies = [ "chardet>=3.0.2,<6.0.0", "openai>=2.8.0", "tiktoken>=0.12.0,<1.0.0", - "lerobot[feetech,dynamixel] @ file:roboclaw/embodied/engine", + "fastapi>=0.115.0,<1.0.0", + "uvicorn[standard]>=0.34.0,<1.0.0", + "lerobot[feetech,dynamixel,pi]", "pyserial>=3.5,<4.0", ] @@ -65,10 +67,8 @@ brainco = [ langsmith = [ "langsmith>=0.1.0", ] -web = [ - "fastapi>=0.115.0,<1.0.0", - "uvicorn[standard]>=0.34.0,<1.0.0", -] + +[dependency-groups] dev = [ "pytest>=9.0.0,<10.0.0", "pytest-asyncio>=1.3.0,<2.0.0", @@ -83,8 +83,11 @@ roboclaw = "roboclaw.cli.commands:app" requires = ["hatchling"] build-backend = "hatchling.build" -[tool.hatch.metadata] -allow-direct-references = true +[tool.uv] +default-groups = ["dev"] + +[tool.uv.sources] +lerobot = { path = "roboclaw/embodied/engine", editable = true } [tool.hatch.build] include = [ @@ -113,7 +116,7 @@ include = [ [tool.ruff] line-length = 100 -target-version = "py311" +target-version = "py312" [tool.ruff.lint] select = ["E", "F", "I", "N", "W"] diff --git a/roboclaw/agent/context_nav.py b/roboclaw/agent/context_nav.py new file mode 100644 index 00000000..76c6644f --- /dev/null +++ b/roboclaw/agent/context_nav.py @@ -0,0 +1,24 @@ +"""Demo-only context builder for simulation navigation.""" + +from __future__ import annotations + +from pathlib import Path + +from roboclaw.agent.context import ContextBuilder +from roboclaw.agent.demo_navigation_prompt import DEMO_NAVIGATION_PROMPT + + +class NavigationDemoContextBuilder(ContextBuilder): + """Context builder that appends demo navigation guidance to the system prompt.""" + + def __init__(self, workspace: Path, *, extra_system_prompt: str | None = None) -> None: + super().__init__(workspace) + self._extra_system_prompt = extra_system_prompt or DEMO_NAVIGATION_PROMPT + + def build_system_prompt(self, skill_names: list[str] | None = None) -> str: + base_prompt = super().build_system_prompt(skill_names) + if not self._extra_system_prompt: + return base_prompt + return "\n\n---\n\n".join( + [base_prompt, f"# Extra System Guidance\n\n{self._extra_system_prompt}"] + ) diff --git a/roboclaw/agent/demo_navigation_prompt.py b/roboclaw/agent/demo_navigation_prompt.py new file mode 100644 index 00000000..516d7336 --- /dev/null +++ b/roboclaw/agent/demo_navigation_prompt.py @@ -0,0 +1,23 @@ +"""Demo-only system guidance for simulation-first navigation.""" + +DEMO_NAVIGATION_PROMPT = """# Demo Navigation Guidance + +You are an ROS2 Expert and you are operating in the simulation navigation demo mode. + +Before start everything, let us use ROS_DOMAIN_ID=2. + +Follow this workflow unless the user explicitly redirects you: + +1. Start with `embodied_simulation(action="doctor")` to inspect the current runtime. +2. If the environment is not ready, explain the currently available method and ask the user for confirmation before starting modules. +3. When the user agrees, use `embodied_simulation(action="bringup")` to start the simulation stack. +4. For semantic navigation, house navigation, room-to-room requests, or place names such as "kitchen", bring up navigation with `embodied_simulation(action="bringup", map_id="house")` unless the user explicitly requests another map. This selects both the house map (`map_house.yaml`) and the house Gazebo world (`turtlebot3_house.launch.py`). +5. After bringup, tell the user to initialize localization in RViz with `2D Pose Estimate` before attempting navigation. +6. Use `embodied_navigation(action="nav_status")` or `embodied_navigation(action="smoke_test")` before executing a real navigation task when readiness is uncertain. +7. For Demo 2 place names such as "bedroom" or "kitchen", first call `embodied_navigation(action="resolve_place", place="