
简介电赛平衡小车轮腿式平衡小车.zip 是一份面向全国大学生电子设计竞赛及机器人开发的轮腿式自平衡小车工程资料适合有嵌入式与自动控制基础的读者用于备赛或项目复现。资源共 1311 个文件约 49.48MB主体为 619 个 C 源文件、316 个头文件及少量 C 代码用于控制算法与底层驱动同时包含汇编启动文件、ARM CMSIS 数学库.a/.lib、Keil.uvprojx与 CMake 构建配置、.hex/.bin 固件和 .md/.txt 文档方便理解编译链接与烧录调试。已有 581 人学习。压缩包内可深入参考轮腿式小车的 MCU 初始化.ioc、IMU 传感器数据读取与滤波、PID 或更高级控制算法、电机驱动及运动控制逻辑大量编译中间文件和调试配置则有助于对照工程检查构建过程。对学习动态平衡原理、嵌入式系统设计和机器人竞赛准备这是一份能直接落到代码级的高价值参考。 凌晨一点半实验室的空调还在嗡嗡响。我蹲在地上看着那辆轮腿式平衡小车第十二次试跑它终于在一段胶带接缝处站住了然后又被一个微小的绊脚点甩了出去齿轮箱发出让人心里发紧的咔嗒声。问题不在代码在结构——轮腿式方案比纯两轮平衡车多了活动关节任何一个关节的间隙超过0.3mm整车的体感就会从顺滑滑向癫痫。点开这个名为电赛平衡小车轮腿式平衡小车.zip的存档里面不是一份简单的工程文件而是包括完整的STM32固件工程、3D打印结构件图纸、原理图与PCB、以及一套从头到尾的踩坑调参记录。这篇文章我打算按这个存档的目录顺序把从机械结构设计、主控与传感器选型、双环PID整定逻辑到赛前最终测试的完整过程做一次复盘不藏着掖着。这套方案适合三类人正在备赛电赛运动控制类小车的队伍想认真研究倒立摆与串级PID的嵌入式爱好者以及手里有平衡车散件但始终调不稳、想换个技术路线的同学。看完你能大致明白一个反直觉的结论很多平衡小车调不好根源往往不在你写的代码里。1. 轮腿式结构定版让小车从只能跑变成能停能越障1.1 轮腿结构到底给小车增加了什么传统两轮平衡小车的控制思路已经很成熟直立环加速度环数学上就是一个倒立摆问题。但电赛环境里有个隐藏风险——评测场地的地面不是理想平滑平面黑线胶带边缘、地板拼接缝、甚至测试时评委临时放的一个小障碍都可能让纯两轮车在速度稍快时直接翻车。两轮平衡在动态下确实灵活但它的静态稳定性为零一旦需要定点停车超过几秒电机就得一直做小幅修正耗电和控制压力都不小。轮腿式结构解决的就是这个痛点。它本质上是在两个动力轮上方各加一组平行四边形连杆连杆末端是辅助支撑脚。正常运行的时候腿收在中位整车是标准的倒立摆当需要静态保持或越障时腿部通过舵机下压让车身在轮轴以外多出两个支撑点整车从动平衡切换成静平衡。这个设计最有价值的地方是把平衡控制从必须时刻在线降级成大部分时间在线比赛现场遇到不平地面或者需要长时间停车读传感器时控制压力会小一个量级。1.2 尺寸、材料与重心分配方案机械定版时我给自己定了几个硬约束这些数字直接影响后续控制参数别随意改整车质量控制在1.2kg左右两个直流减速电机带霍尔编码器减速比30比1输出轴装68mm橡胶轮轮距140mm整车宽度控制在150mm以内车身平台距离地面大约110mm重心投影落在轮轴正上方略微偏前的位置。轮距这个参数最容易被忽略它决定了小车在倾角方向上的转动惯量占比。轮距越宽抗侧倾能力越强但转向时左右电机差速带来的横摆干扰也会更明显。140mm这个值是在二者之间妥协下来的测试时能明显感觉到比120mm的版本稳得多。轮腿部分的材料我全部用PETG 3D打印没有用PLA。原因很实际PLA在舵机反复下压、车身颠簸受力的场景下容易脆断尤其打印层间结合力不够连续跑二十分钟就可能从应力集中点裂开。PETG韧性好、打印难度略高但作为承载结构件值得多花这点时间。腿的核心是平行四边形四连杆不是简单的一根摆动杆因为四连杆能保证支撑脚在运动过程中始终与地面保持平行这样停车时四个支撑点能同时接触地面不会出现三条腿撑着、一条腿悬空的尴尬局面。装配环节有一个细节值得说所有关节孔位我都预留了0.2mm装配间隙配合M3金属轴套使用。如果直接用塑料轴孔摩擦长时间跑下来孔径会被磨大虚位会越来越大而虚位一旦变大姿态环每个周期都会读到额外的噪声PID怎么调都压不下去。0.3mm是一个经验阈值超过这个值平衡车的抖动会开始变得可见。2. 主控、传感器与执行机构的选型搭配2.1 主控为什么选了STM32F103RCT6而不是更高端的型号这个选择可能让一些同学意外。电赛圈子里F407、H750很常见但具体到平衡小车F103RCT6的算力完全够用而且生态成熟、参考资料多团队里任何一个人都能快速上手改代码。直立环跑1kHz速度环跑100Hz再加上串口遥控指令解析和OLED状态显示F103的负载大概在40%左右余量充足。换F407的真正理由只有一个如果打算同时跑摄像头循线或者更重的视觉处理才需要更高主频或者额外的协处理器。如果小车方案里已经有OpenMV这类视觉模块单独处理图像那主控就安心做运动控制F103反而是更稳妥的选择功耗低、启动快、出问题概率小。电机驱动我用了DRV8833双路H桥每路最大1.5A持续电流。两个370电机堵转时电流能到2A以上但正常运行时平均电流在400mA上下DRV8833留出了足够余量。要注意的是PCB布线时电源线能短则短、能宽则宽别为了好看把电机地线绕一大圈再接电池负极否则电机启停瞬间的压降会通过地线干扰陀螺仪读数这种干扰在示波器上看起来像高频毛刺非常迷惑人。2.2 姿态解算不用DMP自己写一阶互补滤波姿态传感器是MPU6050通过I2C接在主控上。MPU6050内部自带DMP可读四元数很多现成例程直接调用它但我在这个项目里没有用DMP而是自己写了一阶互补滤波原因有两点。第一DMP的输出频率有上限实际跑下来稳定输出在100-200Hz之间而直立环控频是1kHz如果每个控制周期都去I2C读DMP解算出的欧拉角I2C总线会成为瓶颈姿态数据还带着几毫秒的额外延迟。第二DMP把姿态解算封装成了一个黑盒比赛现场如果发现角度数据有异常你很难判断是传感器安装问题还是DMP配置问题。自己写互补滤波虽然代码多一些但每个环节都透明出了问题可以逐级排查。一阶互补滤波的核心思路不复杂陀螺仪积分得到的高频角度可信但长时间积分会漂移加速度计通过反正切算出的角度没有漂移但高频噪声大。把两者融合起来公式可以写成angle 0.98 * (angle gyro_y * dt) 0.02 * accel_angle其中gyro_y是绕俯仰轴的角速度accel_angle由加速度计分量算出。0.98和0.02这两个系数是关键它们决定了陀螺仪和加速度计的信任权重。我这个项目里采样频率1kHzdt0.001秒0.98的系数已经足够让角度输出平稳同时不会在快速倾斜时明显滞后。有些同学上车后思路是疯狂提高滤波系数让角度看起来更平滑但系数太高会带来相位滞后直观表现就是小车反应迟钝一脚踢过去要晃两下才找回平衡。2.3 轮腿执行机构怎么并入运动控制腿部运动我用两个MG996R舵机分别驱动左右平行四边形连杆。舵机的控制频率是50Hz位置反馈通过舵机内置电位器读回来并没有单独的编码器。这块要特别说清楚舵机是一个独立的位置执行系统它和平衡控制是两个相对独立的回路。舵机动作时车身的重心高度和支撑点位置都会改变平衡环必须能够容忍这种扰动。所以在控制架构里我把舵机位置控制和平衡控制设计成了主从关系默认情况下舵机保持收腿状态此时小车是标准的平衡模式当需要停车或越障时上层状态机发送指令给舵机让它以固定步长下压每一步动作完成后等待200ms让平衡环收敛稳定后再进行下一步。这个步进等待的设计比直接让舵机一口气转到目标位置要稳得多因为直接快速压腿会让质心在极短时间内移动超过一厘米任何PID都很难不震荡。3. 双环PID整定从抖着站起来到跑得稳3.1 串级控制的物理直觉平衡小车的控制本质是倒立摆它要回答的问题只有一个当车身向某个方向倾倒时轮子该往哪个方向加速才能让重心重新回到轮轴正上方。我的控制律分成两个环内环是直立环外环是速度环但内环更关键。直立环的核心逻辑是让电机的加速度输出正比于当前倾角。写成伪代码是// 直立环输入倾角 和 陀螺仪角速度 balance_output Kp * angle Kd * gyro_y;注意第二项用的不是倾角的微分而是直接读陀螺仪的角速度。这样做的好处是减少一次微分运算带来的噪声放大同时陀螺仪本身的响应速度比加速度计推算出的角度微分更快。速度环的作用是抑制小车整体漂移因为单纯的直立环理论上会让小车回到平衡点但任何一点传感器零偏或机械不对称都会让整辆车缓慢地朝着一个方向溜走。速度环通过编码器测出实时的平均速度与目标速度比较把误差累积并反馈到最终输出上// 速度环输入目标速度与实际速度 speed_output Kp_speed * speed_error Ki_speed * integral_speed; // 最终PWM输出限幅保护 final_pwm balance_output speed_output;速度环的输出和直立环的输出是加法关系最终叠加成PWM占空比再做限幅。很多初学者容易把速度环设计成直接修正角度参考值这种做法不是不行但对于电赛这种需要快速调试的场景加法叠加的逻辑更直观出问题也更容易定位。3.2 参数整定的顺序和方法双环PID的整定顺序有一个铁律先直立环后速度环中途不要跳跃。我最初犯过的错误是一上来就同时动所有参数结果车在地上疯狂抽搐你根本分不清是哪个环的问题。正确的流程是这样第一步只保留直立环放开速度环输出让车在手里扶正观察响应。Kp从小到大慢慢加从300开始每隔五十加一次直到车能短暂地自行站立一两秒。这个阶段车子会剧烈抖动没关系关键是找到能站一下的临界值。第二步在Kp基础上加KdKd的作用是抑制震荡让车从抖着站变成相对稳地站。这个阶段如果Kd加得过大会引入高频噪声表现是电机发出很尖锐的嗡鸣声。第三步把车放地上跑开始加速度环。速度环一开始Kp_speed从2到3开始Ki_speed从0.05开始逐步观察车的漂移情况直到它能在原地稳定停住。我在这台车上的最终参数可以给一组参考值直立环Kp约1200Kd约60速度环Kp_speed约4.5Ki_speed约0.12。注意这些数值高度依赖你的传感器安装位置、电机减速比、PWM分辨率换一辆车之后不要直接套最多作为数量级参考。调参时我习惯把输出限幅控制在总PWM的50%以内也就是绝对值不超过500定时器ARR设置为1000这样即使控制律暂时溢出电机也不会瞬间打到满占空比给调试留出反应时间。3.3 轮腿切换时段的平滑过渡轮腿切换产生的扰动比很多人预想的要大。腿部舵机从收腿状态转为支撑状态时支撑脚落地瞬间会给车身一个向上的冲击力等效于给车体重心一个竖直方向的加速度扰动。我在状态机里做了三件事来消解这个问题下肢动作分五步执行每步间隔200ms每一步执行期间直立环的参考角度从当前角度做一个线性插值移动到0度附近同时将速度环的积分量清零一次防止切换瞬间的冲击被积分项放大成持续漂移。这套逻辑写出来大约七八十行代码但它决定了大车的行驶质感值得认真做。4. 实战踩坑记录那些不在任何教程里的问题4.1 霍尔编码器在低速段的失灵第一次把车放到场地上跑发现一个很怪的现象在平整的理石地面上车偶尔会朝一个方向突进一下然后立刻拉回来看起来像被人推了一下。起初我以为是PID参数问题把速度环的P和I都降到很低现象反而变得更加不规律。后来用一个简易逻辑分析仪挂在编码器A相和B相上才发现问题出在编码器信号本身霍尔编码器在低速段输出的脉冲边沿间隔很长而我的速度环以100Hz运行每次读到的脉冲计数经常是0偶尔跳到2或3速度信号就变成了一串台阶状的高频跳变。解决办法是两个一是在速度环输出前加一个一阶低通滤波把速度信号的时间常数设到30ms左右这样单次跳变会被明显钝化二是加了一个最小计数判断当编码器两次采样周期的计数都小于1时强制速度输出为0避免把量化噪声当成真实速度。问题解决之后小车在地面上的行驶细腻度立刻提升一个档次这说明有时候不是控制策略的问题而是感知层面的信号质量没做好。4.2 电池电压跌落导致参数全部失效另一个让我印象深刻的坑是电池电压。满电时电池电压8.4V车在实验室调得非常好直立稳定速度环收敛也快。但带去比赛场地跑了几轮之后再测同样的代码车的表现完全变了直立环输出明显偏软轻轻一推就倒。原因是电机转速和电压强相关相同PWM占空比下7.2V时的实际驱动力矩比8.4V时要低不少而我整定的PID增益是基于满电状态的。解决方案是在控制循环里加一个量程为0-10V的电压采集通道实时读取电池电压然后对所有控制输出乘一个补偿系数compensation nominal_voltage / current_voltage其中nominal_voltage取8.4V。这样电压低的时候PID输出会自动变大一些等效弥补了驱动力矩的下降。加了这行逻辑之后即使在电池临近低压报警时小车也还能保持基本可控。这里要提醒的是别把这个补偿系数设置得过于激进上限建议限制在1.3倍否则低电量时会引入过大的输出振荡反而得不偿失。4.3 机械谐振和陀螺仪的固定方式有段时间我的车怎么调D都抖Kd加大会抖得更厉害减小又站不稳进入了死循环。后来偶然用手电筒照了一下陀螺仪模块发现它是用一块薄的双面胶贴在车架悬空铝板上的电机转动时铝板本身的振动会通过双面胶传到MPU6050形成一种机械谐振。姿态环看到的是身体在高速抖动于是控制律也跟着高频输出形成了正反馈。解决办法很朴素把陀螺仪模块拆下来重新用厚的3M VHB双面胶加一根扎带固定在靠近车体重心、且下方有支撑柱的硬质车架平板上谐振问题立刻消失。这个坑让我明白一个道理陀螺仪安装的物理刚度和它的算法滤波参数同样重要甚至更重要。调试时如果发现D参数怎么调都无效先检查传感器安装再检查参数。5. 赛前固化与现场调试的经验5.1 用轮腿结构应对评测场地的不确定性比赛评测时最怕的不是算法不够先进而是场地与你预期不符。纯两轮车在光滑地板上站得很稳但到了铺了某种纹路的展台地胶上摩擦系数变了同样的PID参数就会偏软或者偏硬。轮腿式结构的额外支撑在此时价值凸显传送带上需要两轮平衡过弯那就收腿跑需要原地停车等待传感器读数那就放腿静止根本不需要关心平衡环在这个状态下是否还在工作。这个用结构降低算法压力的思路是很多获奖队伍的共同玩法。我不建议把调试精力全花在让算法适应所有地面利用好机械结构的能力边界才是更实际的工程思维。5.2 把参数调整做进工程而不是依赖烧录代码比赛现场最怕的事情是改一个参数就要重新编译烧录一次那几乎等于宣布进入失控状态。我在这套方案里预留了两个调参通道一是通过串口指令在计算机上直接发P和I参数值实时写入运行中的变量二是把十二个核心参数直立环Kp、Kd速度环Kp、Ki目标速度斜坡时间舵机步进间隔等存到STM32内部的Flash每次上电时读出来板子上的三颗按键可以循环选择参数并微调。这样现场即使发现车子状态不对也能在两分钟内完成参数切换和恢复而不至于傻站在原地重新烧程序。5.3 压缩包里每一份文件的作用最后介绍一下这个工程存档的内容方便你打开后快速找到自己需要的部分。硬件目录下是Altium Designer画好的原理图与PCB工程包含了主控板、电机驱动和电压采集电路机械目录下是轮腿结构全部3D打印件的STL文件与SolidWorks源文件尺寸参数和装配图都在里面固件目录是完整的STM32工程使用标准库开发主循环、编码器读取、互补滤波、PID和舵机状态机都做了模块划分对应注释写得很细文档目录里有一份调参记录表和一份设计报告模板后者在电赛提交纸质材料时可以直接参考格式。我建议无论你是否复用这套硬件都先把第3节的整定顺序在代码里标出来因为那部分是整套系统能不能站起来的钥匙。比赛头天晚上我最后一次用满电和低电压分别跑完整个流程把两套场景的参数都固化好了以后在实验记录本上写了一句很朴素的话能在场地里稳稳站在原地的车比能在PPT上画出花哨框图的系统更接近奖项。后来这份经验在很多场合都被验证了——控制系统的瓶颈常常不在算法复杂度而在结构刚度和你对每一处细节的掌控。本文还有配套的精品资源点击获取