#include "IQmathLib.h" #include "math.h" #include "params.h" #include "adc_tools.h" #include "regul_turns.h" #include "pid_reg3.h" #include "vector.h" #include "teta_calc.h" #include "pwm_vector_regul.h" #include "my_filter.h" // #pragma DATA_SECTION(pidFvect,".fast_vars1"); PIDREG3 pidFvect = PIDREG3_DEFAULTS; #define MAX_PID_CURRENT IQ_OUT_NOM #define IQ_165_RPM 2306867 //165об/мин #define IQ_170_RPM 2376772 //170об/мин #define IQ_5_RPM 69905 //5об/мин #define TIME_RMP_FAST 10.0 //sec #define TIME_RMP_SLOW 30.0 //sec #define F_DEST 3.0 //Hz void init_Fvect_pid() { pidFvect.Ref = 0; pidFvect.Kp = _IQ(10.0);//_IQ(30.0);// // pidFvect.Ki = _IQ(0.03); //_IQ(0.015); pidFvect.Kc = _IQ(0.5); pidFvect.OutMax = _IQ(MAX_PID_CURRENT / NORMA_ACP); pidFvect.OutMin = -_IQ(MAX_PID_CURRENT / NORMA_ACP); } void reset_F_pid() { pidFvect.Up = 0; pidFvect.Up1 = 0; pidFvect.Ui = 0; pidFvect.Ud = 0; pidFvect.Out = 0; } void vector_turns(_iq Fzad, _iq Frot, _iq Iq, int mode, _iq* Iq_zad, _iq* Id_zad) { static _iq Fzad_rmp = 0, koef_fast = _IQ(F_DEST / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM / 2.5); static _iq koef_slow = _IQ(F_DEST / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM / 5.0); // static _iq cos_fi_nom = _IQ(COS_FI), cos_fi_nom_squared = _IQ(COS_FI * COS_FI); //prev_Fzad = 0, static _iq Iq_out_max = _IQ(IQ_OUT_NOM / NORMA_ACP); static _iq Id_out_max = _IQ(500.0 / NORMA_ACP); //_IQ(ID_OUT_NOM / NORMA_ACP); static _iq mzz_zad_int=0; static int Iq_rmp_to_optica = 0; // static int flag_Iq_synced_with_optica = 0; // static _iq step_Iq_rmp = _IQ(20.0 / NORMA_ACP); _iq koef_rmp; //, koef_spad; _iq Iq_out_unsat, Iq_out_sat, Id_out_sat, Id_out_unsat; _iq deltaVar; // if (f.DownTemperature) { // // mzz_zad_int = zad_intensiv_q(35480, 35480, mzz_zad_int, _IQmpy(Iq_out_max, temperature_limit_koeff)); // mzz_zad_int = zad_intensiv_q(25480, 25480, mzz_zad_int, _IQmpy(f.iq_mzz_zad, temperature_limit_koeff)); // } else { mzz_zad_int = zad_intensiv_q(35480, 35480, mzz_zad_int, f.iq_mzz_zad); // mzz_zad_int = zad_intensiv_q(25480, 25480, mzz_zad_int, pid_Out_max); } pidFvect.OutMax = Iq_out_max; pidFvect.OutMin = -Iq_out_max; if (Fzad >= 0 && Frot > 0) { pidFvect.OutMin = 0; } if (Fzad <= 0 && Frot < 0) { pidFvect.OutMax = 0; } if((mode != 1) || (!f.Go)) //Заносим текущее состояние в регул-тор, что бы при смене режима не было скачков { // Fzad_rmp = Frot; // prev_Fzad = Frot; reset_F_pid(); //Было ниже, может быть что-то было не так pidFvect.Ui = Iq; pidFvect.Out = Iq; *Iq_zad = Iq; Iq_rmp_to_optica = Iq; // *Id_zad = _IQdiv(_IQmpy(Iq, _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); if(!f.Go) { *Iq_zad = *Id_zad = 0; } // flag_Iq_synced_with_optica = 0; return; } //Синхронизация парных ПЧ //Задание по Iq передаётся по оптической шине // if ((f.flag_leading == 0) && (f.read_task_from_optical_bus == 1) && (f.sync_Iq_from_optical_bus == 1)) { // // if (flag_Iq_synced_with_optica == 0) { // // if (_IQabs(analog.iqIq_zad_from_optica - Iq_rmp_to_optica) > 1118481) { //200A // // Iq_rmp_to_optica = zad_intensiv_q(step_Iq_rmp, step_Iq_rmp, Iq_rmp_to_optica, analog.iqIq_zad_from_optica); // // } else { // // Iq_rmp_to_optica = analog.iqIq_zad_from_optica; // // flag_Iq_synced_with_optica = 1; // // } // // } else { // // Iq_rmp_to_optica = analog.iqIq_zad_from_optica; // // } // Iq_rmp_to_optica = analog.iqIq_zad_from_optica; // Iq_out_unsat = Iq_rmp_to_optica; // Iq_out_sat = _IQsat(Iq_out_unsat, mzz_zad_int, -mzz_zad_int); // Id_out_unsat = _IQdiv(_IQmpy(_IQabs(Iq_out_sat), _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); // Id_out_sat = _IQsat(Id_out_unsat, Id_out_max, 0); // *Iq_zad = Iq_out_sat; // *Id_zad = Id_out_sat; // reset_F_pid(); // pidFvect.Ui = Iq_out_sat; // pidFvect.Out = Iq_out_sat; // Fzad_rmp = Frot; // return; // } //if(Fzad != prev_Fzad) //Рампа зависит от режима. Если просто повышение, то медленно. //{ //Если понижение или реверс, то быстро. if(_IQabs(Fzad_rmp) <= _IQabs(Fzad) && (((Fzad >= 0) && (Fzad_rmp >= 0)) || ((Fzad < 0 ) && (Fzad_rmp < 0)))) { koef_rmp = koef_slow; } else { koef_rmp = koef_fast; } // prev_Fzad = Fzad; //} // Fzad_rmp = zad_intensiv_q(koef_rmp, koef_rmp, Fzad_rmp, Fzad); // logpar.log2 = (int16)(_IQtoIQ15(Fzad)); // logpar.log19 = (int16)(_IQtoIQ15(Fzad_rmp)); //В какой-то момент перестала корректно работать функция zad_intensiv_q // поэтому код из неё вставил сюда. deltaVar = Fzad-Fzad_rmp; if ((deltaVar>koef_rmp) || (deltaVar<-koef_rmp)) { if (deltaVar>0) Fzad_rmp += koef_rmp; else Fzad_rmp -= koef_rmp; } else Fzad_rmp = Fzad; pidFvect.Ref = Fzad_rmp; pidFvect.Fdb = Frot; pidFvect.calc(&pidFvect); Iq_out_unsat = pidFvect.Out; //TODO: ATTENTION!!! worked better on stend if (_IQabs(Iq_out_unsat) < 27962) //5A { pidTetta.Ui = 0; pidTetta.SatErr = 0; } Iq_out_sat = _IQsat(Iq_out_unsat, Iq_out_max, -Iq_out_max); // if(f.DownToNominal) //In this mode max I equial Inom // { // Iq_out_sat = _IQsat(Iq_out_unsat, I_OUT_NOMINAL_IQ, -I_OUT_NOMINAL_IQ); // } // Iq_out_sat = _IQsat(Iq_out_unsat, mzz_zad_int, -mzz_zad_int); //Test //Расчёт d составл-ющей тока Iq_out_unsat = _IQabs(Iq_out_unsat); Id_out_unsat = _IQdiv(_IQmpy(Iq_out_unsat, _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); Id_out_sat = _IQsat(Id_out_unsat, Id_out_max, 0); *Iq_zad = Iq_out_sat; *Id_zad = Id_out_sat; }