@@ -29,7 +29,7 @@ void BLDCMotor::linkDriver(BLDCDriver* _driver) {
29
29
driver = _driver;
30
30
}
31
31
32
- // init hardware pins
32
+ // init hardware pins
33
33
void BLDCMotor::init () {
34
34
if (monitor_port) monitor_port->println (" MOT: Initialise variables." );
35
35
// sanity check for the voltage limit configuration
@@ -53,13 +53,13 @@ void BLDCMotor::disable()
53
53
{
54
54
// set zero to PWM
55
55
driver->setPwm (0 , 0 , 0 );
56
- // disable the driver
56
+ // disable the driver
57
57
driver->disable ();
58
58
}
59
59
// enable motor driver
60
60
void BLDCMotor::enable ()
61
61
{
62
- // enable the driver
62
+ // enable the driver
63
63
driver->enable ();
64
64
// set zero to PWM
65
65
driver->setPwm (0 , 0 , 0 );
@@ -93,7 +93,7 @@ int BLDCMotor::initFOC( float zero_electric_offset, Direction sensor_direction
93
93
int BLDCMotor::alignSensor () {
94
94
if (monitor_port) monitor_port->println (" MOT: Align sensor." );
95
95
// align the electrical phases of the motor and sensor
96
- // set angle -90 degrees
96
+ // set angle -90 degrees
97
97
98
98
float start_angle = shaftAngle ();
99
99
for (int i = 0 ; i <=5 ; i++ ) {
@@ -134,19 +134,19 @@ int BLDCMotor::alignSensor() {
134
134
}
135
135
136
136
137
- // Encoder alignment the absolute zero angle
137
+ // Encoder alignment the absolute zero angle
138
138
// - to the index
139
139
int BLDCMotor::absoluteZeroAlign () {
140
140
141
141
if (monitor_port) monitor_port->println (" MOT: Absolute zero align." );
142
142
// if no absolute zero return
143
143
if (!sensor->hasAbsoluteZero ()) return 0 ;
144
-
144
+
145
145
146
146
if (monitor_port && sensor->needsAbsoluteZeroSearch ()) monitor_port->println (" MOT: Searching..." );
147
147
// search the absolute zero with small velocity
148
148
while (sensor->needsAbsoluteZeroSearch () && shaft_angle < _2PI){
149
- loopFOC ();
149
+ loopFOC ();
150
150
voltage_q = PID_velocity (velocity_index_search - shaftVelocity ());
151
151
}
152
152
voltage_q = 0 ;
@@ -167,9 +167,9 @@ int BLDCMotor::absoluteZeroAlign() {
167
167
// Iterative function looping FOC algorithm, setting Uq on the Motor
168
168
// The faster it can be run the better
169
169
void BLDCMotor::loopFOC () {
170
- // shaft angle
170
+ // shaft angle
171
171
shaft_angle = shaftAngle ();
172
- // set the phase voltage - FOC heart function :)
172
+ // set the phase voltage - FOC heart function :)
173
173
setPhaseVoltage (voltage_q, voltage_d, _electricalAngle (shaft_angle,pole_pairs));
174
174
}
175
175
@@ -219,7 +219,7 @@ void BLDCMotor::move(float new_target) {
219
219
220
220
// Method using FOC to set Uq and Ud to the motor at the optimal angle
221
221
// Function implementing Space Vector PWM and Sine PWM algorithms
222
- //
222
+ //
223
223
// Function using sine approximation
224
224
// regular sin + cos ~300us (no memory usaage)
225
225
// approx _sin + _cos ~110us (400Byte ~ 20% of memory)
@@ -257,7 +257,7 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
257
257
};
258
258
// static int trap_150_state = 0;
259
259
sector = 12 * (_normalizeAngle (angle_el + PI/6.0 + zero_electric_angle) / _2PI); // adding PI/6 to align with other modes
260
-
260
+
261
261
Ua = Uq + trap_150_map[sector][0 ] * Uq;
262
262
Ub = Uq + trap_150_map[sector][1 ] * Uq;
263
263
Uc = Uq + trap_150_map[sector][2 ] * Uq;
@@ -272,7 +272,7 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
272
272
break ;
273
273
274
274
case FOCModulationType::SinePWM :
275
- // Sinusoidal PWM modulation
275
+ // Sinusoidal PWM modulation
276
276
// Inverse Park + Clarke transformation
277
277
278
278
// angle normalization in between 0 and 2pi
@@ -299,10 +299,10 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
299
299
break ;
300
300
301
301
case FOCModulationType::SpaceVectorPWM :
302
- // Nice video explaining the SpaceVectorModulation (SVPWM) algorithm
302
+ // Nice video explaining the SpaceVectorModulation (SVPWM) algorithm
303
303
// https://www.youtube.com/watch?v=QMSWUMEAejg
304
304
305
- // if negative voltages change inverse the phase
305
+ // if negative voltages change inverse the phase
306
306
// angle + 180degrees
307
307
if (Uq < 0 ) angle_el += _PI;
308
308
Uq = abs (Uq);
@@ -316,14 +316,14 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
316
316
// calculate the duty cycles
317
317
float T1 = _SQRT3*_sin (sector*_PI_3 - angle_el) * Uq/driver->voltage_limit ;
318
318
float T2 = _SQRT3*_sin (angle_el - (sector-1.0 )*_PI_3) * Uq/driver->voltage_limit ;
319
- // two versions possible
319
+ // two versions possible
320
320
float T0 = 0 ; // pulled to 0 - better for low power supply voltage
321
- if (centered) {
321
+ if (centered) {
322
322
T0 = 1 - T1 - T2; // centered around driver->voltage_limit/2
323
- }
323
+ }
324
324
325
325
// calculate the duty cycles(times)
326
- float Ta,Tb,Tc;
326
+ float Ta,Tb,Tc;
327
327
switch (sector){
328
328
case 1 :
329
329
Ta = T1 + T2 + T0/2 ;
@@ -369,7 +369,7 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
369
369
break ;
370
370
371
371
}
372
-
372
+
373
373
// set the voltages in driver
374
374
driver->setPwm (Ua, Ub, Uc);
375
375
}
@@ -386,7 +386,13 @@ void BLDCMotor::velocityOpenloop(float target_velocity){
386
386
float Ts = (now_us - open_loop_timestamp) * 1e-6 ;
387
387
388
388
// calculate the necessary angle to achieve target velocity
389
- shaft_angle += target_velocity*Ts;
389
+ shaft_angle += target_velocity*Ts;
390
+
391
+ // check if shaft_angle gets too large
392
+ if (shaft_angle >= (_2PI * 4 ))
393
+ {
394
+ shaft_angle = 0 ;
395
+ }
390
396
391
397
// set the maximal allowed voltage (voltage_limit) with the necessary angle
392
398
setPhaseVoltage (voltage_limit, 0 , _electricalAngle (shaft_angle, pole_pairs));
@@ -403,17 +409,17 @@ void BLDCMotor::angleOpenloop(float target_angle){
403
409
unsigned long now_us = _micros ();
404
410
// calculate the sample time from last call
405
411
float Ts = (now_us - open_loop_timestamp) * 1e-6 ;
406
-
412
+
407
413
// calculate the necessary angle to move from current position towards target angle
408
414
// with maximal velocity (velocity_limit)
409
415
if (abs ( target_angle - shaft_angle ) > abs (velocity_limit*Ts))
410
- shaft_angle += _sign (target_angle - shaft_angle) * abs ( velocity_limit )*Ts;
416
+ shaft_angle += _sign (target_angle - shaft_angle) * abs ( velocity_limit )*Ts;
411
417
else
412
418
shaft_angle = target_angle;
413
-
419
+
414
420
// set the maximal allowed voltage (voltage_limit) with the necessary angle
415
421
setPhaseVoltage (voltage_limit, 0 , _electricalAngle (shaft_angle, pole_pairs));
416
422
417
423
// save timestamp for next call
418
424
open_loop_timestamp = now_us;
419
- }
425
+ }
0 commit comments