ESP32-S3微鼠V2.0实战:选型、PID调参与比赛全程记录

发布时间:2026/10/6 6:57:27
ESP32-S3微鼠V2.0实战:选型、PID调参与比赛全程记录
“NeuroMouse V2.0”这个方案在AAMC 2026拿了个第三名。说实话冲线那一刻我的心情挺复杂没能守到第一但隔壁几个调试团队都在抱怨鼠“发疯”时我的鼠还能稳定跑完接近满速的全程这本身就是一种胜利。我是从V1.0那个“跑直线都会画龙”的版本一路改过来的整个项目最核心的变化就是主控从STM32F103换成了ESP32-S3并且围绕这颗芯片重写了全套控制框架。这篇文章就把我这次V2.0迭代时的硬件选型、结构设计、算法调参以及比赛现场踩坑的记录完整摊开适合正在做Micromouse或者准备参加类似自主迷宫竞赛的朋友参考。不少人和我说过Micromouse这种比赛用ESP32-S3显得“不够严肃”毕竟MATLAB仿真、FPGA、高速裸机代码才是主流。但我的出发点很简单我缺的不是底层计算而是快速迭代和调试的效率。ESP32-S3有双核240MHz带浮点单元和向量指令USB原生烧录还内置WiFi和蓝牙。这个规格对一台微型鼠来说已经溢出真正难的是如何在有限的体积里把传感器、电机、电源和算法可靠地捏成一个闭环。V2.0花了三个多月才达到“敢在比赛场上把速度拉到80%以上”的状态下面这些内容全是从一次次炸车里总结出来的。1. 项目背景与选型为什么是ESP32-S31.1 Micromouse到底是什么Micromouse比赛要求一台完全自主的小型机器人在没有外部干预的情况下探索一个由16x16个方格组成的迷宫每格尺寸通常为18cm x 18cm通过感知墙壁的位置实时构建地图并找到从起点到迷宫中心的最短路径最后在最短时间内完成从起点到终点的冲刺。这项比赛已经有几十年历史不过真正让它“卷”起来的是近十年电机、传感器和控制算法的进步。现在的顶级鼠能跑出10秒以内的成绩而普通爱好者做出来的作品往往还在“能不能不撞墙”这个阶段挣扎。AAMC 2026是我参加的一个亚太地区小型自主迷宫竞赛项目名NeuroMouse V2.0用的是我自己的命名体系。所谓“Neuro”并不是说用了什么高深的神经网络而是我把整个系统整理成类似神经反射的结构感知层每隔一小段时间采集传感器数据中间层根据地图和当前速度生成运动指令底层电机驱动负责执行。分层设计让每部分可以独立调参V2.0最大的改变就是把V1.0里纠缠不清的裸机回调重构成了清晰可维护的实时状态机。1.2 主控选型的纠结与最终选择做V1.0时我用的是STM32F103外设寄存器太灵活写代码时经常因为一个GPIO复用配置错误花了半天时间查“为什么轮子不动”。后来换了STM32F4性能有所提升但每次调试都要外接一个ST-Link现场改参数还要重新编译烧录每次迭代浪费大量时间。加上板子上的蜂鸣器、LED和OLED调试信息实在有限很多时候只能靠盲调。选择ESP32-S3有几个决定性原因。第一原生双核。我把传感器读取和运动控制放到一个核上把WiFi日志、地图更新和遥测放到另一个核上互不干扰。第二内置WiFi配合ROS或自写上位机可以无线修改PID值不需要重新烧录。第三USB CDC可以直接当串口用哪怕手边没有CH340也只需要一根USB线连电脑就能看到日志。第四价格便宜模组几十块钱买几块做破坏性试验都不心疼。当然ESP32-S3也有坑。ADC线性度较差模拟传感器读数容易出现波动FreeRTOS的调度在默认配置下有时候会出现优先级反转还有WiFi射频辐射可能会干扰旁边走线的传感器信号。这些问题在V2.0中都遇到过了后面会一个一个拆开说解决办法。我的结论是对于“以开发效率优先”的业余或半专业参赛团队ESP32-S3是很合适的选择如果你已经有成熟的高速代步鼠那换主控反而会打破原有的稳定状态不建议盲目跟风。2. 硬件架构V2.0迭代里那些取舍2.1 机械底盘设计要点V1.0的底盘是用3D打印的一块聚乳酸板材重量达到280g电机直接装在打印件上一跑起来就抖动编码器读数经常跳变。V2.0放弃了纯打印底盘改用碳纤维板加铝合金立柱的方案。碳纤维板用激光切割出来厚度1.5mm重量比V1.0轻了将近100g。不过碳纤维导电安装时必须注意PCB和碳板之间要有绝缘垫片否则电源正极压到碳板就是一场微型烟花。底盘尺寸上我设计的车体长96mm宽82mm前轮距55mm后轮距55mm车高包括顶部传感器板大约62mm。这个尺寸比规则允许的最大值小很多但并不意味着越小越好。如果轮距太窄车在高速直线行驶时对左右传感器一致性要求极高而且电池安装位置也受限轮距太宽转弯半径变大在做迷宫搜索的90度转向时会明显缩短可用的“提前量”。电机我选的是N20微型减速电机减速比130带霍尔编码器。轮子是36mm直径的硅胶轮表面有轻微摩擦纹。这里有个关键点轮子的直径决定了每转对应的距离而编码器分辨率又是通过轮径换算的因此轮径的精确值不要完全相信标称值我用游标卡尺测了多个轮子发现直径差0.3mm都会导致左右轮速度差最终表现为跑不直。最稳妥的办法是实际滚动几圈量出平均周长再把单位脉冲对应的距离标进系统参数里。2.2 传感器阵列红外测量还是ToFMicromouse的墙壁检测有三种常用方案红外距离传感器、激光ToF传感器、超声波传感器。超声波响应慢、精度低几乎不用于高速竞赛激光ToF如VL53L0X精度好但每次测量需要几毫秒在高速冲刺中如果每个周期读5颗传感器控制周期就会被拖到十几毫秒以上运动响应会显得迟钝。V2.0最终选择的是定制红外传感器阵列用850nm红外发射管和光电接收管通过测量反射光强来估算墙壁距离。这种方案最大的问题是“模拟量”很脏墙壁反光率、环境光、传感器温漂都会造成读数偏差。但我愿意付出校准成本换取的是极快的响应速度模拟量可以直接被ADC采样加上滤波和外推整个控制周期能做到1ms以内。实际布局是前向2颗、左右侧各2颗、后向1颗总共5颗传感器呈斜向安装以兼顾不同距离的测量范围。每颗传感器输出经过一级运放放大后接入ESP32-S3的ADC引脚。ADC线性差的问题我处理方式很简单不依赖线性关系每颗传感器单独做距离标定。标定时用步进电机带动一个小墙板从3cm到30cm每隔2mm记录一次ADC值生成一张查找表。因为ADC的重复性在恒温下尚可只要标定一次跑比赛前再只用距离为0的参考点做偏移修正就够了。如果你手头没有步进电机也可以手工用带刻度的滑台来标虽然没有那么平滑但已经比赛足够。2.3 电源与电机驱动车上的电源直接用2S锂聚合物电池标称7.4V实际充满电压8.4V放到3.7V每节就不能再跑。电机驱动选用TB6612FNG原因是它体积小、压降低且带电流限制功能对电机这种堵转电流可以达到数安培的负载来说足够稳定。TB6612的电源端直接接电池逻辑端接3.3V注意电机驱动器的地和ESP32-S3的地必须单点连接否则数字噪声会引入编码器计数异常。ESP32-S3的工作电压是3.3V我用了一颗低静态电流的LDO把电池电压降到5V再用一颗LDO降到3.3V。很多人会忽略电池电压的变化对电机驱动力矩的影响。PID速度环虽然能补偿一部分但补偿前馈电压项非常关键。我的做法是每5ms采样一次电池电压算出一个与电压成反比的前馈PWM值叠加在PID输出之前。这样电池从8.4V掉到7.2V时相同的速度指令对应的PWM占空比会相应变化避免速度环的积分器不断加深导致响应迟钝。3. 软件系统感知、决策、运动闭环3.1 状态机与多任务划分ESP32-S3双核让我有条件把代码拆成两个并行上下文。核心0运行运动控制线程优先级设为最高并且用固定频率的定时器中断触发比如500Hz。核心1运行传感器融合、地图更新、WiFi日志、调试命令甚至还有一小块故障监视器。这样即使WiFi传输占用了大量CPU也不会影响电机控制循环。整个系统状态机分为如下状态BOOT校准传感器、初始化电机、等待启动按键。EXPLORE_SEARCH迷宫搜索模式结合Floodfill算法更新地图。RETURN_HOME搜索完成后返回到起点为冲刺做准备。SPEED_RUN冲刺模式依据已建立的地图高速运行。STOP结束并待机。状态切换不能直接硬跳。比如从EXPLORE_SEARCH切换到RETURN_HOME需要先将速度降到安全值等车完全停稳后再修改目标点避免因为速度突变导致位置估算错误。这个看起来“多余”的步骤其实是很多新手鼠撞墙的根源位置信息在高速移动中已经积累了误差不减速就切换路径规划后面全乱套。3.2 速度环与位置环PID设计的细节速度环是控制小车的核心我用的是标准增量式PID控制频率是500Hz。你别看PID原理简单真正稳定跑高速需要处理好三个问题编码器测速噪声。霍尔编码器在低速时容易有漏脉冲如果直接微分会得到毛刺。我用了滑动窗口中值滤波窗口长度3配合一阶低通基本能把速度估计的噪声压在2%以内。积分限幅。电机堵转时PID积分会飞速累积不加限幅的话等外力消失后会给一个猛烈输出让车弹出去。我的积分限幅设置成最大PWM的20%。前馈。单靠PID响应低频变化够用但在梯形速度曲线的加速段纯PID会有明显的滞后。因此我加了一个速度前馈项根据目标速度查表给出基础PWMPID只负责修正偏差。代码里大致建模如下// 500Hz控制循环内 speed_pid.InnerFeedback(encoder_speed_mm_s); float ff feedforward_curve.sample(target_speed_mm_s); float pid_out speed_pid.compute(target_speed_mm_s, encoder_speed_mm_s); float voltage_comp battery_voltage_comp(target_voltage_nominal, battery_voltage); float pwm_set ff pid_out voltage_comp; set_motor_voltage(left_motor, pwm_set);位置控制则是外环频率100Hz。外环每次根据路径规划计算当前应该到达的位置反推出目标速度再交给内环执行。转向控制我用的是“圆弧过渡”策略在到达十字路口前提前计算出从当前直线过渡到目标方向的圆弧半径并把该圆弧转化为一系列目标横坐标和航向角。这样比“走直角”速度更快也减少了对墙面传感器的依赖。3.3 Floodfill迷宫搜索与冲刺规划迷宫算法是最经典的了。我用了Floodfill以迷宫中心为目标区域每次探测到新的墙壁后重新计算每个格子的距离值当前格子选择旁边距离最小的格走。这个算法实现起来简单但要让鼠在迷宫搜索时少走回头路、减少转向次数还得额外加启发式规则。比如优先级是优先走直线其次右转然后左转最后掉头。这个规则的排序可以调整不同的迷宫布局会带来不同效率用仿真器验证我觉得很值。搜索阶段结束后鼠已经有了完整地图然后运行迪杰斯特拉算法求出从起点到迷宫中心的最短路径。为了让冲刺段更快我把这个路径做了一步平滑处理把连续三个格子形成的两条直线段替换成一条直线段只要中间格子的墙壁允许且转向所需距离足够。这一步平均能缩短4到6个弯道大概节省0.8秒左右。冲刺时鼠运行在速度优先模式直线段用最大的梯形速度曲线极限速度可以到1.8m/s左右弯道处会根据圆弧半径动态限速这个速度阈值不是随便给的我通过实验找出了不同半径下的最大安全过弯速度并存表。再靠陀螺仪或侧向传感器跟踪修正。V2.0没上陀螺仪因为红外侧传感器已经足够密集用侧壁跟随就能完成大部分航向修正。但如果你要跑来年更高等级的赛道我建议还是装一颗低成本IMU尤其对快速掉头会有帮助。4. 赛场上真实遇到的问题与调参记录4.1 红外传感器“死亡结界”强反光导致的误判比赛前一天场地验收我把鼠放上去试跑结果一进那段用高光泽亚克力贴纸围起来的墙面传感器读数立刻爆表明明前面没有墙却显示“距离20cm处有物体”导致车直接减速四处乱探。这就是典型的红外反光干扰。墙面表面反光太强红外接收器收到的是镜面反射而不是漫反射回波。现场解决方法有三个按优先级推荐提高传感器灵敏度阈值同时启用“二次检测”如果读数突然小于3cm而前一刻还在20cm左右认为该读数为无效等待两个周期后再确认。在传感器探头后方贴深色遮光棉减少外部光杂散信号。给发射管加调制脉冲。这需要硬件支持V2.0的PCB上没有设计脉冲驱动所以只能靠软件一致性检测缓过比赛。赛后我已经把下一版硬件改成了38kHz调制的红外发射噪声抑制能力提升明显。4.2 电池电压波动带来的出力不均比赛场地环境温度较高电池性能下降很快满电时最高速度能到1.75m/s跑几圈后掉到1.5m/s。一开始我没有做电压前馈只在速度PID里靠积分硬顶结果就是高速段发飘中速段又过头。后来我把电池电压采样接入前馈表效果立竿见影同样的速度指令在不同电量下输出PWM基本一致。建议准备两张前馈表一张针对新电池一张针对老化电池比赛前根据电量切换。4.3 迷宫第二圈掉速地图重置问题搜索阶段跑完回到起点时软件里地图数组还保留着搜索时生成的临时标记导致冲刺阶段不能用最短路径。第一次发现这个问题时我以为是传感器又闪了但后来通过无线日志看到车在冲刺时走了一条奇怪的绕路。问题出在Floodfill算法为了搜索效率会把终点目标格标记为“绝对值0”而冲刺阶段应该把目标重新设置为迷宫中心并且清空所有格子的访问标记。解决起来就两行代码但如果不加这步就会发生“慢车绕路”的滑稽场景。5. 独家调试技巧与后续扩展5.1 ESP32-S3无线日志与在线调参这是V2.0迭代效率提升最明显的地方。ESP32-S3内置WiFi我把它配成SoftAP模式车本身开一个热点电脑连上这个热点后通过UDP发送和接收调试数据。上位机用Processing写了个极简表格界面每50ms刷新一次速度、编码器值、传感器距离、PID误差和电池电压。比赛现场如果发现问题可以坐在电脑前实时改PID参数包然后通过UDP下发不用拔插U盘、重刷固件。这套流程在V1.0是完全不可想象的。你可能会觉得无线传输会增加系统开销。实测下来WiFi吞吐只有几百字节/秒中断占用量可以忽略。唯一需要注意的是WiFi天线附近不要走模拟传感器线我把天线放在了车尾朝上这样既不影响射频性能也不干扰传感器模拟信号。5.2 基于记录的迷宫回放工具调试深了以后发现单纯看日志并不直观。于是我在PC端加了一个回放工具把每次运行时的地图状态、位置坐标、速度曲线都写入SD卡上的二进制文件。跑完后把文件拖进上位机程序就会把鼠的运动轨迹和感知到的墙壁叠加到虚拟迷宫上这样你可以快速回放“到底第几圈在哪撞上墙”。这个回放工具不复杂核心就是记录每个时间片的位置和传感器读数但效果远超一切现场猜测。建议所有做自主移动竞赛的团队都搞一个。比赛结束后我没有继续开发V3.0而是把这个回放数据整理成了软硬件改进清单第一项是换掉红外发射管驱动部分改用脉冲调制第二项是给电机编码器输出增加信号整形电路第三项是在算法里加入陀螺仪数据融合让过弯更稳。这些方向不一定都适合所有人但如果你在调试自己的鼠时遇到我上面提到的类似症状希望能给你一些可以上手的思路。做Micromouse最有趣的地方不只是比谁跑得快而是比谁在有限时间里解决问题更聪明。ESP32-S3让我把更多精力集中在运动控制和迷宫策略上而不是在烧录器和示波器之间反复横跳。下次比赛我想试试看把WiFi调参工具直接做成手机App赛场边冲电边改参数应该会更有意思。