|
| 1 | +# Reachy 2 |
| 2 | + |
| 3 | +Reachy 2 is an open-source humanoid robot made by Pollen Robotics, specifically designed for the development of embodied AI and real-world applications. |
| 4 | +Check out [Pollen Robotics website](https://www.pollen-robotics.com/reachy/), or access [Reachy 2 documentation](https://docs.pollen-robotics.com/) for more information on the platform! |
| 5 | + |
| 6 | +## Teleoperate Reachy 2 |
| 7 | + |
| 8 | +Currently, there are two ways to teleoperate Reachy 2: |
| 9 | + |
| 10 | +- Pollen Robotics’ VR teleoperation (not included in LeRobot). |
| 11 | +- Robot-to-robot teleoperation (use one Reachy 2 to control another). |
| 12 | + |
| 13 | +## Reachy 2 Simulation |
| 14 | + |
| 15 | +**(Linux only)** You can run Reachy 2 in simulation (Gazebo or MuJoCo) using the provided [Docker image](https://hub.docker.com/r/pollenrobotics/reachy2_core). |
| 16 | + |
| 17 | +1. Install [Docker Engine](https://docs.docker.com/engine/). |
| 18 | +2. Run (for MuJoCo): |
| 19 | + |
| 20 | +``` |
| 21 | +docker run --rm -it \ |
| 22 | + --name reachy \ |
| 23 | + --privileged \ |
| 24 | + --network host \ |
| 25 | + --ipc host \ |
| 26 | + --device-cgroup-rule='c 189:* rwm' \ |
| 27 | + --group-add audio \ |
| 28 | + -e ROS_DOMAIN_ID="$ROS_DOMAIN_ID" \ |
| 29 | + -e DISPLAY="$DISPLAY" \ |
| 30 | + -e RCUTILS_CONSOLE_OUTPUT_FORMAT="[{severity}]: {message}" \ |
| 31 | + -e REACHY2_CORE_SERVICE_FAKE="${REACHY2_CORE_SERVICE_FAKE:-true}" \ |
| 32 | + -v /dev:/dev \ |
| 33 | + -v "$HOME/.reachy_config":/home/reachy/.reachy_config_override \ |
| 34 | + -v "$HOME/.reachy.log":/home/reachy/.ros/log \ |
| 35 | + -v /usr/lib/x86_64-linux-gnu:/opt/host-libs \ |
| 36 | + --entrypoint /package/launch.sh \ |
| 37 | + pollenrobotics/reachy2_core:1.7.5.9_deploy \ |
| 38 | + start_rviz:=true start_sdk_server:=true mujoco:=true |
| 39 | +``` |
| 40 | + |
| 41 | +> If MuJoCo runs slowly (low simulation frequency), append `-e LD_LIBRARY_PATH="/opt/host-libs:$LD_LIBRARY_PATH" \` to the previous command to improve performance: |
| 42 | +> |
| 43 | +> ``` |
| 44 | +> docker run --rm -it \ |
| 45 | +> --name reachy \ |
| 46 | +> --privileged \ |
| 47 | +> --network host \ |
| 48 | +> --ipc host \ |
| 49 | +> --device-cgroup-rule='c 189:* rwm' \ |
| 50 | +> --group-add audio \ |
| 51 | +> -e ROS_DOMAIN_ID="$ROS_DOMAIN_ID" \ |
| 52 | +> -e DISPLAY="$DISPLAY" \ |
| 53 | +> -e RCUTILS_CONSOLE_OUTPUT_FORMAT="[{severity}]: {message}" \ |
| 54 | +> -e REACHY2_CORE_SERVICE_FAKE="${REACHY2_CORE_SERVICE_FAKE:-true}" \ |
| 55 | +> -e LD_LIBRARY_PATH="/opt/host-libs:$LD_LIBRARY_PATH" \ |
| 56 | +> -v /dev:/dev \ |
| 57 | +> -v "$HOME/.reachy_config":/home/reachy/.reachy_config_override \ |
| 58 | +> -v "$HOME/.reachy.log":/home/reachy/.ros/log \ |
| 59 | +> -v /usr/lib/x86_64-linux-gnu:/opt/host-libs \ |
| 60 | +> --entrypoint /package/launch.sh \ |
| 61 | +> pollenrobotics/reachy2_core:1.7.5.9_deploy \ |
| 62 | +> start_rviz:=true start_sdk_server:=true mujoco:=true |
| 63 | +> ``` |
| 64 | +
|
| 65 | +## Setup |
| 66 | +
|
| 67 | +### Prerequisites |
| 68 | +
|
| 69 | +- On your robot, check the **service images** meet the minimum versions: |
| 70 | + - **reachy2-core >= 1.7.5.2** |
| 71 | + - **webrtc >= 2.0.1.1** |
| 72 | +
|
| 73 | +Then, if you want to use VR teleoperation: |
| 74 | +
|
| 75 | +- Install the [Reachy 2 teleoperation application](https://docs.pollen-robotics.com/teleoperation/teleoperation-introduction/discover-teleoperation/). |
| 76 | + Use version **>=v1.2.0** |
| 77 | +
|
| 78 | +We recommend using two computers: one for teleoperation (Windows required) and another for recording with LeRobot. |
| 79 | +
|
| 80 | +### Install LeRobot |
| 81 | +
|
| 82 | +Follow the [installation instructions](https://github.com/huggingface/lerobot#installation) to install LeRobot. |
| 83 | +
|
| 84 | +Install LeRobot with Reachy 2 dependencies: |
| 85 | +
|
| 86 | +```bash |
| 87 | +pip install -e ".[reachy2]" |
| 88 | +``` |
| 89 | +
|
| 90 | +### (Optional but recommended) Install pollen_data_acquisition_server |
| 91 | + |
| 92 | +How you manage Reachy 2 recording sessions is up to you, but the **easiest** way is to use this server so you can control sessions directly from the VR teleoperation app. |
| 93 | + |
| 94 | +> **Note:** Currently, only the VR teleoperation application works as a client for this server, so this step primarily targets teleoperation. You’re free to develop custom clients to manage sessions to your needs. |
| 95 | +
|
| 96 | +In your LeRobot environment, install the server from source: |
| 97 | + |
| 98 | +```bash |
| 99 | +git clone https://github.com/pollen-robotics/pollen_data_acquisition_server.git |
| 100 | +cd pollen_data_acquisition_server |
| 101 | +pip install -e . |
| 102 | +``` |
| 103 | + |
| 104 | +Find the [pollen_data_acquisition_server documentation here](https://github.com/pollen-robotics/pollen_data_acquisition_server). |
| 105 | + |
| 106 | +## Step 1: Recording |
| 107 | + |
| 108 | +### Get Reachy 2 IP address |
| 109 | + |
| 110 | +Before starting teleoperation and data recording, find the [robot's IP address](https://docs.pollen-robotics.com/getting-started/setup-reachy2/connect-reachy2/). |
| 111 | +We strongly recommend connecting all devices (PC and robot) via **Ethernet**. |
| 112 | + |
| 113 | +### Launch recording |
| 114 | + |
| 115 | +There are two ways to manage recording sessions when using the Reachy 2 VR teleoperation application: |
| 116 | + |
| 117 | +- **Using the data acquisition server (recommended for VR teleop)**: The VR app orchestrates sessions (via the server it tells LeRobot when to create datasets, start/stop episodes) while also controlling the robot’s motions. |
| 118 | +- **Using LeRobot’s record script**: LeRobot owns session control and decides when to start/stop episodes. If you also use the VR teleop app, it’s only for motion control. |
| 119 | + |
| 120 | +### Option 1: Using Pollen data acquisition server (recommended for VR teleop) |
| 121 | + |
| 122 | +Make sure you have installed pollen_data_acquisition_server, as explained in the Setup section. |
| 123 | + |
| 124 | +Launch the data acquisition server to be able to manage your session directly from the teleoperation application: |
| 125 | + |
| 126 | +```bash |
| 127 | +python -m pollen_data_acquisition_server.server |
| 128 | +``` |
| 129 | + |
| 130 | +Then get into the teleoperation application and choose "Data acquisition session". |
| 131 | +You can finally setup your session by following the screens displayed. |
| 132 | + |
| 133 | +> Even without the VR app, you can use the `pollen_data_acquisition_server` with your own client implementation. |
| 134 | +
|
| 135 | +### Option 2: Using lerobot.record |
| 136 | + |
| 137 | +Reachy 2 is fully supported by LeRobot’s recording features. |
| 138 | +If you choose this option but still want to use the VR teleoperation application, select "Standard session" in the app. |
| 139 | + |
| 140 | +**Example: start a recording without the mobile base:** |
| 141 | +First add reachy2 and reachy2_teleoperator to the imports of the record script. Then you can use the following command: |
| 142 | + |
| 143 | +```bash |
| 144 | +python -m lerobot.record \ |
| 145 | + --robot.type=reachy2 \ |
| 146 | + --robot.ip_address=192.168.0.200 \ |
| 147 | + --robot.id=r2-0000 \ |
| 148 | + --robot.use_external_commands=true \ |
| 149 | + --robot.with_mobile_base=false \ |
| 150 | + --teleop.type=reachy2_teleoperator \ |
| 151 | + --teleop.ip_address=192.168.0.200 \ |
| 152 | + --teleop.with_mobile_base=false \ |
| 153 | + --dataset.repo_id=pollen_robotics/record_test \ |
| 154 | + --dataset.single_task="Reachy 2 recording test" \ |
| 155 | + --dataset.num_episodes=1 \ |
| 156 | + --dataset.episode_time_s=5 \ |
| 157 | + --dataset.fps=15 \ |
| 158 | + --dataset.push_to_hub=true \ |
| 159 | + --dataset.private=true \ |
| 160 | + --display_data=true |
| 161 | +``` |
| 162 | + |
| 163 | +#### Specific Options |
| 164 | + |
| 165 | +**Extended setup overview (all options included):** |
| 166 | + |
| 167 | +```bash |
| 168 | +python -m lerobot.record \ |
| 169 | + --robot.type=reachy2 \ |
| 170 | + --robot.ip_address=192.168.0.200 \ |
| 171 | + --robot.use_external_commands=true \ |
| 172 | + --robot.with_mobile_base=true \ |
| 173 | + --robot.with_l_arm=true \ |
| 174 | + --robot.with_r_arm=true \ |
| 175 | + --robot.with_neck=true \ |
| 176 | + --robot.with_antennas=true \ |
| 177 | + --robot.with_left_teleop_camera=true \ |
| 178 | + --robot.with_right_teleop_camera=true \ |
| 179 | + --robot.with_torso_camera=false \ |
| 180 | + --robot.disable_torque_on_disconnect=false \ |
| 181 | + --robot.max_relative_target=5.0 \ |
| 182 | + --teleop.type=reachy2_teleoperator \ |
| 183 | + --teleop.ip_address=192.168.0.200 \ |
| 184 | + --teleop.use_present_position=false \ |
| 185 | + --teleop.with_mobile_base=false \ |
| 186 | + --teleop.with_l_arm=true \ |
| 187 | + --teleop.with_r_arm=true \ |
| 188 | + --teleop.with_neck=true \ |
| 189 | + --teleop.with_antennas=true \ |
| 190 | + --dataset.repo_id=pollen_robotics/record_test \ |
| 191 | + --dataset.single_task="Reachy 2 recording test" \ |
| 192 | + --dataset.num_episodes=1 \ |
| 193 | + --dataset.episode_time_s=5 \ |
| 194 | + --dataset.fps=15 \ |
| 195 | + --dataset.push_to_hub=true \ |
| 196 | + --dataset.private=true \ |
| 197 | + --display_data=true |
| 198 | +``` |
| 199 | + |
| 200 | +##### `--robot.use_external_commands` |
| 201 | + |
| 202 | +Determine whether LeRobot robot.send_action() sends commands to the robot. |
| 203 | +**Must** be set to false while using the VR teleoperation application, as the app already sends commands. |
| 204 | + |
| 205 | +##### `--teleop.use_present_position` |
| 206 | + |
| 207 | +Determine whether the teleoperator reads the goal or present position of the robot. |
| 208 | +Must be set to true if a compliant Reachy 2 is used to control another one. |
| 209 | + |
| 210 | +##### Use the relevant parts |
| 211 | + |
| 212 | +From our initial tests, recording **all** joints when only some are moving can reduce model quality with certain policies. |
| 213 | +To avoid this, you can exclude specific parts from recording and replay using: |
| 214 | + |
| 215 | +```` |
| 216 | +--robot.with_<part>=false |
| 217 | +```, |
| 218 | +with `<part>` being one of : `mobile_base`, `l_arm`, `r_arm", `neck`, `antennas`. |
| 219 | +It determine whether the corresponding part is recorded in the observations. True if not set. |
| 220 | +
|
| 221 | +By default, **all parts are recorded**. |
| 222 | +
|
| 223 | +The same per-part mechanism is available in `reachy2_teleoperator` as well. |
| 224 | +
|
| 225 | +```` |
| 226 | + |
| 227 | +--teleop.with\_<part> |
| 228 | + |
| 229 | +``` |
| 230 | +with `<part>` being one of : `mobile_base`, `l_arm`, `r_arm", `neck`, `antennas`. |
| 231 | +Determine whether the corresponding part is recorded in the actions. True if not set. |
| 232 | +
|
| 233 | +> **Important:** In a given session, the **enabled parts must match** on both the robot and the teleoperator. |
| 234 | +For example, if the robot runs with `--robot.with_mobile_base=false`, the teleoperator must disable the same part `--teleoperator.with_mobile_base=false`. |
| 235 | +
|
| 236 | +##### Use the relevant cameras |
| 237 | +
|
| 238 | +You can do the same for **cameras**. By default, only the **teleoperation cameras** are recorded (both `left_teleop_camera` and `right_teleop_camera`). Enable or disable each camera with: |
| 239 | +
|
| 240 | +``` |
| 241 | + |
| 242 | +--robot.with_left_teleop_camera=<true|false> |
| 243 | +--robot.with_right_teleop_camera=<true|false> |
| 244 | +--robot.with_torso_camera=<true|false> |
| 245 | + |
| 246 | +```` |
| 247 | + |
| 248 | + |
| 249 | +## Step 2: Replay |
| 250 | + |
| 251 | +Make sure the robot is configured with the same parts as the dataset: |
| 252 | + |
| 253 | +```bash |
| 254 | +python -m lerobot.replay \ |
| 255 | + --robot.type=reachy2 \ |
| 256 | + --robot.ip_address=192.168.0.200 \ |
| 257 | + --robot.use_external_commands=false \ |
| 258 | + --robot.with_mobile_base=false \ |
| 259 | + --dataset.repo_id=pollen_robotics/record_test \ |
| 260 | + --dataset.episode=0 |
| 261 | + --display_data=true |
| 262 | +```` |
| 263 | + |
| 264 | +## Step 3: Train |
| 265 | + |
| 266 | +```bash |
| 267 | +python -m lerobot.scripts.train \ |
| 268 | + --dataset.repo_id=pollen_robotics/record_test \ |
| 269 | + --policy.type=act \ |
| 270 | + --output_dir=outputs/train/reachy2_test \ |
| 271 | + --job_name=reachy2 \ |
| 272 | + --policy.device=mps \ |
| 273 | + --wandb.enable=true \ |
| 274 | + --policy.repo_id=pollen_robotics/record_test_policy |
| 275 | +``` |
| 276 | + |
| 277 | +## Step 4: Evaluate |
| 278 | + |
| 279 | +```bash |
| 280 | +python -m lerobot.record \ |
| 281 | + --robot.type=reachy2 \ |
| 282 | + --robot.ip_address=192.168.0.200 \ |
| 283 | + --display_data=false \ |
| 284 | + --dataset.repo_id=pollen_robotics/eval_record_test \ |
| 285 | + --dataset.single_task="Evaluate reachy2 policy" \ |
| 286 | + --dataset.num_episodes=10 \ |
| 287 | + --policy.path=outputs/train/reachy2_test/checkpoints/last/pretrained_model |
| 288 | +``` |
0 commit comments