Skip to content

Commit 67841f3

Browse files
committed
Merge branch 'anticogging' into syncadv_test
2 parents 35cec19 + 40367c7 commit 67841f3

File tree

10 files changed

+140
-57
lines changed

10 files changed

+140
-57
lines changed

include/hwdefs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
typedef enum
4747
{
48-
HW_REV1, HW_REV2, HW_REV3, HW_TESLA, HW_BLUEPILL, HW_PRIUS, HW_MINI, HW_LEAF2, HW_LEAF3, HW_BMWI3
48+
HW_REV1, HW_REV2, HW_REV3, HW_TESLA, HW_BLUEPILL, HW_PRIUS, HW_MINI, HW_LEAF2, HW_LEAF3, HW_BMWI3, HW_ZOE
4949
} HWREV;
5050

5151
extern HWREV hwRev;

include/param_prj.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
*/
1919

20-
#define VERSION 5.36
20+
#define VERSION 5.38
2121

2222
/* Entries should be ordered as follows:
2323
1. Saveable parameters
2424
2. Temporary parameters
2525
3. Display values
2626
*/
27-
//Next param id (increase when adding new parameter!): 159
28-
//Next value Id: 2055
27+
//Next param id (increase when adding new parameter!): 164
28+
//Next value Id: 2057
2929
/* category name unit min max default id */
3030

3131
#define MOTOR_PARAMETERS_COMMON \
@@ -53,9 +53,14 @@
5353
PARAM_ENTRY(CAT_MOTOR, iqkp, "", 0, 20000, 32, 107 ) \
5454
PARAM_ENTRY(CAT_MOTOR, idkp, "", 0, 20000, 32, 149 ) \
5555
PARAM_ENTRY(CAT_MOTOR, curki, "", 0, 100000, 20000, 108 ) \
56+
PARAM_ENTRY(CAT_MOTOR, exckp, "", 0, 20000, 3000, 162 ) \
57+
PARAM_ENTRY(CAT_MOTOR, cogkp, "", -1000, 1000, 0, 159 ) \
58+
PARAM_ENTRY(CAT_MOTOR, cogph, "", 0, 65535, 0, 160 ) \
59+
PARAM_ENTRY(CAT_MOTOR, cogmax, "", 0, 30000, 0, 161 ) \
5660
PARAM_ENTRY(CAT_MOTOR, vlimflt, "", 0, 16, 10, 145 ) \
5761
PARAM_ENTRY(CAT_MOTOR, vlimmargin, "dig", 0, 10000, 2500, 141 ) \
5862
PARAM_ENTRY(CAT_MOTOR, fwcurmax, "A", -1000, 0, -100, 144 ) \
63+
PARAM_ENTRY(CAT_MOTOR, excurmax, "A", 0, 10, 0, 163 ) \
5964
PARAM_ENTRY(CAT_MOTOR, syncofs, "dig", 0, 65535, 0, 70 ) \
6065
PARAM_ENTRY(CAT_MOTOR, lqminusld, "mH", 0, 1000, 0, 139 ) \
6166
PARAM_ENTRY(CAT_MOTOR, fluxlinkage, "mWeber", 0, 1000, 90, 140 ) \
@@ -68,7 +73,7 @@
6873
PARAM_ENTRY(CAT_INVERTER,ocurlim, "A", -65536, 65536, 100, 22 ) \
6974
PARAM_ENTRY(CAT_INVERTER,il1gain, "dig/A", -100, 100, 4.7, 27 ) \
7075
PARAM_ENTRY(CAT_INVERTER,il2gain, "dig/A", -100, 100, 4.7, 28 ) \
71-
PARAM_ENTRY(CAT_INVERTER,udcgain, "dig/V", 0, 4095, 6.175, 29 ) \
76+
PARAM_ENTRY(CAT_INVERTER,udcgain, "dig/V", -100, 100, 6.175, 29 ) \
7277
PARAM_ENTRY(CAT_INVERTER,udcofs, "dig", 0, 4095, 0, 77 ) \
7378
PARAM_ENTRY(CAT_INVERTER,udclim, "V", 0, 1000, 540, 48 ) \
7479
PARAM_ENTRY(CAT_INVERTER,snshs, SNS_HS, 0, 7, 0, 45 ) \
@@ -216,6 +221,8 @@
216221
VALUE_ENTRY(ifw, "A", 2048 ) \
217222
VALUE_ENTRY(ud, "dig", 2046 ) \
218223
VALUE_ENTRY(uq, "dig", 2047 ) \
224+
VALUE_ENTRY(uexc, "dig", 2056 ) \
225+
VALUE_ENTRY(anticog, "dig", 2055 ) \
219226

220227
#if CONTROL == CTRL_SINE
221228
#define PARAM_LIST \
@@ -264,7 +271,7 @@
264271
#define TRIPMODES "0=AllOff, 1=DcSwOn, 2=PrechargeOn, 3=AutoResume"
265272
#define SNS_HS "0=JCurve, 1=Semikron, 2=MBB600, 3=KTY81, 4=PT1000, 5=NTCK45_2k2, 6=Leaf, 7=BMW-i3"
266273
#define SNS_M "12=KTY83-110, 13=KTY84-130, 14=Leaf, 15=KTY81-110, 16=Toyota, 21=OutlanderFront, 22=EpcosB57861-S, 23=ToyotaGen2"
267-
#define PWMFUNCS "0=tmpm, 1=tmphs, 2=speed, 3=speedfrq"
274+
#define PWMFUNCS "0=tmpm, 1=tmphs, 2=speed, 3=exciter"
268275
#define SINECURVES "0=VoltageSlip, 1=Simultaneous"
269276
#define CRUISEMODS "0=Off, 1=Switch, 2=CAN, 3=ThrottlePot, 4=Limiter"
270277
#define DIRMODES "0=Button, 1=Switch, 2=ButtonReversed, 3=SwitchReversed, 4=DefaultForward"
@@ -277,7 +284,7 @@
277284
#define CANSPEEDS "0=125k, 1=250k, 2=500k, 3=800k, 4=1M"
278285
#define CANIOS "1=Cruise, 2=Start, 4=Brake, 8=Fwd, 16=Rev, 32=Bms"
279286
#define CANPERIODS "0=100ms, 1=10ms"
280-
#define HWREVS "0=Rev1, 1=Rev2, 2=Rev3, 3=Tesla, 4=BluePill, 5=Prius, 6=MiniMainboard, 7=Leaf2, 8=Leaf3, 9=BMWi3"
287+
#define HWREVS "0=Rev1, 1=Rev2, 2=Rev3, 3=Tesla, 4=BluePill, 5=Prius, 6=MiniMainboard, 7=Leaf2, 8=Leaf3, 9=BMWi3, 10=Zoe"
281288
#define SWAPS "0=None, 1=Currents12, 2=SinCos, 4=PWMOutput13, 8=PWMOutput23"
282289
#define OUTMODES "0=DcSw, 1=TmpmThresh, 2=TmphsThresh"
283290
#define STATUS "0=None, 1=UdcLow, 2=UdcHigh, 4=UdcBelowUdcSw, 8=UdcLim, 16=EmcyStop, 32=MProt, 64=PotPressed, 128=TmpHs, 256=WaitStart, 512=BrakeCheck"
@@ -344,7 +351,7 @@ enum _pwmfuncs
344351
PWM_FUNC_TMPM = 0,
345352
PWM_FUNC_TMPHS,
346353
PWM_FUNC_SPEED,
347-
PWM_FUNC_SPEEDFRQ
354+
PWM_FUNC_EXCITER
348355
};
349356

350357
enum _idlemodes

include/pwmgeneration.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ class PwmGeneration
3636
static void SetTorquePercent(float torque);
3737
static void SetCurrentOffset(int offset1, int offset2);
3838
static void SetCurrentLimitThreshold(s32fp ocurlim);
39-
static void SetControllerGains(int iqkp, int idkp, int ki);
39+
static void SetControllerGains(int iqkp, int idkp, int exckp, int ki);
4040
static int GetCpuLoad();
4141
static void SetChargeCurrent(float cur);
4242
static void SetPolePairRatio(int ratio) { polePairRatio = ratio; }
43-
static void SetFwCurMax(float c);
43+
static void SetFwExcCurMax(float fwcur, float excur);
4444

4545
private:
4646
enum EdgeType { NoEdge, PosEdge, NegEdge };

include/throttle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
class Throttle
2626
{
2727
public:
28-
static bool CheckAndLimitRange(int* potval, uint8_t potIdx);
28+
static bool CheckAndLimitRange(int& potval, uint8_t potIdx);
2929
static float DigitsToPercent(int potval, int potidx);
3030
static float CalcThrottle(float potval, float pot2val, bool brkpedal);
3131
static float CalcThrottleBiDir(float potval, bool brkpedal);

src/hwinit.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ static HWREV ReadVariantResistor()
139139
//See here for variants: https://openinverter.org/wiki/Mini_Mainboard#Hardware_detection
140140
if ((result1 + result2) < 30) return HW_BMWI3; //connected to MISO so always low
141141
else if (result2 > 3700) return HW_MINI; //might have to compare this against result1 later
142-
else if (result1 > 510 && result1 < 630) return HW_LEAF3;
142+
else if (result1 > 510 && result1 < 616) return HW_LEAF3;
143+
else if (result1 > 624 && result1 < 670) return HW_ZOE;
143144
else return HW_MINI;
144145
}
145146

src/pwmgeneration-foc.cpp

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@
3333

3434
#define FRQ_TO_ANGLE(frq) FP_TOINT((frq << SineCore::BITS) / pwmfrq)
3535
#define DIGIT_TO_DEGREE(a) FP_FROMINT(angle) / (65536 / 360)
36+
#define DEGREE_TO_DIGIT(a) (((a) * 65536) / 360)
3637

3738
#ifndef QLIMIT_FREQUENCY
3839
#define QLIMIT_FREQUENCY FP_FROMINT(30)
3940
#endif // QLIMIT_FREQUENCY
4041

42+
static s32fp MeasureCoggingCurrent(uint16_t angle, s32fp id);
43+
static int32_t GenerateAntiCoggingSignal(uint16_t angle, s32fp coggingCurrent);
4144
static int initwait = 0;
4245
static bool isIdle = false;
4346
static const s32fp dcCurFac = FP_FROMFLT(0.81649658092772603273 * 1.05); //sqrt(2/3)*1.05 (inverter losses)
@@ -46,7 +49,9 @@ static const uint32_t shiftForFilter = 8;
4649
static s32fp idMtpa = 0, iqMtpa = 0;
4750
static PiController qController;
4851
static PiController dController;
52+
static PiController excController;
4953
static s32fp fwCurMax = 0;
54+
static s32fp excCurMax = 0;
5055

5156
void PwmGeneration::Run()
5257
{
@@ -75,19 +80,38 @@ void PwmGeneration::Run()
7580
if (0 == frq) amplitudeErrFiltered = fwOutMax << shiftForFilter;
7681

7782
int vlim = amplitudeErrFiltered >> shiftForFilter;
78-
s32fp ifw = ((fwOutMax - vlim) * fwCurMax) / fwOutMax;
79-
Param::SetFixed(Param::ifw, ifw);
8083

81-
s32fp limitedIq = (vlim * iqMtpa) / fwOutMax;
82-
qController.SetRef(limitedIq + Param::Get(Param::manualiq));
83-
84-
s32fp limitedId = -2 * ABS(limitedIq); //ratio between idMtpa and iqMtpa never > 2
85-
limitedId = MAX(idMtpa, limitedId);
86-
limitedId = MIN(ifw, limitedId);
87-
dController.SetRef(limitedId + Param::Get(Param::manualid));
84+
if (hwRev == HW_ZOE)
85+
{
86+
s32fp exciterSpnt = (excCurMax * vlim) / fwOutMax;
87+
s32fp iexc = FP_DIV((AnaIn::udc.Get() - Param::GetInt(Param::udcofs)), Param::GetInt(Param::udcgain));
88+
Param::SetFixed(Param::ifw, iexc);
89+
dController.SetRef(idMtpa + Param::Get(Param::manualid));
90+
excController.SetRef(exciterSpnt);
91+
qController.SetRef(iqMtpa + Param::Get(Param::manualiq));
92+
uint16_t pwm = excController.Run(iexc);
93+
Param::SetInt(Param::uexc, pwm);
94+
timer_set_oc_value(OVER_CUR_TIMER, TIM_OC4, pwm);
95+
}
96+
else
97+
{
98+
s32fp ifw = ((fwOutMax - vlim) * fwCurMax) / fwOutMax;
99+
Param::SetFixed(Param::ifw, ifw);
100+
101+
s32fp limitedIq = (vlim * iqMtpa) / fwOutMax;
102+
qController.SetRef(limitedIq + Param::Get(Param::manualiq));
103+
104+
s32fp limitedId = -2 * ABS(limitedIq); //ratio between idMtpa and iqMtpa never > 2
105+
limitedId = MAX(idMtpa, limitedId);
106+
limitedId = MIN(ifw, limitedId);
107+
dController.SetRef(limitedId + Param::Get(Param::manualid));
108+
}
88109
}
89110

90-
int32_t ud = dController.Run(id);
111+
s32fp coggingCurrent = MeasureCoggingCurrent(angle, id);
112+
int32_t antiCogScaled = GenerateAntiCoggingSignal(angle, coggingCurrent);
113+
Param::SetInt(Param::anticog, antiCogScaled);
114+
int32_t ud = dController.Run(id, antiCogScaled);
91115
int32_t qlimit = FOC::GetQLimit(ud);
92116

93117
if (frqFiltered < QLIMIT_FREQUENCY)
@@ -117,8 +141,10 @@ void PwmGeneration::Run()
117141
if (isIdle || initwait > 0)
118142
{
119143
timer_disable_break_main_output(PWM_TIMER);
144+
//timer_set_oc_value(OVER_CUR_TIMER, TIM_OC4, 0); //stop rotor excitation
120145
dController.ResetIntegrator();
121146
qController.ResetIntegrator();
147+
//excController.ResetIntegrator();
122148
RunOffsetCalibration();
123149
amplitudeErrFiltered = fwOutMax << shiftForFilter;
124150
}
@@ -144,9 +170,10 @@ void PwmGeneration::Run()
144170
}
145171
}
146172

147-
void PwmGeneration::SetFwCurMax(float cur)
173+
void PwmGeneration::SetFwExcCurMax(float fwcur, float excur)
148174
{
149-
fwCurMax = FP_FROMFLT(cur);
175+
fwCurMax = FP_FROMFLT(fwcur);
176+
excCurMax = FP_FROMFLT(excur);
150177
}
151178

152179
void PwmGeneration::SetTorquePercent(float torquePercent)
@@ -167,10 +194,11 @@ void PwmGeneration::SetTorquePercent(float torquePercent)
167194
idMtpa = FP_FROMFLT(id);
168195
}
169196

170-
void PwmGeneration::SetControllerGains(int iqkp, int idkp, int ki)
197+
void PwmGeneration::SetControllerGains(int iqkp, int idkp, int exckp, int ki)
171198
{
172199
qController.SetGains(iqkp, ki);
173200
dController.SetGains(idkp, ki);
201+
excController.SetGains(exckp, 1000);
174202
}
175203

176204
void PwmGeneration::PwmInit()
@@ -185,6 +213,8 @@ void PwmGeneration::PwmInit()
185213
dController.ResetIntegrator();
186214
dController.SetCallingFrequency(pwmfrq);
187215
dController.SetMinMaxY(-maxVd, maxVd);
216+
excController.SetCallingFrequency(pwmfrq);
217+
excController.SetMinMaxY(0, 2048);
188218

189219
if (opmode == MOD_ACHEAT)
190220
AcHeatTimerSetup();
@@ -217,7 +247,7 @@ s32fp PwmGeneration::ProcessCurrents(s32fp& id, s32fp& iq)
217247

218248
void PwmGeneration::CalcNextAngleSync()
219249
{
220-
if (Encoder::SeenNorthSignal())
250+
if (true)
221251
{
222252
uint16_t syncOfs = Param::GetInt(Param::syncofs);
223253
uint16_t rotorAngle = Encoder::GetRotorAngle();
@@ -250,3 +280,54 @@ void PwmGeneration::RunOffsetCalibration()
250280
samples = 0;
251281
}
252282
}
283+
284+
static s32fp MeasureCoggingCurrent(uint16_t angle, s32fp id)
285+
{
286+
static uint16_t previousAngle = 0;
287+
static s32fp minId = 0x7fffffff, maxId = -0x7fffffff;
288+
static s32fp coggingCurrent = 0;
289+
290+
if (previousAngle < 32767 && angle > 32767)
291+
{
292+
coggingCurrent = ABS(minId - maxId);
293+
minId = 0x7fffffff;
294+
maxId = -minId;
295+
}
296+
else
297+
{
298+
minId = MIN(id, minId);
299+
maxId = MAX(id, maxId);
300+
}
301+
previousAngle = angle;
302+
return coggingCurrent;
303+
}
304+
305+
/** \brief Generates a trapezoidal wave form to counter the cogging current of IPM motors
306+
*
307+
* \param angle rotor angle
308+
* \param coggingCurrent magnitude of cogging current in A
309+
* \return int32_t counter waveform as integer
310+
*
311+
*/
312+
static int32_t GenerateAntiCoggingSignal(uint16_t angle, s32fp coggingCurrent)
313+
{
314+
angle += Param::GetInt(Param::cogph);
315+
316+
if (angle < DEGREE_TO_DIGIT(90))
317+
angle = angle; //no change
318+
else if (angle < DEGREE_TO_DIGIT(180)) //90 to 180°
319+
angle = 32767 - angle;
320+
else if (angle < DEGREE_TO_DIGIT(270)) //180 to 270°
321+
angle = angle - 32767;
322+
else //270 to 360°
323+
angle = 65535 - angle;
324+
325+
uint16_t antiCog = 4 * angle;
326+
int32_t antiCogScaled = ((int32_t)antiCog) - 32767;
327+
int32_t antiCogMax = Param::GetInt(Param::cogmax);
328+
antiCogScaled = (antiCogScaled * FP_TOINT(coggingCurrent) * Param::GetInt(Param::cogkp)) / 65536;
329+
antiCogScaled = MIN(antiCogScaled, antiCogMax);
330+
antiCogScaled = MAX(antiCogScaled, -antiCogMax);
331+
332+
return antiCogScaled;
333+
}

src/stm32_sine.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,10 @@ void Param::Change(Param::PARAM_NUM paramNum)
310310
PwmGeneration::SetPolePairRatio(Param::GetInt(Param::polepairs) / Param::GetInt(Param::respolepairs));
311311

312312
#if CONTROL == CTRL_FOC
313-
PwmGeneration::SetControllerGains(Param::GetInt(Param::iqkp), Param::GetInt(Param::idkp), Param::GetInt(Param::curki));
313+
PwmGeneration::SetControllerGains(Param::GetInt(Param::iqkp),
314+
Param::GetInt(Param::idkp),
315+
Param::GetInt(Param::exckp),
316+
Param::GetInt(Param::curki));
314317
Encoder::SwapSinCos((Param::GetInt(Param::pinswap) & SWAP_RESOLVER) > 0);
315318
FOC::SetMotorParameters(Param::GetFloat(Param::lqminusld) / 1000.0f, Param::GetFloat(Param::fluxlinkage) / 1000.0f);
316319
FOC::SetMaximumModulationIndex(Param::GetInt(Param::modmax));
@@ -350,10 +353,7 @@ void Param::Change(Param::PARAM_NUM paramNum)
350353

351354
if (hwRev != HW_BLUEPILL)
352355
{
353-
if (Param::GetInt(Param::pwmfunc) == PWM_FUNC_SPEEDFRQ)
354-
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO9);
355-
else
356-
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
356+
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
357357
}
358358
break;
359359
}

src/terminal_prj.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,20 @@ extern "C" const TERM_CMD TermCmds[] =
5757
{ NULL, NULL }
5858
};
5959

60-
static void LoadDefaults(Terminal* term, char *arg)
60+
static void LoadDefaults(Terminal* , char *)
6161
{
62-
arg = arg;
63-
term = term;
6462
Param::LoadDefaults();
6563
printf("Defaults loaded\r\n");
6664
}
6765

68-
static void StopInverter(Terminal* term, char *arg)
66+
static void StopInverter(Terminal*, char *)
6967
{
70-
arg = arg;
71-
term = term;
7268
Param::SetInt(Param::opmode, 0);
7369
printf("Inverter halted.\r\n");
7470
}
7571

76-
static void StartInverter(Terminal* term, char *arg)
72+
static void StartInverter(Terminal* , char *arg)
7773
{
78-
term = term;
7974
arg = my_trim(arg);
8075
#if CONTROL == CTRL_SINE
8176
int val = my_atoi(arg);
@@ -94,17 +89,13 @@ static void StartInverter(Terminal* term, char *arg)
9489
#endif
9590
}
9691

97-
static void PrintErrors(Terminal* term, char *arg)
92+
static void PrintErrors(Terminal* , char *)
9893
{
99-
term = term;
100-
arg = arg;
10194
ErrorMessage::PrintAllErrors();
10295
}
10396

104-
static void PrintSerial(Terminal* term, char *arg)
97+
static void PrintSerial(Terminal* , char *)
10598
{
106-
arg = arg;
107-
term = term;
10899
printf("%X:%X:%X\r\n", DESIG_UNIQUE_ID2, DESIG_UNIQUE_ID1, DESIG_UNIQUE_ID0);
109100
}
110101

0 commit comments

Comments
 (0)