第21届智能汽车竞赛总决赛的看台边上,英飞凌轮腿穿越组几乎成了全场人气最高的“打卡点”。车还没发车,围栏外就挤了一排端着相机的学生和指导老师。我挤到最前面蹲了半天,最大的感受是:这项比赛已经不只是在比“谁能跑完”,而是在比谁对英飞凌这颗芯片、对电机控制、对编译和调试工具链的理解更透。趁着赛间休息,我跟几支车队的队员聊了聊,把关于TC264、ADS编译器、PMSM驱动和GTM模块的现场问题都摊开问了一遍,收获比想象中大得多。
1. 为什么轮腿穿越组成为了总决赛最值得蹲守的一站
1.1 轮腿穿越组到底在跑什么
智能汽车竞赛里的轮腿组,本质上是一台两轮自平衡小车,但任务远比单纯“立起来跑直线”复杂。总决赛的赛道里通常会有坡道、障碍、颠簸路面,甚至要求车辆在穿越过程中保持姿态稳定、不能碰到边界。轮腿车既要靠左右两个轮子维持纵向平衡,又要在行进中完成横向控制,这比普通四轮循迹车多了一个“随时会倒”的不确定因素。
现场看下来,绝大多数车队用的是英飞凌的TC264双核控制器。这颗芯片在智能车竞赛里的地位相当高,AURIX架构、两个TriCore内核、片内Flash和丰富的定时器外设,让它既能跑复杂的控制算法,又能应对高频的传感器采样。更有意思的是,几乎每支队伍的车上都贴着英飞凌的Logo,说明大家在选型上已经形成了高度共识:不是没有别的方案,而是这个方案在性能和生态上最省心。
1.2 从起跑先丢失到冲出赛道,现场的“事故”才是真教材
我在现场看到的完赛率其实不算高。有一支车队发车后刚过第一个坡道,车身就开始低频振荡,幅度越来越大,最后直接侧翻在弯道里。队员赛后跟我说,问题出在速度环和直立环的响应频率没拉开——直立环跑得太快,速度环又跟不上,两个环在同一个时间尺度上互相“打架”,车就会像弹簧一样越颠越猛。
还有一支车队的车在直线段跑得非常好,姿态稳得像是被钉在轨道上,但一到颠簸区就出现明显的“点头”现象。他们后来查出来,是轮子上的编码器采样频率不够,速度反馈在冲击瞬间出现了接近一个控制周期的延迟。这个细节在调试台上很难发现,只有上了真实赛道、遇到路面激励才算真正暴露。蹲在现场看这些事故,比看十遍技术报告都更有说服力。
2. 赛后采访:TC264和ADS编译器教会我的三件事
2.1 为什么大家都从Keil转到了ADS
我以前总觉得编译器只是写代码的工具,选哪个都差不多。现场跟队员聊下来才发现,对于TC264这种多核芯片,编译器的选择直接影响你能不能把代码塞进Flash、能不能压出足够的性能余量。
英飞凌官方的ADS,也就是AURIX Development Studio,是基于Eclipse的一套免费IDE。它最大的好处是和英飞凌的芯片绑定得非常紧,新建工程时会直接帮你把启动文件、链接脚本、内核配置这些底层东西准备好。相比之下,如果硬用通用IDE去建TC264的工程,光是链接脚本和三核启动代码就够你折腾一两个星期。
我问了几个队员“ADS下载和安装时踩过什么坑”,答案高度一致:版本兼容问题。有人装的是旧版ADS,配的是新版编译器插件,结果编译出来的elf文件在调试器里不认;还有人环境变量没有配置好,ADS自带的GCC工具链没有被正确调用,一编译就报“找不到make”这种莫名错误。如果你正准备用ADS,建议装完先建立一个空工程烧个LED点灯程序,确认整个工具链是通的,再往里搬算法代码,不要一上来就开大工程。
2.2 TC264双核任务划分的现场讨论
TC264最值钱的部分是它有两个TriCore内核,但很多队伍在最开始根本不知道怎么分配任务。我们在采访里专门聊了这个问题,有一支成绩不错的车队给出的方案很有参考价值:
- CPU0负责直立环和速度环,这两个环对实时性要求最高,必须独占一个内核,避免被其他任务打断。
- CPU1负责图像处理或传感器融合、路径规划、无线通信这类相对复杂的逻辑。
- 核间通信用共享内存加标志位的方式,主循环里轮询对方核放下的数据,不在中断里直接跨核访问。
这个方案听上去简单,但执行起来有不少细节。比如两个内核如果同时读写同一个内存地址,就会产生一致性问题,轻则数据错误,重则直接死机。他们的做法是每个内核只写自己管辖的变量,对方内核只读,读之前用编译器自带的内存屏障指令做一次同步。这种习惯很多初学者没有,调了几天车突然出现随机失控,往往就是缓存一致性惹的祸。
2.3 一段让我印象深刻的采访实录
采访过中有一位队员提到,他们最痛苦的折腾不是算法,而是把整个项目从裸机单核程序迁移到双核架构上。原话的大意是:
“我们把所有代码搬进ADS工程以后,编译倒是通过了,但跑起来总是在同一个地方卡住。后来用调试器看,才发现是一个全局变量既被CPU0的中断改、又被CPU1的主循环改,两边同时开始时就出现了竞争。最后花了一个晚上把所有跨核变量都列成一张表,逐一手动加锁,才把问题解决。”
这段话说得轻描淡写,但现场能感受到那种熬过夜之后的疲惫。用ADS的调试视图看变量、看内核寄存器状态,真的可以在这种离奇问题上一针见血。如果你也遇到莫名其妙的重启或跑飞,先别急着怀疑硬件,打开调试器看一眼两个内核各自停在哪个函数里,往往几秒钟就能锁定问题。
3. 从“会上路”到“跑得好”:PMSM驱动方案到底改了什么
3.1 轮腿车几乎都选了PMSM电机,为什么
现场看了十几辆轮腿车的电机构型,绝大多数都是永磁同步电机(PMSM),而不是传统的直流减速电机或舵机。原因并不难理解:轮腿车需要在极低速下输出大力矩来维持平衡,同时又要有足够的响应速度来应对瞬间冲击。PMSM天生具备力矩密度高、调速范围宽、运转平稳这些特点,配合FOC矢量控制,可以在整个调速区间内输出平滑的力矩。
英飞凌针对这类应用有一整套PMSM驱动系统解决方案,从单片机、栅极驱动器到MOSFET功率级,再到参考的FOC控制代码都可以串在一起。现场有支队伍直接用了英飞凌的驱动评估板做电机驱动部分,上层自己写算法,底层电流环和PWM生成全部交给官方代码库,这让他们的开发周期至少缩短了一个月。
3.2 FOC背后的英飞凌外设协同:ADC、GTM与PWM
要跑FOC,最核心的是要把电机的三相电流、母线电压、转子位置这些信号精确采进来,然后在一个极短的控制周期里完成坐标变换和SVPWM输出。这个过程中,ADC采样时刻和PWM载波信号必须严格同步。如果采样点对不上,电流环看到的数值会带着很大的纹波,控制品质会直线下降。
TC264的GTM模块在这里起到了关键作用。GTM有一个专门的TIM(定时器输入)单元和一个TOM(定时器输出)单元,可以灵活生成多路高精度PWM,同时利用它的触发信号去同步ADC采样。通俗地讲,GTM让PWM的边沿一出现,ADC就自动开始转换,不再需要CPU在中断里掰着手指算时间戳。现场队员跟我演示了他们的配置,这个同步关系在示波器上看得清清楚楚:电流采样点被稳定放在PWM载波的谷底,电流波形干净得几乎没有毛刺。
3.3 现场实测数据与调试心得
我们在采访里聊到了很多具体的调试参数,这里挑几个通用的心得说。
第一,电流环的PI参数一定要先在堵转或负载固定的条件下整定,不要在车轮空转时调。空转时皮带和地面的摩擦负载很小,电流环带宽看起来很高,一上真实赛道负载突变,电流环立刻就会不稳定。
第二,轮腿车落地瞬间的冲击电流非常容易超限。我在现场看到有队伍在电流环前面加了一个扭矩斜坡限制器,意思是当转速误差突然变大时,不直接把最大扭矩怼上去,而是用程序限制扭矩每秒能变化的最大幅度。这样做牺牲了百分之几的响应速度,却换来了整车的机械寿命——很多车摔了几次以后电机轴和行星减速器就开始出现异响,就是冲击电流引起的力矩尖峰把齿轮打伤了。
第三,PMSM驱动不是越快越好。现场也有一支队伍把电流环带宽调得很高,听起来很猛,但整个系统变成了一根“绷紧的钢丝”,任何一个微小噪声都会引起剧烈的力矩波动。正确的做法是把电流环带宽设置在电机电气时间常数的合理范围之内,让机械系统有时间“吸收”掉反馈上的抖动。
4. 你看不到的轮腿车内部:GTM、MCAL与数据通路
4.1 GTM不是一颗普通定时器
很多刚接触英飞凌芯片的人,第一次看到GTM模块的介绍时都会一头雾水:它到底是什么?跟普通定时器有什么区别?
普通单片机的定时器输出PWM,靠的是计数器溢出翻转输出脚。一旦你需要的PWM通道变多、频率变高、还要同时处理捕获和比较,CPU的负担就会直线上升。GTM的思路是把这些定时任务下沉到独立硬件单元里,内部有若干个可以并行运行的子模块,包括用来生成PWM的TOM、用来捕获输入信号的TIM,以及可以做多通道序列控制的ATOM等等。
对轮腿车来说,GTM最大的价值有两个:一是多路PWM输出不需要CPU逐个维护,二是它可以做到事件触发的高精度时间同步。比如用GTM的TIM模块去捕获编码器AB相脉冲,再用另一个输出通道触发ADC采样,整个数据采集链路可以做到零CPU介入。这种能力在普通单片机上是很难做到的。
如果你正在用TC264做电机控制,我的建议是别把PWM和采样都寄托在传统中断里。花一点时间读读GTM的基本结构,把PWM生成和ADC触发交给GTM管,你会发现CPU占用率一下子降下来一大截,空中腾出来的资源可以拿去做更复杂的决策逻辑。
4.2 EB MCAL 与 AUTOSAR:竞赛车队里的“重武器”
在热词里看到“eb 英飞凌 tc mcal”这条,说明已经有人开始关注MCAL这个层次了。MCAL是AUTOSAR架构里的微控制器抽象层,简单说就是把寄存器操作封装成标准API,让上层软件不用关心你用的是什么芯片。
EB tresos是英飞凌官方配套的MCAL配置工具,可以图形化配置引脚、时钟、中断、ADC、PWM等等,然后自动生成初始化代码。现场采访中,有队伍用了MCAL,也有队伍完全没用。用MCAL的好处是:引脚分配、时钟树这些底层初始化,不用再对着几百页参考手册逐句看,配置完点一下生成,代码就有了。
但MCAL也有它的代价。第一,工具链安装比较复杂,EB tresos和编译器、调试器之间的版本配套经常让人头大。第二,MCAL生成的是通用性代码,有些地方为了兼容性,性能不是最优。对于轮腿车这种要求极致实时性的应用,关键路径上的代码最后还是要自己写寄存器操作来替代MCAL生成的默认实现。
我的建议是:如果你想快速评估一块新板子,MCAL是很高效的入口;如果你已经明确知道自己的需求,直接在关键部位手写寄存器反而更可控。两者并不互斥,很多队伍的做法是初始化部分用MCAL,控制环部分的PWM和ADC触发自己写。
4.3 现场最隐蔽的坑:中断风暴与看门狗
轮腿车因为要处理电机控制、姿态解算、无线通信,中断源非常多。现场采访里有个队员提到,他们曾经在跑完一圈之后车突然“失忆”——所有状态清零,但又没有完全复位。查了很久才发现问题是看门狗中断和定时器中断优先级设反了,看门狗在每次喂狗时都会挤掉一个关键采样中断,导致控制环的数据链路上时不时出现一个空洞。
这类问题在调试中最难复现,因为每次出现的时机都不固定,但影响又很致命。我的经验是,在中断优先级的设计上一定要分层:电机控制相关的中断放到最高优先级,传感器采样次之,通信和显示任务放在最低优先级。同时尽量少用阻塞式API,串口打印要加节流,别让调试输出反向影响了实时控制。
5. 我在现场观察到的备赛细节和一些琐碎经验
5.1 成绩稳定的车队都在反复做同一件事:回归基础
连续看了几支跑得稳的队伍,发现他们有一个共同动作:赛前不停地做电机零位标定和传感器校准。轮腿车的电机和编码器在装配时会存在机械零位偏移,如果不做补偿,电机在零电流附近会产生一个固定方向的额外力矩,车就会“偏着站”。这个偏移量用肉眼看不出来,但会让直立环的输出始终带着一个常数项,车自然就站不稳。
一位队员跟我分享了他们的校准流程:上电以后先让电机工作在零电流模式,手动缓慢转动轮子,记录编码器读数与电角度的对应关系,然后把这个关系存成一张静态标定表。每到一个新场地,他们第一件事就是重新做一遍这个标定,而不是直接沿用上一站的参数。这个细节可能只有几分钟,但对整车姿态的一致性帮助极大。
5.2 一个好的调试顺序比什么都重要
现场看下来,我发现翻车概率最高的队伍,往往是那些在赛前临时改参数的队伍。轮腿车是一个高度耦合的系统,你在速度环上动一个系数,即便当时感觉速度响应变好了,也会在下一个弯道以直立环振荡的形式报复回来。
我的建议是先调机械和电路,再调传感器,最后再调控制参数。具体顺序大概是:先确认电机正反方向正确、编码器波形干净、电流采样没有偏置;然后做直立环,让车在原地保持平衡;再开速度环,让它能在直线上匀速行走;最后才加入路径规划、避障这些上层逻辑。每一步都稳定了再进下一步,不要并行迭代。比赛现场比的不是谁的参数更极限,而是谁的系统更不容易崩。
5.3 比赛不会告诉你的那些“场外功夫”
还有一个很容易被低估的地方是电源系统的稳定性。轮腿车的电机峰值电流非常大,瞬间可达好几安培,如果电池内阻偏大或线路压降过高,控制板上的电压就会出现跌落,英飞凌TC264本身倒是很皮实,但外部传感器和编码器很容易在低压下产生误码。现场有一支队伍在电池输出端加了一排大容量电解电容,相当于给整个系统加了一个小型稳压池,这个看似“不上台面”的操作,恰恰是许多稳定发挥背后的真正功臣。
我在现场还注意到,那些准备充分的队伍都有一个共同特点:车上留了充足的调试接口——串口、SWD调试口、备用IO都引出来了。比赛间隙他们可以非常快速地把调试器插上去看变量,而不需要拆开整车外壳。这种线上的“预埋”习惯,对压缩排错时间是非常有效的。
采访结束准备离场时,看台上还有队伍在连夜调试。轮腿车这种项目,真正难的不是某一个控制环,而是把所有环节——机械、电源、传感器、电机驱动、双核软件架构、工具链配置——严丝合缝地咬合在一起。英飞凌这套从TC264到ADS、从GTM到PMSM驱动解决方案的链条,把这些环节之间的接缝尽量抹平了,但最终能把车跑好的,仍然是那些愿意在每一个细节上较真的人。如果你正准备入场,我的建议很简单:先花一个晚上把ADS工具链装好点灯,再花两个晚上把GTM和ADC触发的同步关系跑通,剩下的,就是你跟赛道之间的漫长拉锯了。