Bigpie wrote: ↑Tue Aug 30, 2022 8:07 am
Got a diff of your changes to MTPA? I'll do a build and have a test

Looking forward to having a play with the sim too, another bugbear for me is the sharp ending of braking regen when lifting off the pedal at slow speed, would be good to simulate and I can have a crack at fixing it.
Sorry, should have added it last night but it but it was getting late. Changes are:
In stm32_sine.cpp add this at the top:
and the FOC line in the Param::Change function:
Code: Select all
#if CONTROL == CTRL_FOC
PwmGeneration::SetControllerGains(Param::GetInt(Param::curkp), Param::GetInt(Param::curki), Param::GetInt(Param::fwkp));
Encoder::SwapSinCos((Param::GetInt(Param::pinswap) & SWAP_RESOLVER) > 0);
FOC::SetMtpaParams();
#endif // CONTROL
In foc.cpp replace the existing variable definitions at the top with these:
Code: Select all
static s32fp fluxLinkage = (Param::Get(Param::fluxlinkage)<<(CST_DIGITS-FRAC_DIGITS))/1000;
static u32fp fluxLinkage2 = FP_MUL(fluxLinkage, fluxLinkage);
static s32fp lqminusld = (Param::Get(Param::lqminusld)<<(CST_DIGITS-FRAC_DIGITS))/1000;
static u32fp lqminusldSquaredBs10 = FP_MUL(lqminusld<<14, lqminusld);//additional 14-bit left shift because otherwise it can't be represented
And the replace the FOC:Mtpa function with:
Code: Select all
/** \brief update the parameter values used by the MTPA routine, must be called from the Param::Change(Param::PARAM_NUM paramNum)
*/
void FOC::SetMtpaParams()
{
fluxLinkage = (Param::Get(Param::fluxlinkage)<<(CST_DIGITS-FRAC_DIGITS))/1000;
fluxLinkage2 = FP_MUL(fluxLinkage, fluxLinkage);
lqminusld = (Param::Get(Param::lqminusld)<<(CST_DIGITS-FRAC_DIGITS))/1000;
lqminusldSquaredBs10 = FP_MUL(lqminusld<<14, lqminusld);//additional 14-bit left shift because otherwise it can't be represented
}
/** \brief distribute motor current in magnetic torque and reluctance torque with the least total current
*
* \param[in] is int32_t total motor current
* \param[out] idref int32_t& resulting direct current reference
* \param[out] iqref int32_t& resulting quadrature current reference
* Equation being used is Id = (1/(4 x (Lq-Ld))) x (λ - sqrt(λ2 + (8 x Is2 x (Lq-Ld)2))))
*/
void FOC::Mtpa(int32_t is, int32_t& idref, int32_t& iqref)
{
uint32_t isSquared = (is * is);
uint32_t isSquaredFP = isSquared<<(CST_DIGITS-11); //convert to FP but less 1bits to prevent overflow
int32_t sign = is < 0 ? -1 : 1;
if(lqminusld != 0)
{
u32fp term1 = FP_MUL(lqminusldSquaredBs10,isSquaredFP); //Note - 11bit shift in current and 14bit in lqminusldSquaredBs10 gives x8 term)
u32fp term2 = fpsqrt(fluxLinkage2 + term1);
s32fp term3 = fluxLinkage - term2;
idref = term3/(lqminusld<<2); //no need for conversions here as FP_DIV and FP_TOINT cancel each other
}
else
idref = 0;
int32_t iSum = isSquared - (idref * idref);
if(iSum < 0) //equation should mean never goes negative but just in case
{ //so set -Id to max and Iq to zero
idref = -is;
iqref = 0;
}
else
iqref = sign * (int32_t)sqrt(isSquared - idref * idref);
}
And you will need the following MOTOR_PARAMETERS_FOC block in your param_prj.hfile
Code: Select all
#define MOTOR_PARAMETERS_FOC \
PARAM_ENTRY(CAT_MOTOR, curkp, "", 0, 20000, 2000, 107 ) \
PARAM_ENTRY(CAT_MOTOR, curki, "", 0, 100000, 50, 108 ) \
PARAM_ENTRY(CAT_MOTOR, curkifrqgain,"dig/Hz", 0, 1000, 50, 120 ) \
PARAM_ENTRY(CAT_MOTOR, fwkp, "", 0, 10000, 32, 118 ) \
PARAM_ENTRY(CAT_MOTOR, fwki, "", 0, 100000, 40, 141 ) \
PARAM_ENTRY(CAT_MOTOR, vlimkp, "", 0, 1000, 1, 142 ) \
PARAM_ENTRY(CAT_MOTOR, vlimki, "", 0, 10000, 0, 143 ) \
PARAM_ENTRY(CAT_MOTOR, ffwstart, "Hz", 0, 1000, 199, 136 ) \
PARAM_ENTRY(CAT_MOTOR, syncofs, "dig", 0, 65535, 0, 70 ) \
PARAM_ENTRY(CAT_MOTOR, syncadv, "dig/Hz", 0, 65535, 10, 133 ) \
PARAM_ENTRY(CAT_MOTOR, lqminusld, "mH", 0, 1000, 0, 139 ) \
PARAM_ENTRY(CAT_MOTOR, fluxlinkage, "mWeber", 0, 1000, 90, 140 )
These values work well in the simulation but may not be so good in the car!
Good luck with your testing
