-
Notifications
You must be signed in to change notification settings - Fork 150
Open
Description
void FOC_update_current_ctrl_gain(float bw)
{
float bandwidth = bw * M_2PI;
Foc.current_ctrl_p_gain = UsrConfig.motor_phase_inductance * bandwidth;
Foc.current_ctrl_i_gain = UsrConfig.motor_phase_resistance / UsrConfig.motor_phase_inductance;
}
void FOC_current(float Id_set, float Iq_set, float phase, float phase_vel)
{
// Clarke transform
float i_alpha, i_beta;
clarke_transform(Foc.i_a, Foc.i_b, Foc.i_c, &i_alpha, &i_beta);
// Park transform
float i_d, i_q;
park_transform(i_alpha, i_beta, phase, &i_d, &i_q);
// Current PI control
float i_d_err = Id_set - i_d;
float i_q_err = Iq_set - i_q;
float v_d = i_d_err * Foc.current_ctrl_p_gain + Foc.current_ctrl_integral_d;
float v_q = i_q_err * Foc.current_ctrl_p_gain + Foc.current_ctrl_integral_q;
// voltage normalize = 1/(2/3*v_bus)
float v_to_mod = 1.5f / Foc.v_bus_filt;
float mod_vd = v_d * v_to_mod;
float mod_vq = v_q * v_to_mod;
// Vector modulation saturation, lock integrator if saturated
float factor = 0.9f * SQRT3_BY_2 / sqrtf(SQ(mod_vd) + SQ(mod_vq));
if (factor < 1.0f) {
mod_vd *= factor;
mod_vq *= factor;
Foc.current_ctrl_integral_d *= 0.99f;
Foc.current_ctrl_integral_q *= 0.99f;
} else {
Foc.current_ctrl_integral_d += i_d_err * (Foc.current_ctrl_i_gain * CURRENT_MEASURE_PERIOD);
Foc.current_ctrl_integral_q += i_q_err * (Foc.current_ctrl_i_gain * CURRENT_MEASURE_PERIOD);
}
// Inverse park transform
float alpha, beta;
float pwm_phase = phase + phase_vel * CURRENT_MEASURE_PERIOD;
inverse_park(mod_vd, mod_vq, pwm_phase, &alpha, &beta);
// SVM
if (0 == svm(alpha, beta, &Foc.dtc_a, &Foc.dtc_b, &Foc.dtc_c)) {
set_a_duty((uint16_t) (Foc.dtc_a * (float) HALF_PWM_PERIOD_CYCLES));
set_b_duty((uint16_t) (Foc.dtc_b * (float) HALF_PWM_PERIOD_CYCLES));
set_c_duty((uint16_t) (Foc.dtc_c * (float) HALF_PWM_PERIOD_CYCLES));
}
// used for report
Foc.i_q = i_q;
UTILS_LP_FAST(Foc.i_q_filt, Foc.i_q, 0.01f);
Foc.i_d = i_d;
UTILS_LP_FAST(Foc.i_d_filt, Foc.i_d, 0.01f);
Foc.i_bus = (mod_vd * i_d + mod_vq * i_q);
UTILS_LP_FAST(Foc.i_bus_filt, Foc.i_bus, 0.01f);
Foc.power_filt = Foc.v_bus_filt * Foc.i_bus_filt;
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels