Skip to content

Commit 50beba6

Browse files
committed
Fix current limit + res and volt mode
1 parent 95783d0 commit 50beba6

File tree

1 file changed

+41
-39
lines changed

1 file changed

+41
-39
lines changed

src/BLDCMotor.cpp

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ void BLDCMotor::init() {
4444
PID_current_d.limit = voltage_limit;
4545
// velocity control loop controls current
4646
PID_velocity.limit = current_limit;
47+
}else if(!current_sense && _isset(phase_resistance)){
48+
PID_velocity.limit = current_limit;
4749
}else{
4850
PID_velocity.limit = voltage_limit;
4951
}
@@ -101,32 +103,32 @@ int BLDCMotor::initFOC( float zero_electric_offset, Direction _sensor_direction
101103

102104
// aligning the current sensor - can be skipped
103105
// checks if driver phases are the same as current sense phases
104-
// and checks the direction of measuremnt.
106+
// and checks the direction of measuremnt.
105107
_delay(500);
106-
if(exit_flag){
108+
if(exit_flag){
107109
if(current_sense) exit_flag *= alignCurrentSense();
108110
else if(monitor_port) monitor_port->println(F("MOT: No current sense."));
109111
}
110-
112+
111113
if(exit_flag){
112114
if(monitor_port) monitor_port->println(F("MOT: Ready."));
113115
}else{
114116
if(monitor_port) monitor_port->println(F("MOT: Init FOC failed."));
115117
disable();
116118
}
117-
119+
118120
return exit_flag;
119121
}
120122

121123
// Calibarthe the motor and current sense phases
122124
int BLDCMotor::alignCurrentSense() {
123-
int exit_flag = 1; // success
125+
int exit_flag = 1; // success
124126

125127
if(monitor_port) monitor_port->println(F("MOT: Align current sense."));
126128

127129
// align current sense and the driver
128130
exit_flag = current_sense->driverAlign(driver, voltage_sensor_align);
129-
if(!exit_flag){
131+
if(!exit_flag){
130132
// error in current sense - phase either not measured or bad connection
131133
if(monitor_port) monitor_port->println(F("MOT: Align error!"));
132134
exit_flag = 0;
@@ -143,7 +145,7 @@ int BLDCMotor::alignCurrentSense() {
143145
int BLDCMotor::alignSensor() {
144146
int exit_flag = 1; //success
145147
if(monitor_port) monitor_port->println(F("MOT: Align sensor."));
146-
148+
147149
// if unknown natural direction
148150
if(!_isset(sensor_direction)){
149151
// check if sensor needs zero search
@@ -169,7 +171,7 @@ int BLDCMotor::alignSensor() {
169171
float end_angle = sensor->getAngle();
170172
setPhaseVoltage(0, 0, 0);
171173
_delay(200);
172-
// determine the direction the sensor moved
174+
// determine the direction the sensor moved
173175
if (mid_angle == end_angle) {
174176
if(monitor_port) monitor_port->println(F("MOT: Failed to notice movement"));
175177
return 0; // failed calibration
@@ -180,7 +182,7 @@ int BLDCMotor::alignSensor() {
180182
if(monitor_port) monitor_port->println(F("MOT: sensor_direction==CW"));
181183
sensor_direction = Direction::CW;
182184
}
183-
// check pole pair number
185+
// check pole pair number
184186
if(monitor_port) monitor_port->print(F("MOT: PP check: "));
185187
float moved = fabs(mid_angle - end_angle);
186188
if( fabs(moved*pole_pairs - _2PI) > 0.5 ) { // 0.5 is arbitrary number it can be lower or higher!
@@ -193,7 +195,7 @@ int BLDCMotor::alignSensor() {
193195
// zero electric angle not known
194196
if(!_isset(zero_electric_angle)){
195197
// align the electrical phases of the motor and sensor
196-
// set angle -90(270 = 3PI/2) degrees
198+
// set angle -90(270 = 3PI/2) degrees
197199
setPhaseVoltage(voltage_sensor_align, 0, _3PI_2);
198200
_delay(700);
199201
zero_electric_angle = _normalizeAngle(_electricalAngle(sensor_direction*sensor->getAngle(), pole_pairs));
@@ -212,7 +214,7 @@ int BLDCMotor::alignSensor() {
212214
// Encoder alignment the absolute zero angle
213215
// - to the index
214216
int BLDCMotor::absoluteZeroSearch() {
215-
217+
216218
if(monitor_port) monitor_port->println(F("MOT: Index search..."));
217219
// search the absolute zero with small velocity
218220
float limit_vel = velocity_limit;
@@ -243,7 +245,7 @@ int BLDCMotor::absoluteZeroSearch() {
243245
// The faster it can be run the better
244246
void BLDCMotor::loopFOC() {
245247
// if disabled do nothing
246-
if(!enabled) return;
248+
if(!enabled) return;
247249
// if open-loop do nothing
248250
if( controller==MotionControlType::angle_openloop || controller==MotionControlType::velocity_openloop ) return;
249251

@@ -263,7 +265,7 @@ void BLDCMotor::loopFOC() {
263265
// filter the value values
264266
current.q = LPF_current_q(current.q);
265267
// calculate the phase voltage
266-
voltage.q = PID_current_q(current_sp - current.q);
268+
voltage.q = PID_current_q(current_sp - current.q);
267269
voltage.d = 0;
268270
break;
269271
case TorqueControlType::foc_current:
@@ -274,15 +276,15 @@ void BLDCMotor::loopFOC() {
274276
current.q = LPF_current_q(current.q);
275277
current.d = LPF_current_d(current.d);
276278
// calculate the phase voltages
277-
voltage.q = PID_current_q(current_sp - current.q);
279+
voltage.q = PID_current_q(current_sp - current.q);
278280
voltage.d = PID_current_d(-current.d);
279281
break;
280282
default:
281283
// no torque control selected
282284
if(monitor_port) monitor_port->println(F("MOT: no torque control selected!"));
283285
break;
284286
}
285-
287+
286288
// set the phase voltage - FOC heart function :)
287289
setPhaseVoltage(voltage.q, voltage.d, electrical_angle);
288290
}
@@ -294,7 +296,7 @@ void BLDCMotor::loopFOC() {
294296
// - if target is not set it uses motor.target value
295297
void BLDCMotor::move(float new_target) {
296298
// if disabled do nothing
297-
if(!enabled) return;
299+
if(!enabled) return;
298300
// downsampling (optional)
299301
if(motion_cnt++ < motion_downsample) return;
300302
motion_cnt = 0;
@@ -307,8 +309,8 @@ void BLDCMotor::move(float new_target) {
307309
case MotionControlType::torque:
308310
if(torque_controller == TorqueControlType::voltage) // if voltage torque control
309311
if(!_isset(phase_resistance)) voltage.q = target;
310-
else voltage.q = target*phase_resistance;
311-
else
312+
else voltage.q = target*phase_resistance;
313+
else
312314
current_sp = target; // if current/foc_current torque control
313315
break;
314316
case MotionControlType::angle:
@@ -318,7 +320,7 @@ void BLDCMotor::move(float new_target) {
318320
shaft_velocity_sp = P_angle( shaft_angle_sp - shaft_angle );
319321
// calculate the torque command
320322
current_sp = PID_velocity(shaft_velocity_sp - shaft_velocity); // if voltage torque control
321-
// if torque controlled through voltage
323+
// if torque controlled through voltage
322324
if(torque_controller == TorqueControlType::voltage){
323325
// use voltage if phase-resistance not provided
324326
if(!_isset(phase_resistance)) voltage.q = current_sp;
@@ -331,7 +333,7 @@ void BLDCMotor::move(float new_target) {
331333
shaft_velocity_sp = target;
332334
// calculate the torque command
333335
current_sp = PID_velocity(shaft_velocity_sp - shaft_velocity); // if current/foc_current torque control
334-
// if torque controlled through voltage control
336+
// if torque controlled through voltage control
335337
if(torque_controller == TorqueControlType::voltage){
336338
// use voltage if phase-resistance not provided
337339
if(!_isset(phase_resistance)) voltage.q = current_sp;
@@ -353,7 +355,7 @@ void BLDCMotor::move(float new_target) {
353355
break;
354356
}
355357
}
356-
358+
357359

358360
// Method using FOC to set Uq and Ud to the motor at the optimal angle
359361
// Function implementing Space Vector PWM and Sine PWM algorithms
@@ -376,9 +378,9 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
376378
};
377379
// static int trap_120_state = 0;
378380
sector = 6 * (_normalizeAngle(angle_el + _PI_6 ) / _2PI); // adding PI/6 to align with other modes
379-
// centering the voltages around either
380-
// modulation_centered == true > driver.volage_limit/2
381-
// modulation_centered == false > or Adaptable centering, all phases drawn to 0 when Uq=0
381+
// centering the voltages around either
382+
// modulation_centered == true > driver.volage_limit/2
383+
// modulation_centered == false > or Adaptable centering, all phases drawn to 0 when Uq=0
382384
center = modulation_centered ? (driver->voltage_limit)/2 : Uq;
383385

384386
if(trap_120_map[sector][0] == _HIGH_IMPEDANCE){
@@ -391,7 +393,7 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
391393
Ub = center;
392394
Uc = trap_120_map[sector][2] * Uq + center;
393395
driver->setPhaseState(_ACTIVE, _HIGH_IMPEDANCE, _ACTIVE);// disable phase if possible
394-
}else{
396+
}else{
395397
Ua = trap_120_map[sector][0] * Uq + center;
396398
Ub = trap_120_map[sector][1] * Uq + center;
397399
Uc = center;
@@ -407,9 +409,9 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
407409
};
408410
// static int trap_150_state = 0;
409411
sector = 12 * (_normalizeAngle(angle_el + _PI_6 ) / _2PI); // adding PI/6 to align with other modes
410-
// centering the voltages around either
411-
// modulation_centered == true > driver.volage_limit/2
412-
// modulation_centered == false > or Adaptable centering, all phases drawn to 0 when Uq=0
412+
// centering the voltages around either
413+
// modulation_centered == true > driver.volage_limit/2
414+
// modulation_centered == false > or Adaptable centering, all phases drawn to 0 when Uq=0
413415
center = modulation_centered ? (driver->voltage_limit)/2 : Uq;
414416

415417
if(trap_150_map[sector][0] == _HIGH_IMPEDANCE){
@@ -422,7 +424,7 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
422424
Ub = center;
423425
Uc = trap_150_map[sector][2] * Uq + center;
424426
driver->setPhaseState(_ACTIVE, _HIGH_IMPEDANCE, _ACTIVE);// disable phase if possible
425-
}else{
427+
}else{
426428
Ua = trap_150_map[sector][0] * Uq + center;
427429
Ub = trap_150_map[sector][1] * Uq + center;
428430
Uc = center;
@@ -468,15 +470,15 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
468470
// 1) Ualpha, Ubeta
469471
// 2) Uout = sqrt(Ualpha^2 + Ubeta^2)
470472
// 3) angle_el = atan2(Ubeta, Ualpha)
471-
//
473+
//
472474
// equivalent to 2) because the magnitude does not change is:
473475
// Uout = sqrt(Ud^2 + Uq^2)
474476
// equivalent to 3) is
475477
// angle_el = angle_el + atan2(Uq,Ud)
476478

477479
float Uout;
478480
// a bit of optitmisation
479-
if(Ud){ // only if Ud and Uq set
481+
if(Ud){ // only if Ud and Uq set
480482
// _sqrt is an approx of sqrt (3-4% error)
481483
Uout = _sqrt(Ud*Ud + Uq*Uq) / driver->voltage_limit;
482484
// angle normalisation in between 0 and 2pi
@@ -562,16 +564,16 @@ float BLDCMotor::velocityOpenloop(float target_velocity){
562564
// calculate the sample time from last call
563565
float Ts = (now_us - open_loop_timestamp) * 1e-6;
564566
// quick fix for strange cases (micros overflow + timestamp not defined)
565-
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
567+
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
566568

567569
// calculate the necessary angle to achieve target velocity
568-
shaft_angle = _normalizeAngle(shaft_angle + target_velocity*Ts);
570+
shaft_angle = _normalizeAngle(shaft_angle + target_velocity*Ts);
569571
// for display purposes
570572
shaft_velocity = target_velocity;
571-
573+
572574
// use voltage limit or current limit
573575
float Uq = voltage_limit;
574-
if(_isset(phase_resistance)) Uq = current_limit*phase_resistance;
576+
if(_isset(phase_resistance)) Uq = current_limit*phase_resistance;
575577

576578
// set the maximal allowed voltage (voltage_limit) with the necessary angle
577579
setPhaseVoltage(Uq, 0, _electricalAngle(shaft_angle, pole_pairs));
@@ -591,7 +593,7 @@ float BLDCMotor::angleOpenloop(float target_angle){
591593
// calculate the sample time from last call
592594
float Ts = (now_us - open_loop_timestamp) * 1e-6;
593595
// quick fix for strange cases (micros overflow + timestamp not defined)
594-
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
596+
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
595597

596598
// calculate the necessary angle to move from current position towards target angle
597599
// with maximal velocity (velocity_limit)
@@ -603,15 +605,15 @@ float BLDCMotor::angleOpenloop(float target_angle){
603605
shaft_velocity = 0;
604606
}
605607

606-
608+
607609
// use voltage limit or current limit
608610
float Uq = voltage_limit;
609-
if(_isset(phase_resistance)) Uq = current_limit*phase_resistance;
611+
if(_isset(phase_resistance)) Uq = current_limit*phase_resistance;
610612
// set the maximal allowed voltage (voltage_limit) with the necessary angle
611613
setPhaseVoltage(Uq, 0, _electricalAngle(shaft_angle, pole_pairs));
612614

613615
// save timestamp for next call
614616
open_loop_timestamp = now_us;
615-
617+
616618
return Uq;
617619
}

0 commit comments

Comments
 (0)