/* * Файл: estimate.c * Модуль идентификации параметров асинхронного двигателя */ #include "estimate.h" #include "def.h" #include #include #ifndef M_PI #define M_PI 3.14159265358979323846f #endif /* * Настройки эксперимента по определению активного сопротивления статора Rs * Метод: разностный метод с двумя уровнями постоянного тока */ float RS_IREF1 = 0.1f; /* первый уровень тока, А */ float RS_IREF2 = 0.2f; /* второй уровень тока, А */ float RS_SETTLE_TIME = 0.5f; /* время установления тока, с */ float RS_THRESHOLD = 0.98f; /* относительный порог достижения тока */ /* * Настройки эксперимента по определению сопротивления ротора Rr * и индуктивностей рассеяния Llr, Lls * Метод: подача переменного тока по оси q, RMS измерения */ float RRL_IQ_AMP = 0.2f; /* амплитуда тока, А */ float RRL_RAMP_TIME = 2.0f; /* время нарастания амплитуды, с */ float RRL_FREQ = 1.0f; /* частота тестового сигнала, Гц (дефолт) */ int RRL_SAMPLES = 200; /* количество выборок для RMS */ int RRL_AVG = 10; /* количество усреднений на частоте */ /* Частоты для многоточечной идентификации (Гц) */ #define RRL_FREQ_COUNT 5 static const float RRL_FREQS[RRL_FREQ_COUNT] = { 1.0f, 2.0f, 3.0f, 5.0f, 10.0f }; /* * Настройки эксперимента по определению взаимной индуктивности Lm * Метод: подача постоянного тока по оси d, интегрирование ЭДС на фронте */ float LM_IDREF = 0.3f; /* заданный постоянный ток, о.е. */ float LM_SETTLE_THRESHOLD = 0.95f; /* порог окончания переходного процесса */ float LM_SETTLE_TIME = 0.5f; /* выдержка для усреднения Id, с */ float LM_DEMAG_TIME = 0.3f; /* размагничивание между циклами, с */ int LM_AVG = 5; /* количество измерений для усреднения */ /* * Настройки переключения между экспериментами */ float STEP_PAUSE_TIME = 0.5f; /* Текущий шаг идентификации */ static Estimate_Test_t test_step = ESTIMATE_TEST_IDLE; /* Структура с вычисленными параметрами двигателя */ static Params_t params = { 0 }; /* ============================================ * ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ * ============================================ */ static RsState_t rs_state = {0}; static RrlState_t rrl_state = {0}; static LmState_t lm_state = {0}; static int in_pause; static float pause_timer; /* ============================================ * ˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ * ============================================ */ /* * ˜˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ Vd/Vq ˜ ˜˜˜˜˜˜ * ˜˜˜˜: v - ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ (˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜) * ˜˜˜˜˜: ˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜ */ static inline float vdq_to_volts(float vq) { float vq_oe = vq / T1_PRD; float dt_oe = DT / T_PWM; if (vq_oe > dt_oe) vq_oe -= dt_oe; else if (vq_oe < -dt_oe) vq_oe += dt_oe; return vq_oe * U_BAZ / SQRT3; } /* * ˜˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜ Iq ˜ ˜˜˜˜˜˜ * ˜˜˜˜: iq - ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜ * ˜˜˜˜˜: ˜˜˜ ˜ ˜˜˜˜˜˜˜ */ static inline float idq_to_amps(float iq) { return iq * I_BAZ; } /* ============================================ * ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ * ============================================ */ /* * ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ */ void estimate_init(void) { params.Rs = 0.0192f; params.Rr = 0.0085f; params.Lls = 0.0019364f; params.Llr = 0.0019364f; params.Lk = params.Llr + params.Lls; params.Zk = 0; params.Rk = params.Rs+ params.Rr; params.Xk = 0; params.Lm = 0; memset(&rs_state, 0, sizeof(RsState_t)); memset(&rrl_state, 0, sizeof(RrlState_t)); memset(&lm_state, 0, sizeof(LmState_t)); in_pause = 0; pause_timer = 0; } void estimate_reset(void) { memset(&rs_state, 0, sizeof(RsState_t)); memset(&rrl_state, 0, sizeof(RrlState_t)); memset(&lm_state, 0, sizeof(LmState_t)); test_step = ESTIMATE_TEST_IDLE; } void estimate_start(Estimate_Test_t start_test) { estimate_reset(); test_step = start_test; } /* * ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜˜ */ Estimate_Test_t estimate_get_step(void) { return test_step; } /* * ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜˜˜˜˜ * ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜ params */ Params_t* estimate_get_params(void) { return ¶ms; } /* ============================================ * ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * ============================================ */ /* * ˜˜˜˜˜˜˜˜˜˜˜: ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ Rs * * ˜˜˜˜˜˜˜˜: * step0: ˜˜˜˜˜˜ ˜˜˜˜ IREF1, ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜ * step1: ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜, ˜˜˜˜˜˜˜˜˜ U1 ˜ I1 * step2: ˜˜˜˜˜˜ ˜˜˜˜ IREF2, ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜ * step3: ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜, ˜˜˜˜˜˜˜˜˜ U2 ˜ I2 * step4: ˜˜˜˜˜˜ Rs = (U2-U1)/(I2-I1), ˜˜˜˜˜˜˜˜˜˜ * * ˜˜˜˜˜˜˜˜˜: * vq, iq - ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜ (˜˜˜. ˜˜.) * dt - ˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * iq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜ * freq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜˜ (0 ˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜) */ static void process_Rs(float vq, float iq, float dt, float* iq_ref, float* freq_ref) { if (freq_ref) *freq_ref = 0; switch (rs_state.step) { case 0: *iq_ref = RS_IREF1; rs_state.sum_v = 0; rs_state.sum_i = 0; rs_state.sample_cnt = 0; if (fabsf(iq) >= RS_IREF1 * RS_THRESHOLD) { rs_state.step = 1; rs_state.timer = 0; } break; case 1: *iq_ref = RS_IREF1; rs_state.timer += dt; rs_state.sum_v += vdq_to_volts(vq); rs_state.sum_i += idq_to_amps(iq); rs_state.sample_cnt++; if (rs_state.timer >= RS_SETTLE_TIME) { if (rs_state.sample_cnt > 0) { rs_state.meas1 = rs_state.sum_v / rs_state.sample_cnt; rs_state.val1 = rs_state.sum_i / rs_state.sample_cnt; } rs_state.step = 2; } break; case 2: *iq_ref = RS_IREF2; rs_state.sum_v = 0; rs_state.sum_i = 0; rs_state.sample_cnt = 0; if (fabsf(iq) >= RS_IREF2 * RS_THRESHOLD) { rs_state.step = 3; rs_state.timer = 0; } break; case 3: *iq_ref = RS_IREF2; rs_state.timer += dt; rs_state.sum_v += vdq_to_volts(vq); rs_state.sum_i += idq_to_amps(iq); rs_state.sample_cnt++; if (rs_state.timer >= RS_SETTLE_TIME) { if (rs_state.sample_cnt > 0) { rs_state.meas2 = rs_state.sum_v / rs_state.sample_cnt; rs_state.val2 = rs_state.sum_i / rs_state.sample_cnt; } rs_state.step = 4; } break; case 4: *iq_ref = 0; if (fabsf(rs_state.val2 - rs_state.val1) > 0.001f) { params.Rs = (rs_state.meas2 - rs_state.meas1) / (rs_state.val2 - rs_state.val1); if (params.Rs < 0) params.Rs = 0; } rs_state.step = 5; rs_state.done = 1; /* ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ */ break; default: *iq_ref = 0; break; } } /* * ˜˜˜˜˜˜˜˜˜˜˜: ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜ Rr ˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ * * ˜˜˜˜˜˜˜˜: * - ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜˜ ˜˜ 0 ˜˜ RRL_IQ_AMP ˜˜ ˜˜˜˜˜ RRL_RAMP_TIME * - ˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ * - ˜˜˜˜˜˜˜˜˜˜ RRL_SAMPLES ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜, Vq^2, Iq^2 * - ˜˜˜˜˜˜ RMS ˜˜˜˜˜˜˜˜, ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ Zk ˜ ˜˜˜˜˜˜˜˜˜ Rk * - ˜˜˜˜˜˜ Rr = Rk - Rs, Xk, Lk * - ˜˜˜˜˜˜˜˜˜˜ RRL_AVG ˜˜˜ * * ˜˜˜˜˜˜˜˜˜: * vq, iq - ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜ (˜˜˜. ˜˜.) * dt - ˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * iq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜ * freq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜˜ */ static void process_RrL(float vq, float iq, float dt, float* iq_ref, float* freq_ref) { float f = RRL_FREQS[(rrl_state.freq_idx < RRL_FREQ_COUNT) ? rrl_state.freq_idx : (RRL_FREQ_COUNT - 1)]; /* ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ (0...1) */ float amp_k = rrl_state.ramp_timer / RRL_RAMP_TIME; if (amp_k > 1.0f) amp_k = 1.0f; /* ˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜ */ float current_amp = RRL_IQ_AMP * amp_k; /* ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜ */ *iq_ref = current_amp * sinf(2.0f * M_PI * f * rrl_state.timer); if (freq_ref) *freq_ref = f; rrl_state.timer += dt; rrl_state.ramp_timer += dt; /* ˜˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜ ˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ - ˜˜ ˜˜˜˜˜˜˜˜ */ if (amp_k < 1.0f) { return; } /* ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜, ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ */ float vq_oe = vq / T1_PRD; float dt_oe = DT / T_PWM; if (vq_oe > dt_oe) vq_oe -= dt_oe; else if (vq_oe < -dt_oe) vq_oe += dt_oe; float vq_V = vdq_to_volts(vq); float iq_A = idq_to_amps(iq); rrl_state.sum_p += vq_V * iq_A; rrl_state.sum_vq2 += vq_V * vq_V; rrl_state.sum_iq2 += iq_A * iq_A; rrl_state.sample_count++; if (rrl_state.sample_count >= RRL_SAMPLES) { float P = rrl_state.sum_p / (float)RRL_SAMPLES; float Vq_rms = sqrtf(rrl_state.sum_vq2 / (float)RRL_SAMPLES); float Iq_rms = sqrtf(rrl_state.sum_iq2 / (float)RRL_SAMPLES); if (Iq_rms > 0.001f) { float Zk = Vq_rms / Iq_rms; float Rk = P / (Iq_rms * Iq_rms); float Rr = Rk - params.Rs; if (Rr < 0) Rr = 0; float Xk = (Zk > Rk) ? sqrtf(Zk * Zk - Rk * Rk) / 2 : 0; float Lk = (f > 1e-6f) ? (Xk / (2.0f * M_PI * f)) : 0.0f; (void)Rr; rrl_state.avg_Zk += Zk; rrl_state.avg_Xk += Xk; rrl_state.avg_Lk += Lk; rrl_state.avg_Rk += Rk; rrl_state.avg_count++; } rrl_state.sum_p = 0; rrl_state.sum_vq2 = 0; rrl_state.sum_iq2 = 0; rrl_state.sample_count = 0; } if (rrl_state.avg_count >= RRL_AVG) { /* ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ */ int k = rrl_state.freq_idx; if (k < RRL_FREQ_COUNT) { rrl_state.freq_Zk[k] = rrl_state.avg_Zk / (float)RRL_AVG; rrl_state.freq_Xk[k] = rrl_state.avg_Xk / (float)RRL_AVG; rrl_state.freq_Lk[k] = rrl_state.avg_Lk / (float)RRL_AVG; rrl_state.freq_Rk[k] = rrl_state.avg_Rk / (float)RRL_AVG; rrl_state.freq_ready = k + 1; } /* ˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ */ rrl_state.freq_idx++; rrl_state.timer = 0.0f; rrl_state.ramp_timer = 0.0f; rrl_state.sum_p = 0.0f; rrl_state.sum_vq2 = 0.0f; rrl_state.sum_iq2 = 0.0f; rrl_state.sample_count = 0; rrl_state.avg_Zk = 0.0f; rrl_state.avg_Xk = 0.0f; rrl_state.avg_Lk = 0.0f; rrl_state.avg_Rk = 0.0f; rrl_state.avg_count = 0; /* ˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜ 0 ˜˜ */ if (rrl_state.freq_idx >= RRL_FREQ_COUNT) { float s1 = 0.0f, sf = 0.0f, sf2 = 0.0f; float sR = 0.0f, sfR = 0.0f; float sfX = 0.0f; int n = rrl_state.freq_ready; for (int i = 0; i < n; i++) { float fi = RRL_FREQS[i]; float Ri = rrl_state.freq_Rk[i]; float Xi = rrl_state.freq_Xk[i]; s1 += 1.0f; sf += fi; sf2 += fi * fi; sR += Ri; sfR += fi * Ri; sfX += fi * Xi; } /* Rk(f) = a + b f */ float den = (s1 * sf2 - sf * sf); float aR = (fabsf(den) > 1e-9f) ? ((sR * sf2 - sf * sfR) / den) : (n > 0 ? (sR / (float)n) : 0.0f); /* Xk(f) = c f (˜˜˜˜˜ 0) */ float cX = (sf2 > 1e-9f) ? (sfX / sf2) : 0.0f; params.Rk = aR; params.Xk = 0.0f; /* ˜˜˜ f=0 ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜ -> 0 */ params.Zk = params.Rk; params.Lk = cX / (2.0f * M_PI); params.Rr = params.Rk - params.Rs; if (params.Rr < 0.0f) params.Rr = 0.0f; params.Lls = params.Lk / 2.0f; params.Llr = params.Lk / 2.0f; rrl_state.done = 1; } } } /* * ˜˜˜˜˜˜˜˜˜˜˜: ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ Lm * * ˜˜˜˜˜˜˜˜: * - ˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜ Idref * - ˜˜˜˜˜˜˜˜˜˜˜ Ed = Vd - Rs*Id ˜˜˜˜˜˜ ˜˜˜˜ ˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ * - ˜˜˜ ˜˜˜˜˜˜ ˜˜˜ ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜ LM_SETTLE_THRESHOLD - ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ * - Ls = integral(Ed*dt) / Id_steady * - Lm = Ls - Lls * * ˜˜˜˜˜˜˜˜˜: * vd, id - ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜ (˜˜˜. ˜˜.) * dt - ˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * id_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜ * freq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜˜ */ static void process_Lm(float vd, float id, float dt, float* id_ref, float* freq_ref) { float vd_abs = vdq_to_volts(vd); float id_abs = idq_to_amps(id); float ed = vd_abs - params.Rs * id_abs; float id_pu = fabsf(id); float id_thresh = LM_IDREF * LM_SETTLE_THRESHOLD; if (freq_ref) *freq_ref = 0.0f; switch (lm_state.step) { case 0: *id_ref = 0.0f; lm_state.timer += dt; if (lm_state.timer >= LM_DEMAG_TIME) { lm_state.timer = 0.0f; lm_state.integral_psi = 0.0f; lm_state.first_sample = 0; lm_state.prev_ed = ed; lm_state.step = 1; } break; case 1: *id_ref = LM_IDREF; if (!lm_state.first_sample) { lm_state.prev_ed = ed; lm_state.first_sample = 1; } else { lm_state.integral_psi += (ed + lm_state.prev_ed) * 0.5f * dt; lm_state.prev_ed = ed; } if (id_pu >= id_thresh) { lm_state.step = 2; lm_state.timer = 0.0f; lm_state.sum_id = 0.0f; lm_state.sample_cnt = 0; } break; case 2: *id_ref = LM_IDREF; lm_state.timer += dt; lm_state.sum_id += id_abs; lm_state.sample_cnt++; if (lm_state.timer >= LM_SETTLE_TIME) { lm_state.step = 3; } break; case 3: { *id_ref = LM_IDREF; int measure_ok = 0; if (lm_state.sample_cnt > 0 && lm_state.integral_psi > 0.0f) { float id_avg = lm_state.sum_id / (float)lm_state.sample_cnt; if (id_avg > 0.001f) { float Ls = lm_state.integral_psi / id_avg; float Lm = Ls - params.Lls; if (Lm > 0.0f) { lm_state.avg_Lm += Lm; lm_state.avg_count++; measure_ok = 1; } } } if (lm_state.avg_count >= LM_AVG) { params.Lm = lm_state.avg_Lm / (float)LM_AVG; lm_state.done = 1; lm_state.step = 4; } else if (measure_ok) { lm_state.timer = 0.0f; lm_state.step = 0; } else { lm_state.timer = 0.0f; lm_state.step = 0; } break; } case 4: *id_ref = 0.0f; break; default: *id_ref = 0.0f; lm_state.step = 0; break; } } /* ============================================ * ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ * ============================================ */ /* * estimate_process - ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * * ˜˜˜˜˜˜˜˜˜˜: ˜˜˜˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜ ˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜, ˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ * ˜˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ * * ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜: * vd, vq - ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜ ˜˜˜˜ d,q (˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜) * id, iq - ˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜ ˜ ˜˜˜˜ d,q (˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜) * dt - ˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜ (˜˜˜˜˜˜˜) * * ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜: * vd_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜ ˜˜˜ d (˜˜˜. ˜˜.) * vq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜ ˜˜˜ q (˜˜˜. ˜˜.) * freq_ref - ˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜ ˜˜˜˜ (˜˜) */ void estimate_process(float vd, float vq, float id, float iq, float dt, float* vd_ref, float* vq_ref, float* freq_ref) { *vd_ref = 0; *vq_ref = 0; if (freq_ref) *freq_ref = 0; /* ˜˜˜˜ ˜ ˜˜˜˜˜˜ IDLE - ˜˜˜˜˜˜ ˜˜ ˜˜˜˜˜˜ */ if (test_step == ESTIMATE_TEST_IDLE) { return; } /* ˜˜˜˜˜ ˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜˜˜ */ if (in_pause) { pause_timer += dt; if (pause_timer >= STEP_PAUSE_TIME) { in_pause = 0; /* ˜˜˜˜˜˜˜ ˜ ˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜˜˜˜ */ if (test_step == ESTIMATE_TEST_RS) test_step = ESTIMATE_TEST_RR_L; else if (test_step == ESTIMATE_TEST_RR_L) test_step = ESTIMATE_TEST_LM; else if (test_step == ESTIMATE_TEST_LM) test_step = ESTIMATE_TEST_DONE; } return; } switch (test_step) { case ESTIMATE_TEST_RS: process_Rs(vq, iq, dt, vq_ref, freq_ref); if (rs_state.done) { in_pause = 1; pause_timer = 0; } break; case ESTIMATE_TEST_RR_L: process_RrL(vq, iq, dt, vq_ref, freq_ref); if (rrl_state.done) { in_pause = 1; pause_timer = 0; } break; case ESTIMATE_TEST_LM: if (vq_ref) *vq_ref = 0.0f; process_Lm(vd, id, dt, vd_ref, freq_ref); if (lm_state.done) { in_pause = 1; pause_timer = 0; } break; case ESTIMATE_TEST_DONE: /* ˜˜˜˜˜˜˜˜˜˜˜˜˜ ˜˜˜˜˜˜˜˜˜ */ break; default: break; } }