news 2026/11/6 1:04:52

智能车竞赛开源目录:电路设计、PID控制与图像处理实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
智能车竞赛开源目录:电路设计、PID控制与图像处理实战解析

第二十一届全国大学生智能车竞赛结束后的那个暑假,我们Soberup战队做了一件比拿奖更让我觉得踏实的事:把整个备赛过程压缩成了一份结构化开源目录——原理图、PCB工程、TC264端嵌入式代码、图像处理脚本、调参记录、踩坑文档,全在里面。这份目录能被叫“疯狂电路组”,不是因为名字响亮,而是我们从电源方案到电机驱动,几乎把所有能推翻的设计都推翻了一遍,最后留下来的都是经过赛道验证的版本。如果你正在备赛、准备接手战队、或者单纯想看看一支电控队伍是怎么把“车能跑”变成“车稳跑”的,这份目录的拆解思路应该能帮你少走至少一个月的弯路。

我会按实际使用顺序,把目录里的核心文件和背后的设计逻辑逐层拆开讲。不是简单的文件清单罗列,而是每个模块“为什么这么设计、调试时遇到什么、最终怎么落地”的完整复盘。

1. 开源目录到底“开”了什么:先看懂Soberup的文件夹

很多战队开源就丢一个代码压缩包,解压之后全是main.c、test1.c、最终版v3.c,看得人血压升高。我们这次刻意避免这种局面,目录顶层是这样设计的:

SmartCar-21-Soberup/ ├── 00_Docs/ │ ├── README.md │ ├── competition_notes/ │ ├── rule_analysis/ │ └── post_match_review/ ├── 01_Hardware/ │ ├── schematics/ │ ├── pcb/ │ ├── datasheets/ │ ├── bom/ (含嘉立创/立创EDA导出BOM) │ └── manufacturing_notes/ ├── 02_Firmware/ │ ├── tc264_project/ │ ├── drivers/ │ ├── algorithms/ │ ├── control/ │ ├── perception/ │ └── modules/ ├── 03_Tools/ │ ├── config_tool/ │ ├── data_logger/ │ ├── image_debugger/ │ └── battery_tester/ └── 04_Tests/ ├── bench_test/ ├── track_test/ └── calibration/

顶层结构是给两类人准备的:一类是刚进实验室的大一新生,可以直接顺着00_Docs读起;另一类是想立刻动手改硬件的师兄,直接进01_Hardware。中间不需要猜。

1.1 真正值钱的是“反模式记录”

目录里有一个容易被忽略的文件夹:post_match_review。里面不是比赛总结PPT,而是失败实验的完整记录。比如某版电源板在电机启动瞬间掉压导致主控复位,我们把波形截图、原因分析、修改方案做成了一页页“事故报告”。这些内容拿到下一届,比任何成功设计都能更快帮人避开重复踩坑。

1.2 开源目录不完整的地方,我也直说

诚实讲,这份目录并没有包含全部源码。部分图像处理核心算法因为涉及指导老师横向项目,我们只开放了流程框架和关键思路,没有放出逐行代码。另外,现场赛时临时改的几版参数没有完全回填到仓库里,这是整理时时间太紧留下的遗憾。所以在看这份目录时,建议把它当“带导航的地图”而不是“一键复制粘贴的保姆教程”。

2. 疯狂电路组的硬件核心:电源、电机驱动与信号调理的取舍

电路组的“电路”二字不是白叫的。整辆车上最难的部分不是代码,而是在有限空间和有限功耗下把电送对、送稳。

2.1 供电架构:为什么我们不直接一个DCDC拉到所有芯片

电池用的是一块7.4V的2S锂聚合物电池,标称容量和放电倍率都经过筛选。整车供电分了三条主干路:

  • 动力路:7.4V直接进电机驱动,经过大电流MOS开关后给电机,这一路要承受频繁的大电流冲击。
  • 逻辑路:7.4V经过一级同步降压DCDC转5V,再经过低噪声LDO转3.3V,供主控、摄像头、编码器、IMU。
  • 采样路:电磁传感器和电流采样的运放供电,单独用一路低噪声LDO,避免与数字电路共用电源带来的纹波串扰。

电解电容和陶瓷电容混搭是基本功。电机启动瞬间电流能到5A以上,如果电源环路响应跟不上,不说主控,光是摄像头就会出斜纹干扰。我们最后在电机驱动输入端并联了一排低ESR的聚合物电容,实测启动压降从之前的0.4V压到了0.1V以内,稳定性一下子就不一样了。

2.2 电机驱动:“疯狂”到底疯狂在哪

我们的电机驱动板用了双路半桥并联输出结构,峰值电流余量比常规方案大了一倍。刚开始有人觉得这是浪费,事实证明在频繁启停的环岛和坡道元素上,余量就是可靠性。栅极驱动芯片我们换过三款,最终留下的那款主要胜在死区时间稳定,不会在高速PWM下出现上下管直通。死区设得太小会炸管,设得太大又会产生明显非线性,这块参数必须根据实际使用的MOS开关电荷反复标定。

驱动板的布局上,功率地和信号地是严格分开的,在电池负极单点汇合。这个细节让我们的电流采样波形从毛糙变干净,后续速度环的PI参数也更好整定。

2.3 信号调理链:电磁传感器和电流采样的共同逻辑

现在赛道上电磁组依然有位置,我们电路组在验证阶段也做了电磁传感器板。工字电感感应到的微弱交变信号要先经过选频放大、整流、滤波,再进ADC。这里运放选型比放大倍数更重要,低输入失调电压和低噪声是第一优先级,增益稳定性反而是第二位的,因为ADC采完还要在软件里做归一化。整流后的RC滤波截止频率大概取在几百赫兹,太高纹波大、太低动态响应慢,实车测试下来这是个比较甜点的区间。

如果你对“业余制作锂电池放电仪”这类分立元件电路感兴趣,我们的battery_tester文件夹里正好有一套用功率电阻加恒流MOS管搭的简易放电负载,配合单片机的ADC做电压采集,可以在备赛时挑电池、测内阻。用分立元件组装的版本虽然精度不如专用芯片,但逻辑完全透明,调试起来反而更容易理解恒流原理。

2.4 PCB布局经验:改版三次得出的规则

我们PCB一共改了三版,第一版能跑但纹波大,第二版加了地平面但铺铜不完整导致部分运放失调电压漂移,第三版才稳定下来。核心经验就几条:

  • 大电流走线尽量短粗,过孔要多打,估算电流密度时别卡着上限用。
  • 模拟地和数字地确实要分,但分割线不能把底层地平面切成孤岛,信号跨分割区时一定要有回流路径。
  • 电感、MOS、续流二极管这些高频开关器件离传感器接口远一点,必要时要加屏蔽框。

3. 从底层驱动到调度框架:TC264上的软件架构复盘

电控代码不是随便写个while循环就能稳定跑的,尤其上了环岛和坡道之后,每个任务的时间确定性都必须可控。

3.1 TC264多核怎么分工

TC264是双核单片机,我们做了明确分工:CPU0跑主状态机、控制环路和通信任务,CPU1跑图像采集、图像预处理和特征提取。两个核之间通过共享内存传递图像帧和计算结果,配合硬件信号量防止读写冲突。这样能把图像处理这种耗时大户隔离出去,主控环路仍然保持严格的时间确定性。

刚开始我们试过把任务全塞在一个核里,结果图像处理稍微波动一下,速度环立刻跟着抖。后来拆了核,相当于一人盯一段流水线,控制质量立刻提升。

3.2 外设驱动里的细节

代码库drivers目录里几乎每个外设都有对应的测试demo,这是强烈建议效仿的习惯。摄像头用了MT9V03X系列感光芯片,DMA搬运图像数据到内存双缓冲,PIT定时器触发采集帧率锁定在固定值,这样后面图像算法拿到的帧间隔严格一致。编码器用定时器输入捕获,多倍频方式提高低速分辨率。舵机和电机PWM频率也是反复实验过,不是随意选的。

串口部分我们留了两个物理通道:一个接无线模块调参,一个接蓝牙模块做低速日志输出。比赛现场人很多,无线模块抗干扰能力直接决定你能不能在现场快速调车,这块必须提前测试。

3.3 为什么不用RTOS:比赛场景下的偏执选择

很多同学问为什么不直接上FreeRTOS。我们考虑过,但比赛场景的特点就是任务少、周期固定、行为高度确定。裸机定时中断加一个精简调度表就完全够用,还能避免RTOS优先级翻转和调度抖动带来的不确定性。想改车的逻辑,打开一个函数就能改,不需要翻任务通信文档,这对比赛最后两天的紧急调试太重要了。

调度框架上,我们按1ms、5ms、20ms、50ms分了四个周期档。1ms里跑编码器读取和舵机控制输出,5ms里跑速度环PI,20ms里跑方向控制和赛道元素状态机,50ms里跑无线通信和电源监测。分层分周期,出问题时候能快速定位是哪一层抖了。

4. 控制算法的人肉调参记录:把“PID输出角速度”讲明白

这个赛季我们最满意的不是某个电路,而是把方向控制和速度控制的衔接理顺了。很多队伍把转向和油门分开调,但我们发现,真正让车稳定的关键是让方向环和速度环对同一个物理量达成共识。

4.1 “PID输出角速度”这个说法到底怎么回事

网上经常有人搜“智能车PID输出角速度”,其实这不是一个严谨的控制术语,但它在工程里很常见。我们的做法是:速度环的目标量直接给定为车轮的角速度,单位是rpm或者rad/s,编码器反馈回来也是角速度,误差经过PI运算后输出电机PWM占空比。说白了,最内层是“轮速角速度环”,外层才是“整车速度环”。

这样做的好处是,轮胎打滑、负载变化引起的控制偏差可以在内环被快速抑制掉,外环只需要给出“我想跑多快”的目标角速度就行。如果不分层,直接拿整车速度去算PWM,车在坡道上的表现会非常挣扎。

4.2 参数整定顺序:先机械、再内环、再外环

我们整理了一份详细的调参手册,核心顺序是:

  1. 把机械调好。前束、主销后倾、底盘高度、重心位置,这些不解决,电控参数怎么调都白搭。
  2. 只调内环。给固定目标角速度,观察轮子是否快速到达、有没有超调,P和I先粗调。
  3. 再调外环。让车走直线,观察速度波动和电流波动,然后加D抑制振荡。
  4. 最后调方向环。方向环的P和D需要在不同速度段分开处理,速度越高,方向D越要收敛。

这里有一个容易忽略的点:方向环输出的转向补偿量,最后也会换算成左右轮角速度的差值。所以方向控制和速度控制其实共享同一个底层内环,参数之间会互相影响。我们每改一次方向参数,都会重新跑一遍直线加速看速度环是否被带偏。

4.3 赛道元素触发参数切换

环岛、十字、坡道的理想参数其实不一样。直线高速段我们希望方向环柔一些,避免频繁修正;环岛段我们希望方向环硬一些,确保贴内线。我们实现了一个简单的参数调度:图像特征状态机识别到特定赛道元素时,切换整套PID参数组。切换时机用的是“先切换、后执行”的策略,在特征确认但还没到执行点时完成参数装载,避免入环瞬间舵机响应迟滞。

这部分调试了大量数据,03_Tools/data_logger里存了当时的串口记录,可以还原出每个入环时刻的参数切换时序,对想复现的战队应该很有帮助。

5. 图像处理三件套:环岛识别、十字补线与动态前瞻

图像算法是决定车速上限的关键。电路组听起来偏硬件,但到了比赛后期,真正拉开差距的其实是图像处理的质量。

5.1 逆透视变换:把梯形赛道还原成俯视图

摄像头斜着装在车前,看到的是一个梯形赛道,远端窄近端宽。直接用这个图像算中线,远近引入的误差权重是不一致的。我们实现了逆透视变换,通过标定板获取透视矩阵,把图像映射成鸟瞰图。这样在鸟瞰图里赛道边缘基本平行,中线计算、曲率估算都简单很多。

标定过程要特别注意地面平整度和摄像头安装角度的稳定性,每次拆装摄像头后都要重新标定,不然保存的矩阵会失效。我们在代码里把这个矩阵参数做成可配置项,现场改安装角度后不用重新编译,直接串口下发就行。

5.2 环岛识别:状态机比单纯找特征靠谱

环形赛道最怕的就是入环判断晚、出环判断早。我们的方案是组合特征加状态机:

  • 环岛入口附近会出现一侧边界在较长一段行数内持续消失的“空洞”区域。
  • 优化边界提取时我们发现,只看边界跳变不够,还要结合曲率突变的方向来判断是左环还是右环。
  • 状态机分为“正常状态-疑似入环-确认入环-环内行驶-确认出环-恢复正常”六个状态,每个状态切换都有连续多帧确认,防止单帧噪声误触发。

这套状态机让我们的入环点比以前提前了大概一个车身距离,环内平均速度提高了约15%。调试时的录像回放都保存在04_Tests/track_test里,能看到每个状态切换时对应的图像帧。

5.3 十字补线:不是每个缺口都要刹车

十字是很多新队伍的噩梦。看到左右边界突然同时消失,第一反应是减速,其实不必要。我们的策略是:当底部若干行同时出现无效边界时,先判断是否处于十字区域,如果是就用上一帧有效边界的斜率和位置做外插补线,让中线计算不产生剧烈跳变。

补线会在图像上强加一条虚拟边界,这时中线可能看起来平滑,但实际赛道并不存在这条线。所以补线只适合短距离推理,一旦推理超过一定行数,就必须进入状态机判断,而不是盲目依赖补线。

5.4 动态前瞻:速度越快看得越远,但不能无限远

前瞻距离不是固定值。低速时看得近,转向更灵活;高速时看得远,提前感知曲率。实现方式是:根据实时测得的整车速度,动态调整要在图像中搜索有效边界的最远行数。速度越快,最远行越靠近图像顶端。

这里有个容易被忽略的坑:逆透视变换后图像远端分辨率低,一个像素对应真实赛道很大距离,直接把前瞻行拉得太远会导致抖动量放大。我们加了曲率平滑和边界筛选,保证动态前瞻在高速时不会把远端噪声当成赛道特征。

6. 整车联调的顺序与踩坑标本:一块PCB是如何毁掉整个周末的

硬件和软件单独看都没问题,合在一起才发现问题,这是最磨人的阶段。这一章对应的就是04_Tests里的真实记录。

6.1 先机械后电控,这个顺序不能乱

机械上我们每周末固定做一次全车检查:底盘螺丝扭矩、轮胎磨损、转向机构虚位、O型圈状态。转向虚位是最大的敌人,哪怕只有零点几毫米的间隙,在图像反馈里都会被放大成高频抖动。我们后来给转向拉杆换了球头轴承并加了少量阻尼脂,虚位问题才压下去。

传感器安装角度也很讲究。摄像头高度、俯仰角、电磁传感器离地高度,这些参数直接影响图像和信号质量,而且它们之间互相耦合。我们建立了一张“传感器姿态参数表”,每次调车都记录当前姿态,方便复盘是哪一次机械改动导致算法表现变化。

6.2 数据回放:一场让调试时间减半的习惯

data_logger工具会以固定周期记录图像特征、中线偏差、目标角速度、实际角速度、PID输出、状态机状态等数据,并打包传回上位机。每跑完一圈,我们可以在电脑上像看赛车游戏录像一样复盘:哪个位置方向发生抖动、哪个状态切换早了、哪个环节的角速度偏差过大。这比盯着屏幕上滚动的日志文本高效太多。

现场赛时,一套跑完立刻导出数据、回放、定位问题、改参数、再跑下一圈,这个闭环让我们在有限试车时间里调整了将近十轮参数。

6.3 三个典型踩坑标本

  • 电机启动瞬间主控复位:根因是电池到驱动板的线材过细,瞬时压降触发了主控低压复位阈值。换粗线加电容阵解决。这个案例放在hardware/manufacturing_notes里,还附了压降波形。
  • 摄像头图像雪花:数字电路和模拟电路的地在板子上某一点意外连通,导致开关噪声耦合进图像信号。重新分割地平面并加磁珠隔离后解决。
  • 运放输出电压缓慢漂移:PCB铺铜不完整导致运放参考地电位不稳定,温度变化后失调电压跟着变。这个问题查了一个通宵,最后用示波器对比了参考地电压才锁定。

这类问题没写在教科书里,但每个车队的实验室里都发生过。我把它们记在开源目录里,就是希望下一个人踩到同一块石头时,能少用一整个周末。

7. 复用开源目录的正确姿势:给21届之后战队的迁移建议

开源目录再完整,直接复制也会水土不服。每一届的赛道元素不同、MCU平台不同、队伍成员技术背景不同,合理的姿势是把这份目录当参考框架,而不是成品。

7.1 按备赛阶段对号入座

建议把备赛分成四个阶段,每个阶段只取目录里的对应部分:

  • 规则分析期(赛前1-2个月):只看00_Docs/rule_analysis,结合当年的官方规则梳理技术方案。这时不要碰代码,先搞清楚今年的赛道元素需要哪些能力。
  • 硬件设计期(赛前1个月到开赛前):参考01_Hardware/schematics和pcb,但不要照抄。芯片供货、元件封装、预算都会变,你要学的是划分电源域、处理地线、估算电流裕量的思路。
  • 软件框架期(硬件稳定后):参考02_Firmware的调度框架和驱动层写法。TC264相关的寄存器级配置如果换了平台,需要重写,但任务切分和周期规划可以沿用。
  • 赛道联调期:重点看post_match_review和04_Tests/track_test里的踩坑记录。你会发现很多坑都是跨年份共通的。

7.2 开源的道德问题:引用、改动和回馈

用了别人的开源成果,在文档和代码注释里保留原作者信息是基本礼貌。我们对所有来自开源社区的外设驱动都保留原始版权头,改动的地方单独写了一个CHANGELOG。如果你们基于这份目录做了大的改进,也非常欢迎把改进后的经验再传回给社区。智能车圈子这些年的传承就是靠一届一届这么互相抬轿子抬出来的。

7.3 目录不是终点,而是给下一把钥匙

整理这份开源目录过程中,我最大的体会其实是:把东西写下来的动作本身,就会逼你把每个设计决定重新想一遍。很多当时觉得“就这样吧”的地方,写文档时发现逻辑其实是断的;很多当时凭手感调出来的参数,写文档时才补上了“为什么是这个值”的解释。这份目录对我们战队的价值,甚至大于对别人的价值。

如果你正在准备下一届比赛,别等到比赛结束才开始整理。从一个驱动、一块板子、一次调参记录开始,一边做一边写。到赛门前你自然就拥有一份完整的开源目录,那时候你会感谢当时愿意多花十分钟记录的自己。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/6 1:04:40

MIPI LP TX调试指南:从电气原理到FPGA状态机实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/6 1:04:36

ESP32-S3/C3 Mini采购单技术规范指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/6 1:02:49

汽车诊断系统开发框架详解:从物理层到UDS应用层的完整设计思路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/6 1:02:12

Nor Flash 迁移到 SD NAND:接口、驱动与启动流程全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/6 1:01:15

C# 对象初始化器:让对象创建更简洁优雅

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/5 16:25:37

Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6…

作者头像 李华