Skip to content

Commit a9f4cfe

Browse files
jbcayroupkooij
authored andcommitted
docs: Fix the SO-100 documentation, the motors configuration step should be before the assembly instructions (#1315)
Co-authored-by: Pepijn <[email protected]>
1 parent 76ec715 commit a9f4cfe

File tree

1 file changed

+160
-157
lines changed
  • lerobot/common/robots/so100_follower

1 file changed

+160
-157
lines changed

lerobot/common/robots/so100_follower/so100.mdx

Lines changed: 160 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,166 @@ In addition to these instructions, you need to install the Feetech SDK:
1515
pip install -e ".[feetech]"
1616
```
1717

18+
## Configure the motors
19+
20+
**Note:**
21+
Unlike the SO-101, the motor connectors are not easily accessible once the arm is assembled, so the configuration step must be done beforehand.
22+
23+
### 1. Find the USB ports associated with each arm
24+
25+
To find the port for each bus servo adapter, run this script:
26+
```bash
27+
python lerobot/find_port.py
28+
```
29+
30+
<hfoptions id="example">
31+
<hfoption id="Mac">
32+
33+
Example output:
34+
35+
```
36+
Finding all available ports for the MotorBus.
37+
['/dev/tty.usbmodem575E0032081', '/dev/tty.usbmodem575E0031751']
38+
Remove the USB cable from your MotorsBus and press Enter when done.
39+
40+
[...Disconnect corresponding leader or follower arm and press Enter...]
41+
42+
The port of this MotorsBus is /dev/tty.usbmodem575E0032081
43+
Reconnect the USB cable.
44+
```
45+
46+
Where the found port is: `/dev/tty.usbmodem575E0032081` corresponding to your leader or follower arm.
47+
48+
</hfoption>
49+
<hfoption id="Linux">
50+
51+
On Linux, you might need to give access to the USB ports by running:
52+
```bash
53+
sudo chmod 666 /dev/ttyACM0
54+
sudo chmod 666 /dev/ttyACM1
55+
```
56+
57+
Example output:
58+
59+
```
60+
Finding all available ports for the MotorBus.
61+
['/dev/ttyACM0', '/dev/ttyACM1']
62+
Remove the usb cable from your MotorsBus and press Enter when done.
63+
64+
[...Disconnect corresponding leader or follower arm and press Enter...]
65+
66+
The port of this MotorsBus is /dev/ttyACM1
67+
Reconnect the USB cable.
68+
```
69+
70+
Where the found port is: `/dev/ttyACM1` corresponding to your leader or follower arm.
71+
72+
</hfoption>
73+
</hfoptions>
74+
75+
### 2. Set the motors ids and baudrates
76+
77+
Each motor is identified by a unique id on the bus. When brand new, motors usually come with a default id of `1`. For the communication to work properly between the motors and the controller, we first need to set a unique, different id to each motor. Additionally, the speed at which data is transmitted on the bus is determined by the baudrate. In order to talk to each other, the controller and all the motors need to be configured with the same baudrate.
78+
79+
To that end, we first need to connect to each motor individually with the controller in order to set these. Since we will write these parameters in the non-volatile section of the motors' internal memory (EEPROM), we'll only need to do this once.
80+
81+
If you are repurposing motors from another robot, you will probably also need to perform this step as the ids and baudrate likely won't match.
82+
83+
#### Follower
84+
85+
Connect the usb cable from your computer and the power supply to the follower arm's controller board. Then, run the following command or run the API example with the port you got from the previous step. You'll also need to give your leader arm a name with the `id` parameter.
86+
87+
For a visual reference on how to set the motor ids please refer to [this video](https://huggingface.co/docs/lerobot/en/so101#setup-motors-video) where we follow the process for the SO101 arm.
88+
89+
<hfoptions id="setup_motors">
90+
<hfoption id="Command">
91+
92+
```bash
93+
python -m lerobot.setup_motors \
94+
--robot.type=so100_follower \
95+
--robot.port=/dev/tty.usbmodem585A0076841 # <- paste here the port found at previous step
96+
```
97+
</hfoption>
98+
<hfoption id="API example">
99+
100+
```python
101+
from lerobot.common.robots.so100_follower import SO100Follower, SO100FollowerConfig
102+
103+
config = SO100FollowerConfig(
104+
port="/dev/tty.usbmodem585A0076841",
105+
id="my_awesome_follower_arm",
106+
)
107+
follower = SO100Follower(config)
108+
follower.setup_motors()
109+
```
110+
</hfoption>
111+
</hfoptions>
112+
113+
You should see the following instruction
114+
```
115+
Connect the controller board to the 'gripper' motor only and press enter.
116+
```
117+
118+
As instructed, plug the gripper's motor. Make sure it's the only motor connected to the board, and that the motor itself is not yet daisy-chained to any other motor. As you press `[Enter]`, the script will automatically set the id and baudrate for that motor.
119+
120+
<details>
121+
<summary>Troubleshooting</summary>
122+
123+
If you get an error at that point, check your cables and make sure they are plugged in properly:
124+
<ul>
125+
<li>Power supply</li>
126+
<li>USB cable between your computer and the controller board</li>
127+
<li>The 3-pin cable from the controller board to the motor</li>
128+
</ul>
129+
130+
If you are using a Waveshare controller board, make sure that the two jumpers are set on the `B` channel (USB).
131+
</details>
132+
133+
You should then see the following message:
134+
```
135+
'gripper' motor id set to 6
136+
```
137+
138+
Followed by the next instruction:
139+
```
140+
Connect the controller board to the 'wrist_roll' motor only and press enter.
141+
```
142+
143+
You can disconnect the 3-pin cable from the controller board, but you can leave it connected to the gripper motor on the other end, as it will already be in the right place. Now, plug in another 3-pin cable to the wrist roll motor and connect it to the controller board. As with the previous motor, make sure it is the only motor connected to the board and that the motor itself isn't connected to any other one.
144+
145+
Repeat the operation for each motor as instructed.
146+
147+
> [!TIP]
148+
> Check your cabling at each step before pressing Enter. For instance, the power supply cable might disconnect as you manipulate the board.
149+
150+
When you are done, the script will simply finish, at which point the motors are ready to be used. You can now plug the 3-pin cable from each motor to the next one, and the cable from the first motor (the 'shoulder pan' with id=1) to the controller board, which can now be attached to the base of the arm.
151+
152+
#### Leader
153+
Do the same steps for the leader arm.
154+
155+
<hfoptions id="setup_motors">
156+
<hfoption id="Command">
157+
```bash
158+
python -m lerobot.setup_motors \
159+
--teleop.type=so100_leader \
160+
--teleop.port=/dev/tty.usbmodem575E0031751 # <- paste here the port found at previous step
161+
```
162+
</hfoption>
163+
<hfoption id="API example">
164+
165+
```python
166+
from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig
167+
168+
config = SO100LeaderConfig(
169+
port="/dev/tty.usbmodem585A0076841",
170+
id="my_awesome_leader_arm",
171+
)
172+
leader = SO100Leader(config)
173+
leader.setup_motors()
174+
```
175+
</hfoption>
176+
</hfoptions>
177+
18178
## Step-by-Step Assembly Instructions
19179

20180
## Remove the gears of the 6 leader motors
@@ -252,163 +412,6 @@ For the leader configuration, perform **Steps 1–23**. Make sure that you remov
252412
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/so100_assembly_28.webp" style="height:300px;"/>
253413
</div>
254414

255-
## Configure the motors
256-
257-
### 1. Find the USB ports associated with each arm
258-
259-
To find the port for each bus servo adapter, run this script:
260-
```bash
261-
python lerobot/find_port.py
262-
```
263-
264-
<hfoptions id="example">
265-
<hfoption id="Mac">
266-
267-
Example output:
268-
269-
```
270-
Finding all available ports for the MotorBus.
271-
['/dev/tty.usbmodem575E0032081', '/dev/tty.usbmodem575E0031751']
272-
Remove the USB cable from your MotorsBus and press Enter when done.
273-
274-
[...Disconnect corresponding leader or follower arm and press Enter...]
275-
276-
The port of this MotorsBus is /dev/tty.usbmodem575E0032081
277-
Reconnect the USB cable.
278-
```
279-
280-
Where the found port is: `/dev/tty.usbmodem575E0032081` corresponding to your leader or follower arm.
281-
282-
</hfoption>
283-
<hfoption id="Linux">
284-
285-
On Linux, you might need to give access to the USB ports by running:
286-
```bash
287-
sudo chmod 666 /dev/ttyACM0
288-
sudo chmod 666 /dev/ttyACM1
289-
```
290-
291-
Example output:
292-
293-
```
294-
Finding all available ports for the MotorBus.
295-
['/dev/ttyACM0', '/dev/ttyACM1']
296-
Remove the usb cable from your MotorsBus and press Enter when done.
297-
298-
[...Disconnect corresponding leader or follower arm and press Enter...]
299-
300-
The port of this MotorsBus is /dev/ttyACM1
301-
Reconnect the USB cable.
302-
```
303-
304-
Where the found port is: `/dev/ttyACM1` corresponding to your leader or follower arm.
305-
306-
</hfoption>
307-
</hfoptions>
308-
309-
### 2. Set the motors ids and baudrates
310-
311-
Each motor is identified by a unique id on the bus. When brand new, motors usually come with a default id of `1`. For the communication to work properly between the motors and the controller, we first need to set a unique, different id to each motor. Additionally, the speed at which data is transmitted on the bus is determined by the baudrate. In order to talk to each other, the controller and all the motors need to be configured with the same baudrate.
312-
313-
To that end, we first need to connect to each motor individually with the controller in order to set these. Since we will write these parameters in the non-volatile section of the motors' internal memory (EEPROM), we'll only need to do this once.
314-
315-
If you are repurposing motors from another robot, you will probably also need to perform this step as the ids and baudrate likely won't match.
316-
317-
#### Follower
318-
319-
Connect the usb cable from your computer and the power supply to the follower arm's controller board. Then, run the following command or run the API example with the port you got from the previous step. You'll also need to give your leader arm a name with the `id` parameter.
320-
321-
For a visual reference on how to set the motor ids please refer to [this video](https://huggingface.co/docs/lerobot/en/so101#setup-motors-video) where we follow the process for the SO101 arm.
322-
323-
<hfoptions id="setup_motors">
324-
<hfoption id="Command">
325-
326-
```bash
327-
python -m lerobot.setup_motors \
328-
--robot.type=so100_follower \
329-
--robot.port=/dev/tty.usbmodem585A0076841 # <- paste here the port found at previous step
330-
```
331-
</hfoption>
332-
<hfoption id="API example">
333-
334-
```python
335-
from lerobot.common.robots.so100_follower import SO100Follower, SO100FollowerConfig
336-
337-
config = SO100FollowerConfig(
338-
port="/dev/tty.usbmodem585A0076841",
339-
id="my_awesome_follower_arm",
340-
)
341-
follower = SO100Follower(config)
342-
follower.setup_motors()
343-
```
344-
</hfoption>
345-
</hfoptions>
346-
347-
You should see the following instruction
348-
```
349-
Connect the controller board to the 'gripper' motor only and press enter.
350-
```
351-
352-
As instructed, plug the gripper's motor. Make sure it's the only motor connected to the board, and that the motor itself is not yet daisy-chained to any other motor. As you press `[Enter]`, the script will automatically set the id and baudrate for that motor.
353-
354-
<details>
355-
<summary>Troubleshooting</summary>
356-
357-
If you get an error at that point, check your cables and make sure they are plugged in properly:
358-
<ul>
359-
<li>Power supply</li>
360-
<li>USB cable between your computer and the controller board</li>
361-
<li>The 3-pin cable from the controller board to the motor</li>
362-
</ul>
363-
364-
If you are using a Waveshare controller board, make sure that the two jumpers are set on the `B` channel (USB).
365-
</details>
366-
367-
You should then see the following message:
368-
```
369-
'gripper' motor id set to 6
370-
```
371-
372-
Followed by the next instruction:
373-
```
374-
Connect the controller board to the 'wrist_roll' motor only and press enter.
375-
```
376-
377-
You can disconnect the 3-pin cable from the controller board, but you can leave it connected to the gripper motor on the other end, as it will already be in the right place. Now, plug in another 3-pin cable to the wrist roll motor and connect it to the controller board. As with the previous motor, make sure it is the only motor connected to the board and that the motor itself isn't connected to any other one.
378-
379-
Repeat the operation for each motor as instructed.
380-
381-
> [!TIP]
382-
> Check your cabling at each step before pressing Enter. For instance, the power supply cable might disconnect as you manipulate the board.
383-
384-
When you are done, the script will simply finish, at which point the motors are ready to be used. You can now plug the 3-pin cable from each motor to the next one, and the cable from the first motor (the 'shoulder pan' with id=1) to the controller board, which can now be attached to the base of the arm.
385-
386-
#### Leader
387-
Do the same steps for the leader arm.
388-
389-
<hfoptions id="setup_motors">
390-
<hfoption id="Command">
391-
```bash
392-
python -m lerobot.setup_motors \
393-
--teleop.type=so100_leader \
394-
--teleop.port=/dev/tty.usbmodem575E0031751 # <- paste here the port found at previous step
395-
```
396-
</hfoption>
397-
<hfoption id="API example">
398-
399-
```python
400-
from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig
401-
402-
config = SO100LeaderConfig(
403-
port="/dev/tty.usbmodem585A0076841",
404-
id="my_awesome_leader_arm",
405-
)
406-
leader = SO100Leader(config)
407-
leader.setup_motors()
408-
```
409-
</hfoption>
410-
</hfoptions>
411-
412415
## Calibrate
413416

414417
Next, you'll need to calibrate your robot to ensure that the leader and follower arms have the same position values when they are in the same physical position.

0 commit comments

Comments
 (0)