Bladeren bron

feat:增加恒压制动单元测试,测试通过,应用恒压制动
fix: 修复不同系统过压欠压恢复阈值bug

CN\guohui27 2 jaren geleden
bovenliggende
commit
1b7e2e766f

+ 1 - 1
User project/2.MotorDrive/Source/packed

@@ -1 +1 @@
-Subproject commit 5db4fa0b12ca132566622a2c03e42759fd233596
+Subproject commit ca3425cf69490131d292d9e28a7b104bdf98211d

+ 23 - 4
User project/2.MotorDrive/Source/spdctrFSM.c

@@ -126,8 +126,28 @@ void ClzLoop_TbcupHook(void)
     pwr_stPwrLimIn.PCBTemp = adc_stUpOut.PCBTemp;
     pwr_voPwrLim2(&pwr_stPwrLimIn, &pwr_stPwrLimCof, &pwr_stPwrLimOut2); // Q14
 
-    scm_swIqRefPu = swCurRefrompu;
-    scm_swIdRefPu = 0; //flx_stCtrlOut.swIdRefPu;
+    /*======================================================================= 
+             Set Iq and Id reference for Constant Voltage Break
+    =======================================================================*/
+    cvb_stBrakeIn.uwVdcLpfPu = adc_stUpOut.uwVdcLpfPu;
+    cvb_stBrakeIn.swIdRefPu = scm_swIdRefPu;
+    cvb_stBrakeIn.swIqRefPu = swCurRefrompu;             
+    cvb_stBrakeIn.swSpdPu = scm_stSpdFbkLpf.slY.sw.hi;
+    cvb_stBrakeIn.uwAngelPu = scm_uwAngRefPu;
+    cvb_stBrakeIn.uwSpdLpfAbsPu = scm_uwSpdFbkLpfAbsPu;
+    cvb_voBrake(&cvb_stBrakeIn,&cvb_stBrakeCoef,&cvb_stBrakeOut);
+ 
+    /** Idref可变范围-3A~0A且未弱磁,暂不做过多处理;Angle在down中更新,暂不改为改为恒压制动角度 **/
+    if(cvb_stBrakeIn.uwVdcLpfPu >= cvb_stBrakeCoef.uwVdcStartCvbPu)
+    {
+        scm_swIdRefPu = cvb_stBrakeOut.swIdRefPu;
+    }
+    else
+    {
+        scm_swIdRefPu = 0;  //flx_stCtrlOut.swIdRefPu;  
+    }  
+
+    scm_swIqRefPu = cvb_stBrakeOut.swIqRefPu;
 }
 
 void Stop_TbcupHook(void)
@@ -159,8 +179,7 @@ void ParDet_TbcdownHook(void)
 }
 void StartUp_TbcdownHook(void)
 {
-
-/* Speed feedback LPF */
+    /* Speed feedback LPF */
     if(cp_stFlg.ThetaGetModelSelect == ANG_OBSERVER)
     {
         mth_voLPFilter(obs_stObsOutPu.swElecFreqPu, &scm_stSpdFbkLpf);

+ 6 - 1
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/glbcof.h

@@ -21,6 +21,9 @@ Revising History (ECL of this file):
 #ifndef GLBCOF_H
 #define GLBCOF_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /************************************************************************
  Compiler Directives (N/A)
 *************************************************************************/
@@ -211,8 +214,10 @@ _GLBCOF_EXT void cof_voSysInit(void);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
 
-/***********************************************************************/
 #endif
 /*************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 4 - 4
User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Include/user.h

@@ -249,11 +249,11 @@ Update Time
 /* Recover time of IPM OC */
 #define ALM_IPM_OC_REC_TM 200 // unit: ms, Time of duration(TBC)
 /* Recover time & value of over voltage */
-#define ALM_OVR_VLT_REC_VAL 450 // unit: 0.1V
+#define ALM_OVR_VLT_REC_VAL (ALM_OVR_VLT_LVL1_VAL - 30)  // unit: 0.1V
 #define ALM_OVR_VLT_REC_TM  100 // unit: ms, Time of duration(TBC)
 #define ALM_OVR_VLT_REC_TM1 150 // unit: ms, Time of duration(TBC)
 /* Recover time & value of under voltage */
-#define ALM_UNDR_VLT_REC_VAL 300 // unit: 0.1V
+#define ALM_UNDR_VLT_REC_VAL (ALM_UNDR_VLT_LVL1_VAL + 30) // unit: 0.1V
 #define ALM_UNDR_VLT_REC_TM  200 // unit: ms, Time of duration(TBC)
 #define ALM_UNDR_VLT_REC_TM1 400 // unit: ms, Time of duration(TBC)
 /* Recover time & value of IPM over heat */
@@ -369,8 +369,8 @@ Update Time
 /*======================================================================*
    Constant Voltage Braking Parameter define
 *=======================================================================*/
-#define CVB_CONSTANT_VOL_BRAKE_V 42   // unit:0.1V,Voltage limit of Constant Voltage Brake
-#define CVB_CONSTANT_SPD_LOW_RPM 1000 // unit:rpm,
+#define CVB_CONSTANT_VOL_BRAKE_V (ALM_OVR_VLT_LVL1_VAL - 30)   // unit:0.1V,Voltage limit of Constant Voltage Brake
+#define CVB_CONSTANT_SPD_LOW_RPM 4500 // unit:rpm,
 
 /*======================================================================*
    Power limit

+ 195 - 0
unit_test/test_brake.cpp

@@ -0,0 +1,195 @@
+#include "gtest/gtest.h"
+#include <cmath>
+#include <gtest/gtest.h>
+#include <stdint.h>
+#include <tuple>
+#include "scope.h"
+#include "test_user.h"
+#include "PmsmSimUt.h"
+#include "motor_sim_helper.h"
+
+class ConsVoltBrakeTest : public testing::Test
+{
+protected:
+    McStatus      McStatus1;
+    McPuBase      McPuBase1;
+
+    static void SetUpTestSuite()
+    {
+
+    }
+    virtual void SetUp() override
+    {
+        McPuBaseIn puBaseIn = {
+            .Pairsb = MOTOR_PAIRS,
+            .UbVt   = VBASE,
+            .IbAp   = IBASE,
+            .FbHz   = FBASE,
+        };
+        McPuBaseInit(&McPuBase1, &puBaseIn);
+        McStatusInit(&McStatus1, &McPuBase1);
+
+        CodeParaInit();
+        cvb_voBrakeInit();
+        cof_voSysInit();
+    }
+    virtual void TearDown() override
+    {
+
+    }
+};
+
+class ConsVoltBrakeTest1 : public ConsVoltBrakeTest, public testing::WithParamInterface<::std::tuple<int,int,int>>
+{};
+
+TEST_P(ConsVoltBrakeTest1, ConsVoltBrake)
+{
+    /* Coef Cal */
+    cvb_stBrakeCoefIn.uwVdcCvbVt = cp_stControlPara.swCvbConstantVolBrakeV;
+    cvb_stBrakeCoefIn.uwLowSpdRpm = cp_stControlPara.swCvbConstantSpdLowRpm;
+    cvb_stBrakeCoefIn.swIqRefMaxAp = cp_stMotorPara.swIpeakMaxA;
+    cvb_stBrakeCoefIn.swIdRefMaxAp = cp_stMotorPara.swIdMaxA;
+    cvb_stBrakeCoefIn.swIdRefMinAp = cp_stMotorPara.swIdMinA;
+    cvb_stBrakeCoefIn.uwVBaseVt = VBASE;
+    cvb_stBrakeCoefIn.uwIBaseAp = IBASE;
+    cvb_stBrakeCoefIn.uwFBaseHz = FBASE;
+    cvb_stBrakeCoefIn.uwMotorPairs = cp_stMotorPara.swMotrPolePairs;
+    cvb_voBrakeCoef(&cvb_stBrakeCoefIn, &cvb_stBrakeCoef);
+
+    s16 udc = get<0>(GetParam());       ///< unit: 0.1V
+    s16 spd = get<1>(GetParam());       ///< unit: rpm
+    s16 iqrefIn = get<2>(GetParam());   ///< unit: 0.01A
+
+    McStatus1.Pu.swUdc = ((u32)udc << 14)/ McPuBase1.uwUbVt;
+    McStatus1.Pu.swElecOmega = ((s32)spd << 15)/ McPuBase1.uwVbRpm; ///< Q15
+    McStatus1.Pu.swElecAngle = 200;   ///< Q15
+
+    for (int i = 0; i < 100 ; i++)
+    {
+        /* Constant voltage brake */
+        cvb_stBrakeIn.uwVdcLpfPu = McStatus1.Pu.swUdc;
+        cvb_stBrakeIn.swIdRefPu = cvb_stBrakeOut.swIdRefPu;
+        cvb_stBrakeIn.swIqRefPu = ((s32)iqrefIn << 14) / IBASE;         
+        cvb_stBrakeIn.swSpdPu = McStatus1.Pu.swElecOmega;
+        cvb_stBrakeIn.uwAngelPu = McStatus1.Pu.swElecAngle;
+        cvb_stBrakeIn.uwSpdLpfAbsPu = abs(McStatus1.Pu.swElecOmega);
+        cvb_voBrake(&cvb_stBrakeIn,&cvb_stBrakeCoef,&cvb_stBrakeOut);
+
+        double iqlim,iqrefOut,elecAngle,delta;
+        /* Ajust Iqlim according to Vdc */
+        if(McStatus1.Pu.swUdc > cvb_stBrakeCoef.uwVdcStartCvbPu)
+        {
+            iqlim = (double)(McStatus1.Pu.swUdc - cvb_stBrakeCoef.uwVdcCvbPu) * cvb_stBrakeCoef.swKcvb / 512;   ///< Q14 = Q14 + Q9 - Q9
+        }
+        else
+        {
+            iqlim = -cvb_stBrakeCoef.swIqLimMaxPu;
+        }
+        if(iqlim > 0)
+        {
+            iqlim = 0;
+        }
+        iqlim = -iqlim;
+        if(iqlim >  cvb_stBrakeCoef.swIqLimMaxPu)
+        {
+            iqlim = cvb_stBrakeCoef.swIqLimMaxPu;
+        }  
+        if ((McStatus1.Pu.swUdc < cvb_stBrakeCoef.uwVdcStartCvbPu) && (cvb_stBrakeCoef.swKcvb > 16384) && (iqlim == 0)) // avoid overflow
+        {
+            iqlim = cvb_stBrakeCoef.swIqLimMaxPu;
+        }
+
+        /* Ajust Electrical Angle according to Vdc */
+        if(McStatus1.Pu.swUdc  < cvb_stBrakeCoef.uwVdcCvbPu)
+        {
+            delta = 0;
+        }
+        else if(McStatus1.Pu.swUdc  < cvb_stBrakeCoef.uwVdcLagAngelPu)
+        {
+            delta = ((double)(McStatus1.Pu.swUdc  - cvb_stBrakeCoef.uwVdcCvbPu) * cvb_stBrakeCoef.uwKAnglePu) / 128;    ///< Q15
+        }
+        else 
+        {
+            delta = ((double)(cvb_stBrakeCoef.uwVdcLagAngelPu - cvb_stBrakeCoef.uwVdcCvbPu) *  cvb_stBrakeCoef.uwKAnglePu) / 128;
+        }
+
+        /* Output Iqref limit */
+        if(McStatus1.Pu.swElecOmega > 0)
+        {
+            if(cvb_stBrakeIn.swIqRefPu < -iqlim)
+            {
+                iqrefOut = -iqlim;
+            }
+            else
+            {
+                iqrefOut = cvb_stBrakeIn.swIqRefPu;
+            }
+            elecAngle = McStatus1.Pu.swElecAngle - delta;
+        }
+        else
+        {
+            if(cvb_stBrakeIn.swIqRefPu > iqlim)
+            {
+                iqrefOut = iqlim;
+            }
+            else
+            {
+                iqrefOut = cvb_stBrakeIn.swIqRefPu;
+            }
+            elecAngle = McStatus1.Pu.swElecAngle + delta;
+        }
+        
+        if(elecAngle < 0)
+        {
+            elecAngle=  elecAngle + 65536;  
+        }   
+        else 
+        {
+            elecAngle =  elecAngle;
+        }
+ 
+        /* Ajust Idref according to Vdc */
+        double idrefOut;
+        if((cvb_stBrakeIn.swIqRefPu < 0 && McStatus1.Pu.swElecOmega > 0) || (cvb_stBrakeIn.swIqRefPu > 0 && McStatus1.Pu.swElecOmega < 0))
+        {
+            if(abs(McStatus1.Pu.swElecOmega) < cvb_stBrakeCoef.uwLowSpdPu)
+            {
+                idrefOut =  cvb_stBrakeIn.swIdRefPu + cvb_stBrakeCoef.swIdRcyPu;
+            }
+            else
+            {
+                idrefOut =  cvb_stBrakeIn.swIdRefPu - cvb_stBrakeCoef.swIdDrpPu;
+            }   
+
+        }
+        else
+        {
+            idrefOut =   cvb_stBrakeIn.swIdRefPu;
+        }
+        
+        /* Output Idref limit */
+        if(idrefOut <  cvb_stBrakeCoef.swIdRefMinPu)
+        {
+            idrefOut =  cvb_stBrakeCoef.swIdRefMinPu;
+        }
+        else if(idrefOut >  cvb_stBrakeCoef.swIdRefMaxPu)
+        {
+            idrefOut =  cvb_stBrakeCoef.swIdRefMaxPu;
+        }
+        else 
+        {
+            idrefOut = idrefOut;
+        }
+
+        EXPECT_NEAR(iqrefOut,  cvb_stBrakeOut.swIqRefPu, 2);
+        EXPECT_NEAR(idrefOut,  cvb_stBrakeOut.swIdRefPu, 2);
+        EXPECT_NEAR(elecAngle, cvb_stBrakeOut.uwAngelPu, 2);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(DiffUdc, ConsVoltBrakeTest1,
+                         ::testing::Combine(::testing::Values(CVB_CONSTANT_VOL_BRAKE_V - 20, CVB_CONSTANT_VOL_BRAKE_V + 10), ::testing::Values(-2000,0,2000), ::testing::Values(-200,0,200)));
+
+
+
+

+ 12 - 11
unit_test/test_cursample_calib.cpp

@@ -37,9 +37,9 @@ TEST_P(CurSampleCalibTest1, SingResCalib)
     double currentFreqHz = 100;             // unit: Hz
     double currentMod = get<0>(GetParam()); // unit: A
     double rdsonCoef = get<1>(GetParam());
-    double voltageMod = get<2>(GetParam()); // unit: V
+    double emf = get<2>(GetParam()); // unit: V
     double loopNum = 100000000;
-    double spdAbsTarget = voltageMod * 32768 * 1000 / M_FLUX_WB / 2 / 3.14 * 1000 / FBASE; // 2600
+    double spdAbsTarget = emf * 32768 * 1000 / M_FLUX_WB / 2 / 3.14 * 1000 / FBASE; // Q15
 
     /* Coef Cal */
     adc_voSampleCoef(&adc_stCof);
@@ -213,13 +213,14 @@ TEST_P(CurSampleCalibTest1, SingResCalib)
                 adc_voSRCalibration(&adc_stCof, &adc_stUpOut, &adc_stDownOut);
 
                 /* ADC Trigger Cal */ 
-                pwm_stGenIn.swUalphaPu = (SWORD)(voltageMod * 10 * sin(phase + (double)3.14 / 36) * 16384 / VBASE); // Q14
-                pwm_stGenIn.swUbetaPu = (SWORD)(voltageMod * 10 * cos(phase + (double)3.14 / 36) * 16384 / VBASE);  // Q14
+                double phase2 = atan2((double)currentMod * M_LQ_NOLOAD_MH / 100 / 1000000, (double )M_FLUX_WB / 1000000) ;
+                pwm_stGenIn.swUalphaPu = (SWORD)(emf * 10 * sin(phase + phase2) * 16384 / cos(phase2) / VBASE); // Q14
+                pwm_stGenIn.swUbetaPu = (SWORD)(emf * 10 * cos(phase + phase2) * 16384 / cos(phase2) / VBASE);  // Q14
                 pwm_stGenIn.uwVdcPu = (UWORD)(36 * 10 * 16384 / VBASE);                                             // Q14
                 pwm_voGen(&pwm_stGenIn, &pwm_stGenCoef, &pwm_stGenOut);
 
                 /* Scope */ 
-                //UdpScope::Send(0, adc_stDownOut.slSampIcPu, adc_stUpOut.swCalibIcPu, adc_stDownOut.swIcPu);
+                UdpScope::Send(0, adc_stDownOut.slSampIcPu, adc_stUpOut.swCalibIcPu, adc_stDownOut.swIcPu);
                 //UdpScope::Send(0, scm_uwSpdFbkLpfAbsPu, pwm_stGenOut.blSampleCalibFlag);
 
                 /* Determine whether the unit test pass */
@@ -265,9 +266,9 @@ TEST_P(CurSampleCalibTest1, SingResCalib)
                         }
                         else if (1024 / rdsonCoef > adc_stCof.uwCalibcoefMax)
                         {
-                            EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIaPu, 10);
-                            EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIbPu, 10);
-                            EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIcPu, 10);
+                            EXPECT_NEAR((double)adc_stDownOut.slSampIaPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIaPu, 50);
+                            EXPECT_NEAR((double)adc_stDownOut.slSampIbPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIbPu, 50);
+                            EXPECT_NEAR((double)adc_stDownOut.slSampIcPu * adc_stCof.uwCalibcoefMax / 1024, adc_stDownOut.swIcPu, 50);
                         }
                         else
                         {
@@ -279,9 +280,9 @@ TEST_P(CurSampleCalibTest1, SingResCalib)
                             }
                             else
                             {
-                                EXPECT_NEAR(ia * 100 * 16384 / IBASE, adc_stDownOut.swIaPu, 1.1 * 100 * 16384 / IBASE);
-                                EXPECT_NEAR(ib * 100 * 16384 / IBASE, adc_stDownOut.swIbPu, 1.1 * 100 * 16384 / IBASE);
-                                EXPECT_NEAR(ic * 100 * 16384 / IBASE, adc_stDownOut.swIcPu, 1.1 * 100 * 16384 / IBASE);
+                                EXPECT_NEAR(ia * 100 * 16384 / IBASE, adc_stDownOut.swIaPu, 1.5 * 100 * 16384 / IBASE); 
+                                EXPECT_NEAR(ib * 100 * 16384 / IBASE, adc_stDownOut.swIbPu, 1.5 * 100 * 16384 / IBASE);
+                                EXPECT_NEAR(ic * 100 * 16384 / IBASE, adc_stDownOut.swIcPu, 1.5 * 100 * 16384 / IBASE);
                             }
                         }
                     }

+ 1 - 1
xmake.lua

@@ -17,7 +17,7 @@ target("unittest")
     add_files("User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Source/macroequ.c","User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Source/glbcof.c")
     add_files("User project/3.BasicFunction/Source/Cadence.c", "User project/3.BasicFunction/Source/bikespeed.c", "User project/3.BasicFunction/Source/torquesensor.c")
     add_files("User project/2.MotorDrive/Source/adc.c", "User project/2.MotorDrive/Source/pwm.c", "User project/2.MotorDrive/Source/packed/torqobs.c")
-    add_files("User project/2.MotorDrive/Source/packed/pwrlim.c", "User project/2.MotorDrive/Source/packed/asr.c")
+    add_files("User project/2.MotorDrive/Source/packed/pwrlim.c", "User project/2.MotorDrive/Source/packed/asr.c", "User project/2.MotorDrive/Source/packed/brake.c")
     add_files("User project/3.BasicFunction/Source/Temp.c")