尧图精选

从坐标变换到电流环:FOC电机控制实战指南

🕒 发布时间:2026/10/1 7:20:24 📁 来源:尧图网络
很多人第一次接触FOC都是被那一堆坐标变换公式吓退的。我当时也一样看了三天Clark、Park变换脑子里全是矩阵一上电电机还是纹丝不动。后来才发现真正把FOC跑起来的关键不在于把公式背得多熟而在于搞清楚每一步变换在硬件上到底在干什么电流环为什么非得这样调。今天这篇东西就把我从零开始做FOC这一段攒下来的经验按实际工程里最容易卡壳的点重新捋一遍。不管是准备做PMSM无感FOC控制还是想在STM32上移植FOC代码或者只是好奇步进电机FOC控制原理跟普通直流电机有什么不同这篇都能给你一个相对完整的框架。1. 学FOC之前先搞明白这几件事1.1 FOC到底在控制什么FOC的全称是Field Oriented Control国内一般叫磁场定向控制也有叫矢量控制的。说白了一句话想办法让定子产生的磁场始终和转子磁场保持90度的关系。为啥非得是90度因为电机产生转矩靠的是定子磁场和转子磁场之间的相互作用两个磁场夹角为90度时力的分量最大小于90度或者大于90度都会有一部分磁场分量被浪费掉要么用来拉转子而不是转转子要么干脆把转子往外推表现在宏观上就是电流大、发热大、出力还小。这句话说起来简单难就难在“始终”两个字上。直流电机天然就做到了这一点因为有换向器和碳刷转子转到一个角度电流就自动换到对应的绕组电枢磁场和励磁磁场永远保持正交。所以直流电机的控制模型非常干净调一个电压就能线性地调转速调一个电流就能线性地调转矩。FOC干的事情本质上就是给交流电机或者无刷直流电机装一个看不见的“电子换向器”把原本耦合在一起的三相交流量先拆成两个互相垂直的直流分量再按照直流电机的思路去控制。这就是为什么很多老工程师说FOC学到最后你会发现你还是在做直流电机控制。这个思路能成立还有一个物理前提电机三相绕组在空间上差120度通上三相交流电之后合成的定子磁场是一个旋转的磁场它的幅值方向可以用一个旋转的矢量来描述。这个矢量有大小、有方向跟我们平时说的向量是一回事。控制这个旋转磁场的矢量和转子磁场的相对角度就是FOC的核心任务。1.2 永磁同步电机为什么会“转”再说说控制对象。热词里反复出现PMSMPMSM就是永磁同步电机转子上镶着永磁体。普通的异步电机转子是靠感应电流产生磁场的PMSM不用转子磁场就是永磁体自身提供的。它为什么跟着定子磁场转道理跟两个磁铁互相吸引一样定子磁场在前面转转子永磁体就被磁力拽着跟着跑。这就叫同步定子旋转磁场的转速和转子机械转速严格一致转速等于电频率除以极对数再乘以60。所以PMSM的控制精度本质上取决于对定子电流矢量的控制精度。你让定子磁场转多快转子就得跟着转多快你让定子磁场和转子磁场的夹角保持在90度转矩就是最大的。FOC所有复杂的变换、所有PI调节器折腾来折腾去最终目的就是精确控制这个合成电流矢量的幅值和相位。这里也顺便提一嘴无刷直流电机也就是BLDC。BLDC和PMSM在电机本体上常常长得几乎一样绕组形式也都是三相星型接法。区别在控制方式上传统BLDC用六步换相法每个时刻只有两相通电梯形波电流简单粗爆转矩脉动明显FOC是三相同时通电正弦波电流转矩理论上恒定。同一个电机用六步换相和用FOC控制噪音、发热、低速平顺性完全不是一个级别。这也是为什么这几年连电动自行车、电动工具都在往FOC上靠不是FOC有多玄而是六步换相的天花板太低了。2. 三个坐标变换是FOC的地基2.1 从三相到两相Clark变换三相绕组在空间上差120度三相电流在时间上也差120度三个量耦合在一起没法像直流电机那样单独控制。第一件事就是降维把三个交流量变成两个交流量。这就是Clark变换也叫3s/2s变换。Clark变换的思路非常直观三相坐标系里任意一个电流矢量都可以用两个互相垂直的坐标轴来表示。选一个轴叫做α轴通常跟A相绕组轴线对齐再选一个垂直的轴叫做β轴。A相电流直接投影到α轴上B相和C相电流分别按60度角投影到α、β轴上加起来就行。公式长这样Iα Ia - 0.5 * Ib - 0.5 * Ic Iβ (√3/2) * Ib - (√3/2) * Ic如果做一个等幅值变换前面还有个2/3系数等功率变换则用√(2/3)。实际工程里两种都有用代码里一般会预先算好系数写成常量。这个变换本身不复杂但我见过不少新手在这里犯迷糊既然Ia Ib Ic 0为什么还要保留三相再变换因为在实际采样时我们只采两相电流第三相算出来再有就是三相电流有采样噪声和偏置直接保留三相做运算会有累积误差变换之后反而统一了坐标系后面好做处理。2.2 从静止到旋转Park变换Clark变换之后iα和iβ仍然是随时间变化的交流量幅值不变但是方向在转。还是不方便因为PI调节器处理不了交流量一来稳态误差消不掉二来调节带宽也不够。于是就有了Park变换把静止的αβ坐标系旋转起来旋转速度和转子同步这样再看电流矢量它就静止了。Park变换需要一个角度就是转子当前的电角度θ。有了这个角度把iα、iβ投影到d轴和q轴上。d轴方向跟转子磁极方向对齐q轴跟它垂直。公式是Id Iα * cos(θ) Iβ * sin(θ) Iq -Iα * sin(θ) Iβ * cos(θ)变换完之后Id和Iq就是两个直流量了。Id代表跟转子磁场同方向的分量叫励磁电流分量Iq代表跟转子磁场垂直的分量叫转矩电流分量。对表贴式永磁同步电机来说让Id等于0把Iq控制到目标值就能得到最直接的转矩输出。这就是FOC里常说的id0控制策略。写代码的时候Park变换里的sin和cos一般不用实时去算而是查表或者用Cordic算法加速。STM32F4以上的芯片带FPU直接用库函数算也行但控制频率高的时候要注意算力开销。我之前在一个Cortex-M0的平台上跑10kHz电流环实时三角函数扛不住最后换成查表一劳永逸。2.3 逆变换和SVPWM从电压矢量回到开关波形电流环输出的是Ud、Uq两个直流量要加到三相逆变器上就得先反Park变换回Uα、Uβ再用SVPWM生成六路PWM波去驱动三相桥臂。这最后一步是整个FOC里最容易让人脱发的地方。SVPWM的全称是空间矢量脉宽调制。它的思路不是逐相独立调制而是把三相桥臂的八种开关状态对应成八个基本电压矢量六个非零矢量把平面分成六个扇区两个零矢量在中间。想要合成任意方向、任意大小的电压矢量就用相邻两个基本矢量以及零矢量去“拼”。拼的方法就是算各自作用的时间再用定时器输出对应占空比的PWM。很多人被SVPWM的扇区判断和矢量作用时间计算劝退。其实不用怕工程上有一套固定模板。第一步根据Uα、Uβ判断当前参考电压在哪个扇区第二步算出三个中间变量X、Y、Z第三步根据扇区查表得到两个相邻矢量的作用时间T1、T2第四步判断是否过调制加起来超过PWM周期就按比例缩放。代码写出来一共就几十行但每一步都有坑具体我在第6章展开讲。3. 电流环与速度环FOC的骨架3.1 PID和PI为什么这里不用DFOC的电流环几乎百分之百用PI控制器。比例项负责“现在”误差大了就使劲输出积分项负责“过去”一点一点消掉剩下的稳态误差。那D项呢微分项负责“预测未来”看到误差在快速变窄就提前减小输出。听起来很美好但电流环的采样频率通常20kHz一次控制周期只有50微秒电流信号里全是高频噪声微分项会把噪声放大成剧烈的抖动轻则电流波形毛刺重则整个环路啸叫。所以做电机控制的老工程师常说一句话电流环不要加D加了D就是给自己找麻烦。速度环倒是有部分场合用PD或者PID的那是因为速度反馈信号通常来自编码器或者观测器相对平滑一些微分项可以起到阻尼作用。但也要注意滤波位置差分出来的转速信号噪声很大我一般会先上一阶低通滤波再加速度环。3.2 电流环的参数整定思路电流环的PI参数是FOC里最核心的一组参数调不好后面速度环、位置环全都是空中楼阁。比较科学的办法是频域整定。电流环控制对象是电机的电回路也就是电感和电阻的串联传递函数是一阶惯性环节。把PI调节器的零点设计到和电机电气时间常数对齐也就是让PI的积分时间常数等于L/R这样开环传递函数就变成一个纯粹的积分环节闭环带宽可以用比例增益线性调整。公式上写出来是这样Kp L * 2π * fc Ki Kp * R / L其中fc是期望的电流环带宽单位Hz。一般取开关频率的1/20到1/10比如20kHz开关频率电流环带宽做到1kHz到2kHz就合理了。L和R是电机相电感和相电阻这个可以从电机参数手册上拿到也可以拿LCR表实测。实测更靠谱因为手册上的参数往往是标称值制造偏差能到百分之二三十。我实际调试的时候是这样做的先根据公式算出Kp、Ki然后给一个很小的Iq阶跃指令观察电流响应波形。如果电流有超调就适当减小Kp如果响应太慢就加大Kp。Ki的作用是消稳态误差基本调好Kp再动不然两个参数一起改出了问题你根本不知道是哪个导致的。还有一点要特别注意Kp和Ki增大到一定程度之后电流环会出现高频振荡这个时候不是参数越大越好参数和开关频率是有匹配上限的。3.3 速度环与位置环的叠加电流环稳住之后外面是可以无限嵌套速度环和位置环的。速度环的输出是Iq参考值位置环的输出是速度参考值这也是FOC能做成高精度伺服的原因——环环相套越外层时间常数越大。速度环带宽一般要比电流环低五倍以上否则内外环频率接近会互相干扰系统容易不稳定。位置环带宽再低一些。我见过有人把速度环带宽调到电流环的一半结果整个系统一启动就震荡最后把带宽降下来稳如老狗。这里面的规律是内环必须比外环快越快越稳但也不能太快太快了内环噪声会被外环放大。实际操作里电流环1kHz速度环200Hz位置环50Hz这个比例在大多数工业伺服场合都是能用的。至于位置环如果只是做点简单的速度控制不一定要加。但是如果你的项目是伺服定位那位置环至少加一个P就够了位置环的I加不加都行加多了反而会有位置超调。4. 转子的初始位置检测FOC的启动关键4.1 有编码器方案装了就一了百了如果电机轴上装了增量式编码器FOC启动也不简单。增量式编码器只有相对位置上电的时候并不知道转子在哪个电角度必须想办法找零。常见做法是上电先给一个固定的电压矢量把转子强行拉到某个已知角度然后再把编码器当前位置记为零点。这就是“强制对齐”简单粗暴但是会带来一个问题转子可能会来回摆动一下负载稍微重点还可能拉不动。更好的办法是用带零位信号的编码器上电后低速转一下找Z信号找到就把Z信号位置定义为电角度零点。当然电机不能自由转动的情况下就得走高频注入或者脉冲电压法了。还有绝对值编码器上电直接能读角度省去对齐这一步但成本高不少工程上就见仁见智了。这里想提醒一点增量式编码器的Z信号对应电角度零点但这个零点在不同电机里不一定刚好就是d轴位置可能差一个固定的偏移角。正规的做法是上电对齐之后记录一下Z信号位置算出偏移量存到Flash里以后每次上电直接读偏移不用再对齐。我最早没做这个每次上电都要对齐后来加上了偏移量存储上电直接秒启动体验完全不一样。4.2 无感方案中的初始位置辨识无感FOC最头疼的还不是运行中观测而是启动的那一刻。电机静止时反电动势为零滑模观测器没有输入检测不到转子位置。这时候需要额外的办法把转子角度辨出来。常用的方法有几类。第一类是电感法给d轴方向注入高频电压信号通过检测电流响应来判断转子磁极方向。这类方法在高频信号设计上有一点门槛稍微处理不好就有噪音而且对电机电感饱和特性有依赖。第二类是脉冲电压矢量法。给电机分别施加几个固定方向的电压脉冲持续很短时间然后检测电流的大小转子位置越接近施加电压方向电流变化率就越大。通过比较不同方向上的电流峰值就能估算出转子的大致位置。这个方法实现简单而且是工业上用得很多的一种因为不需要电机有特别参数适应性好。但要注意脉冲法只能判断磁极方向的大致位置不能区分N极和S极因为电流响应只跟角度差有关差180度效果一样。所以需要在判断出来的方向上再施加一个正向磁链脉冲观察电流饱和情况来确定极性。说实话我在工程现场一般是有条件就上编码器没条件才用无感。无感启动那一下要做得好需要花不少精力调初始位置辨识的参数而且每次启动还都存在一定的失败概率。如果你是刚接触FOC不建议一上来就啃无感这块硬骨头先花了把电流环跑稳了再用无感去替换位置反馈。5. 无感FOC与滑模观测器5.1 为什么要做无感FOC省掉编码器对成本、体积、可靠性都是巨大的改善。编码器线束是故障高发区震动、油污、高温都容易让编码器出问题。无感FOC靠的是电机的反电动势来推测转子位置不需要额外传感器这是这几年无感FOC、无感滑膜观测器这些热词被反复提起的根本原因。代价是算法复杂度上去了。特别是零低速段反电动势和转速成正比电机不转或者低速转的时候反电动势太小根本提取不出来。所以无感FOC的低速性能和带载启动能力天然就不如有编码器的方案。这是物理约束不是调参就能完全弥补的。工程上常见的做法是零低速用开环强拖或者高频注入中高速再平滑切换到闭环观测器模式。5.2 滑模观测器的原理滑模观测器英文缩写SMO全称Sliding Mode Observer是无感方案里最普及的一种。它的核心思想非常简单用电机模型的电流方程来估计算电流把估算电流和实测电流的误差作为修正项用一个符号函数sign函数把误差强行“拉”到零。这就是滑模面的由来。估算电流方程里包含反电动势项一旦实际电流和估算电流被滑模面锁定观测器内部的等效反电动势就被“逼”出来再对这个反电动势做反正切运算就能得到转子的电角度。代码实现上非常简洁核心就两步第一步算电流误差第二步通过符号函数和电流方程更新估算电流。有人说滑模观测器难其实难的不是算法本身而是对采样噪声的容忍度。符号函数的开关特性天生会带来高频抖振所以实际代码里几乎都会把符号函数换成饱和函数也就是在误差绝对值小于某个边界时用线性区代替跳变能显著压低抖振。这个边界值我自己是用电流环带宽和噪声幅值来定的太小了抖振压不住太大了观测器就不“滑模”了滞后变大高速时位置误差会很要命。5.3 反电动势估测和切入时机观测器得出的角度不是直接就能用的。首先要路过一个低通滤波器滤掉高频噪声其次低通滤波器会给角度带来相位滞后转速越高滞后越大。所以正式投用到控制环路之前需要做一个角度补偿补偿量和估算转速成正比。补偿系数靠实测做法是低速跑一下中速跑一下对比实际角度和估算角度的差值线性拟合出一条斜率。再说说切入时机。电机从静止开始反电动势太小无感观测器起不来必须先让电机开环强拖到一定转速。这个开环模式通常是用一个斜坡函数把定子电流矢量的频率从0慢慢升上去像开车一样油门给着先让车走起来再松手把方向盘交给闭环。切入转速一般选在额定转速的5%到10%左右太高了如果开环强拖过程中失步闭环切入也没意义。踩过的坑提醒一下开环强拖的时间不能太长电流一直在非最优角度上电机发热比闭环运行快很多。我见过有人为了保险把开环时间设了好几秒最终电机没转到闭环直接烧了绕组。正确做法是开环加快的时间尽量短只要角度观测器输出收敛立刻切换。6. 定时器与PWM波形代码落地的关键6.1 定时器配置与互补PWMFOC代码落到STM32上第一步就是配定时器。三相逆变桥需要六路PWM每相两路互补输出再加死区。STM32的高级定时器TIM1和TIM8就是干这个的自带互补通道和硬件死区发生器比用普通定时器加外部逻辑简单得多。关键参数跟PWM波形直接相关计数模式、频率、死区时间。FOC的PWM一般用中心对齐模式也就是定时器先向上计数再向下计数输出的是对称PWM。为什么非得中心对齐因为SVPWM的矢量作用时间是基于对称PWM计算出来的中心对齐模式下每个PWM周期的脉冲在周期中央对称谐波分量小电流波形更干净。边沿对齐也能跑但效果差一截不建议省这个事。死区时间根据功率管的开关特性来定。IGBT一般留2到3微秒MOSFET可以短一点几百纳秒到1微秒。死区太短上下桥直通炸管就在一瞬间死区太长波形失真、电流谐波变大。一个实测过的经验如果你不确定往大了留先让硬件安全跑起来再用示波器看波形慢慢往小调。6.2 SVPWM在定时器里面的实现软件结构上控制频率和PWM频率是绑定的一般用定时器更新中断来触发电流环计算。电流环计算完拿到目标电压矢量Uα、Uβ算好三相对应比较值直接写入定时器比较寄存器下一个PWM周期自动生效。整个过程必须在一个PWM周期内完成所以控制频率和PWM频率一致20kHz的PWM电流环也是20kHz。这里有一个很多新手特别容易犯的错误SVPWM算出来的比较值是相对于PWM周期中心对称的写入定时器的CCR寄存器时一定要想清楚定时器是向上计数还是向下计数的以及比较值代表的是“高电平时间”还是“翻转时刻”。不同定时器模式里CCR含义有差别。我吃过一次亏程序在STM32F103上跑正常换到F407上定时器配置一样结果占空比完全反了电机直接反转。排查了两天最后发现是F407的定时器计数方向配置位默认值跟F103不一样。6.3 STM32 FOC代码的结构思路移植FOC代码不要想着一次写完就跑通。我强烈建议分模块验证先只测开环SVPWM六路PWM输出波形确认无误三相电压加到电机上确认电机能手动转得动、UVW相序正确再测电流采样确认三相电流的偏置和标定没问题在静止状态下采到的电流噪声在合理范围内然后才做电流环闭环用角度对齐方式驱动电机旋转最后再上速度环或者无感观测器。电流采样是容易被忽略的一环。FOC对电流采样精度要求很高采样电阻的温漂、运放的失调电压、ADC的偏移都会让电流环性能劣化。常见做法是采样电阻加差分运放ADC采样时刻放在PWM下桥臂导通的中点也就是电流最平稳的时刻。这需要用到定时器触发ADC的功能STM32的高级定时器可以直接产生TRGO事件触发ADC注入组采样。如果配置不好采样时刻落在开关噪声上电流波形会很难看怎么调PI都调不好。7. 步进电机的FOC控制和PMSM区别在哪7.1 步进电机磁场特性与FOC适配步进电机本来是用开环脉冲控制的细分驱动只是把电流波形从方波换成阶梯正弦波本质上还是开环。近几年步进电机FOC控制火起来是因为步进电机的结构跟PMSM本来就非常像定子同样三相或两相绕组转子本身也是永磁体或者混合式磁路。做FOC控制相当于把一个开环的运动器件变成了闭环伺服效果立竿见影噪音小了、发热低了、堵转不丢步了、高速扭矩也稳了。但是步进电机和伺服PMSM有几个明显差异。第一是极对数多常见的两相步进电机极对数从25到50都有可能电角度变化是机械角度的几十倍对角度检测的分辨率要求更高。第二是电感大、电阻大电气时间常数长电流环带宽做不高PI参数和普通PMSM差异很大。第三是齿槽转矩和磁阻转矩突出低速时转矩波动大FOC里需要更强的谐波抑制能力。7.2 电流采样和细分控制的差异步进电机FOC的电流采样上有一点必须注意传统步进电机驱动器通常把两相绕组接成H桥相电流就是驱动电流但三相步进电机FOC跟PMSM一样也是三相全桥电流采样仍然采两相算第三相。如果你把原来给两相步进设计的采样电路原封不动拿过来用很可能拿到手的数据就不对因为三相电流有三个自由度第三个电流必须满秩才算得出来。细分控制和FOC的关系也要理清。传统步进电机的“细分”是指把一步电流插值成多个微步本质是位置的细分控制FOC本身不细分步数它直接连续控制电流矢量角度理论上比传统细分更平滑。实际做步进电机FOC时你不需要再单独实现细分数FOC天然就是无限细分。8. 常见问题与排查实录8.1 电机嗡嗡叫但不转动这几乎是新手玩FOC第一个会撞上的问题。电机通电后嗡嗡响不转电流还很大说明电流是通了但产生的磁场方向和转子对不上磁场在“拉”转子但拉的角度不对形成不了连续的旋转力矩。先用最笨的办法排查跑开环SVPWM手动给定一个固定角度电机应该能锁定到一个位置并有阻力然后把角度按斜坡慢慢增加电机应该跟着慢慢转。这一步如果正常说明PWM和相序没问题。接着排查电流采样把电流环断开手动固定一个角度观察采回来的三相电流是不是正常的正弦且相位正确。最后排查的是旋变或编码器角度方向我遇到过最多的情况就是角度方向反了电流环一闭环就正反馈结果就是剧烈的震动或者锁定到错误位置。8.2 电流环发烫严重电流环跑起来电机不热驱动板上的采样电阻和运放热得烫手这说明电流采样回路上有持续的高频振荡或者偏置过大。先看电流波形是不是存在高频分量如果有大概率是PI参数过大、采样时刻不对或者死区设置过小。还有一种隐蔽问题电流采样运放的零点漂移造成了虚假的直流偏置而这个偏置在电流环里被PI积分项当成真实电流去补偿长期累积出一个很大的直流电流。解决这类问题的步骤是断开电流环用固定的占空比输出观察三相电流波形是否对称正常波形应该是幅值稳定、中心点在1.65V附近3.3V ADC中间值。如果中心点偏移就在代码里加上软件校准上电时采样三个通道的零点存为偏移量所有采样值减去这个偏移量之后再进环路。8.3 无感FOC高速切入时失步无感观测器在所有转速段里高速是最容易出问题的。反电动势是高速时观测器的主要输入但同时PWM占空比的非线性、死区效应在高速时会引入额外的电压误差观测器估算出来的反电动势会有偏移。另一个大坑是角度补偿低通滤波器带来的相位滞后随转速线性增大如果不做补偿或者补偿不准电流矢量和转子磁场夹角就不是90度输出转矩下降严重时就会失步。我的排查清单是这样的先看估算转速和实际转速如果有编码器做对比的话在高速时是否一致不一致先调角度补偿再看Iq参考值和实际Iq是否跟踪得上跟踪不上就说明电流环带宽不够最后看角度波形是否平滑如果有毛刺检查观测器里的饱和函数边界参数。还有一个很实用的小技巧无感FOC的高速段和低速段完全可以用两套观测器参数切换时做软切换比用一套参数硬扛省心得多。做FOC跟做其他嵌入式开发不一样的地方在于它是软硬件交织的一个不起眼的模拟量偏置、一段没配好的死区时间都会让算法跑成玄学。我自己踩过最多的坑反而不是坐标变换和PI调参而是ADC采样时序、PWM死区方向这种听起来很低级的东西。所以如果你现在正在调试FOC感到无从下手先把示波器夹到PWM输出上把三相电流波形捞出来看一眼一半的故障原因当场就能判断个大概。高深的说完了最后分享一个实在的小经验FOC不是一次性能调通的先开环、再闭环、先低速、再高速每一步稳了再往下走才能让我少走弯路。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →