Testing FOC for synchronous motor
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Testing FOC for synchronous motor
Thought I should split this off from the Touran topic.
So today I whacked the formulas found on wikipedia into the firmware to see what happens. Well, what does happen is a little *blip* on the motor and then over current shutdown, just like expected really. So I guess I have a couple of misconceptions about using FOC, maybe somebody can take a look: https://github.com/jsphuebner/stm32-sine/tree/foc-test
I should add, before I did the full loop I ran the motor with V/Hz to see if iq and id looked sane. So when I went up the driveway iq became positive, id negative. When going down, both id and iq were negative. So nothing strange so far.
And I should add that I plotted the generated duty cycles and they sit nicely at 1024 (mid-value for 18kHz PWM) when idle and spread off in different directions with increase in throttle.
So today I whacked the formulas found on wikipedia into the firmware to see what happens. Well, what does happen is a little *blip* on the motor and then over current shutdown, just like expected really. So I guess I have a couple of misconceptions about using FOC, maybe somebody can take a look: https://github.com/jsphuebner/stm32-sine/tree/foc-test
I should add, before I did the full loop I ran the motor with V/Hz to see if iq and id looked sane. So when I went up the driveway iq became positive, id negative. When going down, both id and iq were negative. So nothing strange so far.
And I should add that I plotted the generated duty cycles and they sit nicely at 1024 (mid-value for 18kHz PWM) when idle and spread off in different directions with increase in throttle.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
For a PMSM, as far as I know idref should be zero when operating normally (except field weakening)
So in ProcessThrottle() in stm32_sine.cpp
If I'm interpreting the code correctly this is where idref and iqref are set. Here you can try setting idref=0 instead of what you get from the throttle. iqref can be anything, a positive value should spin the motor clockwise, or vice versa. In the field weakening region you should apply negative idref.
So in ProcessThrottle() in stm32_sine.cpp
Code: Select all
s32fp id = FP_MUL(Param::Get(Param::throtid), ABS(slowThrottleCommmand));
s32fp iq = FP_MUL(Param::Get(Param::throtiq), slowThrottleCommmand);
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
I'm not sure if that applies to IPM motors as they operate 135° ahead of the rotor field for using reluctance torque. But I will try it anyway.
Can you take a look at pwmgeneration.cpp:173-229 if that stuff makes sense? Perhaps also in foc.cpp.
I'm also not sure which angle to put into the Park and inverse Park transformation. Current rotor angle + syncofs? When should rotor angle be 0 for Park? And then inverse, do I use the same angle again. Or the newly tracked one? Currently I do the latter.
Can you take a look at pwmgeneration.cpp:173-229 if that stuff makes sense? Perhaps also in foc.cpp.
I'm also not sure which angle to put into the Park and inverse Park transformation. Current rotor angle + syncofs? When should rotor angle be 0 for Park? And then inverse, do I use the same angle again. Or the newly tracked one? Currently I do the latter.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
If you have a mechanically perfectly aligned resolver, when the resolver arctan(sine, cosine) gives you zero, you should give angle=0. So since your resolver is misaligned (with an unknown angle), the angle+syncofs is what you should feed to the Park and Inverse Park. Providing the correct value of syncofs is crucial. All the examples I have seen uses the very same angle both for Park and Inverse Park, but the time passed between two operations is generally measured by several microseconds, so it shouldn't matter. But I'd prefer using the same angle.
So I have looked at the pwmgeneration.cpp and foc.cpp, and everything looked perfectly OK to me.
I'm not sure with the 135° offset for the reluctance stuff, but for the idea of applying zero idref, you can check out this TI document (page 8): http://www.ti.com/lit/an/sprabz0/sprabz0.pdf
EDIT: For the IPM motor, this TI document gives some information (page 3): http://www.ti.com/lit/an/spracf3/spracf3.pdf
So you are right, a negative Id must be given for the maximum efficiency and best torque output. But the equations look weird and need some study
So I have looked at the pwmgeneration.cpp and foc.cpp, and everything looked perfectly OK to me.
I'm not sure with the 135° offset for the reluctance stuff, but for the idea of applying zero idref, you can check out this TI document (page 8): http://www.ti.com/lit/an/sprabz0/sprabz0.pdf
Also Paul Holmes gives zero idref for synchronous motors and he's running his inverter for Nissan Leaf, so I think it should apply here too. Check here (line: 2111-2124): https://github.com/MPaulHolmes/AC-Contr ... ntroller.cTwo motor phase currents are measured. These measurements feed the Clarke transformation module. The outputs of this projection are designated isα and isβ. These two components of the current along with rotor flux position are the inputs of the Park transformation that transform them to currents (isd and isq) in d,q rotating reference frame. The isd and isq components are compared to the references isdref (the flux reference) and isqref (the torque reference). At this point, this control structure shows an interesting advantage: it can be used to control either synchronous or HVPM machines by simply changing the flux reference and obtaining rotor flux position. As in synchronous permanent magnet a motor, the rotor flux is fixed determined by the magnets; there is no need to create one. Hence, when controlling a PMSM, isdref should be set to zero. As ACIM motors need a rotor flux creation in order to operate, the flux reference must not be zero. This conveniently solves one of the major drawbacks of the “classic” control structures: the portability from asynchronous to synchronous drives. The torque command isqref can be the connected to the output of the speed regulator. The outputs of the current regulators are Vsdref and Vsqref; they are applied to the inverse Park transformation. Using the position of rotor flux, this projection generates Vsαref and Vsβref, which are the components of the stator vector voltage in the stationary orthogonal reference frame. These are the inputs of the Space Vector PWM. The outputs of this block are the signals that drive the inverter. Note that both Park and inverse Park transformations need the rotor flux position. Obtaining this rotor flux position depends on the AC machine type (synchronous or asynchronous machine).
EDIT: For the IPM motor, this TI document gives some information (page 3): http://www.ti.com/lit/an/spracf3/spracf3.pdf
So you are right, a negative Id must be given for the maximum efficiency and best torque output. But the equations look weird and need some study
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Alright, that clears things up, thanks!
So here I need to set syncofs to align with the rotor. So I most likely found the 90° angle at syncofs=55000, so 0° would be at 55000-16384=38616.
Now lets see if the imprinted numbers make any sense: 82 00 DF 00 5D
38616 in hex is 96D8. Hmm, 8200 in decimal is 33280. Another 30° less.
Well I guess I'll go and try.
So here I need to set syncofs to align with the rotor. So I most likely found the 90° angle at syncofs=55000, so 0° would be at 55000-16384=38616.
Now lets see if the imprinted numbers make any sense: 82 00 DF 00 5D
38616 in hex is 96D8. Hmm, 8200 in decimal is 33280. Another 30° less.
Well I guess I'll go and try.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Let's hope it works.
I also looked at the IPM literature and saw that the MTPA (Maximum torque per ampere) strategy is popular for finding the best idref for the IPM machines. The idea is, there are infinite number of id/iq vectors that would provide the same torque, and to find the best of them that produces the least stator current to minimize the winding losses.
But this strategy requires knowledge of Ld and Lq, i.e. direct and quadrature inductances. Will investigate further.
I also looked at the IPM literature and saw that the MTPA (Maximum torque per ampere) strategy is popular for finding the best idref for the IPM machines. The idea is, there are infinite number of id/iq vectors that would provide the same torque, and to find the best of them that produces the least stator current to minimize the winding losses.
But this strategy requires knowledge of Ld and Lq, i.e. direct and quadrature inductances. Will investigate further.
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Yes it's like T~ o*iq + (Ld-Lq)*id*iq . The last term is for reluctance torque. (Ld-Lq) is positive.
But back to present. I tried different syncofs settings, including the ones above. In the end I tried all from 0-65000 in 1000 digit steps. At around 44000 the id and iq looked most like what I commanded. But all I could achieve was a shaking motor, no matter if the car is in gear or not. If you look at the rotor angle it oscillates back and forth.
There must be some glitch in the implementation. Maybe because I only use a P-regulator?
But back to present. I tried different syncofs settings, including the ones above. In the end I tried all from 0-65000 in 1000 digit steps. At around 44000 the id and iq looked most like what I commanded. But all I could achieve was a shaking motor, no matter if the car is in gear or not. If you look at the rotor angle it oscillates back and forth.
There must be some glitch in the implementation. Maybe because I only use a P-regulator?
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Yes there is a glitch...
Fixed frequency to 10Hz and feeding the current sensors 10Hz. Thats what it outputs.
Fixed frequency to 10Hz and feeding the current sensors 10Hz. Thats what it outputs.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Not sure the glitch is caused by this, but can you make sure that the Inverse Park transformation is implemented correctly?
TI's IPARK C macro defines this transformation like this:
while the foc.cpp has this:
sqrt32 should be fine, but the signs are different.
TI's IPARK C macro defines this transformation like this:
Code: Select all
v.Alpha = _IQmpy(v.Ds,v.Cosine) - _IQmpy(v.Qs,v.Sine);
v.Beta = _IQmpy(v.Qs,v.Cosine) + _IQmpy(v.Ds,v.Sine);
Code: Select all
ia = FP_MUL(sqrt32, (FP_MUL(cos, id) + FP_MUL(sin, iq)));
ib = FP_MUL(sqrt32, (-FP_MUL(sin, id) + FP_MUL(cos, iq)));
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Oh I removed sqrt32 on the last commit, signs are the same, I had just arranged the terms differently.
Edit: now I see what you mean, will check tomorrow.
EditEdit: I saw that I fixed it in the last commit
I suspect the data type might be overflowing?
Edit: now I see what you mean, will check tomorrow.
EditEdit: I saw that I fixed it in the last commit
I suspect the data type might be overflowing?
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Which one is your last edit So I guess you already the fixed it before your last try and the glitch happened on the latest commit. I had the initial branch, let me check the latest one.
Yes, the data type might be overflowing but I cannot tell off the top of my head why. Actually, it could be better if we scaled all the currents down to per-unit to avoid such things. In other words, we can simply divide everything to say 600 and let the current stay always between -1 and 1. That's how TI implements the FOC. But TI does it with 18 bit fraction fixed-point, so it would take some time to implement that with our 5 bit fraction fixed-point math.
In the latest commit all Clarke, Park, Inverse Park and Inverse Clarke operations look nice.
So you fed 10 Hz to the current sensors, did you give a 10 Hz angle as well or only some random angle? Our fixed-point data type here is only 5 bit fraction so it shouldn't overflow at these values easily.
Edit: In the foc.cpp line 35
could you please try int32_t instead of uint32_t here? I'm aware the duty cycles are always positive but after the Inverse Clarke you are probably ending up with negative values, which are then biased by +32768 in pwmgeneration.cpp. I think this is where the glitch happens.
Yes, the data type might be overflowing but I cannot tell off the top of my head why. Actually, it could be better if we scaled all the currents down to per-unit to avoid such things. In other words, we can simply divide everything to say 600 and let the current stay always between -1 and 1. That's how TI implements the FOC. But TI does it with 18 bit fraction fixed-point, so it would take some time to implement that with our 5 bit fraction fixed-point math.
In the latest commit all Clarke, Park, Inverse Park and Inverse Clarke operations look nice.
So you fed 10 Hz to the current sensors, did you give a 10 Hz angle as well or only some random angle? Our fixed-point data type here is only 5 bit fraction so it shouldn't overflow at these values easily.
Edit: In the foc.cpp line 35
Code: Select all
uint32_t FOC::DutyCycles[3];
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Yes, that looks better. See changes on github.
Basically set iackp to 0.5 (was 10 yesterday) and simulated 90A rms current with the same frequency as fstat. The phase is probably pretty random due to clock skew. setpoint for id=0, iq=10A.
Will test in Touran now.
Of course now handling field weakening becomes less straight forward. Amplitude will just keep increasing until you end up with 6-step modulation.
Basically set iackp to 0.5 (was 10 yesterday) and simulated 90A rms current with the same frequency as fstat. The phase is probably pretty random due to clock skew. setpoint for id=0, iq=10A.
Will test in Touran now.
Of course now handling field weakening becomes less straight forward. Amplitude will just keep increasing until you end up with 6-step modulation.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
No improvent in Touran... But now for above test case I plotted id and iq. Pretty sinusoidal for a DC quantity...
Edit: when I swap phase currents it becomes DC.
Edit: when I swap phase currents it becomes DC.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Nice, hopefully it'll just work smooth! Now I guess you'll try all syncofs values again.
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
It works!!
I had to swap pretty much every input
Swap il1 and il2, make ilXgain negative, swap resolver sin and cos. I think that was it
I think I will make a swap parameter with flags: swap forward/reverse, swap pwm phases, swap resolver phases, swap current sensors.. Anything else?
So good news first: the car drives and regens very smooth
Neutral news: setpoints for id and iq aren't always obeyed, maybe I have to use PI instead of P controller
Not so good news: Motor still draws too much current for doing relatively little
I'm not sure if I found the right syncofs. at around 20000 the motor stops producing torque despite supposedly sending 150A iq. Around 7000 seemed right. Not quite sure if syncadv is still needed to compensate for tracking delay? Maybe scoping resolver and phase voltage is not a bad idea after all.
If anyone with a Leaf motor would like to try, the firmware and parameters are attached.
I should add: v/f parameters are irrelevant (boost, fweak, udcnom). idckp is relevant for controller gain, and throtiq (torque producing current per % of throttle) and analog throtid. throtid needs to be optimized later for optimal torque per amp.
I had to swap pretty much every input
Swap il1 and il2, make ilXgain negative, swap resolver sin and cos. I think that was it
I think I will make a swap parameter with flags: swap forward/reverse, swap pwm phases, swap resolver phases, swap current sensors.. Anything else?
So good news first: the car drives and regens very smooth
Neutral news: setpoints for id and iq aren't always obeyed, maybe I have to use PI instead of P controller
Not so good news: Motor still draws too much current for doing relatively little
I'm not sure if I found the right syncofs. at around 20000 the motor stops producing torque despite supposedly sending 150A iq. Around 7000 seemed right. Not quite sure if syncadv is still needed to compensate for tracking delay? Maybe scoping resolver and phase voltage is not a bad idea after all.
If anyone with a Leaf motor would like to try, the firmware and parameters are attached.
I should add: v/f parameters are irrelevant (boost, fweak, udcnom). idckp is relevant for controller gain, and throtiq (torque producing current per % of throttle) and analog throtid. throtid needs to be optimized later for optimal torque per amp.
- Attachments
-
- Leaf 2019-06-01.json
- (1.24 KiB) Downloaded 102 times
-
- stm32_sine.zip
- (25.62 KiB) Downloaded 113 times
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Great news! I wish I had a power stage tied to my Leaf motor. Would love to try it.
A PI controller instead of P is a must in my opinion. Also, after we do the Park transformation and run the P/PI control, what we have is the new Vd/Vq voltage vectors in the d-q axis which are then transformed back into Va, Vb and Vc sinusoidal phase voltages, that supposedly should lead the motor Id/Iq to IdRef/IqRef, right? That means, the Vd/Vq vectors need to stay under the maximum duty cycle radius. With the integral control, in practice, the system will never reach zero error and the output of the integral will be very large so the calculated duty cycles can overflow easily. A saturation point to the PI control, or an extra anti-windup correction gain is also placed to avoid this. Here is another TI article about it: https://e2e.ti.com/blogs_/b/motordrivec ... e-part-vii
I think syncadv is needed if you're really sure the position reading lags the actual position as the motor gets faster. Can you spin it externally and scope the angle and back-emf?
Swapping stuff is needed sometimes In my current ACIM slip controller I had added a parameter myself that swaps two phases of the PWM outputs. I named the parameter "dirrev". I needed it because my quadrature encoder was mounted inversely, so the software was thinking motor spins backwards while it's actually spinning forward, so the speed feedback was always negative and the motor only ran back and forth. Mechanically swapping the phases wasn't possible, so I simply swapped two phase voltages. The code looks like this.
A PI controller instead of P is a must in my opinion. Also, after we do the Park transformation and run the P/PI control, what we have is the new Vd/Vq voltage vectors in the d-q axis which are then transformed back into Va, Vb and Vc sinusoidal phase voltages, that supposedly should lead the motor Id/Iq to IdRef/IqRef, right? That means, the Vd/Vq vectors need to stay under the maximum duty cycle radius. With the integral control, in practice, the system will never reach zero error and the output of the integral will be very large so the calculated duty cycles can overflow easily. A saturation point to the PI control, or an extra anti-windup correction gain is also placed to avoid this. Here is another TI article about it: https://e2e.ti.com/blogs_/b/motordrivec ... e-part-vii
I think syncadv is needed if you're really sure the position reading lags the actual position as the motor gets faster. Can you spin it externally and scope the angle and back-emf?
Swapping stuff is needed sometimes In my current ACIM slip controller I had added a parameter myself that swaps two phases of the PWM outputs. I named the parameter "dirrev". I needed it because my quadrature encoder was mounted inversely, so the software was thinking motor spins backwards while it's actually spinning forward, so the speed feedback was always negative and the motor only ran back and forth. Mechanically swapping the phases wasn't possible, so I simply swapped two phase voltages. The code looks like this.
Code: Select all
if (!reversed) {
sine[0] = SineLookup(angle);
sine[1] = SineLookup((angle + PHASE_SHIFT120) & 0xFFFF);
sine[2] = SineLookup((angle + PHASE_SHIFT240) & 0xFFFF);
} else {
sine[0] = SineLookup(angle);
sine[1] = SineLookup((angle + PHASE_SHIFT240) & 0xFFFF);
sine[2] = SineLookup((angle + PHASE_SHIFT120) & 0xFFFF);
}
-
- Posts: 260
- Joined: Sat Jan 12, 2019 12:39 am
- Location: UK
Re: Testing FOC for synchronous motor
This is all looking very good.
The integral ought to tend towards zero, always a good idea to set upper and lower bounds though. It's been a few years since I used PI.
The integral ought to tend towards zero, always a good idea to set upper and lower bounds though. It's been a few years since I used PI.
-
- Posts: 3265
- Joined: Mon Dec 24, 2018 1:37 pm
- Location: Slovenia
- Has thanked: 80 times
- Been thanked: 234 times
- Contact:
Re: Testing FOC for synchronous motor
Well very good. We can try your code by the end of next week.
But tell me something. If i would just use the new code in my ACIM car would it work with slip? Or is that completely new code?
Even though i reduced minslip I can still feel several very pronounced jolts when i release throttle and regen takes over. They subside only because of mass damping by 1t vehicle Could the new PI reduce that?
tnx
A
Re: Testing FOC for synchronous motor
Yes, a dynamic upper and lower bound could be set for the PI result so that (Vd^2+Vq^2) doesn’t exceed the duty cycle radius. With Johannes’ current software, the radius 32768 if I’m correct. Or 16384?doobedoobedo wrote: ↑Sat Jun 01, 2019 9:06 pm This is all looking very good.
The integral ought to tend towards zero, always a good idea to set upper and lower bounds though. It's been a few years since I used PI.
Also before the dynamic bounds we could initially set upper/lower limits of Vd and Vq to plus and minus 32768*(1/sqrt(2)) which will guarantee we’ll always stay under the radius.
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
I haven't tried this. In fact for acim code the regular slip calculation is still in effect so FOC is run with rotor angle + slip angle. Not sure if that is the way it's supposed to be.arber333 wrote: ↑Sat Jun 01, 2019 9:32 pm But tell me something. If i would just use the new code in my ACIM car would it work with slip? Or is that completely new code?
Even though i reduced minslip I can still feel several very pronounced jolts when i release throttle and regen takes over. They subside only because of mass damping by 1t vehicle Could the new PI reduce that?
Yes since I use fixed point decimal with 15 fraction digits for FOC, the radius is 32768.nailgg wrote: ↑Sun Jun 02, 2019 5:06 am Yes, a dynamic upper and lower bound could be set for the PI result so that (Vd^2+Vq^2) doesn’t exceed the duty cycle radius. With Johannes’ current software, the radius 32768 if I’m correct. Or 16384?
Also before the dynamic bounds we could initially set upper/lower limits of Vd and Vq to plus and minus 32768*(1/sqrt(2)) which will guarantee we’ll always stay under the radius.
I still can't get my head around how to detect that we've run out of voltage and now need to decrease id even further to enter field weakening.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Let's say when we spin the Leaf motor externally at 3000 RPM, it outputs a 200 Hz (for 4 pole pairs) 280V phase-to-phase back-emf (I don't actually know what voltage it outputs, I'm using random values). That means 280V*sqrt(2) ~= 400V DC-link is what we need for operating up to 3000 RPM until the weakening starts. So let's assume we've set udcnom to 400, and fweak to 200.
So the software knows the base RPM point where the weakening should start. But that's under the assumption of DC-link being supplied where the inverter is able to provide with motors nominal phase to phase voltage. If we're supplying the DC-link with a voltage below than the nominal voltage i.e. udcnom, the software already shifts the fweak point back or forth, so the weakening start point is shifted accordingly.
So instead of detecting we've run out of voltage, can't we simply start decreasing IdRef right after fweak, as the name already suggests? For the speeds under the weakening point, a fixed IdRef could be given. Above that point, a declining IdRef curve (with a lookup table maybe) based on motor speed, could be used. Since Leaf is an IPM, a smarter algorithm for IdRef can be implemented in the future.
After we run the field weakening logic and find the required IdRef, then run the PI control for IdRef->VdRef, we now have the Vd vector. Then we run the IqRef->VqRef PI controller, but now we should saturate the upper/lower points of Vq so that vectorial sum of new Vd/Vq vectors doesn't exceed the maximum voltage radius.
--
Below is a snippet from the Microchip's PMSM FOC example (link http://ww1.microchip.com/downloads/en/A ... _MCHV3.zip, pmsm.c:491). Above this snippet Clarke and Park are done. VdRef is defined by the need for field weakening, and VqRef is defined by the torque control knob/speed regulator. Then here it prioritizes VdRef and dynamically limits VqRef so that sqrt(VdRef^2+VqRef^2)<=1.
Code: Select all
/* Flux weakening control - the actual speed is replaced
with the reference speed for stability
reference for d current component
adapt the estimator parameters in concordance with the speed */
ctrlParm.qVdRef=FieldWeakening(_Q15abs(ctrlParm.qVelRef));
/* PI control for D */
piInputId.inMeasure = idq.d;
piInputId.inReference = ctrlParm.qVdRef;
MC_ControllerPIUpdate_Assembly(piInputId.inReference,
piInputId.inMeasure,
&piInputId.piState,
&piOutputId.out);
vdq.d = piOutputId.out;
/* Dynamic d-q adjustment
with d component priority
vq=sqrt (vs^2 - vd^2)
limit vq maximum to the one resulting from the calculation above */
temp_qref_pow_q15 = (int16_t)(__builtin_mulss(piOutputId.out ,
piOutputId.out) >> 15);
temp_qref_pow_q15 = Q15(MAX_VOLTAGE_VECTOR) - temp_qref_pow_q15;
piInputIq.piState.outMax = Q15SQRT (temp_qref_pow_q15);
/* PI control for Q */
piInputIq.inMeasure = idq.q;
piInputIq.inReference = ctrlParm.qVqRef;
MC_ControllerPIUpdate_Assembly(piInputIq.inReference,
piInputIq.inMeasure,
&piInputIq.piState,
&piOutputIq.out);
vdq.q = piOutputIq.out;
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Now I'm wondering, does it make any sense to make id dynamic below field weakening. Like right now I'm scaling it with throttle. Should I rather set it to a fixed value?
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Is’s best to tell it after test but I think we’ll end up setting it to a fixed value until weakening starts.
- johu
- Site Admin
- Posts: 5789
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 157 times
- Been thanked: 1023 times
- Contact:
Re: Testing FOC for synchronous motor
Tried a fixed value, wasn't convinced. The motor will hardly start spinning. Apparently it's the ratio of iq/id that matters.
I have also introduced a PI controller now.
id regulation is still kind of weird. It works quite good when there is load on the motor but if I just want to spin it up in idle, id can quickly reach -70A even though I set it to 0.
I guess I'm running out of time to figure this out before going on holiday, so firmware and parameters are attached for testing.
I have also introduced a PI controller now.
id regulation is still kind of weird. It works quite good when there is load on the motor but if I just want to spin it up in idle, id can quickly reach -70A even though I set it to 0.
I guess I'm running out of time to figure this out before going on holiday, so firmware and parameters are attached for testing.
- Attachments
-
- stm32_sine.zip
- (25.67 KiB) Downloaded 85 times
-
- Leaf 2019-06-03.json
- (1.27 KiB) Downloaded 99 times
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
Re: Testing FOC for synchronous motor
Kp and Ki parameters might need to be tuned more carefully maybe, until you reach zero id at zero id reference? I’d initially lower the Ki very close to zero to validate if it oscillates around zero with only Kp.