@@ -35,7 +35,7 @@ int trap_150_map[12][3] = {
3535// - R - motor phase resistance
3636// - KV - motor kv rating (rmp/v)
3737// - L - motor phase inductance
38- BLDCMotor::BLDCMotor (int pp, float _R, float _KV, float _inductance )
38+ BLDCMotor::BLDCMotor (int pp, float _R, float _KV, float _Lq, float _Ld )
3939: FOCMotor()
4040{
4141 // save pole pairs number
@@ -46,7 +46,8 @@ BLDCMotor::BLDCMotor(int pp, float _R, float _KV, float _inductance)
4646 // 1/sqrt(3) - rms value
4747 KV_rating = _KV;
4848 // save phase inductance
49- phase_inductance = _inductance;
49+ phase_inductance_dq = {_Ld, _Lq};
50+ phase_inductance = _Lq; // FOR BACKWARDS COMPATIBILITY
5051
5152 // torque control type is voltage by default
5253 torque_controller = TorqueControlType::voltage;
@@ -64,11 +65,11 @@ void BLDCMotor::linkDriver(BLDCDriver* _driver) {
6465int BLDCMotor::init () {
6566 if (!driver || !driver->initialized ) {
6667 motor_status = FOCMotorStatus::motor_init_failed;
67- SIMPLEFOC_DEBUG ( " MOT: Init not possible, driver not initialized " );
68+ SIMPLEFOC_MOTOR_ERROR ( " Init not possible, driver not init " );
6869 return 0 ;
6970 }
7071 motor_status = FOCMotorStatus::motor_initializing;
71- SIMPLEFOC_DEBUG ( " MOT: Init" );
72+ SIMPLEFOC_MOTOR_DEBUG ( " Init" );
7273
7374 // sanity check for the voltage limit configuration
7475 if (voltage_limit > driver->voltage_limit ) voltage_limit = driver->voltage_limit ;
@@ -80,6 +81,11 @@ int BLDCMotor::init() {
8081 updateVoltageLimit (voltage_limit);
8182 updateVelocityLimit (velocity_limit);
8283
84+ if (_isset (phase_inductance) && !(_isset (phase_inductance_dq.q ))) {
85+ // if only single inductance value is set, use it for both d and q axis
86+ phase_inductance_dq = {phase_inductance, phase_inductance};
87+ }
88+
8389 // if using open loop control, set a CW as the default direction if not already set
8490 // only if no sensor is used
8591 if (!sensor){
@@ -92,7 +98,7 @@ int BLDCMotor::init() {
9298
9399 _delay (500 );
94100 // enable motor
95- SIMPLEFOC_DEBUG ( " MOT: Enable driver." );
101+ SIMPLEFOC_MOTOR_DEBUG ( " Enable driver." );
96102 enable ();
97103 _delay (500 );
98104 motor_status = FOCMotorStatus::motor_uncalibrated;
@@ -214,28 +220,29 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
214220
215221 case FOCModulationType::SinePWM :
216222 case FOCModulationType::SpaceVectorPWM :
217- // Sinusoidal PWM modulation
218- // Inverse Park + Clarke transformation
219- _sincos (angle_el, &_sa, &_ca);
220223
221- // Inverse park transform
222- Ualpha = _ca * Ud - _sa * Uq; // -sin(angle) * Uq;
223- Ubeta = _sa * Ud + _ca * Uq; // cos(angle) * Uq;
224+ if (modulation_centered) {
225+ // Sinusoidal PWM modulation
226+ // Inverse Park + Clarke transformation
227+ _sincos (angle_el, &_sa, &_ca);
224228
225- // Clarke transform
226- Ua = Ualpha;
227- Ub = -0 .5f * Ualpha + _SQRT3_2 * Ubeta;
228- Uc = -0 .5f * Ualpha - _SQRT3_2 * Ubeta;
229+ // Inverse park transform
230+ Ualpha = _ca * Ud - _sa * Uq; // -sin(angle) * Uq;
231+ Ubeta = _sa * Ud + _ca * Uq; // cos(angle) * Uq;
229232
230- // centering the voltages around either
231- // - centered modulation: around driver.voltage_limit/2
232- // - non-centered modulation: pulls the lowest voltage to 0
233- // - Can be useful for low-side current sensing
234- // in cases where the ADC had long sample time
235- // - The part of the duty cycle in which all phases are
236- // off is longer than in centered modulation
237- // - Both SinePWM and SpaceVectorPWM have the same form for non-centered modulation
238- if (modulation_centered) {
233+ // Clarke transform
234+ Ua = Ualpha;
235+ Ub = -0 .5f * Ualpha + _SQRT3_2 * Ubeta;
236+ Uc = -0 .5f * Ualpha - _SQRT3_2 * Ubeta;
237+
238+ // centering the voltages around either
239+ // - centered modulation: around driver.voltage_limit/2
240+ // - non-centered modulation: pulls the lowest voltage to 0
241+ // - Can be useful for low-side current sensing
242+ // in cases where the ADC had long sample time
243+ // - The part of the duty cycle in which all phases are
244+ // off is longer than in centered modulation
245+ // - Both SinePWM and SpaceVectorPWM have the same form for non-centered modulation
239246 center = driver->voltage_limit /2 ;
240247 if (foc_modulation == FOCModulationType::SpaceVectorPWM){
241248 // discussed here: https://community.simplefoc.com/t/embedded-world-2023-stm32-cordic-co-processor/3107/165?u=candas1
@@ -249,10 +256,41 @@ void BLDCMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
249256 Ub += center;
250257 Uc += center;
251258 }else {
252- float Umin = min (Ua, min (Ub, Uc));
253- Ua -= Umin;
254- Ub -= Umin;
255- Uc -= Umin;
259+ angle_el = _normalizeAngle (angle_el + _PI_2);
260+ _sincos (angle_el, &_sa, &_ca);
261+
262+
263+
264+ // Inverse park transform
265+ Ualpha = _ca * Uq;// - _sa * Uq; // -sin(angle) * Uq;
266+ Ubeta = _sa * Uq;// + _ca * Uq; // cos(angle) * Uq;
267+
268+ // Clarke transform
269+
270+ // determine the segment I, II, III
271+ if ((angle_el >= 0 ) && (angle_el < _120_D2R)) {
272+ // section I
273+ Ua = Ualpha + _1_SQRT3 * Ubeta;
274+ Ub = _2_SQRT3 * Ubeta;
275+ Uc = 0 ;
276+
277+ } else if ((angle_el >= _120_D2R) && (angle_el < (2 * _120_D2R))) {
278+ // section III
279+ Ua = 0 ;
280+ Ub = _1_SQRT3 * Ubeta - Ualpha;
281+ Uc = -_1_SQRT3 * Ubeta - Ualpha;
282+
283+ } else if ((angle_el >= (2 * _120_D2R)) && (angle_el < (3 * _120_D2R))) {
284+ // section II
285+ Ua = Ualpha - _1_SQRT3 * Ubeta;
286+ Ub = 0 ;
287+ Uc = - _2_SQRT3 * Ubeta;
288+ }
289+
290+ Ua = Ua*1.5 ;
291+ Ub = Ub*1.5 ;
292+ Uc = Uc*1.5 ;
293+
256294 }
257295 break ;
258296 }
0 commit comments