Note
Go to the end to download the full example code.
2.6-kW bearingless SyRM, GradNet from FEM data, levitation control#
This example simulates levitation control of a 2.6-kW six-phase bearingless synchronous reluctance machine (SyRM) drive. The machine model is a GradNet current map trained on finite-element data, including magnetic saturation, the spatial harmonics, and the unbalanced magnetic pull. The force is controlled by the direct force controller [1], parametrized by a GradNet flux map with the spatial harmonics averaged. Its radial force estimate includes the unbalanced magnetic pull, since the force map depends on the measured displacement.
Compute base values based on the nominal values (just for figures).
nom = utils.NominalValues(U=220, I=12, f=50, P=2.6e3, tau=14.5)
base = utils.BaseValues.from_nominal(nom, n_p=2)
Configure the system model. The rotor mass roughly corresponds to the rotor lamination and the shaft inside it.
p = Path(__file__).resolve().parent if "__file__" in globals() else Path.cwd()
R_s = 0.215 # Stator resistance from [#Das2026]_
path = "trained_models/bsyrm_fem_curr_map_harm_softmax_d128.npz"
current_map = gn.CurrentMapWithHarmonics(gn.load_gradnet(p / path))
par = model.SpatialSaturatedBearinglessSynchronousMachinePars(R_s, current_map)
m = 20.0
machine = model.BearinglessSynchronousMachine(par)
w_M_rated = 2 * pi * 1700 / 60
k = nom.tau / w_M_rated**2 # Quadratic load torque, rated torque at the rated speed
mechanics = model.MechanicalSystem(J=0.05, B_L=lambda w_M: k * abs(w_M))
radial = model.RadialMechanics(m=m)
converter = model.MultiThreePhaseConverter(u_dc=540)
sensors = model.BearinglessDriveSensors(w_M=model.Sensor(), theta_M=model.Sensor())
mdl = model.BearinglessDrive(machine, mechanics, radial, converter, sensors)
Configure the control system.
path = "trained_models/bsyrm_fem_flux_map_softmax_d128.npz"
est_flux_map = gn.FluxMap(gn.load_gradnet(p / path))
est_par = control.SaturatedBearinglessSynchronousMachinePars(
R_s, psi_s_fcn=est_flux_map
)
cfg = control.DirectForceControllerCfg(i_s_max=1.5 * base.i, psi_s_min=0.4)
force_ctrl = control.DirectForceController(est_par, cfg)
speed_ctrl = control.SpeedController(J=0.05, alpha_s=2 * pi * 4)
levitation_ctrl = control.LevitationController(
m=m, alpha_q=2 * pi * 50, alpha_o=2 * pi * 150
)
ctrl = control.DirectForceControlSystem(force_ctrl, speed_ctrl, levitation_ctrl)
Set the references and the external force. The machine is magnetized during the first 0.2 s, after which the rotor is accelerated to the rated speed of 1700 r/min in 0.6 s against the quadratic load torque. The gravity is applied as a step at t = 0.1 s in the negative direction of the j axis, and a displacement reference step of 50 µm at t = 1 s.
ctrl.set_speed_ref(lambda t: min(max(t - 0.2, 0) / 0.6, 1) * w_M_rated)
ctrl.set_displacement_ref(lambda t: (t > 1) * 50e-6)
radial.set_external_force(lambda t: (t > 0.1) * -9.81j * radial.m)
Create the simulation object, simulate, and plot the results.

Plot the response to the gravity step and to the displacement reference step. The static force in the end of the simulation includes the force of the unbalanced magnetic pull at the displacement of 50 µm.
utils.plot(res, base, ["force", "displacement"], t_lims=(0.08, 0.2), y_lims=[f_lims])
utils.plot(res, base, ["force", "displacement"], t_lims=(0.98, 1.1), y_lims=[f_lims])
References
Total running time of the script: (0 minutes 26.379 seconds)

