Build Your Own SO-101 Robot!

Obtain the parts for the SO-101

Follow this README. It includes the bill of materials with a link to sources for the parts, as well as the instructions for 3D printing the parts. Additionally, advise whether this is your first time printing or if you do not own a 3D printer.

Install LeRobot

To install LeRobot, follow Installation Guide.
In addition to these instructions, you must install the Feetech SDK:
 pip install -e ".[feetech]"

Step-by-Step Assembly Instructions

The follower arm uses 6x STS3215 motors with 1/345 gearing. The leader, however, uses three motors with different gearings to ensure it can both support its own weight and be moved with minimal effort. The table below shows which motor is required for each joint.
Leader-Arm Axis Motor Gear Ratio
Base / Shoulder Pan 1 1 / 191
Shoulder Lift 2 1 / 345
Elbow Flex 3 1 / 191
Wrist Flex 4 1 / 147
Wrist Roll 5 1 / 147
Gripper 6 1 / 147

Clean Parts of the SO-101

Remove all support material from the 3D-printed parts. The easiest approach is to slide a small screwdriver under the support material to remove it.
After placing the motors, install one 3-pin cable into each motor before proceeding with assembly.

Install Joint 1

  1. Insert the first motor into the base.
  2. Secure the motor with four M2x6mm screws (the smallest screws): two from the top and two from the bottom.
  3. Slide the first motor holder over the motor and fix it with two M2x6mm screws (one on each side).
  4. Fit both motor horns, and fasten the upper horn with an M3x6mm screw.
  5. Mount the shoulder part.
  6. Secure the shoulder part with four M3x6mm screws on the top and four M3x6mm screws on the bottom.
  7. Install the shoulder motor holder.

Install Joint 2

  1. Slide the second motor down into place from the top.
  2. Secure the second motor with four M2x6mm screws.
  3. Fit both motor horns to motor 2 and fasten the top horn with an M3x6mm screw.
  4. Attach the upper arm, securing it with four M3x6mm screws on each side.

Install Joint 3

  1. Insert motor 3 and secure it with four M2x6mm screws.
  2. Install both motor horns on motor 3, fastening one of them with an M3x6mm horn screw.
  3. Attach the forearm to motor 3, using four M3x6mm screws on each side.

Install Joint 4

  1. Slide motor holder 4 into position.
  2. Insert motor 4.
  3. Secure motor 4 with four M2x6mm screws, then attach its motor horns and fasten one with an M3x6mm horn screw.

Install Joint 5

  1. Insert motor 5 into the wrist holder and fasten it with two M2x6mm front screws.
  2. Fit a single motor horn onto the wrist motor and secure it with an M3x6mm horn screw.
  3. Attach the wrist to motor 4, fastening it with four M3x6mm screws on each side.

Install Gripper / Handle

Follower

  1. Mount the gripper onto motor 5 by fastening it to the wrist motor horn with four M3x6mm screws.
  2. Insert the gripper motor and secure it with two M2x6mm screws on each side.
  3. Fit the motor horns and fasten one with an M3x6mm horn screw.
  4. Install the gripper claw and secure it with four M3x6mm screws on each side.

Leader

  1. Mount the leader holder on the wrist and fasten it with four M3x6mm screws.
  2. Attach the handle to motor 5 using one M2x6mm screw.
  3. Insert the gripper motor and secure it with two M2x6mm screws on each side; fit a motor horn and fasten it with an M3x6mm horn screw.
  4. Attach the follower trigger using four M3x6mm screws.

Configure the motors of the SO-101

Locate the USB ports corresponding to each arm

To identify the port for each bus servo adapter, connect the MotorBus to your computer with USB and power. Run the following script and unplug the MotorBus when prompted:
 lerobot-find-port

Mac

Example output:
 Finding all available ports for the MotorBus.
['/dev/tty.usbmodem575E0032081', '/dev/tty.usbmodem575E0031751']
Remove the USB cable from your MotorsBus and press Enter when done.

[...Disconnect corresponding leader or follower arm and press Enter...]

The port of this MotorsBus is /dev/tty.usbmodem575E0032081
Reconnect the USB cable.
The detected port is /dev/tty.usbmodem575E0032081, which corresponds to either your leader or follower arm.

Linux

On Linux, you may need to grant access to the USB ports by running:

 sudo chmod 666 /dev/ttyACM0

 sudo chmod 666 /dev/ttyACM1

Example output:
 Finding all available ports for the MotorBus. 
['/dev/ttyACM0', '/dev/ttyACM1']

Remove the usb cable from your MotorsBus and press Enter when done.

[...Disconnect corresponding leader or follower arm and press Enter...]

The port of this MotorsBus is /dev/ttyACM1
Reconnect the USB cable.

The discovered port is /dev/ttyACM1, which corresponds to your leader or follower arm.

Assign the motor IDs and set their baud rates

Each motor has a unique ID on the bus. New motors typically ship with an ID of 1. For proper communication between the motors and the controller, every motor must be assigned a distinct ID. The baudrate determines the data transmission speed on the bus; the controller and all motors must share the same baudrate to communicate.
To do this, connect to each motor individually with the controller and configure its ID and baudrate. These settings are written to the motor’s non-volatile memory (EEPROM), so the process needs to be done only once.
If you’re reusing motors from another robot, you’ll likely need to repeat this step because their IDs and baudrate may not match.
The video below demonstrates the step-by-step procedure for setting motor IDs.

Follower

Plug the USB cable from your computer and the power supply into the follower arm’s controller board. Then execute the command below (or run the API example) using the port you obtained earlier. Also assign a name to your leader arm using the id parameter.
Command:

 lerobot-setup-motors \
      --robot.type=so101_follower \
      --robot.port=/dev/tty.usbmodem585A0076841 # <- paste here the port found at previous step

API example:
 from lerobot.robots.so101_follower import SO101Follower, SO101FollowerConfig

config = SO101FollowerConfig(
      port="/dev/tty.usbmodem585A0076841",
      id="my_awesome_follower_arm",
)
follower = SO101Follower(config)
follower.setup_motors()
You will see the following instruction.
 Connect the controller board to the 'gripper' motor only and press enter.
As directed, connect the gripper motor—ensure it is the only motor attached to the board and not daisy-chained to any others. When you press [Enter], the script will automatically configure that motor’s ID and baudrate.
Troubleshooting:
If an error occurs, verify all cable connections:
  • Power supply
  • USB cable between your computer and the controller board
  • 3‑pin cable from the controller board to the motor
If using a Waveshare controller board, confirm both jumpers are set to the B channel (USB).
After that, you should see the following message:
 'gripper' motor id set to 6
Followed by the next instruction:
 Connect the controller board to the 'wrist_roll' motor only and press enter.
You may unplug the 3‑pin cable from the controller board but leave its other end attached to the gripper motor, since that end is already in position. Next, connect a fresh 3‑pin cable from the controller board to the wrist roll motor. As before, ensure this motor is the only one connected to the board and is not daisy‑chained to any other motor.
Repeat this procedure for each motor as directed.
Before pressing Enter each time, verify all cable connections — the power cable, for example, can become loose while you handle the board.
When the script completes, the motors will be configured and ready. You can then daisy‑chain the 3‑pin cables from motor to motor, and connect the cable from the first motor (the shoulder pan with id=1) to the controller board, which can be mounted to the arm’s base.

Leader

Do the same steps for the leader arm.
Command:
 lerobot-setup-motors \
      --teleop.type=so101_leader \
      --teleop.port=/dev/tty.usbmodem575E0031751 # <- paste here the port found at previous step
API example:
 from lerobot.teleoperators.so101_leader import SO101Leader, SO101LeaderConfig
config = SO101LeaderConfig(
      port="/dev/tty.usbmodem585A0076841",
      id="my_awesome_leader_arm",
)
leader = SO101Leader(config)
leader.setup_motors()

Calibrate your Robot

Next, calibrate the robot so the leader and follower arms report identical position values when they occupy the same physical pose. This calibration is crucial because it enables a neural network trained on one robot to function correctly on another.

Follower

Execute the command below (or use the API example) to calibrate the follower arm:
Command:
 lerobot-calibrate \
      --robot.type=so101_follower \
      --robot.port=/dev/tty.usbmodem58760431551 \ # <- The port of your robot
      --robot.id=my_awesome_follower_arm # <- Give the robot a unique name
API example:
 from lerobot.robots.so101_follower import SO101FollowerConfig, SO101Follower

config = SO101FollowerConfig(
      port="/dev/tty.usbmodem585A0076891",
      id="my_awesome_follower_arm",
)
follower = SO101Follower(config)
follower.connect(calibrate=False)
follower.calibrate()
follower.disconnect()
The video below demonstrates the calibration: first position the robot so every joint is centered in its range, then press Enter and move each joint through its full range of motion.

Leader

Perform the same steps to calibrate the leader arm — execute the command below or use the API example:
Command:
 lerobot-calibrate \
      --teleop.type=so101_leader \
      --teleop.port=/dev/tty.usbmodem58760431551 \ # <- The port of your robot
      --teleop.id=my_awesome_leader_arm # <- Give the robot a unique name
API example:
 from lerobot.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader
config = SO101LeaderConfig(
      port="/dev/tty.usbmodem58760431551",
      id="my_awesome_leader_arm",
)

leader = SO101Leader(config)
leader.connect(calibrate=False)
leader.calibrate()
leader.disconnect()

Zijbalk

Laatste bericht

Deze sectie bevat momenteel geen inhoud. Voeg inhoud toe aan deze sectie via de zijbalk.

Meld je aan voor onze nieuwsbrief

Ontvang de laatste informatie over onze producten en speciale aanbiedingen.