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,项目处于预订阶段。
一台 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 对两种版本一视同仁。
硬件规格与自研 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 内部温度 |
两路摄像头固定 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.0 | 0 ~ 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 个文件全部带 SPDX 头,根目录和两个 ROS2 包各有 LICENSE,均为 Apache-2.0。控制 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。对一个还在预订期的小项目来说,这种把改坏的地方写清楚的变更记录,比一句「性能提升」有用得多。