The PMSM dq model
The Clarke and Park transforms deliver two currents in a frame that turns with the rotor. This page is the model that sits under them: what voltage those currents demand, which parameters set it, and how to measure the parameters when the datasheet is missing or wrong.
Four numbers describe the machine electrically — , , and . Every controller gain on this site is computed from them, so being wrong about one is not an academic problem.
Flux linkage first
Voltage equations are easier to remember if the flux linkages come first, because the voltage equations are just their time derivatives.
The d-axis flux has two contributors: what the stator current produces, and the magnets, which produce whether or not any current flows. The q-axis has only the stator’s contribution — the magnets point along by definition, which is what makes the frame worth choosing.
is the only term in the model that is nonzero with the inverter switched off. It is why a PMSM back-drives, why a shorted machine brakes, and why the terminals are live on a coasting motor.
The voltage equations
In a frame rotating at , the derivative of a vector picks up an extra term — the frame itself is turning underneath it. That gives
and substituting the flux linkages:
Those terms are worth being clear about. They are not new physics. Nothing was added to the machine by writing it in a rotating frame; they are the bookkeeping cost of describing a stationary quantity from a spinning viewpoint, and they are exactly what makes the dq currents constant in steady state instead of sinusoidal. Every awkward property of a PMSM drive — the cross-coupling, the back-EMF, the voltage ceiling — was already there in the three-phase equations. The rotating frame does not create them, it names them.
Set and four kinds of term remain:
| Term | Where | Grows with | What it is |
|---|---|---|---|
| both axes | current | copper loss, all of it heat | |
| both axes | rate of change | the only term the current loop steers with | |
| cross-axis | speed × current | each axis disturbing the other | |
| q only | speed | the back-EMF |
Why
Inductance measures how easily the stator’s field crosses the rotor, and on most rotors that depends on direction.
On a surface-magnet rotor the magnets are glued to the outside. Magnet material has a permeability close to air’s, so the stator’s field sees roughly the same gap whichever way it points: , and the machine is non-salient.
On an interior-magnet rotor the magnets are buried in the iron. Along the d-axis the flux path goes straight through the magnets — a long stretch of effectively-air. Along the q-axis it can travel through iron between the magnets, which is a far easier path. So on an IPM the q-axis carries more inductance: , typically by a factor of 1.5 to 3.
Note the direction, because it is the opposite of the intuition that the magnet-bearing axis should be the “strong” one. It is exactly the presence of the magnets that makes the d-axis path hard. The reference machine used throughout this site has and , a saliency ratio of 1.57.
Two consequences follow immediately, and both get their own page:
- The two axes have different electrical time constants — s and s here. The two current loops are not the same loop, and tuning both with one gain leaves one of them detuned by the saliency ratio. That is the current loop page.
- A difference in inductance is a torque-producing mechanism in its own right, independent of the magnets. That is torque and MTPA.
Where the volts actually go
The equations above are easy to nod along to. What they do not convey is that the balance between the terms changes completely across the operating range — so much so that a drive at 200 rpm and the same drive at 5000 rpm are solving different problems with the same code.
At the default point — 1500 rpm, A, — the three terms are V, V and V, giving V, V and a total of 9.08 V. That is 33% of the 27.71 V the 48 V link can produce linearly.
Now sweep the speed and watch the crossover.
- At standstill the machine is a resistor. kills two of the three terms outright. All the inverter is doing is pushing current through 0.35 Ω, and every volt it produces becomes heat.
- The resistive term never grows with speed at all. It is flat at 3.50 V across the whole sweep, because it depends only on current.
- The back-EMF overtakes it at 983 rpm for this current, and keeps going: by 6000 rpm it is 21.4 V against the same 3.50 V. The machine has become a generator that the inverter is pushing against.
The crossover speed is not a property of the machine alone — it is , so it scales with current. At 40 A the resistive term is 14 V and the back-EMF does not overtake it until 3932 rpm. A heavily loaded machine stays resistance-dominated for four times longer. That is why a drive that behaves impeccably on a lightly loaded bench can surprise you under load, and vice versa.
On the bench Raise to 40 A and watch the total curve cross the line at 2662 rpm. At 10 A the same crossing does not happen until 6394 rpm. Base speed is not a number the machine has — it is a number the machine and the load and the DC link have together, and quoting one without a torque is meaningless. What to do once you reach it is field weakening.
There is a third effect hiding in the sweep. Set to 40 A and go to 3000 rpm: the cross-coupling term is V against a back-EMF of 10.7 V. At high current the coupling between the axes is larger than the back-EMF itself. A current loop that treats it as a small disturbance to be rejected by the integrator is asking the integrator to chase two-thirds of the total voltage. Feedforward decoupling is not a refinement at that operating point; it is the difference between a loop that tracks and a loop that lags.
The model in code
The whole electrical model, per control period:
/* Cross-coupling and back-EMF are known, so subtract them and what remains
is a plain R-L load on each axis — which is what the PI is tuned for. */
const float we = pole_pairs * omega_m;
float vd_ff = -we * Lq * iq;
float vq_ff = we * (Ld * id + flux_m);
vd = pi_update(&pi_d, id_ref - id) + vd_ff;
vq = pi_update(&pi_q, iq_ref - iq) + vq_ff;
Two things about those four lines. The feedforward uses measured current on the opposite axis, not the reference, because it is compensating what is actually flowing. And the grouping is deliberate: that sum is the d-axis flux, and driving negative to shrink it is field weakening, written here as a term that was in the model from the start.
Measuring the four numbers
The model is only as good as its parameters, and datasheets are an unreliable
source for all four. identify.ts carries the standard bench procedures, and
the site’s tests run each one against the simulated machine and check the
parameter comes back — which is the one thing you cannot do on a real bench,
because there you have no truth to compare against.
— and the factor of two
Force DC through two terminals and measure. The current passes through two windings in series, so the reading is twice the per-phase value: the reference machine’s 0.35 Ω reads 0.700 Ω on the meter. The same factor applies to an LCR meter’s inductance reading — 210 µH reads as 420 µH.
This is the single most common parameter error, and it is silent. Both current loops end up with double the resistance they should have, both integral gains are wrong by 2×, and everything still runs — just not the way it was tuned to.
and — and an angle you do not control
Lock the rotor, apply a voltage step, and the current rises with time constant toward . One step yields both parameters.
The trap is which inductance you measured. With the rotor locked, what you see depends on where it happens to be sitting:
Aligned with the d-axis it reads 210 µH; a quarter of an electrical revolution away, 330 µH. Land at 45° and you read 270 µH — the mean, which is neither parameter and looks entirely plausible. A single locked-rotor measurement at an unknown angle is not a parameter; it is a number between two parameters. The reliable procedure is to sweep the rotor through an electrical revolution and take the minimum and the maximum.
On the bench
Sample rate matters more than it looks when fitting the step. At 20 kHz there
are exactly twelve samples in the reference machine’s 600 µs d-axis time
constant, so taking the nearest sample to the 63.2% crossing rather than
interpolating between the two that straddle it costs up to half a sample in
twelve — about 4% on , before any measurement noise. fitStepResponse
interpolates.
The rotor must also genuinely be held. Any movement generates back-EMF that corrupts the tail of the response, and the fitted inductance comes out low.
— where every trap is a unit
Spin the machine with something else, leave the terminals open, and measure the voltage. With no current flowing there is no resistive or inductive drop, so the terminal voltage is the back-EMF and .
Three unit conversions sit between the instrument and the parameter, and each one is a factor people drop:
| The reading | Multiply by | Why |
|---|---|---|
| line-to-line | you want per-phase | |
| RMS | you want peak | |
| mechanical speed | you want electrical |
Miss all three and you are out by a factor of 4.9. Miss one and you are out by enough to matter and not enough to notice. The reference machine’s 8.5 mWb corresponds to 4.36 V/krpm line-to-line RMS, which is the form a datasheet is most likely to quote — worth computing and comparing before trusting either.
While the machine is spinning, count electrical cycles per mechanical revolution and get the pole pairs too: 4 pole pairs at 1500 rpm is 100 Hz electrical. An incorrect pole count makes the drive run at the wrong speed by an exact integer ratio, which is at least a distinctive symptom.
And then it all changes with temperature
None of the four are constants.
- Copper gains 0.393% per kelvin. A winding measured at 25 °C and run at 125 °C has 39% more resistance — 0.35 Ω becomes 0.488 Ω. A current loop tuned cold is detuned after twenty minutes of work.
- Neodymium loses about 0.12% per kelvin, reversibly. Over a 100 K rise that is 12% less flux: 8.5 mWb down to 7.48 mWb. Less torque per amp, and a higher base speed — a rare case of a thermal effect helping.
- and both fall with current as the iron saturates, which is why production drives that care about accuracy use a 2-D lookup table measured on a dynamometer rather than two constants.
The point is not to model all of it. It is to know which claims are exact and which are nominal, so the surprises land where you expect them.
On the bench A parameter set that is self-consistent still satisfies power balance, which is a free check. At 1500 rpm and 10 A the model absorbs W, delivers 80.1 W to the shaft and dissipates 52.5 W in the windings — and 80.1 + 52.5 = 132.6 exactly. The is the amplitude-invariant convention’s power factor, the same one in front of the torque equation and traceable all the way back to the resultant MMF of three windings on the space vectors page. If your measured power does not close, suspect that factor before suspecting the machine.
What to take away
- Four parameters — , , , — carry the whole electrical model. Everything downstream is computed from them.
- The terms are the price of a rotating viewpoint, not new physics. They buy you constant dq currents in steady state.
- on an interior-magnet rotor, because the q-axis path avoids the magnets. The two axes therefore have different time constants and want different gains.
- Which term dominates changes with the operating point: pure resistance at standstill, back-EMF above 983 rpm at 10 A, and cross-coupling larger than the back-EMF at high current. One set of equations, three different regimes.
- The crossover and the base speed both depend on load, so neither is a property of the machine alone.
- Measuring the parameters is mostly a matter of not dropping factors: 2 for line-to-line, and for back-EMF, for electrical speed — and an inductance measured at an unknown rotor angle is not a parameter at all.
Next: what all this voltage is producing — and why is not the best answer on a salient machine.