1. 仿生蝴蝶飞行器的整体设计思路与方案选型
1.1 为什么选择蝴蝶作为仿生对象
做扑翼飞行器的人,第一个要回答的问题就是:仿谁?蜂鸟、蜻蜓、蝙蝠、蝴蝶,各有各的气动优势。我当初选蝴蝶,不是因为它好看,而是因为它的飞行雷诺数区间和我们的目标尺寸最匹配。蝴蝶的翼展通常在5到15厘米,拍翅频率在5到12赫兹之间,这个频率区间对微型舵机和轻量化结构非常友好——你不需要像做蜂鸟那样追求30赫兹以上的高频驱动,那对材料和驱动器的要求会直接上一个数量级。
更关键的是,蝴蝶的翅膀是柔性膜结构,在拍翅过程中会产生被动的形变,这种形变能显著提升气动效率。工程上这意味着你不需要用复杂的主动控制去实现每个攻角变化,翅膀自己会“自适应”。这一点在低功耗设计里极其重要,因为省下来的每一个毫瓦都意味着更长的续航或者更小的电池。
从生物机理上讲,蝴蝶的飞行肌肉属于间接飞行肌,它通过改变胸腔形状来驱动翅膀,而不是直接拉动翅根。这种结构的能量转换效率很高,而且有一个天然的弹性储能机制——每次拍翅的动能有一部分被胸腔的弹性结构回收,用于下一次拍翅。我们在工程实现上虽然不能完全复刻这套生物结构,但可以用碳纤维骨架加预张力薄膜来模拟这种弹性储能效果。
1.2 低功耗扑翼设计的核心矛盾
低功耗是这类飞行器最头疼的问题。扑翼飞行器和固定翼、旋翼最大的区别在于:它的升力来源是周期性的非定常气动力,这意味着驱动系统必须持续做功,没有巡航状态下“油门收小”的概念。你只要在飞,舵机或者电机就在不停地正反转。
我实测过一组数据:一台翼展12厘米的仿生蝴蝶,如果用SG90舵机直驱,悬停状态下电流稳定在280到350毫安,峰值能到600毫安以上。一块300毫安时的锂电池,理论上撑不过一个小时,实际因为电压下降和效率损失,四十分钟左右就歇了。这个续航水平连基本的室外飞行都很难保证。
所以低功耗设计的核心矛盾就变成了:如何在保证足够拍翅频率和力矩的前提下,把驱动系统的平均功耗压下来。这里面涉及三个层面的优化——驱动器的选型、传动机构的效率、以及控制策略的优化。后面我会逐一展开。
1.3 方案选型的几个关键决策
在正式动手之前,我对比了几种常见的驱动方案:
| 方案 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| 空心杯电机+减速组 | 效率高、转速快 | 需要减速机构、无法直接输出摆角 | 高频扑翼、蜂鸟类 |
| 微型舵机直驱 | 控制简单、角度精确 | 功耗偏高、死区损耗 | 低频扑翼、蝴蝶类 |
| 电磁驱动器 | 响应快、结构简单 | 力矩小、发热严重 | 超微型、厘米级 |
| 压电陶瓷驱动 | 功耗极低 | 位移小、驱动电压高 | 微型扑翼、实验室阶段 |
最终我选了微型舵机直驱方案,具体型号是MG90S金属齿舵机。原因很直接:MG90S的扭矩在2.0kg·cm左右(4.8V供电),足够驱动12厘米翼展的碳纤维翅膀;金属齿轮比塑料齿轮耐磨损,扑翼这种高频往复运动对齿轮的磨损很严重;而且舵机自带位置反馈,控制上只需要给PWM信号就行,不需要额外的编码器。
但MG90S的静态电流是个问题——它在保持位置的时候也在耗电。所以我后来改用了总线舵机方案,只在需要改变角度的时候才发送指令,舵机内部在到达目标位置后会进入低功耗保持状态。这个改动让待机功耗从原来的80毫安降到了15毫安左右。
1.4 碳纤维骨架的设计逻辑
碳纤维在这类项目里的角色不是“锦上添花”,而是“没有它根本做不出来”。原因很简单:扑翼飞行器对重量的敏感程度远超你的想象。我用3D打印的PLA翅膀骨架试过,单只翅膀重量4.2克,换成碳纤维之后降到了1.1克。两只翅膀省下来的6克重量,直接决定了你能不能多带一块电池。
碳纤维的选型也有讲究。我试过1mm、1.5mm和2mm的碳纤维棒,最终主梁用了1.5mm的,翅脉用了0.8mm的。主梁需要承受拍翅时的弯矩,太细会断,太粗会重;翅脉只需要维持翼膜的形状,不需要承受太大应力,所以越轻越好。
翼膜材料我用的是0.05mm厚的聚酯薄膜,预张力控制在5%左右。这个预张力很关键——太松了翅膀会兜风,产生不了足够的升力;太紧了翅膀失去柔性形变的能力,气动效率反而下降。我试了3%、5%、8%三档,5%是综合表现最好的。
2. 核心细节解析与实操要点
2.1 舵机驱动机构的几何设计
舵机直驱扑翼,最核心的机械设计就是曲柄摇杆机构。舵机输出轴连接一个曲柄,曲柄通过连杆推动翅膀根部的摇杆,把舵机的旋转运动转换成翅膀的上下拍动。
这里有一个很容易踩的坑:曲柄长度和摇杆长度的比例。我一开始随便设了个1:1,结果翅膀的拍动角度只有30度左右,升力严重不足。后来算了一下,拍动角度θ和曲柄半径r、连杆长度L的关系大致是:
θ ≈ 2 × arcsin(r / L)
要让拍动角度达到60度以上(蝴蝶的正常拍翅幅度),曲柄半径和连杆长度的比值至少要0.5。我最终用的是曲柄半径6mm、连杆长度10mm,理论拍动角度约73度,实际因为机构间隙和舵机行程限制,实测在65度左右,够用了。
还有一个细节:连杆和摇杆的连接点位置。这个点越靠近翅膀根部,力矩越大但拍动角度越小;越远离翅膀根部,拍动角度越大但舵机负载越重。我试了三个位置,最终选在距翅根15mm处,兼顾了角度和负载。
2.2 低功耗控制策略的实现
低功耗设计不只是选个低功耗芯片就完事了,控制策略本身对功耗的影响可能比硬件选型还大。
我一开始用的是Arduino Nano加SG90舵机的组合,代码就是最简单的servo.write()循环。实测功耗在320毫安左右。后来做了三个优化:
第一个优化是降低PWM更新频率。舵机不需要每毫秒都接收新指令,我改成每20毫秒更新一次,功耗降到了280毫安。这个改动很小,但效果立竿见影。
第二个优化是使用舵机的休眠模式。很多总线舵机支持在到达目标位置后自动断电保持,我用的这款可以通过串口指令设置保持力矩为0。代价是翅膀在风阻下会被吹动,但对于蝴蝶这种低频扑翼,风阻的影响在可接受范围内。这个改动直接把平均功耗拉到了180毫安。
第三个优化是动态调整拍翅频率。起飞和爬升阶段用8Hz,巡航阶段降到5Hz,下降阶段用3Hz。这个策略让整体飞行功耗又降了约25%。
最终实测:悬停状态平均电流210毫安,巡航状态160毫安,配合一块500毫安时的电池,续航能到2.5小时左右。这个数据在同类项目里算是相当能打的了。
2.3 主控芯片的选型对比
主控芯片的选择直接决定了你能不能实现上面那些低功耗策略。我前后试了三款芯片:
STM32L151C8T6A是我最开始用的,Cortex-M3内核,低功耗模式做得很好,Stop模式下电流只有1.5微安。但它的PWM输出通道有限,控制多个舵机的时候需要外扩,增加了布线和重量。
HC32L196是后来换的,国产芯片里低功耗做得相当不错的一款。它的优势是外设丰富,自带多路PWM,而且有硬件死区控制,对舵机控制很友好。实测运行功耗比STM32L151低了约15%。
GD32E503CC我也试过,性能更强,但功耗偏高,更适合需要复杂运算的场景,比如带激光测距和实时姿态解算的版本。
最终我选了HC32L196作为主控,配合STM32L151做传感器数据处理,双芯片分工。这个方案看起来复杂,但实际上两块芯片都跑在低功耗模式下,整体功耗反而比单芯片方案更低。
2.4 电源管理与复位电流问题
复位电流是我踩过的最大的坑之一。你辛辛苦苦把运行功耗降到了200毫安以下,结果一测待机功耗,发现电池还是在掉电。查了半天才发现是复位电路的漏电流。
大部分单片机的最小系统板上,复位引脚会接一个上拉电阻和一个电容。这个上拉电阻如果阻值太小(比如常见的10kΩ),在复位引脚被拉低的时候会产生持续的漏电流。我实测过,10kΩ的上拉电阻在3.3V供电下,漏电流约0.33毫安。听起来不大,但24小时就是8毫安时,对于小容量电池来说很致命。
解决办法很简单:把上拉电阻换成100kΩ,漏电流降到0.033毫安。代价是复位响应变慢,但对于扑翼飞行器这种不需要频繁复位的应用,完全没问题。
还有一个容易被忽略的点是舵机的静态电流。即使舵机不动作,它的控制电路也在耗电。我实测MG90S的静态电流约8毫安,总线舵机约3毫安。如果你用了4个舵机,光静态电流就是12到32毫安。所以能少用舵机就少用,能用总线舵机就不用PWM舵机。
3. 实操过程与核心环节实现
3.1 碳纤维骨架的制作流程
碳纤维骨架的制作是整个项目里最考验手工的环节。我前后做了七套骨架,前五套都因为各种原因报废了,第六套才勉强能用,第七套才算满意。
第一步是切割碳纤维棒。我用的是1.5mm和0.8mm的碳纤维棒,用斜口钳切割。注意:切碳纤维一定要戴口罩和护目镜,碳纤维粉尘对呼吸道和眼睛的刺激很大。切的时候不要用力过猛,碳纤维会劈裂,切口不平整。
第二步是打磨切口。用400目砂纸把切口磨平,然后用600目精磨。这一步不能省,切口不平整会导致后续粘接不牢固。
第三步是搭建主梁结构。蝴蝶的翅膀主梁不是一根直杆,而是有一个自然的弧度。我用两根1.5mm碳纤维棒交叉粘接,形成一个类似“人”字形的结构。粘接剂用的是环氧树脂AB胶,固化时间选的是30分钟的,太快的强度不够,太慢的等得着急。
第四步是粘接翅脉。翅脉用0.8mm碳纤维棒,按照蝴蝶翅膀的脉序排列。这里不需要完全复刻生物结构,但要有基本的放射状分布,保证翼膜在受力时不会局部塌陷。我用的是5主脉+8副脉的布局。
第五步是覆膜。聚酯薄膜裁成比骨架大一圈的尺寸,用喷胶均匀喷涂后覆盖在骨架上。覆膜的时候要从翅根向翅尖方向赶,把气泡赶出去。覆膜完成后用吹风机热风收缩,薄膜会紧紧包住骨架。
注意:覆膜后的翅膀要静置24小时再装机,让胶水完全固化。我试过覆膜后直接装机,结果飞行中薄膜脱落,整个翅膀报废。
3.2 舵机控制代码的实现
控制代码这块,我用的是HC32L196的官方库,配合自己写的PWM控制逻辑。核心思路是:用定时器产生50Hz的PWM信号,通过改变占空比来控制舵机角度。
// 舵机PWM初始化(以HC32L196为例) void Servo_PWM_Init(void) { stc_tim3_init_t stcTim3Init; stc_gtim_pwm_init_t stcPwmInit; // 使能TIM3时钟 PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM3, Enable); // 定时器基础配置:50Hz,周期20ms TIM3_StructInit(&stcTim3Init); stcTim3Init.u16ClockDiv = TIM3_CLOCK_DIV1; stcTim3Init.u16Period = 20000; // 20ms周期 TIM3_Init(&stcTim3Init); // PWM通道配置 stcPwmInit.u16CompareValue = 1500; // 初始1.5ms,舵机中位 stcPwmInit.u16Mode = GTIM_PWM_MODE1; stcPwmInit.u16Polarity = GTIM_PWM_POLARITY_HIGH; GTIM_PWM_Init(TIM3, GTIM_CHANNEL_1, &stcPwmInit); GTIM_PWM_Cmd(TIM3, GTIM_CHANNEL_1, Enable); TIM3_Cmd(Enable); } // 设置舵机角度(0-180度) void Servo_SetAngle(uint8_t angle) { // 0.5ms对应0度,2.5ms对应180度 uint16_t compareValue = 500 + (angle * 2000) / 180; GTIM_SetCompareValue(TIM3, GTIM_CHANNEL_1, compareValue); }这段代码的关键在于compareValue的计算。舵机的控制信号是周期20ms的PWM,高电平时间0.5ms对应0度,2.5ms对应180度。所以compareValue = 500 + (angle * 2000) / 180,单位是微秒。
实际使用的时候,我不会让舵机在0到180度之间全范围运动,因为扑翼只需要60到70度的拍动角度。所以我会把角度映射到60到120度之间,这样舵机的响应更快,功耗也更低。
3.3 低功耗模式的配置
HC32L196的低功耗模式配置是省电的关键。我主要用了两种模式:Sleep模式和Stop模式。
Sleep模式下,CPU停止运行,但外设继续工作。这个模式适合在两次拍翅之间使用,因为定时器还在跑,可以定时唤醒CPU更新PWM。实测Sleep模式电流约1.2毫安。
Stop模式下,所有时钟停止,只有外部中断能唤醒。这个模式适合在飞行器待机时使用。实测Stop模式电流约2微安。
// 进入Sleep模式 void Enter_SleepMode(void) { // 配置唤醒源为定时器中断 TIM3_IntCmd(Enable); NVIC_EnableIRQ(TIM3_IRQn); // 进入Sleep模式 __WFI(); } // 进入Stop模式 void Enter_StopMode(void) { // 配置唤醒源为外部中断(比如遥控器信号) EXTI_Init(); // 关闭不必要的外设时钟 PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM3, Disable); PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_UART1, Disable); // 进入Stop模式 PWC_StopModeEnter(); }提示:进入Stop模式之前一定要把不用的外设时钟关掉,否则漏电流会比你想象的大得多。我一开始没关UART时钟,Stop模式电流一直在200微安下不来,查了半天才发现是UART的漏电。
3.4 飞行测试与数据记录
飞行测试我是在室内无风环境下做的,用一个简易的测试架把飞行器固定住,只允许它绕一个轴自由转动,这样可以测量升力和功耗的关系。
测试设备:可调电源(模拟电池)、电流表、转速计、风速计。
测试步骤:
- 把飞行器固定在测试架上,连接可调电源,电压设为3.7V(单节锂电池标称电压)。
- 从3Hz开始,逐步增加拍翅频率,每次增加1Hz,记录电流和升力数据。
- 每个频率点稳定运行30秒后读数,取平均值。
实测数据:
| 拍翅频率 | 平均电流 | 升力 | 功耗 |
|---|---|---|---|
| 3Hz | 95mA | 8.2g | 0.35W |
| 5Hz | 160mA | 14.5g | 0.59W |
| 7Hz | 245mA | 19.8g | 0.91W |
| 9Hz | 380mA | 23.1g | 1.41W |
从数据可以看出,升力随频率增加但边际效益递减,而功耗几乎线性增长。5Hz是一个比较好的平衡点,升力足够(飞行器总重约12克),功耗可控。
4. 常见问题与排查技巧实录
4.1 舵机抖动与复位问题
问题现象:舵机在运行过程中突然抖动,然后回到中位,飞行器失去控制。
排查过程:一开始怀疑是PWM信号干扰,换了屏蔽线之后问题依旧。后来用示波器看电源波形,发现舵机动作瞬间电源电压从3.7V跌到了2.9V,触发了单片机的欠压复位。
根本原因:舵机启动瞬间的浪涌电流太大,锂电池的内阻和线路电阻导致电压跌落。
解决方案:在舵机电源引脚并联一个470μF的低ESR电解电容,再并联一个0.1μF的陶瓷电容滤高频。电容的作用是提供瞬态电流,把电压跌落控制在0.2V以内。这个改动之后,舵机抖动问题彻底解决。
实操心得:电容要尽量靠近舵机的电源引脚,引线越短越好。我一开始把电容放在电源板上,离舵机有10厘米的线,效果大打折扣。后来直接焊在舵机引脚上,效果立竿见影。
4.2 翅膀不对称导致偏航
问题现象:飞行器起飞后总是往一个方向偏,遥控需要一直修正。
排查过程:先检查了舵机的中位是否一致,用示波器测了两路PWM的占空比,误差在1%以内,排除控制信号问题。然后检查翅膀,发现左右翅膀的重量差了0.3克,而且右翅的预张力比左翅大。
根本原因:手工制作翅膀的时候,覆膜的张力和胶水的用量很难完全一致,导致左右翅膀的气动特性有差异。
解决方案:两个办法。一是制作的时候用电子秤称重,每只翅膀的重量控制在±0.05克以内。二是软件上做补偿,给偏重的一侧舵机加一个微小的角度偏移。我最终用的是软件补偿,因为手工控制重量太难了。
补偿的方法很简单:在代码里给左右舵机的角度加一个偏移量,通过遥控器的微调通道来调整。实测偏移量在3到5度之间就能修正大部分偏航。
4.3 低功耗模式唤醒失败
问题现象:配置了Stop模式之后,飞行器进入待机就再也唤不醒了,必须断电重启。
排查过程:查了芯片手册,发现Stop模式下只有特定的外部中断能唤醒,而且中断触发方式必须是边沿触发,不能是电平触发。我一开始配置的是电平触发,所以唤醒不了。
根本原因:中断触发方式配置错误。
解决方案:把外部中断改成上升沿触发,并且在进入Stop模式之前清除所有中断标志位。另外,唤醒之后需要重新配置系统时钟,因为Stop模式下时钟停止了,唤醒后默认用的是内部低速时钟,需要手动切回外部高速时钟。
// 唤醒后的时钟恢复 void SystemClock_Recover(void) { // 切换回外部高速时钟 PWC_Unlock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1); CLK_SetSysClockSrc(CLK_SYSCLK_SRC_XTH); while (CLK_GetSysClockFreq() != 24000000); // 等待时钟稳定 PWC_Lock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1); }4.4 常见问题速查表
| 问题 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 舵机不动作 | PWM信号未输出 | 示波器测PWM引脚 | 检查定时器配置和引脚复用 |
| 舵机抖动 | 电源电压跌落 | 示波器测电源波形 | 并联大电容 |
| 飞行偏航 | 翅膀不对称 | 称重和目视检查 | 软件补偿或重新制作 |
| 续航不足 | 静态电流过大 | 万用表测待机电流 | 换低功耗舵机、优化复位电路 |
| 唤醒失败 | 中断配置错误 | 查芯片手册 | 改边沿触发、恢复时钟 |
| 翅膀断裂 | 碳纤维疲劳 | 目视检查 | 增加主梁直径或换更高模量碳纤维 |
4.5 几个容易被忽略的细节
第一个是舵机线的重量。三根20厘米的杜邦线重量约2克,换成漆包线能降到0.5克。对于总重12克的飞行器来说,这1.5克的减重相当于续航提升10%以上。
第二个是电池的放电曲线。锂电池在3.7V到3.4V之间能放出大部分容量,但低于3.4V之后电压下降很快。如果你的低功耗设计让工作电流很小,电池电压会一直维持在较高水平,实际可用容量反而更大。我实测在200毫安放电下,500毫安时电池能放出约460毫安时的电量,效率92%。
第三个是温度对舵机的影响。舵机内部的电机和齿轮在低温下阻力增大,功耗会上升。我在10度环境下测试,同样的拍翅频率,电流比25度时高了约15%。如果要在室外飞行,冬天续航会明显缩短。
第四个是碳纤维的导电性。碳纤维是导电的,如果骨架和电路板接触,可能会造成短路。我在骨架和电路板之间垫了一层0.5mm的绝缘胶带,这个细节很容易被忽略,但一旦短路就是烧板子的事。
4.6 关于仿生手臂舵机的跨界参考
做这个项目的过程中,我参考了不少仿生手臂的舵机方案。仿生手臂和仿生蝴蝶在舵机控制上有不少共通之处:都需要多路舵机协调运动,都对功耗敏感,都需要精确的位置控制。
仿生手臂常用的总线舵机机械臂方案给了我很大启发。总线舵机通过串口通信,一根线可以串联多个舵机,大大简化了布线。我在后来的版本里也改用了总线舵机,虽然单个舵机贵一些,但省下来的线材重量和布线复杂度完全值回票价。
另外,仿生手臂里常用的舵机PWM控制和舵机控制原理也是相通的。舵机的核心就是一个带位置反馈的减速电机,控制信号是PWM,反馈信号是电位器的分压。理解了这一点,不管是控制蝴蝶翅膀还是机械臂关节,底层逻辑都是一样的。
5. 后续优化方向与个人体会
这个项目做到现在,基本功能已经稳定了,但离我心目中的“完美”还有距离。下一步我打算在几个方向上继续折腾。
第一个方向是柔性翼膜的主动形变控制。现在的翼膜是被动形变,如果能用形状记忆合金或者介电弹性体做主动形变,气动效率还能再提升一截。不过这些材料的驱动电压很高,低功耗设计会面临新的挑战。
第二个方向是视觉导航。我试过用树莓派Pico加激光测距做避障,但Pico的功耗对于这个项目来说还是偏高。后来换成了ESP32做WiFi图传,功耗也不理想。目前还在找更合适的方案,可能最终会用低功耗蓝牙做遥控和遥测,把图像处理放到地面站。
第三个方向是集群飞行。单只蝴蝶的载荷能力有限,但如果能做出多只协同飞行,就能携带更大的载荷。这涉及到低功耗蓝牙组网和分布式控制,复杂度会高很多,但想象空间也大很多。
最后分享一个我在这个项目里体会最深的一点:低功耗设计是一个系统工程,不是换个低功耗芯片就能解决的。它涉及到器件选型、电路设计、控制策略、机械效率的每一个环节。你在这个环节省了1毫安,在那个环节省了2毫安,加起来就是可观的续航提升。反过来,任何一个环节的疏忽,比如一个上拉电阻选错了,就能把你所有的优化成果吃掉。
我踩过的坑包括但不限于:复位电路漏电、舵机静态电流、PWM更新频率过高、碳纤维短路、翅膀重量不对称、Stop模式唤醒失败。每一个坑都花了我至少一个晚上去排查。但正是这些坑,让我对这套系统的理解深入了很多。如果你也在做类似的项目,希望这些经验能帮你少走一些弯路。