@@ -24,7 +24,6 @@ BLDCMotor::BLDCMotor(int phA, int phB, int phC, int pp, int en)
24
24
PI_velocity.P = DEF_PI_VEL_P;
25
25
PI_velocity.I = DEF_PI_VEL_I;
26
26
PI_velocity.timestamp = _micros ();
27
- PI_velocity.voltage_limit = voltage_power_supply;
28
27
PI_velocity.voltage_ramp = DEF_PI_VEL_U_RAMP;
29
28
PI_velocity.voltage_prev = 0 ;
30
29
PI_velocity.tracking_error_prev = 0 ;
@@ -37,8 +36,11 @@ BLDCMotor::BLDCMotor(int phA, int phB, int phC, int pp, int en)
37
36
// position loop config
38
37
// P controller constant
39
38
P_angle.P = DEF_P_ANGLE_P;
39
+
40
40
// maximum angular velocity to be used for positioning
41
- P_angle.velocity_limit = DEF_P_ANGLE_VEL_LIM;
41
+ velocity_limit = DEF_P_ANGLE_VEL_LIM;
42
+ // maximum voltage to be set to the motor
43
+ voltage_limit = voltage_power_supply;
42
44
43
45
// index search velocity
44
46
velocity_index_search = DEF_INDEX_SEARCH_TARGET_VELOCITY;
@@ -56,6 +58,8 @@ BLDCMotor::BLDCMotor(int phA, int phB, int phC, int pp, int en)
56
58
57
59
// monitor_port
58
60
monitor_port = nullptr ;
61
+ // sensor
62
+ sensor = nullptr ;
59
63
}
60
64
61
65
// init hardware pins
@@ -73,7 +77,7 @@ void BLDCMotor::init() {
73
77
_setPwmFrequency (pwmA, pwmB, pwmC);
74
78
75
79
// sanity check for the voltage limit configuration
76
- if (PI_velocity. voltage_limit > voltage_power_supply) PI_velocity. voltage_limit = voltage_power_supply;
80
+ if (voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
77
81
78
82
_delay (500 );
79
83
// enable motor
@@ -187,10 +191,14 @@ int BLDCMotor::absoluteZeroAlign() {
187
191
*/
188
192
// shaft angle calculation
189
193
float BLDCMotor::shaftAngle () {
194
+ // if no sensor linked return 0
195
+ // if(!sensor) return 0;
190
196
return sensor->getAngle ();
191
197
}
192
198
// shaft velocity calculation
193
199
float BLDCMotor::shaftVelocity () {
200
+ // if no sensor linked return 0
201
+ // if(!sensor) return 0;
194
202
float Ts = (_micros () - LPF_velocity.timestamp ) * 1e-6 ;
195
203
// quick fix for strange cases (micros overflow)
196
204
if (Ts <= 0 || Ts > 0.5 ) Ts = 1e-3 ;
@@ -269,6 +277,18 @@ void BLDCMotor::move(float new_target) {
269
277
shaft_velocity_sp = target;
270
278
voltage_q = velocityPI (shaft_velocity_sp - shaft_velocity);
271
279
break ;
280
+ case ControlType::velocity_openloop:
281
+ // velocity control in open loop
282
+ // loopFOC should not be called
283
+ shaft_velocity_sp = target;
284
+ velocityOpenloop (shaft_velocity_sp);
285
+ break ;
286
+ case ControlType::angle_openloop:
287
+ // angle control in open loop
288
+ // loopFOC should not be called
289
+ shaft_angle_sp = target;
290
+ angleOpenloop (shaft_angle_sp);
291
+ break ;
272
292
}
273
293
}
274
294
@@ -364,9 +384,9 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
364
384
}
365
385
366
386
// calculate the phase voltages and center
367
- Ua = Ta*voltage_power_supply;// + (voltage_power_supply - Uq) / 2;
368
- Ub = Tb*voltage_power_supply;// + (voltage_power_supply - Uq) / 2;
369
- Uc = Tc*voltage_power_supply;// + (voltage_power_supply - Uq) / 2;
387
+ Ua = Ta*voltage_power_supply;
388
+ Ub = Tb*voltage_power_supply;
389
+ Uc = Tc*voltage_power_supply;
370
390
break ;
371
391
}
372
392
@@ -376,14 +396,13 @@ void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
376
396
377
397
378
398
379
-
380
399
// Set voltage to the pwm pin
381
400
void BLDCMotor::setPwm (float Ua, float Ub, float Uc) {
382
401
// calculate duty cycle
383
402
// limited in [0,1]
384
- float dc_a = (Ua < 0 ) ? 0 : (Ua >= voltage_power_supply) ? 1 : Ua / voltage_power_supply;
385
- float dc_b = (Ub < 0 ) ? 0 : (Ub >= voltage_power_supply) ? 1 : Ub / voltage_power_supply;
386
- float dc_c = (Uc < 0 ) ? 0 : (Uc >= voltage_power_supply) ? 1 : Uc / voltage_power_supply;
403
+ float dc_a = constrain (Ua / voltage_power_supply, 0 , 1 );
404
+ float dc_b = constrain (Ub / voltage_power_supply, 0 , 1 );
405
+ float dc_c = constrain (Uc / voltage_power_supply, 0 , 1 );
387
406
// hardware specific writing
388
407
_writeDutyCycle (dc_a, dc_b, dc_c, pwmA, pwmB, pwmC );
389
408
}
@@ -419,7 +438,7 @@ float BLDCMotor::controllerPI(float tracking_error, PI_s& cont){
419
438
float voltage = cont.voltage_prev + (tmp + cont.P ) * tracking_error + (tmp - cont.P ) * cont.tracking_error_prev ;
420
439
421
440
// antiwindup - limit the output voltage_q
422
- if ( abs ( voltage) > cont. voltage_limit ) voltage = voltage > 0 ? cont. voltage_limit : -cont. voltage_limit ;
441
+ voltage = constrain ( voltage, - voltage_limit, voltage_limit) ;
423
442
// limit the acceleration by ramping the the voltage
424
443
float d_voltage = voltage - cont.voltage_prev ;
425
444
if (abs (d_voltage)/Ts > cont.voltage_ramp ) voltage = d_voltage > 0 ? cont.voltage_prev + cont.voltage_ramp *Ts : cont.voltage_prev - cont.voltage_ramp *Ts;
@@ -440,10 +459,51 @@ float BLDCMotor::positionP(float ek) {
440
459
// calculate the target velocity from the position error
441
460
float velocity_target = P_angle.P * ek;
442
461
// constrain velocity target value
443
- if ( abs ( velocity_target) > P_angle. velocity_limit ) velocity_target = velocity_target > 0 ? P_angle. velocity_limit : -P_angle. velocity_limit ;
462
+ velocity_target = constrain ( velocity_target, - velocity_limit, velocity_limit) ;
444
463
return velocity_target;
445
464
}
446
465
466
+ // Function (iterative) generating open loop movement for target velocity
467
+ // - target_velocity - rad/s
468
+ // it uses voltage_limit variable
469
+ void BLDCMotor::velocityOpenloop (float target_velocity){
470
+ // get current timestamp
471
+ long now_us = _micros ();
472
+ // calculate the sample time from last call
473
+ float Ts = (now_us - open_loop_timestamp) * 1e-6 ;
474
+
475
+ // calculate the necessary angle to achieve target velocity
476
+ shaft_angle += target_velocity*Ts;
477
+ // set the maximal allowed voltage (voltage_limit) with the necessary angle
478
+ setPhaseVoltage (voltage_limit, electricAngle (shaft_angle));
479
+
480
+ // save timestamp for next call
481
+ open_loop_timestamp = now_us;
482
+ }
483
+
484
+ // Function (iterative) generating open loop movement towards the target angle
485
+ // - target_angle - rad
486
+ // it uses voltage_limit and velocity_limit variables
487
+ void BLDCMotor::angleOpenloop (float target_angle){
488
+ // get current timestamp
489
+ long now_us = _micros ();
490
+ // calculate the sample time from last call
491
+ float Ts = (now_us - open_loop_timestamp) * 1e-6 ;
492
+
493
+ // calculate the necessary angle to move from current position towards target angle
494
+ // with maximal velocity (velocity_limit)
495
+ if (abs ( target_angle - shaft_angle ) > abs (velocity_limit*Ts))
496
+ shaft_angle += _sign (target_angle - shaft_angle) * abs ( velocity_limit )*Ts;
497
+ else
498
+ shaft_angle = target_angle;
499
+
500
+ // set the maximal allowed voltage (voltage_limit) with the necessary angle
501
+ setPhaseVoltage (voltage_limit, electricAngle (shaft_angle));
502
+
503
+ // save timestamp for next call
504
+ open_loop_timestamp = now_us;
505
+ }
506
+
447
507
/* *
448
508
* Monitoring functions
449
509
*/
@@ -498,17 +558,20 @@ int BLDCMotor::command(String user_command) {
498
558
switch (cmd){
499
559
case ' P' : // velocity P gain change
500
560
case ' I' : // velocity I gain change
501
- case ' L' : // velocity voltage limit change
502
561
case ' R' : // velocity voltage ramp change
503
562
if (monitor_port) monitor_port->print (" PI velocity| " );
504
563
break ;
505
564
case ' F' : // velocity Tf low pass filter change
506
565
if (monitor_port) monitor_port->print (" LPF velocity| " );
507
566
break ;
508
567
case ' K' : // angle loop gain P change
509
- case ' N' : // angle loop gain velocity_limit change
510
568
if (monitor_port) monitor_port->print (" P angle| " );
511
569
break ;
570
+ case ' L' : // velocity voltage limit change
571
+ case ' N' : // angle loop gain velocity_limit change
572
+ if (monitor_port) monitor_port->print (" Limits| " );
573
+ break ;
574
+
512
575
}
513
576
514
577
// apply the the command
@@ -525,8 +588,8 @@ int BLDCMotor::command(String user_command) {
525
588
break ;
526
589
case ' L' : // velocity voltage limit change
527
590
if (monitor_port) monitor_port->print (" volt_limit: " );
528
- if (!GET)PI_velocity. voltage_limit = value;
529
- if (monitor_port) monitor_port->println (PI_velocity. voltage_limit );
591
+ if (!GET)voltage_limit = value;
592
+ if (monitor_port) monitor_port->println (voltage_limit);
530
593
break ;
531
594
case ' R' : // velocity voltage ramp change
532
595
if (monitor_port) monitor_port->print (" volt_ramp: " );
@@ -545,8 +608,8 @@ int BLDCMotor::command(String user_command) {
545
608
break ;
546
609
case ' N' : // angle loop gain velocity_limit change
547
610
if (monitor_port) monitor_port->print (" vel_limit: " );
548
- if (!GET) P_angle. velocity_limit = value;
549
- if (monitor_port) monitor_port->println (P_angle. velocity_limit );
611
+ if (!GET) velocity_limit = value;
612
+ if (monitor_port) monitor_port->println (velocity_limit);
550
613
break ;
551
614
case ' C' :
552
615
// change control type
@@ -612,36 +675,4 @@ int BLDCMotor::command(String user_command) {
612
675
}
613
676
// return 0 if error and 1 if ok
614
677
return errorFlag;
615
- }
616
-
617
-
618
- // set velocity in open loop
619
- // - velocity - rad/s
620
- // - voltage - V
621
- void BLDCMotor::velocityOpenloop (float vel, float voltage){
622
- float Ts = (_micros () - open_loop_timestamp) * 1e-6 ;
623
-
624
- shaft_angle += vel*Ts;
625
-
626
- setPhaseVoltage (voltage, electricAngle (shaft_angle));
627
-
628
- open_loop_timestamp = _micros ();
629
- }
630
-
631
- // set angle in open loop
632
- // - angle - rad
633
- // - velocity - rad/s
634
- // - voltage - V
635
- void BLDCMotor::angleOpenloop (float angle, float vel, float voltage){
636
- float Ts = (_micros () - open_loop_timestamp) * 1e-6 ;
637
-
638
- if (abs (angle- shaft_angle) > abs (vel*Ts)){
639
- shaft_angle += _sign (angle - shaft_angle) * abs (vel)*Ts;
640
- }else {
641
- shaft_angle = angle;
642
- }
643
-
644
- setPhaseVoltage (voltage, electricAngle (shaft_angle));
645
-
646
- open_loop_timestamp = _micros ();
647
678
}
0 commit comments