1
- #include " BLDCMotor .h"
1
+ #include " SimpleFOC .h"
2
2
3
3
4
4
/*
@@ -20,30 +20,32 @@ BLDCMotor::BLDCMotor(int phA, int phB, int phC, int pp, int en)
20
20
// enable_pin pin
21
21
enable_pin = en;
22
22
23
+ // Power supply woltage
24
+ power_supply_voltage = DEF_POWER_SUPPLY;
25
+
23
26
// Velocity loop config
24
27
// PI contoroller constant
25
- PI_velocity.K = 0.4 ;
26
- PI_velocity.Ti = 0.005 ;
28
+ PI_velocity.K = DEF_PI_VEL_K ;
29
+ PI_velocity.Ti = DEF_PI_VEL_TI ;
27
30
PI_velocity.timestamp = micros ();
31
+ PI_velocity.u_limit = DEF_POWER_SUPPLY;
28
32
29
33
// Ultra slow velocity
30
34
// PI contoroller
31
- PI_velocity_ultra_slow.K = 120.0 ;
32
- PI_velocity_ultra_slow.Ti = 100.0 ;
35
+ PI_velocity_ultra_slow.K = DEF_PI_VEL_US_K ;
36
+ PI_velocity_ultra_slow.Ti = DEF_PI_VEL_US_TI ;
33
37
PI_velocity_ultra_slow.timestamp = micros ();
38
+ PI_velocity_ultra_slow.u_limit = DEF_POWER_SUPPLY;
34
39
35
40
// position loop config
36
41
// P controller constant
37
- P_angle.K = 15 ;
38
-
39
- // Power supply woltage
40
- U_max = 12 ;
42
+ P_angle.K = DEF_P_ANGLE_K;
41
43
// maximum angular velocity to be used for positioning
42
- velocity_max = 20 ;
44
+ P_angle. velocity_limit = DEF_P_ANGLE_VEL_LIM ;
43
45
}
44
46
45
47
// init hardware pins
46
- void BLDCMotor::init (DriverType type ) {
48
+ void BLDCMotor::init () {
47
49
// PWM pins
48
50
pinMode (pwmA, OUTPUT);
49
51
pinMode (pwmB, OUTPUT);
@@ -57,7 +59,7 @@ void BLDCMotor::init(DriverType type) {
57
59
setPwmFrequency (pwmB);
58
60
setPwmFrequency (pwmC);
59
61
60
- driver_type = type ;
62
+ driver = DriverType::bipolar ;
61
63
62
64
delay (500 );
63
65
}
@@ -107,10 +109,12 @@ void BLDCMotor::linkEncoder(Encoder* enc) {
107
109
Encoder alignment to electrical 0 angle
108
110
*/
109
111
void BLDCMotor::alignEncoder () {
110
- setPhaseVoltage (12 , M_PI / 2 );
112
+ setPhaseVoltage (12 , - M_PI/ 2 );
111
113
delay (1000 );
112
114
encoder->setCounterZero ();
113
- setPhaseVoltage (0 , M_PI / 2 );
115
+
116
+
117
+ setPhaseVoltage (0 , 0 );
114
118
}
115
119
116
120
/* *
@@ -131,7 +135,8 @@ float BLDCMotor::electricAngle(float shaftAngle) {
131
135
return normalizeAngle (shaftAngle * pole_pairs);
132
136
}
133
137
/*
134
- Update motor angles and set thr Uq voltage
138
+ Iterative function looping FOC algorithm, setting Uq on the Motor
139
+ The faster it can be run the better
135
140
*/
136
141
void BLDCMotor::loopFOC () {
137
142
// voltage open loop loop
@@ -140,7 +145,10 @@ void BLDCMotor::loopFOC() {
140
145
}
141
146
142
147
/*
143
- Update motor angles and velocities
148
+ Iterative funciton running outer loop of the FOC algorithm
149
+ Bahvior of this funciton is determined by the motor.controller variable
150
+ It runs either angle, veloctiy, velocity ultra slow or voltage loop
151
+ - needs to be called iteratively it is asynchronious function
144
152
*/
145
153
void BLDCMotor::move (float target) {
146
154
// get angular velocity
@@ -176,6 +184,7 @@ void BLDCMotor::move(float target) {
176
184
*/
177
185
/*
178
186
Method using FOC to set Uq to the motor at the optimal angle
187
+ - for unipolar drivers - only positive values
179
188
*/
180
189
void BLDCMotor::setPhaseVoltageUnipolar (double Uq, double angle_el) {
181
190
@@ -212,12 +221,14 @@ void BLDCMotor::setPhaseVoltageUnipolar(double Uq, double angle_el) {
212
221
}
213
222
/*
214
223
Method using FOC to set Uq to the motor at the optimal angle
224
+ - for bipolar drivers - posiitve and negative voltages
215
225
*/
216
226
void BLDCMotor::setPhaseVoltageBipolar (double Uq, double angle_el) {
217
227
228
+ // q component angle
229
+ float angle = angle_el + M_PI/2 ;
218
230
// Uq sign compensation
219
- float angle;// = angle + shaft_velocity*0.0003;
220
- angle = Uq > 0 ? angle_el : normalizeAngle ( angle_el + M_PI );
231
+ angle = Uq > 0 ? angle : normalizeAngle ( angle + M_PI );
221
232
222
233
// Park transform
223
234
Ualpha = abs (Uq) * cos (angle);
@@ -239,7 +250,7 @@ void BLDCMotor::setPhaseVoltageBipolar(double Uq, double angle_el) {
239
250
Method using FOC to set Uq to the motor at the optimal angle
240
251
*/
241
252
void BLDCMotor::setPhaseVoltage (double Uq, double angle_el) {
242
- switch (driver_type ) {
253
+ switch (driver ) {
243
254
case DriverType::bipolar :
244
255
// L6234
245
256
setPhaseVoltageBipolar (Uq, angle_el);
@@ -251,13 +262,15 @@ void BLDCMotor::setPhaseVoltage(double Uq, double angle_el) {
251
262
}
252
263
}
253
264
265
+
254
266
/*
255
267
Set voltage to the pwm pin
256
268
*/
257
269
void BLDCMotor::setPwm (int pinPwm, float U) {
258
270
int U_pwm = 0 ;
271
+ int U_max = power_supply_voltage;
259
272
// uniploar or bipolar FOC
260
- switch (driver_type ) {
273
+ switch (driver ) {
261
274
case DriverType::bipolar :
262
275
// sets the voltage [-U_max,U_max] to pwm [0,255]
263
276
// - U_max you can set in header file - default 12V
@@ -291,38 +304,25 @@ double BLDCMotor::normalizeAngle(double angle)
291
304
double a = fmod (angle, 2 * M_PI);
292
305
return a >= 0 ? a : (a + 2 * M_PI);
293
306
}
294
- /*
295
- Reference low pass filter
296
- used to filter set point signal - to remove sharp changes
297
- */
298
- float BLDCMotor::filterLP (float u) {
299
- static float Ts, yk_1;
300
- float M_Tau = 0.01 ;
301
- Ts = (micros () - Ts) * 1e-6 ;
302
- float y_k = Ts / (M_Tau + Ts) * u + (1 - Ts / (M_Tau + Ts)) * yk_1;
303
- Ts = micros ();
304
- yk_1 = y_k;
305
- return y_k;
306
- }
307
307
308
308
309
309
310
310
311
311
/* *
312
- Motor `ntrol functions
312
+ Motor control functions
313
313
*/
314
314
float BLDCMotor::velocityPI (float ek) {
315
315
float Ts = (micros () - PI_velocity.timestamp ) * 1e-6 ;
316
316
317
317
// u(s) = Kr(1 + 1/(Ti.s))
318
318
float uk = PI_velocity.uk_1 ;
319
319
uk += PI_velocity.K * (Ts / (2 * PI_velocity.Ti ) + 1 ) * ek + PI_velocity.K * (Ts / (2 * PI_velocity.Ti ) - 1 ) * PI_velocity.ek_1 ;
320
- if (abs (uk) > U_max ) uk = uk > 0 ? U_max : -U_max ;
320
+ if (abs (uk) > PI_velocity. u_limit ) uk = uk > 0 ? PI_velocity. u_limit : -PI_velocity. u_limit ;
321
321
322
322
PI_velocity.uk_1 = uk;
323
323
PI_velocity.ek_1 = ek;
324
324
PI_velocity.timestamp = micros ();
325
- return - uk;
325
+ return uk;
326
326
}
327
327
328
328
// PI controller for ultra slow velocity control
@@ -336,53 +336,20 @@ float BLDCMotor::velocityUltraSlowPI(float vel) {
336
336
// u(s) = Kr(1 + 1/(Ti.s))
337
337
float uk = PI_velocity_ultra_slow.uk_1 ;
338
338
uk += PI_velocity_ultra_slow.K * (Ts / (2 * PI_velocity_ultra_slow.Ti ) + 1 ) * ek + PI_velocity_ultra_slow.K * (Ts / (2 * PI_velocity_ultra_slow.Ti ) - 1 ) * PI_velocity_ultra_slow.ek_1 ;
339
- if (abs (uk) > U_max ) uk = uk > 0 ? U_max : -U_max ;
339
+ if (abs (uk) > PI_velocity_ultra_slow. u_limit ) uk = uk > 0 ? PI_velocity_ultra_slow. u_limit : -PI_velocity_ultra_slow. u_limit ;
340
340
341
341
PI_velocity_ultra_slow.uk_1 = uk;
342
342
PI_velocity_ultra_slow.ek_1 = ek;
343
343
PI_velocity_ultra_slow.timestamp = micros ();
344
- return - uk;
344
+ return uk;
345
345
}
346
346
// P controller for position control loop
347
347
float BLDCMotor::positionP (float ek) {
348
348
float velk = P_angle.K * ek;
349
- if (abs (velk) > velocity_max ) velk = velk > 0 ? velocity_max : -velocity_max ;
349
+ if (abs (velk) > P_angle. velocity_limit ) velk = velk > 0 ? P_angle. velocity_limit : -P_angle. velocity_limit ;
350
350
return velk;
351
351
}
352
352
353
- // voltage control loop api
354
- void BLDCMotor::setVoltage (float Uq) {
355
- voltage_q = Uq;
356
- }
357
- // shaft velocity loop api
358
- void BLDCMotor::setVelocity (float vel) {
359
- shaft_velocity_sp = vel;
360
- }
361
-
362
- // utra slow shaft velocity loop api
363
- void BLDCMotor::setVelocityUltraSlow (float vel) {
364
- shaft_velocity_sp = vel;
365
-
366
- shaft_velocity = shaftVelocity ();
367
- static long timestamp;
368
- static float angle_1;
369
- if (!timestamp) {
370
- // init
371
- timestamp = micros ();
372
- angle_1 = shaft_angle;
373
- }
374
- float dt = (micros () - timestamp) / 1e6 ;
375
- angle_1 += vel * dt;
376
- voltage_q = velocityUltraSlowPI (angle_1 - shaft_angle);
377
- timestamp = micros ();
378
- }
379
-
380
- // postion control loop
381
- void BLDCMotor::setPosition (float pos) {
382
- shaft_angle_sp = pos;
383
- }
384
-
385
-
386
353
387
354
/*
388
355
High PWM frequency
0 commit comments