本文章更多的是,阅读别人的文章,再加上自己的理解和实践凑起来的

什么是FOC?

FOC(Field-Oriented Control),直译是磁场定向控制,也被称作矢量控制 (VC,Vector Control) ,是目前无刷直流电机(BLDC)和永磁同步电机(PMSM)高效控制的最优方法之一。FOC旨在通过精确地控制磁场大小与方向,使得电机的运动转矩平稳、噪声小、效率高,并且具有高速的动态响应。

简单来说就是,FOC是一种对无刷电机的驱动控制方法,它可以让我们对无刷电机进行 “像素级” 控制,实现很多传统电机控制方法所无法达到的效果。

因为所谓的“矢量控制”其实就是在做 解耦 ,把相互耦合的三相磁链解耦为容易控制的交轴 IqI_qIq​ 和直轴 IdI_dId​ 。整个过程就好比我们在做信号处理的时候,通过FFT把信号变换到频域进行处理之后再IFFT反变换回时域是一个道理。

FOC驱动器和无刷电调的区别

玩过航模的同学可能对无刷电机很熟悉,也应该知道航模中对于无刷电机的驱动使用的是 电子调速器(ESC) 也就是我们常说的电调,那么这个FOC驱动器和普通的电调有什么区别呢?

FOC的优势:

  1. 低转速下控制
    由于控制原理的区别,无刷电调只能控制电机工作在高转速下,低速下无法控制;而FOC控制器则完全没有这个限制,不论在什么转速下都可以实现精确控制。
  2. 电机换向
    同上面的理由,由于电调无法反馈转子位置,因此很难实现电机正反转的换向(当然有感电调可以实现);而FOC驱动器的换向性能极其优秀,最高转速下正反转切换可以非常顺畅;此外FOC还可以以能量回收的形式进行刹车控制。
  3. 力矩控制
    普通电调都只能控制电机转速,而FOC可以进行电流(力矩)、速度、位置三个闭环控制。
  4. 噪音
    FOC驱动器的噪音会比电调小很多,原因是普通电调采用方波驱动,而FOC是正弦波。

电调的优势:

  1. 兼容性
    电调驱动不同的BLDC不需要进行参数整定,而FOC需要。
  2. 算法复杂度
    电调的算法实现更简单,运算量少,很适合需要提高带宽的超高转速电机。
  3. 成本
    电调的成本比FOC低很多。

综上大家应该可以看出来,FOC驱动器在控制性能上是要比电调强大得多的,其优异的性能和 磁场定向控制 的原理是密不可分的。

电机原理概述

基本物理知识准备

左手定则

百度百科

左手定则常用于判断通电导体在磁场中受力方向,由英国电机学工程师弗莱明提出。

导体受力 F(N)F(N)F(N) 为
F=ILB\LARGE F=ILB F=ILB
式中,BBB 为磁通量密度 (Wb/m2)(Wb/m^2)(Wb/m2) ;III 为电流 (A)(A)(A) ;LLL 为处于磁场中的导体的长度 (m)(m)(m) 。

弗莱明右手定则 (又称发电机定则)

  • 如右圖所示,右手三根手指互相垂直,大拇指的方向是 a/x/I\mathbf{a}/\mathbf{x}/\mathbf{I}a/x/I 的方向、食指的方向是 b/y/B\mathbf{b}/\mathbf{y}/\mathbf{B}b/y/B 的方向、中指的方向則為 c/z/F\mathbf{c}/\mathbf{z}/\mathbf{F}c/z/F 的方向。

右手定則可以用來找到力矩的方向。将右手掌张开,将四根手指从参考点朝着作用力的位置 rrr 指去,然后将大拇指伸开垂直于四根手指,再找到这四根手指与作用力 FFF 之间角度最小的夹角,将这四根手指弯扫过这夹角,则力矩矢量的方向是大拇指所指的方向。

  1. 拇指的方向是导体移动方向

  2. 食指的是磁场方向

  3. 中指的则为生成的电流方向

维基百科:中国教科书中的右手定则实为弗莱明右手定则的变体,而将这个定则叫做“右手螺旋定则”。

这个其实就是上面的 “左手定则” ,在国外可能是用“右手”表示。

右手定则

伸开右手,使大拇指跟其余四个手指垂直并且都跟手掌在一个平面内,把右手放入磁场中,让磁感线垂直穿入手心,大拇指指向导体运动方向,则其余四指指向感生电动势的方向。也就是切割磁感线的导体会产生反电动势,实际上通过反电动势定位转子位置也是普通无感电调工作的基础原理之一

右手螺旋定则 (又称安培定则)

百度百科

右手定则可以用于安培定律的两种互补应用方法:

  1. 螺线管载有的电流,会产生磁场。使用右手定则,可以判断磁场方向。将右手握住螺线管,四根手指朝着电流方向指去,然后将大拇指沿着螺线管的中心轴伸直,则磁场的方向即为大拇指所指的方向。

  2. 右手定则也可以用来辨明一条电线四周磁场的方向。对于这用法,右手定则称为“安培右手定则”,或“安培定则”。如右图所示,假若将右手的大拇指朝着电线的电流方向指去,再将其它四根手指握紧电线,则四根手指弯曲的方向为磁场的方向。

有刷、无刷电机

直流有刷电机简介

直流有刷电机通过换向器来改变电流方向,进而改变绕组的受力方向。由于其是机械换向,因此就带来一系列缺点,例如摩擦大,发热大,效率低等缺点

直流无刷电机简介

直流无刷电机通过使用电子器件代替机械换向,解决了直流有刷电机的缺点。为了便于分析我们将直流无刷电机抽象出上图模式,定子由三个线圈组成,转子由一对磁极组成。通过改变ABC三者电流方向来改变定子产生的磁场方向,从而使磁铁转动起来。

FOC控制原理

有感FOC步骤框图:

概括一下,FOC控制的整个过程是这样的:

  1. 对电机三相电流进行采样得到 Ia,Ib,IcI_{a}, I_{b}, I_{c}Ia​,Ib​,Ic​
  2. 将 Ia,Ib,IcI_{a}, I_{b}, I_{c}Ia​,Ib​,Ic​ 经过Clark变换得到 Iα,IβI_{\alpha}, I_{\beta}Iα​,Iβ​
  3. 将 Iα,IβI_{\alpha}, I_{\beta}Iα​,Iβ​ 经过Park变换得到 Iq,IdI_{q}, I_{d}Iq​,Id​
  4. 计算 Iq,IdI_{q}, I_{d}Iq​,Id​ 和其设定值 Iq−ref,Id−refI_{q_{-}} r e f, I_{d_{-}} r e fIq−​​ref,Id−​​ref 的误差
  5. 将上述误差输入两个PID(只用到PI)控制器,得到输出的控制电压 Uq,UdU_q,U_dUq​,Ud​
  6. 将 Uq,UdU_q,U_dUq​,Ud​ 进行反Park变换得到 Uα,UβU_{\alpha}, U_{\beta}Uα​,Uβ​
  7. 用 Uα,UβU_{\alpha}, U_{\beta}Uα​,Uβ​ 合成电压空间矢量,输入SVPWM模块进行调制,输出该时刻三个半桥的状态编码值(前文有提到)
  8. 按照前面输出的编码值控制三相逆变器的 MOS 管开关,驱动电机
  9. 循环上述步骤

变换

Clarke变换

clark变换:将 abc\large abcabc 变换到 静止 的 αβ\large \alpha \betaαβ 坐标系下。

三相对称正弦电流的大小可以这样表示:

{Ia=Imcos⁡(ωt)Ib=Imcos⁡(ωt−2π3)Ic=Imcos⁡(ωt+2π3)(2-1)\large \left\{\begin{matrix} I_a =& I_m \cos( \omega t) \tag{2-1}\\ I_b =& I_m \cos( \omega t - \frac{2\pi}{3}) \\ I_c =& I_m \cos( \omega t + \frac{2\pi}{3}) \\ \end{matrix}\right. ⎩⎨⎧​Ia​=Ib​=Ic​=​Im​cos(ωt)Im​cos(ωt−32π​)Im​cos(ωt+32π​)​(2-1)

其中,Im\large I_mIm​ 标识赋值;ω=2πf\large \omega = 2\pi fω=2πf 标识角速度,三项电流在空间上互差120° 。

三相电流的矢量表达和合成矢量可以这样表达:
{Ia→=Ia⋅e0Ib→=Ib⋅e−j2π3Ic→=Ic⋅ej2π3Is→=Ia→+Ib→+Ic→\large \begin{align} \left\{\begin{matrix} \overrightarrow{I_a} =& I_a \cdot e^0 \\ \overrightarrow{I_b} =& I_b \cdot e^{-j \frac{2\pi}{3}} \\ \overrightarrow{I_c} =& I_c \cdot e^{j \frac{2\pi}{3}} \\ \tag{2-2} \end{matrix}\right. \end{align} \\\\ \large \begin{align} \overrightarrow{I_s} = \overrightarrow{I_a} + \overrightarrow{I_b} + \overrightarrow{I_c} \tag{2-3} \end{align} ⎩⎨⎧​Ia​​=Ib​​=Ic​​=​Ia​⋅e0Ib​⋅e−j32π​Ic​⋅ej32π​​​(2-2)​Is​​=Ia​​+Ib​​+Ic​​​(2-3)​

所以 Is→\large \overrightarrow{I_s}Is​​ 就等于
Is→=Imcos⁡(ωt)+Imcos⁡(ωt−2π3)⋅e−j2π3+Imcos⁡(ωt+2π3)⋅ej2π3(2-4)\large \overrightarrow{I_s} = I_m \cos( \omega t) + I_m \cos( \omega t - \frac{2\pi}{3}) \cdot e^{-j \frac{2\pi}{3}} + I_m \cos( \omega t + \frac{2\pi}{3}) \cdot e^{j \frac{2\pi}{3}} \tag{2-4} Is​​=Im​cos(ωt)+Im​cos(ωt−32π​)⋅e−j32π​+Im​cos(ωt+32π​)⋅ej32π​(2-4)
根据 欧拉公式 ejx=cos⁡x+jsin⁡x\large e^{jx} = \cos x+j\sin xejx=cosx+jsinx ,可以推出:
Is→=Imcos⁡(ωt)+Imcos⁡(ωt−2π3)(cos⁡(2π3)+jsin⁡(2π3))+Imcos⁡(ωt+2π3)(cos⁡(2π3)−jsin⁡(2π3))(2-5)\large \begin{array}{rc} \overrightarrow{I_{s}}=\quad & I_{m} \cos (\omega t)+\\ & I_{m} \cos \left(\omega t-\frac{2 \pi}{3}\right)\left(\cos \left(\frac{2 \pi}{3}\right)+j \sin \left(\frac{2 \pi}{3}\right)\right)+\\ & I_{m} \cos \left(\omega t+\frac{2 \pi}{3}\right)\left(\cos \left(\frac{2 \pi}{3}\right)-j \sin \left(\frac{2 \pi}{3}\right)\right) \tag{2-5} \end{array} Is​​=​Im​cos(ωt)+Im​cos(ωt−32π​)(cos(32π​)+jsin(32π​))+Im​cos(ωt+32π​)(cos(32π​)−jsin(32π​))​(2-5)
进一步化简可得:
Is→=Imcos⁡(ωt)+Im[cos⁡(ωt)cos⁡(2π3)+sin⁡(ωt)sin⁡(2π3)](−12+j32)+Im[cos⁡(ωt)cos⁡(2π3)−sin⁡(ωt)sin⁡(2π3)](−12−j32)(2-6)\large \begin{array}{rc} \overrightarrow{I_{s}}= & I_{m} \cos (\omega t)+ \\ & I_{m}\left[\cos (\omega t) \cos \left(\frac{2 \pi}{3}\right)+\sin (\omega t) \sin \left(\frac{2 \pi}{3}\right)\right]\left(-\frac{1}{2}+j \frac{\sqrt{3}}{2}\right)+ \\ & I_{m}\left[\cos (\omega t) \cos \left(\frac{2 \pi}{3}\right)-\sin (\omega t) \sin \left(\frac{2 \pi}{3}\right)\right]\left(-\frac{1}{2}-j \frac{\sqrt{3}}{2}\right) \tag{2-6} \end{array} Is​​=​Im​cos(ωt)+Im​[cos(ωt)cos(32π​)+sin(ωt)sin(32π​)](−21​+j23​​)+Im​[cos(ωt)cos(32π​)−sin(ωt)sin(32π​)](−21​−j23​​)​(2-6)
代入三角函数值可得:
Is→=Imcos⁡(ωt)+Im[−12cos⁡(ωt)+32sin⁡(ωt)](−12+j32)+Im[−12cos⁡(ωt)−32sin⁡(ωt)](−12−j32)(2-7)\large \begin{array}{rc} \overrightarrow{I_{s}}= & I_{m} \cos (\omega t)+ \\ & I_{m}\left[-\frac{1}{2} \cos (\omega t)+\frac{\sqrt{3}}{2} \sin (\omega t)\right]\left(-\frac{1}{2}+j \frac{\sqrt{3}}{2}\right)+ \\ & I_{m}\left[-\frac{1}{2} \cos (\omega t)-\frac{\sqrt{3}}{2} \sin (\omega t)\right]\left(-\frac{1}{2}-j \frac{\sqrt{3}}{2}\right) \tag{2-7} \end{array} Is​​=​Im​cos(ωt)+Im​[−21​cos(ωt)+23​​sin(ωt)](−21​+j23​​)+Im​[−21​cos(ωt)−23​​sin(ωt)](−21​−j23​​)​(2-7)
最后化简得到:
Is→=32Imcos⁡(ωt)+j32Imsin⁡(ωt)(2-8)\large \overrightarrow{I_s} = \frac{3}{2}I_m\cos(\omega t ) + j\frac{3}{2}I_m \sin(\omega t) \tag{2-8} Is​​=23​Im​cos(ωt)+j23​Im​sin(ωt)(2-8)
既:
Is→=32Ime−jωt(2-9)\large \overrightarrow{I_s} = \frac{3}{2}I_m e^{-j \omega t} \tag{2-9} Is​​=23​Im​e−jωt(2-9)
可以看出,三相对称正弦电流的合成矢量的一个角速度为 ω\large \omegaω ,绕中心点旋转的矢量,因此能形成旋转磁场。它的幅值为单相幅值的 32\large \frac{3}{2}23​ 倍。

进一步,我们将 abcabcabc 变换到 静止 的 α−β\large \alpha - \betaα−β 坐标系下,我们可以得到

{Iα=Ia−Ibcos⁡π3−Iccos⁡π3Iβ=Ibcos⁡π6−Iccos⁡π6(2-10)\large \left\{\begin{array}{rc} I_{\alpha}= & I_{a}-I_{b} \cos \frac{\pi}{3}-I_{c} \cos \frac{\pi}{3} \\ I_{\beta} = & I_{b} \cos \frac{\pi}{6}-I_{c} \cos \frac{\pi}{6} \tag{2-10} \end{array}\right. {Iα​=Iβ​=​Ia​−Ib​cos3π​−Ic​cos3π​Ib​cos6π​−Ic​cos6π​​(2-10)

将上式写为矩阵形式:
[IαIβ]=k[1−12−12032−32][IaIbIc](2-11)\large \begin{bmatrix} I_{\alpha }\\ I_{\beta } \end{bmatrix} =k\begin{bmatrix} 1 &-\frac{1}{2} &-\frac{1}{2} \\ 0&\frac{\sqrt{3}}{2} &-\frac{\sqrt{3}}{2} \end{bmatrix} \begin{bmatrix} I_{a}\\ I_{b}\\ I_{c} \tag{2-11} \end{bmatrix} [Iα​Iβ​​]=k[10​−21​23​​​−21​−23​​​]⎣⎡​Ia​Ib​Ic​​⎦⎤​(2-11)

  • 若 k=23\large k=\sqrt\frac{2}{3}k=32​​ ,变换前后,功率不变。又称为: Concordia变换

  • 若 k=23\large k=\frac{2}{3}k=32​ ,变换前后,幅值不变,(既合成矢量的大小和方向相等)。

⭐️根据基尔霍夫电流定律 Ia+Ib+Ic=0\large I_a + I_b + I_c = 0Ia​+Ib​+Ic​=0 ,然后为了保证幅值不变把 k=23\large k=\frac{2}{3}k=32​ 带入,上述式子继续化简,最后可以得到
{Iα=kIa−12kIb−12kIc=32kIaIβ=32kIb−32kIc=32Ia+3Ib(2-12)\large \left\{\begin{matrix} I_{\alpha } &=& kI_a - \frac{1}{2}kI_b - \frac{1}{2}kI_c &=& \frac{3}{2}kI_a \\ I_{\beta } &=& \frac{\sqrt{3}}{2}kI_b - \frac{\sqrt{3}}{2}kI_c &=& \frac{\sqrt{3}}{2}I_a + \sqrt{3}I_b \tag{2-12} \end{matrix}\right. {Iα​Iβ​​==​kIa​−21​kIb​−21​kIc​23​​kIb​−23​​kIc​​==​23​kIa​23​​Ia​+3​Ib​​(2-12)

把 k=23\large k=\frac{2}{3}k=32​ 带入

{Iα=23Ia−13Ib−13Ic=IaIβ=13Ib−13Ic=13Ia+23Ib(2-13)\large \left\{\begin{matrix} I_{\alpha } &=& \frac{2}{3}I_a - \frac{1}{3}I_b - \frac{1}{3}I_c &=& I_a \\ I_{\beta } &=& \frac{1}{\sqrt{3}}I_b - \frac{1}{\sqrt{3}}I_c &=& \frac{1}{\sqrt{3}}I_a + \frac{2}{\sqrt{3}}I_b \tag{2-13} \end{matrix}\right. {Iα​Iβ​​==​32​Ia​−31​Ib​−31​Ic​3​1​Ib​−3​1​Ic​​==​Ia​3​1​Ia​+3​2​Ib​​(2-13)

上述式子(2-13)可以看到 Iα=Ia\large I_{\alpha } = I_aIα​=Ia​ 也就是 变换 前后 幅值不变

然后我们再来看看 功率不变 情况,也就是 k=23\large k=\sqrt\frac{2}{3}k=32​​ 时:
{Iα=23Ia−16Ib−16IcIβ=12Ib−12Ic(2-14)\large \left\{\begin{matrix} I_{\alpha } &=& \sqrt{\frac{2}{3}}I_a - \frac{1}{\sqrt{6}}I_b - \frac{1}{\sqrt{6}}I_c \\ I_{\beta } &=& \frac{1}{\sqrt{2}}I_b - \frac{1}{\sqrt{2}}I_c \tag{2-14} \end{matrix}\right. ⎩⎨⎧​Iα​Iβ​​==​32​​Ia​−6​1​Ib​−6​1​Ic​2​1​Ib​−2​1​Ic​​(2-14)

假设变换前的功率为 P0=IaUa+IbUb+IcUc\large P_0 = I_aU_a +I_bU_b + I_cU_cP0​=Ia​Ua​+Ib​Ub​+Ic​Uc​ ,变换后的功率为 P1=IαUα+IβUβ\large P_1 = I_{\alpha }U_{\alpha } + I_{\beta }U_{\beta }P1​=Iα​Uα​+Iβ​Uβ​ ,那么有:

P1=IαUα+IβUβ=23IaUa−13IaUb−13IaUc−13IbUa+16IbUb+16IbUc−13IcUa+16IcUb+16IcUc+12IbUb−12IbUc−12IcUb+12IcUc=23IaUa−13IaUb−13IaUc−13IbUa+23IbUb−13IbUc−13IcUa−13IcUb+23IcUc因为 Ua+Ub+Uc=0=(23P0)+(13P0)=P0(2-15)\large \begin{array}{l} P_{1} = \quad I_{\alpha} U_{\alpha}+I_{\beta} U_{\beta}\\ =\quad \frac{2}{3} I_{a} U a-\frac{1}{3} I_{a} U b-\frac{1}{3} I_{a} U c\\ \tag{2-15} -\frac{1}{3} I_{b} U a+\frac{1}{6} I_{b} U b+\frac{1}{6} I_{b} U c\\ -\frac{1}{3} I_{c} U a+\frac{1}{6} I_{c} U b+\frac{1}{6} I_{c} U c\\ +\frac{1}{2} I_{b} U_{b}-\frac{1}{2} I_{b} U_{c}-\frac{1}{2} I_{c} U_{b}+\frac{1}{2} I_{c} U_{c}\\ =\quad \frac{2}{3} I_{a} U a-\frac{1}{3} I_{a} U b-\frac{1}{3} I_{a} U c\\ -\frac{1}{3} I_{b} U a+\frac{2}{3} I_{b} U b-\frac{1}{3} I_{b} U c\\ -\frac{1}{3} I_{c} U a-\frac{1}{3} I_{c} U b+\frac{2}{3} I_{c} U c\\ \text { 因为 } U_{a}+U_{b}+U_{c}=0\\ =\quad\left(\frac{2}{3} P_{0}\right)+\left(\frac{1}{3} P_{0}\right)=P_{0} \end{array} P1​=Iα​Uα​+Iβ​Uβ​=32​Ia​Ua−31​Ia​Ub−31​Ia​Uc−31​Ib​Ua+61​Ib​Ub+61​Ib​Uc−31​Ic​Ua+61​Ic​Ub+61​Ic​Uc+21​Ib​Ub​−21​Ib​Uc​−21​Ic​Ub​+21​Ic​Uc​=32​Ia​Ua−31​Ia​Ub−31​Ia​Uc−31​Ib​Ua+32​Ib​Ub−31​Ib​Uc−31​Ic​Ua−31​Ic​Ub+32​Ic​Uc 因为 Ua​+Ub​+Uc​=0=(32​P0​)+(31​P0​)=P0​​(2-15)

上述式子(2-15)可以看到 P0=P1\large P_0 = P_1P0​=P1​ 也就是 变换 前后 功率不变

或者也可以通过下面这种方式算出 功率不变 情况:

根据式子(2-12), Iα=32kIa\large I_{\alpha } =\frac{3}{2}kI_aIα​=23​kIa​ 。
P0=Um×Im×3P1=32kUm×32kIm×2(2-16)\large \begin{array}{rlc} P_{0} & = U_{m} \times I_{m} \times 3 \\ P_{1} & =\frac{3}{2} k U_{m} \times \frac{3}{2} k I_{m} \times 2 \tag{2-16} \end{array} P0​P1​​=Um​×Im​×3=23​kUm​×23​kIm​×2​(2-16)
当 k=23\large k=\sqrt\frac{2}{3}k=32​​ 时, P0=P1\large P_0 = P_1P0​=P1​ ,也就是功率不变

关于恒功率变换和恒幅值变换可以参考:交流电机Clark变换中的功率不变约束与幅值不变约束_SmartFish.liu的博客-CSDN博客_clark变换的幅值不变和功率不变

Park变换

这一步中我们接着Clark变换将 α−β\large \alpha - \betaα−β 坐标系旋转 θ 度,其中 θ 是转子当前的角度,如下图:

变换公式如下:
{Id=Iαcos⁡(θ)+Iβsin⁡(θ)Iq=−Iαsin⁡(θ)+Iβcos⁡(θ)(3-1)\large \left\{\begin{array}{l} I_{d}=I_{\alpha} \cos (\theta)+I_{\beta} \sin (\theta) \\ \tag{3-1} I_{q}=-I_{\alpha} \sin (\theta)+I_{\beta} \cos (\theta) \end{array}\right. {Id​=Iα​cos(θ)+Iβ​sin(θ)Iq​=−Iα​sin(θ)+Iβ​cos(θ)​(3-1)
⭐️也很简单,就是作用了一个旋转矩阵 ,写成矩阵形式:
[IdIq]=[cos⁡θsin⁡θ−sin⁡θcos⁡θ][IαIβ](3-2)\large \left[\begin{array}{c} I_{d} \\ I_{q} \end{array}\right]=\left[\begin{array}{cc} \tag{3-2} \cos \theta & \sin \theta \\ -\sin \theta & \cos \theta \end{array}\right]\left[\begin{array}{c} I_{\alpha} \\ I_{\beta} \end{array}\right] [Id​Iq​​]=[cosθ−sinθ​sinθcosθ​][Iα​Iβ​​](3-2)
也就是说,这个 d−qd-qd−q 坐标系是始终跟着转子旋转的!

  • ddd 轴方向与转子磁链方向重合,又叫直轴
  • qqq 轴方向与转子磁链方向垂直,又叫交轴

这个操作是可行的,因为我们会通过编码器输入转子的实时旋转角度,所以这个角度始终是一个已知数。经过这一步的变换,我们会发现,一个匀速旋转向量在这个坐标系下变成了一个定值!(显然的嘛,因为参考系相对于该向量静止了),这个坐标系下两个控制变量都被线性化了!

接下来如果我们以 Iq,IdI_q, I_dIq​,Id​ 这两个值作为反馈控制的对象,那么显然就可以使用一些线性控制器来进行控制了,比如PID(是的,尽管学术界有很多炫酷的高级控制方法, 但是工业界还是偏爱PID)。

至此我们已经理解完上面FOC控制过程9个步骤的前3步了。

Clarke Park 变换测试

上位机用的是 “VOFA+”

模拟三相电流(红色、绿色和蓝色)

经过 Clarke变换 的波形(紫色和橙色)

经过 Park 变换 的波形(粉色和黄色)

说明

特别说明一下其中的 Iq,Id,Iq_ref,Id_ref\LARGE I_q,I_d, I_{q\_ref}, I_{d\_ref}Iq​,Id​,Iq_ref​,Id_ref​ ,前两者大家知道是通过Clark变换Park变换得到的,而后两者是我们预期希望前两者达到的值,这个值具体代表了什么物理量呢?参考一下下图:

也就是说我们一通操作将转子磁链进行了解耦,分解为了转子旋转的径向切向这两个方向的变量:

  • 其中 Iq\LARGE I_qIq​ 是我们需要的,代表了期望的力矩输出
  • 而 Id\LARGE I_dId​ 是我们不需要的,一般我们希望尽可能把它控制为0

FOC的控制目标通过PID控制器使用上述输入(电流采样值、编码器位置)和输出(MOS管开关状态)完成对电机电流的闭环控制。

代码

clark

/*-----------------------------------------------------------------------------CLARKE 变换 宏
-----------------------------------------------------------------------------*/
#define CLARKE_DEFAULTS \{ 0, 0, 0, 0, 0 }#define CLARK_ONEbySQRT3 0.57735026918963f /* 1/sqrt(3) */
#define CLARK_ONEbyTHREE 0.33333333333333f /* 1/3 *//* 为1的话是虚假的三电流输入,本质上还是两电流,为0的话是不用电流相加为0这个公式来计算clark */
#define CLARK_3_current 1/*-----------------------------------------------------------------------------CLARKE 变换 结构体
-----------------------------------------------------------------------------*/
typedef struct {fp32 As;     //!< Input: phase-a stator variablefp32 Bs;     //!< Input: phase-b stator variablefp32 Cs;     //!< Input: phase-c stator variablefp32 Alpha;  //!< Output: stationary d-axis stator variablefp32 Beta;   //!< Output: stationary q-axis stator variable
} clarke_t;/*------------------------------------------------------------------------------CLARKE 变换 变量
------------------------------------------------------------------------------*/
static const fp32 _onebysqrt3 = (CLARK_ONEbySQRT3);
static const fp32 _onebythree = (CLARK_ONEbyTHREE);/*------------------------------------------------------------------------------CLARKE 变换 函数实体
------------------------------------------------------------------------------*/
/*** @brief       clarke变换* @param[in]   *v: clarke_t结构体* @param[in]   _A: ABC坐标系下的电流a* @param[in]   _B: ABC坐标系下的电流b* @param[out]  v->Alpha: Alpha Beta坐标系下的电流Alpha*              v->Beta: Alpha Beta坐标系下的电流Beta* @retval      none* @attention   输入两电流*/
static inline void clarke_calc_2(clarke_t* v, fp32 _A, fp32 _B) {v->As = _A;v->Bs = _B;v->Alpha = v->As;v->Beta = (v->As + (v->Bs * 2.0f)) * _onebysqrt3;
}/*** @brief       clarke变换* @param[in]   *v: clarke_t结构体* @param[in]   _A: ABC坐标系下的电流a* @param[in]   _B: ABC坐标系下的电流b* @param[in]   _C: ABC坐标系下的电流c* @param[out]  v->Alpha: Alpha Beta坐标系下的电流Alpha*              v->Beta: Alpha Beta坐标系下的电流Beta* @retval      none* @attention   输入三电流*/
static inline void clarke_calc_3(clarke_t* v, fp32 _A, fp32 _B, fp32 _C) {v->As = _A;v->Bs = _B;v->Cs = _C;#if (CLARK_3_current == 1)v->Alpha = v->As;v->Beta = (v->Bs - v->Cs) * _onebysqrt3;
#elif (CLARK_3_current == 0)v->Alpha = (2 * v->As - v->Bs - v->Cs) * _onebythree;v->Beta = (v->Bs - v->Cs) * _onebysqrt3;
#endif
}

park

/*-----------------------------------------------------------------------------PARK 变换 宏
-----------------------------------------------------------------------------*/
#define PARK_DEFAULTS \{ 0, 0, 0, 0, 0, 0, 0, }/*-----------------------------------------------------------------------------PARK 变换 结构体
-----------------------------------------------------------------------------*/
typedef struct {fp32 Alpha;  //!< Input: stationary d-axis stator variablefp32 Beta;   //!< Input: stationary q-axis stator variablefp32 Angle;  //!< Input: rotating angle (pu)fp32 Ds;     //!< Output: rotating d-axis stator variablefp32 Qs;     //!< Output: rotating q-axis stator variablefp32 Sine;    //!< Input: Sine termfp32 Cosine;  //!< Input: Cosine term
} park_t;/*------------------------------------------------------------------------------PARK 变换 函数实体
------------------------------------------------------------------------------*/
/*** @brief       park变换* @param[in]   *v: park_t结构体* @param[in]   _Alpha: Alpha Beta坐标系下的电流Alpha* @param[in]   _Beta: Alpha Beta坐标系下的电流Beta* @param[out]  v->Ds: dq坐标系下的电流d*              v->Qs: dq坐标系下的电流q* @retval      none*/
static inline void park_calc(park_t* v, fp32 _Alpha, fp32 _Beta, fp32 _Angle) {fp32 cosTh, sinTh;v->Alpha = _Alpha;v->Beta = _Beta;v->Angle = _Angle;sinTh = falst_sin(v->Angle);cosTh = falst_cos(v->Angle);v->Ds = (v->Alpha * cosTh) + (v->Beta * sinTh);v->Qs = (v->Beta * cosTh) - (v->Alpha * sinTh);
}

ipark

/*-----------------------------------------------------------------------------IPARK 变换 宏
-----------------------------------------------------------------------------*/
#define IPARK_DEFAULTS \{ 0, 0, 0, 0, 0, 0, 0, }/*------------------------------------------------------------------------------IPARK 变换 结构体
------------------------------------------------------------------------------*/
typedef struct {fp32 Alpha;  //!< Output: stationary d-axis stator variablefp32 Beta;   //!< Output: stationary q-axis stator variablefp32 Angle;  //!< Input: rotating angle (pu)fp32 Ds;     //!< Input: rotating d-axis stator variablefp32 Qs;     //!< Input: rotating q-axis stator variablefp32 Sine;    //!< Input: Sine termfp32 Cosine;  //!< Input: Cosine term
} ipark_t;/*------------------------------------------------------------------------------IPARK 变换 函数实体
------------------------------------------------------------------------------*/
/*** @brief       ipark变换* @param[in]   *v: ipark_t结构体* @param[in]   _Ds: dq坐标系下的电流d* @param[in]   _Qs: dq坐标系下的电流q* @param[out]  v->Alpha: Alpha Beta坐标系下的电流Alpha*              v->Beta: Alpha Beta坐标系下的电流Beta* @retval      none*/
static inline void ipark_calc(ipark_t* v, fp32 _Ds, fp32 _Qs, fp32 _Angle) {fp32 Cosine, Sine;v->Ds = _Ds;v->Qs = _Qs;v->Angle = _Angle;Sine = falst_sin(v->Angle);Cosine = falst_cos(v->Angle);v->Alpha = (v->Ds * Cosine) - (v->Qs * Sine);v->Beta = (v->Qs * Cosine) + (v->Ds * Sine);
}

参考、引用

  • 【自制FOC驱动器】深入浅出讲解FOC算法与SVPWM技术
  • 手撕系列(2):Clark变换与Park变换
  • Clark变换与Park(派克)变换
  • FOC:在MCU上检验Clark和Park坐标变换是否正确
  • FOC中的Clarke变换和Park变换详解(动图+推导+仿真+附件代码)
  • FOC入门教程 和 嘉立创上的开源的板子(有代码地址)

电机系列(1) - foc最基本原理、clark变换 、park变换、附代码相关推荐

  1. MATLAB坐标系变换动画gif(附代码):坐标系旋转动画+坐标系平移动画代码

    MATLAB坐标系变换动画gif(附代码) 以之前的文章中的例题为例,绘制一个向量和一个运动坐标系在空间中的变换过程,并生成gif动画. 已知坐标系{B}的初始位姿与{A}重合,首先{B}相对于{A} ...

  2. 逆clarke变换_CLARKE 变换PARK 变换

    1918年,Fortescue提出对称分量法,为解决多相(三相)不对称交流系统的分析和计算提供了一个有效方法.对称分量法是用于线性系统的坐标变换法.它将不对称多相系统(后面均以三相系统为代表)以同等待 ...

  3. Clark与Park变换推导

    1.beta轴超前alpha轴90度 2. beta轴滞后alpha轴90度 参考资料:(124条消息) 电机FOC中的坐标变换(CLARK+PARK+公式推导+仿真+C语言实现)_qq_271581 ...

  4. 并网逆变器的clark、park变换的C语言实现技巧

    坐标变换,及c语言实现的讲解多如牛毛. 在此也做点整理,加入一根牛毛.偏重用什么样的C语言语法技巧实现这些变换来做双环控制的. 此处用到了C语言在嵌入式领域非常常用的一个语法:函数指针. 指针是个变量 ...

  5. STM32F103C8T6控制电机驱动模块298N驱动电机调速以及正反转(附代码资源包)

    STM32F103C8T6控制电机驱动模块298N驱动电机调速以及正反转 一. 硬件选型 1. stm32f103c8t6 2. L298N 3. 电机 4. 其他 二. 硬件连接(连接以接一路电机为 ...

  6. Clark变化和Park变换

    利用投影法推导两大变换公式,这里直接给出推导结果: Clark变换 FOC->等幅值变换 Park变换 反Park变换(电压的变换) 反Clark变换

  7. FOC中的Park变换(TI与ST)

    Park变换 Park变换的本质是静止坐标系αβ乘以一个旋转矩阵,从而得到dq坐标系,输入的i_α和i_β经过Park变换得到i_d和i_q(交直变换). 数学公式 跟着转子旋转的"d-q& ...

  8. 手撕永磁同步电机:foc(clark、park、ipark)变换、电机数学模型解耦过程推导

    文章目录 前言 一.建立数学模型的作用? 二.数学模型 1.三相坐标系下数学模型 2.复平面的数学模型(两相坐标) 3.dq轴坐标数学模型(旋转坐标) 4.clark.park推导 总结 前言 此文是 ...

  9. FOC控制中Clark/iClark和Park/iPark变换及matpoltlib仿真

    注:本文部分内容及图片来自网络,如有侵权通知删除! 三相交流电: 三相交流电是由三个频率相同.电势振幅相等.相位差互差120°角的交流电路组成的电力系统.日常用电系统中的三相四线制中电压为380/22 ...

  10. 【嵌入式--伺服电机】无刷电机FOC驱动基本原理与设计

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 一.无刷直流电机FOC原理[重点] 1.无刷直流电机的特点 2.无刷 ...

最新文章

  1. pytorch 卷积网络入门实例
  2. pip3 install face_recognition
  3. 刚毕业的我,参与了一场大厂之间的争夺之战
  4. ubuntu安装samba
  5. python语言的重要性_【一点资讯】这个可能打败Python的编程语言,正在征服科学界 www.yidianzixun.com...
  6. 第十一章项目沟通管理重点--转载
  7. Java GregorianCalendar computeTime()方法与示例
  8. Django(1.7 part1)
  9. 淘宝API介绍-淘宝的 API 开放到什么程度?哪些数据是可以抓取的,哪些不能?
  10. HUSTOJ SPJ 示例
  11. 运兴ETF:期权多空双向,策略多样优势大
  12. 最新 9个免费建站空间 网站均免备案
  13. Kali历史版本下载地址
  14. 定积分及其应用知识点总结_高中定积分知识点总结
  15. python xlrdxlwt应用 以文本形式存储数字 数字前补零
  16. 用python做思维导图软件_分享一下python数据处理工具思维导图
  17. 学渣的刷题之旅 leetcode刷题 20.有效的括号
  18. 树莓派(USB麦克风和麦克风阵列) 录音和播放
  19. sqlserverSMSS登录 18456 错误
  20. qq飞车前瞻版服务器维护,QQ飞车手游前瞻版

热门文章

  1. mac adb环境变量配置
  2. 微信小程序:最新掌上题库微信小程序源码下载,修复登录接口,支持在线考试,自定义导入考题
  3. 本地KMS虚拟服务器,搭建kms本地服务器
  4. CDISC SDTM AE domain学习笔记 - 1
  5. win7无法删除文件夹,提示“找不到该项目”
  6. 深度神经网络的优化算法,深度神经网络算法原理
  7. distpicker动态赋值问题
  8. 移动端车牌识别SDK集成免手工录入
  9. 51单片机之程序下载不进单片机
  10. http post java工具类_java实现Http post(参数json格式)、get 请求的HttpUtil工具类