电机FOC中的坐标变换(CLARK+PARK+公式推导+仿真+C语言实现)
一般SVPWM算法的实现是在静止的αβ坐标系上实现。而PID控制器由于是对直流参考信号的跟踪效果较好,因此三相交流电会经过坐标变换,在旋转的DQ坐标轴上,可以用直流量描述电枢绕组的合成矢量。
FOC控制中,有两种坐标转换需要的,分别是克拉克注意变换,和公园变换。克拉克变换将abc坐标系转换为αβ坐标系,而公园变换将静止的αβ坐标系转换为旋转的dq坐标系。
1克拉克变换实际上
可以直接把转换转换公式。
写成转换矩阵,就是:
克拉克变换的逆变换:
写成转换矩阵,就是:
将两个转换矩阵相乘,应该是一个单位矩阵,系数的作用是可以将转换成等幅值转换或者等功率转换。
当
,是等幅值转换;当
,是等功率转换。
1.1 MATLAB仿真
在Matlab / Simulink中搭建仿真模型:
abcToAlphabeta中的代码:
函数y = FCN(A,b,C)%# eml
alpha = a - b/2 - c/2;
beta = sqrt(3)/2 * (b - c);
y = (2/3)*[α;β];
字母aToABC中的代码:
函数 y = fcn(alpha,beta)%#emla = alpha;
b = -1/2 * alpha + sqrt(3)/2 * beta;
c = -1/2 * alpha - sqrt(3)/2 * beta;
y = [ab;c];
仿真一个:
我在这里介绍的是幅值变换。因为这里使用解释等为1个值,各个正弦波的幅值1。假设使用等功率变换,alpha beta坐标系。上的幅值会超过1,此时若直接经过SVPWM算法,会变成过调制。
2公园变换
通过几何变换,直接可以得到
图产品中
就是d轴和α轴之间的夹角。我们也可以用q轴和α轴之间的夹角进行转换,但会影响矩阵的参数。故还是采用d轴和α轴之间的夹角。因为我参考了维基百科的alphabeta转换和TI的controlSuite里面的资料,都是使用这个夹角去推转换矩阵的因此不转牛角尖了。
写成矩阵的形式:
那么逆变换就是:
2.1仿真
搭建仿真模型:
alphabetaToDQ代码:
函数y = FCN(α,β,C)%# emld = cos(c)* alpha + sin(c)*beta;q = -sin(c)* alpha + cos(c)*beta;y=[d;q];
DQToAlphabeta代码:
函数 y = fcn(d,q, c)%#emlalpha = cos(c) * d - sin(c)*q;beta = sin(c) * d + cos(c)*q;y=[alpha; β-;
波形:
此时注意到:
现在三相ABC的波形函数是:
假如需要反转,那么把输入改为:
同时把仿真模型中的常数改为-2 * PI * 10
可以得到:
图3C语言
以下代码来自TI的controlSUITE。在此特别鸣谢TI。
3.1 clarke.h
/* ============================== ================================================== =文件名:CLARKE.H ============================================ ======================================*/#ifndef CLARKE_H
#define CLARKE_H
typedef struct { _iq 作为; //输入:a相定子变量
_iq Bs; // 输入:b 相定子变量
_iq Cs; // 输入:c相定子变量
_iq 阿尔法; //输出:静止d轴定子变量
_iq Beta;// 输出:静止 q 轴定子变量
} CLARKE;
/ ------------------------------------------------- ---------------------------
CLARKE 对象的默认初始化程序。
-------------------------------------------------- --------------------------- /
#define CLARKE_DEFAULTS { 0,
0,
0,
0,
0,
}
/ ------ -------------------------------------------------- ----------------------
CLARKE 变换宏定义
------------------------ -------------------------------------------------- ---- /
// 1/sqrt(3) = 0.57735026918963
#define ONEbySQRT3 0.57735026918963 /* 1/sqrt(3) */
// 克拉克变换宏(2 个电流)
//============== ============================
#define CLARKE_MACRO(v)
v.Alpha = v.As ;
v.Beta = _IQmpy(( v.As +_IQmpy2( v.Bs )),_IQ(ONEbySQRT3));
// 克拉克变换宏(3 个电流)
//====================================== ====
#define CLARKE1_MACRO(v)
v.Alpha = v.As ;
v.Beta = _IQmpy(( v.Bs - v.Cs),_IQ(ONEbySQRT3));
#endif // CLARKE_H
3.2 park.h
/* ================================================ ================================文件名:PARK.H ============ ================================================== ======================*/#ifndef PARK_H
#define PARK_H
typedef struct { _iq Alpha; // 输入:静止d轴定子变量
_iq Beta;// 输入:静止q轴定子变量
_iq角度;// 输入:旋转角度 (pu)
_iq Ds; // 输出:旋转d轴定子变量
_iq Qs; // 输出:旋转q轴定子变量
_iq Sine;
_iq 余弦;
} 公园;
/ ------------------------------------------------- ----------------------------
PARK 对象的默认初始化程序。
-------------------------------------------------- --------------------------- /
#define PARK_DEFAULTS { 0,
0,
0,
0,
0,
0,
0,
}
/ -- -------------------------------------------------- --------------------------
PARK 变换宏定义
-------------------- -------------------------------------------------- -------- /
#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
/* ================================================ ==================================文件名:IPARK.H ============ ================================================== ======================*/#ifndef IPARK_H
#define IPARK_H
typedef struct { _iq Alpha; //输出:静止d轴定子变量
_iq Beta;//输出:静止q轴定子变量
_iq角度;// 输入:旋转角度 (pu)
_iq Ds; // 输入:旋转d轴定子变量
_iq Qs; // 输入:旋转q轴定子变量
_iq Sine; // 输入:正弦项
_iq Cosine; // 输入:余弦项
} IPARK;
/ ------------------------------------------------- -----------------------------
IPARK 对象的默认初始化程序。
-------------------------------------------------- --------------------------- /
#define IPARK_DEFAULTS { 0,
0,
0,
0,
0,
0,
0,
}
/ -- -------------------------------------------------- --------------------------
逆PARK变换宏定义
------------------- -------------------------------------------------- --------- /
#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中也是重要的一部分。本文介绍了克拉克变换和公园变换。这两种变换实际上在网上资料十分丰富。但这里还是写了一遍。一方面是自己的能力,一方面是自己的能力是满足自己的收藏癖好。如果需要重新编程,那么我还是会清除现有的资料,现在的资料很丰富,我往下在代码上修改实现FOC的话,估计会从现有的。
现在干活都LED了,看维基上面的克拉克变换,让我知道了以前的日子。以前没搞懂的坐标公式和PID公式,多推几遍,也学习了解了。
电机FOC中的坐标变换(CLARK+PARK+公式推导+仿真+C语言实现)
一般SVPWM算法的实现是在静止的αβ坐标系上实现。而PID控制器由于是对直流参考信号的跟踪效果较好,因此三相交流电会经过坐标变换,在旋转的DQ坐标轴上,可以用直流量描述电枢绕组的合成矢量。
FOC控制中,有两种坐标转换需要的,分别是克拉克注意变换,和公园变换。克拉克变换将abc坐标系转换为αβ坐标系,而公园变换将静止的αβ坐标系转换为旋转的dq坐标系。
1克拉克变换实际上
可以直接把转换转换公式。
写成转换矩阵,就是:
克拉克变换的逆变换:
写成转换矩阵,就是:
将两个转换矩阵相乘,应该是一个单位矩阵,系数的作用是可以将转换成等幅值转换或者等功率转换。
当
,是等幅值转换;当
,是等功率转换。
1.1 MATLAB仿真
在Matlab / Simulink中搭建仿真模型:
abcToAlphabeta中的代码:
函数y = FCN(A,b,C)%# eml
alpha = a - b/2 - c/2;
beta = sqrt(3)/2 * (b - c);
y = (2/3)*[α;β];
字母aToABC中的代码:
函数 y = fcn(alpha,beta)%#emla = alpha;
b = -1/2 * alpha + sqrt(3)/2 * beta;
c = -1/2 * alpha - sqrt(3)/2 * beta;
y = [ab;c];
仿真一个:
我在这里介绍的是幅值变换。因为这里使用解释等为1个值,各个正弦波的幅值1。假设使用等功率变换,alpha beta坐标系。上的幅值会超过1,此时若直接经过SVPWM算法,会变成过调制。
2公园变换
通过几何变换,直接可以得到
图产品中
就是d轴和α轴之间的夹角。我们也可以用q轴和α轴之间的夹角进行转换,但会影响矩阵的参数。故还是采用d轴和α轴之间的夹角。因为我参考了维基百科的alphabeta转换和TI的controlSuite里面的资料,都是使用这个夹角去推转换矩阵的因此不转牛角尖了。
写成矩阵的形式:
那么逆变换就是:
2.1仿真
搭建仿真模型:
alphabetaToDQ代码:
函数y = FCN(α,β,C)%# emld = cos(c)* alpha + sin(c)*beta;q = -sin(c)* alpha + cos(c)*beta;y=[d;q];
DQToAlphabeta代码:
函数 y = fcn(d,q, c)%#emlalpha = cos(c) * d - sin(c)*q;beta = sin(c) * d + cos(c)*q;y=[alpha; β-;
波形:
此时注意到:
现在三相ABC的波形函数是:
假如需要反转,那么把输入改为:
同时把仿真模型中的常数改为-2 * PI * 10
可以得到:
图3C语言
以下代码来自TI的controlSUITE。在此特别鸣谢TI。
3.1 clarke.h
/* ============================== ================================================== =文件名:CLARKE.H ============================================ ======================================*/#ifndef CLARKE_H
#define CLARKE_H
typedef struct { _iq 作为; //输入:a相定子变量
_iq Bs; // 输入:b 相定子变量
_iq Cs; // 输入:c相定子变量
_iq 阿尔法; //输出:静止d轴定子变量
_iq Beta;// 输出:静止 q 轴定子变量
} CLARKE;
/ ------------------------------------------------- ---------------------------
CLARKE 对象的默认初始化程序。
-------------------------------------------------- --------------------------- /
#define CLARKE_DEFAULTS { 0,
0,
0,
0,
0,
}
/ ------ -------------------------------------------------- ----------------------
CLARKE 变换宏定义
------------------------ -------------------------------------------------- ---- /
// 1/sqrt(3) = 0.57735026918963
#define ONEbySQRT3 0.57735026918963 /* 1/sqrt(3) */
// 克拉克变换宏(2 个电流)
//============== ============================
#define CLARKE_MACRO(v)
v.Alpha = v.As ;
v.Beta = _IQmpy(( v.As +_IQmpy2( v.Bs )),_IQ(ONEbySQRT3));
// 克拉克变换宏(3 个电流)
//====================================== ====
#define CLARKE1_MACRO(v)
v.Alpha = v.As ;
v.Beta = _IQmpy(( v.Bs - v.Cs),_IQ(ONEbySQRT3));
#endif // CLARKE_H
3.2 park.h
/* ================================================ ================================文件名:PARK.H ============ ================================================== ======================*/#ifndef PARK_H
#define PARK_H
typedef struct { _iq Alpha; // 输入:静止d轴定子变量
_iq Beta;// 输入:静止q轴定子变量
_iq角度;// 输入:旋转角度 (pu)
_iq Ds; // 输出:旋转d轴定子变量
_iq Qs; // 输出:旋转q轴定子变量
_iq Sine;
_iq 余弦;
} 公园;
/ ------------------------------------------------- ----------------------------
PARK 对象的默认初始化程序。
-------------------------------------------------- --------------------------- /
#define PARK_DEFAULTS { 0,
0,
0,
0,
0,
0,
0,
}
/ -- -------------------------------------------------- --------------------------
PARK 变换宏定义
-------------------- -------------------------------------------------- -------- /
#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
/* ================================================ ==================================文件名:IPARK.H ============ ================================================== ======================*/#ifndef IPARK_H
#define IPARK_H
typedef struct { _iq Alpha; //输出:静止d轴定子变量
_iq Beta;//输出:静止q轴定子变量
_iq角度;// 输入:旋转角度 (pu)
_iq Ds; // 输入:旋转d轴定子变量
_iq Qs; // 输入:旋转q轴定子变量
_iq Sine; // 输入:正弦项
_iq Cosine; // 输入:余弦项
} IPARK;
/ ------------------------------------------------- -----------------------------
IPARK 对象的默认初始化程序。
-------------------------------------------------- --------------------------- /
#define IPARK_DEFAULTS { 0,
0,
0,
0,
0,
0,
0,
}
/ -- -------------------------------------------------- --------------------------
逆PARK变换宏定义
------------------- -------------------------------------------------- --------- /
#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中也是重要的一部分。本文介绍了克拉克变换和公园变换。这两种变换实际上在网上资料十分丰富。但这里还是写了一遍。一方面是自己的能力,一方面是自己的能力是满足自己的收藏癖好。如果需要重新编程,那么我还是会清除现有的资料,现在的资料很丰富,我往下在代码上修改实现FOC的话,估计会从现有的。
现在干活都LED了,看维基上面的克拉克变换,让我知道了以前的日子。以前没搞懂的坐标公式和PID公式,多推几遍,也学习了解了。
举报