simplefoc / Arduino-FOC

Arduino FOC for BLDC and Stepper motors - Arduino Based Field Oriented Control Algorithm Library
https://docs.simplefoc.com
MIT License
2.03k stars 521 forks source link

[FEATURE] Foc calculation refactoring #311

Closed Candas1 closed 3 months ago

Candas1 commented 1 year ago

Hi,

This is not adding a feature, but could make further changes easier. There is duplicate code here and here

    float i_alpha, i_beta;
    if(!current.c){
        // if only two measured currents
        i_alpha = current.a;  
        i_beta = _1_SQRT3 * current.a + _2_SQRT3 * current.b;
    }if(!current.a){
        // if only two measured currents
        float a = -current.c - current.b;
        i_alpha = a;  
        i_beta = _1_SQRT3 * a + _2_SQRT3 * current.b;
    }if(!current.b){
        // if only two measured currents
        float b = -current.a - current.c;
        i_alpha = current.a;  
        i_beta = _1_SQRT3 * current.a + _2_SQRT3 * b;
    } else {
        // signal filtering using identity a + b + c = 0. Assumes measurement error is normally distributed.
        float mid = (1.f/3) * (current.a + current.b + current.c);
        float a = current.a - mid;
        float b = current.b - mid;
        i_alpha = a;
        i_beta = _1_SQRT3 * a + _2_SQRT3 * b;
    }

This could be made a function getAlphaBeta or getClarkTransform that uses foc currents as inputs, and returns alpha and beta. A function getParkTransform could use the electrical angle, alpha and beta and return DQcurrents. getDCCurrent could use the electrical angle, alpha and beta and return DCcurrent.

Eventually, foc_current torque control type in loopfoc would do:

And dc_current torque control type in loopfoc would do:

Candas1 commented 1 year ago

If this generates too much work (changing the examples, ....) This alternative should have less impact:

getfoccurrents:

getdccurrents:

and no changes in loopfoc.

Candas1 commented 1 year ago

I only added a getABCurrents function and it looks like that

before: RAM: [= ] 9.2% (used 4536 bytes from 49152 bytes) Flash: [=== ] 27.3% (used 71540 bytes from 262144 bytes) loopfoc = 260us

RAM: [= ] 9.2% (used 4536 bytes from 49152 bytes) Flash: [=== ] 27.3% (used 71500 bytes from 262144 bytes) loopfoc = 260us

So no real space saving, no performance impact, but a single function to enhance in the future. If you think it's useful I can send you the PR.

Candas1 commented 1 year ago

I thought a getDQCurrents function (park transform) wouldn't be useful because it's used only once. But if you guys want to implement FOC for steppers, you could reuse such a function. Inverse park is used for both bldc and stepper motors also, it could be a getABVoltages function.

askuric commented 3 months ago

@Candas1 should be close this one?

Candas1 commented 3 months ago

Sorry I forgot about this one, it was covered here.