基于 TI MSPM0G3507 的差速循迹小车完整工程(CCS + SysConfig + DriverLib)。
面向 2024 年电赛 H 题:12 路灰度循迹 + 编码器速度环 + IMU 航向保持,实现「有线 PD 循迹 / 脱线航向盲走」交替控制,并按赛题要求覆盖 直行撞线停车、跑道形、八字多圈 等路径任务。
仓库地址: https://github.com/kaka12331/2024-dian-sai-h-line-follower
2024 电赛 H 题为 智能循迹小车 类题目,场地通常由 直线、圆弧、折线/对角 等元素组成(如跑道形、八字交叉)。典型能力要求包括:
| 能力点 | 本工程对应实现 |
|---|---|
| 沿黑线稳定循迹 | 12 路灰度 + 横向误差 PD |
| 直线段航向保持 | IMU Yaw 软件归零 + 航向 PD 盲走 |
| 脱线后继续完成路径 | 脱线瞬间切换目标航向,陀螺仪保向 |
| 到达节点 / 撞线识别 | 灰度见线 / 丢线 + 里程闸门去抖 |
| 多圈、多任务切换 | 4 键模式机 + 段序列表 |
本仓库为参赛/复盘用 应用源码 + CCS 工程配置,便于复现调参与二次开发。
| 项目 | 说明 |
|---|---|
| 赛题 | 2024 全国大学生电子设计竞赛 H 题 |
| 主控 | MSPM0G3507(LaunchPad / 自制板) |
| IDE | Code Composer Studio (CCS) + SysConfig |
| 驱动 | TI DriverLib(ti_msp_dl_config) |
| 控制 | 双轮速度 PID + 循迹 PD + 偏航角 PD + 段序列状态机 |
| 显示 / 提示 | OLED 姿态显示 + 蜂鸣器节点提示 |
核心思路(100 Hz 定时器):
- 有黑线:12 路灰度算横向误差 → 循迹 PD 修正左右轮速
- 全白 / 直线段:IMU 相对航向 Yaw PD 盲走保向
- 左右轮:
base ± turn_adj作为速度目标 → 编码器闭环 PID 输出 PWM - 任务路径:段表(直线 / 弧线)+ 里程闸门 + 见线/丢线事件推进
┌──────────────┐ ┌────────────────────────┐ ┌────────────┐
│ 12路灰度探头 │────►│ 误差 / 见线 / 丢线 │ │ 差速电机 │
└──────────────┘ │ + 段序列状态机 │────►│ 左右 PWM │
┌──────────────┐ │ + 速度环 PID (100Hz) │ └────────────┘
│ 编码器 A / B │────►│ │
└──────────────┘ └───────────┬────────────┘
┌──────────────┐ │
│ IMU 陀螺仪 │──UART 帧解析────┘ 盲走 / 直行航向保持
└──────────────┘
▲
KEY1~4 模式切换 · 蜂鸣器 · OLED · 调试串口
| 按键 | 模式 | 行为 |
|---|---|---|
| KEY_1 | 八字 ×3 圈(段序列) | 要求 3 类八字路径,3 圈;启用过圈航向偏置,补偿陀螺仪漂移 |
| KEY_2 | 航向直行 | 锁定当前航向直行,任意探头见黑线后停车 + 长鸣 |
| KEY_3 | 跑道形 1 圈 | 要求 2:A→B 直线 → 弧 → 返程直线 → 弧,回到起点停车 |
| KEY_4 | 八字 × N 圈 | 要求 3/4:按 target_laps 跑八字(可 1 圈 / 多圈) |
| 再按同键 | 中止 | 运行中再按切换回 MODE_IDLE 停车 |
启动任一运动模式前会 等待约 300ms 稳定 + 多帧平均锁软件航向零点,并短鸣提示就绪,避免手指压车导致零点歪斜。
路径用表驱动,每段为 直线(航向盲走) 或 弧线(灰度循迹),并用 编码器里程闸门(默认走够预期长度的 70%)过滤误检/漏检。
相对航向以 A→C 对角方向 为 0°:
| 段序 | 类型 | 目标航向 | 预期里程 | 说明 |
|---|---|---|---|---|
| 0 | 直线 | 0° | ~1.28 m | A→C 对角盲走,见线进弧 |
| 1 | 弧 | — | ~1.26 m | C→B 循迹,丢线出弧 |
| 2 | 直线 | ~-108° | ~1.28 m | B→D 对角盲走 |
| 3 | 弧 | — | ~1.26 m | D→A 循迹 |
- KEY_1:固定 3 圈,第 2 圈起 A→C 加
yaw_lap_bias;B→D 用分圈显式角fig8_diag_lap1 / fig8_diag_rest - KEY_4:圈数 =
target_laps(调试器可改)
相对航向以 A→B 为 0°:
| 段序 | 类型 | 目标航向 | 预期里程 | 说明 |
|---|---|---|---|---|
| 0 | 直线 | 0° | ~1.00 m | 顶边 A→B |
| 1 | 弧 | — | ~1.26 m | 右半圆 B→C |
| 2 | 直线 | ~185° | ~1.00 m | 底边 C→D(返程,实车标定) |
| 3 | 弧 | — | ~1.26 m | 左半圆 D→A |
每经过一个节点 短鸣;末圈终点 长鸣约 1s 并停车。
| 文件 | 职责 |
|---|---|
empty.c |
主程序:模式机、100Hz 控制、按键任务、串口/OLED 显示 |
track.c/h |
6/12 路灰度读取、查表误差、电机底层接口 |
motor.c/h |
左右轮 PWM + 方向脚 |
pid.c/h |
位置式速度 PID(限幅 + 积分抗饱和) |
encoder.c/h |
双编码器测速 / 测距(脉冲 → m/s、m) |
imu_parser.c/h |
新 IMU 串口协议解析(0x5A 帧:加速度 / 陀螺 / 欧拉角 / 四元数) |
mems_sensor.c/h |
旧版 MEMS 协议(可保留对照;当前主路径用 imu_parser) |
key.c/h |
4 键扫描消抖(定时器内 Key_Update) |
OLED.c/h + OLED_Font.h |
四行 OLED:Roll / Pitch / Yaw / 相对航向 Yr |
uart_debug.c/h |
调试串口打印 |
delay.c/h |
微秒/毫秒延时 |
empty.syscfg |
SysConfig 引脚与外设配置源 |
targetConfigs/ |
MSPM0G3507 目标配置 |
Key_Update() + Encoder_Update() + Beep_Update()
MODE_TRACK:
有线 → turn = track PD(err)
全白 → 脱线瞬间切换目标角 0° ↔ blind_target_yaw
turn = yaw PD(target - Yr)
MODE_STRAIGHT:
turn = yaw PD(0°) 保向直行
连续见线 → 停车 + 长鸣
MODE_SEQ:
直线段: yaw PD(段航向) + 里程闸门后见线 → 下一段
弧线段: track PD + 里程闸门后连续丢线 → 下一段
末圈完成 → IDLE + 长鸣
左右轮:
vA = base ± turn_adj
PWM ← PID_Calc(编码器速度环)
| 参数 | 默认 | 含义 |
|---|---|---|
track_velocity |
0.4 m/s | 有线 / 弧段基础速度 |
blind_velocity |
0.4 m/s | 盲走 / 直线段基础速度 |
track_Kp / track_Kd |
0.07 / 0.01 | 循迹 PD |
yaw_Kp / yaw_Kd |
0.023 / 0.005 | 航向 PD |
yaw_turn_limit |
0.25 m/s | 航向差速修正上限 |
blind_target_yaw |
-108° | 八字对角盲走目标(IMU 坐标系,注意符号) |
yaw_lap_bias |
10° | KEY_1 第 2 圈起 A→C 航向偏置 |
fig8_diag_lap1/rest |
-103° / -97° | KEY_1 对角段分圈目标角 |
| 速度环 PID | Kp=1900, Ki=15, Kd=1 | 左右轮编码器闭环 |
SEG_GATE_FRAC |
0.70 | 段切换里程闸门比例 |
符号约定: 本 IMU 模块 Yaw 正方向与期望物理转向可能相反。
要物理转约 105° 时,目标角常填 -105° 附近。
- 车能稳住但转反了 → 改
blind_target_yaw等目标角的符号/数值- 车原地打转不收敛 → 再动
YawHold_Calc里反馈极性
- 轮径 48 mm,编码器 13 线,减速比 20,双边沿 → 约 1040 脉冲/圈
- 输出
velocity_A/B(m/s)、distance_A/B(m),段里程取左右平均
具体引脚以 SysConfig(empty.syscfg)及编译生成的 Debug/ti_msp_dl_config.h 为准。
| 子系统 | 典型用途 |
|---|---|
| PWM 定时器 | 左右电机占空比、蜂鸣器 |
| GPIO | 电机方向、12 路灰度、4 键 |
| 编码器输入 | 左右轮测速 / 测距 |
| UART_1 | IMU 陀螺仪(imu_parser 协议) |
| UART_DEBUG | 上位机调试串口 |
| TIMER_0 | 100 Hz 控制节拍 |
| I2C / 软件 I2C | OLED |
上电流程:蜂鸣器自检 → 等待 IMU 帧 → 软件锁零 → OLED 显示姿态。
当前版本为被动收 IMU 帧,不依赖硬件解锁/归零指令。
- Code Composer Studio(支持 MSPM0)
- MSPM0 SDK / DriverLib
- 调试器:板载 XDS-110 或外部 SWD
- 用 CCS 导入本工程目录
- 打开
empty.syscfg,确认引脚与硬件一致 - Build → 生成
Debug/*.out - 连接 MSPM0G3507,下载运行
- 串口应看到类似:
Hello! System Init.../IMU ready (soft yaw zero). - 按 KEY1~4 启动对应任务;串口输出传感器位图、误差与航向
Sens:001100 000000 Err:x.x | TarYaw:n Yr:y.yy YawErr:z.zz Raw:r.rr
Sens:12 路 1/0(左 6 + 空格 + 右 6),压线为 1Err:横向误差TarYaw/Yr/YawErr:目标航向、相对航向、航向误差- OLED:Roll / Pitch / Yaw / Yr
- 先低速确认电机方向、编码器符号、灰度黑白极性
- 速度环:能平稳跟上
blind_velocity再开循迹 / 航向环 - 循迹:弯道冲出 → 略增
track_Kp;抖动 → 增track_Kd或降速 - 盲走:画龙降
yaw_Kp;不回正略增;打转检查极性 - 八字对角角
blind_target_yaw、跑道返程185°必须实车标定 - 多圈漂移:用
yaw_lap_bias/fig8_diag_*分圈补偿 - 节点误触发:加大
SEG_GATE_FRAC或段length_m
- 本仓库为 应用源码 + CCS 工程配置;
Debug/构建产物已忽略,请本地编译 - SysConfig 生成的
ti_msp_dl_config.*在完整编译后出现在Debug/ - 与同账号其他工程相互独立
| 仓库 | 内容 |
|---|---|
| 2023-dian-sai-visual-gimbal | 2023 电赛视觉伺服云台 |
| dual-stepper-trapezoid | 步进电机梯形加减速 |
| brushless-motor | 串口无刷电机控制 |
dian_sai_h_copy/
├── empty.c / empty.syscfg # 主程序与 SysConfig
├── track.* motor.* pid.* # 循迹 / 电机 / PID
├── encoder.* # 编码器
├── imu_parser.* # IMU 串口解析
├── mems_sensor.* # 旧 MEMS 接口(对照)
├── key.* OLED.* uart_debug.* delay.*
├── targetConfigs/ # 芯片目标配置
├── README.md
└── .gitignore
用于 2024 电赛 H 题 学习、复盘与技术交流。欢迎 Issue / PR。