-
Notifications
You must be signed in to change notification settings - Fork 510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Include motor inductance in voltage control. #246
Comments
Thank you for this report! It makes sense to me, but I would like to think what @askuric thinks as well. It could be easily implemented, I think as a subclass of BLDCMotor, and if it works well eventually rolled into the main implementation. As you point out, the main problem for users will be obtaining the value of the motor inductance if it is not given in the datasheet... |
Very interesting @dzid26, I'm going to test this in code and report back, if the results are as expected we could make it a part of our next release. |
Hey guys,
What's even more interesting is that using this simple approach the max velocity reached is higher than for the pure So all in all, I am very happy with this addition and it sets a nice base for the future features. Thatnks a lot for your proposition and if you have the time to test the code that would be awesome as well. For my motor the // pole_pairs : 11
// resitance : 10 Ohm
// KV rating : 110
// inductance : 0.01 H
BLDCMotor motor = BLDCMotor(11, 10, 110, 0.01); The phase inductance can be also set using motor.phase_inductance = 0.001; of in the
|
Amazing. I would love to try it. Funny thing is that I haven't run SimpleFOC on anything yet. So far I was just admiring simplicity and the good documentation :) |
This is very cool. |
Just trying to understand this brilliant idea - this is related to both stepper and BLDC motors, correct? :-) |
I have added the changes to my code, and tested it - it works beautifully :-) |
Awesome! In the release v2.3 we did include this change to the stepper code as well, so please do let us know if it works for you as well. 😄 |
Hi, I used this feature with voltage mode and it works great. Now I think something is missing here, and that would also help with field weakening, I think it's called the circle limitation. |
I think the way it works now is that the waveform is saturated by the voltage limit of the driver resulting with overmodulation ? |
I don't fully understand what happens when you don't do this, but here is how it should be calculated: And at the end of loopfoc, it should look like this:
|
It makes sense to me. I think it is easier to see in the stepper controller because it has just Parke transformation. Arduino-FOC/src/StepperMotor.cpp Lines 367 to 368 in 05954cb
The voltage can be exceeded when the angle is say 45 deg because cos+sin adds up to sqrt(2). I am just not sure why Vd should be prioritized and how one magnetizes a rotor. I think that would apply to induction motors. Here, I think the geometrical limitation from STM32 FOC bible (chapter 4.12.1) would be more appropriate. |
I came across a nice example here. It shows that increasing vd not only shifts the waveform, but also increases the magnitude. SimpleFOC is limiting the magnitude in the driver by doing clipping. I believe this approach is meant to limit the magnitude without clipping, while prioritizing d axis for efficiency. Sorry for all the posts, I am sharing as I learn more about the topic. |
That's a cool stack exchange answer.
I think if you start to prioritize one over another then you effectively rotate the frame reference. I think it should be: |
Look at this comment in VESC @runger1101001 @askuric please let me know if you would be interested in this in the future, it will be useful for MTPA and FW. |
I am happy to help. I will test more and share. This simple example from stackoverflow also made me understand why we need decoupling. |
I believe this code should be improved to prioritize BEMF voltage when limiting to supply voltage: Arduino-FOC/src/StepperMotor.cpp Lines 300 to 304 in c32bdd1
The idea is that the remaining of the Uq would then be the actual IR voltage. From that, the actual Iq (and actual torque!) can be back-calculated. Then the actual Iq shall be used with IqwL. Here is a simplified c code from my other project that does that.
That's what I am using currently and it's good enough for me (but I don't care about high speed too much). It's better than limiting without the prioritization, but it doesn't solve issue brought by @Candas1 about exceeding the limit circle. The exceeded voltage can be seen on this visualization (X is I mentioned earlier a relatively simple circle limiting. But as can be seen now here above the 10rev/s the Uq stops increasing (it's slowly decreasing for the given parameters) and there is too much Ud voltage compared to the actual Iq. This would cause premature field weakening - good for the speed, but would reduce available torque/power. I would rather leave it at as I did it in the code above with simple bemf priority. As to prioritizing Vd, this doesn't make sense to me. If Iq drops (which it will when crossing base speed), so should the Vd. I believe, that even when limiting for the limit circle the U_emf should be prioritized to remain true to FOC theory (at least in the context of Id=0, aka below field weakening). |
I want to just lay out the foundation for a possible improvement, and also get feedback to verify the idea.
Issue
Lemma 1
Current is proportional to forward torque but only when its vector is at a 90-degree electrical angle.
Lemma 2
The current always lags the rotating voltage vector.
In the present Voltage control scheme, a 90-degree electrical angle is not maintained when speed increases.
Currently, this is the control scheme
Arduino-FOC/src/StepperMotor.cpp
Lines 297 to 299 in 45219c4
Vd=0
Vq=BEMF+ Itarget R
(Source)
Proposal
The voltage vector must be phase-shifted to compensate for the current vector lag. Since Park transform is already implemented, the phase lead angle can happen naturally by manipulating Vd. (White vector below)
The control should look like this:
Setting Vd=-Itarget * ω*RL will shift the effective current target vector to the desired 90deg. Only then will this current be proportional to torque.
ω is the electrical angular speed in rad/s. I.e. shaft speed * poles_pairs.
If the combined motor inductance RL is unknown, it can be set to 0.
From what I know, coil inductance can be an approximation of motor inductance, but I don't know how good. On the other hand, RLcan be found experimentally presumably by optimizing the value for maximum motor power.
References:
https://docs.simplefoc.com/voltage_torque_mode#voltage-control-with-current-estimation-and-back-emf-compensation
https://endless-sphere.com/sphere/threads/tsdz2-mid-drive-with-860c-850c-or-sw102-displays-only-flexible-opensource-firmware-casainho-code-only.93818/post-1376865
https://github.com/EGG-electric-unicycle/documentation/blob/master/Shane_Colton/3phduo.pdf - page 27.
The text was updated successfully, but these errors were encountered: