公司动态

智能车电磁组竞赛:从电感信号到PID控制的完整实践指南

📅 2026/9/1 6:34:51
智能车电磁组竞赛:从电感信号到PID控制的完整实践指南
简介面向第二十届全国大学生智能车竞赛缩微电磁组这份方案资源为参赛学生和嵌入式开发者系统梳理了从赛题解析、机械结构设计、硬件配置到软件控制落地的完整备赛路径。资源包共2个文件以inscode代码文件和html说明文档为主压缩包总大小约5KB体量轻巧便于快速部署与查阅。内容重点覆盖差比和算法、动态权重调整、转向环串级控制等核心技术针对直角弯、十字路口等复杂赛道给出了具体的优化思路并附有接线说明、元件清单和开源库指引。结合龙邱工程师在缩微电磁组积累的调车心得可帮助备赛者减少初期摸索成本提升车模稳定性与响应速度。目前已有245人学习浏览适合需要快速搭建电磁组基线方案、借鉴成熟调试经验的参赛队伍。1. 整车架构与代码模块划分先画框架再写代码做智能车竞赛电磁组最容易犯的一个错误就是拿到例程就改改到哪算哪。等你把传感器数据、PID参数、电机输出全部堆在一个 main.c 里车跑起来出了毛病想定位问题是哪儿出的那就真的只能靠猜了。所以无论你用的是哪一届的车模、哪家的单片机第一步一定是先把整车架构理清楚。1.1 电磁组整车传感器的基础选型与排布思路电磁组核心是检测赛道导线中交变电流产生的磁场车模上通常用一组工字电感配合谐振电容来感应。常见的排布有水平电感、垂直电感和斜光电感三种思路。很多人会纠结到底用几个电感实际上以近年国赛规则来看3个水平电感加2个斜光电感是比较稳的起步组合复杂赛道再加两个水平电感做超前预瞄。我的建议是前期不要贪多先把3个水平电感的信号吃透再逐步增加。因为你每加一个电感对应的归一化、加权融合和元素识别逻辑都要跟着改代码调试难度会翻倍增长。我用过的组合是中间电感垂直放置负责主检测左右两个水平电感负责赛道偏移方向判断。这一套组合在十字、环岛、坡道上的表现都不差关键参数也容易调。1.2 代码模块划分采集、滤波、决策、执行四层分离我个人的工程习惯是把代码拆成四层每一层只负责一件事。底层电感ADC采集和电机编码器读取只负责拿数据不参与任何策略判断。信号层对原始ADC值做滤波处理输出稳定的电感值和速度值。决策层根据电感信号判断赛道位置、识别元素、计算目标速度和目标舵机角度。执行层把目标角度和目标速度交给PID控制器最终输出PWM给舵机和电机。这样做的好处非常明显比赛前你只需要盯着决策层调参数底层和信号层只要测一次没问题后面基本不用动。如果你的队伍打算从21届规则过渡到新规则这种分层结构也能让你快速适配新传感器而不是把原代码推倒重写。下面这个结构是我常用的代码目录基本不用改动就能适配大部分单片机平台├── bsp/ // 板级驱动ADC、PWM、定时器、串口 ├── control/ // PID控制器、舵机与电机控制 ├── signal/ // 滤波、归一化、加权融合 ├── strategy/ // 元素识别、状态机、速度规划 └── main.c // 主循环调度分层设计还有一个隐藏好处当你从8位单片机换到Cortex-M系列只需要重新实现bsp层上层算法代码可以原封不动地移植。我在21届备赛时就是从K60换到TC264signal和strategy两层几乎零改动省下的时间全用来跑赛道了。2. 电感信号采集与归一化信号链决定车的上限电磁组的信号链是整个系统里最容易被低估的部分。很多队伍代码看起来没问题PID也调了不少但车就是跑不稳大概率就是电感信号本身就是不干净的。2.1 硬件调理电路与LM393寻光方案的借鉴很多做过寻光小车的同学对LM393比较器电路很熟其实电磁组信号调理的思路和寻光车也有共通之处。电感感应出的交流信号先经过谐振选频再经过放大、检波最后送到单片机的ADC引脚。如果硬件电路直接输出的是比较器方波那你的软件只能拿到有/无信号两个状态这对电磁组来说信息量远远不够所以绝大多数队伍最终都会选择使用ADC采集模拟量而不是接比较器。我之前踩过一个坑电感放大倍数调得太大导致ADC在赛道中间也接近满偏左右移动时数值几乎不变方向判断直接失效。后来把放大倍数调整为中间电感在赛道中央约ADC满量程的60%-70%左右电感大约40%-50%才算留出了足够的线性区间。这个经验值在不同车模和不同赛道上有差异但大概率能给你一个起步参考。2.2 归一化与差比和把原始ADC值变成稳定误差量拿到电感ADC原始值之后不要直接用一是因为不同电感的放大倍数、谐振参数存在个体差异二是因为地线干扰和温漂会让基线缓慢变化。我每跑一条新赛道第一件事就是采集一条空赛道把每个电感的最小值和最大值都记录下来然后对原始值做线性归一化。归一化的代码很简洁但这个步骤决定了后面所有计算的稳定性float scale_value(uint16_t raw_value, uint16_t min_value, uint16_t max_value) { if (max_value min_value) return 0.0f; float x (float)(raw_value - min_value) / (float)(max_value - min_value); if (x 0.0f) x 0.0f; if (x 1.0f) x 1.0f; return x; }归一化之后我习惯把三个电感的组合量换算成一个偏差量。最常用的就是差比和左右电感信号之差除以左右电感信号之和得到一个正负对称的数值正值表示车偏右负值表示车偏左绝对值表示偏移程度。float calculate_error(float left, float right) { float sum left right; if (sum 0.001f) return 0.0f; return (right - left) / sum; }这个error值就是后续转向控制的输入。它天然把赛道宽度的影响排除掉了换赛道不需要重新标定。很多新队员会问为什么我的差比和数值很小、变化很平缓多半是因为左右电感间距太窄或者归一化基准没校准先查这两项不要急着改PID。2.3 滤波细节滑动平均还是低通滤波电感信号在过十字、环岛时会有明显的跳变和毛刺直接拿去算差比和再进PID容易引起舵机抖动。我自己在信号层用的是滑动窗口平均窗口大小取5到7个点实测下来延迟可以接受滤波效果也够。如果单片机主频紧张可以用一阶低通递归滤波代码量更少效果也不错float low_pass_filter(float input, float last_output, float alpha) { return alpha * input (1.0f - alpha) * last_output; }alpha值一般取0.3到0.5越大跟随越快、滤波越弱越小越平滑、延迟越大。我的建议是在直道用稍大的alpha在弯道可以用大前瞻的斜光电感信号来补偿延迟这样整体动态响应和稳定性都能兼顾。3. 转向控制核心差比和、加权融合与PID参数整定电磁组的方向控制是整个代码方案里最核心的一块。我见过不少队伍归一化没做、加权融合没调好就急着把转向PID参数调到很大结果车在直道上左右蛇形。方向控制绝对不是单纯把PID调大调小那么简单。3.1 转向控制量的计算与限幅在拿到基础error值之后还可以叠加不同电感的加权融合。比如左侧斜光电感对前方弯道的敏感度更高右侧水平电感对当前偏移更敏感。我会给不同来源的error配不同的权重让车在弯道入口提前响应在弯道中保持稳定。下面这段代码展示了如何把多路信号融合成最终的方向控制输入float combine_direction_error(float mid, float left, float right, float left_diag, float right_diag) { float base_error calculate_error(left, right); float lookahead (right_diag - left_diag); float dir_error 0.6f * base_error 0.4f * lookahead; if (dir_error 1.0f) dir_error 1.0f; if (dir_error -1.0f) dir_error -1.0f; return dir_error; }权重比例需要根据赛道实际来标定没有通吃所有赛道的固定值。一个实用技巧是在入弯之前那段直道上观察斜光电感的变化能否准确预示弯道方向如果能就把lookahead的权重大一些如果入弯总是冲出去那说明前瞻权重过高、介入太早把提前量减小即可。3.2 转向PID参数整定的实测过程电磁组转向控制一般用位置式PD就够了I项在很多场景下反而不合适因为它会引入积分饱和在长弯道中一直累积误差导致出弯回正太慢。我最常用的转向PD模板如下float steer_pid_ctrl(float error) { float P 0.85f, D 4.2f; static float last_error 0.0f; float d_error error - last_error; last_error error; float output P * error D * d_error; if (output 90.0f) output 90.0f; if (output -90.0f) output -90.0f; return output; }D项的作用是在误差快速变化时抑制过冲相当于给转向加了阻尼。整定时先只给P车能过中速弯道之后再加D解决直道抖动。一轮实测下来你会发现同一个P值车上坡道和下坡道的表现完全不同因为负载和重心转移影响了转向响应。这是正常的不要为某一类赛道去拼命调参而是要学会用前瞻和速度调节来适配。3.3 速度与转向的耦合处理电磁组的速度控制和方向控制不是两个独立回路它们之间必须耦合。高速情况下舵机转角稍微大一点车就会因为惯性冲出去低速情况下转向即使很激进车也大概率能救回来。所以速度控制一定要根据当前的转向输出做一个动态限幅。我实现的方法很简单实时计算舵机输出量的绝对值如果偏大说明当前弯道很急速度控制器输出的目标速度就打一个折扣。折扣系数用分段线性函数float speed_restrict_by_steering(float target_speed, float steer_abs) { if (steer_abs 20.0f) return target_speed; if (steer_abs 80.0f) return 0.25f * target_speed; return target_speed * (1.0f - (steer_abs - 20.0f) * 0.75f / 60.0f); }这样的好处是代码简单、调参直观不需要专门通过机器学习或查表来建立速度与转向的映射关系。你在调试时只要盯住两个阈值多大的转角开始减速、多大的转角强制降到最低速。这两个值标定好绝大多数组合弯都能顺利过。4. 元素识别与特殊路况处理不能靠猜要靠状态机电磁组赛道上最常见的特殊元素就是十字、环岛和坡道。这几类元素靠单一电感信号很难精准识别但用代码完全可以做到可靠判断。核心思路是用状态机把当前车辆所处状态、历史信号特征和传感器突变结合起来判断而不是拿到一帧信号就下结论。4.1 十字、环岛、坡道的信号特征十字路口的特征是中间电感信号短暂急剧增强、左右电感同时出现明显抬升。因为十字线上的磁场分布比直道更复杂感应强度变化很快。碰到十字时不要做太激进的动作保持当前方向修正量即可但要注意在十字区域前面适当减速防止车身在脱离十字时突然抖动。环岛的判断更麻烦需要左右电感信号的长时间不对称。我的处理办法是设定一个N毫秒的持续检测窗口在窗口内如果左右电感偏差持续超过阈值就判定可能进入环岛同时开始记录方向信息。这样能有效避免直道上的瞬时干扰导致误判。坡道的特点是高差导致电感信号整体强度变化。上坡时中间电感信号会明显变弱如果不做归一化这一变化会被误认为是车体偏移。归一化在这里帮了很大忙它能让坡道上的整体信号幅值变化被削弱而左右偏移信息仍然保留。4.2 用状态机管理元素识别与恢复我建议在代码里维护一个简单的枚举类型typedef enum { STATE_NORMAL, STATE_CROSS, STATE_RING_ENTER, STATE_RING_INSIDE, STATE_RING_EXIT, STATE_RAMP } track_state_t;状态机的迁移逻辑要非常保守。比如从NORMAL进入CROSS需要同时满足连续5帧十字特征条件成立从CROSS回到NORMAL也要连续5帧特征消失才允许切换。这个延迟判定能极大降低误判率。在RING_INSIDE状态里转向控制就不再依赖差比和error而是使用固定的内侧环岛修正角度直到检测到出口信号回到STATE_NORMAL。这段逻辑写起来并不难但实际调试时一定要在真赛道上反复跑因为在电磁信号上环岛出口和入口的波形非常像很容易误判。5. 实测调试从模拟赛道到冲击国赛的落地经验代码写完了、参数粗调了真正的考验才刚开始。我每次调试电磁车都会随身带一个串口模块把关键变量实时打印出来通过上位机绘制曲线观察信号变化。这不只是排查问题的手段更是验证自己代码逻辑是否正确的最快路径。5.1 用串口输出与逻辑分析仪定位问题当你发现车在某个弯道撞路肩时不要直接去调PID先看串口数据。把左右电感归一化值、差比和error、舵机PWM输出、速度目标值这四组数据以时间戳形式发出来你就能看出是哪一层出了问题。比如转弯前error已经明显增大但舵机输出没有跟上那就是PID响应太慢如果舵机输出跟上了但车还是进不了弯那就是前瞻不够或者速度没降下来。这四组数据配合赛道跑圈的录像基本能覆盖90%的疑难杂症。5.2 参数在线标定的一个小技巧我写代码时会用拨码开关或者蓝牙模块做在线参数修改不需要每次改参数都烧录固件。方法很简单在决策层里留一组全局参数通过串口接收协议更新值。调试时你只需要把笔记本连上蓝牙赛道边直接改P、D和权重观察车的反应效率比反复烧录高一个量级。5.3 常见坑与应对策略这里分享几个我平时带队时最常遇到的坑供大家参考。电感基线没有定期校准。赛道环境变化导致电感最小值、最大值漂移后归一化失效差比和输出异常。建议上电自检阶段预留一段空跑自动采样基线。滤波窗口设置过大。滑动平均窗口取到15个点以上时信号延迟会明显增加入弯反应慢半拍。窗口最好控制在5到9之间。目标速度和转向输出耦合太弱。很多队伍速度控制独立跑转向控制独立跑速度闭环本身没问题但合在一起车就飞。一定要做动态限速。PID参数不区分上下坡。坡道段如果完全不调整D项车在坡顶会有明显点头。可以考虑用坡道状态机略微降低D项增益。环岛出入口判断过度依赖单个帧。单帧判断极其容易误判务必用持续特征窗口加状态机。最后再补充一个经验在冲击高速之前先把低中速的稳定性做到极致。很多队伍一上来就追求3m/s甚至更高结果每天都在处理撞车和甩尾连基础数据都没积累下来。我带的队伍通常先把1.5m/s速度跑满整条赛道保证这个速度下不冲出赛道、不误判元素然后以0.1m/s为单位往上加。每一次提速后最先暴露的不是速度控制的问题而是信号处理在动态场景下的不足这个迭代过程才是电磁组真正的成长路径。本文还有配套的精品资源点击获取