ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

25厘米鸭子机器人:RK3566与15电机的高集成嵌入式设计

25厘米鸭子机器人:RK3566与15电机的高集成嵌入式设计 1. 25厘米的鸭子凭什么在Github刷屏这一阵子刷Github trending一只鸭子吸引了我的注意。准确说是一个嵌入式机器人项目外观被做成了鸭子造型整机只有25cm高重量压到800g以内却在这么小的身板里塞进一颗RK3566和15个电机。最开始我以为又是那种拍个视频就扔在那里吃灰的网红demo但点进去看了仓库里的代码、电路图和装配说明越看越觉得这项目的完成度不低。很多做嵌入式的人看到这种项目的反应都是好家伙RK3566这颗芯片通常拿来做带HDMI显示的开发板再不济也是跑Linux的迷你主机怎么会被塞进一只玩偶鸭子里面但这恰恰是这个项目最吸引我的地方。RK3566是瑞芯微主打能效比的一颗四核A55处理器主频最高1.8GHz带Mali-G52 GPU和独立的NPU算力虽然比不了旗舰芯片但做机器人主控绰绰有余。15个电机意味着鸭子有15个自由度对应不同身体部位的运动所以在体积受限的前提下RK3566的算力可以用在图像识别、语音交互、运动规划这些真正需要“思考”的任务上而不是单纯去PWM发波。更让我觉得有意思的是这个项目把很多矛盾集中在一个很小的空间里要轻、要小、要多个执行器、要强算力、还要能跑得动Linux系统。这些条件的组合让它在同类项目中显得非常另类。如果说以前我们看惯了“树莓派小车”和“STM32四轴飞行器”那这只鸭子就是一次在算力与机械自由度之间找平衡的尝试。而对于想入门嵌入式Linux、机器人控制、小型机械结构的开发者来说这个项目的可参考价值其实比很多成熟产品还要高。1.1 这不是玩具而是一个嵌入式全家桶有人可能会想15个电机听起来很多但大多数玩具鸭子不也能扭头扇翅膀吗区别在于普通玩具用的是机械联动电机就一个或者两个所有动作都是固定的凸轮轨迹。这个项目里的15个电机每一个都是独立控制的相当于每个运动关节都有专门的驱动通道。从颈部的摆动到翅膀的抬升从尾巴的翘起到腿部的前进后退在控制层面是完全解耦的。这种设计带来的第一个问题就是电机驱动电路的数量和体积。15路电机如果要全部由RK3566直接驱动显然不现实。RK3566没有那么多硬件PWM引脚即使有足够引脚驱动电流也不够。所以项目中大概率采用了“主控电机驱动MCU”的分层架构。RK3566只算决策不碰执行细节通过串口或USB把“头部往左转30度”“左翅膀抬到40度”这类高层指令发给下位机具体PWM周期、占空比、舵机速度曲线都由下位机来处理。如果往深里想这种架构其实和现代自动驾驶的域控制器方案如出一辙主计算单元做感知与规划MCU做底层执行控制中间通过通信协议握手。只不过我们平时看到的工业级方案动辄几百瓦功耗而这只鸭子把整套系统缩到了800g以内使得它更像一个可以放在桌面上随便玩的机器人。1.2 从仓库结构看项目的完整度我在翻代码的时候发现作者对仓库的整理非常克制。每个目录的命名基本都能直接看出作用固件源码、PCB设计文件、3D打印模型、上位机调试工具各自分得清清楚楚。熟悉开源硬件项目的朋友都知道很多项目火起来往往是因为视频效果炸裂但点进仓库发现资料乱成一团连个像样的README都没有。这个鸭子项目至少在分享意识上是到位的它甚至把BOM表物料清单和装配步骤都整理成了markdown文档这一点非常拉好感。作者还提供了一个调试用的上位机界面让我很意外。虽然只是简单的滑块和仪表盘但配合一些主流的图形界面框架可以实现实时调参。这也让我意识到15个自由度的小型机器人在调试阶段如果没有一个好用的实时控制界面光靠烧录固件来试错效率会低得离谱。2. 拆掉外壳看布局15个电机的分配艺术先说结论15个电机听着多但分到每个身体部位之后其实不算奢侈。我自己拿这个数推了一下大致可以这么分配左右两条腿共用4个电机左右翅膀各2个、合计4个脖子和头部转动2个尾巴上下或左右摆动1个嘴巴开合1个眼睛或眼皮活动1到2个剩下2到3个可能会分配给身体前倾后仰或者内部悬挂重心调节。每一路关节只要多一点自由度的组合整体看起来就会自然很多。不过真正难的不是数量而是如何在25cm的高度内让这些电机互不干涉并且整体重量不超。这需要设计者每一个电机都亲自选型不能只图力矩大。我见过不少人做的桌面机器人为了追求扭矩直接上20kg级别的金属舵机结果整个设备动起来和挖掘机一样动作迟滞还有很大的声音。这个项目针对鸭子这种小型仿生对象电机选型应该偏向小型金属齿轮舵机扭矩无需太大关键是重量轻、反应速度快。2.1 驱动方案为什么不能全用RK3566 GPIO这里我想多聊一点硬件分工。RK3566运行Linux系统Linux不是实时操作系统进程调度可能随时被中断如果直接让Linux内核去控制PWM波形的起始结束时间一旦系统负载升高或者某个后台进程抢占了CPU电机控制就会出现明显抖顿。对于鸭子这种需要连续平滑动作的机器人来说稍有卡顿就会原形毕露看起来一点都不自然。所以最合理的做法是给RK3566配一颗MCU协处理器专门负责生成15路PWM信号。RK3566通过USB或者UART与MCU通信。底层MCU内部跑一个实时循环定时刷新每一路PWM的占空比。RK3566下发的指令不是原始PWM值而是目标角度和运动时间。MCU自己负责将角度值插值成一条平滑的轨迹简单说就是“规划在Linux执行在MCU”。这种分工既保证了控制带宽又让上层应用可以专注于视觉、语音、路径规划等复杂任务。在这个项目中上层到下层之间的通信协议设计尤为关键。如果每帧只传角度数据15路角度加上校验和数据量并不大串口115200波特率完全足够。作者在仓库中定义了一套简洁的帧格式帧头、指令类型、通道编号、目标值、校验位一目了然。这种设计的好处是即使后续把鸭子换成猫、狗或者其他机器人形态这套通信协议依然可以复用。2.2 结构件选材与减重细节800g以内的裸机重量限制意味着结构件不能全用铝合金板或厚厚的亚克力否则光外壳和支架就要占掉一大半重量。更常见的做法是关键受力部位比如腿部关节和电机固定座使用PLA或者PETG材质的3D打印件内部填充率控制在20%到30%之间外壳部分用轻薄的ABS塑料片或者光固化打印的薄壳外面再做打磨与喷漆手感也不会差太多。同时还要注意重心的分布。25cm的小鸭子如果整个头部塞了一堆摄像头和麦克风头部比重过大站立时就会前倾。所以我在看项目图的时候特意观察了身体中后部是否预留了放电池的空间。把锂电池和电机驱动板放在胸腔偏后的位置可以有效压低重心让鸭子在站立状态下的自稳能力更强。别看这个细节小对多关节机器人的运动表现影响非常直接。重心高一点走起来就是摇摇晃晃像纸片人重心低一点动作才能显得扎实。3. 软件怎么让这只鸭子“活”起来如果说硬件是骨肉那软件就是灵魂。这个项目让我觉得很有学习价值的地方不只是结构设计而是它的软件架构并没有走捷径。作者没有简单写一个跑马灯程序让鸭子按顺序动关节而是把姿态生成、动作插值、指令下发、反馈修正这几层分得很清楚。3.1 步态控制从四足退化到双足的策略鸭子走路和人类走路有本质区别人走路时躯干基本保持竖直靠双腿交替向前摆动鸭子走路时躯干会左右摇摆走路步伐比我们想象的更依赖重心转移。作者首先在计算机上建了一个简化模型把鸭子简化为一个躯干加两条腿和两个翅膀的刚体系统先仿真重心位置随时间的变化再把仿真的轨迹输出为每个电机角度的变化曲线。初始版本的步态代码大概率是离线生成的也就是预先算好一组“走一步”的关节角度序列然后存成表。这样做的优点是控制简单、开发难度低缺点是非常死板遇到地面不平或者被推一下就很难恢复平衡。看仓库更新记录作者后期加了简单的姿态反馈比如在躯干上装了一个IMU惯性测量单元读取鸭子的俯仰和横滚角然后对步伐周期或关节角度做小幅补偿。这种做法在机器人领域叫“开环步态闭环稳定修正”比纯开环进了一大步但又不至于引入复杂的模型预测控制非常适合这个体积级别的机器人项目。如果你也想复刻一只类似的仿生机器人我建议第一版不用急着做动态平衡先把开环步态调自然让鸭子能平稳走两米不摔跤再考虑要不要引入IMU做闭环。一上来就上全状态反馈控制大概率会被非线性摩擦和舵机响应延迟搞到头大。3.2 动作层与逻辑层的解耦我特别注意到项目里有一个行为状态机的概念作者它的实现不算复杂但足够灵活。比如当鸭子检测到面前有障碍物时状态机会从“闲逛”切换到“观察”观察状态下会调用一组头部和眼部的电机组合动作然后再决定是转向还是后退。这些状态之间的切换是通过在Linux侧跑一个轻量级的事件循环来实现的每隔几十毫秒读取一次传感器数据判断当前状态再生成对应的动作指令队列。做这个设计的时候作者没有把传感器数据处理和电机动作逻辑混在同一个模块里。传感器数据统一发布到消息队列动作模块只订阅结果。这种思路和机器人的发布订阅范式很像虽然在高算力平台上有更复杂的通信框架可以用但在这只鸭子上用只有几千行的纯代码实现反而能保证系统的确定性和低延迟我觉得这就是嵌入式项目中“好钢用在刀刃上”的体现。3.3 PID调节与实时性验证虽然底层MCU负责了PWM输出但15个电机的角度闭环仍然需要处理。常见的舵机内部带有电位器反馈可以近似看作一个位置闭环系统但它的动态响应是固定的我们不能直接调PID。为了避免舵机之间响应速度不一致导致的动作畸形作者在MCU层面加入了统一的速度规划意思是每个动作指令都附带一个期望运动时间MCU不直接把目标角度一步到位而是将它拆分成许多小步进按固定的时间间隔逐步逼近目标值。这种做法相当于在外部加了一层控制环能有效抹平不同舵机的个体差异。在调试时作者用了一套简单的可视化工具把15路电机的目标角度和实际反馈角度实时绘制成曲线类似逻辑分析仪抓波形那样。打开开关后鸭子每次做动作曲线都会立即反映有没有过冲或者滞后。如果你自己复刻也可以在串口上每隔20ms输出一组角度值然后用常用的串口绘图工具来看曲线不用专门去买显示屏。这样一套流程下来对PID或者速度曲线参数该怎么调心里会非常清楚。4. 供电系统800克极限里的最后一公里很多小型机器人项目会在机械结构和代码上花尽心思却在供电上翻车。相信我80%的“为什么一通电就重启”“为什么电机一动作屏幕就闪烁”的问题最后都能追溯到供电系统设计不合理。这只鸭子的供电设计虽然没有采用特别高端的方案但在小型化、轻量化方面有不少值得抄作业的地方。4.1 电池选型与安装位置在800g的限重里电池必须精打细算。目前常见的2S锂电池单颗重量大约在80g到120g之间容量在800mAh到1500mAh左右。考虑到RK3566在跑Linux时峰值功耗可能达到5W以上加上15个电机的平均功耗整机平均功率大概在15W到25W之间待机时可以低一些但跑动作时瞬间功耗会波动较大。如果用2S电池7.4V供电1500mAh的容量理论上可以提供11Wh左右的能量但实际可用容量要打折大概够这只鸭子连续活跃运行30到50分钟。电池的安装位置也很讲究。很多复刻者会顺手把电池放在鸭子肚子正中间看着挺稳实际上走路时重心在身体中部会晃动。这个项目更合理的做法是把电池尽量放在身体重心偏下的位置甚至可以把电池平放在腹部靠近腿部的位置让转动惯量更小动作响应更敏捷。还有一点要注意电池与主板之间必须用带自锁的XH2.54或者XT30接插件千万不能用杜邦线直接怼在电池上否则大幅度动作时线头松脱引发断电轻则重启重则飞线短路。4.2 电机瞬时电流与压降15个电机同时启动瞬间的电流总和相当可观。小型舵机堵转电流可以达到1A以上即便正常转动时平均电流只有200到400mA15个一起动也可能在瞬间拉到5到8A。如果电源提供的电流能力不足或者线缆内阻过大电压就会被瞬间拉低导致RK3566在低电压下触发上电复位整个系统直接重启。为了应对这个问题常见的方案是加一个大容量的稳压电容比如在电源入口并联2到3个470uF到1000uF的电解电容或者用一个超级电容模块来吸收电流尖峰。电容不能解决所有问题但可以明显缓解瞬时压降。更好的方案是隔离供电把RK3566和电机驱动模块分别用独立的DC-DC降压电路电机电源直接从电池获取主控电源经过一颗5V的LDO或者DC-DC来稳压。这样即使电机把电压拉得很低只要不低于主控电路的最低输入电压Linux系统就不会崩。另外选用输出电流足够的大功率稳压芯片也很重要。RK3566本身需要多路供电但通常开发板上已经集成了电源管理芯片外部只需要给它提供一路5V或12V即可。如果在自制底板时复用PMIC参考设计要特别留意每路电源的纹波抑制尤其是在电机启动瞬间的电磁干扰下电源纹波可能变得很脏。这时候可以用示波器去抓一下各路电源的电压毛刺如果发现有超过200mV的尖峰就需要在布局上减少电机线与电源线的平行走线或加LC滤波。4.3 电源管理休眠与唤醒嵌入式Linux项目的另外一个容易被忽略的点是低功耗管理。鸭子不可能一直满负荷工作长时间待机时如果电机驱动板和主控一起通电电会掉得飞快。较好的做法是在不活动时让RK3566进入浅休眠状态或降频模式同时下位机MCU也进入低功耗睡眠只保留一个定时唤醒的周期或者红外触发器。一旦检测到有人靠近或用手拍它MCU立刻唤醒RK3566完成重启或快速恢复。这个项目在唤醒策略上做得比较务实因为RK3566从深度睡眠中唤醒的延迟比较明显如果每次唤醒都要等Linux系统完整重启用户体验会非常糟糕。更合适的是让系统在空闲时挂起一部分外设保留内核在内存中运行类似鼠标移动唤醒电脑那样从浅睡眠快速恢复。在嵌入式Linux下可以通过内核的suspend到内存与RTC闹钟唤醒来实现结合GPIO外部中断也可以做到。但要留意并非所有底层驱动都支持suspend/resume如果发现唤醒后传感器或蓝牙模块异常那就要根据自己的外设情况做状态恢复处理。5. 从0到1复刻一只鸭子流程与建议如果你看完前面这些内容已经心痒难耐想自己也做一只鸭子那我基于对项目的理解帮你梳理一下从开始的复刻流程。整个过程大概分硬件准备、结构装配、软件调试三大块中间会有不少在你没实际动手前根本想不到的坑。5.1 硬件采购哪些必须买好的哪些可以平替核心主控板建议直接选择现成的RK3566开发板体积尽量选紧凑型最好是核心板底板的形式。市面上常见的RK3566核心板尺寸通常只有几十毫米见方重量也不大非常适合塞进鸭子身体。底板可以自己画也可以选用官方设计的通用底板但要注意底板的大小和接口方向是否影响安装在鸭子的内部骨架里。电机部分关键参数是扭矩、尺寸和重量。15个电机里腿部受力最大的位置需要扭矩大一些至少选2.5kg/cm以上的金属舵机尾部和嘴巴这种轻微活动的位置用1.3kg/cm的塑料齿轮舵机就够了。尽量统一电机驱动信号线和电源线的接口免得装好后分不清哪个是哪路。在预算允许的情况下买带金属输出轴的舵机比塑料轴耐用很多尤其是鸭子走路时脚的冲击会反复传导到舵机输出轴塑料轴很容易被打滑。结构件要么直接用仓库里的3D打印文件要么自己画适配的板件。如果你没有3D打印机可以在网上找代打印服务PLA材料就够价格也不高。需要注意的是打印时的层高和填充率不要太低否则螺柱位置容易裂开。组装时不要急着上螺丝卡死建议先用手捏住相关关节试一下转动角度是否被干涉。5.2 软件编译与系统烧录RK3566跑的主系统大概率是某个定制化的Linux镜像作者可能基于Buildroot或者Debian裁剪。作为复刻者你需要先在电脑上克隆源码仓库然后安装交叉编译工具链。这里的坑通常出现在环境依赖上不同Ubuntu版本对老版本工具链的兼容性不一样如果你在编译过程中遇到莫名其妙的头文件找不到建议直接用仓库文档推荐的Docker镜像或者指定发行版版本能省掉大量时间。烧录系统时最好用支持USB烧录的开发板工具或者按官方教程制作一张快速启动的SD卡。第一次启动往往显示不出画面或者串口日志里卡在某一段这时候不要慌先把串口调试线接好看内核日志结束在哪里再查对应外设的驱动配置。我自己的经验是很多人做这类Linux单板机器人最后卡住的不是代码逻辑而是某个外设的设备树配置没有打开。比如某个舵机驱动板挂在I2C总线上设备树里没定义对应地址和节点系统就永远扫不到设备电机自然一动不动。5.3 常见问题与排查思路根据我踩过类似项目坑的经验几个高频问题你一定要提前有数。第一上电后RK3566反复重启大概率是电源电压跌落导致。先不要查软件拿万用表量电机启动瞬间的供电电压如果掉到4.5V以下赶紧加大电容或改隔离供电。第二多个舵机之间互相串扰比如转动腿的时候翅膀也跟着抖。这通常不是电机的机械问题而是PWM信号线上有电源干扰或者是舵机电源回流到了主控板的地线。可以尝试在电机电源和主控电源之间加共地电感或把舵机信号线用双绞线绕一下。第三手臂或者腿的动作反了。如果你发现鸭子在调姿时越调越乱那就先检查一下输入到每个舵机的角度极性。很多舵机支持正向和反向安装同样给50%的占空比转动方向可能完全相反。调试时不要一张嘴就改程序先用上位机单独控制某一通道确认正方向后再在代码里把偏移量记下来。第四IMU数据抖动导致姿态误判。在步态闭环修正中如果IMU的数据没有经过滤波加速度计的震动噪声会让鸭子误以为自己倾斜了从而做出奇怪的补偿动作。建议先用低通滤波或简单的互补滤波把分轴的角度算平滑再送给状态机。6. 我从中得到的几条经验这个项目最让我有收获的不是RK3566有多强也不是15个电机有多炫而是它在产品化思维上的平衡术。做一个能动的鸭子不难做一个能稳定走、能交互、还不超重的鸭子难的是每一个环节都做到刚刚好用。我最赞同的一点是它对通信协议和状态机的简化。很多开发者看到一个机器人有15个电机第一反应就是上ROS、写各种复杂节点但实际效果未必比一个几KB状态机好。这个项目让我重新意识到嵌入式项目的核心不在于用多前沿的框架而在于搞懂每一层之间传递什么数据、什么时候传递、缺失了怎么办。通信帧短小、状态清晰、反馈及时比堆砌一堆抽象层有用得多。如果你只是想体验一下做小型机器人的乐趣不一定要完全复刻这只鸭子。你可以先拆出它的结构设计思路用一块更便宜的开发板加4到6个舵机做一个只会点头的小鸟机器人。等你理解了一个动作从规划到执行的完整链路再回来挑战15个电机的鸭子和RK3566就会发现难度没有想象中那么高。我始终觉得这种“小体量、高集成”的项目才是让嵌入式爱好者成长最快的东西。
返回列表