# RoboMME

  The commands below run the simulator locally. To keep its dependencies away from your policy's, serve it instead with `lerobot-env-server --config_path=docker/sim/configs/robomme.yaml --sim.task= --docker=true`, where `` is the command's `--env.task`, and add `--env.server.endpoint=tcp/127.0.0.1:7448` to the command. A server runs the task it was started with (see [Simulation: local or served](./simulation)).

[RoboMME](https://robomme.github.io) 是一个基于 ManiSkill (SAPIEN) 构建的记忆增强型操作基准测试。它评估机器人在一个回合中保留和使用信息的能力，包括计数、物体恒存性、指代和模仿。

- 4 个记忆技能套件中的 **16 个任务**
- **1,600 个训练演示**（每个任务 100 个，其中 50 个用于验证，50 个用于测试）
- **数据集**：[`lerobot/robomme`](https://huggingface.co/datasets/lerobot/robomme) — LeRobot v3.0，10 fps 下的 768K 帧
- **模拟器**：ManiSkill / SAPIEN，Panda 机械臂，仅支持 Linux

![RoboMME benchmark tasks overview](https://cdn-thumbnails.huggingface.co/social-thumbnails/papers/2603.04639/gradient.png)

## 任务

| 套件                             | 任务                                                         |
| --------------------------------- | ------------------------------------------------------------- |
| **计数**（时间记忆）    | BinFill, PickXtimes, SwingXtimes, StopCube                    |
| **持久性**（空间记忆）   | VideoUnmask, VideoUnmaskSwap, ButtonUnmask, ButtonUnmaskSwap  |
| **参考**（对象内存）     | PickHighlight, VideoRepick, VideoPlaceButton, VideoPlaceOrder |
| **模仿**（程序性记忆） | MoveCube, InsertPeg, PatternLock, RouteStick                  |

## 安装

> RoboMME 需要 **Linux**（ManiSkill/SAPIEN 使用 Vulkan 渲染）。建议使用 Docker 以隔离依赖冲突。

### Native （Linux）

```bash
uv pip install --override <(printf 'gymnasium==0.29.1\nnumpy==1.26.4\n') \
  -e '.[smolvla,av-dep]' \
  'robomme @ git+https://github.com/RoboMME/robomme_benchmark.git@main'
```

> **依赖说明**：`mani-skill`（由 `robomme` 引入）固定了 `gymnasium==0.29.1` 和 `numpy<2.0.0`，这与 lerobot 的基础依赖 `numpy>=2.0.0` 冲突。因此 `robomme` 不是 pyproject 的 extra 依赖——请使用上述覆盖安装方式，或采用下方的 Docker 方案以完全避免冲突。

### Docker （推荐）

在独立的模拟器镜像中运行 RoboMME，使其 `numpy`/`gymnasium` 的版本固定策略与策略本身的版本固定策略互不冲突：

```bash
lerobot-env-server --config_path=docker/sim/configs/robomme.yaml --docker=true
```

然后使用 `--env.type=robomme --env.server.endpoint=tcp/127.0.0.1:7448` 进行评估（参见 [仿真：本地或托管](./simulation)）。

## 运行评估

### Default （单任务，单回合）

```bash
lerobot-eval \
    --policy.path=<your_policy_repo> \
    --env.type=robomme \
    --env.task=PickXtimes \
    --env.dataset_split=test \
    --env.task_ids=[0] \
    --eval.batch_size=1 \
    --eval.n_episodes=1
```

### 多任务评估

通过逗号分隔任务名称，可在一次运行中评估多个任务。使用 `task_ids` 来控制每个任务评估哪些 episode。建议：测试集每个任务评估 50 个 episode。

```bash
lerobot-eval \
    --policy.path=<your_policy_repo> \
    --env.type=robomme \
    --env.task=PickXtimes,BinFill,StopCube,MoveCube,InsertPeg \
    --env.dataset_split=test \
    --env.task_ids=[0,1,2,3,4,5,6,7,8,9] \
    --eval.batch_size=1 \
    --eval.n_episodes=50
```

### `env.type=robomme` 的主要 CLI 选项

| 选项               | 默认       | 描述                                        |
| -------------------- | ------------- | -------------------------------------------------- |
| `env.task`           | `PickXtimes`  | 上述 16 个任务名称中的任意一个（以逗号分隔）   |
| `env.dataset_split`  | `test`        | `train`、`val` 或 `test`                          |
| `env.action_space`   | `joint_angle` | `joint_angle`（8 维）或 `ee_pose`（7 维）             |
| `env.episode_length` | `300`         | 每集最大步数                              |
| `env.task_ids`       | `null`        | 要评估的剧集索引列表（null = `[0]`） |

## 数据集

数据集 [`lerobot/robomme`](https://huggingface.co/datasets/lerobot/robomme) 采用 **LeRobot v3.0 格式**，可以直接加载：

```python
from lerobot.datasets.lerobot_dataset import LeRobotDataset

dataset = LeRobotDataset("lerobot/robomme")
```

### 数据集特性

| 功能            | 形状         | 描述                     |
| ------------------ | ------------- | ------------------------------- |
| `image`            | (256, 256, 3) | 前置摄像头 RGB                |
| `wrist_image`      | (256, 256, 3) | 手腕相机 RGB                |
| `actions`          | (8,)          | 关节角度 + 夹爪          |
| `state`            | (8,)          | 关节位置 + 夹爪状态 |
| `simple_subgoal`   | str           | 高级语言注释  |
| `grounded_subgoal` | str           | 基于实体的语言标注    |
| `episode_index`    | int           | 剧集 ID                      |
| `frame_index`      | int           | Episode 内的帧            |

### 特征键对齐（训练）

env 包装器将其摄像头暴露在 `pixels/<camera_name>` 下，名称由 `RoboMMEEnvConfig.front_camera_name` 和 `RoboMMEEnvConfig.wrist_camera_name` 指定（默认为 `camera1` 和 `camera2`）。策略将它们接收为 `observation.images.camera1` 和 `observation.images.camera2`，并将状态（`agent_pos`）接收为 `observation.state`。

数据集的原始列与这些策略键不匹配，因此在微调时请传入 `--rename_map`：

```bash
--rename_map='{"image": "observation.images.camera1", "wrist_image": "observation.images.camera2", "state": "observation.state", "actions": "action"}'
```

如果您针对不同的键名进行训练，请覆盖 `--env.front_camera_name` / `--env.wrist_camera_name`，以确保评估时的观测值与策略训练时使用的键名一致。

## 动作空间

| 类型          | 维度 | 描述                                               |
| ------------- | --- | --------------------------------------------------------- |
| `joint_angle` | 8   | 7 个关节角度 + 1 个夹爪（-1 为闭合，+1 为张开，绝对值） |
| `ee_pose`     | 7   | xyz + 横滚/俯仰/偏航 + 夹爪                            |

通过 `--env.action_space=joint_angle`（默认值）或 `--env.action_space=ee_pose` 设置。

## 平台说明

- **仅限 Linux**：ManiSkill 需要 SAPIEN/Vulkan。不支持 macOS 和 Windows。
- **建议使用 GPU**：渲染功能支持 CPU，但速度较慢；使用 CUDA + Vulkan 可获得完整速度。
- **gymnasium / numpy 冲突**：请参阅上方的安装说明。Docker 镜像会自动处理此问题。
- **ManiSkill 分支**：`robomme` 依赖于特定的 ManiSkill 分支（`YinpeiDai/ManiSkill`），通过 `robomme` 包自动引入。

