Skip to content
←返回开源项目

OPEN SOURCE DEEP DIVE

双足机器人人形机器人开源强化学习

Bimo:45 厘米开源双足机器人

Bimo 是一台 45 厘米、约 1.6 公斤的髋-头双足机器人套件:8 个 STS-3215 总线舵机、BNO08x 九轴 IMU、4 路 VL53L0X 测距、2 路 180° 摄像头,主控是自研 RP2040 板,控制闭环 20 Hz。仓库公开 Python 控制 API(1023 行)、三份 MCU 固件(1349 行)、ROS2 封装(1431 行)与 Isaac Lab 训练环境(874 行,含六项奖励、密集域随机化、按系统辨识建模的 STS3215Actuator:3.113 Hz 带宽、方向性齿隙、5 ms 总线延迟),外加 26MB 的 Bimo.usd 模型。CPG 步态的 104 个傅里叶系数与逐关节增益在 Python 与 C 里各存一份;PPO 教师 [256,128,64] 可蒸馏成学生 [64,32],经 onnx2c 编进固件后脱机在 MCU 上行走。代码全部 Apache-2.0,但 README 承诺的 CAD 与电路设计仍标注 coming soon,仓库与全部 git 历史里没有任何 STL/STEP/原理图/Gerber/BOM,也没有预训练权重(两个 release 附件数均为 0)与 DIY 装配手册。当前版本 v1.1.0,198 star,项目处于预订阶段。

mekion/the-bimo-project198PythonApache-2.05 min read

一台 45 厘米高的髋-头双足机器人

Bimo 是西班牙开发者 Mykhaylo Ilyin(Mekion)做的双足机器人套件,它瞄准的是一个很具体的痛点:想研究双足行走的人,通常要先花掉一笔大钱买硬件,或者先啃完一套庞大的仿真栈。Bimo 把这两件事压缩到一台 45 厘米高、裸机约 1.6 公斤的小机器上,用 8 个 STS-3215 总线舵机驱动,主控是一块自研 RP2040 板子,整套仓库 60 个文件、约 4680 行代码全部 Apache-2.0 授权。

结构上它是「髋-头」(hip-head)双足:每条腿 3 个关节(髋、膝、踝),加上两个肩关节和一个头部关节,头部留出一个空腔和 4 个 M3 安装点,官方标称可挂 1 公斤载荷(挂上去之后需要重新调 CPG 增益或重训 RL)。它有两种形态:装好的 SLS 烧结套件,以及自己 3D 打印组装的 DIY 版;步态、固件、仿真环境和控制 API 对两种版本一视同仁。

Bimo 双足机器人正面照
Bimo 本体:红白双色外壳,8 个 STS-3215 舵机外露在髋、膝、踝、肩与头部关节上,头部是预留 1 公斤载荷的空腔。

硬件规格与自研 RP2040 控制板

规格表里最值得注意的不是尺寸,而是「算力放在哪」这一栏——同一台机器可以在 PC 上算、在头部塞一块 SBC 算,或者完全不要外部计算单元,让 RP2040 自己跑完 20 赫兹的控制闭环。这三种形态对应仓库里三个不同的固件。

项目规格
身高 / 重量45 厘米 / 约 1.6 公斤(不含载荷)
载荷头部最多 1 公斤(需重调 CPG 增益或重训 RL)
执行器8 × STS-3215 总线舵机,12V,堵转扭矩 2.943 牛·米,空载转速 4.712 弧度/秒,减速比 1:345
传感器BNO08x 九轴 IMU、4 × VL53L0X 激光测距、2 × 180° 视场摄像头
主控自研 RP2040 板,通过数据与电源连接器兼容 SBC
通信 / 电源USB 2.0,串口 921600 波特;9–13V 供电,含香蕉插头转接件,不含电池
控制频率20 赫兹(固件里 PERIOD = 50 毫秒)
遥测StateData 结构体 118 字节(__attribute__((packed))):IMU 四元数、4 路测距、8 路舵机的位置/速度/负载/电压/电流/温度、系统电压、RP2040 内部温度
Bimo 控制板引脚图
控制板引脚图:舵机总线走 GPIO 0/1,IMU 走 GPIO 2/3(Wire1),四路测距传感器经 TCA9548A I2C 多路复用器挂在 GPIO 4/5 上,GPIO 6 控制舵机电源开关。A0/A1/A2 是 I2C 复用器的地址选择脚,方便在同一总线上再挂新设备。

两路摄像头固定 30 帧 MJPEG,initialize() 默认取 1280×720,白名单里还有 640×480、640×360、320×240 等八档分辨率;capture_image("front"|"top") 返回单帧 BGR numpy 数组。预置动作是 50 毫秒一步的时序序列,与 20 赫兹控制频率同源。

硬件接线在 MCU/README.md 里写得很细:测距传感器按左、前、后、右的顺序接线,每个接口是 3V3/GND/SDA/SCL 四线;文档明确提醒 GPIO 2、3 已被 IMU 占用、GPIO 4、5 已被 I2C 复用器占用,加新设备前要先查地址冲突。想用电池脱开线缆跑,就把板上的降压模块接到 DATA 口给 RP2040 供电。

走路有三条路

仓库把「让它走起来」按上手成本分成三档,这个分层是 Bimo 最实用的设计之一。

第一档是内置 CPG,开箱即走,不用训练。第二档是基线 RL 策略,用仓库自带的 Isaac Lab 环境训一个行走模型,再按 BimoAPI/examples/nn_walk.py 的推理循环部署。第三档是完全自训:改奖励、改域随机化、加载荷支持,然后自己训。

Bimo 的行走:CPG 步态与 RL 策略都能让它前进和侧向移动。v1.1.0 的状态说明里写的是「CPG 模型可全向行走,RL 策略已实现前向行走的 sim-to-real」——也就是说 CPG 在运动能力上目前反而更完整。

CPG 本身不是神经网络,而是一个六阶傅里叶级数拟合出来的步态发生器。BimoAPI/bimo/cpg.py 里 K = 6,每个关节一组 13 个系数(a0、a1、b1 一直到 a6、b6),八个关节共 104 个浮点数,直接硬编码在源文件里;再叠一层逐关节幅值修正 AMP_GAIN:髋关节 1.7、肩关节 1.0、膝关节 2.0、踝关节 1.5。这组数字的来源在 README 里说清楚了——可以对录制的关节轨迹重新做傅里叶拟合,把新策略「refit」成 CPG。

关节序关节幅值增益位置限幅(度)
0 / 1右髋 / 左髋1.7-90 ~ 90
2 / 3右肩 / 左肩1.0-12 ~ 90 / -90 ~ 12
4 / 5右膝 / 左膝2.00 ~ 140
6 / 7右踝 / 左踝1.5-93 ~ 93

站姿基准是 [-30, -30, 0, 0, 60, 60, 30, 30] 度:髋后摆 30、膝弯 60、踝背屈 30,是个典型的下蹲预备位。转向的做法也写得很直白——在直走的偏置量 CENTER_VALUE 之上,把两个髋关节往相反方向偏,MAX_TURN 限住偏置上限;cpg_walk.py 按航向偏差成比例自动算这个偏置来走直线,cpg_walk_keyboard.py 则改成按住 Q/E 键实时打舵。文档同时提醒 CENTER_VALUE 是逐台标定的常数,自己装出来的机器走不直就要调它。

Python 侧的 Bimo 类把硬件封得很干净:initialize() 一次连上 MCU 与两路摄像头、坐下、标定 IMU 零偏;perform("stand") / perform("sit") 走预置动作;request_state_data() 解包遥测(系统电压按 9 + raw/65535 × 4 还原成 9–13V 区间);send_positions() 直接下发八个关节角度。routines.py 提供 sit / stand 两段预置例程,并允许 add_routine() 注册自己的动作。README 里那句警告很有现场感:示例代码是在坐下之后发站姿角度,写反顺序会让机器人自己往后弹出去。

Isaac Lab 环境:这个项目最值钱的部分

如果只看代码量和工程密度,IsaacLab/ 那 874 行才是 Bimo 的核心资产,而且它带着一份 26MB 的 Bimo.usd 模型(含网格与物理属性),拿过去就能在 Isaac Lab 2.3.2 里直接训。

环境是 DirectRLEnv 写法:物理步长 dt = 0.005 秒、decimation = 10,所以策略每 50 毫秒出一次动作,正好对上真机 20 赫兹的控制频率;回合长度 10 秒。观测量只有 11 维——3 维 IMU 姿态角(roll/pitch/yaw,加 σ=0.015 的高斯噪声后归一化到 [-1,1])加 8 维上一步命令角度,最后统一 torch.round(..., decimals=4)。动作是增量式:网络输出先裁到 [-3,3],乘 4/3 累加到当前命令角上再裁进关节限位,然后叠 σ=0.5° 的执行器噪声。观测量刻意不含线速度、不含关节实测位置,这让它能被 IMU + 「自己上一步发了什么」这两样东西在真机上完全复现——这正是它能 sim-to-real 的前提。

奖励项计算方式
姿态|roll| + |pitch| + 0.6|yaw| ≤ 0.95 时给 1 − √(和/0.95),超过直接 −1;偏航项软化系数 v1.1.0 从 0.5 提到 0.6
躯干高度理想 0.381 米,最大容差 0.3 米,线性映射到 [0,1]
关节位置与站姿基准的偏差,逐关节上限 [90,90,90,90,75,75,90,90] 度,1 − √ 后取均值映射到 [−1,1]
足端离地高度目标 2 厘米,指数衰减 scale=150;双脚同时腾空或同时着地直接给 0
前进速度抛物线跟踪:1 − ((vx − 0.06)/σ)²,σ = 0.03;目标速度 v1.1.0 从 0.1 降到 0.06 米/秒
横向偏移偏离出生点 Y 轴距离,1 − |Δy|/0.2 映射到 [−1,1];前向进度完全交给速度项,这里只罚侧漂

六项奖励权重全是 1,运行时按权重之和归一化。终止条件同样干脆:躯干高度低于 0.1 米,或 |roll|、|pitch| 任一超过 0.95 弧度(约 54°)。

真正体现工程投入的是 actuators/STS3215.py。v1.1.0 把原来的理想电机模型 DCMotorCfg 整个换掉,改成直接继承 ActuatorBase 的显式执行器 STS3215Actuator,按系统辨识出来的真实舵机动力学建模,而且每个物理常数旁边都注明了测法:

参数取值来源
堵转扭矩2.943 牛·米30 公斤·厘米 @ 12V,1:345 减速箱
刚度57.386 牛·米/弧度k = Irefl·ωn²,ωn = 2π × 3.113 赫兹,舵机固件 P=30 下实测
阻尼1.339 牛·米·秒/弧度c = 2ζ·Irefl·ωn,ζ ≈ 0.228 由阶跃响应衰减拟合,D=35
库仑摩擦0.044 牛·米m·g·lCoM·sin θhold,lCoM = 0.19 米,髋关节上实测
带宽3.113 赫兹系统辨识;驱动位置用一阶滞后滤波,α = 1 − e−2π·f·dt
齿隙1.0 ~ 2.4 度真机上实测;方向性齿隙算子,换向时才出现死区,带宽随每次换向重采样
总线延迟1 个物理步 ≈ 5 毫秒数据请求 + 推理 + 执行往返,固定不随机

域随机化铺得也很密:连杆质量按 ±5% 均匀缩放并重算惯量;地面只保留 flat 地形但带 ±1 毫米的高度场噪声;地面材质静摩擦 0.6、动摩擦 0.5;每个环境的足垫单独随机成 TPU 材质,静摩擦 0.3~0.7(动摩擦再减 0.1)、恢复系数 0~0.05、接触刚度 5e4、阻尼 8e2;每 2~4 秒对头部做一次速度清零式推搡;舵机堵转扭矩在 2.7~2.94 牛·米之间分 24 档循环,对应 10~12V 的母线电压波动。

训练配置在 agents/rsl_rl.py:BimoPPORunnerCfg 用 [256,128,64] 的 actor/critic、学习率 3e-3、每环境 16 步、500 次迭代,配 2048 个并行环境跑 headless,README 标称 5~6 分钟出结果。PPO 与蒸馏是两个独立注册的 Gym task ID,切换只要改 --task 参数。

蒸馏到 MCU:拔掉电脑也能走

这是整条链路最完整的一段闭环。先训 PPO 教师网络([256,128,64]),再用 Bimo-Distillation 任务训一个 [64,32] 的学生网络去模仿它,师生两侧的观测都做归一化;play 脚本自动导出 ONNX 到 bimo_ppo_rsrl 目录;然后用 onnx2c 把这个小 ONNX 转成 C 代码,编进 micro_bimo_nn.ino。

Bimo 的动作演示:预置例程与步态切换。

转出来的固件里能看到接口签名 entry(const float tensor_obs[1][11], float tensor_actions[1][8]),和 Isaac Lab 环境的 11 维观测、8 维动作严丝合缝。固件自己复现了原本由主机做的 IMU 俯仰/横滚零偏标定、站立例程和航向锁定——因为脱机之后主机根本不在。它用 pico/multicore 把双核分开跑,整个主机通信协议被整段删掉。另一份 micro_bimo_cpg.ino 走同样的脱机结构,但驱动步态的是那张 C 数组形式的傅里叶系数表 CPG_COEFFS[8][13]——和 Python 版 cpg.py 里的数字一模一样,不需要蒸馏也不需要 onnx2c。

同一份步态在 Python 与 C 里各存一遍,代价是改一处要同步两处,收益是 20 赫兹闭环可以完全跑在一颗几美元的 RP2040 上。这是小机器人项目里少见的、把「sim-to-real 一直做到 MCU」走完的例子。

ROS2 封装:单一硬件所有者

ROS2/ 是 v1.1.0 新加的一层,1431 行。设计上只承认一个节点 bimo_comms 持有硬件——它是唯一碰 /dev/ttyACM* 和 /dev/video* 的进程,其他节点一律通过话题和服务进来:订阅 /bimo/cmd_action、发布 /bimo/state,外加 alive、perform_routine、add_routine、get_routine、calibrate、lock/unlock_heading、capture_image 共 8 个服务。

仲裁用的是一个优先级工作队列(queue.PriorityQueue):动作指令的优先级高于周期性状态轮询,所以策略输出不会卡在一次例行传感器读取后面;perform_routine、calibrate 这类长耗时操作走另一条回调路径保持节点响应,执行期间收到的 cmd_action 会被丢弃并打日志告警,而不是迟到后才被执行。examples/ 里的 CPG 行走节点和 ONNX 策略节点被明确定位成参考实现,控制律怎么写留给用户。

开源到底彻不彻底

这个问题要分两半回答,因为 README 的承诺和仓库的现状并不完全一致。

软件层面是彻底开源的,但「全部文件都带许可证头」这句要打个折扣:60 个文件里 21 个手写源码带 SPDX 头(BimoAPI 7、IsaacLab 5、MCU 3、ROS2 核心 6),另外 32 个文本文件——8 份 README/CHANGELOG、3 个 LICENSE、两份 setup.py、msg/srv 接口定义、package.xml、launch 文件,以及 3 个 ROS2 脚手架自动生成的 test_*.py——没有逐文件头,改由根目录和两个 ROS2 包各自的 LICENSE 覆盖,均为 Apache-2.0。其余 7 个是图片与 USD 二进制。控制 API、三个固件、ROS2 封装、Isaac Lab 环境、执行器模型、PPO 与蒸馏配置,连同 26MB 的 Bimo.usd 机器人模型都在仓库里。步态本身也完全公开——CPG 的 104 个傅里叶系数和逐关节增益在 Python 与 C++ 里都能读到,RL 侧的奖励、终止条件、域随机化、执行器物理常数一个不落。想复现或改步态,不需要向作者要任何东西。

类别状态仓库里有什么
控制 API / 固件 / ROS2已开源BimoAPI 1023 行、MCU 1349 行、ROS2 1431 行,全部 Apache-2.0
步态(locomotion)已开源CPG 傅里叶系数表(Python + C 双份)、Isaac Lab 874 行(奖励/DR/执行器模型/PPO+蒸馏)
仿真模型已开源IsaacLab/bimo/assets/Bimo.usd,26MB,含网格与物理 prim
结构 CAD未开源README 第 20 行明写「CAD files (coming soon)」;工作树与全部 git 历史里没有任何 STL / STEP / F3D / 3MF
电路设计未开源没有原理图、KiCad 工程、Gerber 或 BOM;只有 assets/pcb.png 一张引脚图渲染
预训练权重未提供没有 policy.onnx 或任何 checkpoint;v1.0.0 与 v1.1.0 两个 release 的附件数都是 0,nn_walk.py 需要你自己训出来的权重
DIY 装配手册未开源README 标注「DIY Manual (coming soon)」

换句话说,License 那一节写的「All code and CAD designs are, and will, be released under the Apache 2.0 License」是个前瞻性表述——代码已经在了,CAD 还没在。仓库同时提供「自己 3D 打印组装的 DIY 版」这条路径,但没有图纸的情况下这条路目前走不通,能落地的入口是 mekion.com/product 上的预订。所以准确的说法是:Bimo 现在是一个软件与算法完全开源、硬件设计尚未放出的项目。

这个缺口的实际影响因人而异。做步态研究、做 sim-to-real 方法验证、或者想读一份注释详尽的小机器人执行器辨识代码,现有内容已经足够,甚至可以说比多数同类项目更完整——很多项目只放策略不放执行器模型。想从零复刻一台整机,则必须等 CAD 与电路放出来。

项目状态

当前版本 v1.1.0(2026-09-01),仓库最后推送 2026-09-03,198 star、8 fork。官方状态说明写得很坦白:CPG 模型可全向稳定行走,RL 策略已完成前向行走的 sim-to-real;项目处于预订阶段,预订量达标后发货,随后进行 CE/FCC 认证与交付。合作方是西班牙工业组织学院 EOI 与 CNC 加工服务商 JLCCNC。

CHANGELOG 也值得一读,它记录的不只是功能增加,还包括一批诚实的缺陷修复:v1.1.0 修掉了动作累加不裁进关节限位导致的「命令角越绕越远」问题,修掉了 reset 时 base_pose[0] 误用第 0 行而非按环境索引的问题,修掉了重置后 last_position 仍保留上一回合终点的状态泄漏;速度奖励从「30/70 混合前进速度与偏航惩罚」重构成单一的抛物线速度跟踪项,横向偏移奖励不再奖励前向进度,地形从含 rough/slope 简化为纯 flat。对一个还在预订期的小项目来说,这种把改坏的地方写清楚的变更记录,比一句「性能提升」有用得多。

相关开源项目

作为亚马逊联盟会员,我们可能从符合条件的购买中获得佣金。