test_pwrlim.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "gtest/gtest.h"
  2. #include <cmath>
  3. #include <gtest/gtest.h>
  4. #include <stdint.h>
  5. #include <tuple>
  6. #include "scope.h"
  7. #include "test_user.h"
  8. #include "PmsmSimUt.h"
  9. #include "motor_sim_helper.h"
  10. class PwrLimTest : public testing::Test
  11. {
  12. protected:
  13. PmsmSimUtModelClass *sys1;
  14. McStatus McStatus1;
  15. McPuBase McPuBase1;
  16. virtual void SetUp() override
  17. {
  18. sys1 = new PmsmSimUtModelClass();
  19. sys1->initialize();
  20. MotorSimHelper::RestoreDefaultParam(sys1);
  21. sys1->PmsmSimUt_P.Params.Ts = 1.0 / FTBC_HZ;
  22. sys1->PmsmSimUt_P.Params.SpdCtrl = 1;
  23. sys1->PmsmSimUt_P.Params.B = 0;
  24. sys1->PmsmSimUt_P.Params.Jm = M_JD * 1e-7;
  25. sys1->PmsmSimUt_P.Params.Pn = M_POLE_PAIRS;
  26. sys1->PmsmSimUt_P.Params.R = M_RS_OHM * 1e-5;
  27. sys1->PmsmSimUt_P.Params.Ld = M_LD_NOLOAD_MH * 1e-8;
  28. sys1->PmsmSimUt_P.Params.Lq = M_LQ_NOLOAD_MH * 1e-8;
  29. sys1->PmsmSimUt_P.Params.Flux = M_FLUX_WB * 1e-6;
  30. sys1->PmsmSimUt_P.Params.SKp = (sys1->PmsmSimUt_P.Params.Jm * 20 * 2 * 3.14 / sys1->PmsmSimUt_P.Params.Flux) / 30 * 3.14;
  31. sys1->PmsmSimUt_P.Params.SKi = 20 * 2 * 3.14 * sys1->PmsmSimUt_P.Params.SKp;
  32. sys1->PmsmSimUt_P.Params.CKpd = (300 * 2 * 3.14) * sys1->PmsmSimUt_P.Params.Ld;
  33. sys1->PmsmSimUt_P.Params.CKid = (300 * 2 * 3.14) * sys1->PmsmSimUt_P.Params.R;
  34. sys1->PmsmSimUt_P.Params.CKpq = (300 * 2 * 3.14) * sys1->PmsmSimUt_P.Params.Lq;
  35. sys1->PmsmSimUt_P.Params.CKiq = (300 * 2 * 3.14) * sys1->PmsmSimUt_P.Params.R;
  36. sys1->PmsmSimUt_reset();
  37. McPuBaseIn puBaseIn = {
  38. .Pairsb = MOTOR_PAIRS,
  39. .UbVt = VBASE,
  40. .IbAp = IBASE,
  41. .FbHz = FBASE,
  42. };
  43. McPuBaseInit(&McPuBase1, &puBaseIn);
  44. McStatusInit(&McStatus1, &McPuBase1);
  45. CodeParaInit();
  46. pwr_voPwrLimInit();
  47. asr_voSpdPIInit();
  48. }
  49. virtual void TearDown() override
  50. {
  51. sys1->terminate();
  52. delete sys1;
  53. pwr_voPwrLimInit();
  54. asr_voSpdPIInit();
  55. }
  56. };
  57. class PwrLimTest2 : public PwrLimTest, public testing::WithParamInterface<::std::tuple<int,int>>
  58. {};
  59. TEST_P(PwrLimTest2, PwrLim)
  60. {
  61. /* Coef Cal */
  62. pwr_stPwrLimCofIn.swPwrLimW = cp_stControlPara.swPwrLimitValWt;
  63. pwr_stPwrLimCofIn.uwPwrErrW = cp_stControlPara.swPwrLimitErrWt;
  64. pwr_stPwrLimCofIn.swIqMaxAp = cp_stMotorPara.swIpeakMaxA;
  65. pwr_stPwrLimCofIn.uwIBaseAp = IBASE;
  66. pwr_stPwrLimCofIn.uwUbVt = VBASE;
  67. pwr_stPwrLimCofIn.uwPwrLimPIKp = cp_stControlPara.swPwrLimitKpPu;
  68. pwr_stPwrLimCofIn.uwPwrLimPIKi = cp_stControlPara.swPwrLimitKiPu;
  69. pwr_stPwrLimCofIn.swPwrLimStartTempCe = cp_stControlPara.swAlmPwrLimitStartTempVal;
  70. pwr_stPwrLimCofIn.swAlarmTempCe = cp_stControlPara.swAlmOverHeatCeVal;
  71. pwr_voPwrLimCof(&pwr_stPwrLimCofIn, &pwr_stPwrLimCof);
  72. mth_voLPFilterCoef((1000000 / cp_stControlPara.swPwrLimitLPFFre), FTBC_HZ, &scm_stMotoPwrInLpf.uwKx);
  73. asr_stSpdPICoefIn.uwUbVt = VBASE;
  74. asr_stSpdPICoefIn.uwIbAp = IBASE;
  75. asr_stSpdPICoefIn.uwFbHz = FBASE;
  76. asr_stSpdPICoefIn.uwFTbsHz = FTBS_HZ;
  77. asr_stSpdPICoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs;
  78. asr_stSpdPICoefIn.uwMtJm = cp_stMotorPara.swJD;
  79. asr_stSpdPICoefIn.uwMtFlxWb = cp_stMotorPara.swFluxWb;
  80. asr_stSpdPICoefIn.uwMcoef = cp_stControlPara.swAsrPIM;
  81. asr_stSpdPICoefIn.uwWvcHz = cp_stControlPara.swAsrPIBandwidth;
  82. asr_stSpdPICoefIn.uwRatioJm = cp_stControlPara.swAsrSpdInerRate;
  83. asr_voSpdPICoef(&asr_stSpdPICoefIn, &asr_stSpdPICoef);
  84. /* Custom Spd Ctrl */
  85. sys1->PmsmSimUt_P.Params.CustomSpdCtrl = 1;
  86. int16_t spdRefRpm = 3000;
  87. for (int i = 0; i < 10 / sys1->PmsmSimUt_P.Params.Ts; i++)
  88. {
  89. /* Speed Ref */
  90. // spdRefRpm += 1;
  91. // if(spdRefRpm > 3000)
  92. // {
  93. // spdRefRpm = 3000;
  94. // }
  95. int16_t spdRefPu = ((int32_t)spdRefRpm << 15) / McStatus1.Base->uwVbRpm;
  96. /* Motor Load Torque */
  97. // sys1->PmsmSimUt_U.CtrlIn.Tm += 0.001;
  98. // if(sys1->PmsmSimUt_U.CtrlIn.Tm > 2)
  99. // {
  100. // sys1->PmsmSimUt_U.CtrlIn.Tm = 2;
  101. // }
  102. sys1->PmsmSimUt_U.CtrlIn.Tm = 1; ///< 注意:加载需加到恒功率区以测试功率是否被限制,但是太大会导致仿真中转速负增加最终溢出,需要算一下
  103. /* Pu Value to Named Value */
  104. MotorSimHelper::SetModelICmdPu(sys1, 0, asr_stSpdPIOut.swIqRefPu, McStatus1.Base);
  105. /* Motor Control */
  106. sys1->step();
  107. /* Named Value to Pu Value */
  108. MotorSimHelper::TransitModelOutput(sys1, &McStatus1);
  109. /* Power Cal */
  110. double ualpha = 0.6667 * (sys1->PmsmSimUt_Y.Out.Uabc[0] - 0.5 * sys1->PmsmSimUt_Y.Out.Uabc[1] - 0.5 * sys1->PmsmSimUt_Y.Out.Uabc[2]);
  111. double ubeta = 0.57735 * (sys1->PmsmSimUt_Y.Out.Uabc[1] - sys1->PmsmSimUt_Y.Out.Uabc[2]);
  112. double ud = ualpha * cos(sys1->PmsmSimUt_Y.Out.Theta) + ubeta * sin(sys1->PmsmSimUt_Y.Out.Theta);
  113. double uq = -ualpha * sin(sys1->PmsmSimUt_Y.Out.Theta) + ubeta * cos(sys1->PmsmSimUt_Y.Out.Theta);
  114. double udPu = ud * 10 * 16384 / VBASE;
  115. double uqPu = uq * 10 * 16384 / VBASE;
  116. // int16_t power = ((int32_t)McStatus1.Pu.swIalpha * McStatus1.Pu.swUalpha + (int32_t)McStatus1.Pu.swIbeta * McStatus1.Pu.swUbeta) >> 13; //Q15
  117. int16_t power = ((int32_t)udPu * McStatus1.Pu.swId + (int32_t)uqPu * McStatus1.Pu.swIq) >> 13; // Q15
  118. mth_voLPFilter(power, &scm_stMotoPwrInLpf);
  119. /* Power Limit Control */
  120. pwr_stPwrLimIn.swMotorPwrPu = scm_stMotoPwrInLpf.slY.sw.hi;
  121. pwr_stPwrLimIn.swPCBTemp = get<0>(GetParam());
  122. pwr_stPwrLimIn.uwBatCap = get<1>(GetParam());
  123. pwr_voPwrLimPI(&pwr_stPwrLimIn, &pwr_stPwrLimCof, &pwr_stPwrLimOut2); // Q14
  124. /* Speed Control */
  125. if (i % (FTBC_HZ / FTBS_HZ) == 0)
  126. {
  127. asr_stSpdPIIn.swSpdRefPu = spdRefPu;
  128. asr_stSpdPIIn.swSpdFdbPu = McStatus1.Pu.swElecOmega;
  129. asr_stSpdPIIn.swIqMaxPu = ABS(pwr_stPwrLimOut2.swIqLimPu);
  130. asr_stSpdPIIn.swIqMinPu = -ABS(pwr_stPwrLimOut2.swIqLimPu);
  131. asr_voSpdPI(&asr_stSpdPIIn, &asr_stSpdPICoef, &asr_stSpdPIOut);
  132. }
  133. UdpScope::Send(0, pwr_stPwrLimOut2.swPwrLimActualPu, power, pwr_stPwrLimOut2.swIqLimPu, asr_stSpdPIOut.swIqRefPu, McStatus1.Pu.swIq,
  134. McStatus1.Pu.swElecOmega);
  135. }
  136. /* 判断单元测试是否通过 */
  137. /* 判断实际功率是否在限制功率以下 */
  138. EXPECT_LE(scm_stMotoPwrInLpf.slY.sw.hi, (pwr_stPwrLimOut2.swPwrLimActualPu + 2));
  139. /* 判断限制电流与设计值是否一致 */
  140. if(ABS(pwr_stPwrLimOut2.swPwrLimActualPu - scm_stMotoPwrInLpf.slY.sw.hi) > 10)
  141. {
  142. double Iqlim;
  143. if (pwr_stPwrLimIn.swPCBTemp < pwr_stPwrLimCof.swPwrLimStartTemp)
  144. {
  145. Iqlim = pwr_stPwrLimCof.swIqMaxPu;
  146. }
  147. else if(pwr_stPwrLimIn.swPCBTemp < pwr_stPwrLimCof.swPwrLimEndTemp)
  148. {
  149. Iqlim = pwr_stPwrLimCof.swIqMaxPu - ((int32_t)(pwr_stPwrLimIn.swPCBTemp - pwr_stPwrLimCof.swPwrLimStartTemp) * pwr_stPwrLimCof.swIqMaxPu * 83 / (pwr_stPwrLimCof.swPwrLimEndTemp - pwr_stPwrLimCof.swPwrLimStartTemp) >> 7);
  150. }
  151. else
  152. {
  153. Iqlim = (int32_t)pwr_stPwrLimCof.swIqMaxPu * 45 >> 7;
  154. }
  155. EXPECT_NEAR(Iqlim, pwr_stPwrLimOut2.swIqLimPu, 2);
  156. }
  157. else
  158. {
  159. EXPECT_NEAR((pwr_stPwrLimCof.swIqMaxPu + pwr_stPwrLimOut2.swIqLimDetaSum), pwr_stPwrLimOut2.swIqLimPu, 2);
  160. }
  161. }
  162. INSTANTIATE_TEST_SUITE_P(DiffTemp, PwrLimTest2,::testing::Combine(::testing::Values(60, 95, 100),::testing::Values(100, 15, 10, 0)));