Files
chenlin f3a8a38acd
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
feat: release v1.0.1 CADWorld 网站与 LeKiwi 智能抓放
集成同源 BYOK 会话隔离、精简模型设置、官方订阅入口和 HTTPS 发布运维;保留本地训练/调参与控制能力。同步 npm 版本及 CHANGELOG,记录公网真实 API 验收仍待用户凭据。
2026-09-24 09:57:41 +08:00

144 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LeKiwi 仿真示例
目标:通过统一机器人接口连接 LeRobot 0.6.1 的上层控制逻辑。此目录不包含实体硬件驱动、相机或 RL 训练任务。相同 A 资产还可在主工作台「控制台 → LeKiwi 智能抓放」运行有限场景任务,见 [模型任务与物理验收](../../docs/lekiwi-agent.md);不使用外控桥作为模型服务。
## 可重建模型输入
```bash
source .venv/bin/activate
python examples/lekiwi/prepare_assets.py --source /path/to/LeKiwi
# 或明确允许下载固定版本所需文件(不会克隆整个仓库)
python examples/lekiwi/prepare_assets.py --download
```
生成 `build/lekiwi/lekiwi-v1.zip`、原始 URDF/资源副本、SHA-256 清单及 Apache-2.0 许可证。原参考仓库保持只读;常规前端构建不下载任何资产。
资产重建脚本适用源:SIGRobotics-UIUC/LeKiwi 的 `efa608d7ee5a495a4803b1d28cd0c955b4f1e033`;URDF SHA-256 见 `robot_profiles/lekiwi-v1.json`。网页显式选择 profile 时也支持换色、显示名、XML 重排和等价数值等非机械变体;固定运动链、物理属性与全部源网格仍须匹配。几何/动力学或拓扑改变不能套用旧 profile,`New_urdf` 两包的新七关节臂属于此边界。详见 [变体检查结果与适配边界](../../docs/lekiwi-urdf-compatibility.md)。
## 动力学边界
- CAD 轮 STL 每个 314,244 面,超出 MuJoCo STL 解码器的 200,000 面限制。现已通过不减面的 OBJ 兼容层完整恢复三轮 CAD 视觉,并随轮轴运动;原始 STL、派生资源与哈希可完整导出。简化轮毂/每轮 12 个被动滚子仍用于动力学,不以视觉细节冒充精确三角面碰撞。见 [完整网格与性能边界](../../docs/lekiwi-mesh-compatibility.md)。
- 九个主执行器:5 个臂位置伺服、夹爪位置伺服、3 个轮速度伺服;另外 36 个滚子 hinge **不加电机**。仅通过物理接触驱动车体,不强写底盘位姿/速度。
- CAD +Y 朝前,在 canonical 基座中旋转 -90°。简化三轮按理想 0.125 m 轮距、0.05 m 半径布置;并非沿用 CAD 不等距的轮轴位置。
- 原始 CAD 的 17.324 kg 惯性估计不用于动力学。仿真采用 2.2 kg 基座、按 profile 给出的臂段/轮质量、简化碰撞和保守限位。惯性、摩擦、增益均为**仿真估计**,不代表实体标定。
- 当前碰撞配方为 **revision 4**:从整臂 18 个原始视觉网格(含固定舵机/附件)离线 CoACD 分解成 538 个凸包,再按轴承配合区切分成 1,220 个独立碰撞凸包,替代旧臂胶囊和手工分段。保持视觉坐标变换、夹爪空隙、零附加碰撞质量与显式惯性。工具隔离在 `build/venvs/collision`,浏览器仅使用生成数据。来源、许可证、缓存/参数和重建方法见 [碰撞数据说明](../../robot_profiles/NOTICE.md)。
- 不再整对排除相邻连杆:显式启用 5,581 对结构凸包接触,包括 `SO_ARM100_08k_Mirror-v1` / `SO_ARM100_08k_116_Square-v1`。跨区域凸包先切分,只对完全落入关节轴承/舵机配合区域的部分保留局部例外,以免装配重叠锁死关节;非相邻碰撞保持启用。细化为 1 ms 物理步长,未放宽 500 ms 安全阈值。凸分解仍有误差,不等于逐三角形精确碰撞或所有姿态无穿入保证。
- 自碰撞会阻挡不可能到达的目标,动作确认值不等于实测关节角;遇阻时目标/实测不一致是正常反馈。这不是自动避障或无碰撞路径规划,也没有关闭全臂自碰撞、缩小肩关节范围来隐藏问题。
- CAD 夹爪轴已反向,使开度增大确实张开;内部关节范围为 -0.18…0.9 rad,LeRobot 的 0–100 开度接口不变。当前配方闭合端测试间隙约 1.47 mm,另有指面间接触保护;不会通过关闭自碰撞来允许两指交叉。
- 平地低速控制、静态障碍阻挡和夹爪指尖/物体接触经过真实浏览器 WASM 验证;不保证崎岖地形、可靠抓取、相机、训练或 sim-to-real 策略迁移。MuJoCo 使用软接触,受力时允许小量穿入,瞬态大小取决于速度/载荷;这与缺少碰撞体导致整体穿过不同,高速/薄物体也不属于已验证范围。
### 更新碰撞体后必须重新转换模型
1. 退出 Python 控制脚本,停止外控;刷新前端页面加载新代码。
2. **重新导入 `build/lekiwi/lekiwi-v1.zip` 中的原始 URDF**,显式选择 **LeKiwi v1(仿真专用)**,重新“转换并加载”。源 ZIP 没变,不必重新下载;不要继续使用旧的已转换 MJCF/缓存模型。旧 MJCF 会提示从原始 URDF 重新转换。
3. 在检查器勾选“显示碰撞几何”,可查看橙色凸包,确认覆盖两侧指尖、臂座、`Square`、`Mirror`、其他臂段和固定附件;此开关仅影响显示,不开关物理碰撞。
4. 重新连接桥接、播放并允许外部控制,再启动键盘脚本。`v` 张开、`b` 闭合;可以先用 `--gripper-speed 25` 低速检查。
### 网页关节滑条不是物理运动
旧关节滑条是暂停后直接写 `qpos` 的姿态编辑器,会绕过物理积分,碰撞体不能阻止这种“瞬移”。现在启用机器人 profile 时,**关节角只读、禁用关节拖动/单独重置关节、禁止直接位姿写入和忽略关节限位**;要运动请播放后调整“执行器”目标,或使用键盘/外控。普通非 profile 模型仍保留原姿态编辑功能。“重置仿真”仍可用,并保留撤销外控和 epoch 更新。外控期间继续禁止手动执行器写入。
## 完整演示
从仓库根目录执行:
```bash
source .venv/bin/activate # Python 3.12
python -m pip install -e ./control_bridge
python examples/lekiwi/setup_lerobot.py # 固定 CPU 依赖,仅写 build/venvs/lerobot/
npm ci
npm run dev
```
1. 将 `build/lekiwi/lekiwi-v1.zip` 导入工作台,在 URDF 对话框显式选择 **LeKiwi v1(仿真专用)**,点击“转换并加载”。若已导入可兼容 MJCF,在“控制台 → 开源项目 / 外部控制”选择 profile 并重新编译。
2. 另一终端用 `.venv/bin/python -m mujoco_control_bridge` 启动本机服务。复制启动时显示的 token,在工作台填入 `http://127.0.0.1:8766` 和 token,点击“连接桥接”。
3. 点击“播放”,再点击“允许外部控制”。外控锁定 1×;手动关节/执行器写入不可用,原 Python/ONNX 停止。
4. 第三个终端设置同一 token,运行真正的 LeRobot 插件示例:
```bash
read -rsp '控制 token: ' MUJOCO_CONTROL_TOKEN; echo
export MUJOCO_CONTROL_TOKEN
export MUJOCO_CONTROL_ENDPOINT=http://127.0.0.1:8766
env -u PYTHONPATH PYTHONNOUSERSITE=1 build/venvs/lerobot/bin/python \
examples/lekiwi/demo_control.py --duration 60
```
脚本保留“读状态 → 合成动作 → 发送 → 节拍等待”的上游 30 Hz 循环形状,九个通道一起运动,输出确认目标、实测反馈、时间和延迟统计。不运行硬件构造函数,不初始化串口/相机/GPU。
脚本退出会自动暂停。重新演示必须再次播放并授权;重置、模型重载、页面隐藏/退出、控制进程崩溃和超时也不会自动恢复。
键盘演示(包括从 `demo_control.py` 切换过来)必须再次完成 **播放 → 允许外部控制 → 启动脚本**。授权不会自动播放;确认按钮已变为“暂停”、外控状态为“等待 Python 控制者”,再执行:
```bash
env -u PYTHONPATH PYTHONNOUSERSITE=1 build/venvs/lerobot/bin/python \
examples/lekiwi/teleoperate_sim.py
```
### 底盘 + 机械臂键盘控制
原 LeKiwi 仓库主要提供硬件/CAD/URDF,其 README 的遥操作方案是 **WASD + leader arm**:键盘控制底盘,SO-ARM leader 的六路位置控制从臂。当前仿真已经实现五个臂关节和夹爪的执行器、单位换算与反馈;这里用键盘关节点动替代实体 leader,无需安装硬件驱动或更换桥接;但更新碰撞配方仍须按上文重新转换模型。
在运行脚本的 Linux 交互终端使用小写按键:
| 按键 | 功能 | LeRobot 动作通道 |
| -------------- | ---------------------------------------------- | ----------------------- |
| `w / s` | 底盘前进 / 后退 | `x.vel` |
| `a / d` | 底盘左移 / 右移 | `y.vel` |
| `z / x` | 底盘左转 / 右转 | `theta.vel` |
| `r / f` | 底盘速度升档 / 降档(不改变臂速度) | — |
| `u / j` | 肩部旋转角增大 / 减小 | `arm_shoulder_pan.pos` |
| `i / k` | 肩部俯仰角增大 / 减小 | `arm_shoulder_lift.pos` |
| `o / l` | 肘部角度增大 / 减小 | `arm_elbow_flex.pos` |
| `t / g` | 腕部俯仰角增大 / 减小 | `arm_wrist_flex.pos` |
| `y / h` | 腕部旋转角增大 / 减小 | `arm_wrist_roll.pos` |
| `v / b` | 夹爪张开 / 闭合 | `arm_gripper.pos` |
| 空格 | 清除按键脉冲,底盘停止、机械臂保持最后确认目标 | — |
| `q` / `Ctrl+C` | 退出、释放控制权并暂停仿真 | — |
- 臂按键是**关节空间点动**,不是末端 XYZ/逆运动学控制。五个关节使用度,夹爪使用 0–100 开度;角度正负不代表相机画面中的上下左右。
- 初始目标来自实测姿态,不会启动即归零。每轮 30 Hz 将底盘速度与臂增量合成一条动作;关节/夹爪限幅由现有 profile 执行,下一轮从**确认后的目标**累加,避免到限位后积累不可见的超限目标。
- 默认臂速度为 20 度/秒、夹爪速度为 50 百分点/秒,可用下列参数调慢(上限分别为 90 和 100,必须大于零)。控制循环卡顿不会补发大幅角度跳变。
```bash
env -u PYTHONPATH PYTHONNOUSERSITE=1 build/venvs/lerobot/bin/python \
examples/lekiwi/teleoperate_sim.py --arm-speed 5 --gripper-speed 25
```
终端输入是 **180 ms 脉冲**,不是系统级按下/松开监听;点按为小步调整,长按依赖系统键盘重复,组合键只是重叠脉冲。脉冲过期后底盘速度归零、机械臂保持最后确认目标,脚本仍持续发送动作。空格不会退出授权,也不会将机械臂归零;真正停止仿真请按 `q` 或在页面停止外控。请并排显示浏览器和终端,保持仿真页面可见;隐藏/最小化页面会撤销授权。
底盘和机械臂必须由**同一个控制循环**合成动作,不能分别启动两个 Python 控制者;外控期间也不能同时用网页执行器滑条写入。碰到其他臂段/安装板后不会继续到达目标;完整 CAD 下可用运动范围可能比声明的关节上下限窄,遇阻应反向点动,而不是扩大限位或禁用碰撞。
### 后续接实体 leader 的接入点
若要复用上游 SO100/SO101 leader,保留 `lekiwi_sim` 作为被控机器人,只替换机械臂输入源:在 leader 已连接、完成硬件校准且 `use_degrees=True` 的前提下,将 `leader.get_action()` 的 `shoulder_pan.pos` 等六路键名加 `arm_` 前缀,再与底盘动作合并后调用同一个 `robot.send_action()`。不要启动实体 LeKiwi follower/ZMQ 服务,也不要把归一化的 -100…100 臂角当成度。
这只是接口接入说明,当前终端脚本未实现串口 leader 模式,也未做硬件验证;接入前还需核对真实 leader 与仿真 profile 的零位/方向、限位和每步速度限制。当前模型不保证可靠抓取或 sim-to-real 一致性。
## 连接时提示“机器人观测超过 500ms 未更新”
这表示本机桥接可访问,但未收到浏览器端新的机器人观测;不是 LeRobot 安装或 Python 导入错误。桥接连接成功不等于仿真正在运行。
1. 将浏览器和终端并排显示,保持仿真页面可见,不要切换到其他浏览器标签、最小化或完全遮住仿真窗口。页面隐藏会撤销授权;若显示“未连接”,先重新连接桥接。
2. 查看“机器人观测状态”。若显示“已暂停(非实时观测)”或播放按钮仍为“播放”,先点击 **播放**,再点击 **允许外部控制**。前一个脚本退出、停止外控或超时后都会暂停,不能只重新运行 Python。
3. 确认仿真时间持续增加、观测年龄低于 500 ms,状态显示“等待 Python 控制者”,然后在终端重跑脚本。等待 Python 连接本身没有 500 ms 倒计时;这个阈值检查的是观测新鲜度,取得租约后还会检查动作是否持续更新。
4. 若正在播放且页面可见时观测仍持续过期,检查页面错误和主线程卡顿;必要时重新加载模型并连接、播放、授权。不要通过增大 SDK HTTP 超时来绕过:HTTP 超时与 500 ms 观测/动作安全看门狗是两回事。
旧版桥接会将暂停超过 500 ms 也报成“观测过期”;修复后会明确提示“仿真已暂停;请先在浏览器点击‘播放’,再点击‘允许外部控制’”。更新代码后需重启 `python -m mujoco_control_bridge`,并在页面重新连接、播放、授权;若服务生成了新 token,请同时更新浏览器和终端中的 token。
## 回归和证据
```bash
source .venv/bin/activate
npm run test:control-bridge
build/venvs/lerobot/bin/python -m unittest discover -s integrations/lerobot/tests -v
LEROBOT_PYTHON="$PWD/build/venvs/lerobot/bin/python" npm run test:e2e:lekiwi
# 仅物理测试(不需 LeRobot)
npx playwright test -c web_platform/playwright.lekiwi.config.ts lekiwi.physics.spec.ts lekiwi.gripper.spec.ts lekiwi.armCollision.spec.ts lekiwi.fullCollision.spec.ts
```
专用套件不是 mock:整臂 18 个视觉网格的 108 次独立 CAD 表面接触探针,六关节各两个有界目标扫掠,`Mirror/Square` 主体接触阻挡/脱离及禁止直接 `qpos` 写入;真实 WASM 3.11.0 的 30 仿真秒站稳、正负三轴运动、臂/夹爪、墙体阻挡、两侧 CAD 指尖探针接触、开度与实际指间距同向、张开空隙不误碰撞、闭合被物体阻挡以及指面自碰撞、上臂下压时与自身臂座组件的真实接触/穿入量及反向脱离(完整模型中安装板或肩部结构夹片先于底座本体接触);真实 Python/LeRobot、PTY 终端底盘 + 六路臂/夹爪正反点动、无输入保持与退出撤权、完整工作台文件导入→编译→授权→60 秒控制;另含旧控制回调、reset、新 epoch、崩溃、重载/回滚、隐藏和 JS 冻结恢复。
`build/e2e/lekiwi/` 保存 XML、物理轨迹、60 秒 JSON(RTT、新鲜度、FPS/步进预算、JS/WASM 堆容量)和截图。普通 E2E 不下载资产或安装 LeRobot;专用 CI 缺依赖即失败,不静默跳过。
软件 WebGL 比物理计算慢:外控物理/传输独立调度;检测到 SwiftShader 等软件渲染时关闭阴影、3D 显示上限 5 FPS,观测仍约 30 Hz。不能把此模式当作锁步 RL 或硬实时系统。性能实测、兼容矩阵和限制见 [机器人接口](../../docs/robot-interface.md)。