FOC無感開環啟動排除掉高頻注入這種直接識別當前轉子dq軸的位置直接閉環啟動,大部分的常規啟動方式就是三段式啟動,對齊-強拖-觀測器介入-觀測器誤差穩定后平滑過渡-閉環。
這里就只寫出I/F(V/F)啟動的角度輸出的代碼,力矩就是一條y=kx+b的直線,沒什么好說的。
這里的邏輯是我搭建的Simulink仿真的邏輯
simulink仿真如下圖
相關參數
#define MOTOR_POLE_PAIRS 4 //4對極#define OPEN_LOOP_END_SPEED 300 //RPM
#define OPEN_LOOP_END_TIME 20 //Second
#define OPEN_LOOP_FREQ 0.001f //1kHz#define OPEN_LOOP_CURRENT 0.2f
#define OPEN_LOOP_CURRENT_END 1.1f
#define OPEN_LOOP_VOLTAGE 0.4f
#define OPEN_LOOP_VOLTAGE_END 1.1f#define OPEN_LOOP_TORQUE_DURATION 500 //ms
開環啟動控制頭文件
struct OpenLoopControl
{int8_t CloseLoopFlag; //指示是否可以切入閉環float StartAngle; //初始角度,對齊的角度float OpenLoopAngleAcc; //角加速度float OpenLoopAngleSpeed; //角速度float OpenLoopElecTheta; //電角度uint16_t OpenLoopAccCount; //計數器uint16_t OpenLoopAccTime; //時間float OpenLoopOutAngle; //計算出的開環實際角度float OpenLoopTorqueSlop; //開環力矩斜率float OpenLoopOutTorque; //計算出的實際力矩,V/F是電壓,I/F是電流
};void OpenLoopSlopInit(void);
void OpenLoopCtrl(void);
相關實現
#define PI 3.11415926535f
#define PI_2 (2 * PI)
#define RadGain 2 * PI / 60.0fstatic void OpenLoopTorqueCtrl(void);
static void OpenLoopAngleCtrl(void);struct OpenLoopControl _sOpenLoopHandle;//初始化
void OpenLoopSlopInit(void)
{_sOpenLoopHandle.CloseLoopFlag = 0;_sOpenLoopHandle.OpenLoopOutAngle = 0;_sOpenLoopHandle.OpenLoopOutTorque = OPEN_LOOP_CURRENT;_sOpenLoopHandle.StartAngle = 0;_sOpenLoopHandle.OpenLoopAngleAcc = OPEN_LOOP_END_SPEED * MOTOR_POLE_PAIRS * RadGain / OPEN_LOOP_END_TIME;_sOpenLoopHandle.OpenLoopAccCount = 0;_sOpenLoopHandle.OpenLoopAccTime = (OPEN_LOOP_END_TIME / OPEN_LOOP_FREQ);_sOpenLoopHandle.OpenLoopAngleSpeed = 0.0f;_sOpenLoopHandle.OpenLoopElecTheta = 0.0f;_sOpenLoopHandle.OpenLoopOutAngle = 0.0f;_sOpenLoopHandle.OpenLoopTorqueSlop = (OPEN_LOOP_CURRENT_END - OPEN_LOOP_CURRENT) / OPEN_LOOP_TORQUE_DURATION;
} //開環曲線計算
void OpenLoopCtrl(void)
{OpenLoopTorqueCtrl();OpenLoopAngleCtrl();_sOpenLoopHandle.OpenLoopOutAngle = fmodf(_sOpenLoopHandle.OpenLoopElecTheta ,PI_2);} static void OpenLoopTorqueCtrl(void)
{if(_sOpenLoopHandle.OpenLoopOutTorque < OPEN_LOOP_CURRENT_END){_sOpenLoopHandle.OpenLoopOutTorque += _sOpenLoopHandle.OpenLoopTorqueSlop;}else{_sOpenLoopHandle.OpenLoopOutTorque = OPEN_LOOP_CURRENT_END;}
}static void OpenLoopAngleCtrl(void)
{if(_sOpenLoopHandle.OpenLoopAccCount < _sOpenLoopHandle.OpenLoopAccTime){_sOpenLoopHandle.OpenLoopAngleSpeed += _sOpenLoopHandle.OpenLoopAngleAcc * OPEN_LOOP_FREQ;_sOpenLoopHandle.OpenLoopElecTheta += _sOpenLoopHandle.OpenLoopAngleSpeed * OPEN_LOOP_FREQ;_sOpenLoopHandle.OpenLoopAccCount++;}else{_sOpenLoopHandle.OpenLoopElecTheta += _sOpenLoopHandle.OpenLoopAngleSpeed * OPEN_LOOP_FREQ;}
}
該開環啟動算法是在1ms的周期執行的實測如下