天天看點

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

0 前言

今天獲知了,電機FOC包含了SVPWM、坐标轉換、信号采集回報、PID閉環控制等,這個控制政策,統稱為FOC控制。一般SVPWM算法的實作是在靜止的αβ坐标系上實作。而PID控制器由于是對直流參考信号的跟蹤效果較好,是以三相交流電會經過坐标變換,在旋轉的dq坐标軸上,可以用直流量描述電樞繞組的合成矢量。

FOC控制中,有兩種坐标轉換需要注意的,分别是clark變換,和park變換。clark變換将abc坐标系轉換為αβ坐标系,而park變換将靜止的αβ坐标系轉換為旋轉的dq坐标系。

1 clark變換

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

其實直接可以把轉換公式列出。

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

寫成轉換矩陣,就是:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

clark變換的逆變換:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

寫成轉換矩陣,就是:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

将兩個轉換矩陣相乘,應該是一個機關矩陣,系數K的作用是可以将轉換變為等幅值轉換或者等功率轉換。

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

,是等幅值轉換;當

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

,是等功率轉換。

1.1 matlab仿真

在matlab/simulink中搭建仿真模型:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

abcToAlphabeta中的代碼:

function y = fcn(a,b,c)
%#eml


alpha = a - b/2 - c/2;
beta = sqrt(3)/2 * (b - c);
y = (2/3)*[alpha;beta];
           

alphabetaToABC中的代碼:

function y = fcn(alpha,beta)
%#eml

a = alpha;
b = -1/2 * alpha + sqrt(3)/2 * beta;
c = -1/2 * alpha - sqrt(3)/2 * beta;

y = [a;b;c];
           

仿真波形:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

我在這裡使用的是等幅值變換。因為這裡調制系數為1,各個正弦波的幅值都是1。假如使用等功率變換,alphabeta坐标系上的幅值會超過1,此時若直接經過SVPWM算法,會變成過調制。

2 park變換

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

通過幾何變換,可以直接得到

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

圖中

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

就是d軸和α軸之間的夾角。我們也可以用q軸和α軸之間的夾角進行轉換,但是會影響矩陣的參數。故還是采用d軸和α軸之間的夾角。因為我參考了wikipedia的alphabeta transformation和TI的controlSuite裡面的資料,都是使用這個夾角去推轉換矩陣的。是以不轉牛角尖了。

寫成矩陣的形式:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

那麼逆變換就是:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結
電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

2.1 仿真

搭建仿真模型:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

alphabetaToDQ代碼:

function y = fcn(alpha,beta, c)
%#eml
d = cos(c)* alpha + sin(c)*beta;
q = -sin(c)* alpha + cos(c)*beta;

y=[d;q];
           

DQToAlphabeta代碼:

function y = fcn(d,q, c)
%#eml
alpha = cos(c) * d - sin(c)*q;
beta =  sin(c) * d + cos(c)*q;

y=[alpha;beta];
           

波形:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

此時注意到:

現在三相abc的波形函數是:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

假如需要反轉,那麼把輸入改為:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

同時把仿真模型中的constant改為 -2*pi*10

可以得到:

電機FOC中的坐标變換(CLARK+PARK+公式推導+仿真+C語言實作)0 前言1 clark變換2 park變換3 C語言小結

3 C語言

以下代碼來自TI的controlSUITE。在此特别鳴謝TI。

3.1 clarke.h

/* =================================================================================
File name:       CLARKE.H  
===================================================================================*/


#ifndef __CLARKE_H__
#define __CLARKE_H__

typedef struct {  _iq  As;  		// Input: phase-a stator variable
				  _iq  Bs;			// Input: phase-b stator variable
				  _iq  Cs;			// Input: phase-c stator variable  
				  _iq  Alpha;		// Output: stationary d-axis stator variable 
				  _iq  Beta;		// Output: stationary q-axis stator variable
		 	 	} CLARKE;	            

/*-----------------------------------------------------------------------------
	Default initalizer for the CLARKE object.
-----------------------------------------------------------------------------*/                     
#define CLARKE_DEFAULTS { 0, \
                          0, \
                          0, \
                          0, \
                          0, \
              			} 

/*------------------------------------------------------------------------------
	CLARKE Transformation Macro Definition
------------------------------------------------------------------------------*/

//  1/sqrt(3) = 0.57735026918963
#define  ONEbySQRT3   0.57735026918963    /* 1/sqrt(3) */
	

// Clarke transform macro (with 2 currents)
//==========================================
#define CLARKE_MACRO(v)										\
v.Alpha = v.As;												\
v.Beta = _IQmpy((v.As +_IQmpy2(v.Bs)),_IQ(ONEbySQRT3));


// Clarke transform macro (with 3 currents)
//==========================================
#define CLARKE1_MACRO(v)									\
v.Alpha = v.As;											    \
v.Beta  = _IQmpy((v.Bs - v.Cs),_IQ(ONEbySQRT3));

#endif // __CLARKE_H__

           

3.2 park.h

/* =================================================================================
File name:       PARK.H 
===================================================================================*/

#ifndef __PARK_H__
#define __PARK_H__

typedef struct {  _iq  Alpha;  		// Input: stationary d-axis stator variable 
				  _iq  Beta;	 	// Input: stationary q-axis stator variable 
				  _iq  Angle;		// Input: rotating angle (pu) 
				  _iq  Ds;			// Output: rotating d-axis stator variable 
				  _iq  Qs;			// Output: rotating q-axis stator variable
				  _iq  Sine;
				  _iq  Cosine; 	 
		 	 	} PARK;	            

/*-----------------------------------------------------------------------------
Default initalizer for the PARK object.
-----------------------------------------------------------------------------*/                     
#define PARK_DEFAULTS {   0, \
                          0, \
                          0, \
                          0, \
                          0, \
						  0, \
                          0, \
              			  }

/*------------------------------------------------------------------------------
	PARK Transformation Macro Definition
------------------------------------------------------------------------------*/


#define PARK_MACRO(v)											\
																\
	v.Ds = _IQmpy(v.Alpha,v.Cosine) + _IQmpy(v.Beta,v.Sine);	\
    v.Qs = _IQmpy(v.Beta,v.Cosine) - _IQmpy(v.Alpha,v.Sine);

#endif // __PARK_H__
           

3.3 ipark.h

/* =================================================================================
File name:       IPARK.H   
===================================================================================*/

#ifndef __IPARK_H__
#define __IPARK_H__

typedef struct {  _iq  Alpha;  		// Output: stationary d-axis stator variable
				  _iq  Beta;		// Output: stationary q-axis stator variable
				  _iq  Angle;		// Input: rotating angle (pu)
				  _iq  Ds;			// Input: rotating d-axis stator variable
				  _iq  Qs;			// Input: rotating q-axis stator variable
				  _iq  Sine;		// Input: Sine term
				  _iq  Cosine;		// Input: Cosine term
		 	    } IPARK;	            

/*-----------------------------------------------------------------------------
Default initalizer for the IPARK object.
-----------------------------------------------------------------------------*/                     
#define IPARK_DEFAULTS {  0, \
                          0, \
                          0, \
                          0, \
                          0, \
						  0, \
                          0, \
              		   }

/*------------------------------------------------------------------------------
	Inverse PARK Transformation Macro Definition
------------------------------------------------------------------------------*/


#define IPARK_MACRO(v)										\
															\
v.Alpha = _IQmpy(v.Ds,v.Cosine) - _IQmpy(v.Qs,v.Sine);		\
v.Beta  = _IQmpy(v.Qs,v.Cosine) + _IQmpy(v.Ds,v.Sine);

#endif // __IPARK_H__

           

小結

坐标變換在FOC中也是重要的部分。本文介紹了clark變換和park變換。這兩種變換其實在網上資料十分豐富了。但在這裡還是寫了一遍。一方面是貢獻自己的能力,另一方面是滿足自己的收藏癖。假如需要重新程式設計,那麼我還是會重新找出資料。但是目前TI的資料也很豐富,我往下在實物上實作FOC的話,估計會從現有的代碼上修改。

現在幹活都做LED了,看維基上面的clarke變換,讓我想起了以前的日子。以前沒搞懂的坐标公式和PID公式,多推幾遍,現在也越來越熟悉了。

參考資料1:https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_transformation

參考資料2:http://www.ti.com/controlsuite

繼續閱讀