首先,先學習一下理論知識
附加上TI的smo代碼
首先先貼出代碼中的變量,以便大家更快的看懂。
typedef struct { _iq Valpha; // Input: Stationary alfa-axis stator voltage
_iq Ealpha; // Variable: Stationary alfa-axis back EMF
_iq Zalpha; // Output: Stationary alfa-axis sliding control
_iq Gsmopos; // Parameter: Motor dependent control gain
_iq EstIalpha; // Variable: Estimated stationary alfaaxis stator current
_iq Fsmopos; // Parameter: Motor dependent plant matrix
_iq Vbeta; // Input: Stationary beta-axis stator voltage
_iq Ebeta; // Variable: Stationary beta-axis back EMF
_iq Zbeta; // Output: Stationary beta-axis sliding control
_iq EstIbeta; // Variable: Estimated stationary beta-axis statorcurrent
_iq Ialpha; // Input: Stationary alfa-axis stator current
_iq IalphaError; // Variable: Stationary alfaaxis current error
_iq Kslide; // Parameter: Sliding control gain
_iq Ibeta; // Input: Stationary beta-axis stator current
_iq IbetaError; // Variable: Stationary betaaxis current error
_iq Kslf; // Parameter: Sliding control filter gain
_iq Theta; // Output: Compensated rotor angle
void (*calc)(); // Pointer to calculation function
} SMOPOS;
typedef SMOPOS *SMOPOS_handle;
/*-----------------------------------------------------------------------------
Default initalizer for the SMOPOS object.
-----------------------------------------------------------------------------*/
#define SMOPOS_DEFAULTS { 0,0,0,0,0,0,0,0,0,0, \
0,0,0,0,0,0,0, \
(void (*)(Uint32))smopos_calc }
以下是smo的代碼
#include "IQmathLib.h" // Include header for IQmath library
// Don't forget to set a proper GLOBAL_Q in "IQmathLib.h" file
#include "dmctype.h"
#include "smopos.h"
void smopos_calc(SMOPOS *v)
{
_iq E0;
E0 = _IQ(0.5);
// Sliding mode current observer
v->EstIalpha = _IQmpy(v->Fsmopos,v->EstIalpha) + _IQmpy(v->Gsmopos,(v->Valpha - v->Ealpha - v->Zalpha)); //mpy是乘法,就對應上面的公式(3)注意不是完全對應,因爲程序裏開關量是不能直接寫出來的是要用下面的if語句描述出來的,其實這裏我有一個疑問,有些書上這個公式等號前面是微分,而有的卻不是對i的微分,看TI的意思應該不是微分,
v->EstIbeta = _IQmpy(v->Fsmopos,v->EstIbeta) + _IQmpy(v->Gsmopos,(v->Vbeta - v->Ebeta - v->Zbeta));//這個對應公式(4)
// Current errors
v->IalphaError = v->EstIalpha - v->Ialpha; //得出觀察與實際的誤差
v->IbetaError = v->EstIbeta - v->Ibeta; //同上
// Sliding control calculator
if (_IQabs(v->IalphaError) < E0) //如果小於開關設定值就將滑模增益乘以誤差與設定值的比
v->Zalpha = _IQmpy(v->Kslide,_IQdiv(v->IalphaError,E0));
else if (v->IalphaError >= E0) //如果大於開關設定值則將滑模增益賦給z
v->Zalpha = v->Kslide;
else if (v->IalphaError <= -E0)
v->Zalpha = -v->Kslide;
if (_IQabs(v->IbetaError) < E0)
v->Zbeta = _IQmpy(v->Kslide,_IQdiv(v->IbetaError,E0));
else if (v->IbetaError >= E0)
v->Zbeta = v->Kslide;
else if (v->IbetaError <= -E0)
v->Zbeta = -v->Kslide;
// Sliding control filter -> back EMF calculator
v->Ealpha = v->Ealpha + _IQmpy(v->Kslf,(v->Zalpha-v->Ealpha)); //v->Kslf濾波器增益
v->Ebeta = v->Ebeta + _IQmpy(v->Kslf,(v->Zbeta-v->Ebeta));
// Rotor angle calculator -> Theta = atan(-Ealpha,Ebeta)
v->Theta = _IQatan2PU(-v->Ealpha,v->Ebeta); //得出α與β軸的估算反電勢就可以估算出角度了。
}
從代碼中我們可以很直觀的看出smo是怎麼寫出來的,ps:_iq是一個iq math集裏的指令,是用來自己設定一個變量它的小數位和整數位各是多少爲(即移動小數點位置)比如這個數是16位的數,我們可以選擇讓它有9位是整數位,7位是小數位,這種方式能夠很大的提高運算速度。
問題:在在上述程序中使用反正切函數時,IQmath庫中的輸出範圍爲0-1,對應實際應該是0-2π,但實際上正切週期是π,也就是說也就是對於同一個反正切值而言如果不進行象限判斷,都可以在0-π中找到對應的值也就是說IQmath庫中反正切函數的實際輸出範圍是0-0.5
標幺值 英文爲 per unit 簡寫爲 pu 一些科學軟件中通常寫作 p.u. 中文有時也寫作 標麼值 其中的 麼 的讀音是yāo 不是me也不是mó
標幺值是相對於某一基準值而言的 同一有名值 當基準值選取不同時 其標幺值也不同 它們的關係如下 標幺值= 有名值/ 基準值
比如在短路電流計算中 選定一個基準容量(Sjz)和基準電壓(Ujz) 將短路計算中各個參數都轉化爲和該參數的基準量的比值(相對於基準量的比值) 稱爲標幺值 標幺值 =實際值 / 基準值
各物理量基準值的選擇必須和其實際值具有相同的量綱 常用下標註B表示基準值 下標註*表示標幺值
假設功率的實際值爲 基準值爲 則其標幺值爲S*=S/SB.
好處:
1 三相電路的計算公式與單相電路的計算公式完全相同 線電壓的標幺值與相電壓的標幺值相等 三相功率的標幺值和單相功率的標幺值相等
2 只需確定各電壓等級的基準值 而後直接在各自的基準值下計算標幺值 不需要進行參數和計算結果的折算
3) 對於低壓系統 功率的標幺值遠小於1
4 用標幺值後 電力系統的元件參數比較接近 易於進行計算和對結果的分析比較
5 可以省去公式中的比例係數 使計算簡化