如果你第一次看到“colibri”这个名字,可能以为它是某个轻巧的软件工具。但懂得法语的朋友已经看出来了,这是“蜂鸟”的意思。我把我这个迷你扑翼机器人项目命名成 colibri,一部分是因为它确实想模仿蜂鸟的飞行方式,另一部分是因为这个项目一开始就给自己立了一个规矩:小而轻、反应要快。
这个项目最终做出来的是什么东西呢?严格来说,它还不是一架能真正到处飞的蜂鸟无人机,而是一台翼展约20厘米的桌面级扑翼验证平台。它用一对高速往复摆动的翅膀产生升力,并通过机身上的姿态传感器和控制板,在一个柔性万向台上完成姿态稳定实验。说白了,就是把“蜂鸟为什么能悬停”这个复杂问题,拆成一个可以放在桌面上反复打磨的小系统。
我自己玩了几年嵌入式,也折腾过四轴、车模这类常见机器人,但真正让我觉得有意思的,反而是这种“看起来做不成”的扑翼装置。它不像四轴那样有现成的飞控和桨叶,几乎每个环节都要自己从物理层面重新想。如果你也想尝试一个不套模板的硬件项目,colibri 的这套思路可以直接拿过去用。
1. 项目整体设计与思路拆解
1.1 蜂鸟飞行到底难在哪里
蜂鸟这个物种在飞行上是开了挂的。常见的中型蜂鸟拍翅频率能达到50Hz左右,更小的吸蜜蜂鸟甚至能到80Hz,起飞和急转时还会更高。作为对比,普通鸽子拍翅频率只有5Hz上下。这意味着蜂鸟的翅膀在一秒钟内完成几十次完整的上抬和下压,整个机构一直处于高频率的动态变化中。
更麻烦的是,蜂鸟悬停时翅膀并不是简单地上下拍,而是在空中画出类似“∞”的形状。它在向下压和向上回程两个过程中都产生升力,靠的就是翅膀在运动过程中不断改变攻角,让翼面每一瞬间都能把空气“推向正确方向”。普通鸟类的回程是收翅滑行,蜂鸟则是全程发力,所以它才能像直升机一样钉在半空。
这些生物学事实直接决定了仿生项目的难度。第一,动力系统必须能支撑高频往复运动;第二,翼面必须能在高频运动下产生主动扭转;第三,控制系统的采样和响应速度要比普通四轴高出一个量级。这三点缺一不可,否则做出来的东西要么翅膀摆不起来,要么摆起来但没有任何升力,要么能飞但完全无法稳定。
1.2 设计目标:先复刻“高频扑动”,再谈悬停
很多朋友看到蜂鸟悬停的视频,第一反应是“我也要做一个能悬停的”。我一开始也是这个想法,结果被现实教育之后,把目标拆成了三个台阶。
第一台阶是做出一对能高频、同步、稳定往复摆动的翅膀;第二台阶是把姿态传感器和控制器装上去,在一个受限的万向节台架上验证“扑翼状态下姿态能不能稳住”;第三台阶才是把整机从台架上解耦,尝试自由飞行。
目前这个 colibri 做到的是第一台阶到第二台阶之间的部分。为什么不做整机自由飞?因为扑翼飞行器整机涉及材料疲劳、结构共振、控制延迟、电池能量密度等一系列问题,任何一个环节出问题都会直接炸机。与其在一堆不确定性里试错,不如先把核心问题锁定在台架上,让失控和油门拉满的情况都只发生在实验平台上。这个思路和我当年玩穿越机的做法有点像:先在模拟器里练方向感,再拿真机下场。
1.3 整机模块划分
整个系统我按功能拆成了五个模块,方便每个模块单独调试和替换:
| 模块 | 核心部件 | 作用 | 备注 |
|---|---|---|---|
| 机械动力 | 微型空心杯电机、减速齿轮组、曲柄摇杆 | 把电机旋转变成翅膀往复摆动 | 全项目最关键的机构 |
| 翼面 | 碳纤维翼梁、PET薄膜翼膜 | 在扑动中产生升力和推力 | 翼根要留扭转自由度 |
| 姿态感知 | MPU6050六轴传感器 | 提供角速度、加速度原始数据 | 安装时注意减震 |
| 控制核心 | STM32F103/ESP32 | 输出PWM、跑姿态环、记录数据 | 实时性要求高 |
| 供电 | 1S锂电池 3.7V 300~500mAh | 给电机和主控供电 | 验证机可以外接稳压源 |
这样分完模块之后,任何一个环节出问题,都可以独立拆下来排查。我在做之前先把模块图贴在墙上,后面所有调试都是按这个框架走,避免了“不知道哪里在拖后腿”的困境。
2. 核心细节解析与关键元器件选型
2.1 扑翼机构:曲柄摇杆方案
整个仿蜂鸟项目里,机构设计是第一关,也是水最深的一关。一开始我想到的最简单方案是用舵机直接带着翅膀往复摆动。但常见的9g舵机工作在50Hz刷新率下,实际能支持的连续大幅摆动频率只有几赫兹,而且越靠近极限位置越没力。这个方案很快就排除了。
第二个想到的是凸轮机构。凸轮理论上可以精确控制翅膀在任何时刻的位置,甚至能复现蜂鸟那种非正弦运动曲线。但凸轮的设计和加工成本高,磨损之后间隙会越来越大,调试期想改一个参数几乎要重新做一版零件。对于验证机来说太不友好。
最后用的是经典的曲柄摇杆机构:电机带动曲柄连续旋转,曲柄通过连杆推动摇杆,摇杆再带着翅膀往复摆动。它的好处是结构简单、零件少、成本低,而且曲柄半径和连杆长度都是可以快速替换的参数,非常适合做实验。
具体参数上,我给自己定的目标是翅膀单边摆幅大约20到25度。如果按近似公式算,摆角的弧度值约等于2倍曲柄半径除以摇杆长度。曲柄半径4.5毫米、摇杆长度20毫米时,单边摆幅约合0.22弧度也就是12度多,要更大摆幅的话需要继续加大曲柄半径或缩小摇杆长度。我最终选了曲柄半径6毫米,摇杆长度20毫米,配上35毫米的连杆,实测单边摆幅大概在25度左右。连杆长度一定要大于曲柄好几倍,否则运动过程会明显卡顿,这是曲柄摇杆机构的先天特性。
这里有个容易踩的坑:两个翅膀必须挂在同一根驱动轴上,不能各用各的电机。各用各的电机意味着左右相位不可能长期同步,蜂鸟飞行本身就要左右高度协同,一旦相位差拉大,整个机身会像喝醉一样摇摆。同轴驱动不能保证左右翼面角度完全一致,但至少相位是锁死的。
2.2 电机与减速组:参数先算清楚
蜂鸟扑翼频率高,但普通微型电机转速更高,而且扭矩远远不够。所以电机和减速组必须当成一个整体来选。
我选的微型空心杯电机,工作电压3.7V,空载转速在五万转左右,也就是大约833转每秒。如果想达到最开始定的10Hz翼频,减速比大概是833除以10,约等于83比1。市面上常见的微型齿轮箱有30比1、50比1、100比1这几个挡位,最后我选了50比1和100比1各买了一套,实测下来50比1偏快、扭矩也够用,100比1扭矩很大但拍翅频率只有8Hz左右,静升力反而不好。最后留在机器上的是50比1那一套。
这里提醒一句:空载转速不是带载转速。接上曲柄摇杆之后,负载会让实际转速掉下来不少,所以理论算出来的翼频只能作为选型参考。真正确定方案之前,最好把电机、减速组、机构全部装好,用几百帧的慢动作视频数一下实际翼频。
供电方面,验证机阶段我直接用了稳压电源,电压从3.3V慢慢往上加,等机构稳定后再换成锂电池。如果一开始就把1S电池接上去,大油门瞬间电流可以到1.5A以上,电池内阻压降会造成转速波动,排查起来特别麻烦。
2.3 传感器与控制板选型
控制板我选了STM32F103,因为手头熟悉,主频72MHz跑姿态环富余很多。如果你更熟悉ESP32,也完全没问题,只是要注意ESP32的ADC线性度一般,最好不用它直接采集模拟油门信号。
姿态传感器用的MPU6050,型号老旧但足够稳定,I2C接口400kHz模式下可以做到很高采样率。真正要注意的是传感器的安装位置和减震。扑翼机的振动比四轴大得多,电机和机构的震动会直接传导到传感器。我用一片薄泡棉双面胶把MPU6050垫高,再固定在机体的几何中心附近,避开电机正上方。
控制频率上,我按500Hz来跑主要姿态环,对应2毫秒一个控制周期。这个频率远高于翼频10Hz,理论上能覆盖扑翼带来的周期性扰动。如果控制频率降到100Hz,就会出现明显的滞后。
2.4 材料与总成本
机身骨架用2毫米碳纤维圆杆,强度和重量比非常好。关节和底座用3D打印制作,材料选了PETG,比PLA韧性高很多,不会在反复拆装的时候脆断。翼面用0.05毫米PET薄膜,超市里的文档封套那种厚度就可以,便宜且平整。
总成本我列了一个清单:
| 部件 | 参考价格 | 说明 |
|---|---|---|
| 主控板 STM32F103 | 15元 | 常见最小系统板 |
| MPU6050模块 | 12元 | 买带稳压的 |
| 空心杯减速电机 | 30~50元 | 含50:1齿轮箱 |
| 碳纤维杆、打印件 | 20元 | 打印几个版本 |
| PET薄膜、双面胶 | 5元 | 做翼面 |
| 万向节/支架 | 30元 | 台架调试用 |
| 锂电池 1S 300mAh | 20元 | 后段测试换电池 |
整套下来大约150到200元,没有特别贵的零件。这也是我把项目命名为colibri的另一个原因:蜂鸟是轻量化的极致,这个项目也应该尽量小巧便宜,而不是堆钱堆料。
3. 实操过程与核心环节实现
3.1 第一步:先搭静态样机,验证机构
我强烈建议不要一上来就通电。先把电机拆掉,手动转动曲柄,观察整个机构是否顺畅。这一步看着简单,实际上是整个项目里回报最高的一步。
具体做法是:把打印好的曲柄、连杆、摇杆和碳纤维机身装在一起,曲柄末端固定一个小拨杆方便手转。慢慢转动一整圈,观察左右两个翅膀的摆动角度是否一致、关节处有没有卡顿。如果某个位置明显发涩,就用小锉刀修一下轴承孔,或者换更长的连杆改善运动角度。
静态测试时还要用角度尺或手机上的量角app,实测一下翅膀的极限摆角。我这个版本的机构理论摆幅是25度左右,实测差不多在23到26度之间摆动。如果偏差太大,一般是连杆长度和设计值有误差,重新打印一个更长的连杆就能解决。
这个阶段听起来很枯燥,但能修掉后面80%的机械故障。第一次通电时如果翅膀抖动异常、角度不对称,多半就是这个环节没做扎实。
3.2 翼面制作:柔性扭转是灵魂
蜂鸟和普通鸟类最大的不同,在于回程也产生升力,而这个特性要落到翼面上,就只能靠扭转来实现。翼面光有刚性不够,还得在运动过程中自然弯曲扭转。
我做翼面的方法是:翼骨架前缘用1.5毫米碳杆,后缘先用0.8毫米碳杆或尼龙线拉紧。翼膜裁剪成比骨架四周大出几毫米的形状,先把前缘用双面胶固定住,再把膜向斜后方慢慢抻平,最后用胶水固定在翼尖和后缘。注意在翼根位置留出一小段不粘死,让翅膀在扑动时能顺着空气阻力产生扭转变形。这一段看似不起眼,实际却是产生升力的关键自由度。
左右翼膜的张力一定要尽量保持一致。张力不同会导致左右翅膀的扭转角不同,升力不均衡,机器的姿态就会出现固定方向的偏航。我在第一次试机时就因为左侧翼膜拉得更紧,导致机身一直往右下侧偏,白白排查了半天。
3.3 电气接线与最简控制程序
装完机构以后开始通电。我的电气连接顺序是:锂电池或稳压电源接到主控板的5V输入,电机由主控板PWM输出驱动一个MOS管开关,MPU6050用I2C挂到主控上。为了调试方便,我还外接了一个电位器作为油门,这样不用每次改代码才能调节翼频。
程序方面,先写一个最简的开环版本,只做一件事:读油门,输出PWM,间隔读数并打印到串口。不要一开始就加PID。
// Colibri v0.1 开环调试代码骨架 #include <math.h> void pwm_init(void) { // 配置为20kHz PWM,初始占空比0 } void set_motor_pwm(float throttle) { // throttle: 0.0 ~ 1.0,映射到定时器比较值 } int main(void) { pwm_init(); imu_init(); // MPU6050 初始化 uart_init(); // 串口日志 float throttle = 0.0f; while (1) { throttle = read_throttle_pot(); // 电位器采样 set_motor_pwm(throttle); imu_read_raw(); // 先只读,不上环 uart_printf("%.3f\n", throttle); delay_us(2000); // 500Hz 循环 } }这段代码的价值在于先跑通“电信号 -> PWM -> 电机 -> 机构”这条链路。如果这个环节就不正常,后面所有控制都无从谈起。在确认开环稳定之后,再把IMU的原始数据串进上位机观察波形,最后才把串级PID放进去。
3.4 台架试运行:从“抽搐”到“平稳扑翼”
第一次通电时,我的机器表现得惨不忍睹:翅膀高频颤动,机身跟着抖,像一只得了帕金森的机械鸟。后来排查发现原因不复杂——PWM频率设成了1kHz,电机每毫秒才被刷新一次,扭矩输出就变得很顿挫,翅膀自然就抽搐。把PWM频率改成20kHz之后,这种现象瞬间消失。
还有一种“抽搐”来自机构虚位。如果各个关节的孔比轴大了零点几毫米,高频运动下所有间隙都会被放大,翅膀就会甩出杂乱的微小抖动。解决办法是在关节处塞一小段特氟龙套管,消除多余间隙。
机构顺畅之后,把油门从零慢慢往上推。注意观察两个现象:一是机身有没有共振点,通常在某个特定翼频下整个台架会抖得特别厉害,这时直接跳过这段油门;二是翅膀是否有“呼呼”的风感,用手放在翅膀下方能明显感觉到排气气流,说明翼面扭转已经开始起作用了。
等这些都在台架上稳定运行后,我用240帧慢动作视频数了一下实际翼频,大约在13Hz左右,比设计的10Hz高一点,说明减速组负载比预想的小。整个系统在这个状态下非常稳定,机身的姿态偏移只剩很小的周期性晃动。
4. 常见问题与排查技巧实录
4.1 翅膀不对称,左右相位差越来越大
这个问题在第一次通电时几乎必然出现。现象是右翼比左翼慢半拍,或者右翼明显“甩”得更厉害。先看电机轴到两个曲柄的传动路径,只要有一段出现打滑或虚位,就会导致左右不对称。同轴驱动能锁相位,但不能消除结构上的差异。
排查顺序是:先断开电源手动转动曲柄,左右各量一次极限角度;再用游标卡尺对比左右连杆长度,误差超过零点几毫米就必须换;最后看翼膜张力,这是最容易被忽略的。三个因素都排除干净了再谈软件补偿,别指望PID能替你修好机械误差。
4.2 电机带不动翅膀,或者转几圈就发烫
电机带不动机构,最常见的原因是减速比选小了。也就是说,电机输出转速太高,但经过曲柄摇杆之后没剩下多少扭矩。另一个原因是连杆和曲柄夹角太小,机构在某个位置处于“死点”,需要靠惯性冲过去。碰到这种情况,要么换更大减速比的齿轮箱,要么把连杆加长,让机构运动学更平滑。
电机发烫则要查电流。我用万用表测过,正常工况下整机电流在0.8A左右,但如果机构卡滞,电流会瞬间飙到2A以上。这个时候别急着换电机,先用手转一圈曲柄找卡点,多数时候是轴承孔太紧或者齿轮啮合带齿。
4.3 IMU数据全是噪声,姿态环没法闭
扑翼平台的振动和四轴完全不同,振幅不大但频率很高,直接作用于传感器。我第一次把MPU6050贴在碳杆正中,读取到的加速度数据在静态悬停时也能上下蹦0.5g,姿态角解算出来根本没法用。
第一道防线是物理减震,用薄泡棉双面胶垫高传感器,很多项目这一步就能解决大部分噪声。第二道防线才是软件滤波,我在姿态环前加了一阶低通滤波,截止频率大约30Hz,压住了高频振动。第三步是把采样率提高,用500Hz以上的采样,让滤波器有足够的样本来做平滑。
这里有一个经验之谈:如果原始数据的噪声已经大到超出物理规律,任何滤波都救不回来。一定要先看原始数据,再决定上什么滤波算法。
4.4 一加大油门机身就抖,控制环稳不住
机身抖动不一定是机构问题,也可能来自共振。扑翼机在工作时会有一个固有频率,如果翼频正好落在这个共振区,整个台架就会剧烈晃动。这种抖动用PID是压不掉的,反而越调P越崩。解决办法是微调油门让翼频避开共振频率,或者在机身与台架之间加橡胶垫,改变系统的固有频率。
如果共振解决后姿态环仍然发散,一套比较稳妥的调参顺序是:先只调角速度环,P从很小的值往上加,直到机身不再出现高频嗡鸣;再加D,抑制超调;I最后加,用来消除静态误差。我现在的参数里P是0.02,D是0.05,I保持0,在这个平台上已经能满足验证机需求。
4.5 调试参数速查表
为了方便后续复刻,我把当前方案的关键参数整理成一张表:
| 项目 | 参数 | 备注 |
|---|---|---|
| 翼展 | 20cm | 碳杆翼骨架最外端距离 |
| 翼弦 | 3~4cm | 根部到翼尖渐缩 |
| 翼频 | 10~15Hz | 实测约13Hz |
| 单边摆角 | 20~25度 | 曲柄半径6mm,摇杆20mm |
| 减速比 | 50:1 | 30:1和100:1实测不理想 |
| 整机重量 | 约45g | 验证机不含台架 |
| 控制频率 | 500Hz | 2ms中断 |
| PWM频率 | 20kHz | 电机驱动 |
| 角度环参数 | P=2.0, D=0.3 | 参考值,按机构微调 |
| 角速度环参数 | P=0.02, D=0.05 | 参考值 |
这张表不是终点。换了材料、改了翼面积之后,很多参数都要跟着变,但它可以作为你调试时的起点,能省掉大量从头摸索的时间。
最后再分享一个小体会。colibri这个项目做到现在,我最大的感触是,仿生类的硬件项目里,真正难的不是算法,不是代码,而是把机械机构、动力和传感器这三样东西磨合成一个整体。很多问题看着像控制问题,追根溯源其实是结构问题。你先把机构调顺、翼面做对,后面所有事情都会顺起来。如果你也想试试类似的扑翼项目,建议从这台20厘米的小家伙开始,别一上来就想着复刻蜂鸟的悬停特技。蜂鸟用了千万年进化出的技能,我们用几十块钱的电机和几根碳杆能摸到一点门道,已经很值了。