STM32平衡车进阶实录:如何优雅地解决“飞车失控”与“急停点头”两大痛点
项目定位基于B站Up主“会飞的鱿鱼”开源硬件框架但我并未止步于复刻。本次重构的核心目标是提升小车的运行安全性与环境适应性重点攻克了“拿起飞车”和“避障顿挫”两个工业级PID调试中常见的棘手问题一、 从复刻到重构我的增量价值在哪“会飞的鱿鱼”的教程提供了极佳的入门基石MPU6050姿态解算 串级PID。但在实际把玩中我发现原逻辑存在两个影响体验的硬伤安全隐患用手拿起小车时轮子会因速度环积分饱和而飞速空转极易伤手或烧毁驱动。动作僵硬开启超声波避障时小车接近障碍物会突然急停/倒退车身剧烈“点头”姿态极不稳定。我的工作并非简单地修改几个阈值而是重新设计了控制状态机State Machine并从工程角度对PID输出进行了平滑与安全冗余处理。二、 系统顶层设计一张图看懂我的状态机为了避免代码逻辑混乱我将小车的运行划分为4个明确的互斥状态。这不仅是代码结构优化更是嵌入式开发中“防御性编程”的体现。状态1FALL倾覆/悬空 - 动作紧急制动电机PWM强制归零。状态2RECOVER等待恢复 - 动作关闭平衡输出静置观察防抖动计时。状态3NORMAL自平衡运行 - 动作执行核心PID直立闭环。状态4AVOID主动避障 - 动作在NORMAL基础上动态修改速度环目标值。工程价值将零散的if判断抽象为状态机使得后续添加“电量过低保护”或“遥控超时失联保护”时只需新增状态无需重构主循环。三、 重点攻克难点一自动避障的“平滑哲学”痛点分析原逻辑直接将目标速度从 5 硬切到 -10。由于平衡车是一个非最小相位系统速度的突变会直接转化为角度的剧烈变化即“点头”这是PID控制的大忌。我的解决方案目标值斜坡生成器Target Ramp我不直接给速度环赋极值而是让目标值 Target_Speed 按照一定的加速度斜率逼近期望值。// pid.c 核心逻辑提取 if (distance 35) { expect_speed 4; // 期望慢速前行 } else { expect_speed -10; // 期望快速后退 } // 关键通过限幅递增实现“软着陆”防止速度突变 if (Target_Speed expect_speed) Target_Speed; // 每次控制周期10ms只增加1 else if (Target_Speed expect_speed) { // 后退时加大斜率确保遇到障碍反应足够快 Target_Speed - (expect_speed 0) ? 3 : 1; }技术亮点前进行走时缓慢加减速步长1保证车身姿态平稳遇到障碍后退时加快响应步长3确保安全性。这种非对称斜率控制在伺服驱动器中是极为实用的工程技巧。四、 重点攻克难点二“防飞车”双重保险机制这是我在调试初期被“打手”教训后深刻反思的成果。飞车产生的根源在于当轮子悬空失去负载时速度环实测值远小于目标值导致积分项Ki * Error_sum无限累加积分饱和。第一重保险姿态异常拦截当 roll 角偏离机械中值超过 35° 时物理上已判定小车失控立即关闭平衡。第二重保险运动异常感知轮速判据仅靠角度判断不够。当小车在水平面被突然拿起时倾角尚未突变但轮速已经飙升。我加入了基于编码器的感知层// 只有在非遥控状态下且左右轮速绝对值之和超过120时触发保护 if ((Fore 0) (Back 0) (abs(raw_left) abs(raw_right) 120)) { balance_enable 0; Load(0, 0); // 立即关断PWM // 关键同时清空速度环积分累加器防止重启时的“假性饱和” Encoder_S 0; }为什么阈值是120这是我根据电机空载最大转速约200转/分和编码器线数390线换算得出的经验值确保正常行走颠簸时80不误触异常空转时120快速响应。第三重保障带防抖的恢复机制Recovery Timer保护触发后小车不能立即恢复平衡否则会在晃动中再次跌倒。我加入了 300ms 的滞回判断必须同时满足“倾角回归中值±8°以内”且“轮子几乎停转”持续 30 个控制周期30 * 10ms 300ms才重新使能平衡。这极大提升了小车在粗糙地面行走时的抗干扰能力。五、 调试踩坑实录一次积分限幅引发的血案在调试“拿起保护”时我曾犯过一个经典错误只关闭了PWM输出但没有清零速度环的积分累加器 Encoder_S。现象小车被拿起停转后再放回地面它会猛地向前一冲。根因悬空时的巨大偏差全部累计在 Encoder_S 中。虽然电机停了但“账本”上还欠着巨债。一旦恢复PID控制器会瞬间输出巨大PWM进行补偿。修复在 if(stop1) 分支中显式执行 Encoder_S 0;已在代码中实现。反思这让我深刻理解了PID控制中 “积分分离”和“积分限幅” 不仅是理论更是关乎安全的红线。六、 效果展示与实测数据此处建议插入两个不到10秒的短视频/GIF防飞车测试手持小车悬空 - 轮子不会全速运转放回地面平稳站立。平衡小车避障测试小车以0.3m/s速度冲向墙壁 - 在35cm处开始线性减速无点头顿挫平稳后退。平衡小车1七、总结这次改进让我认识到做一个能站的平衡车是入门而做一个“摔不坏、拿得稳”的平衡车才是工程。从调参到状态机设计再到异常处理每一步都是在驯服不确定性。这份代码目前仍有许多优化空间比如加入蓝牙遥控与自动模式的互斥锁但它已是我从“会跑”到“可控”迈出的一大步。