
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/plot_3kw_bsyrm_levitation_gradnet.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_plot_3kw_bsyrm_levitation_gradnet.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_plot_3kw_bsyrm_levitation_gradnet.py:


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
[#Das2026]_, 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.

.. GENERATED FROM PYTHON SOURCE LINES 16-22

.. code-block:: Python

    from math import pi
    from pathlib import Path

    import motulator_bearingless.gradnet as gn
    from motulator_bearingless import control, model, utils








.. GENERATED FROM PYTHON SOURCE LINES 23-24

Compute base values based on the nominal values (just for figures).

.. GENERATED FROM PYTHON SOURCE LINES 24-28

.. code-block:: Python


    nom = utils.NominalValues(U=220, I=12, f=50, P=2.6e3, tau=14.5)
    base = utils.BaseValues.from_nominal(nom, n_p=2)








.. GENERATED FROM PYTHON SOURCE LINES 29-31

Configure the system model. The rotor mass roughly corresponds to the rotor
lamination and the shaft inside it.

.. GENERATED FROM PYTHON SOURCE LINES 31-48

.. code-block:: Python


    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)








.. GENERATED FROM PYTHON SOURCE LINES 49-50

Configure the control system.

.. GENERATED FROM PYTHON SOURCE LINES 50-65

.. code-block:: Python


    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)








.. GENERATED FROM PYTHON SOURCE LINES 66-71

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.

.. GENERATED FROM PYTHON SOURCE LINES 71-76

.. code-block:: Python


    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)








.. GENERATED FROM PYTHON SOURCE LINES 77-78

Create the simulation object, simulate, and plot the results.

.. GENERATED FROM PYTHON SOURCE LINES 78-86

.. code-block:: Python


    sim = model.Simulation(mdl, ctrl)
    res = sim.simulate(t_stop=1.2)
    subplots = ["speed", "torque", "force", "displacement", "current"]
    f_lims = (-60.0, 500.0)  # Room for the legends
    y_lims = [None, (-0.05, 1.75), f_lims, (-75.0, 60.0), (-1.4, 0.95)]
    utils.plot(res, base, subplots, y_lims=y_lims)




.. image-sg:: /examples/images/sphx_glr_plot_3kw_bsyrm_levitation_gradnet_001.png
   :alt: plot 3kw bsyrm levitation gradnet
   :srcset: /examples/images/sphx_glr_plot_3kw_bsyrm_levitation_gradnet_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 87-90

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.

.. GENERATED FROM PYTHON SOURCE LINES 90-94

.. code-block:: Python


    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])




.. rst-class:: sphx-glr-horizontal


    *

      .. image-sg:: /examples/images/sphx_glr_plot_3kw_bsyrm_levitation_gradnet_002.png
         :alt: plot 3kw bsyrm levitation gradnet
         :srcset: /examples/images/sphx_glr_plot_3kw_bsyrm_levitation_gradnet_002.png
         :class: sphx-glr-multi-img

    *

      .. image-sg:: /examples/images/sphx_glr_plot_3kw_bsyrm_levitation_gradnet_003.png
         :alt: plot 3kw bsyrm levitation gradnet
         :srcset: /examples/images/sphx_glr_plot_3kw_bsyrm_levitation_gradnet_003.png
         :class: sphx-glr-multi-img





.. GENERATED FROM PYTHON SOURCE LINES 95-100

.. rubric:: References

.. [#Das2026] Das, Martin, Kontodinas, Hinkkanen, "Direct force control of six-phase
   bearingless synchronous machines," Proc. ICEM, 2026,
   https://doi.org/10.1109/ICEM68283.2026.11757980


.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 26.379 seconds)


.. _sphx_glr_download_examples_plot_3kw_bsyrm_levitation_gradnet.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_3kw_bsyrm_levitation_gradnet.ipynb <plot_3kw_bsyrm_levitation_gradnet.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_3kw_bsyrm_levitation_gradnet.py <plot_3kw_bsyrm_levitation_gradnet.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_3kw_bsyrm_levitation_gradnet.zip <plot_3kw_bsyrm_levitation_gradnet.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
