Refine robot milestones and make GPU setup reproducible

This commit is contained in:
ylhan
2026-09-08 15:03:32 +08:00
parent 0e1b7eaf4d
commit d71fcc7650
9 changed files with 406 additions and 537 deletions
+4 -1
View File
@@ -2,7 +2,10 @@
* text=auto * text=auto
*.sh text eol=lf *.sh text eol=lf
*.py text eol=lf *.py text eol=lf
*.md text *.md text eol=lf
*.in text eol=lf
*.lock text eol=lf
*.sha256 text eol=lf
*.toml text *.toml text
*.yaml text *.yaml text
*.yml text *.yml text
+85 -179
View File
@@ -1,222 +1,128 @@
# 方案:LeRobot 双臂移动 VLA 机器人(可自行训练) # LeRobot 双臂移动操作项目方案
> 本文件是项目的「单一事实来源」(single source of truth)。所有决策、预算、阶段、命令、待办都以此为准,随进展更新。 > 决策与阶段验收以本文件为准。更新:2026-09-08,设计评审修订。
> 最后更新:_P0 定稿(双 GPU 机版:3080 主家 + 3090 训练)_ > 当前 P0:已有规划与环境脚本,尚无 GPU 环境、训练效果或真机验收结果。
--- ## 1. 目标与边界
## 0. 目标(一句话) 基于 LeRobot,完成“人工遥操示范 → 数据采集 → 策略训练 → 真机执行”的闭环,逐步扩展至桌面双臂与移动操作。
复刻 LeRobot 工作流,造一台**会走(LeKiwi 底盘)+ 双手协作(2×SO-101)+ 语言/视觉驱动(VLA)+ 能自己采集数据并训练**的移动操作机器人。 首个交付是单臂固定场景抓放;整机首个交付是“移动到位 → 停稳 → 抓取 → 收臂 → 移动 → 放置”。边移动边双臂操作、一个 VLA 统一控制整机,列为后续探索目标。
**核心思路**:不重写 LeRobot,而是**站在 LeRobot 框架上组装这台特定机器人**;架构上采用「**瘦边 + 厚芯**」——机器人只带一块便宜的驱动板(RPi 5)做实时控制,**推理放 3080 主家(挨着机器人)、训练放 3090(24GB)**,走局域网。 “可自行训练”指使用自己的示范数据训练模型。自主探索、自动成功判定、自动恢复与持续学习尚无实现,不作为当前交付承诺。
**协作模型**(详见 [env/machines.md](env/machines.md)): ## 2. 技术决策
- **3080 机(10GB · 本地 Ubuntu · 机器人旁)= 主家**:开发 + 臂(USB) + 遥操/采数 + **推理部署** + P4 policy server。
- **3090 机(24GB · 远程 SSH · 同局域网)= 训练专用**:只跑训练;数据集/模型经 HF Hub(或 rsync)流转。
- **本 Windows 机 = 写字台**:我(agent)写代码/配置/文档 → **你 push 到 git 库** → 两台 GPU 机 clone/pull。
- 我无外网 → **我产出,你在两台机器上跑并粘回输出,我迭代**。
--- | 项目 | 决策 | 约束 |
## 1. 决策总表(已拍板)
| 项 | 决策 | 备注 |
|---|---|---| |---|---|---|
| 框架 | **LeRobot**(HF 官方,Py3.12, Transformers v5;最新 0.6.0) | 官方旗舰生态;装时取最新 stable | | 框架 | LeRobot **0.6.1 / Python 3.12** | 锁定依赖,不自动跟随 main;升级必须复验 |
| 机械臂 | **4× SO-101**(2 leader + 2 follower) | 双臂遥操 = 2 主 + 2 从;6DOF + 夹爪;自印有 3D 打印机 | | 单臂基线 | ACT | 模仿学习策略,不作为语言理解证明 |
| 底盘 | **LeKiwi**(三轮全向,Feetech STS3215,Seeed 12V 版) | SO-101 专用移动底盘,LeRobot 原生 `.[lekiwi]` | | VLA | SmolVLA 450M 预训练基座微调 | 记录冻结模块;默认微调不等于全参数解冻 |
| 上机驱动板 | **RPi 5 (8GB)** + 有源 USB Hub | 只管实时控制/采图/执行/fail-safe,不做 ML | | 大模型 | π0-FAST 等仅作后续候选 | LoRA、量化支持、显存及任务收益均需实测 |
| 主家(开发+推理) | **3080 机(本地 Ubuntu · 10GB · 机器人旁)** | 臂 USB 直插;遥操/采数/推理部署;P4 policy server 在它上面 | | 机械臂 | P1:1 leader + 1 follower;P2 再加各 1 条 | SO-101 为 5 个臂关节 + 夹爪,共 6 个电机 |
| 训练专用 | **3090 机(远程 SSH · 24GB)** | 只跑 lerobot-train;与 3080 同局域网(rsync 直传 / π0 代推) | | 底盘 | LeKiwi | 双臂安装、重心、供电与桌面可达性先验证 |
| 富余算力 | **AWU408 双 DRIVE Orin**(空闲,非关键路径) | 3090 忙训练时可顶推理 / 或做固定台 | | 采集/推理 | 3080 10GB,机器人旁 Ubuntu 主机 | P1/P2 USB 直连;测实际显存和延迟 |
| 相机 | **3× USB 相机**(1 前置全局 + 2 腕部) | USB 最通用,适配 RPi5/3080 | | 训练 | 3090 24GB,同局域网 Ubuntu 主机 | 小 batch 起步,按峰值显存调参 |
| VLA 主力 | **SmolVLA (4.5亿)** | 单卡可全量训、10GB 卡可推理、异步分块天生适合分布式 | | 上机计算 | RPi 5,P3 前采购 | 采图、驱动、执行和超时处理;不宣称硬实时 |
| VLA 验证/起步 | **ACT**(小、快) | P1 先证明"能学会" | | 调度与导航 | 先状态机;有定位/建图/避障需求再考虑 ROS 2/Nav2 | 导航与学习策略分层验收 |
| VLA 上限 | **π0-FAST**(自回归,~3B,LoRA 微调) | 算力宽裕后的 SOTA | | 网络推理 | 优先官方 PolicyServer/RobotClient | 验证锁定版本支持范围,仅补组合适配与故障处理 |
| 架构演进 | P1/P2 **单机**(3080 直连臂) → P4 **拆分**(RPi5↔局域网↔3080) | 先最快出结果,再长成分布式 | | 数据流 | 同局域网优先 rsync,HF Hub 可选 | 数据、模型、处理器、配置与校准成套留存 |
| 预算 | **~¥6500-8000**(自印可更低) | 落在 ¥5000–10000 内(详见 [hw/bom.md](hw/bom.md)) | | Orin | 不在关键路径 | 另行验证系统和运行时兼容性 |
--- v0.6.1 已有 `BiSOFollower`,P2 优先复用;双臂加底盘的组合 robot、遥操与动作定义仍需适配。LeKiwi 已有远程链路,不从零实现整个网络层。Async 与 RTC 是不同机制,先跑同步基线,再分别评估。
## 2. 硬件 BOM(采购清单) ## 3. 架构与接口
> 完整链接/店铺/状态见 **[hw/bom.md](hw/bom.md)**。这里给概览。 P1/P2:leader/follower/相机 → USB → 3080(采集与执行);数据经 rsync 到 3090 训练,checkpoint 与处理器回传 3080。
| # | 部件 | 数量 | 参考价 (¥) | 小计 | 说明 | P3/P4:RPi 负责本机硬件,3080 负责操作策略;状态机负责移动、到位确认、操作与失败退出。优先复用 LeKiwi 与官方异步接口,避免叠加不必要的图像转发链路。`server/`、`client/` 目前仅是占位目录。
|---|---|---|---|---|---|
| 1 | SO-ARM101(含 3D 打印件+舵机+驱动板+电源) | 4 | ~879 | **~3500** | 2L+2F;淘宝现货树脂版最省;自印可降 |
| 2 | LeKiwi 底盘(12V,Seeed 含打印件+电池) | 1 | ~1800 | **~1800** | 或 base-only 12V ~¥1501 自印结构件 |
| 3 | RPi 5 (8GB) + 27W 电源 + 有源 USB Hub + 存储 | 1 套 | ~800 | **~800** | 上机驱动板 |
| 4 | USB 相机(1 前置 + 2 腕部) | 3 | ~130 | **~400** | 1080P 免驱;或 ¥138 双相机套件 |
| 5 | 线束/夹具/耗材/电源/网线 等杂项 | — | — | **~600** | |
| | **合计** | | | **~¥7100-8000** | P1 起步(2臂)~¥3300 |
**已拥有(0 成本)**:3080 机(10GB·主家)、3090 机(24GB·训练)、AWU408 双 Orin、3D 打印机、本 Windows 开发机。 实施前固定以下契约并写入版本化配置:
**关键提醒**: - 状态/动作字段顺序、左右臂前缀、关节单位、夹爪范围、底盘坐标系与速度单位;训练与执行使用同一归一化及处理器。
- SO-101 **打印件**:官方 STL 可 FDM(PLA) 或光固化;Leader 臂用**轻负载齿轮**才捏得动;**电机 ID 按顺序烧录**。 - 相机名、序列号/稳定设备路径、分辨率、帧率、曝光与安装位置;相机变化视为数据分布变化。
- 4 条臂 = **2 leader(遥操主手)+ 2 follower(执行从手)**。P1 先买/用 2 条(1L+1F),P2 再补 2 条。 - 图像和本体状态时间、观测编号、动作对应观测编号、动作序号与有效期;跨主机时钟对齐方式及误差。
- LeKiwi 顶板 **M3 螺孔**直接固定 SO-101 底座;12V 底盘自带 12V→5V 降压给 5V 臂。 - 关节限位、每步最大变化量、底盘限速、队列长度、过期丢弃、队列耗尽和重连规则。
--- 网络预算:三路 640×480 RGB 10fps 原始图像约 221Mbps;三路 1080p 同配置约 1.49Gbps(不含协议开销)。明确压缩格式,测编码、传输、解码、推理与执行延迟,记录 P50/P95/P99、丢帧与队列耗尽次数。10Hz 观测、20–30Hz 执行、200–500ms 分块仅为候选参数,不是已满足指标。
## 3. 系统架构 ### 故障处理
### 3.1 目标态(P4 整机自主)——瘦边 + 厚芯 本机执行约束不能依赖模型服务在线。网络超时/动作过期时底盘停止,旧队列失效;手臂根据姿态与负载采用经验证的保持/受控停止,不默认回中位或直接失去支撑。重连需显式重新使能,不继续播放旧动作。
``` P1 起验证停止手段、限位、限速与人工接管。P3 前定义最大允许停车时间和距离。P4 注入断网、推理进程退出、相机卡死、乱序/过期动作和队列耗尽;记录触发到停止的时间及位移。Python watchdog 不等于完整硬件安全保证。
算力层(拆两台,同一局域网)
┌─────────────────────────────────────────────┐
│ 3080(10GB)=推理芯 · 挨着机器人: │
│ · 遥操(P1/P2:接 leader 臂)/ 采数 │
│ · policy server(obs→action chunk) │
│ · 数据集管理 / HF Hub 上传下载 │
│ 3090(24GB)=训练芯: │
│ · SmolVLA 全量 / π0-FAST LoRA │
│ (数据集·模型经 HF Hub / rsync 两机流转) │
└────────────────────────┬────────────────────┘
│ 局域网 (1Gbps 有线最稳)
上行: 3相机 + 本体状态(低频~10Hz)
下行: 动作chunk(每 200~500ms 一批 K 步)
│
┌────────────────────────┴────────────────────┐
│ 移动机器人 = LeKiwi 底盘 + 2×SO-101(follower) │
│ RPi 5 驱动板: │
│ · USB: 左/右臂舵机 + 3 底盘轮 (实时 20~30Hz) │
│ · USB: 3 相机 (采集 → 推给算力层) │
│ · 执行: 收 chunk → 实时插值下发 │
│ · 安全: 断链 watchdog → 底盘停 / 臂缓回中位 │
└─────────────────────────────────────────────┘
```
**为什么这样**:VLA 每 200~500ms 只算"一小批"未来动作(异步分块),网络只传"几张图 + 一小批动作",带宽占用极小;实时伺服与安全 100% 留在机器人本地(RPi 5),断网即停。训练/推理拆两台:训练吃显存只有 3090 干得动,推理不吃显存 3080 足够,还挨着机器人。 ## 4. 阶段与验收
### 3.2 起步态(P1/P2)——单机,最快闭环 时间按实际进度滚动估计。每阶段达标后再扩大任务,P3/P4 先做试验再估工时。
P1/P2 底盘还没上、臂在固定夹/桌上时,**3080 主家直接用 USB 接臂**(1L+1F / 4 条),单机跑 遥操→采集→推理;**训练丢给同局域网的 3090**(数据集经 HF Hub / rsync 过去,模型拉回来),最快打通闭环。等 P3/P4 上 LeKiwi 移动,才切到 3.1 的分布式。 ### P0:环境与采购确认
--- - [ ] 两台补齐 OS、驱动、GPU、Python、uv 信息([机器记录](env/machines.md))。
- [ ] 3080 用 `env/setup_lerobot.sh --resolve` 生成依赖锁并通过软件冒烟检查,保留报告。
- [ ] 将锁文件和输入指纹同步到 3090,以默认模式安装,核对两台锁的 SHA256。
- [ ] 完成短视频编码/解码、小样本训练和模型加载;解决 CUDA/FFmpeg/TorchCodec 兼容性后再认可该锁。
- [ ] 验证过的锁、指纹与精简环境记录入 git,不提交凭据或原始日志。
- [ ] 确认实际套件的 leader/follower 电机、供电规格,先买一对臂、相机和夹具。
## 4. VLA 模型路线(训练:3090 24GB · 推理:3080 10GB) 验收:两台同锁、CUDA 运算与 CLI 加载通过,小样本管线可运行。脚本通过不等于真机验收通过。
| 阶段 | 模型 | 训练(3090 · 24GB) | 推理显存(3080 · 10GB) | 作用 | ### P1:单臂抓放闭环
|---|---|---|---|---|
| P1 起步 | **ACT** | 全量,几分钟~数十分钟 | **<1GB ✅** | 最快证明"采集→训练→会动"闭环 |
| P1→P4 主力 | **SmolVLA** | 全量微调(24GB 舒适) | **fp16 ~2GB ✅** | 语言+视觉驱动,异步推理,部署主力 |
| 上限/进阶 | **π0-FAST** | LoRA 微调(24GB 为此而生) | **~7GB ⚠️ 紧张** | SOTA 泛化,算力富余后上 |
- 数据统一走 **HF Hub**(`lerobot-record` 直接 push);两台 GPU 机同局域网,大数据集/模型也可 rsync 直传。 - [ ] 完成电机 ID/波特率设置、组装、校准、稳定设备路径和停止手段验证。
- SmolVLA 的 **Real-Time Chunking / 异步推理** 正是为"算力层算、机器人执行"这种拆分设计的,天然契合 3.1。 - [ ] 相机覆盖全过程,遥操无异常;备份校准与安装照片。
- π0-FAST 推理在 10GB 上紧张的 3 条后路:**4-bit 量化** / batch=1+bf16 硬试 / **3090 同局域网代推**。 - [ ] 首轮约 50 条一致示范,例如 5 个位置各 10 条;逐条检查画面、动作和时间对齐。
- [ ] ACT 建立基线,记录数据版本、步数、batch、随机种子、显存、耗时与 checkpoint。
- [ ] 按 [评测协议](docs/evaluation.md) 独立测试 20 次,成功至少 16 次、碰撞为 0;干预计失败并完整记录。
- [ ] 同数据和测试协议比较 SmolVLA,不用训练 loss 代替真机成功率。
--- 验收:上述指标达标,能补采示范并复现实验。调参试验与最终验收分开。
## 5. 分阶段实施计划 ### P2:桌面双臂
> 假设业余时间(每周若干小时)。**采购前置**:3D 打印件/套件到货周期可能 1~6 周,P0 期间就下单。 - [ ] 新增 **1 leader + 1 follower**,总数 2L+2F;按遮挡需求扩展至前置+两腕相机。
> 每阶段有明确「验收标准」,达到再进下一阶段。 - [ ] 复用官方双臂驱动,验证校准、镜像方向、动作顺序与碰撞区域。
- [ ] 选择需要两手协作的短任务,先验证遥操和数据质量,再训练。
- [ ] 固定初始条件范围,独立测试 20 次,至少成功 16 次、无碰撞。
### P0 · 环境 & 工具链(~1~2 周,含下单等货) 验收:一个桌面协作任务可复现;不默认单臂 checkpoint 能直接用于双臂。
**目标**:软件环境全通 + git 库建好 + 硬件下单。
- [x] **建 git 库** ✅ `git.hyonglin.top/ylhan/lerobot_learn`(已 init+commit 待 push;匿名可读=GPU 机 clone 免密)
- [ ] **两台 GPU 机装环境**(同一脚本 [env/setup_lerobot.sh](env/setup_lerobot.sh):自动探测→国内镜像自适应→Py3.12 venv→clone LeRobot→装 `feetech,lekiwi,dataset,smolvla,pi0`→验证 GPU/CLI):**先 3080 主家**(P1 在它上面跑),**再 3090**(训练用);各把 [1]~[7] 输出粘回
- [ ] **HF 登录**:两台机器都 `huggingface-cli login`(HF_ENDPOINT=hf-mirror)
- [ ] **固定官方 CLI 命令**(find-port / find-cameras / calibrate / teleoperate / record / train / eval|rollout 的确切 flag,以装好后的 `--help` 实测为准)
- [ ] **下单硬件**([hw/bom.md](hw/bom.md),**先 2 条 SO-ARM101 起步**)
- [ ] (可选)验证 AWU408 能否跑 Ubuntu+CUDA+PyTorch(只影响"富余算力",不阻塞主线)
**验收**:两台 GPU 机 `torch.cuda.is_available()==True`;LeRobot CLI 全 OK;git 库建好且两机已 clone;硬件已下单。
### P1 · 单臂 SO-101 闭环(~2~4 周)⭐核心 ### P3:底盘、机械与网络
**目标**:1 leader + 1 follower,把 **采集→训练→部署** 整条闭环跑通。
- [ ] 组装+校准 1 follower + 1 leader(`lerobot-calibrate`),USB 直连 3080 主家
- [ ] 接 1 相机;遥操作(`lerobot-teleoperate`)验证跟手
- [ ] 采集第一个数据集(简单任务:抓方块 / 放杯子 / 按按钮),`lerobot-record` → push HF Hub
- [ ] 3090 上先训 **ACT** 快速验证能学 → 再训 **SmolVLA**
- [ ] 推理部署(3080 单机直连 follower),手臂独立完成任务
**验收**:**follower 独立完成一个抓取/放置任务**(无人工逐帧干预);能稳定记录新 episode 并增量再训。
### P2 · 双臂 BiSO-101(~2~4 周) - [ ] 采购前验证安装空间、臂展与桌高,检查伸臂负载时重心、顶板刚度和线束。
**目标**:双手协作。 - [ ] 按实际电机电压设计供电,测峰值电流、压降、发热与续航;确认 RPi/Hub 的移动供电。
- [ ] 加装 2 条 leader + 1 条 follower(凑 2L+2F),接 3 相机(1 前 + 2 腕) - [ ] 底盘独立遥操,测限速、停车距离与故障停止;仅采用 ROS 桥后才要求 `cmd_vel`/`odom`。
- [ ] 上 **bimanual 驱动**(`left_*`/`right_*` 前缀;参考 Maker-Mods / Xbotics 的 BiSO-101,移植进 LeRobot) - [ ] 固定位置测试 RPi↔3080,再有限范围有线移动;有线测试不算无线自主移动验收。
- [ ] 采集双臂数据(双手递物 / 协同开盒 / 双手抓取) - [ ] 实现“移动 → 停稳确认 → 单臂操作”,暂不要求边走边操作。
- [ ] 3090 训双臂 SmolVLA,3080 测双手协作任务
**验收**:双臂协同完成一个需要两手配合的任务。
### P3 · 底盘 LeKiwi(~2~3 周) 验收:先根据 P1 抓取容差和制动试验定义到位误差、停稳条件、停车上限,填入评测记录。重复 20 次到位测试,报告误差分布并符合阈值后再连接操作任务。
**目标**:会走 + 底盘与臂联动。
- [ ] 组装 LeKiwi + 校准(3 轮 STS3215)
- [ ] 上 **LeKiwi 底盘驱动**(LeRobot 原生 `.[lekiwi]` / 或 lerobot-ros 桥),`cmd_vel`/`odom` 跑通
- [ ] 底盘 + **单臂** 联动:边走边摆臂(先不拆网,3080 直连)
- [ ] (可选)雷达 + SLAM / nav2
**验收**:机器人能"边走边完成一个臂任务"。
### P4 · 整机整合(分布式落地)(~3~6 周) ### P4:分阶段整机任务
**目标**:把 3.1 的「瘦边+厚芯」跑通,整机自主。
- [ ] 双臂固定到 LeKiwi 顶板,统一 **state/action 空间**(左/右臂关节 + 夹爪 + 底盘速度)
- [ ] 写 **policy server**(**3080 主家**上,FastAPI/GRPC:obs→action chunk;训练仍归 3090)+ **thin client**(RPi 5:推图+收 chunk+实时执行+**fail-safe watchdog**)
- [ ] RPi 5 上机(USB 接 2 臂+3 轮+3 相机),以太网接 3080
- [ ] 采集"整机"遥操数据(人在 leader 处,臂+底盘在 RPi5 处,走网),训一个**同时控制双臂+底盘**的 VLA
- [ ] 端到端任务:**走到桌边 → 双手抓取 → 移动到目标点放下**
**验收**:**无人干预**下,移动机器人完成"走+双手抓取+移动放置"的端到端任务;断网能安全停机。
### P5 · 打磨 / 规模化(持续) - [ ] 组合双臂与底盘,复用上游链路,为缺口补适配与本机故障处理。
- [ ] 多任务、多数据集、课程式学习 - [ ] 状态机:移动到位 → 停稳 → 双臂抓取 → 收臂 → 移动 → 放置;每步有成功条件、超时、失败退出和人工接管。
- [ ] 异步推理提速、动作 chunk 调参、fail-safe 加固 - [ ] 采集实际整机安装状态下的示范,不默认桌面策略直接迁移。
- [ ] (可选)sim2real(IsaacLab-Arena / EnvHub)、力控/触觉扩展、π0-FAST 上限冲刺 - [ ] 第 3 节故障注入全部符合预定义停止上限,且不自动恢复动作。
- [ ] 固定任务范围内独立测试 20 次,至少成功 16 次、无碰撞;报告全程及子阶段成功率与干预次数。
--- 验收:分阶段任务可复现,故障停止通过;不描述成开放环境通用自主能力。
## 6. 目录结构约定 ### P5:探索与扩展
``` 按失败数据选择:物体/光照变化、语言对照任务、失败检测与恢复、无线链路、Async/RTC、导航扩展。最后探索边移动边操作、统一整机 VLA、大模型、LoRA/量化与仿真迁移,分别立项并测量。
(本 Windows 写字台 & 两台 GPU 机共用同一仓库,GPU 机上放 ~/robot/)
robot/
├─ PLAN.md # 本方案(单一事实来源)
├─ README.md # 仓库导览
├─ hw/
│ └─ bom.md # 采购清单/链接/到货状态
├─ env/
│ ├─ machines.md # 机器拓扑 + 协作模型
│ └─ setup_lerobot.sh # GPU 机一键装环境(3080/3090 都跑)
├─ lerobot/ # LeRobot 仓库 clone(各 GPU 机自己 clone,不入库)
├─ robots/
│ └─ bi_so101_lekiwi/ # 本机器人的 LeRobot robot 定义(双臂+底盘驱动,P2/P3)
├─ configs/
│ ├─ teleop/ record/ train/ eval/ # 各场景的 .toml/.yaml 配置
├─ server/ # policy server(3080 主家上,P4)
├─ client/ # thin client + 执行 + fail-safe(RPi 5 上,P4)
└─ docs/ # 组装/校准/CLI参考/踩坑笔记
```
> 说明:**3080 主家与 3090 训练机都 clone 本仓库 + LeRobot**(目录统一 `~/robot/`);本 Windows `D:\robot\lerobot` 是源头,你 push 到 git 库后两机 pull。**数据集/模型不入 git**(走 HF Hub / rsync)。 ## 5. 预算与风险
--- 历史基础 BOM 粗估 ¥6500–8000,未核实现价;另预留 20%–30% 结构、电源和备件费,规划约 ¥7800–10400。若上限 ¥10000,应先拿报价并缩减非必要项。P1 暂缓 RPi/底盘,详见 [BOM](hw/bom.md)。
## 7. 风险 & 待验证项 主要风险依次为机械可达性/稳定性、示范质量、长任务失败累积、时序与故障处理、依赖兼容性。显存和训练时长作为测量项,不承诺“24GB 全量舒适”“几分钟训好”或“量化必定可用”。
| # | 风险/未知 | 影响 | 对策 | ## 6. 参考与下一步
|---|---|---|---|
| 1 | **两台 GPU 机都不在我沙箱里(无外网)** | 我无法直接跑命令 | **协作**:我写 → 你 push git → 3080/3090 跑 → 粘回输出(见 machines.md) |
| 2 | **CLI flag 随版本变**(0.5→0.6 有差异) | 照旧文档会报错 | 装好后以 `--help` 实测为准(记到 docs/cli_reference.md) |
| 3 | **双臂驱动非官方内置**(靠社区 BiSO-101 移植) | P2 要多写/改驱动 | 参考 Maker-Mods/Xbotics,必要时自写 `bi_so101_follower` |
| 4 | **LeKiwi 驱动**:LeRobot 原生 `.[lekiwi]` vs lerobot-ros 桥 | P3 集成方式 | 优先 LeRobot 原生 lekiwi;不行再上 ROS2 桥 |
| 5 | **局域网可靠性**(WiFi 抖动 → 臂卡顿) | P4 体验/安全 | 优先**有线 1G**;client 带 watchdog 断链即停 |
| 6 | **AWU408 能否跑 Ubuntu+PyTorch**(常出厂 QNX/DRIVE OS) | 只影响"富余算力" | 非阻塞;跑不了就不管它 |
| 7 | **硬件到货周期**(3D 打印件 1~6 周) | 拖慢 P1 起步 | P0 立即下单,等货期间把软件全搭好 |
| 8 | **RPi 5 USB 口不够**(2臂+3轮+3相机≈6-8 设备) | 上机接线 | 用**有源 USB 3.0 Hub**;相机降到 2 个 USB3 口 |
| 9 | **GPU 机网络可达性**(能否直连 pip/HF/github) | 装环境速度/成败 | `setup_lerobot.sh` 自动探测并切国内镜像 |
| 10 | **π0-FAST 推理 ~7GB,3080 10GB 紧张** | P5 上限模型部署 | 4-bit 量化 / batch=1+bf16 / 3090 同局域网代推 |
--- 下一步:3080 完成 P0 首次解析和报告,再同步 3090;同时确认 P1 型号。未经测试的项保持未勾选。
## 8. 下一步(P0 第一步 · 现在就能做) - [v0.6.1 依赖](https://github.com/huggingface/lerobot/blob/v0.6.1/pyproject.toml)
- [v0.6.1 双臂源码](https://github.com/huggingface/lerobot/blob/v0.6.1/src/lerobot/robots/bi_so_follower/bi_so_follower.py)
1. **push 完成建库**:仓库已建好并 commit(`git.hyonglin.top/ylhan/lerobot_learn`),你在本机终端跑一次 `git push -u origin master`(输入 Gitea 账号密码,之后自动记住)。 - [v0.6.1 SmolVLA](https://github.com/huggingface/lerobot/blob/v0.6.1/docs/source/smolvla.mdx)
2. **两台 GPU 机装环境**:clone 后在 **3080 主家** 与 **3090** 各跑一遍 `env/setup_lerobot.sh`,各把 **[1]~[7] 完整输出粘回**。 - [v0.6.1 Async](https://github.com/huggingface/lerobot/blob/v0.6.1/docs/source/async.mdx)
3. **下单**:[hw/bom.md](hw/bom.md) 先买 **2 条 SO-ARM101(1L+1F)** 起步。 - [LeKiwi](https://huggingface.co/docs/lerobot/lekiwi)(接口以安装版本为准)
4. **HF 登录**:两台机器都 `huggingface-cli login`(脚本已配 hf-mirror)。
> **协作**:我(本机)写 → 你 push git → 3080/3090 跑 → 粘回输出 → 我迭代。
> 装环境输出回来后,我就铺 **P1 的具体命令/配置**(第一条臂的 find-port / 校准 / 遥操 / 采集)。
+25 -17
View File
@@ -1,31 +1,39 @@
# LeRobot 双臂移动 VLA 机器人(可自行训练) # LeRobot 双臂移动操作项目
会走(LeKiwi 底盘)+ 双手协作(2×SO-101)+ VLA(SmolVLA / π0-FAST)+ 可自行采集数据并训练。 基于 LeRobot,建立人工遥操示范、采集、训练与真机执行闭环。先完成单臂抓放,再扩展桌面双臂,最后实现“移动到位 → 停稳 → 操作”的分阶段任务。
基于 HuggingFace **LeRobot** 框架组装;架构「**瘦边 + 厚芯**」:RPi 5 只做实时控制,**推理在 3080 主家、训练在 3090**,走局域网。
当前处于 P0:规划与环境脚本已准备,GPU、数据管线和机器人效果尚未验收。
## 导览 ## 导览
| 文件 | 内容 | | 文件 | 内容 |
|---|---| |---|---|
| [PLAN.md](PLAN.md) | ⭐ 单一事实来源:决策 / 预算 / 架构 / P0–P5 阶段 / 风险 | | [PLAN.md](PLAN.md) | 决策、阶段范围、验收与风险 |
| [hw/bom.md](hw/bom.md) | 采购清单(链接 / 价格 / 到货状态) | | [hw/bom.md](hw/bom.md) | 分批采购、供电和机械验证 |
| [env/machines.md](env/machines.md) | 机器拓扑 + 人机协作模型 | | [env/machines.md](env/machines.md) | 机器分工、依赖锁流程和环境记录 |
| [env/setup_lerobot.sh](env/setup_lerobot.sh) | GPU 机一键装环境(3080 / 3090 都跑) | | [env/setup_lerobot.sh](env/setup_lerobot.sh) | Ubuntu GPU 环境安装与冒烟检查 |
| [docs/cli_reference.md](docs/cli_reference.md) | SO-101 全流程 CLI 命令 | | [env/requirements.in](env/requirements.in) | LeRobot 0.6.1 / P1 依赖输入 |
| `robots/` `configs/` | 机器人定义与各场景配置(P2/P3 填充) | | [docs/cli_reference.md](docs/cli_reference.md) | 单臂设置、采集、训练和 rollout 示例 |
| `server/` `client/` | P4:policy server(3080)+ thin client(RPi5) | | [docs/evaluation.md](docs/evaluation.md) | 20 次评测及故障验证记录模板 |
`robots/`、`configs/`、`server/`、`client/` 当前为占位。后续优先复用上游驱动与网络推理,仅实现组合硬件适配、任务调度和故障处理。
## 机器分工 ## 机器分工
- **3080(10GB · 本地 Ubuntu · 机器人旁)**=主家:开发 + 臂 USB + 遥操/采数 + 推理部署 - 3080 10GB:遥操、采集与推理,P1/P2 USB 直连。
- **3090(24GB · 远程 SSH · 同局域网)**=训练专用:只跑 `lerobot-train` - 3090 24GB:训练,与 3080 使用同一经过验证的依赖锁。
- **RPi 5(P3/P4)**=上机驱动板:实时控制 + fail-safe - RPi 5:P3 起采图和动作执行,ARM64 环境单独验证。
- **数据流**:采数@3080 → HF Hub(hf-mirror)→ 训练@3090 → 模型 → 推理@3080 - ACT:固定任务基线;SmolVLA:预训练基座微调和语言条件探索。
- **代码流**:Windows 写字台 → git 库 → 两台 GPU 机 pull - 数据/模型优先局域网 rsync,HF Hub 可选;代码经 git 同步。
## 快速开始(GPU 机上) ## 开始(3080 Ubuntu 主机)
先安装 git、uv、NVIDIA 驱动、FFmpeg,详见机器文档。
```bash ```bash
mkdir -p ~/robot
git clone https://git.hyonglin.top/ylhan/lerobot_learn.git ~/robot/proj git clone https://git.hyonglin.top/ylhan/lerobot_learn.git ~/robot/proj
bash ~/robot/proj/env/setup_lerobot.sh # 自动装环境(国内镜像自适应) bash ~/robot/proj/env/setup_lerobot.sh --resolve
``` ```
第一次在目标主机解析完整依赖并生成锁;通过 P0 验证后,把锁和输入指纹同步至 3090,再执行不带 `--resolve` 的脚本。当前未附经过 GPU 验证的完整锁,不能声称两机已可复现。脚本不会自动拉取上游最新代码,也不会操作机器人。
+82 -50
View File
@@ -1,74 +1,106 @@
# LeRobot CLI 命令参考(SO-101 · 默认在 3080 主家跑;训练命令在 3090) # SO-101 CLI 参考(LeRobot 0.6.1)
> ⚠️ LeRobot 从 v0.3/0.4 的 `python -m lerobot.xxx` 改成了独立 **`lerobot-*` 控制台命令**(v0.5/0.6)。 > 按 v0.6.1 官方文档核对;尚未在目标 GPU/真机上执行。安装报告包含 CLI 帮助,实际差异必须回填。
> 下列命令基于调研,**确切 flag 以装好后 `<命令> --help` 实测为准**——跑完 setup 后先 `lerobot-record --help` 等核对一遍,把差异记回来。 > 遥操、采集和 rollout 在 3080;训练在 3090。电机设置/校准会写硬件或校准数据,先按装配文档确认接线。
> 前置:`source ~/robot/.venv/bin/activate && cd ~/robot/lerobot && export HF_ENDPOINT=https://hf-mirror.com`
## 0. 环境与变量
## 0. 常用准备
```bash ```bash
pip install pynput # 采数时用键盘 空格/回车 开始/停止 episode source ~/robot/.venv-lerobot-0.6.1/bin/activate
huggingface-cli login # HF token(推/拉 数据集、模型) # 使用 Hub 时先登录;本地 rsync 路线不要求登录。
# hf auth login
export ROBOT_DATA="$HOME/robot/data/so101_pickplace_v1"
export DATASET_ID="YOUR_HF_USER/so101_pickplace_v1"
export PORT_F="/dev/serial/by-id/REPLACE_FOLLOWER"
export PORT_L="/dev/serial/by-id/REPLACE_LEADER"
export TASK="put the red brick in a bowl"
export CAMERAS='{front:{type:opencv,index_or_path:0,width:640,height:480,fps:30}}'
``` ```
## 1. 探测硬件 将账号、端口和相机索引替换为实测值;训练机同样设置数据路径和 ID。优先稳定设备路径,备份实际校准目录。所有阶段使用同一个 robot/teleop ID、相机字段和任务文本。上面的单相机配置只是起点。
```bash
lerobot-find-port # 列出 USB 串口,认出手臂(和底盘轮)的 /dev/tty*
lerobot-find-cameras # 列出 USB 相机及其 index
```
> 记住每个设备对应的端口/索引,下面命令要用。多设备时**电机 ID 按顺序烧录**,别串。
## 2. 校准(每条臂都要) ## 1. 探测、设置电机与校准
```bash ```bash
# follower(执行从手) lerobot-find-port
lerobot-calibrate --robot.type=so101_follower --robot.port=<PORT_F> --robot.id=my_follower lerobot-find-cameras
# leader(遥操主手) # 新电机逐个连接,根据交互提示设置 ID/波特率;不要一次接满总线。
lerobot-calibrate --robot.type=so101_leader --robot.port=<PORT_L> --robot.id=my_leader lerobot-setup-motors --robot.type=so101_follower --robot.port="$PORT_F"
lerobot-setup-motors --teleop.type=so101_leader --teleop.port="$PORT_L"
lerobot-calibrate --robot.type=so101_follower --robot.port="$PORT_F" --robot.id=my_follower
lerobot-calibrate --teleop.type=so101_leader --teleop.port="$PORT_L" --teleop.id=my_leader
``` ```
> 校准会引导你把每个关节到极限位置、记 min/max/mid。产物存到 `--calibration_dir`(默认 `calibrations/`),**别丢**。
校准位置以实际输出及 `--robot.calibration_dir` / `--teleop.calibration_dir` 配置为准,不假设存于当前目录。更换电机、校准或机构后记录新版本,先遥操验证。
## 2. 遥操
## 3. 遥操作(验证跟手)
```bash ```bash
lerobot-teleoperate \ lerobot-teleoperate \
--robot.type=so101_follower --robot.port=<PORT_F> --robot.id=my_follower \ --robot.type=so101_follower --robot.port="$PORT_F" --robot.id=my_follower \
--teleop.type=so101_leader --teleop.port=<PORT_L> --teleop.id=my_leader --robot.cameras="$CAMERAS" \
--teleop.type=so101_leader --teleop.port="$PORT_L" --teleop.id=my_leader
``` ```
> 拿 leader 摆位 → follower 应同步跟上。**跟手不顺先查 ID/齿轮/校准**,别急着采数。
## 4. 采数(P1 核心) 先清空工作区,低速验证限位与停止手段,再采数。数据采集中的控制键以当前 CLI 提示为准,不沿用旧版“空格开始、回车保存”的说法。
## 3. 采集(3080)
```bash ```bash
lerobot-record \ lerobot-record \
--robot.type=so101_follower --robot.port=<PORT_F> --robot.id=my_follower \ --robot.type=so101_follower --robot.port="$PORT_F" --robot.id=my_follower \
--teleop.type=so101_leader --teleop.port=<PORT_L> --teleop.id=my_leader \ --robot.cameras="$CAMERAS" \
--dataset.repo_id=$HF_USER/so101_<task> \ --teleop.type=so101_leader --teleop.port="$PORT_L" --teleop.id=my_leader \
--dataset.num_episodes=30 \ --dataset.repo_id="$DATASET_ID" --dataset.root="$ROBOT_DATA" \
--dataset.single_task="put the red brick in a bowl" \ --dataset.single_task="$TASK" --dataset.num_episodes=50 \
--robot.cameras="{front:{type:opencv,index_or_path:0,width:640,height:480,fps:30}}" --dataset.push_to_hub=false
``` ```
- 键盘:**空格=开始 episode,回车=保存**。
- 多相机(P2 双臂):`--robot.cameras="{front:{...},left_wrist:{...},right_wrist:{...}}"`(index 以 `find-cameras` 为准)。
- 采完自动 push 到 HF Hub(`$HF_USER/...`),3090 上即可训练。
## 5. 训练(在 3090 训练机上跑,数据集从 Hub 拉) 先用少量 episode 验证保存、解码和时序,再完整采集。正式采集使用新数据目录,续录前核对当前版本的 resume 流程,勿覆盖旧实验。停止录制后将整个数据目录经 rsync 同步至 3090;保留 meta、视频和数据文件的相对结构。Hub 上传是可选独立步骤,不自动走镜像上传。
## 4. 训练(3090)
以下 batch/步数是起步配置,不承诺最终成功率或训练耗时。输出目录每个实验独立,不复用已存在的目录。
```bash ```bash
# ACT(P1 快速验证) # ACT:固定任务基线。
lerobot-train --policy.type=act --dataset.repo_id=$HF_USER/so101_<task> lerobot-train \
# SmolVLA(主力,24GB 单卡全量微调) --policy.type=act --policy.device=cuda --policy.push_to_hub=false \
lerobot-train --policy.type=smolvla --dataset.repo_id=$HF_USER/so101_<task> --dataset.repo_id="$DATASET_ID" --dataset.root="$ROBOT_DATA" \
--batch_size=8 --steps=20000 --seed=42 \
--output_dir="$HOME/robot/outputs/act_pickplace_v1" \
--job_name=act_pickplace_v1 --wandb.enable=false
# SmolVLA:显式加载预训练基座,然后微调。
lerobot-train \
--policy.path=lerobot/smolvla_base --policy.device=cuda --policy.push_to_hub=false \
--dataset.repo_id="$DATASET_ID" --dataset.root="$ROBOT_DATA" \
--batch_size=4 --steps=20000 --seed=42 \
--output_dir="$HOME/robot/outputs/smolvla_pickplace_v1" \
--job_name=smolvla_pickplace_v1 --wandb.enable=false
``` ```
> 3090 24GB:SmolVLA 全量、π0-FAST 用 LoRA。GPU 不足时降 batch / 用 `--policy.batch_size`。
先做短训练与保存/重载验证,再跑正式训练。显存不足调顶层 `--batch_size`;更改步数时一并检查学习率调度。记录实际冻结模块、图像数量/尺寸、精度、峰值显存和步耗时。默认微调不应写作“全参数解冻”。ACT 的视觉骨干也可能需要首次下载权重。
`lerobot/smolvla_base` 首次会访问 Hub;正式复现实验应记录 revision 并保存完整本地快照,后续将 `--policy.path` 指向该快照。不要只保存模型权重而遗漏处理器、统计量或配置。
## 5. 真机执行(3080)
将训练输出中完整的 `pretrained_model` 目录(含配置和处理器)复制到本机;以实际输出目录为准。
## 6. 评测 / 部署到真机(在 3080 主家跑,臂插它)
```bash ```bash
# 两种名字都见过(随版本),用 --help 确认当前是哪个 export MODEL_DIR="$HOME/robot/models/act_pickplace_v1/pretrained_model"
lerobot-eval --policy.path=<trained_model_dir> --robot.type=so101_follower --robot.port=<PORT_F> --robot.id=my_follower lerobot-rollout \
# 或 --strategy.type=base \
lerobot-rollout --policy.path=<trained_model_dir> --robot.type=so101_follower --robot.port=<PORT_F> --robot.id=my_follower --robot.type=so101_follower --robot.port="$PORT_F" --robot.id=my_follower \
--robot.cameras="$CAMERAS" \
--task="$TASK" --policy.path="$MODEL_DIR" --policy.device=cuda
``` ```
> 3090 单机直连 follower,让**没被遥操的 follower** 独立完成任务 = P1 验收。
--- 使用训练时的相机/动作契约和当前机器人校准。先单次低风险试运行,再按 [评测协议](evaluation.md) 测 20 次。`lerobot-eval` 不作为这里的真机命令替代;同步 rollout 达标后再评估 Async/RTC。
## P4 分布式(薄边厚芯)命令形态 ## 6. 双臂与移动
- **3080 主家(推理芯)**:policy server —— 不是官方 `lerobot-*`,而是我们自写(`server/`),内部调 LeRobot 的 policy 推理,输入 obs 输出 action chunk;**训练仍归 3090**。
- **RPi5(机器人)**:thin client(`client/`)—— 采 3 相机 + 本体状态 → 推 3080 → 收 chunk → 实时插值下发舵机/底盘 + 断链 fail-safe。 P2 先检查 v0.6.1 的 `BiSOFollower` 配置,不从零移植双臂驱动。P3 复用 LeKiwi host/client,P4 核对官方 PolicyServer/RobotClient 与组合 robot 兼容性,再添加适配、状态机和本机故障处理。此处暂不编写未验证的整机 CLI。
- 复用:3080 上仍用 `lerobot-record`(遥操采集);训练丢给 3090 的 `lerobot-train`。
参考:[v0.6.1 模仿学习流程](https://github.com/huggingface/lerobot/blob/v0.6.1/docs/source/il_robots.mdx)、[v0.6.1 SmolVLA 与 rollout](https://github.com/huggingface/lerobot/blob/v0.6.1/docs/source/smolvla.mdx)、[SO-101 电机设置](https://huggingface.co/docs/lerobot/so101)。
+43
View File
@@ -0,0 +1,43 @@
# 实验与评测协议
当前无实测结果。本文件为模板,每轮复制至独立实验记录后填写;不得将占位或演示数据填为真实结果。
## 实验身份
记录日期、操作者、任务、机器人/机构版本、校准 ID 与备份校验值、相机安装照片和参数、数据版本/校验值、LeRobot 版本、依赖锁 SHA256、GPU/驱动、模型来源 revision、checkpoint、处理器、训练步数/batch/种子/精度/冻结模块。
另记录训练步耗时、训练峰值显存、推理峰值显存与延迟 P50/P95/P99。评测不通过时先分类失败原因,再决定补数据、修机构或调模型。
## P1/P2/P4 任务评测
1. 开始前写明任务成功条件、初始位置范围、物体、目标区域、最大执行时长、允许的接触、碰撞定义与停止条件。抓放成功应包括物体最终稳定留在目标区域,而非仅短暂抓起。
2. 预先列出 20 次初始条件和测试顺序。可用 5 个规定位置各 4 次;这只能说明该范围内能力。未见位置、物体、光照或语言指令泛化应另测,不能混为同一结论。
3. 固定 checkpoint;测试期间不调参、不挑选成功视频替代全量记录。每次运行前允许人工复位;运行开始后任何人工接管均算本次失败。
4. 超时、掉落或需人工救援算失败;保存失败视频与原因。更换模型/数据或调参后重新开始完整一轮,不删除失败试次。
5. 阶段门槛:20 次至少成功 16 次、碰撞 0 次;全部干预和失败完整记录。任一碰撞均使该轮不通过。该样本量只是项目门槛,不代表精确的长期可靠性估计。
| 试次(1–20,每次一行) | 初始条件 | 成功/失败 | 耗时 | 干预次数 | 碰撞次数 | 失败阶段/原因 | 视频/日志 |
|---|---|---|---|---|---|---|---|
| 待填 | | | | | | | |
汇总:成功 __/20,超时 __,干预 __,碰撞 __,是否通过 __。P4 同时报告移动、到位、抓取、运输、放置的分阶段结果,但整机成功必须全程通过。
## P3 到位与制动
根据 P1 抓取容差和底盘试验,**在验收前**填入:位置误差上限 __;角度误差上限 __;停稳速度/持续时间 __;停车时间上限 __;停车距离上限 __;测试负载 __;地面 __;最大速度 __。
重复 20 次移动到位,逐次记录位置/角度误差、停稳时间及是否达标,报告误差分布。全部符合预先规定阈值才能连接操作策略。未定义阈值时只能称为探索测试,不能验收。
## P4 故障注入
在受控工作区从低速、轻负载开始。使用独立停止手段,按实际负载明确手臂保持/受控停止行为;不默认回中位。
| 故障 | 测试内容 | 触发到停车时间/距离 | 手臂行为 | 旧动作是否失效 | 重连是否需重新使能 | 是否通过 |
|---|---|---|---|---|---|---|
| 断网 | 双向断开与单向通信失败 | 待测 | | | | |
| 推理进程退出 | 服务意外退出 | 待测 | | | | |
| 相机卡死 | 无新帧与反复返回旧帧 | 待测 | | | | |
| 乱序/过期动作 | 延迟包、重复包、旧 session 包 | 待测 | | | | |
| 队列耗尽 | 推理耗时超过动作缓冲 | 待测 | | | | |
所有故障均符合 P3 预定停止上限、旧动作不可再执行、恢复需显式使能后,故障验收才通过。阈值或停止行为改变后须复测。
+43 -112
View File
@@ -1,131 +1,62 @@
# 机器拓扑 & 环境 & 协作模型 # GPU 环境与机器记录
> 本文件记录各机器角色、连接方式、软件环境,以及**我和你的协作方式**。**每次改动后更新。** 基线:LeRobot 0.6.1 / Python 3.12。脚本适用 Ubuntu x86_64 GPU 主机;不用于 Windows 或 RPi。当前 GPU 环境与模型训练均未验收。
> `[待补]` = 需要你在对应机器上跑命令后回填。
## ⭐ 协作模型(先读这个) ## 分工与路径
| 角色 | 机器 | 谁操作 | | 机器 | 用途 | 环境记录 |
|---|---|---| |---|---|---|
| **主家(开发+臂+推理)** | **② 3080 机(10GB · 本地 Ubuntu · 机器人旁)** | **你**(本地终端) | | Windows | 编辑、静态检查、git 同步 | 本仓库 `D:\robot\lerobot` |
| **训练专用** | **③ 3090 机(24GB · 远程 SSH)** | **你**(SSH) | | 3080 10GB | USB 遥操、采集、推理,首次解析依赖 | OS/驱动/Python/uv/锁 SHA256:待填 |
| 写字台(写代码/规划/文档) | ① 本 Windows 机 `D:\robot\lerobot` | **我(agent)** | | 3090 24GB | 训练,同局域网 | OS/驱动/Python/uv/锁 SHA256:待填 |
| 富余算力(非关键路径) | ⑤ AWU408 双 Orin | 暂不用 | | RPi 5 | P3 起硬件驱动、采图、执行和故障处理 | ARM64 环境另行验证,不复用 x86_64 锁 |
| 上机驱动板(P3/P4 起) | ④ RPi 5 | P3/P4 前你配 | | DRIVE Orin | 可选实验 | 不阻塞主线 |
**关键约束**:我的沙箱**无外网**,够不到你任何一台 GPU 机。工作流: GPU 机统一路径:项目 `~/robot/proj`;专用环境 `~/robot/.venv-lerobot-0.6.1`;数据 `~/robot/data`;模型 `~/robot/models`;训练输出 `~/robot/outputs`;安装报告 `~/robot/reports`。脚本支持 `ROBOT_WORKDIR`,改动后相应调整命令。
``` ## 首次安装与依赖锁
我(①写字台)写代码/配置 ──你 push──▶ git 库 ──clone/pull──▶ ② 3080 & ③ 3090
你在 ②/③ 执行(本地终端 / SSH)──粘回完整输出──▶ 我诊断/迭代
```
**git 仓库**:`https://git.hyonglin.top/ylhan/lerobot_learn.git`(身份 ylhan <ylhan@hyonglin.com>;**匿名可读** → GPU 机 clone 免密,push 才需认证) 前置:安装 NVIDIA 驱动、git、uv、FFmpeg。脚本用 uv 创建 Python 3.12 环境(必要时 uv 下载 Python),不自动 sudo 安装系统组件。缺少前置即退出。
**约定**: 先在 3080:
1. 我给**自包含、复制即跑**的脚本/命令块(尽量一次给全)。
2. **代码/配置**走 git 库(你 push,两机 pull);**数据集/模型**走 HF Hub(hf-mirror)或局域网 rsync(两机互通,大文件直传更快)。
3. 两台 GPU 机目录统一 `~/robot/`:本仓库 + lerobot clone + `.venv`。
---
## 拓扑总览
```
┌──────────────────────┐ push ┌───────┐ clone/pull ┌─────────────────────────┐
│ ① Windows 写字台 │ ──────▶ │ git 库 │ ──────────▶ │ ② 3080 主家 (10GB) │
│ D:\robot\lerobot │ └───────┘ ⟨同一库⟩ │ 本地 Ubuntu · 机器人旁 │
│ 我写代码/文档/规划 │ ┌────────┴─────────────────────────┐
└──────────────────────┘ │ ③ 3090 训练 (24GB) · 远程 SSH │
└───────────────────────────────────┘
② ↔ ③ 同一局域网:rsync 直传数据集/模型;π0 推理紧张时 3090 可代推
② 3080 主家(推理芯,挨着机器人 = 低延迟):
开发 · 臂 USB 直连 · 遥操 · 采数 · 推理部署 · P4 policy server
③ 3090 训练(训练芯):
只跑 lerobot-train:ACT / SmolVLA 全量 / π0-FAST LoRA
数据流: 采数@② → HF Hub(或 rsync) → 训练@③ → 模型 → 推理@②
```
**为什么这样拆**:训练吃显存(参数+梯度+优化器+激活 ≈ 推理的 4~8 倍),推理不吃。
- 3090 24GB:SmolVLA 全量微调 / π0-FAST LoRA —— 只有它干得动。
- 3080 10GB:ACT(<1GB) / SmolVLA fp16(~2GB) 推理绰绰有余;遥操/采数几乎不占 GPU。
---
## ② 3080 机(主家 · 10GB · 本地 Ubuntu · 机器人旁)
| 项 | 值 |
|---|---|
| 位置 | **机器人/工作台旁**(SO-101 臂 USB 直插它) |
| 主机名 / IP | `[待补]` |
| Ubuntu 版本 | `[待补]`(建议 22.04) |
| GPU | **3080(10GB)** —— 开发 + 推理 |
| 驱动 / CUDA | `[待补]`(setup 脚本会打印) |
| Python | **3.12**(venv,脚本自建) |
| LeRobot | `[待补]`(预期 0.6.x) |
| HF 账号 | `huggingface-cli login`(HF_ENDPOINT=hf-mirror) |
| 目录 | `~/robot/`(本仓库 + lerobot + .venv) |
**跑什么**:日常开发、`lerobot-teleoperate` / `lerobot-record`(臂插这)、`lerobot-eval|rollout`(推理部署)、P4 的 policy server。
**显存预算**:ACT <1GB ✅ / SmolVLA fp16 ~2GB ✅ / π0-FAST ~7GB ⚠️(fallback 见文末)。
## ③ 3090 机(训练专用 · 24GB · 远程 SSH)
| 项 | 值 |
|---|---|
| 访问 | **SSH**(远程,与 ② 同局域网互通) |
| 主机名 / IP | `[待补]` |
| Ubuntu 版本 | `[待补]` |
| GPU | **3090(24GB)** —— 只管训练 |
| Python / LeRobot | 与 ② 同一 setup 脚本 |
| 目录 | `~/robot/`(同一 git 库) |
**跑什么**:只跑 `lerobot-train`(拉数据集 → 训 → 推模型回 Hub)。
**兜底角色**:π0-FAST 推理在 ② 放不下时**代推**(同局域网+异步分块,多一跳延迟可接受);② 忙时也可顶 ACT / SmolVLA-LoRA 训练。
### 两机传大文件(同局域网,比 HF Hub 快)
```bash ```bash
# ② → ③ 推数据集 mkdir -p ~/robot
rsync -avzP ~/robot/data/ <user>@<3090-ip>:~/robot/data/ git clone https://git.hyonglin.top/ylhan/lerobot_learn.git ~/robot/proj
# ③ → ② 拉训练好的模型 bash ~/robot/proj/env/setup_lerobot.sh --resolve
rsync -avzP <user>@<3090-ip>:~/robot/outputs/train/<exp>/ ~/robot/models/<exp>/
``` ```
## ① 本 Windows 机(`D:\robot\lerobot` · 我的写字台) 产生 `env/requirements-linux-py312.lock` 和 `env/requirements-linux-py312.lock.input.sha256`。第一次解析尚不是经过验证的完整环境锁:先完成脚本检查,再做短视频编码/解码、小样本训练、保存和重新加载模型。
| 项 | 值 | 将这两个文件一起传到 3090 同一项目的 `env/` 目录,再运行:
|---|---|
| 角色 | 写代码 / 规划 / 文档;**不跑 LeRobot** |
| Python | 3.14(LR 要 3.12;本机只编辑) |
| git | 2.51.0 ✅ |
| 外网 | ❌ 沙箱无外网 |
| 同步 | **你从本机 push 到 git 库** → ② ③ pull |
## ④ RPi 5(上机驱动板 · P3/P4 起) ```bash
bash ~/robot/proj/env/setup_lerobot.sh
source ~/robot/.venv-lerobot-0.6.1/bin/activate
```
| 项 | 值 | 默认安装严格使用锁与包哈希,不重新解析。两台比较报告中的锁 SHA256;验收通过后把锁、输入指纹与精简环境信息提交 git。**当前仓库尚未包含经过 Ubuntu/GPU 验证的传递依赖锁,默认安装会明确拒绝继续。**
|---|---|
| OS | Raspberry Pi OS 64-bit |
| 连接 | USB(有源 Hub):2 臂 + 3 轮 + 3 相机;**以太网 → ② 3080**(policy server 在它上面) |
| 软件 | LeRobot `.[feetech,lekiwi,dataset]` + thin client(推图/收 chunk/执行/fail-safe) |
| 静态 IP | `[待补]` |
## ⑤ AWU408(富余算力,非关键路径) 两台尽量统一 Ubuntu 版本,记录 Python 补丁版本、uv 版本与 NVIDIA 驱动;同一 Python 包锁不能锁定系统库或驱动。脚本 `uv pip sync` 仅作用于新命名的项目专用环境,会使其中包与锁一致,请勿把它用于其他项目。
- 双 DRIVE Orin(508 TOPS)+ Aurix TC397。默认不用。
- 用途:3090 忙训练时顶推理 / 固定台。
- **待验证**:能否刷 Ubuntu+CUDA+PyTorch(常出厂 QNX/DRIVE OS);跑不通就不管它。
--- 更新依赖时修改 `requirements.in`,人工归档旧锁及指纹后重新解析、两机复验;脚本拒绝覆盖已有锁,也不会自动更新 LeRobot。大模型、双臂移动所需新 extras 在对应阶段再加入输入并复验。
## 国内网络 / 镜像(两台 GPU 机通用,setup 脚本自动处理) ## 网络与数据
| 用途 | 直连不可达时的镜像 |
|---|---|
| pip | `https://pypi.tuna.tsinghua.edu.cn/simple`(或 Aliyun) |
| HF dataset/weights | `HF_ENDPOINT=https://hf-mirror.com` |
| git clone lerobot | `https://ghproxy.com/https://github.com/huggingface/lerobot.git` |
## π0-FAST 推理在 3080(10GB) 放不下时的 fallback(P5 才需要) 默认使用官方索引。若需要镜像,可在安装前显式设置 `UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple`;uv 自身的 Python 下载不由该变量代理。下载失败应按报告排查,不自动切换不明 Git 代理。
1. **4-bit 量化**(权重 6.6GB → ~2GB,立刻宽裕)
2. **batch=1 + bf16 硬试**(~8-9GB,可能刚好) 同局域网优先 rsync。HF Hub 可选;登录使用 `hf auth login`,认证上传使用官方端点,勿把下载镜像当作上传服务。Token 保存在机器凭据环境中,不进入 git、报告或聊天。
3. **3090 代推**:policy server 起在 ③,② 只做遥操/采数(同局域网,异步分块下延迟可接受)
```bash
# 将占位符替换成自己的 SSH 目标;先停止录制,传完整且不再写入的数据目录。
rsync -avP ~/robot/data/ USER@TRAIN_HOST:~/robot/data/
rsync -avP USER@TRAIN_HOST:~/robot/outputs/ ~/robot/outputs/
```
每个实验保留数据版本/校验值、模型与处理器、配置、校准备份和评测记录。模型快照记录来源 revision,不自动随 Hub main 更新。同步代码使用 git;当前未配置 GPU 主机远程访问,因此 GPU 执行结果需从目标机器回传。
## 验收报告
脚本失败即非零退出,不把 MISS 当通过;输出完整日志、包列表、Python/FFmpeg 版本、CLI 帮助与锁哈希。脚本验证 CUDA 矩阵运算、实际策略模块和视频库导入,不连接电机,也不下载模型权重。
后续必须记录:录制/解码结果、训练步耗时、训练和推理峰值显存、单次推理 P50/P95/P99,以及 20 次真机评测。不要将包可导入或显存参考值当作任务能力证据。
+4
View File
@@ -0,0 +1,4 @@
# P0/P1: Ubuntu x86_64 GPU hosts, Python 3.12.
# Resolve once on 3080; share the lock and its input fingerprint with 3090.
# ACT uses the base dependencies; v0.6.1 has no 'act' extra.
lerobot[core_scripts,training,feetech,smolvla]==0.6.1
+91 -114
View File
@@ -1,116 +1,93 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# ============================================================ # Ubuntu x86_64 GPU hosts. First host: --resolve; second host: same lock.
# LeRobot 一键环境 — 3080 主家 / 3090 训练机(两台 Ubuntu 都跑一遍) set -Eeuo pipefail
# 用法: trap 'printf "ERROR at line %s: environment NOT verified.\n" "$LINENO" >&2' ERR
# nano ~/robot/setup_lerobot.sh # 粘入本文件 SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
# bash ~/robot/setup_lerobot.sh WORKDIR="${ROBOT_WORKDIR:-${HOME}/robot}"
# 跑完把【整段输出】粘回给助手,我带你走 P1。 VENV="${WORKDIR}/.venv-lerobot-0.6.1"
# ============================================================ LOCK="${SCRIPT_DIR}/requirements-linux-py312.lock"
set -uo pipefail INPUT="${SCRIPT_DIR}/requirements.in"
RESOLVE=false
WORKDIR="${HOME}/robot" case "${1:-}" in
LEROBOT_DIR="${WORKDIR}/lerobot" --resolve) RESOLVE=true ;;
VENV="${WORKDIR}/.venv" --help) echo "Usage: bash $0 [--resolve] (Linux x86_64, uv, NVIDIA driver, ffmpeg)"; exit 0 ;;
PY=3.12 "") ;;
# LeRobot extras:feetech(SO-101) + lekiwi(底盘) + dataset(采数) + smolvla(主力VLA) + pi0(π0/π0-FAST) *) echo "Unknown argument: $1" >&2; exit 2 ;;
EXTRAS="feetech,lekiwi,dataset,smolvla,pi0" esac
[[ $# -le 1 ]] || { echo "Too many arguments" >&2; exit 2; }
hr(){ echo; echo "========== $* =========="; } [[ "$(uname -s)" == Linux && "$(uname -m)" == x86_64 ]] || {
echo "Only Linux x86_64 GPU hosts are supported; RPi needs a separate environment." >&2; exit 1;
hr "[1/7] 环境探测" }
if [ -r /etc/os-release ]; then . /etc/os-release; echo "OS: ${PRETTY_NAME:-?}"; fi for cmd in uv nvidia-smi ffmpeg sha256sum; do
if command -v nvidia-smi >/dev/null 2>&1; then command -v "$cmd" >/dev/null || { echo "Missing prerequisite: $cmd" >&2; exit 1; }
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
else
echo "!! 未检测到 nvidia-smi —— GPU 驱动可能没装(3090 应能识别)。先装驱动再继续。"
fi
echo "系统 python3: $(python3 --version 2>&1)"
echo "有 python3.12: $([ -x "$(command -v python3.12)" ] && echo 是 || echo 否)"
echo "有 uv: $([ -x "$(command -v uv)" ] && echo 是 || echo 否)"
echo "有 git: $(git --version 2>&1)"
echo "有 ffmpeg: $([ -x "$(command -v ffmpeg)" ] && echo 是 || echo 否)"
hr "[2/7] 网络/镜像策略(直连 vs 国内镜像)"
PIP_URL="https://pypi.org/simple"
if curl -fsS --max-time 6 https://pypi.org >/dev/null 2>&1; then
echo "pypi 直连可达 → 官方源"
else
echo "pypi 直连不可达 → 清华镜像"; PIP_URL="https://pypi.tuna.tsinghua.edu.cn/simple"
fi
if curl -fsS --max-time 6 https://huggingface.co >/dev/null 2>&1; then
echo "HF 直连可达 → 官方"; HF_ENDPOINT="https://huggingface.co"
else
echo "HF 直连不可达 → hf-mirror"; HF_ENDPOINT="https://hf-mirror.com"
fi
export HF_ENDPOINT
echo "→ PIP_URL=$PIP_URL"; echo "→ HF_ENDPOINT=$HF_ENDPOINT"
hr "[3/7] Python ${PY} venv (${VENV})"
mkdir -p "${WORKDIR}"
if [ -d "${VENV}" ]; then echo "venv 已存在,复用"; else
if command -v uv >/dev/null 2>&1; then
uv venv --python ${PY} "${VENV}"
elif command -v python3.12 >/dev/null 2>&1; then
python3.12 -m venv "${VENV}"
elif command -v python3.11 >/dev/null 2>&1; then
echo "无 3.12,用 3.11 兜底(LeRobot 要 3.12,可能装不上,建议装 uv 或 deadsnakes 3.12)"
python3.11 -m venv "${VENV}"
else
echo "!! 没有 3.12/3.11/uv。装 uv: curl -LsSf https://astral.sh/uv/install.sh | sh 然后重跑"; exit 1
fi
fi
# shellcheck disable=SC1091
source "${VENV}/bin/activate"
python -m pip install -U pip -i "${PIP_URL}"
echo "venv python: $(python --version) ($(which python))"
hr "[4/7] clone LeRobot → ${LEROBOT_DIR}"
if [ -d "${LEROBOT_DIR}/.git" ]; then
echo "已存在 → git pull 更新"; ( cd "${LEROBOT_DIR}" && git pull ) || true
else
if curl -fsS --max-time 6 https://github.com >/dev/null 2>&1; then
git clone https://github.com/huggingface/lerobot.git "${LEROBOT_DIR}"
else
echo "github 直连慢/不可达 → 走 ghproxy 加速"
git clone https://ghproxy.com/https://github.com/huggingface/lerobot.git "${LEROBOT_DIR}"
fi
fi
cd "${LEROBOT_DIR}"
echo "当前 commit: $(git log -1 --oneline 2>/dev/null)"
hr "[5/7] 安装 LeRobot [${EXTRAS}]"
pip install -e ".[${EXTRAS}]" -i "${PIP_URL}" 2>&1 | tail -n 25
# ffmpeg(LeRobot 编视频需要)
if ! command -v ffmpeg >/dev/null 2>&1; then
echo "装 ffmpeg ..."; ( sudo apt-get install -y ffmpeg 2>&1 || conda install -y -c conda-forge ffmpeg 2>&1 ) | tail -n 5
fi
hr "[6/7] 验证"
python - <<'PY'
import importlib, torch
print("torch", torch.__version__,
"| cuda", torch.cuda.is_available(),
"| gpu", (torch.cuda.get_device_name(0) if torch.cuda.is_available() else "N/A"),
"| vram_GB", round(torch.cuda.get_device_properties(0).total_memory/1e9,1) if torch.cuda.is_available() else 0)
try:
import lerobot; print("lerobot", getattr(lerobot, "__version__", "?"))
except Exception as e:
print("lerobot import 失败:", e)
for m in ["lerobot.policies.smolvla","lerobot.policies.pi0","lerobot.policies.act"]:
try: importlib.import_module(m); print("OK ", m)
except Exception as e: print("MISS", m, "->", e)
PY
echo "--- CLI 命令 ---"
for c in lerobot-find-port lerobot-find-cameras lerobot-calibrate lerobot-teleoperate lerobot-record lerobot-train lerobot-eval lerobot-rollout; do
command -v "$c" >/dev/null 2>&1 && echo "OK $c" || echo "MISS $c"
done done
if ! $RESOLVE && [[ ! -s "$LOCK" ]]; then
hr "[7/7] 完成 — 之后每次用 3090 前先:" echo "Missing lock: use --resolve on 3080 first; transfer the validated lock and .input.sha256 to 3090." >&2; exit 1
cat <<EOF fi
source ${VENV}/bin/activate if $RESOLVE && [[ -e "$LOCK" || -e "$LOCK.input.sha256" ]]; then
cd ${LEROBOT_DIR} echo "Refusing to overwrite existing lock. Review and archive it before an intentional update." >&2; exit 1
export HF_ENDPOINT=${HF_ENDPOINT} fi
huggingface-cli login # 首次: 输你的 HF token mkdir -p "$WORKDIR"
EOF REPORT="${WORKDIR}/reports/$(date -u +%Y%m%dT%H%M%SZ)-$$"
echo "✅ 把上面 [1]~[7] 的完整输出粘回给助手。" mkdir -p "$REPORT"
echo " 若全 OK,我们就进 P1:插第一条 SO-101 → lerobot-find-port → 校准 → 遥操。" exec > >(tee "$REPORT/setup.log") 2>&1
echo "[1/5] Prerequisites"
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
uv --version
ffmpeg -version > "$REPORT/ffmpeg.txt"
# Set UV_DEFAULT_INDEX explicitly if a mirror is needed. No automatic Hub/token routing.
echo "[2/5] Dedicated Python 3.12 environment"
if [[ ! -d "$VENV" ]]; then uv venv --python 3.12 "$VENV"; fi
PYTHON="${VENV}/bin/python"
"$PYTHON" -c 'import sys; assert sys.version_info[:2] == (3, 12), sys.version'
if $RESOLVE; then
TEMP_LOCK="$(mktemp "${LOCK}.tmp.XXXXXX")"
trap 'rm -f -- "$TEMP_LOCK"' EXIT
uv pip compile "$INPUT" --python "$PYTHON" --generate-hashes --output-file "$TEMP_LOCK"
mv -- "$TEMP_LOCK" "$LOCK"
(cd "$SCRIPT_DIR" && sha256sum requirements.in) > "$LOCK.input.sha256"
trap - EXIT
fi
[[ -s "$LOCK.input.sha256" ]] || { echo "Missing input fingerprint" >&2; exit 1; }
(cd "$SCRIPT_DIR" && sha256sum --check "${LOCK}.input.sha256")
echo "[3/5] Install locked packages (dedicated venv only)"
uv pip sync --python "$PYTHON" --require-hashes "$LOCK"
uv pip check --python "$PYTHON"
echo "[4/5] GPU, policy implementations, video libraries and CLI"
"$PYTHON" - <<'PY'
import importlib
import importlib.metadata
import torch
assert importlib.metadata.version('lerobot') == '0.6.1'
assert torch.cuda.is_available(), 'CUDA unavailable: check driver and torch build'
x = torch.ones((32, 32), device='cuda')
assert (x @ x).sum().item() == 32768
torch.cuda.synchronize()
print('torch:', torch.__version__, 'CUDA:', torch.version.cuda, 'GPU:', torch.cuda.get_device_name(0))
for module in (
'lerobot.policies.act.modeling_act',
'lerobot.policies.smolvla.modeling_smolvla',
'lerobot.robots.so_follower',
'lerobot.teleoperators.so_leader',
'av', 'torchcodec',
):
importlib.import_module(module)
print('OK:', module)
PY
for cli in lerobot-find-port lerobot-find-cameras lerobot-setup-motors lerobot-calibrate lerobot-teleoperate lerobot-record lerobot-train lerobot-rollout; do
[[ -x "$VENV/bin/$cli" ]] || { echo "Missing CLI: $cli" >&2; exit 1; }
done
# find-port ignores --help and starts an interactive USB discovery procedure.
# Discovery tools are checked for existence only; never invoke them in setup.
for cli in lerobot-setup-motors lerobot-calibrate lerobot-teleoperate lerobot-record lerobot-train lerobot-rollout; do
"$VENV/bin/$cli" --help > "$REPORT/$cli-help.txt" 2>&1
done
echo "[5/5] Save verification evidence"
uv pip freeze --python "$PYTHON" > "$REPORT/packages.txt"
"$PYTHON" -VV > "$REPORT/python.txt"
sha256sum "$LOCK" > "$REPORT/lock.sha256"
cp -- "$LOCK" "$LOCK.input.sha256" "$REPORT/"
echo "PASS: software smoke checks only; recording, model training and robot safety remain unverified."
echo "Report: $REPORT"
printf 'Activate: source %q/bin/activate\n' "$VENV"
echo "Use hf auth login only if accessing the Hub; use the official endpoint for authenticated uploads."
+29 -64
View File
@@ -1,75 +1,40 @@
# 采购清单 (BOM) — 双臂移动 VLA 机器人 # 硬件 BOM 与采购门槛
> 状态图例:⬜ 未下单 · 🟨 已下单待发货 · 🟩 已到货 · ✅ 已组装 > 2026-09-08 修订。下列单价来自旧计划的 2025 参考值,未核实现价/库存,不能作为报价。
> 价格为 2025 国内参考价,**下单前按链接核当期价/库存**。 > 先买 P1 一对臂、相机与固定件;P2 再补一对;RPi 和底盘在 P3 机械验证后采购。
> **采购策略**:P1 先买 **2 条 SO-ARM101(1 Leader + 1 Follower)** 打通单臂闭环;P2 再补 2 条。LeKiwi / RPi5 在 P3 前买即可(等货期正好用来搭软件)。
--- ## 分批清单
## A. 机械臂 — SO-ARM101(LeRobot 官方 6DOF + 夹爪,Feetech STS3215) | 阶段 | 部件 | 数量 | 历史参考价 | 状态 |
| # | 状态 | 部件 | 数量 | 参考价(¥) | 链接 / 店铺 |
|---|---|---|---|---|---|
| A1 | ⬜ | SO-ARM101 **Follower**(执行从手,含 3D 打印件+舵机+驱动板+电源) | 1 | ~879 | 淘宝搜「SO-ARM101 LeRobot」¥879-899 现货树脂打印版 |
| A2 | ⬜ | SO-ARM101 **Leader**(遥操主手,轻齿轮、带握把) | 1 | ~879 | 同上(买 **Leader 版**) |
| A3 | ⬜ | (P2 补) SO-ARM101 Follower #2 | 1 | ~879 | 同上 |
| A4 | ⬜ | (P2 补) SO-ARM101 Leader #2 | 1 | ~879 | 同上 |
| A5 | ⬜ | (可选) 舵机调试板 TTL/USB | 1-2 | ~49 | 淘宝「幻尔 SO-ARM101 调试板」 |
- **官方备选**:Seeed SO-ARM101(3D-printed parts $35 / SKU 114993668;舵机散件 SKU 114993667);Waveshare SO-ARM100/101 ~¥1406(带相机)。
- **自印省钱**:有打印机则只买「舵机+电子件」散件(~¥500/条),自己打印结构件(官方 STL 支持 FDM/PLA,或树脂更佳)。
- **Leader 用轻负载齿轮**才捏得动(SO-101 已优化,无需外置齿轮箱);**电机 ID 要按顺序烧录**(装时注意)。
## B. 移动底盘 — LeKiwi(三轮全向,SO-101 专用,SIGRobotics-UIUC × HF)
| # | 状态 | 部件 | 数量 | 参考价(¥) | 链接 / 说明 |
|---|---|---|---|---|---|
| B1 | ⬜ | LeKiwi 底盘 **12V(Seeed 含 3D 打印件+电池)** | 1 | ~1600-2000 | Seeed「LeKiwi Kit(12V)」SKU SS114090065 |
| B2 | ⬜ | (省) LeKiwi **base-only 12V**(自印结构件) | 1 | ~1501 | SIGRobotics-UIUC/LeKiwi → BOM(CN) |
| | | 内含:3× STS3215 1:345 12V 舵机 / 全向轮 / 电池 / 分线盒 / 12V转5V 降压 | | | 见 BOM |
- LeRobot 有**原生 `.[lekiwi]` extra**(P3 时装)。底盘顶板 **M3 螺孔**直接固定 SO-101 底座。
- **新手官方建议**:若臂用 5V,底盘用 12V + 自带 12V→5V 降压模块(套件提供);舵机统一 12V。
## C. 上机驱动板 — Raspberry Pi 5(实时控制 + 采图 + 执行 + 联网)
| # | 状态 | 部件 | 数量 | 参考价(¥) |
|---|---|---|---|---| |---|---|---|---|---|
| C1 | ⬜ | Raspberry Pi 5 (8GB) | 1 | ~550-650 | | P1 | SO-101 follower,含舵机、控制板、结构、电源 | 1 | 约 ¥879 | 未确认型号/报价 |
| C2 | ⬜ | RPi5 官方电源 (27W/5A USB-C) | 1 | ~100 | | P1 | SO-101 leader,匹配各关节齿比 | 1 | 约 ¥879 | 未确认型号/报价 |
| C3 | ⬜ | **有源 USB 3.0 Hub**(4-7 口,独立供电) | 1 | ~80-150 | | P1 | USB 相机 | 1,视野不足再加腕部相机 | 约 ¥100–150/个 | 待确认输出格式 |
| C4 | ⬜ | 128G+ microSD / 或 NVMe SSD(系统+数据集) | 1 | ~60-150 | | P1 | 台夹、数据线、耗材、停止/断电装置 | 1 批 | 待报价 | 不重复购买套件已有配件 |
| P2 | leader + follower | 各 1 | 合计约 ¥1758 | P1 达标后采购 |
| P2 | 另加相机与支架 | 补至最多 3 个 | 约 ¥100–150/个 | 按遮挡情况确认 |
| P3 | LeKiwi 底盘 | 1 | 约 ¥1600–2000 | 确认是否含电池、结构和电源模块 |
| P3 | RPi 5 8GB | 1 | 约 ¥550–650 | ARM64 依赖另测 |
| P3 | 供电、存储、散热、有源 Hub | 1 批 | 待报价 | 核实移动供电及 USB 带宽 |
| P3/P4 | 双臂顶板、加固、线束、电池保护、备用舵机 | 1 批 | 待报价 | 机械与电气验证后定型 |
> RPi5 **不做 ML**(推理在 3080 主家、训练在 3090);它只跑 LeRobot robot 驱动 + 动作执行 + fail-safe。 已有:3080 10GB、3090 24GB、3D 打印机、Windows 开发机;Orin 可选。P1 臂+单相机历史小计约 ¥1860–1910,未包含夹具、备件、运费等,须报价后形成实际总额。取消原 P1 预购 RPi 的安排。
> USB 设备数:2 臂 + 3 底盘轮 + 3 相机 ≈ 6-8 → **必须有源 Hub**。
## D. 相机 ×3(LeRobot `--robot.cameras` 用 opencv 类型配置) 原完整基础 BOM 粗估 ¥6500–8000,仅作量级参考;另预留 20%–30% 改件/电源/备件费,规划约 ¥7800–10400。若总预算限制 ¥10000,先用实际报价调整范围。分批明细齐全后重新加总,不把粗估当作各项精确求和。
| # | 状态 | 部件 | 数量 | 参考价(¥) | ## 下单前确认
|---|---|---|---|---|
| D1 | ⬜ | 腕部 USB 相机(1080P 免驱) | 2 | ~58-138 |
| D2 | ⬜ | 前置全局 USB 相机(广角 1080P) | 1 | ~100 |
| | | (可选) 「SO-101 双相机 USB 广角套件」 | — | 淘宝 ~¥138 |
> 相机名 `front` / `left_wrist` / `right_wrist`,与 P4 的 state/action 对齐。 - SO-101 为 5 个臂关节加夹爪,共 6 个电机;leader 各关节齿比不同,不能笼统购买“轻齿轮版”。按官方 BOM 核对每个型号。
- 电机 ID 与波特率按每条总线设置;串联舵机不是每个都占一个 USB 口。画出控制板/总线/相机拓扑后再决定 Hub 数量。
- 逐项确认电机额定电压、控制板允许电压、峰值电流、降压模块额定能力及电池保护。不能默认所有 12V 底盘套件都附带适合手臂的 5V 降压,也不能混用电机电压。
- 台式 27W 电源只能用于有插座场景;移动时 RPi、Hub 和舵机需要合适的电池供电设计。测多轴动作压降、相机重启、发热和续航。
- 依据官方结构和材料建议打印;不默认树脂比 FDM 更适合承载件。样件先做受力和紧固验证。
- 双臂装到底盘前检查顶板刚度、臂间碰撞、负载伸展时重心、制动时稳定性,以及实际桌高与可达范围;孔位匹配不代表整机稳定。
- 相机确认 UVC、目标分辨率下的 MJPEG/其他输出格式、帧率、视角、曝光和稳定设备识别,测多路同时运行;腕部线束不可限制关节或被夹住。
- 有线网络用于受限范围验证,考虑网线拖拽/缠绕;无线移动另做延迟和故障测试。
## E. 杂项 ## 采购记录格式
| # | 部件 | 说明 | 每项回填:厂商、商品链接/SKU、版本、供电、套件内含物、单价、数量、运费、交期、状态、实付金额。P3 另附接线图、负载/供电测试与结构照片。
|---|---|---|
| E1 | USB-C 数据线 ×4-6 | 臂/底盘/相机连 RPi5 |
| E2 | 桌夹 / 台夹 ×4 | P1/P2 把臂固定在桌/台面 |
| E3 | 3D 打印耗材(PLA / 或树脂) | 自印结构件 / 相机支架 / 分线盒 |
| E4 | 5V / 12V 电源适配器 | 散件自供时用 |
| E5 | (P4) 短 1G 网线 / PoE 模块 | RPi5 ↔ 3080 主家,尽量有线 |
--- 参考:[SO-101 官方装配](https://huggingface.co/docs/lerobot/so101)、[SO-ARM100/101 硬件仓库](https://github.com/TheRobotStudio/SO-ARM100)、[LeKiwi 官方文档](https://huggingface.co/docs/lerobot/lekiwi)。按实际采购版本核对,不沿用不明来源的商品编号或套件内含物。
## 合计
| 采购批次 | 内容 | 小计(¥) |
|---|---|---|
| **P1 起步** | 2 臂 + 2 相机 + RPi5 套 + 杂项 | **~3300** |
| **完整整机** | 4 臂 + LeKiwi + RPi5 + 3 相机 + 杂项 | **~6500-8000** |
> **已拥有(0 成本)**:3080 机(10GB·主家·推理)、3090 机(24GB·训练)、AWU408 双 Orin(富余算力)、3D 打印机、本 Windows 机(写代码)。