很多朋友想在桌面上放一只会晃头、能迈着小碎步走动的陪伴小鸭子,最近社区里 Open Duck 系列和 Hugging Face LeRobot 的结合越来越火。今天把我们团队复现 Open Duck Mini 的全过程拆开,包含硬件选型 BOM 清单、电路接线避坑指南,以及如何把多自由度结构接入 LeRobot 框架进行动作示教与步态控制。
文章所有步骤均基于可复现标准编写,中途容易打齿、烧主控的地方会重点标出。
一、 硬件选型与 BOM 清单
做小型桌面机器人的核心矛盾永远是:空间狭小、散热有限、瞬态电流极大。选型时尽量避开纯模拟的 9g 舵机,优先选择带绝对位置反馈的总线舵机,否则后期无法在 LeRobot 里做 Leader-Follower(主从示教)的数据采集。
| 类别 | 部件名称 | 规格参数 / 推荐型号 | 数量 | 作用与选型理由 |
|---|---|---|---|---|
| 执行器 | 微型磁编码总线舵机 | 飞特 (Feetech) STS3215 或 SCS0009 | 6-8 个 | 腿部 4 自由度,颈部与头部 2-4 自由度。必须带位置反馈与温度上报 |
| 主控 | 微型控制器 | ESP32-S3-DevKitC-1 (N16R8) | 1 块 | 负责下位机协议转发,USB CDC 虚拟串口与上位机通信 |
| 驱动接口 | 舵机驱动板 | 飞特 URT-1 或专用总线转接板 | 1 块 | 提供 TTL 串口半双工转换及独立大电流供电接口 |
| 上位机 | 计算单元 | 树莓派 5 (4GB+) 或 PC 本地环境 | 1 台 | 运行 Python、PyTorch 与 LeRobot 框架 |
| 供电 | 稳压电源 / 锂电池 | 2S 7.4V 锂电 或 6V 5A DC 开关电源 | 1 套 | 严禁仅靠上位机 USB 接口供电,瞬间堵转电流极易拉垮主控 |
| 结构件 | 3D 打印外壳与骨架 | PETG / PLA+ 耗材,0.16mm 层高 | 1 套 | 开源 STL 模型切片打印,活动关节处填充率建议 40% 以上 |
二、 3D 打印与机构组装翻车点
-
先校准中位,再装舵盘 绝大多数初学者组装双足或四足结构时,第一个翻车点就是盲装。总线舵机在通电写入 ID 和归中(通常是 2048 点位)之前,千万不要硬拧舵盘。 正确流程:先写个简单的 Python 脚本,将所有舵机的 ID 依次修改为 1 至 8,发指令让它们回到中位(Offset = 0),断电后再将腿部机械臂以设计垂直角度压入花键。
-
关节公差处理 小型鸭子的腿部连杆非常紧凑,PETG 打印件收缩可能导致轴孔过紧。如果舵机轴承孔偏小,请用铰刀扩孔,切忌大力下压,否则容易导致微型减速箱内部齿轮偏心打齿。
三、 电气接线拓扑与防烧指南
很多同学在测试步态时遇到 ESP32 莫名其妙不断重启(Brownout Reset),90% 是因为强弱电共用或者回流地线阻抗过大。
1. 接线拓扑图解
[DC 稳压电源 6V-7.4V 5A]
|
+----> 舵机群 VCC (并联至各总线舵机电源脚)
|
+----> URT-1 / 舵机驱动板 VIN
|
+----> [DC-DC 降压至 5V] ---> ESP32-S3 5V 引脚
|
+----> 共地 GND ------------------------+
|
[PC / 树莓派] |
| |
(USB-C 数据线) |
| |
v v
[ESP32-S3] --(TX1/RX1 TTL 半双工)--> [URT-1] --(总线串联信号线)--> [舵机 1~8]
2. 接线注意细节
- 共地 (Common Ground):电源负极、降压模块负极、ESP32 的 GND 和舵机驱动板的 GND 必须单点牢固连接。
- 避免板载 LDO 供电:绝对不要试图用 ESP32 板载的 3.3V/5V 引脚引出给舵机供电,一个舵机启动瞬间电流可达 1A 以上,必定烧毁板载稳压芯片。
四、 接入 LeRobot 框架环境配置
Hugging Face 推出的 LeRobot 专为真实机器人学习设计,对基于总线舵机的示教与模仿学习非常友好。
1. 软件环境准备
在上位机(Ubuntu 22.04 或 macOS/Windows 均可)创建独立环境:
conda create -y -n lerobot python=3.10
conda activate lerobot
# 安装核心依赖与 LeRobot
git clone https://github.com/huggingface/lerobot.git
cd lerobot
pip install -e .
pip install pyserial feetech-servo-sdk
2. 编写 Open Duck 硬件适配抽象
在 LeRobot 的执行架构下,我们需要为 Open Duck Mini 定义 Follower 机器人。以下是一个极简的双舵机腿部总线通信封装示例:
import time
import serial
from dataclasses import dataclass
# 假设使用基础串口协议与 ESP32 或驱动板通信
class OpenDuckMotors:
def __init__(self, port: str = "/dev/ttyUSB0", baudrate: int = 1000000):
self.ser = serial.Serial(port, baudrate, timeout=0.05)
# 初始化舵机 ID 列表:左髋、左膝、右髋、右膝
self.servo_ids = [1, 2, 3, 4]
def read_positions(self) -> list[float]:
"""
读取当前所有关节角度(归一化到 -1.0 至 1.0 之间)
LeRobot 的策略网络输入要求特征范围规整
"""
raw_positions = []
for sid in self.servo_ids:
# 伪代码:向舵机发送读取位置指令
self.ser.write(bytearray([0xFF, 0xFF, sid, 0x04, 0x02, 0x38, 0x02]))
response = self.ser.read(8)
if len(response) >= 8:
pos = (response[5] << 8) | response[6]
# 将 0-4096 映射到 -1.0 到 1.0
norm_pos = (pos - 2048) / 2048.0
raw_positions.append(norm_pos)
else:
raw_positions.append(0.0)
return raw_positions
def write_positions(self, target_positions: list[float]):
"""
下发控制指令
"""
assert len(target_positions) == len(self.servo_ids)
for sid, norm_pos in zip(self.servo_ids, target_positions):
# 将 -1.0 到 1.0 还原为原始刻度
raw_pos = int(norm_pos * 2048 + 2048)
raw_pos = max(0, min(4095, raw_pos))
# 发送同步写或单写指令
low_byte = raw_pos & 0xFF
high_byte = (raw_pos >> 8) & 0xFF
packet = bytearray([0xFF, 0xFF, sid, 0x05, 0x03, 0x2A, low_byte, high_byte])
self.ser.write(packet)
def close(self):
self.ser.close()
五、 步态训练与控制入门
在小型双足机器人上做步态,通常有两条路线:
- 经典 CPG(中枢模式发生器)参数化示教: 先用简单的正弦波振荡器写一套能让机器鸭摇摆前行的开环步态,然后让 LeRobot 的数据采集脚本录制这套动作序列(包含关节位置、速度反馈以及机载 IMU 姿态),构建离线 Dataset。
import numpy as np
def generate_duck_gait_step(t: float, freq: float = 1.5) -> list[float]:
"""
极简的开环对侧摆动步态
t: 时间戳 (秒)
"""
phase = 2 * np.pi * freq * t
# 髋关节负责前倾推进,膝关节负责抬腿离地
left_hip = 0.3 * np.sin(phase)
left_knee = 0.4 * np.maximum(0, np.cos(phase))
right_hip = 0.3 * np.sin(phase + np.pi)
right_knee = 0.4 * np.maximum(0, np.cos(phase + np.pi))
return [left_hip, left_knee, right_hip, right_knee]
- 利用 LeRobot 进行策略克隆 (Behavior Cloning / ACT): 如果你做了一只相同的 Duck 骨架作为遥控把手(Leader 模式,舵机关闭扭矩作为编码器),可以通过物理牵引 Duck 做出转弯、起伏、坐下等动作,直接运行 LeRobot 官方录制脚本:
# 录制 50 组演示片段至本地数据集
python lerobot/scripts/record.py \
--robot-path lerobot.common.robot_devices.robots.open_duck \
--fps 30 \
--num-episodes 50 \
--run-compute-stats 1 \
--out-dir data/duck_walking_dataset
随后通过 ACT (Action Chunking with Transformers) 算法进行网络训练,让模型自主平滑步态输出,补偿 3D 打印件摩擦力导致的步态不稳。
六、 总结与下阶段测试
复现 Open Duck Mini 的关键在于软硬件闭环:
- 选型阶段务必使用支持总线回传的舵机,这是后续能接入 LeRobot 学习生态的前提。
- 调试供电时优先把瞬态退耦电容(470uF 电解电容)焊在总线转接板电源输入端,能解决 80% 的通信丢包和主控复位问题。
下一步我们会把机载单目摄像头(OV2640 / USB 鱼眼镜头)的数据流接入 LeRobot,训练机器鸭跟随红球移动的双足步态闭环。欢迎大家在本地先把硬件骨架打起来,有问题随时交流。
License: CC BY-NC 4.0
Updated an hour ago
Was this article helpful? Give it a like.
0 comments


