【智能车】电磁组进阶之路(五):赛道元素识别与多状态机管理
前言
很多同学问:“大佬,你的直道判定阈值是多少?环岛判定值是多少?”
说实话,直接抄数值是最没用的。电感高度、运放型号、信号源功率不同,ADC 采集的绝对值天差地远。本文将揭示一套科学的“数据拟合”方法,并分享如何通过 状态机(直道/弯道/环岛/十字)实现真正的“分场景调参”。
一、判定阈值怎么定?别靠猜,靠“拟合”
我们在初期也尝试过抄大佬的阈值,结果车子跑得一塌糊涂。后来发现,最土但最科学的方法是:串口收集 + 数据拟合。
1. 数据收集黄金法则:别做“实验室派”
- 🚫 拒绝“完美数据”
不要只测量小车“正正好”在赛道中央的数据。在实战中,车子绝大多数时间都处于微小的偏差或晃动中。 - ✅ 动态采样
要刻意测量车头 略微偏离中心线(1cm, 2cm, 3cm…) 时的信号表现。💡 核心逻辑: 如果判定条件写得太“死”,车子稍微一抖,状态机就会在“直道”和“弯道”之间疯狂跳变(俗称:状态震荡)。
2. 基础元素判定逻辑:特征提取
为了提高识别率,我们不看单一电感,看特征组合:
| 元素类型 | 核心判定逻辑 (逻辑与 &&) | 物理意义 |
|---|---|---|
| 🏁 直道 | sum_heng > MIN_LIMIT && sum_shu < BEND_GATE | 确保有线,且没有检测到弯道前兆 |
| 🎢 弯道 | diff_heng > DIFF_THRESHOLD || sum_shu ↑ | 差值增大说明偏离,纵向值抬升说明角度切入 |
| 🛑 丢线 | sum_all < CRITICAL_VALUE | 所有传感器均无感应,立即刹车或找线 |
🔍 逻辑拆解:
- 信号强度: 横向电感总和 (
sum_heng) 必须大于最小阈值,这是系统运行的“底线”,防止误触发。 - 特征压制: 纵向电感总值 (
sum_shu) 是预判的“哨兵”。如果纵向值突然抬升,说明磁感线方向发生了偏转,前方大概率是弯道或特殊元素。 - 差值特征: 利用横向或纵向的电感差值(
diff_heng/diff_shu)的显著抬高来锁定转向时机。
二、关键策略:引入“默认区”
🛡️ 团队核心经验:
除了直道、弯道、环岛这三大金刚,你一定要写一个判断不出状态的 “默认区”。
1. 痛点:为什么要设默认区?
赛道上的数据异常复杂,当小车姿态不稳定、或是遇到电磁干扰时,传感器数据往往不符合任何一个标准特征。
- 🚫 错误做法: 强行把它归类到“直道”或“弯道”。
- 💥 后果: 导致参数不匹配,引起舵机剧烈抖动甚至打死,直接冲出赛道。
2. 处理逻辑:以稳求快
如果当前的信号不符合直道特征,也没达到环岛触发条件,就直接丢进“默认区”。
- ⚙️ 参数策略: 在默认区,使用 折中 的 PID 参数(介于直道和弯道之间,通常 P 值适中,D 值稍大以增加阻尼)。
- 🧘 最终目的: 优先让车回到 “正常姿态”。只有姿态稳了,才能再次判断出正常的赛道元素。
一句话总结: 默认区就是系统的“避风港”,极大增强了鲁棒性。
3. 实战案例:十字路口 = 默认区
早期的方案中,我们试图为十字路口写复杂的逻辑,结果经常因为识别过早或过晚导致误判。后来发现,十字路口除了纵向电感变大外,横向信号和直道区别不大。
- ❌ 复杂方案: 单独写十字路口的状态,容易状态跳变。
- ✅ 最终方案: 不单独设十字状态。
直接利用“默认区”的逻辑进行 盲操通过。因为十字路口的特征模糊,正好落入“默认区”的判定范围,利用折中的参数反而能平稳通过,效果最好。
三、Boss 级难点:七状态环岛状态机
🔜 预告:详细的代码实现与深度解析将移步至本系列的下一篇博文:
《【智能车】电磁组进阶之路(五)》
1. 为什么环岛这么难?
在智能车竞赛中,环岛本质上是一个 “时空干扰项”。
在入环、环内、出环的不同阶段,传感器采集到的磁场信号特征极其相似。如果你只用简单的 if-else 来判断,小车往往会像无头苍蝇一样在路口反复打转,或者干脆“拒不入环” 。
2. 破局之道:7 阶段状态流转
为了解决这个问题,我们将环岛拆解为 7 个逻辑阶段,让小车在每一个瞬间都清楚自己处于什么位置 。
| 状态 | 关键动作 (Action) | 核心逻辑 |
|---|---|---|
| 0. Idle (空闲) | 🔍 寻找 | 默认状态。当一侧纵向信号远强于另一侧(如 diff > 45)时触发 。 |
| 1. Detected (发现) | ⚠️ 预告 | 给出微小的 Steer_Offset,车头微微向环岛口靠拢 。 |
| 2. Enter Guide (入环) | ⚡ 强攻 | 最危险时刻。不再信任 PID,直接给一个强制的转向增益,把车“拽”进环 。 |
| 3. Inside (环内) | 🔄 巡航 | 回归基础 PID 跑线,但时刻监测“出口特征”(纵向再次抬升) 。 |
| 4. Exit Detect (出环) | 🎯 瞄准 | 发现出口,给出反向转向暗示,引导脱离圆环 。 |
| 5. Exiting (离场) | ⚓ 阻尼 | 给予反向补偿,强迫车身快速拉正,防止甩尾 [。 |
| 6. Done (冷却) | ❄️ 闭嘴 | 至关重要。开启 500ms 冷却期,防止因信号余波导致二次误判入环 。 |
四、分场景调参:隔离问题的艺术
❓ 灵魂发问:为什么要费劲写状态机?
并不是为了秀代码量,而是为了给不同的路况匹配专属的 PID 参数。
1. 匹配法则:物理特性决定参数性格
不同的赛道元素,误差变化率完全不同,必须按状态匹配PID参数:
| 场景 | 核心目标 | PID 策略建议 |
|---|---|---|
| 🛣️ 直道 | 追求“高车速”与“极低抖动” | 📉 Kp 较小,Kd 较大 (稳住车身,防止画龙) |
| ↩️ 弯道 | 追求“爆发力”与“入弯灵敏度” | 📈 Kp 大幅提升 (大开大合,拐得动,放宽限幅) |
| 🛡️ 默认区 | 追求“活着、不冲出赛道” | ⚖️ 折中参数 (使用介于直道与弯道之间的参数) |
2. 避坑指南:拒绝“连坐”
我们在调车时最常犯的错误是:试图通过调整全局增益来解决局部问题。
-
🚫 错误操作:
“哎呀,直道有点晃。” 👉 于是把整个代码的 Kp 减小了。
💀 后果:直道确实稳了,但到了弯道,车子因为 Kp 不够软绵绵地冲出了赛道。 -
✅ 正确姿势:隔离调参
在修改参数前,先看串口打印的State标志位:- 直道抖?👉 只改
Straight_PID。 - 弯道转不过去?👉 只改
Curve_PID。 - 谁的问题谁负责,绝不连坐式修改→株连九族。
- 直道抖?👉 只改
📝 总结
所谓“分场景调参”,本质上就是构建一个参数的多状态选择器。
你的状态机识别得越准,这套“动态参数系统”就越丝滑,车子才能在直道上稳如老狗,在弯道上绝不拖泥带水。。









