Field oriented control of induction motors

User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

So, rather late last night I wrote a simpler FOC implementation. The full code is here: https://github.com/catphish/stm32-sine/ ... n-sine.cpp

First we fetch some settings. slipconst is a time constant. It's a combination of motor parameters and the PWM frequency. It doesn't really matter how it's derived, it just needs to be tuned to the specific motor, and it determines the slip. curkp controls the current gains. idtarget is the d-axis current target. We set this to a fixed value for now. throtcur is multiplied by the torque request to get the q-axis current target iqtarget.

Code: Select all

      // Fetch settings
      int dir = Param::GetInt(Param::dir);
      s32fp slipconst = Param::GetInt(Param::slipconst);
      s32fp curkp = Param::Get(Param::curkp);
      s32fp idtarget = Param::Get(Param::idtarget);
      s32fp throtcur  = Param::Get(Param::throtcur);
      s32fp iqtarget = FP_MUL(throtcur, torqueRequest) * dir;
The next part is standard, we fetch the rotor angle from the encoder, and the three phase currents from the ADC.

Code: Select all

      // Update rotor angle from encoder
      Encoder::UpdateRotorAngle(dir);

      // Process currents
      s32fp il2 = GetCurrent(AnaIn::il1, ilofs[0], Param::Get(Param::il1gain));
      s32fp il3 = GetCurrent(AnaIn::il2, ilofs[1], Param::Get(Param::il2gain));
      s32fp il1 = -il2 - il3;
      s32fp ilMax = GetIlMax(il1, il2);
      Param::SetFixed(Param::il1, il1);
      Param::SetFixed(Param::il2, il2);
      Param::SetFixed(Param::ilmax, ilMax);
Next we run a Park and Clarke transform using the last known rotor field angle to derive the Id and Iq currents.

Code: Select all

      // Calculate measured IQ and ID
      FOC::SetAngle(angle);
      FOC::ParkClarke(il1, il2);
      Param::SetFixed(Param::iq, FOC::iq);
      Param::SetFixed(Param::id, FOC::id);
This block of code estimates the slip and advances the rotor field angle accordingly We assume that slip is proportional to iqtarget divided by idtarget, disregarding the difference between target and reality, as well as the rotor time constant. slipIncr is integrated into slipAngle and added the the physical rotor angle to arrive at a rotor field angle. The accuracy of this process is largely determined by the value of slipconst.

Code: Select all

      // Increment rotor field angle
      int32_t slipIncr = 0;
      if(idtarget > 0)
      {
         slipIncr = iqtarget;
         slipIncr <<= 12;
         slipIncr /= slipconst;
         slipIncr <<= 12;
         slipIncr /= idtarget;
      }
      static uint32_t slipAngle = 0;
      slipAngle += slipIncr;
      slipAngle &= 0xFFFFFF;
      uint16_t rotorAngle = Encoder::GetRotorAngle();
      angle = -polePairRatio * rotorAngle + (slipAngle >> 8);
      Param::SetFixed(Param::fslipspnt, fslip);
The slip and electrical frequencies are converted back to Hz for display calculation and use elsewhere in the application.

Code: Select all

      // Caculate slip frequency in Hz
      fslip = (slipIncr * pwmfrq) >> 19;
      Param::SetFixed(Param::fslipspnt, fslip);

      // Calculate rotor frequency in Hz
      frq = ABS(polePairRatio * Encoder::GetRotorFrequency() + fslip);
      Param::SetFixed(Param::fstat, frq);
Here we run an extremely simple I-only PID to apply corrections to Ud and Uq according to the measured error in Id and Iq. Each voltage is limited to a value that prevents the combined total from exceeding the DC bus voltage.

Code: Select all

      // Apply corrections to IQ and ID voltages
      static int32_t ud = 0;
      int32_t dError = idtarget - FOC::id;
      ud += FP_MUL(curkp, dError)/1000;
      if(ud > 26737) ud = 26737;
      if(ud < -26737) ud = -26737;
      static int32_t uq = 0;

      int32_t qError = iqtarget - FOC::iq;
      uq += FP_MUL(curkp, qError)/1000;
      if(uq > 26737) uq = 26737;
      if(uq < -26737) uq = -26737;
      Param::SetFixed(Param::ud, ud);
      Param::SetFixed(Param::uq, uq);

And finally, as one might expect, we run the inverse Park and Clarke before outputting the voltages to the inverter.

Code: Select all

      // Inverse Park Clarke
      FOC::SetAngle(angle);
      FOC::InvParkClarke(ud, uq);

      /* Match to PWM resolution */
      timer_set_oc_value(PWM_TIMER, TIM_OC1, FOC::DutyCycles[0] >> shiftForTimer);
      timer_set_oc_value(PWM_TIMER, TIM_OC2, FOC::DutyCycles[1] >> shiftForTimer);
      timer_set_oc_value(PWM_TIMER, TIM_OC3, FOC::DutyCycles[2] >> shiftForTimer);

This code *appears* to work!
foc1.png
foc2.png
I'm sure there will still be lots to do to get this accurate, and I apologize for not using the existing FOC loop. It just did a lot of things that may not apply to my motor and and I wanted to keep it simple to begin with. Sadly with no load on the motor most tests quickly exceed the voltage of the supply.

I think it's worth appreciating that ultimately, this code is still just controlling current and slip, much like my "current control" version. The substantial difference is that by handling d-axis and q-axis current independently, it should now be able to control negative currents.

Video of this code running on my bench.

Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: Field oriented control of induction motors

Post by Pete9008 »

Looking good :)

Edit - I'll rephrase that - looking VERY good, well done!

Slightly envious of your test setup too ;)
User avatar
johu
Site Admin
Posts: 5769
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 157 times
Been thanked: 1010 times
Contact:

Re: Field oriented control of induction motors

Post by johu »

Wow!

I'm sure we can eventually unify the code, now the target is to run it smoothly, with regen, in your car :)
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: Field oriented control of induction motors

Post by Pete9008 »

catphish wrote: Sun Feb 12, 2023 10:30 pm I'm not sure how best to explain, but I'm thinking that Lm multiplies the input value FOC::id, and hence comes along with it throughout the recursive process. Perhaps this is clearer if written like this:

Code: Select all

   IdLm = FOC::id * LM;
   rotorFlux -= rotorFlux / TR;
   rotorFlux += IdLm / TR;
All terms just become LM larger.
Had a look at this but still can't work out how Lm could cancel :? Here are my calcs in case they are of any use?
Attachments
SlipCalcs.JPG
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Here's another short demo of the motor running on the bench after some tweaking of settings.
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Pete9008 wrote: Mon Feb 13, 2023 2:52 pm Had a look at this but still can't work out how Lm could cancel :? Here are my calcs in case they are of any use?
Thank you for going through this. On the very first line of your calculations, you have "-Psir/Tr". My argument was based on the assumption that Lm and Id are both factors of Psir. If Ld were doubled, Psir would also be doubled independent of time.

I'm no longer certain that I'm correct here, but my best argument is as follows, this isn't a mathematical proof, more a demonstration of how it would be executed:

Starting condition:
Psir = 0

First iteration:
Psir = LmId / Tr - 0 / Tr = LmId / Tr

Second iteration (we insert the previous value of Psir):
Psir = LmId / Tr - (LmId / Tr)/Tr
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: Field oriented control of induction motors

Post by Pete9008 »

Are you referring to equation (11) here? If so that is just for the steady state, where dPsir/dt = 0. Under non-steady state conditions I think you need the other term too.

Gut feel is that either solution will actually work, I think the extra term is mainly there to include flux decay due to rotor resistive losses and I would have thought that would be a fairly minot component compared to everything else.

Edit - and it's very rare I'm ever certain about anything and definitely not this!
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Pete9008 wrote: Mon Feb 13, 2023 5:05 pm Are you referring to equation (11) here? If so that is just for the steady state, where dPsir/dt = 0. Under non-steady state conditions I think you need the other term too.
Nope, referring to Phir in equation 9 - the one that's self-referential. I'm suggesting that if you replace Phir with... itself... Lm and Ld appear as factors.
NB: this really isn't very important, probably best not to spend any more time worrying about it for now.
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Pete9008 wrote: Mon Feb 13, 2023 12:37 pm Slightly envious of your test setup too ;)
I really like this setup. Thanks to johu for providing the STM32 board! The Prius inverter and industrial motor were quite cheap (about £80 each). The battery and contactors were leftover from my car build.

I'd still like to find a way to test with a load. Might need to build a go-kart :)
User avatar
Ev8
Posts: 801
Joined: Sat Jan 30, 2021 11:05 am
Has thanked: 41 times
Been thanked: 149 times

Re: Field oriented control of induction motors

Post by Ev8 »

Need to find an old exercise bike the type with a large flywheel with a brake band around it, hook it up to that and you can simulate inertia and momentum
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: Field oriented control of induction motors

Post by Pete9008 »

Ev8 wrote: Tue Feb 14, 2023 5:07 pm Need to find an old exercise bike the type with a large flywheel with a brake band around it, hook it up to that and you can simulate inertia and momentum
That's been suggested in another thread too :)

I've had this in my ebay watchlist for the last couple of weeks https://www.ebay.co.uk/itm/125763018895 , just can't decide whether I can be bothered!
User avatar
Ev8
Posts: 801
Joined: Sat Jan 30, 2021 11:05 am
Has thanked: 41 times
Been thanked: 149 times

Re: Field oriented control of induction motors

Post by Ev8 »

Yeah that would be perfect, I think you should do it just because it’s a cool contraption to build!
User avatar
Peter
Posts: 310
Joined: Fri Dec 14, 2018 9:07 pm
Location: North West Lancs, UK
Been thanked: 8 times

Re: Field oriented control of induction motors

Post by Peter »

Maybe a car or motorbike wheel, tyre filled with water for extra load ? I can machine a hub to fit your motor if that will work ?
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

I've been donated another 1kW motor with a chain sprocket on it. This one might be more practical to attach a load to :)
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 347 times

Re: Field oriented control of induction motors

Post by Pete9008 »

catphish wrote: Tue Feb 14, 2023 7:44 pm I've been donated another 1kW motor with a chain sprocket on it. This one might be more practical to attach a load to :)
How about coupling the two motors together. One on MG1 the other on MG2 and run the pair as a dyno ;)
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Pete9008 wrote: Tue Feb 14, 2023 10:33 pm How about coupling the two motors together. One on MG1 the other on MG2 and run the pair as a dyno ;)
This is seeming like it might be the best idea. Probably easiest to do with two identical sizes motors, will make mounting and coupling a lot simpler.

I am putting this FOC on hold for now as it kinda works on the bench but I'm a long way from being confident getting it anywhere near by car!

However I have some more ideas about using in phase and out of phase (reactive) current measurements for "good enough" current control. Will update my other thread soon I hope.
MattsAwesomeStuff
Posts: 897
Joined: Fri Apr 26, 2019 5:40 pm
Has thanked: 290 times
Been thanked: 177 times

Re: Field oriented control of induction motors

Post by MattsAwesomeStuff »

What's the benefit be of using FOC for induction motors versus just the plain Sine algorithm?

I'll be running an induction motor (nothing fancy like a tesla, a forklift motor). Wondering if/how this might affect me.
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

MattsAwesomeStuff wrote: Sat Feb 18, 2023 6:47 pm What's the benefit be of using FOC for induction motors versus just the plain Sine algorithm?

I'll be running an induction motor (nothing fancy like a tesla, a forklift motor). Wondering if/how this might affect me.
In theory, a correctly implemented FOC algorithm has three main benefits:
1) More efficiency, because the motor can be run in its optimal conditions regardless of speed and load.
2) More precise control. This means better throttle response and the ability to push the motor closer to its limits.
3) Regen can be controlled properly all the way down to a stop.

The downside is that FOC is very difficult to implement in induction motors, and also requires accurate current sensing. It's unlikely I will have a working implementation any time soon.

I am instead focusing on an approach that lies somewhere in between, driving the motor the normal sine way, but adjusting the various parameters automatically / dynamically. This achieves point (2) above, but I haven't yet got regen working.

The short answer is that this probably doesn't affect you, and you'll probably be happy for now using the sine firmware, but I hope to have a good alternative available soon for comparison.
User avatar
Romale
Posts: 448
Joined: Fri May 20, 2022 4:16 pm
Location: Romania
Has thanked: 208 times
Been thanked: 45 times

Re: Field oriented control of induction motors

Post by Romale »

appeared?
an alternative for comparison?

I would be happy to try something new with my industrial acim motor with a modified winding. it's a pity, but with the sine firmware, I burned three inverters out of the blue at low currents ((
evil neodymium :twisted:
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Romale wrote: Thu Apr 20, 2023 9:28 am appeared?
an alternative for comparison?

I would be happy to try something new with my industrial acim motor with a modified winding. it's a pity, but with the sine firmware, I burned three inverters out of the blue at low currents ((
I haven't made any now progress with this. If you want a viable alternative firmware, please try my current control version.
User avatar
Romale
Posts: 448
Joined: Fri May 20, 2022 4:16 pm
Location: Romania
Has thanked: 208 times
Been thanked: 45 times

Re: Field oriented control of induction motors

Post by Romale »

catphish wrote: Thu Apr 20, 2023 11:04 am If you want a viable alternative firmware, please try my current control version.
I'll try it with pleasure.
and where to get it?
could you add a .bin file here?
evil neodymium :twisted:
User avatar
catphish
Posts: 955
Joined: Fri Oct 08, 2021 11:02 pm
Location: Dorset, UK
Has thanked: 94 times
Been thanked: 179 times

Re: Field oriented control of induction motors

Post by catphish »

Romale wrote: Thu Apr 20, 2023 12:07 pm I'll try it with pleasure.
and where to get it?
could you add a .bin file here?
It's on another thread called current control of induction motors. Go to the bottom of the thread and you'll find the download and information.
Post Reply