【2024电赛H题硬核解析】自动行驶小车满分对策:多路灰度循迹与陀螺仪“交替盲走”融合算法(附源码)

🌟 前言与题目痛点分析

在2024年电赛(TI杯)H题或者历年的小车类题目中,**"循迹"**永远不是一条平滑的实线那么简单。出题人最喜欢在赛道上设置的障碍包括:

  1. 直角/锐角弯(常规PD算法极易冲出赛道)。

  2. 断线/虚线/全白区域(探头全白,小车瞬间"瞎眼"原地打转)。

  3. 光照干扰与赛道反光(探头读出乱码状态)。

今天,我们来深度解析一份直指国奖/高分 的底层逻辑代码。这份代码运行在TI MSPM0系列单片机上,核心亮点在于:巧妙结合了6路红外/灰度传感器与MEMS陀螺仪,在有线时精准压线,在断线全白时利用陀螺仪锁定航向角进行"交替盲走"!


🏗️ 核心架构:外环位置 + 内环速度(串级PID)

从小车的物理控制逻辑来看,代码采用了经典的串级控制思路:

  • 内环(速度环): 读取左右轮编码器,使用 pid_A 和 pid_B 确保电机在电池电压波动、负载变化时,依然能稳稳输出目标转速。

  • 外环(位置/方向环): 根据【循迹误差】或【陀螺仪角度误差】,计算出一个转向补偿量 turn_adj,叠加到基础速度上。

公式表达为:

左轮目标速度 = 基础速度 + 转向补偿量 turn_adj

右轮目标速度 = 基础速度 - 转向补偿量 turn_adj


🔍 亮点一:教科书级别的 6路循迹状态机设计

很多新手写循迹,喜欢写无数个 if...else,不仅运行效率低,一旦遇到噪点就容易跑飞。

我们来看看代码中的 TrackCar_GetError() 是怎么处理的:

1. 二进制位掩码与查表法

探头读回来的状态被压缩成了一个 6-bit 的字节(例如 0x20 代表最左边压线,0x0C 代表中间两路完美压线)。通过 switch-case 直接查表,速度极快!

2. 细腻的权重划分(PD控制的基础)

代码把赛道偏差分成了 7个级别 (从微调的 ±0.5 到极限边缘的 ±4.5)。

特别注意:代码处理了"3路同时压线"的情况(如 0x1C, 0x18, 0x38)。因为实际比赛的胶带很宽,小车在转弯时经常会同时压住3个探头,这种细腻的过渡能极大消除车身的"画龙"抖动。

3. 最强抗干扰:状态记忆(软件滤波)

codeC

复制代码
default: 
    // 遇到不在字典里的状态(噪点)
    // 【不进行任何赋值操作】,直接 break
    break;

遇到反光读出类似 101010 的畸形状态怎么办?直接忽略! 此时返回的 car->previous_error 会保持上一次的正常偏差值。这就相当于加了一个物理惯性滤波器。


🧭 亮点二:杀手锏------基于陀螺仪的"交替盲走"逻辑

这是整份代码最精彩的地方!处理"断线全白"区域(如过十字路口、虚线或特定的90度盲转区)。

在 TIMER_0_INST_IRQHandler (1000Hz定时器) 中,代码做了一个优雅的判断:

codeC

复制代码
if (sensor_status != 0x00) {
    // ---------- 状态 A:有黑线,正常循迹 ----------
    was_on_track = true; 
    float trk_err = TrackCar_GetError(&myCar); 
    turn_adj = (track_Kp * trk_err) + track_Kd * (trk_err - last_track_err);
    // ...
} else {
    // ---------- 状态 B:全白,准备盲走 ----------
    // 1. 刚刚冲出黑线的瞬间触发
    if (was_on_track == true) {
        was_on_track = false; 
        
        // 目标角度交替翻转逻辑 (0 -> 105 -> 0 -> 105 ...)
        if (current_target_yaw == 0.0f) {
            current_target_yaw = 105.0f; // 考虑到机械过冲,设定为105度补偿
        } else {
            current_target_yaw = 0.0f;
        }
    }
    
    // 2. 陀螺仪 PD 角度控制
    float yaw_err = current_target_yaw - mySensor.yaw; 
    turn_adj = (yaw_Kp * yaw_err) + yaw_Kd * (yaw_err - last_yaw_err);
}

逻辑拆解:

  1. 脱线瞬间的捕捉: 利用 was_on_track 标志位,代码精准捕捉到了小车从有线变为全白的这一个瞬间

  2. 交替打角: 比赛中常常要求小车走到断头路后转90度寻找下一条线。代码直接将目标角度 current_target_yaw 在 0° 和 105° 之间切换。(注:设为105°而不是90°,通常是作者实测时为了克服轮胎打滑或超调而加的经验补偿值!)

  3. 无缝切入角度环: 此时外环立刻由"灰度PD"接管为"陀螺仪角度PD"。小车不会像无头苍蝇一样自旋,而是笔直地(或按固定角度)往前冲,直到探头再次压线,切回循迹模式。


⚠️ 亮点三:老兵的避坑细节(工程素养)

如果只懂算法不懂底层硬件,电赛也是拿不到奖的。main.c 中隐藏了几个极其珍贵的排错经验:

  1. 上电防乱码延时

    codeC

    复制代码
    // 等陀螺仪彻底启动稳定,避开上电乱码期
    Delay_ms(1000);

    MEMS芯片上电有初始化和内部校准时间(通常几百毫秒)。如果不等它就绪直接开串口中断,很容易接收错位导致死机。

  2. 清空串口接收 FIFO

    codeC

    复制代码
    while (DL_UART_Main_isRXFIFOEmpty(UART_1_INST) == false) {
        DL_UART_Main_receiveData(UART_1_INST); 
    }

    开启中断前,狂读寄存器,把里面复位时的垃圾乱码全扔掉,确保第一帧数据绝对干净。

  3. 硬件错误自恢复

    codeC

    复制代码
    default:
        // 遇到溢出或帧错误时,把垃圾数据读出来,清除硬件错误!
        DL_UART_Main_receiveData(UART_1_INST);
        break;

    UART通信极易产生 Overrun Error。一旦溢出标志位置位,很多单片机会永远卡死在中断里。在 default 分支里读一下寄存器,可以自动清除溢出标志,实现系统自愈。

  4. 停车清空I项(防溜车/疯跑)

    codeC

    复制代码
    // 强行清空 PID 的积分项 (I项),防止停车溜车
    pid_A.integral = 0.0f; 
    pid_B.integral = 0.0f;

    停止循迹时,不仅要让PWM输出为0,还要清空积分器。否则小车被卡住时积分器疯狂累加,下次启动瞬间会像脱缰野马一样飞出去。


💡 总结与启发

面对电赛 H题,这份代码给出了完美的答卷:
不惧虚线、不怕断头路、底层驱动极其强健。

对于即将参加后续比赛的同学们,建议大家把这套 "查表法循迹 + 陀螺仪补盲 + 串级PID控制" 的框架当作自己的祖传代码固化下来。在赛场上,只需要根据实际赛道调节 track_Kp(循迹灵敏度)和 yaw_Kp(转角灵敏度),就能从容应对90%的自动行驶题目!

创作不易,如果这份源码解析对你的电赛/毕业设计有启发,欢迎:

👍 点赞 ,给坚持开源分享的博主一点鼓励!

⭐️ 收藏 ,写不出循迹逻辑时拿出来抄作业!

💬 评论,有任何关于MSP0配置、PID调参的问题,随时在评论区交流!

祝大家代码一遍跑通,竞赛直取国一!🏆

相关推荐
机器学习之心6 小时前
大跨度拱桥施工智能优化:基于改进RBF神经网络与多目标算法的工程实践
人工智能·神经网络·算法·大跨度拱桥施工智能优化
Deep-w6 小时前
【MATLAB】基于 MATLAB/Simulink 的无刷直流电机(BLDC)转速控制模糊 PID 算法
开发语言·算法·matlab
桑榆肖物6 小时前
nanoFramework 正式支持 Raspberry Pi Pico RP2040
驱动开发·嵌入式硬件·iot
皮卡祺q6 小时前
【算法-0】背包问题(三维+二维)
java·javascript·算法
葫三生6 小时前
《论三生原理》对《周易》《道德经》的一次根本性重写?
人工智能·算法·计算机视觉·区块链·量子计算
天天爱吃肉82186 小时前
2026北京车展专题|电控产品及技术全景解读:集成化、高压化、碳化硅成主流
人工智能·python·功能测试·嵌入式硬件·汽车
一路往蓝-Anbo6 小时前
第五章:如何对 HAL 库本身进行单元测试?
网络·数据结构·stm32·单片机·嵌入式硬件·单元测试·tdd
心中有国也有家6 小时前
ascend-boost-comm:一次写完,到处复用——算子公共平台的 M×N 哲学
人工智能·经验分享·笔记·分布式·算法
AI科技星6 小时前
空间圆柱螺旋运动第一性原理终极推导·证明·核验·全量纲闭环
开发语言·人工智能·算法·计算机视觉·量子计算