Skip to content

Commit bd6e919

Browse files
committed
inital autotuning implementation
1 parent ef9fe50 commit bd6e919

File tree

6 files changed

+67
-12
lines changed

6 files changed

+67
-12
lines changed

src/BLDCMotor.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,6 @@ int BLDCMotor::init() {
7575
// constrain voltage for sensor alignment
7676
if(voltage_sensor_align > voltage_limit) voltage_sensor_align = voltage_limit;
7777

78-
// update the controller limits
79-
if (_isset(phase_resistance) && _isset(phase_inductance)){
80-
PID_current_d.P = phase_inductance * DEF_CURR_BANDWIDTH * _2PI;
81-
PID_current_d.I = PID_current_d.P * phase_resistance / phase_inductance;
82-
83-
PID_current_q.P = phase_inductance * DEF_CURR_BANDWIDTH * _2PI;
84-
PID_current_q.I = PID_current_q.P * phase_resistance /phase_inductance;
85-
}
86-
8778
// update limits in the motor controllers
8879
updateCurrentLimit(current_limit);
8980
updateVoltageLimit(voltage_limit);

src/common/base_classes/FOCMotor.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ int FOCMotor::characteriseMotor(float voltage, float correction_factor=1.0f){
309309
SIMPLEFOC_DEBUG("WARN: MOT: Measured Q inductance is more than twice the D inductance. This is probably wrong. From experience, the lower value is probably close to reality.");
310310
}
311311

312+
// store the measured values
313+
phase_resistance = 2.0f * resistance;
314+
phase_inductance = (Ld + Lq) / 2.0f;
312315
return 0;
313316

314317
}
@@ -520,4 +523,42 @@ void FOCMotor::updateMotionControlType(MotionControlType new_motion_controller)
520523

521524
// finally set the new controller
522525
controller = new_motion_controller;
526+
}
527+
528+
529+
int FOCMotor::tuneCurrentController(float bandwidth) {
530+
if (bandwidth <= 0.0f) {
531+
// check bandwidth is positive
532+
SIMPLEFOC_DEBUG("ERR: MOT: Cannot tune current controller: bandwidth must be positive");
533+
return 1;
534+
}
535+
if (loop_time_us && bandwidth > 0.5f * (1e6f / loop_time_us)) {
536+
// check bandwidth is not too high for the control loop frequency
537+
SIMPLEFOC_DEBUG("ERR: MOT: Bandwidth too high, current loop freq:" , (1e6f / loop_time_us));
538+
return 2;
539+
}
540+
if (!_isset(phase_resistance) || !_isset(phase_inductance)) {
541+
// need motor parameters to tune the controller
542+
SIMPLEFOC_DEBUG("MOT: Measuring motor parameters!");
543+
if(characteriseMotor( voltage_sensor_align )) {
544+
return 3;
545+
}
546+
}
547+
548+
// Simple tuning method for a first order system
549+
float Kp = phase_inductance * (_2PI * bandwidth);
550+
float Ki = phase_resistance * (_2PI * bandwidth);
551+
552+
PID_current_q.P = Kp;
553+
PID_current_q.I = Ki;
554+
PID_current_d.P = Kp;
555+
PID_current_d.I = Ki;
556+
LPF_current_d.Tf = 1.0f / (_2PI * bandwidth * 5.0f); // filter cutoff at 5x bandwidth
557+
LPF_current_q.Tf = 1.0f / (_2PI * bandwidth * 5.0f); // filter cutoff at 5x bandwidth
558+
559+
SIMPLEFOC_DEBUG("MOT: Current controller tuned:\nMOT: Bandwidth (Hz): ", bandwidth);
560+
SIMPLEFOC_DEBUG("MOT: Kp: ", Kp);
561+
SIMPLEFOC_DEBUG("MOT: Ki: ", Ki);
562+
563+
return 0;
523564
}

src/common/base_classes/FOCMotor.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,16 @@ class FOCMotor
159159
*/
160160
int characteriseMotor(float voltage, float correction_factor);
161161

162+
/**
163+
* Auto-tune the current controller PID parameters based on desired bandwidth.
164+
* Uses a simple method that assumes a first order system and requires knowledge of
165+
* the motor phase resistance and inductance (if not set, the characteriseMotor function can be used).
166+
*
167+
* @param bandwidth Desired closed-loop bandwidth in Hz.
168+
* @returns returns 0 for success, >0 for failure
169+
*/
170+
int tuneCurrentController(float bandwidth);
171+
162172
// state variables
163173
float target; //!< current target value - depends of the controller
164174
float feed_forward_velocity = 0.0f; //!< current feed forward velocity

src/common/defaults.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@
1818
#define DEF_PID_CURR_RAMP 1000.0f //!< default PID controller voltage ramp value
1919
#define DEF_PID_CURR_LIMIT (DEF_POWER_SUPPLY) //!< default PID controller voltage limit
2020
#define DEF_CURR_FILTER_Tf 0.01f //!< default velocity filter time constant
21-
#define DEF_CURR_BANDWIDTH 300.0f //!< current bandwidth
21+
#define DEF_CURR_BANDWIDTH 100.0f //!< current bandwidth
2222
#else
2323
// for stm32, due, teensy, esp32 and similar
2424
#define DEF_PID_CURR_P 3 //!< default PID controller P value
2525
#define DEF_PID_CURR_I 300.0f //!< default PID controller I value
2626
#define DEF_PID_CURR_D 0.0f //!< default PID controller D value
2727
#define DEF_PID_CURR_RAMP 0 //!< default PID controller voltage ramp value
2828
#define DEF_PID_CURR_LIMIT (DEF_POWER_SUPPLY) //!< default PID controller voltage limit
29-
#define DEF_CURR_FILTER_Tf 0.005f //!< default currnet filter time constant
3029
#define DEF_CURR_BANDWIDTH 300.0f //!< current bandwidth
30+
#define DEF_CURR_FILTER_Tf 1/(_2PI*DEF_CURR_BANDWIDTH) //!< default currnet filter time constant
3131
#endif
3232
// default current limit values
3333
#define DEF_CURRENT_LIM 2.0f //!< 2Amps current limit by default

src/communication/Commander.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,18 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
269269
motor->initFOC();
270270
println(F("done"));
271271
break;
272+
case SCMD_TUNE_CURR:
273+
printVerbose(F("PI tune curr.| "));
274+
{
275+
int res = motor->tuneCurrentController(value);
276+
if(res == 0){
277+
println(F("done"));
278+
} else {
279+
printVerbose(F("failed, err code: "));
280+
println(res);
281+
}
282+
}
283+
break;
272284
default:
273285
printError();
274286
break;

src/communication/commands.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
#define SCMD_PWMMOD_TYPE 'T' //!<< Pwm modulation type
5050
#define SCMD_PWMMOD_CENTER 'C' //!<< Pwm modulation center flag
5151

52-
#define SCMD_LOOPFOC_TIME 'L' //!< loopFOC execution time
52+
#define SCMD_LOOPFOC_TIME 'L' //!< loopFOC execution time
5353
#define SCMD_REINIT_FOC 'R' //!< reinitialize FOC
54+
#define SCMD_TUNE_CURR 'C' //!< tune current controller
5455

5556
#endif

0 commit comments

Comments
 (0)