motulator_bearingless.utils#

Utilities for six-phase bearingless machine drives.

The utilities include the machine parameters and the magnetic models [1], [2], the vector-space decomposition of the six-phase winding [3], and plotting functions. The base-value classes and the plot style of motulator are re-exported for convenience.

References

Classes#

BaseBearinglessMachinePars

Base class for the machine parameters, as used by the machine model.

BearinglessMagneticModel

Base class for the machine parameters, as used by the control system.

BearinglessSynchronousMachinePars

Constant parameters of a six-phase bearingless synchronous machine.

FluxMapFcn

Flux map with its Jacobian, e.g., FluxMap.

SaturatedBearinglessSynchronousMachinePars

Parameters of a saturated bearingless synchronous machine.

SpatialSaturatedBearinglessSynchronousMachinePars

Parameters of a saturated bearingless synchronous machine with spatial harmonics.

Functions#

c2v(*z)

Stack complex numbers (or arrays) into a real vector along the last axis.

fourpole_pars(par)

Parameters of the four-pole plane as an equivalent three-phase machine.

inv_vsd(x_s1_ab, x_s2_ab)

Inverse vector-space decomposition, see vsd().

plot(res[, base, subplots, t_lims, t_ticks, y_lims, ...])

Plot the simulation results of a bearingless machine drive.

plot_phase_currents(t, i_abc[, t_lims, y_lims, latex, ...])

Plot the six phase currents.

sixphase_currents(i_c_ab)

Phase currents from the space vectors of the two sets.

torque(i_s1, i_s2, psi_s1, psi_s2, q_M, f_M)

Electromagnetic torque (Nm) without the term due to the spatial harmonics.

v2c(v)

Inverse of c2v.

vsd(x_A_ab, x_B_ab)

Vector-space decomposition of the two three-phase sets into the two planes.

Module Contents#

class motulator_bearingless.utils.BaseBearinglessMachinePars[source]#

Bases: Protocol

Base class for the machine parameters, as used by the machine model.

The magnetic model is a lossless mapping between the stator flux linkages, the stator currents, the rotor displacement, and the radial force, consistent with a magnetic energy function W(psi_s, q_M, theta_M). All space vectors are in rotor coordinates, and the methods accept scalars as well as arrays of the same shape.

i_s(psi_s1, psi_s2, q_M, exp_j_theta_M=None)[source]#

Currents (A) and radial force (N) from flux linkages (Vs).

Parameters:
  • psi_s1 (Any)

  • psi_s2 (Any)

  • q_M (Any)

  • exp_j_theta_M (Any)

Return type:

tuple[Any, Any, Any]

magnetic_map(psi_s1, psi_s2, q_M, exp_j_theta_M=None)[source]#

Currents, radial force, and torque from the flux linkages.

Parameters:
  • psi_s1 (complex | ndarray) – Stator flux linkages (Vs) of the two-pole and four-pole planes.

  • psi_s2 (complex | ndarray) – Stator flux linkages (Vs) of the two-pole and four-pole planes.

  • q_M (complex | ndarray) – Rotor displacement (m).

  • exp_j_theta_M (complex | ndarray, optional) – Complex exponential of the mechanical rotor angle, needed by models with spatial harmonics.

Returns:

  • i_s1, i_s2, f_M (complex | ndarray) – Stator currents (A) of the two planes and the radial force (N).

  • tau_M (float | ndarray) – Electromagnetic torque (Nm).

Return type:

tuple[Any, Any, Any, Any]

class motulator_bearingless.utils.BearinglessMagneticModel[source]#

Bases: BaseBearinglessMachinePars, Protocol

Base class for the machine parameters, as used by the control system.

In addition to the machine model, the control system needs the flux map psi_s, the force map f_M, the incremental inductance matrix incr_ind_mat, and the sensitivities di_dq and df_dq to the displacement, all as functions of the currents and the displacement.

df_dq(i_s1, i_s2, q_M)[source]#

Force sensitivity d f_M/d q_M at constant flux, shape (…, 2, 2).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

di_dq(i_s1, i_s2, q_M)[source]#

Current sensitivity d i_s/d q_M at constant flux, shape (…, 4, 2).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

f_M(i_s1, i_s2, q_M)[source]#

Radial force (N) as a function of currents (A) and displacement (m).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

Any

incr_ind_mat(i_s1, i_s2, q_M)[source]#

Incremental inductance matrix (H), shape (…, 4, 4), d psi_s/d i_s.

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

psi_s(i_s1, i_s2, q_M)[source]#

Flux linkages (Vs) as functions of currents (A) and displacement (m).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

tuple[Any, Any]

class motulator_bearingless.utils.BearinglessSynchronousMachinePars[source]#

Bases: BearinglessMagneticModel

Constant parameters of a six-phase bearingless synchronous machine.

The four-pole rotor produces the torque with the four-pole field (h = 2) and the radial force with the two-pole field (h = 1). Linear magnetics are assumed. The flux linkages are psi_s = L_s(q_M)*i_s, where the inductance matrix depends linearly on the rotor displacement via the radial force constants:

L_s = [[L_1*I, L_21.T], [L_21, diag(L_d, L_q)]]
L_21 = [[m_d*q_i, -m_d*q_j], [m_q*q_j, m_q*q_i]]

The corresponding radial force is f_M = 1.5*i_s.T*(dL_s/dq_M)*i_s, i.e.:

f_i = 3*(m_d*i_2d*i_1d + m_q*i_2q*i_1q)
f_j = 3*(m_q*i_2q*i_1d - m_d*i_2d*i_1q)
Parameters:
  • R_s (float) – Stator resistance (Ω).

  • L_1 (float) – Inductance (H) of the two-pole plane, isotropic for the four-pole rotor.

  • L_d (float) – d-axis inductance (H) of the four-pole plane.

  • L_q (float) – q-axis inductance (H) of the four-pole plane.

  • m_d (float) – d-axis radial force constant (H/m).

  • m_q (float) – q-axis radial force constant (H/m).

Notes

The negative stiffness (unbalanced magnetic pull proportional to the displacement) is a second-order effect of the displacement on the inductances, which is not included in this linear model.

df_dq(i_s1, i_s2, q_M)[source]#

Force sensitivity d f_M/d q_M at constant flux, shape (…, 2, 2).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

di_dq(i_s1, i_s2, q_M)[source]#

Current sensitivity d i_s/d q_M at constant flux, shape (…, 4, 2).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

f_M(i_s1, i_s2, q_M)[source]#

Radial force (N) as a function of currents (A) and displacement (m).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

Any

i_s(psi_s1, psi_s2, q_M, exp_j_theta_M=None)[source]#

Currents (A) and radial force (N) from flux linkages (Vs).

Parameters:
  • psi_s1 (Any)

  • psi_s2 (Any)

  • q_M (Any)

  • exp_j_theta_M (Any)

Return type:

tuple[Any, Any, Any]

incr_ind_mat(i_s1, i_s2, q_M)[source]#

Incremental inductance matrix (H), shape (…, 4, 4).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

ind_mat(q_M)[source]#

Inductance matrix (H), shape (…, 4, 4), at the displacement q_M.

Parameters:

q_M (Any)

Return type:

numpy.ndarray

psi_s(i_s1, i_s2, q_M)[source]#

Flux linkages (Vs) as functions of currents (A) and displacement (m).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

tuple[Any, Any]

class motulator_bearingless.utils.FluxMapFcn[source]#

Bases: Protocol

Flux map with its Jacobian, e.g., FluxMap.

The map gives the flux linkages (Vs) of the two planes and the radial force (N) as functions of the currents (A) of the two planes and the displacement (m).

jacobian(i_s1, i_s2, q_M)[source]#

Jacobian matrix of the outputs with respect to the inputs, (…, 6, 6).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

class motulator_bearingless.utils.SaturatedBearinglessSynchronousMachinePars[source]#

Bases: BearinglessMagneticModel

Parameters of a saturated bearingless synchronous machine.

The class corresponds to motulator.drive.model.SaturatedSynchronousMachinePars. The saturation model is specified as a current map. Optionally, to be used only in control systems, a flux map can be provided.

Parameters:
  • R_s (float) – Stator resistance (Ω).

  • i_s_fcn (Callable[[Any, Any, Any], tuple[Any, Any, Any]], optional) – Currents (A) and radial force (N) as functions of the flux linkages (Vs) of the two planes and the displacement (m), e.g., CurrentMap. Needed in the machine model.

  • psi_s_fcn (FluxMapFcn, optional) – Flux linkages (Vs) and radial force (N) as functions of the currents (A) of the two planes and the displacement (m), with the Jacobian, e.g., FluxMap. Needed in the control systems.

df_dq(i_s1, i_s2, q_M)[source]#

Force sensitivity d f_M/d q_M at constant flux, shape (…, 2, 2).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

di_dq(i_s1, i_s2, q_M)[source]#

Current sensitivity d i_s/d q_M at constant flux, shape (…, 4, 2).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

f_M(i_s1, i_s2, q_M)[source]#

Radial force (N) as a function of currents (A) and displacement (m).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

Any

i_s(psi_s1, psi_s2, q_M, exp_j_theta_M=None)[source]#

Currents (A) and radial force (N) from flux linkages (Vs).

Parameters:
  • psi_s1 (Any)

  • psi_s2 (Any)

  • q_M (Any)

  • exp_j_theta_M (Any)

Return type:

tuple[Any, Any, Any]

incr_ind_mat(i_s1, i_s2, q_M)[source]#

Incremental inductance matrix (H), shape (…, 4, 4).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

numpy.ndarray

linearized(i_s2)[source]#

Constant parameters of the linear model at an operating point.

The inductances of the four-pole plane are the secant inductances at the given current and those of the two-pole plane are the incremental inductances at a centric rotor without the two-pole current. The force constants are fitted to the sensitivity of the radial force to the two-pole current.

Parameters:

i_s2 (complex) – Current (A) of the four-pole plane in rotor coordinates. Its both components must be nonzero.

Returns:

Parameters of the linear model.

Return type:

BearinglessSynchronousMachinePars

psi_s(i_s1, i_s2, q_M)[source]#

Flux linkages (Vs) as functions of currents (A) and displacement (m).

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • q_M (Any)

Return type:

tuple[Any, Any]

class motulator_bearingless.utils.SpatialSaturatedBearinglessSynchronousMachinePars[source]#

Bases: BaseBearinglessMachinePars

Parameters of a saturated bearingless synchronous machine with spatial harmonics.

The class corresponds to motulator.drive.model.SpatialSaturatedSynchronousMachinePars. This version is intended for the machine model, while the control methods do not support spatial harmonics.

Parameters:
  • R_s (float) – Stator resistance (Ω).

  • magnetic_map_fcn (Callable[[Any, Any, Any, Any], tuple[Any, Any, Any, Any]]) – Currents (A), radial force (N), and torque (Nm) as functions of the flux linkages (Vs) of the two planes, the displacement (m), and the complex exponential of the mechanical rotor angle, e.g., CurrentMapWithHarmonics.

i_s(psi_s1, psi_s2, q_M, exp_j_theta_M=None)[source]#

Currents (A) and radial force (N) from flux linkages (Vs).

Parameters:
  • psi_s1 (Any)

  • psi_s2 (Any)

  • q_M (Any)

  • exp_j_theta_M (Any)

Return type:

tuple[Any, Any, Any]

magnetic_map(psi_s1, psi_s2, q_M, exp_j_theta_M=None)[source]#

Currents (A), radial force (N), and torque (Nm) from flux linkages (Vs).

Parameters:
  • psi_s1 (Any)

  • psi_s2 (Any)

  • q_M (Any)

  • exp_j_theta_M (Any)

Return type:

tuple[Any, Any, Any, Any]

motulator_bearingless.utils.c2v(*z)[source]#

Stack complex numbers (or arrays) into a real vector along the last axis.

Parameters:

z (Any)

Return type:

numpy.ndarray

motulator_bearingless.utils.fourpole_pars(par)[source]#

Parameters of the four-pole plane as an equivalent three-phase machine.

For a centric rotor, the four-pole plane is a three-phase synchronous reluctance machine with two pole pairs, whose two three-phase sets are connected in parallel: the voltage and the flux linkage of the equivalent machine are those of the plane, while its current is twice the current of the plane, i.e., the sum of the set currents. Hence, the resistance and the inductances of the plane are halved, cf. the common mode of multi-three-phase machines in motulator_multiphase. The equivalent machine produces the total torque 6*Im(i_s2*conj(psi_s2)). The coupling of the planes via the rotor displacement is omitted.

Parameters:

par (BearinglessMagneticModel) – Magnetic model. A saturated model is sliced at zero two-pole current and at a centric rotor.

Returns:

Parameters of the equivalent three-phase machine.

Return type:

SynchronousMachinePars | SaturatedSynchronousMachinePars

Examples

>>> from motulator_bearingless.utils import (
...     BearinglessSynchronousMachinePars,
...     fourpole_pars,
... )
>>> par = BearinglessSynchronousMachinePars(
...     R_s=0.2, L_1=0.03, L_d=0.03, L_q=0.01, m_d=10.0, m_q=0.2
... )
>>> fourpole_pars(par)
SynchronousMachinePars(n_p=2, R_s=0.1, L_d=0.015, L_q=0.005, psi_f=0.0, G_c=0.0)
motulator_bearingless.utils.inv_vsd(x_s1_ab, x_s2_ab)[source]#

Inverse vector-space decomposition, see vsd().

Parameters:
  • x_s1_ab (complex | ndarray) – Space vector in the two-pole plane, in stator coordinates.

  • x_s2_ab (complex | ndarray) – Space vector in the four-pole plane, in stator coordinates.

Returns:

x_A_ab, x_B_ab – Space vectors of the two three-phase sets.

Return type:

complex | ndarray

Examples

>>> from motulator_bearingless.utils import inv_vsd, vsd
>>> x_A_ab, x_B_ab = inv_vsd(0.1j, 1 - 0.5j)
>>> [complex(round(x.real, 12), round(x.imag, 12)) for x in vsd(x_A_ab, x_B_ab)]
[0.1j, (1-0.5j)]
motulator_bearingless.utils.plot(res, base=None, subplots=None, t_lims=None, t_ticks=None, y_lims=None, y_ticks=None, latex=False, save_path=None, **savefig_kwargs)[source]#

Plot the simulation results of a bearingless machine drive.

Parameters:
  • res (SimulationResults) – Simulation results.

  • base (BaseValues, optional) – Base values for scaling the electrical waveforms. If not given, the waveforms are plotted in SI units. Forces and displacements are always in SI units.

  • subplots (list[str], optional) – Subplots to include. Valid names: “speed”, “torque”, “flux”, “force”, “current”, “displacement”. Defaults to all but “displacement”.

  • t_lims (tuple[float, float], optional) – Time axis limits.

  • t_ticks (ArrayLike, optional) – Time axis tick locations.

  • y_lims (Sequence[tuple[float, float] | None], optional) – y-axis limits for each subplot.

  • y_ticks (Sequence[ArrayLike | None], optional) – y-axis tick locations for each subplot.

  • latex (bool, optional) – Use LaTeX fonts for the labels, defaults to False.

  • save_path (str | Path, optional) – Path to save the figure. If None, the figure is not saved.

  • **savefig_kwargs – Additional keyword arguments passed to plt.savefig().

Return type:

None

motulator_bearingless.utils.plot_phase_currents(t, i_abc, t_lims=None, y_lims=None, latex=False, save_path=None, **savefig_kwargs)[source]#

Plot the six phase currents.

Parameters:
  • t (ndarray) – Time (s).

  • i_abc (ndarray, shape (6, N)) – Phase currents (A), see sixphase_currents().

  • t_lims (tuple[float, float], optional) – Time axis limits.

  • y_lims (tuple[float, float], optional) – Current axis limits.

  • latex (bool, optional) – Use LaTeX fonts for the labels, defaults to False.

  • save_path (str | Path, optional) – Path to save the figure. If None, the figure is not saved.

  • **savefig_kwargs – Additional keyword arguments passed to plt.savefig().

Return type:

None

motulator_bearingless.utils.sixphase_currents(i_c_ab)[source]#

Phase currents from the space vectors of the two sets.

Parameters:

i_c_ab (ndarray, shape (2,) or (2, N)) – Space vectors of the first (phases 1, 3, 5) and second (phases 2, 4, 6) sets.

Returns:

Phase currents [i_1, …, i_6].

Return type:

ndarray, shape (6,) or (6, N)

motulator_bearingless.utils.torque(i_s1, i_s2, psi_s1, psi_s2, q_M, f_M)[source]#

Electromagnetic torque (Nm) without the term due to the spatial harmonics.

Parameters:
  • i_s1 (Any)

  • i_s2 (Any)

  • psi_s1 (Any)

  • psi_s2 (Any)

  • q_M (Any)

  • f_M (Any)

Return type:

Any

motulator_bearingless.utils.v2c(v)[source]#

Inverse of c2v.

Parameters:

v (numpy.ndarray)

Return type:

tuple[Any, …]

motulator_bearingless.utils.vsd(x_A_ab, x_B_ab)[source]#

Vector-space decomposition of the two three-phase sets into the two planes.

The symmetrical six-phase winding consists of phases 1…6 at 60° intervals. The first three-phase set consists of the phases 1, 3, 5 and the second set of the phases 2, 4, 6. Each set is described by its standard peak-valued space vector abc2complex([x_1, x_3, x_5]) and abc2complex([x_2, x_4, x_6]), where the vector of the second set is expressed in its own coordinates (its a-phase axis is at 60°). The planes h = 1 (two-pole) and h = 2 (four-pole) result from the vector-space decomposition with peak-value scaling, x_sh = (1/3)*sum(x_k*alpha**(h*(k - 1))), where alpha = exp(1j*pi/3) [3]. Zero-sequence components are omitted.

Parameters:
  • x_A_ab (complex | ndarray) – Space vector of the first three-phase set (phases 1, 3, 5).

  • x_B_ab (complex | ndarray) – Space vector of the second three-phase set (phases 2, 4, 6).

Returns:

x_s1_ab, x_s2_ab – Space vectors in the two-pole and four-pole planes, in stator coordinates.

Return type:

complex | ndarray

Notes

The four-pole plane sees the phases in reversed sequence, which shows up as the complex conjugate in the transformation.

Examples

>>> from motulator_bearingless.utils import ALPHA, vsd
>>> # Equal currents in the opposite phases (i_1 = i_4, i_3 = i_6, i_5 = i_2)
>>> # produce only the four-pole component
>>> i_A_ab = 1 + 1j
>>> i_s1_ab, i_s2_ab = vsd(i_A_ab, ALPHA**2 * i_A_ab)
>>> round(abs(i_s1_ab), 12)
0.0
>>> complex(round(i_s2_ab.real, 12), round(i_s2_ab.imag, 12))
(1-1j)