pypowertrain OS simulation library

Eelco

10 mW
Joined
Jun 5, 2024
Messages
20
Location
NL
Ive been working on an OS library for motor/controller/bike simulation. Partially because I want to understand braking torque better, but also I have some more general needs for optimising powertrains that are not ebikes.

One feature that has given me a lot of value is the ability to programmatically search over / optimise all the parameters of a powertrain.

Im pleased to say that my results *mostly* seem to coincide with the grin simulator; except that im getting somewhat different behavior on the tail end of the curve. Perhaps thats because of the way the grin simulator deals with field-weakening? Or perhaps it reflects some other subtle detail of our motor model. Would be super cool if someone in the know could pinpoint the difference. @justin_le ?

In general any feedback would be most welcome. What id especially love to see are pointers for open datasets of measured data, of known components to compare to. So far the grin data is the only data of that kind that I know of...
 
Ah should have linked to the more on-topic optimisation example here, which actually pertains to optimising an ebike.

Answering the question of how hard it is to get really good electric braking over your full rated speed range was one of the motivating questions to write this software. And the answer is... not that hard. If you optimise your motor/controller system for it, you can get some very asymmetric curves, and with surprising light motors you can have the kind of braking performance that is going to make you forget about mechanical brakes at all.
Screenshot 2024-07-03 at 20.46.49.png
 
Last edited:
I added a runnable notebook to the readme, for lower the barrier to use for those who are not fluent in setting up python environments.

Perhaps with some more polish it will one day approach the usability of the grin simulator!
 
Ah should have linked to the more on-topic optimisation example here, which actually pertains to optimising an ebike.

Answering the question of how hard it is to get really good electric braking over your full rated speed range was one of the motivating questions to write this software. And the answer is... not that hard. If you optimise your motor/controller system for it, you can get some very asymmetric curves, and with surprising light motors you can have the kind of braking performance that is going to make you forget about mechanical brakes at all.
I should note that the model does not include iron saturation, so we should expect the higher end of that torque range to be a tad more compressed in reality. But still; if you have two driven wheels, and the ability to put out 100nm for a few seconds, who needs brake pads?

Note that the thermal limits should not be the issue as far as emergency braking is concerned; its not hard to design the system such that even in the hypothetical limits where you dump your full 50kmh kinetic energy into the coils alone, its still less than a 40C rise. The harder thing to design for would be to compete with external disk brakes for long steep descents... but that isnt my current concern.
 
Last edited:
Looking more closely at the shape of my curves, compared to those of the grin simulator... things are more off in my latest version that I remember them being earlier. I suspect it has to do with the way in which the motor constants are defined. This is what I currently have:

if turns == 8: Kt = 1.28 R = 0.268 L = 680e-6 # convert phase-to-phase to q-d frame # https://community.nxp.com/t5/Model-Based-Design-Toolbox-MBDT/Ld-and-Lq-measurement/td-p/794521 R = R / 2 * 1.5 L = L / 2 * 1.5 # Kt = Kt / 2 * 1.5

I get results pretty close to the grin simulator, if I uncomment that last line. Defining Kt that way would be quite unusual though; I think? For the L and R, the official docs say they are phase-to-phase. Which i understand to be taking the values by clamping a phase wire A and B, and measuring their properties. Internally we want the values in the q and d axes; hence /2 to get phase-to-neutral, and then *1.5 to get the values from phase A to phase BC in parallel.

But... does Kt need any conversion factors? The way its usually defined you just multiply it by your q-axis current and you have your torque, no? And im not seeing any suggestion of a different definition in the official manual. Anyone else tried to model a grin all axle before and think they know how to interpret these numbers?
 
Eh; scratch the above. Taking some more care to autogenerate the grin simulator url from my code, the high rpm behavior actually agrees nicely; (and to answer my earlier question; I suppose the grin simulator does not consider field weakening). I guess that makes me pretty confident we are using the same motor constant definitions.

That being said, if I put a high amp limit controller on my grin motor, and let it blast all the way up to 150Nm, there are stil significant differences ive been unable to track down. My estimates go some 10Nm higher. Im not considering saturation at all; but I dont think thats where the difference is either; since im not seeing parameters for saturation in the sim; nor does the curve show any qualitative evidence of a saturation model being applied.
 
Refined the comparison to the grin simulator, to the point where im pretty happy with it. It agrees both at the high rpm end, and Ive managed to get the low rpm torque to fit, by assuming the grin simulator enforces a 5C max battery discharge under the hood, or thereabouts; which would not be unreasonable, even though I dont see that as an exposed parameter.

Im currently working on a fancy configurable and dimensionally-scalable thermal model; and a nicer interface with interactive plots; its starting to become super useful.
 
The thermal modelling is working pretty nicely now. It fits the grin data nicely, and its set up so that the fitted values automatically scale along with adjustments to the motor design. Taking the values I fitted to grin thermal data and applying them to very different motors, I tend to get within 10% accurate predictions of their manufacturers rated torque, so thats nice.

Ive got to say the more I think about Kt/Kv definitions, the less I understand them. After my latest fury of refactoring, im not all that happy with how well my predictions fit that of the grin simulator. But then again I have no clue whats meant by 'Kt' or 'Kv'. Its even worse than with R and L, where you 'only' have 3 definitions to worry about (and there is like a 50/50 chance a manufacturer will actually mention which definition is used).

But with Kt... could be phase to phase, phase to neutral, q-axis, rms, peak-to-peak, or non-sinusoidal, or some permutation of those attributes. And of course in the rich tradition of motor design, you keep it a closely guarded secret what definition is being used...

It would be super useful to take a look at the grin simulator source code... or have some other established reference to compare to... but I guess if that existed I wouldnt be laboring making software like this. Or does anyone have any good leads on other software to compare to, which I could dig into to the source of to hunt down any discrepancies?
 
I could be totally off but isn't Kt the inverse of Kv (from a theoretical sense which I think doesn't include some losses) and I assume it's motor RMS phase current and only Q-axis because these assume it's a simple motor that has zero D-axis current and I think the grin simulator assumes that. That is so say I think the Grin sim assumes no MTPA or field weakening which is reasonable considering it's mostly for hub motors that don't benefit much from D-axis current.
 
I could be totally off but isn't Kt the inverse of Kv (from a theoretical sense which I think doesn't include some losses) and I assume it's motor RMS phase current and only Q-axis because these assume it's a simple motor that has zero D-axis current and I think the grin simulator assumes that. That is so say I think the Grin sim assumes no MTPA or field weakening which is reasonable considering it's mostly for hub motors that don't benefit much from D-axis current.
Dunno, couldnt find any docs on details like FW; looking at the qualitative character of the curves that grin simulator puts out, it looks like it does not include it. It certainly doesnt include 'unlimited field weakening'; you can push most motors with positive torque at quite high rpm; but only for a short amount of time; and most sensible firmware would probably protect the end user from that. That being said; in my experience the typical ebike motor does benefit quite a bit from a modest amount of FW; like extending its range of capability by some 10% without unreasonable copper losses. Which is nothing to sneeze at imo for a handful of lines of firmware.

But about Kt; yeah, if I take Kt to be defined as the ratio of torque to rms-q-axis current, I do have a reasonable match to the grin simulator in the low rpm limit. But in the high rpm limit, my predictions for the zero-Id no-load rpm are consistently below those of the grin simulator. So perhaps thats because that curve isnt actually at zero Id. Or more likely, there is a bug somewhere. Most likely in my code... but im pretty stumped. Ive seen multiple instances of justin comparing his simulator to actual motors in the high rpm limit and im pretty sure his code holds up.

One possible difference is that most controllers simply command Iq current up to a predicted theoretical no-load rpm as set from the Kv configured in the controller; perhaps in reality when taking inductances and resistances in mind the current-feedback loops dont actually manage to hold a pure Id=0 state under those conditions... but its a small effect any you dont really notice that under this simplified control scheme you are secretly running a little Id a high rpm? The way ive implemented it, for any rpm-torque combo, im actively considering all possible Id values, and pick the one with the lowest bus current... which is a little unusual; but not 'wrong' I think.
 
Ah interesting; the simulator does not actually use sinusoidal commutation; which is what im assuming atm (or SVPWM as a default actually). So that already might explain why im achieving lower no-load rpms. I was assuming sinusoidal since thats what grin's product line contains.... but perhaps the simulator has been updated in the years since?
 
Last edited:
Screenshot 2024-07-27 at 10.03.07.pngScreenshot 2024-07-27 at 10.02.43.png

Still working a lot on this. It now comes with an interactive app, which is pretty neat, for exploring your understanding of how much various (motor) design parameters matter. Also it now calculates effective acceleration, taking into account tire Cf, and weight shift between the wheels as you are accelerating.

Its quite usable at this point id say. Im working on getting this app hosted in a usable way online (which isnt my forte). But if you want to run the app locally, its super simple if you either know how to create a conda env or can bother to google/chatgpt it.
 

Attachments

  • Screenshot 2024-07-27 at 09.30.03.png
    Screenshot 2024-07-27 at 09.30.03.png
    411.3 KB · Views: 1
Last edited:
Back
Top