Skip to content

Commit c53a82e

Browse files
committed
Add bi yam arms implementation
1 parent d1548e1 commit c53a82e

File tree

12 files changed

+1169
-0
lines changed

12 files changed

+1169
-0
lines changed

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ intelrealsense = [
114114
"pyrealsense2-macosx>=2.54,<2.55.0 ; sys_platform == 'darwin'",
115115
]
116116
phone = ["hebi-py>=2.8.0,<2.12.0", "teleop>=0.1.0,<0.2.0", "fastapi<1.0"]
117+
yam = [
118+
"i2rt>=0.0.1",
119+
"portal>=3.7.0,<4.0.0",
120+
]
117121

118122
# Policies
119123
pi = ["transformers @ git+https://github.com/huggingface/transformers.git@fix/lerobot_openpi"]
@@ -154,6 +158,7 @@ all = [
154158
"lerobot[reachy2]",
155159
"lerobot[kinematics]",
156160
"lerobot[intelrealsense]",
161+
"lerobot[yam]",
157162
"lerobot[pi]",
158163
"lerobot[smolvla]",
159164
# "lerobot[groot]", TODO(Steven): Gr00t requires specific installation instructions for flash-attn

src/lerobot/robots/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
from . import bi_yam_follower
1718
from .config import RobotConfig
1819
from .robot import Robot
1920
from .utils import make_robot_from_config
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Bimanual Yam Arms with LeRobot
2+
3+
This guide explains how to use bimanual Yam arms with LeRobot for data collection.
4+
5+
## Overview
6+
7+
The bimanual Yam setup consists of:
8+
- **2 Follower Arms**: Controlled by LeRobot to execute actions
9+
- **2 Leader Arms**: With teaching handles for teleoperation
10+
- **4 CAN Interfaces**: For communication with the arms
11+
12+
## Hardware Setup
13+
14+
### Required CAN Interfaces
15+
16+
You need to set up 4 CAN interfaces with the following names:
17+
- `can_follower_r`: Right follower arm
18+
- `can_follower_l`: Left follower arm
19+
- `can_leader_r`: Right leader arm (with teaching handle)
20+
- `can_leader_l`: Left leader arm (with teaching handle)
21+
22+
### CAN Interface Configuration
23+
24+
For details on setting up persistent CAN interface names, see:
25+
- `i2rt/doc/set_persist_id_socket_can.md`
26+
27+
Make sure all CAN interfaces are UP and accessible:
28+
```bash
29+
ip link show can_follower_r
30+
ip link show can_follower_l
31+
ip link show can_leader_r
32+
ip link show can_leader_l
33+
```
34+
35+
## Software Setup
36+
37+
### Install Dependencies
38+
39+
Install LeRobot with Yam support:
40+
```bash
41+
pip install -e ".[yam]"
42+
```
43+
44+
This will install:
45+
- `portal` library for client-server communication
46+
- `i2rt` library for low-level motor control of Yam arms
47+
48+
**Note**: If `i2rt` is not available on PyPI, you may need to install it separately from source:
49+
```bash
50+
pip install git+https://github.com/your-org/i2rt.git
51+
# OR from a local clone:
52+
# cd /path/to/i2rt && pip install -e .
53+
```
54+
55+
## Running the System
56+
57+
### Step 1: Start the Server Processes
58+
59+
Before using LeRobot, you need to start the server processes that manage the Yam arms:
60+
61+
```bash
62+
python -m lerobot.scripts.setup_bi_yam_servers
63+
```
64+
65+
This will start 4 server processes:
66+
- Right follower arm server: `localhost:1234`
67+
- Left follower arm server: `localhost:1235`
68+
- Right leader arm server: `localhost:5001`
69+
- Left leader arm server: `localhost:5002`
70+
71+
Leave this running in a terminal window.
72+
73+
### Step 2: Record Data with LeRobot
74+
75+
In a new terminal, use `lerobot-record` to collect data:
76+
77+
```bash
78+
lerobot-record \
79+
--robot.type=bi_yam_follower \
80+
--robot.left_arm_port=1235 \
81+
--robot.right_arm_port=1234 \
82+
--robot.cameras='{
83+
left: {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30},
84+
top: {"type": "opencv", "index_or_path": 1, "width": 640, "height": 480, "fps": 30},
85+
right: {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30}
86+
}' \
87+
--teleop.type=bi_yam_leader \
88+
--teleop.left_arm_port=5002 \
89+
--teleop.right_arm_port=5001 \
90+
--dataset.repo_id=${HF_USER}/bimanual-yam-demo \
91+
--dataset.num_episodes=10 \
92+
--dataset.single_task="Pick and place the object" \
93+
--display_data=true
94+
```
95+
96+
### Configuration Parameters
97+
98+
#### Robot Configuration (`bi_yam_follower`)
99+
100+
- `robot.type`: Set to `bi_yam_follower`
101+
- `robot.left_arm_port`: Server port for left follower arm (default: 1235)
102+
- `robot.right_arm_port`: Server port for right follower arm (default: 1234)
103+
- `robot.server_host`: Server hostname (default: "localhost")
104+
- `robot.cameras`: Camera configurations (same as other robots)
105+
- `robot.left_arm_max_relative_target`: Optional safety limit for left arm
106+
- `robot.right_arm_max_relative_target`: Optional safety limit for right arm
107+
108+
#### Teleoperator Configuration (`bi_yam_leader`)
109+
110+
- `teleop.type`: Set to `bi_yam_leader`
111+
- `teleop.left_arm_port`: Server port for left leader arm (default: 5002)
112+
- `teleop.right_arm_port`: Server port for right leader arm (default: 5001)
113+
- `teleop.server_host`: Server hostname (default: "localhost")
114+
115+
## Architecture
116+
117+
### Data Flow
118+
119+
```
120+
┌─────────────────┐ ┌─────────────────┐
121+
│ Leader Arms │ │ Follower Arms │
122+
│ (Teaching │ │ (Execution) │
123+
│ Handles) │ │ │
124+
└────────┬────────┘ └────────▲────────┘
125+
│ │
126+
│ Read State │ Send Actions
127+
│ │
128+
┌────▼────┐ ┌───────┴─────┐
129+
│ Leader │ │ Follower │
130+
│ Servers │ │ Servers │
131+
│ (5001, │ │ (1234, │
132+
│ 5002) │ │ 1235) │
133+
└────┬────┘ └───────▲─────┘
134+
│ │
135+
│ │
136+
┌────▼────────────────────────────┴─────┐
137+
│ LeRobot Recording │
138+
│ - bi_yam_leader (teleoperator) │
139+
│ - bi_yam_follower (robot) │
140+
│ - Cameras │
141+
│ - Dataset writer │
142+
└───────────────────────────────────────┘
143+
```
144+
145+
### Server Process Details
146+
147+
Each server process (started by `setup_bi_yam_servers.py`) runs a separate instance of the i2rt `minimum_gello.py` script in "follower" mode. This mode:
148+
1. Connects to the Yam arm via CAN
149+
2. Provides gravity compensation
150+
3. Exposes the robot state via a portal RPC server
151+
4. Accepts position commands (for follower arms) or just reads state (for leader arms)
152+
153+
## Troubleshooting
154+
155+
### CAN Interface Issues
156+
157+
If you get errors about missing CAN interfaces:
158+
```bash
159+
# Check if interfaces exist
160+
ip link show | grep can
161+
162+
# Bring up an interface if it's down
163+
sudo ip link set can_follower_r up
164+
```
165+
166+
### Port Already in Use
167+
168+
If you get "address already in use" errors:
169+
```bash
170+
# Find and kill processes using the ports
171+
lsof -ti:1234 | xargs kill -9
172+
lsof -ti:1235 | xargs kill -9
173+
lsof -ti:5001 | xargs kill -9
174+
lsof -ti:5002 | xargs kill -9
175+
```
176+
177+
### Connection Timeouts
178+
179+
If LeRobot can't connect to the servers:
180+
1. Make sure `setup_bi_yam_servers.py` is running
181+
2. Check that all 4 servers started successfully
182+
3. Verify the port numbers match in both scripts
183+
184+
### Slow Control Loop
185+
186+
If you see warnings about slow control frequency:
187+
- This usually means the system is overloaded
188+
- Try reducing camera resolution or FPS
189+
- Check CPU usage and close unnecessary applications
190+
191+
## Advanced Usage
192+
193+
### Custom Server Ports
194+
195+
You can run the servers on different ports by modifying the `setup_bi_yam_servers.py` script or running the i2rt `minimum_gello.py` script directly for each arm:
196+
197+
```bash
198+
# Find the i2rt script location
199+
python -c "import i2rt, os; print(os.path.dirname(i2rt.__file__))"
200+
201+
# Right follower
202+
python -m i2rt.scripts.minimum_gello \
203+
--can_channel can_follower_r \
204+
--gripper linear_4310 \
205+
--mode follower \
206+
--server_port 1234 &
207+
208+
# Left follower
209+
python -m i2rt.scripts.minimum_gello \
210+
--can_channel can_follower_l \
211+
--gripper linear_4310 \
212+
--mode follower \
213+
--server_port 1235 &
214+
215+
# Right leader
216+
python -m i2rt.scripts.minimum_gello \
217+
--can_channel can_leader_r \
218+
--gripper yam_teaching_handle \
219+
--mode follower \
220+
--server_port 5001 &
221+
222+
# Left leader
223+
python -m i2rt.scripts.minimum_gello \
224+
--can_channel can_leader_l \
225+
--gripper yam_teaching_handle \
226+
--mode follower \
227+
--server_port 5002 &
228+
```
229+
230+
### Without Teleoperation
231+
232+
You can also use the bimanual Yam follower arms with a trained policy (without teleop):
233+
234+
```bash
235+
lerobot-record \
236+
--robot.type=bi_yam_follower \
237+
--robot.left_arm_port=1235 \
238+
--robot.right_arm_port=1234 \
239+
--robot.cameras='{...}' \
240+
--policy.path=path/to/trained/policy \
241+
--dataset.repo_id=${HF_USER}/bimanual-yam-eval \
242+
--dataset.num_episodes=5
243+
```
244+
245+
## References
246+
247+
- i2rt library: Python library for controlling Yam arm hardware (install via `pip install -e '.[yam]'`)
248+
- LeRobot documentation: See main docs for training and evaluation workflows
249+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 The HuggingFace Inc. team. All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from .bi_yam_follower import BiYamFollower
18+
from .config_bi_yam_follower import BiYamFollowerConfig
19+

0 commit comments

Comments
 (0)