|
|
@@ -241,7 +241,8 @@ void PMSM_FOC_CoreInit(void) {
|
|
|
|
|
|
gFoc_Ctrl.plot_type = Plot_None;
|
|
|
}
|
|
|
-
|
|
|
+//#define UPDATE_Lq_By_iq /* Q轴电感 通过Iq电流补偿 */
|
|
|
+//#define Volvec_Delay_Comp /* 电压矢量角度补偿 */
|
|
|
static __INLINE void PMSM_FOC_Update_Input(void) {
|
|
|
AB_t iAB;
|
|
|
|
|
|
@@ -259,7 +260,8 @@ static __INLINE void PMSM_FOC_Update_Input(void) {
|
|
|
gFoc_Ctrl.in.s_motAngle = gFoc_Ctrl.in.s_hallAngle;
|
|
|
}
|
|
|
gFoc_Ctrl.in.s_motRPM = foc_observer_speed();
|
|
|
-
|
|
|
+ LowPass_Filter(gFoc_Ctrl.in.s_motRPMFilted, gFoc_Ctrl.in.s_motRPM, 0.005f);
|
|
|
+ gFoc_Ctrl.in.s_motVelDegreePers = gFoc_Ctrl.in.s_motRPM / 30.0f * PI * gFoc_Ctrl.params.n_poles;
|
|
|
#ifdef CONFIG_DQ_STEP_RESPONSE
|
|
|
gFoc_Ctrl.in.s_hallAngle = 0;
|
|
|
gFoc_Ctrl.in.s_motAngle = 0;
|
|
|
@@ -275,6 +277,11 @@ static __INLINE void PMSM_FOC_Update_Input(void) {
|
|
|
|
|
|
LowPass_Filter(gFoc_Ctrl.out.s_FilterIdq.d, gFoc_Ctrl.out.s_RealIdq.d, 0.004f);
|
|
|
LowPass_Filter(gFoc_Ctrl.out.s_FilterIdq.q, gFoc_Ctrl.out.s_RealIdq.q, 0.004f);
|
|
|
+#ifdef Volvec_Delay_Comp
|
|
|
+ float next_angle = gFoc_Ctrl.in.s_motAngle + gFoc_Ctrl.in.s_motVelDegreePers / PI * 180.0f * (FOC_CTRL_US - 2e-6f);
|
|
|
+ rand_angle(next_angle);
|
|
|
+ SinCos_Lut(next_angle, &gFoc_Ctrl.out.sin, &gFoc_Ctrl.out.cos);
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_DQ_STEP_RESPONSE
|
|
|
@@ -304,17 +311,16 @@ static u32 PMSM_FOC_Debug_Task(void *p) {
|
|
|
}
|
|
|
return 1;
|
|
|
}
|
|
|
-//#define UPDATE_Lq_By_iq
|
|
|
|
|
|
static __INLINE void id_feedforward(float eW) {
|
|
|
-#ifdef MOTOR_Flux
|
|
|
+#ifdef CONFIG_CURRENT_LOOP_DECOUPE
|
|
|
gFoc_Ctrl.in.s_targetVdq.d += -(gFoc_Ctrl.params.lq * gFoc_Ctrl.out.s_RealIdq.q * eW);
|
|
|
gFoc_Ctrl.in.s_targetVdq.d = fclamp(gFoc_Ctrl.in.s_targetVdq.d, gFoc_Ctrl.pi_id.min, gFoc_Ctrl.pi_id.max);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
static __INLINE void iq_feedforward(float eW) {
|
|
|
-#ifdef MOTOR_Flux
|
|
|
+#ifdef CONFIG_CURRENT_LOOP_DECOUPE
|
|
|
gFoc_Ctrl.in.s_targetVdq.q += (gFoc_Ctrl.params.ld * gFoc_Ctrl.out.s_RealIdq.d + gFoc_Ctrl.params.flux) * eW;
|
|
|
gFoc_Ctrl.in.s_targetVdq.q = fclamp(gFoc_Ctrl.in.s_targetVdq.q, gFoc_Ctrl.pi_iq.min, gFoc_Ctrl.pi_iq.max);
|
|
|
#endif
|
|
|
@@ -325,7 +331,6 @@ void PMSM_FOC_Schedule(void) {
|
|
|
gFoc_Ctrl.ctrl_count++;
|
|
|
|
|
|
PMSM_FOC_Update_Input();
|
|
|
-
|
|
|
if (gFoc_Ctrl.out.n_RunMode != CTRL_MODE_OPEN) {
|
|
|
|
|
|
float max_Vdc = gFoc_Ctrl.in.s_vDC * CONFIG_SVM_MODULATION;
|
|
|
@@ -337,10 +342,9 @@ void PMSM_FOC_Schedule(void) {
|
|
|
#ifndef CONFIG_DQ_STEP_RESPONSE
|
|
|
float target_d = FOC_Get_DqRamp(&gFoc_Ctrl.idq_ctl[0]);
|
|
|
#endif
|
|
|
- float eW = gFoc_Ctrl.in.s_motRPM / 30.0f * PI * gFoc_Ctrl.params.n_poles;
|
|
|
float err = target_d - gFoc_Ctrl.out.s_RealIdq.d;
|
|
|
gFoc_Ctrl.in.s_targetVdq.d = PI_Controller_RunSerial(&gFoc_Ctrl.pi_id, err);
|
|
|
- id_feedforward(eW);
|
|
|
+ id_feedforward(gFoc_Ctrl.in.s_motVelDegreePers);
|
|
|
#ifdef UPDATE_Lq_By_iq
|
|
|
/* update kp&ki from lq for iq PI controller */
|
|
|
float lq = motor_get_lq_from_iq((s16)gFoc_Ctrl.out.s_FilterIdq.q);
|
|
|
@@ -357,7 +361,7 @@ void PMSM_FOC_Schedule(void) {
|
|
|
#endif
|
|
|
err = target_q - gFoc_Ctrl.out.s_RealIdq.q;
|
|
|
gFoc_Ctrl.in.s_targetVdq.q = PI_Controller_RunSerial(&gFoc_Ctrl.pi_iq, err);
|
|
|
- iq_feedforward(eW);
|
|
|
+ iq_feedforward(gFoc_Ctrl.in.s_motVelDegreePers);
|
|
|
}else {
|
|
|
float max_Vdc = gFoc_Ctrl.in.s_vDC * CONFIG_SVM_MODULATION;
|
|
|
float max_vd = max_Vdc * SQRT3_BY_2;
|
|
|
@@ -645,7 +649,6 @@ void PMSM_FOC_Slow_Task(void) {
|
|
|
eRamp_running(&gFoc_Ctrl.rtLim.DCCurrLimRamp);
|
|
|
eRamp_running(&gFoc_Ctrl.rtLim.rpmLimRamp);
|
|
|
eRamp_running(&gFoc_Ctrl.in.cruiseRpmRamp);
|
|
|
-
|
|
|
PMSM_FOC_idqCalc();
|
|
|
}
|
|
|
|