1. 从零到一国赛E题“运动目标控制与自动追踪系统”的实战复盘去年夏天我和我的团队一头扎进了全国大学生电子设计竞赛国电赛的E题——“运动目标控制与自动追踪系统”。这个题目乍一看名字挺唬人什么“运动目标”、“自动追踪”感觉像是电影里的高科技。但说白了核心就是让一个“小车”或者云台能自己动起来去追一个会移动的“目标”。这个目标可能是一个发光的LED一个特定颜色的色块或者一个二维码。听起来是不是有点像我们小时候玩的“老鹰捉小鸡”的自动版只不过老鹰和小鸡都换成了电路板和单片机。为什么这个题目每年都能吸引无数队伍前赴后继因为它完美地融合了嵌入式系统、传感器技术、自动控制、图像处理或光电检测以及机械结构等多个学科的知识点。它不要求你某个单项技术做到极致但要求你具备出色的系统集成能力、工程实践能力和临场应变能力。四天三夜从拿到赛题到封箱上交作品这不仅仅是一场智力的比拼更是一场体力、意志力和团队协作的终极考验。今天我就以一个过来人的身份把我们当时做E题的完整思路、踩过的坑、以及最后让我们拿到国奖的关键决策毫无保留地分享出来。无论你是即将参赛的学弟学妹还是对嵌入式控制感兴趣的爱好者相信这篇近万字的“脱水干货”都能给你带来实实在在的启发。2. 破题与顶层设计你的系统究竟要干什么国赛题目往往言简意赅但字字珠玑。E题描述通常只有一页纸里面却藏着所有得分点和“坑点”。我们的第一步不是急着画电路图或写代码而是像解数学题一样把题目要求逐字逐句“翻译”成明确的技术指标和系统功能。2.1 核心任务分解从模糊描述到清晰指标以我们那年的题目为例核心要求通常包括基本要求系统上电后能自动搜寻并锁定初始静止的目标比如一个特定频率闪烁的LED。锁定后追踪装置如摄像头云台的中心要对准目标中心。这考察的是静态目标捕获能力。发挥部分目标开始按照预定轨迹如圆形、矩形运动追踪装置需持续跟踪保持对准并实时显示目标位置坐标。这考察的是动态目标跟踪与控制系统响应速度。创新部分加分项目标运动轨迹变为随机或变速系统需能适应并稳定跟踪。可能还会要求增加测距、无线数据传输、上位机显示等功能。这考察的是算法鲁棒性和系统扩展能力。我们的做法是制作一张“需求-技术-验证”对应表。用Excel或者直接画在草稿纸上左边列是题目原话中间列是我们理解的具体技术实现右边列是计划如何测试验证。例如题目要求技术实现解读测试验证方法“自动搜寻目标”云台需具备二维旋转能力舵机/步进电机配合传感器进行全域扫描。上电后云台应能自动执行扫描程序并在找到目标后停止。“锁定目标”传感器摄像头/光电管输出信号需达到稳定阈值并认为目标位于视场中心。用示波器或串口监视传感器信号当信号稳定且云台停止运动时视为锁定。“跟踪运动目标”需实现闭环控制传感器反馈目标位置偏差 - 控制器计算 - 驱动电机消除偏差。让目标沿固定轨迹运动观察云台跟随是否平滑用上位机记录轨迹曲线是否吻合。“显示坐标”需有显示模块OLED/LCD或通过串口发送到电脑上位机。目视检查屏幕显示或上位机软件接收到的坐标值是否合理、连续。这张表会成为我们后续所有工作的“宪法”任何设计决策都要回头看看是否满足了表中的某项要求。很多队伍失败的第一个原因就是没有吃透题目想当然地去做结果做出来的东西和评分标准格格不入。2.2 技术路线选型摄像头方案 vs 纯传感器方案这是E题最核心的决策点直接决定了整个系统的复杂度、成本和稳定性。方案一摄像头图像处理方案核心使用OpenMV、K210、树莓派配合摄像头或STM32F4/F7系列配合OV系列摄像头作为主控通过图像算法识别目标。优点信息丰富能获取目标的二维坐标、形状、大小、颜色等多种信息理论上识别更准确。灵活性高通过修改代码可以适应不同特征的目标颜色、形状、图案甚至实现多目标跟踪。“看起来”更高级容易做出炫酷的上位机图像显示界面视觉冲击力强。缺点与巨坑处理速度图像处理非常消耗算力。在低端MCU上帧率可能很低如OpenMV处理复杂算法时可能只有10fps左右导致系统响应迟钝无法跟踪快速目标。光照影响赛场光线不可控。窗户边的阳光、日光灯频闪、其他队伍的灯光干扰都可能让颜色识别或阈值分割完全失效。这是我们亲眼所见最多队伍翻车的地方。算法复杂度你需要编写或调试图像处理流程找色块、轮廓检测、中心点计算并处理好图像坐标到云台舵机角度的映射关系调试周期长。稳定性程序复杂内存占用大容易死机或出现偶发性识别错误。方案二光电传感器阵列方案核心使用光敏电阻、光电二极管、激光接收管等模拟传感器或者集成度更高的灰度传感器、红外循迹模块阵列来感知目标光源的位置。优点响应速度极快模拟电路或数字传感器的响应是微秒级的几乎没有延迟。抗干扰能力强可以针对特定频率如果目标LED是调制的进行选频放大极大抑制环境光干扰。电路做好了稳定性极高。控制逻辑简单传感器输出直接就是电压或数字信号反映目标偏离中心的方向和程度可以直接用于PID控制计算系统简洁可靠。成本低功耗低。缺点信息量少通常只能得到一维或二维的偏差量无法知道目标的绝对坐标或复杂特征。依赖目标特性通常要求目标是主动发光的、特定频率的LED。如果题目目标是被动反射的普通物体此方案可能不适用。我们的关键决策与心得经过激烈讨论和前期实验我们毅然选择了方案二——光电传感器阵列。理由非常功利且直接国赛是在体育馆里进行现场光照条件复杂稳定压倒一切。我们赌题目中的“运动目标”会是一个易于用光电方式检测的主动光源后来证实果然如此。我们用了4个光电二极管配合透镜组成一个“十”字形探测阵列后面接模拟电路进行放大、滤波和比较。整个检测电路的反应时间在毫秒级为后续的高速跟踪打下了坚实基础。这个选择让我们避开了最不可控的“光照”变量把问题从复杂的图像处理拉回到了我们更擅长的电路设计和控制算法上。给后来者的忠告除非你对图像处理有极深的功底和充分的抗干扰测试否则在有限的比赛时间内优先考虑最稳定、最直接的方案。3. 硬件系统的骨架稳定可靠的电路与机械设计硬件是系统的身体软件是灵魂。一个颤颤巍巍的云台或者噪声巨大的传感器信号再优秀的算法也无力回天。3.1 传感器模块如何把“看见”变成“电信号”我们采用四象限光电探测器方案。核心思想是用一个遮光筒将视场限制在一个小圆锥内四个光电二极管A, B, C, D呈“十”字排列在遮光筒底部。当目标光源出现在视野中时它会照亮一个或几个二极管。电路设计要点选型光电二极管要选择响应速度快、暗电流小的型号。我们用的是BPW34。I-V转换光电二极管输出的是微弱的电流信号uA级。第一级运放必须配置成跨阻放大器Transimpedance Amplifier将电流转换为电压。这里的反馈电阻和电容取值至关重要决定了带宽和噪声。放大与滤波第二级可调增益放大将信号放大到MCU ADC可采集的范围如0-3.3V。必须加入带通滤波如果目标LED是1kHz方波调制我们就设计一个中心频率在1kHz的带通滤波器。这能滤除几乎所有的环境光直流和低频以及其他队伍可能用的不同频率光源高频干扰。峰值检波或有效值转换经过滤波放大的交流信号需要转换成直流电压才能被ADC采集。我们用了精密整流加低通滤波构成的峰值检波电路。也可以使用AD736这类真有效值芯片。信号合成得到四个通道的直流电压Va, Vb, Vc, Vd后如何计算目标偏离中心的位置(ΔX, ΔY)水平偏差 ΔX (Va Vd) - (Vb Vc)。当目标在左边时(VaVd) (VbVc)ΔX为正。垂直偏差 ΔY (Va Vb) - (Vc Vd)。当目标在上边时(VaVb) (VcVd)ΔY为正。这个公式的本质是差分测量能有效抵消光源强度变化带来的影响。即使光源变暗只要它偏离中心差值依然存在。3.2 执行机构云台驱动与选型云台需要两个自由度水平Pan和垂直Tilt。常用方案是舵机。舵机选型不要用廉价的9g塑料舵机它们扭矩小、齿轮易打滑、存在死区、精度差。我们选用的是数字金属齿轮舵机如MG996R。虽然贵一点但扭矩大10kg/cm以上回中精度高响应快。机械结构自己用亚克力或铝型材搭建云台时重心和刚度是生命线。摄像头或传感器模块必须牢固安装整体重心尽量靠近两个舵机的旋转轴交汇处。否则舵机负载不均会产生抖动甚至无法带动。我们用了3D打印了一个轻量化且结构坚固的支架并用螺丝严格固定。供电隔离舵机启动瞬间电流很大可达2A会在电源线上产生毛刺严重干扰敏感的模拟电路和单片机。必须将舵机电源和控制系统电源隔离我们的做法是一块大容量锂电池如2S/3S锂电单独给舵机供电。单片机、传感器、运放等由另一块稳压后的电池或通过DC-DC模块从总电源隔离出来。两地之间仅共用信号线PWM。3.3 主控与电路板把一切连起来主控MCUSTM32F103C8T6蓝桥杯板或STM32F407。性能完全足够。F103的ADC和定时器做PID控制绰绰有余。关键是要熟悉其外设特别是定时器产生PWM驱动舵机ADC多通道扫描采集传感器信号以及串口与上位机通信。PCB还是洞洞板强烈建议绘制PCB四天时间看似紧张但用嘉立创等平台打样通常24-48小时就能拿到。洞洞板焊接模拟电路特别是多路运放极易引入噪声、产生虚焊调试起来是噩梦。我们在第一天就确定了原理图当晚就发出去打样第三天早上拿到焊好整个系统的稳定性有了质的飞跃。这是时间投资回报极高。电源管理模拟部分运放最好使用±5V或±12V供电以获得更大动态范围数字部分3.3V。使用LDO如AMS1117-3.3或低噪声DC-DC模块。每个芯片的电源引脚附近都必须放置一个0.1uF和一个10uF的电容进行去耦。4. 软件算法的灵魂从数据到精准控制硬件提供了干净、快速的偏差信号(ΔX, ΔY)软件的任务就是让云台动起来让这个偏差趋于零。4.1 核心控制算法PID的深入理解与整定我们采用了最经典也最有效的位置式PID算法。公式大家都知道Output Kp * error Ki * integral Kd * derivative。但真正用好不容易。误差Error的获取这就是我们传感器计算出的ΔX和ΔY。注意这里存在一个映射关系ΔX的电压值对应目标在水平方向偏离了多少角度。我们需要通过实验标定。例如让目标在云台正前方左右缓慢移动记录下ΔX从正最大到负最大变化时目标实际移动的物理角度。从而建立一个电压差 - 角度偏差的近似线性关系。这个关系系数会直接乘到Kp等参数上。积分项Integral的陷阱与抗饱和积分项能消除静态误差。但如果目标快速运动或云台暂时丢失目标误差一直很大积分项会累积到一个巨大的值积分饱和当目标再次出现时系统会产生严重的超调甚至震荡。必须实现积分抗饱和。我们采用的方法当输出值达到硬件限幅如PWM占空比上限时就停止积分项的累积。或者更精细一点只累积那些与输出方向相反的误差。微分项Derivative与滤波微分项能预测变化趋势提高响应速度。但它对噪声极度敏感传感器信号哪怕有一点毛刺经过微分也会被放大成尖峰。必须在软件中对误差进行低通滤波后再计算微分或者使用“不完全微分”的PID变种。参数整定不是玄学是科学实验。先Kp 再Kd 最后Ki。这是黄金法则。将Ki和Kd设为0。逐渐增大Kp直到云台开始出现等幅振荡临界振荡。记下此时的Kp为Ku振荡周期为Tu。根据齐格勒-尼科尔斯Ziegler-Nichols经验公式设置初始参数经典PID: Kp 0.6 * Ku, Ki 2 * Kp / Tu, Kd Kp * Tu / 8。保守型我们采用的: Kp 0.33 * Ku, Ki 2 * Kp / Tu, Kd Kp * Tu / 3。在这个初始参数附近微调。观察云台跟踪一个匀速运动目标时的响应曲线可以通过串口发送数据到电脑用Python matplotlib画图。理想状态是快速响应小幅超调迅速稳定在误差带内。4.2 程序架构与多任务调度四天三夜写出的代码不能是“面条代码”。一个清晰的架构能让你在最后关头修改功能时不至于牵一发而动全身。时间片轮询我们没有用复杂的RTOS而是采用了简单可靠的时间片轮询。在SysTick中断1ms触发一次中设置多个软件定时器标志位。// 示例代码结构 volatile uint8_t flag_10ms 0, flag_20ms 0, flag_100ms 0; void SysTick_Handler(void) { static uint16_t tick 0; tick; if(tick % 10 0) flag_10ms 1; // 10ms任务 if(tick % 20 0) flag_20ms 1; // 20ms任务 if(tick % 100 0){ // 100ms任务 flag_100ms 1; tick 0; } } int main(void) { // 初始化... while(1) { if(flag_10ms) { flag_10ms 0; Sensor_Read(); // 读取传感器数据 (10ms) PID_Calculate(); // 计算PID输出 (10ms) } if(flag_20ms) { flag_20ms 0; Servo_Update(); // 更新舵机PWM (20ms) } if(flag_100ms) { flag_100ms 0; UART_SendData(); // 向上位机发送数据 (100ms) OLED_Display(); // 刷新显示 (100ms) } // 其他非实时任务... } }10ms任务读取ADC传感器信号执行PID计算。这是控制环的核心周期最短决定了系统带宽。20ms任务更新舵机PWM信号。舵机的控制周期通常在20ms左右太快了没必要。100ms任务刷新OLED显示、向上位机发送调试数据。这些任务实时性要求不高。状态机设计系统工作流程用状态机来管理非常清晰。typedef enum { SYS_INIT, SCANNING, // 扫描目标 LOCKED, // 锁定目标 TRACKING, // 跟踪目标 LOST // 目标丢失 } SysState_t;在while(1)主循环中根据当前状态执行不同的函数并在满足条件时进行状态转移。例如在SCANNING状态云台匀速旋转一旦传感器信号超过阈值就转入LOCKED状态。5. 调试、测试与赛场实战细节决定成败系统搭起来能跑只是第一步如何让它跑得稳、跑得准才是拿高分的关键。5.1 分模块调试隔离问题逐个击破传感器单独测试用信号发生器产生一个1kHz的正弦波模拟光电二极管放大后的信号输入到我们的滤波和检波电路用示波器看输出是否平滑的直流并且幅值随输入信号幅值线性变化。然后用手电筒最好也用1kHz调制在传感器前移动看输出变化是否灵敏、连续。舵机单独测试写一个简单的程序让舵机在0°和180°之间往复运动观察其运动是否平滑有无异响回中是否准确。用手机慢动作拍摄检查是否有抖动。PID开环测试先将PID输出断开手动给一个阶跃的“误差”信号比如通过按键模拟用串口打印出此时PID计算出的输出值观察比例、积分、微分三项的变化是否符合理论预期。闭环联调这是最激动人心也最痛苦的阶段。先让目标静止调整Kp让云台能快速对准并稳定住没有明显抖动。然后让人手持目标缓慢移动观察云台跟随是否平滑。这里一定要用上位机软件如SerialPlot、自己用Python PyQt5写的实时绘制误差曲线和输出曲线眼睛看云台动作是感性的看曲线才是理性的分析依据。5.2 抗干扰与鲁棒性提升软件滤波除了硬件带通滤波ADC采集后还要进行软件滤波。我们用了一阶互补滤波来处理ΔX和ΔY信号平滑掉偶尔的尖峰。float filtered_value 0.9 * filtered_value 0.1 * raw_adc_value; // 一阶低通目标丢失处理在跟踪过程中可能会因为目标移动太快、暂时被遮挡等原因导致传感器信号消失四个通道电压都很低。程序必须能检测到这种情况LOST状态并触发一个重新搜索策略。我们的策略是记录丢失前一刻的目标运动方向让云台向那个方向加速旋转一小段同时缩小搜索范围。如果几秒内还没找到再扩大为全局扫描。这个策略让我们在测试中成功应对了目标的突然加速和短时遮挡。参数自适应进阶玩法。我们尝试了一个简单的方案根据误差的大小动态调整PID参数。当误差很大时目标刚出现或丢失后重新找到使用一组更激进的参数Kp大Kd小快速接近目标当误差很小时使用一组更保守的参数Kp小Ki, Kd适当精细调整避免震荡。这有点像“模糊控制”的思想效果不错。5.3 赛场上的最后48小时封装与测试清单作品封箱前列一个详细的测试清单每项功能都让队友操作自己记录结果。包括上电自检、扫描锁定时间、静态对准精度、匀速圆周跟踪误差、矩形轨迹拐角跟踪性能、目标丢失恢复时间等等。确保万无一失。备用方案我们准备了两套完全相同的传感器模块和一套备用舵机。主控程序烧录在两块不同的核心板上。永远要有Plan B。心态调整最后一天核心代码和参数就不要再做大改了只做微调。把时间花在整理报告、练习答辩、检查机械结构螺丝是否紧固、电池电量是否充足这些“琐事”上。保持冷静相信你们之前上百个小时的调试。6. 总结与延伸E题带来的远不止一个奖项回过头看国赛E题就像是一个微缩的工程项目。它强迫你在极短时间内完成从需求分析、方案论证、硬件设计、软件编程、调试测试到最终交付的全流程。我们选择的“光电阵列经典PID”路线可能不是最炫酷的但却是最扎实、最可靠的。它让我们深刻理解了**“简单即是美”和“稳定高于一切”**的工程哲学。比赛结束后我们在这个系统上做了很多延伸。比如将传感器换成了分辨率更高的PSD位置敏感探测器实现了亚毫米级的定位精度尝试用MPU6050做云台自身的姿态补偿甚至把算法移植到了带浮点单元的STM32F4上实现了更复杂的自适应PID。这些都是在比赛核心框架上生长出来的新技能。对于准备参赛的朋友我的建议是尽早组队明确分工硬件、软件、机械、报告找一个往年的经典赛题如2017年的“滚球控制系统”从头到尾做一遍。在这个过程中你们会遇到本文提到的所有问题并学会如何解决它们。当你们真正比赛时就会发现题目虽然新颖但底层技术和解决问题的方法论是相通的。最后分享一个让我们在测试阶段省下大量时间的小工具一个用Python和PyQt5写的简易上位机。它通过串口接收单片机发来的数据实时误差、PID输出、舵机角度等并实时绘制成曲线图。同时还能发送一些简单的指令如修改PID参数给下位机。这个工具让我们摆脱了反复修改代码、编译、下载、观察的循环调试效率提升了不止十倍。它的核心代码并不复杂网上有很多教程强烈建议每一支队伍都花点时间准备一个。国赛之旅痛并快乐着。那些在实验室通宵调试、争吵又和解、看到云台终于平稳跟踪目标时的欢呼都成为了我们大学生活中最宝贵的记忆和技术生涯最坚实的起点。希望这篇长文能为你点亮一点前行的光。祝你成功