SO-100 开源机械臂 DIY 完全指南:零部件、组装、编程 2026
SO-100 是 2026 年最火的低成本开源机械臂项目,本教程涵盖 BOM 清单、3D 打印、组装步骤、舵机校准、LeRobot 集成,附完整代码示例与常见问题解答,助你从零搭建一台可用于机器人学习研究的 6 自由度机械臂。
SO-100 开源机械臂 DIY 完全指南:零部件、组装、编程 2026
SO-100 是 2025 年由 Hugging Face 社区发起的开源机械臂项目,目标是打造一台成本低于 500 元、性能可用于机器人学习研究的 6 自由度机械臂。它采用 3D 打印结构 + 总线舵机方案,配合 LeRobot 框架,可以实现从数据收集到策略训练的全流程。
截至 2026 年,SO-100 已有超过 5000 台被全球研究者和爱好者组装完成,成为机器人学习领域最受欢迎的硬件平台之一。
你将学到:
- ✅ 完整 BOM 清单与采购指南
- ✅ 3D 打印件准备与后处理
- ✅ 机械组装全流程(含视频链接)
- ✅ 舵机校准与电气连接
- ✅ 与 LeRobot 集成,训练抓取策略
1. SO-100 设计概述
1.1 为什么选择 SO-100?
市面上机械臂方案众多,SO-100 的优势在于:
| 特性 | SO-100 | 工业机械臂 | 其他开源方案 |
|---|---|---|---|
| 成本 | ~500 元 | 5-50 万元 | 1000-3000 元 |
| 自由度 | 6 DOF | 6-7 DOF | 4-6 DOF |
| 负载 | 250g | 5-20kg | 200-500g |
| 重复精度 | ±1mm | ±0.02mm | ±2-5mm |
| 开源程度 | 完全开源 | 封闭 | 部分开源 |
| LeRobot 支持 | 原生 | 需适配 | 部分支持 |
适用场景:
- 机器人学习研究(模仿学习、强化学习)—— 想了解具身 AI 是什么?先看 什么是具身智能(Embodied AI)
- 高校教学实验
- 个人 AI 项目 —— 搭建开发环境可参考 具身智能开发环境搭建
- 数据采集与策略验证
不适用场景:
- 工业级精度要求
- 重载操作(>250g)
- 户外或恶劣环境
1.2 技术规格
- 自由度:6(基座旋转、肩关节、肘关节、腕关节俯仰、腕关节翻滚、末端执行器)
- 驱动:6x ST3215 总线舵机(3.3V/5V,15kg·cm 扭矩)
- 控制器:ESP32-S3 + 舵机控制板
- 通信:USB UART / WiFi
- 结构:3D 打印 PLA/PETG
- 末端:可更换夹爪/吸盘/电磁铁
- 工作半径:~250mm
- 自重:~800g(不含电源)
2. BOM 清单与采购
2.1 核心零部件
| 零件 | 数量 | 参考价格 | 采购渠道 |
|---|---|---|---|
| ST3215 总线舵机 | 6 | 35 元/个 | 淘宝/闲鱼 |
| ESP32-S3 开发板 | 1 | 25 元 | 立创商城 |
| 舵机控制板(Hub) | 1 | 45 元 | SO-100 官方淘宝店 |
| 3D 打印件(全套) | 1 套 | 50-80 元 | 自建/代打印 |
| 轴承 6x10x3mm | 6 | 2 元/个 | 淘宝 |
| M3 螺丝套装 | 1 套 | 15 元 | 淘宝 |
| 铜柱 M3x10mm | 4 | 1 元/个 | 淘宝 |
| 电源 5V 4A | 1 | 30 元 | 淘宝 |
| USB-C 线缆 | 1 | 10 元 | 任意 |
| 杜邦线 | 若干 | 5 元 | 任意 |
总成本:约 400-500 元
2.2 舵机选择
ST3215 是 SO-100 的推荐舵机,关键参数:
- 电压:5-8.4V
- 扭矩:15kg·cm @ 6V
- 通信:TTL 总线(半双工串口)
- 分辨率:4096 步/圈
- 反馈:位置、温度、电压、负载
- 重量:55g
替代方案:
如果 ST3215 缺货,以下舵机也可使用(需调整配置文件):
- STS3215:ST3215 的升级版,推荐
- FEETECH SCS15:兼容协议
- Waveshare Bus Servo:国产兼容方案
注意: 不要使用 PWM 舵机(如 SG90、MG996R),它们不支持位置反馈和总线通信。
2.3 3D 打印件
推荐材料:
- PLA: easiest to print,适合原型
- PETG:更好的韧性和耐温性,推荐最终版
- ABS:不推荐(容易翘边)
打印参数(以 PETG 为例):
- 层高:0.2mm
- 填充:30%
- 壁厚:3 层
- 支撑:需要(部分零件)
- 喷嘴温度:235-245°C
- 热床温度:70-80°C
获取 STL 文件:
# 从 GitHub 下载
git clone https://github.com/SoBot-100/SO-100.git
cd SO-100/hardware/stl/
# 或使用 Thingiverse
# https://www.thingiverse.com/thing:XXXXX
打印后处理:
- 去除支撑材料
- 用砂纸打磨接触面
- 检查轴承孔是否顺畅(必要时用钻头扩孔)
- 螺母嵌入孔用烙铁加热嵌入 M3 螺母
3. 组装步骤
3.1 工具准备
- 十字螺丝刀(PH1)
- 内六角扳手(2mm)
- 烙铁 + 焊锡
- 万用表
- 热熔胶枪(可选)
- 扎带若干
3.2 舵机预组装
在组装机械臂之前,需要先对舵机进行零点校准。
步骤 1:舵机 ID 设置
每个舵机需要唯一的 ID(1-6):
#!/usr/bin/env python3
"""舵机 ID 配置工具"""
import serial
import time
def set_servo_id(port, old_id, new_id):
"""设置舵机 ID"""
# ST3215 协议:写入 ID 寄存器
# 寄存器地址:0x05
instruction = [
0xFF, 0xFF, # Header
old_id, # Current ID
0x04, # Length
0x03, # Write instruction
0x05, # Address (ID register)
new_id # New ID value
]
# 计算校验和
checksum = sum(instruction[2:]) & 0xFF
instruction.append((~checksum) & 0xFF)
ser = serial.Serial(port, 1000000, timeout=1)
ser.write(bytes(instruction))
time.sleep(0.1)
response = ser.read(ser.in_waiting)
ser.close()
print(f"舵机 ID 已从 {old_id} 改为 {new_id}")
return len(response) > 0
# 依次设置 6 个舵机
# 先连接一个舵机,设置 ID 为 1,然后换下一个
for i in range(6):
new_id = i + 1
input(f"请连接第 {new_id} 个舵机,按回车继续...")
set_servo_id("/dev/ttyUSB0", 1, new_id) # 默认 ID 为 1
print(f"舵机 {new_id} 设置完成")
步骤 2:零点校准
将所有舵机转到中位(2048):
#!/usr/bin/env python3
"""舵机零点校准"""
import serial
import time
def move_to_center(port, servo_id):
"""将舵机转到中位"""
position = 2048 # 中位
instruction = [
0xFF, 0xFF,
servo_id,
0x07, # Length
0x03, # Write
0x1E, # Goal Position address (0x1E)
position & 0xFF,
(position >> 8) & 0xFF,
0x00, # Speed
0x00
]
checksum = sum(instruction[2:]) & 0xFF
instruction.append((~checksum) & 0xFF)
ser = serial.Serial(port, 1000000, timeout=1)
ser.write(bytes(instruction))
time.sleep(1.0)
ser.close()
print(f"舵机 {servo_id} 已转到中位")
# 依次校准
for i in range(1, 7):
move_to_center("/dev/ttyUSB0", i)
重要: 在校准中位后再安装舵机臂,确保各关节在中位时对齐。
3.3 机械臂组装
步骤 1:基座(Joint 1 - 旋转)
[底座] → [轴承] → [舵机1] → [舵机臂]
- 将轴承压入底座零件
- 舵机 1(ID=1)从下方插入,螺丝固定
- 安装舵机臂(此时应已在中位)
- 用 M3x10 螺丝固定舵机臂
步骤 2:大臂(Joint 2 - 肩关节)
[舵机1臂] → [连接件] → [舵机2] → [大臂零件]
- 将连接件固定到舵机 1 的臂上
- 舵机 2(ID=2)嵌入大臂零件
- 通过连接件将大臂与基座连接
- 注意线缆走向,预留余量
步骤 3:小臂(Joint 3 - 肘关节)
[大臂] → [舵机3] → [小臂零件]
- 舵机 3(ID=3)安装到小臂根部
- 线缆穿过大臂内部
- 安装小臂零件
步骤 4:腕部(Joint 4 & 5 - 俯仰 + 翻滚)
[小臂] → [舵机4] → [连接件] → [舵机5] → [腕部零件]
- 舵机 4(ID=4)安装到小臂末端
- 通过连接件连接舵机 5
- 舵机 5(ID=5)实现翻滚运动
- 注意两个腕关节的轴线正交
步骤 5:末端执行器(Joint 6 - 夹爪)
[腕部] → [舵机6] → [夹爪]
- 舵机 6(ID=6)安装到腕部末端
- 安装夹爪零件
- 测试开合动作
3.4 电气连接
接线图:
ESP32-S3
├── UART_TX → 舵机控制板 RX
├── UART_RX → 舵机控制板 TX
├── GPIO_2 → 舵机控制板 DIR(方向控制)
└── GND → 共地
舵机控制板
├── 5V 输入 → 电源 5V 4A
├── GND → 电源 GND
├── 总线 → 舵机 1-6 信号线(菊花链)
└── GND → 舵机 1-6 GND
接线注意事项:
- 电源分离:舵机供电(5V 4A)与 ESP32 供电(USB 5V)分开,避免电流干扰
- 共地:所有 GND 必须连接在一起
- 总线拓扑:舵机信号线采用菊花链连接,不是星形
- 线序:信号线颜色通常为 黄=信号、红=VCC、棕=GND
完整接线检查清单:
□ 电源 5V → 控制板 VCC
□ 电源 GND → 控制板 GND
□ ESP32 TX → 控制板 RX
□ ESP32 RX → 控制板 TX
□ ESP32 GPIO_2 → 控制板 DIR
□ ESP32 GND → 控制板 GND
□ 舵机 1-6 总线连接(菊花链)
□ 舵机 1-6 VCC 连接
□ 舵机 1-6 GND 连接
4. 固件与软件
4.1 ESP32 固件
SO-100 使用基于 ESP32 的固件,提供 USB 串口和 LeRobot 兼容接口。
安装 Arduino CLI:
# 下载 Arduino CLI
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
# 添加 ESP32 开发板支持
arduino-cli config add board_manager.additional_urls \
https://espressif.github.io/arduino-esp32/package_esp32_index.json
# 安装 ESP32 核心
arduino-cli core install esp32:esp32
# 安装依赖库
arduino-cli lib install "Servo"
arduino-cli lib install "ArduinoJson"
上传固件:
# 克隆固件仓库
git clone https://github.com/SoBot-100/SO-100-firmware.git
cd SO-100-firmware
# 编译并上传
arduino-cli compile --fqbn esp32:esp32:esp32s3 --upload \
--port /dev/ttyACM0 so100_firmware.ino
固件功能:
- USB 串口通信(115200 baud)
- 舵机总线控制(转发 TTL 指令)
- 位置/速度/扭矩模式
- 实时状态反馈
- 安全保护(过温、过流)
4.2 Python 控制库
# 安装 SO-100 Python 库
pip install so100-controller
# 或从源码安装
git clone https://github.com/SoBot-100/so100-python.git
cd so100-python
pip install -e .
基础控制示例:
#!/usr/bin/env python3
"""SO-100 基础控制"""
from so100_controller import SO100Controller
import time
# 连接机械臂
arm = SO100Controller(port="/dev/ttyACM0")
arm.connect()
# 读取当前关节角度
positions = arm.get_joint_positions()
print(f"当前关节角度: {positions}")
# 移动到目标位置(单位:度)
target = [0, 0, 90, 90, 0, 0] # 各关节角度
arm.move_to(target, duration=2.0)
time.sleep(2.0)
# 夹爪控制
arm.set_gripper(100) # 全开
time.sleep(1.0)
arm.set_gripper(0) # 全关
# 读取状态
for servo_id in range(1, 7):
pos = arm.get_position(servo_id)
temp = arm.get_temperature(servo_id)
load = arm.get_load(servo_id)
print(f"舵机 {servo_id}: 位置={pos}, 温度={temp}°C, 负载={load}%")
# 断开连接
arm.disconnect()
高级控制 - 轨迹规划:
from so100_controller import SO100Controller
from so100_controller.trajectory import LinearPlanner
import numpy as np
arm = SO100Controller(port="/dev/ttyACM0")
arm.connect()
# 创建轨迹规划器
planner = LinearPlanner(max_velocity=60) # 度/秒
# 定义路径点
waypoints = [
[0, 0, 90, 90, 0, 0], # 初始位姿
[45, -30, 60, 60, 0, 0], # 中间位姿
[45, -30, 30, 90, 0, 50], # 目标位姿(夹爪半闭)
]
# 生成平滑轨迹
trajectory = planner.plan(waypoints, dt=0.033) # 30 Hz
# 执行轨迹
for point in trajectory:
arm.set_joint_positions(point)
time.sleep(0.033)
arm.disconnect()
5. LeRobot 集成
5.1 配置 LeRobot 支持
SO-100 是 LeRobot 原生支持的机器人之一。关于 LeRobot 框架的详细介绍,参见 LeRobot 完全指南。
# 安装 LeRobot(含 SO-100 支持)
pip install "lerobot[so100]"
创建配置文件:
# configs/robot/so100.yaml
robot_type: so100
port: /dev/ttyACM0
fps: 30
# 关节配置
joints:
- id: 1
name: shoulder_pan
offset: 0
inverted: false
min: -90
max: 90
- id: 2
name: shoulder_lift
offset: 0
inverted: true
min: -90
max: 90
- id: 3
name: elbow
offset: 0
inverted: false
min: -120
max: 0
- id: 4
name: wrist_pitch
offset: 0
inverted: false
min: -90
max: 90
- id: 5
name: wrist_roll
offset: 0
inverted: false
min: -90
max: 90
- id: 6
name: gripper
offset: 0
inverted: false
min: 0
max: 100
# 摄像头
camera:
type: usb
device: /dev/video0
width: 640
height: 480
fps: 30
5.2 数据收集
使用 LeRobot 的数据收集工具:
# 遥操作模式(用键盘或手柄控制)
python -m lerobot.teleoperate \
--robot=so100 \
--config=configs/robot/so100.yaml
# 录制数据集
python -m lerobot.record_dataset \
--robot=so100 \
--config=configs/robot/so100.yaml \
--repo-id=your-username/so100-pick \
--num-episodes=50 \
--task="pick up the red cube"
遥操作控制方式:
- 键盘控制:WASD 移动,QE 旋转,RF 夹爪
- 手柄控制:左摇杆平移,右摇杆旋转,扳机夹爪
- 主从模式:用另一台机械臂作为主手(需要额外硬件)
5.3 训练策略
# 使用 ACT 训练
python -m lerobot.train \
--config-path=configs/act/so100.yaml \
--dataset=your-username/so100-pick \
--output-dir=outputs/act_so100_pick
# 训练参数
# batch_size: 32
# steps: 10000
# learning_rate: 0.0001
# eval_freq: 500
5.4 部署执行
#!/usr/bin/env python3
"""部署训练好的策略到 SO-100"""
from so100_controller import SO100Controller
from lerobot.common.policies.act.modeling_act import ACTPolicy
import cv2
import torch
import time
# 加载策略
policy = ACTPolicy.from_pretrained("outputs/act_so100_pick/checkpoints/last")
policy.eval()
# 连接机械臂
arm = SO100Controller(port="/dev/ttyACM0")
arm.connect()
# 打开摄像头
cap = cv2.VideoCapture(0)
print("开始执行策略...")
print("按 Ctrl+C 停止")
try:
step = 0
while True:
# 读取图像
ret, frame = cap.read()
if not ret:
break
# 预处理
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = torch.tensor(image).permute(2, 0, 1).float() / 255.0
image = torch.nn.functional.interpolate(
image.unsqueeze(0), size=(480, 640)
)
# 读取关节状态
state = torch.tensor(arm.get_joint_positions()).float()
# 推理
obs = {
"observation.image": image,
"observation.state": state.unsqueeze(0)
}
with torch.no_grad():
action = policy.select_action(obs)
# 执行动作
arm.set_joint_positions(action[0].numpy())
step += 1
if step % 30 == 0:
print(f"Step {step}, Action: {action[0].numpy()}")
time.sleep(0.033) # 30 Hz
except KeyboardInterrupt:
print("停止执行")
finally:
cap.release()
arm.disconnect()
6. 常见问题与优化
6.1 机械问题
问题:关节松动/晃动
- 原因:舵机臂未紧固或轴承间隙过大
- 解决:重新紧固舵机臂螺丝,更换轴承
问题:夹爪打滑
- 原因:摩擦力不足
- 解决:在夹爪表面贴硅胶垫或橡胶皮
问题:线缆干涉
- 原因:线缆长度不足或走线不合理
- 解决:重新布线,使用柔性排线
6.2 电气问题
问题:舵机抖动
- 原因:电源不足或通信干扰
- 解决:更换 5V 4A 以上电源,检查接线
问题:ESP32 重启
- 原因:舵机启动电流过大导致电压跌落
- 解决:为 ESP32 单独供电,添加大容量电容(1000μF)
6.3 软件问题
问题:串口通信超时
- 原因:波特率不匹配或 USB 线缆质量差
- 解决:确认波特率为 1000000,更换高质量 USB 线缆
问题:LeRobot 找不到机器人
- 原因:端口权限或驱动问题
- 解决:
# 添加用户到 dialout 组
sudo usermod -aG dialout $USER
# 重新登录生效
# 检查端口
ls -la /dev/ttyACM*
总结
SO-100 是目前性价比最高的开源机械臂方案,500 元即可拥有一台可用于机器人学习研究的 6 自由度机械臂。通过本教程,你已完成:
- ✅ 采购所有零部件
- ✅ 3D 打印并组装机械臂
- ✅ 舵机校准与电气连接
- ✅ 固件安装与基础控制
- ✅ LeRobot 集成与策略训练
下一步建议:
- 参加 SO-100 社区分享你的作品
- 尝试不同的训练算法(Diffusion Policy、TD-MPC2)
- 升级末端执行器(吸盘、电磁铁、软体夹爪)
- 探索双臂协作(购买第二台 SO-100)
如果你想将 SO-100 与移动机器人结合,可以参考 宇树 Go2 机器狗 ROS2 开发指南 或 ROS2 入门教程。
常见问题(FAQ)
SO-100 机械臂适合初学者吗?
适合。SO-100 的设计目标就是降低机器人学习的门槛,无需专业背景即可组装。只要具备基本的焊接能力和 3D 打印经验,1-2 天即可完成组装。
SO-100 和工业机械臂有什么区别?
主要区别在于精度和负载。SO-100 重复精度约 ±1mm,负载 250g,适合学习和研究;工业机械臂精度可达 ±0.02mm,负载 5-20kg,但价格高达数万至数十万元。
没有 3D 打印机怎么办?
可以选择代打印服务(淘宝上约 50-80 元一套),或者使用激光切割木板/亚克力板替代部分结构件。社区也有铝合金版本的设计方案。
SO-100 可以用于哪些学习场景?
SO-100 支持模仿学习(Imitation Learning)、强化学习(RL)、视觉-语言-动作模型(VLA)等多种机器人学习范式,是学习 LeRobot 框架的理想硬件平台。
参考资料
- SO-100 GitHub:https://github.com/SoBot-100/SO-100
- LeRobot 文档:https://github.com/huggingface/lerobot
- ST3215 舵机手册:[链接]
- SO-100 社区 Discord:[链接]